firmware: xilinx: Implement ZynqMP power management APIs

Add Xilinx ZynqMP firmware APIs to set suspend mode
and inform firmware that master has initialized its
own power management.

Signed-off-by: Rajan Vaja <rajan.vaja@xilinx.com>
Signed-off-by: Jolly Shah <jolly.shah@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
This commit is contained in:
Jolly Shah 2019-01-29 12:38:20 -08:00 committed by Michal Simek
parent d4ff6c9efa
commit e178df31cf
2 changed files with 49 additions and 0 deletions

View File

@ -530,6 +530,33 @@ static int zynqmp_pm_reset_get_status(const enum zynqmp_pm_reset reset,
return ret; return ret;
} }
/**
* zynqmp_pm_init_finalize() - PM call to inform firmware that the caller
* master has initialized its own power management
*
* This API function is to be used for notify the power management controller
* about the completed power management initialization.
*
* Return: Returns status, either success or error+reason
*/
static int zynqmp_pm_init_finalize(void)
{
return zynqmp_pm_invoke_fn(PM_PM_INIT_FINALIZE, 0, 0, 0, 0, NULL);
}
/**
* zynqmp_pm_set_suspend_mode() - Set system suspend mode
* @mode: Mode to set for system suspend
*
* This API function is used to set mode of system suspend.
*
* Return: Returns status, either success or error+reason
*/
static int zynqmp_pm_set_suspend_mode(u32 mode)
{
return zynqmp_pm_invoke_fn(PM_SET_SUSPEND_MODE, mode, 0, 0, 0, NULL);
}
static const struct zynqmp_eemi_ops eemi_ops = { static const struct zynqmp_eemi_ops eemi_ops = {
.get_api_version = zynqmp_pm_get_api_version, .get_api_version = zynqmp_pm_get_api_version,
.get_chipid = zynqmp_pm_get_chipid, .get_chipid = zynqmp_pm_get_chipid,
@ -546,6 +573,8 @@ static const struct zynqmp_eemi_ops eemi_ops = {
.ioctl = zynqmp_pm_ioctl, .ioctl = zynqmp_pm_ioctl,
.reset_assert = zynqmp_pm_reset_assert, .reset_assert = zynqmp_pm_reset_assert,
.reset_get_status = zynqmp_pm_reset_get_status, .reset_get_status = zynqmp_pm_reset_get_status,
.init_finalize = zynqmp_pm_init_finalize,
.set_suspend_mode = zynqmp_pm_set_suspend_mode,
}; };
/** /**

View File

@ -28,14 +28,23 @@
/* SMC SIP service Call Function Identifier Prefix */ /* SMC SIP service Call Function Identifier Prefix */
#define PM_SIP_SVC 0xC2000000 #define PM_SIP_SVC 0xC2000000
#define PM_GET_TRUSTZONE_VERSION 0xa03 #define PM_GET_TRUSTZONE_VERSION 0xa03
#define PM_SET_SUSPEND_MODE 0xa02
#define GET_CALLBACK_DATA 0xa01
/* Number of 32bits values in payload */ /* Number of 32bits values in payload */
#define PAYLOAD_ARG_CNT 4U #define PAYLOAD_ARG_CNT 4U
/* Number of arguments for a callback */
#define CB_ARG_CNT 4
/* Payload size (consists of callback API ID + arguments) */
#define CB_PAYLOAD_SIZE (CB_ARG_CNT + 1)
enum pm_api_id { enum pm_api_id {
PM_GET_API_VERSION = 1, PM_GET_API_VERSION = 1,
PM_RESET_ASSERT = 17, PM_RESET_ASSERT = 17,
PM_RESET_GET_STATUS, PM_RESET_GET_STATUS,
PM_PM_INIT_FINALIZE = 21,
PM_GET_CHIPID = 24, PM_GET_CHIPID = 24,
PM_IOCTL = 34, PM_IOCTL = 34,
PM_QUERY_DATA, PM_QUERY_DATA,
@ -209,6 +218,12 @@ enum zynqmp_pm_reset {
ZYNQMP_PM_RESET_END = ZYNQMP_PM_RESET_PS_PL3 ZYNQMP_PM_RESET_END = ZYNQMP_PM_RESET_PS_PL3
}; };
enum zynqmp_pm_suspend_reason {
SUSPEND_POWER_REQUEST = 201,
SUSPEND_ALERT,
SUSPEND_SYSTEM_SHUTDOWN,
};
/** /**
* struct zynqmp_pm_query_data - PM query data * struct zynqmp_pm_query_data - PM query data
* @qid: query ID * @qid: query ID
@ -240,8 +255,13 @@ struct zynqmp_eemi_ops {
int (*reset_assert)(const enum zynqmp_pm_reset reset, int (*reset_assert)(const enum zynqmp_pm_reset reset,
const enum zynqmp_pm_reset_action assert_flag); const enum zynqmp_pm_reset_action assert_flag);
int (*reset_get_status)(const enum zynqmp_pm_reset reset, u32 *status); int (*reset_get_status)(const enum zynqmp_pm_reset reset, u32 *status);
int (*init_finalize)(void);
int (*set_suspend_mode)(u32 mode);
}; };
int zynqmp_pm_invoke_fn(u32 pm_api_id, u32 arg0, u32 arg1,
u32 arg2, u32 arg3, u32 *ret_payload);
#if IS_REACHABLE(CONFIG_ARCH_ZYNQMP) #if IS_REACHABLE(CONFIG_ARCH_ZYNQMP)
const struct zynqmp_eemi_ops *zynqmp_pm_get_eemi_ops(void); const struct zynqmp_eemi_ops *zynqmp_pm_get_eemi_ops(void);
#else #else