diff options
author | Robin Gong <yibin.gong@nxp.com> | 2017-11-29 19:26:44 +0800 |
---|---|---|
committer | Abel Vesa <abel.vesa@nxp.com> | 2018-06-11 10:08:40 +0300 |
commit | 1fff21f4d6a3314c8d8f181822bc8b2dcc1d61a6 (patch) | |
tree | 5b068105af3f6bd9aca13eee7ffa2899029659a5 /plat | |
parent | f4ec82775b77039912e0b369e808a49bfad7b9c4 (diff) |
plat: freescale: imx8qm/qxp: add poweroff
Add power off interface for Linux. Currently poweroff the whole board,may
change to poweroff partition if necessary.
sync with the below scfw commit:
commit 0e1f8aa5d6c6a6d9b8c05d5a84bbd613b301d367
Author: Chuck Cannon <chuck.cannon@freescale.com>
Date: Tue Nov 28 13:56:29 2017 -0600
Use SC_R_BOARD_R1 to control the base board reset.
Signed-off-by: Chuck Cannon <chuck.cannon@freescale.com>
Signed-off-by: Robin Gong <yibin.gong@nxp.com>
Diffstat (limited to 'plat')
-rw-r--r-- | plat/imx/common/include/sci/svc/pm/api.h | 21 | ||||
-rw-r--r-- | plat/imx/common/sci/svc/pm/pm_rpc_clnt.c | 19 | ||||
-rw-r--r-- | plat/imx/common/sci/svc/pm/rpc.h | 3 | ||||
-rw-r--r-- | plat/imx/imx8qm/imx8qm_psci.c | 10 | ||||
-rw-r--r-- | plat/imx/imx8qxp/imx8qxp_psci.c | 10 |
5 files changed, 47 insertions, 16 deletions
diff --git a/plat/imx/common/include/sci/svc/pm/api.h b/plat/imx/common/include/sci/svc/pm/api.h index 41ed9ea9..83ba8843 100644 --- a/plat/imx/common/include/sci/svc/pm/api.h +++ b/plat/imx/common/include/sci/svc/pm/api.h @@ -187,6 +187,23 @@ typedef uint8_t sc_pm_sys_if_t; */ /*! + * This function sets the system power mode. Only the owner of the + * SC_R_SYSTEM resource can do this. + * + * @param[in] ipc IPC handle + * @param[in] mode power mode to apply + * + * @return Returns an error code (SC_ERR_NONE = success). + * + * Return errors: + * - SC_ERR_PARM if invalid mode, + * - SC_ERR_NOACCESS if caller not the owner of SC_R_SYSTEM + * + * @see sc_pm_set_sys_power_mode(). + */ +sc_err_t sc_pm_set_sys_power_mode(sc_ipc_t ipc, sc_pm_power_mode_t mode); + +/*! * This function sets the power mode of a partition. * * @param[in] ipc IPC handle @@ -203,9 +220,9 @@ typedef uint8_t sc_pm_sys_if_t; * All resources owned by \a pt that are on will have their power * mode changed to \a mode. * - * @see sc_pm_set_resource_power_mode(). + * @see sc_pm_set_partition_power_mode(). */ -sc_err_t sc_pm_set_sys_power_mode(sc_ipc_t ipc, sc_rm_pt_t pt, +sc_err_t sc_pm_set_partition_power_mode(sc_ipc_t ipc, sc_rm_pt_t pt, sc_pm_power_mode_t mode); /*! diff --git a/plat/imx/common/sci/svc/pm/pm_rpc_clnt.c b/plat/imx/common/sci/svc/pm/pm_rpc_clnt.c index ed8f53de..58206a2d 100644 --- a/plat/imx/common/sci/svc/pm/pm_rpc_clnt.c +++ b/plat/imx/common/sci/svc/pm/pm_rpc_clnt.c @@ -28,7 +28,24 @@ /* Local Functions */ -sc_err_t sc_pm_set_sys_power_mode(sc_ipc_t ipc, sc_rm_pt_t pt, +sc_err_t sc_pm_set_sys_power_mode(sc_ipc_t ipc, sc_pm_power_mode_t mode) +{ + sc_rpc_msg_t msg; + uint8_t result; + + RPC_VER(&msg) = SC_RPC_VERSION; + RPC_SVC(&msg) = SC_RPC_SVC_PM; + RPC_FUNC(&msg) = PM_FUNC_SET_SYS_POWER_MODE; + RPC_U8(&msg, 0) = mode; + RPC_SIZE(&msg) = 2; + + sc_call_rpc(ipc, &msg, false); + + result = RPC_R8(&msg); + return (sc_err_t) result; +} + +sc_err_t sc_pm_set_partition_power_mode(sc_ipc_t ipc, sc_rm_pt_t pt, sc_pm_power_mode_t mode) { sc_rpc_msg_t msg; diff --git a/plat/imx/common/sci/svc/pm/rpc.h b/plat/imx/common/sci/svc/pm/rpc.h index f6b02f15..bd63b8fc 100644 --- a/plat/imx/common/sci/svc/pm/rpc.h +++ b/plat/imx/common/sci/svc/pm/rpc.h @@ -27,7 +27,8 @@ typedef enum pm_func_e { PM_FUNC_UNKNOWN = 0, /*!< Unknown function */ - PM_FUNC_SET_SYS_POWER_MODE = 1, /*!< Index for pm_set_sys_power_mode() RPC call */ + PM_FUNC_SET_SYS_POWER_MODE = 19, /*!< Index for pm_set_sys_power_mode() RPC call */ + PM_FUNC_SET_PARTITION_POWER_MODE = 1, /*!< Index for pm_set_partition_power_mode() RPC call */ PM_FUNC_GET_SYS_POWER_MODE = 2, /*!< Index for pm_get_sys_power_mode() RPC call */ PM_FUNC_SET_RESOURCE_POWER_MODE = 3, /*!< Index for pm_set_resource_power_mode() RPC call */ PM_FUNC_GET_RESOURCE_POWER_MODE = 4, /*!< Index for pm_get_resource_power_mode() RPC call */ diff --git a/plat/imx/imx8qm/imx8qm_psci.c b/plat/imx/imx8qm/imx8qm_psci.c index a06cadce..4fb5daea 100644 --- a/plat/imx/imx8qm/imx8qm_psci.c +++ b/plat/imx/imx8qm/imx8qm_psci.c @@ -237,12 +237,10 @@ void __attribute__((noreturn)) imx_system_reset(void) void __attribute__((noreturn)) imx_system_off(void) { - /* - * Never return, no SCFW API is available for - * system poweroff, here just do wfi for now - */ - while (1) - wfi(); + sc_pm_set_sys_power_mode(ipc_handle, SC_PM_PW_MODE_OFF); + wfi(); + ERROR("Power off failed.\n"); + panic(); } static const plat_psci_ops_t imx_plat_psci_ops = { diff --git a/plat/imx/imx8qxp/imx8qxp_psci.c b/plat/imx/imx8qxp/imx8qxp_psci.c index 0eb89ba5..9957bfe8 100644 --- a/plat/imx/imx8qxp/imx8qxp_psci.c +++ b/plat/imx/imx8qxp/imx8qxp_psci.c @@ -193,12 +193,10 @@ void __attribute__((noreturn)) imx_system_reset(void) void __attribute__((noreturn)) imx_system_off(void) { - /* - * Never return, no SCFW API is available for - * system poweroff, here just do wfi for now - */ - while (1) - wfi(); + sc_pm_set_sys_power_mode(ipc_handle, SC_PM_PW_MODE_OFF); + wfi(); + ERROR("power off failed.\n"); + panic(); } static const plat_psci_ops_t imx_plat_psci_ops = { |