summaryrefslogtreecommitdiff
path: root/plat
diff options
context:
space:
mode:
authorRobin Gong <yibin.gong@nxp.com>2017-11-29 19:26:44 +0800
committerAbel Vesa <abel.vesa@nxp.com>2018-06-11 10:08:40 +0300
commit1fff21f4d6a3314c8d8f181822bc8b2dcc1d61a6 (patch)
tree5b068105af3f6bd9aca13eee7ffa2899029659a5 /plat
parentf4ec82775b77039912e0b369e808a49bfad7b9c4 (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.h21
-rw-r--r--plat/imx/common/sci/svc/pm/pm_rpc_clnt.c19
-rw-r--r--plat/imx/common/sci/svc/pm/rpc.h3
-rw-r--r--plat/imx/imx8qm/imx8qm_psci.c10
-rw-r--r--plat/imx/imx8qxp/imx8qxp_psci.c10
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 = {