diff options
author | Anson Huang <Anson.Huang@nxp.com> | 2018-06-19 11:16:33 +0800 |
---|---|---|
committer | Abel Vesa <abel.vesa@nxp.com> | 2018-06-20 16:30:39 +0300 |
commit | 959392911781f3bd4263a01d703097998d0aaa0f (patch) | |
tree | 2afff8fb6bfc141f0a75bc90feb290d76d50db63 | |
parent | 76673d693f8cdadb776e0c89df5d1c6902f47d47 (diff) |
imx8qxp: support SC_R_IRQSTR_SCU2 OFF in system suspend
SC_R_IRQSTR_SCU2 can be OFF in system suspend if there
is no wakeup irq enabled from non-secure OS partion.
Add wakeup source check to decide if turning off
SC_R_IRQSTR_SCU2 or NOT when suspend.
Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
-rw-r--r-- | plat/imx/common/include/fsl_sip.h | 4 | ||||
-rw-r--r-- | plat/imx/common/sip_svc.c | 27 | ||||
-rw-r--r-- | plat/imx/imx8qxp/imx8qxp_psci.c | 17 |
3 files changed, 44 insertions, 4 deletions
diff --git a/plat/imx/common/include/fsl_sip.h b/plat/imx/common/include/fsl_sip.h index 24b8eb31..004349c1 100644 --- a/plat/imx/common/include/fsl_sip.h +++ b/plat/imx/common/include/fsl_sip.h @@ -48,4 +48,8 @@ #define FSL_SIP_NOC 0xc2000008 #define FSL_SIP_NOC_LCDIF 0x0 +#define FSL_SIP_WAKEUP_SRC 0xc2000009 +#define FSL_SIP_WAKEUP_SRC_SCU 0x1 +#define FSL_SIP_WAKEUP_SRC_IRQSTEER 0x2 + #endif diff --git a/plat/imx/common/sip_svc.c b/plat/imx/common/sip_svc.c index 02728556..bf774722 100644 --- a/plat/imx/common/sip_svc.c +++ b/plat/imx/common/sip_svc.c @@ -11,6 +11,7 @@ #include <smcc_helpers.h> #include <std_svc.h> #include <stdint.h> +#include <stdbool.h> #include <uuid.h> #include <string.h> #include <bl_common.h> @@ -25,6 +26,8 @@ extern int imx_soc_handler(uint32_t smc_fid, u_register_t x1, u_register_t x2, u extern int imx_hab_handler(uint32_t smc_fid, u_register_t x1, u_register_t x2, u_register_t x3, u_register_t x4); extern int imx_noc_handler(uint32_t smc_fid, u_register_t x1, u_register_t x2, u_register_t x3); +bool wakeup_src_irqsteer = false; + /* Setup i.MX platform specific services Services */ static int32_t plat_svc_setup(void) { @@ -76,6 +79,27 @@ uint64_t imx_buildinfo_handler(uint32_t smc_fid, return ret; } +int imx_wakeup_src_handler(uint32_t smc_fid, + u_register_t x1, + u_register_t x2, + u_register_t x3) +{ + uint64_t ret; + + switch(x1) { + case FSL_SIP_WAKEUP_SRC_IRQSTEER: + wakeup_src_irqsteer = true; + break; + case FSL_SIP_WAKEUP_SRC_SCU: + wakeup_src_irqsteer = false; + break; + default: + return SMC_UNK; + } + + return ret; +} + /* i.MX platform specific service SMC handler */ uintptr_t imx_svc_smc_handler(uint32_t smc_fid, @@ -116,6 +140,9 @@ uintptr_t imx_svc_smc_handler(uint32_t smc_fid, break; case FSL_SIP_SRTC: return imx_srtc_handler(smc_fid, handle, x1, x2, x3, x4); + case FSL_SIP_WAKEUP_SRC: + SMC_RET1(handle, imx_wakeup_src_handler(smc_fid, x1, x2, x3)); + break; #endif case FSL_SIP_BUILDINFO: SMC_RET1(handle, imx_buildinfo_handler(smc_fid, x1, x2, x3, x4)); diff --git a/plat/imx/imx8qxp/imx8qxp_psci.c b/plat/imx/imx8qxp/imx8qxp_psci.c index 9d0600ff..8705b9ac 100644 --- a/plat/imx/imx8qxp/imx8qxp_psci.c +++ b/plat/imx/imx8qxp/imx8qxp_psci.c @@ -17,6 +17,7 @@ extern sc_ipc_t ipc_handle; extern void mdelay(uint32_t msec); +extern bool wakeup_src_irqsteer; /* save gic dist/redist context when GIC is power down */ static struct plat_gic_ctx imx_gicv3_ctx; @@ -49,8 +50,11 @@ static void imx_enable_irqstr_wakeup(void) mmio_write_32(IMX_WUP_IRQSTR + 0x3c - 0x4 * i, irq_mask); } - /* put IRQSTR into STBY mode */ - sc_pm_set_resource_power_mode(ipc_handle, SC_R_IRQSTR_SCU2, SC_PM_PW_MODE_STBY); + /* set IRQSTR low power mode */ + if (wakeup_src_irqsteer) + sc_pm_set_resource_power_mode(ipc_handle, SC_R_IRQSTR_SCU2, SC_PM_PW_MODE_STBY); + else + sc_pm_set_resource_power_mode(ipc_handle, SC_R_IRQSTR_SCU2, SC_PM_PW_MODE_OFF); } static void imx_disable_irqstr_wakeup(void) @@ -189,9 +193,14 @@ void imx_domain_suspend(const psci_power_state_t *target_state) /* Put GIC in OFF mode. */ sc_pm_set_resource_power_mode(ipc_handle, SC_R_GIC, SC_PM_PW_MODE_OFF); - sc_pm_set_cpu_resume_addr(ipc_handle, ap_core_index[cpu_id], 0x080000000); - sc_pm_req_cpu_low_power_mode(ipc_handle, ap_core_index[cpu_id], SC_PM_PW_MODE_OFF, SC_PM_WAKE_SRC_IRQSTEER); + if (wakeup_src_irqsteer) + sc_pm_req_cpu_low_power_mode(ipc_handle, ap_core_index[cpu_id], + SC_PM_PW_MODE_OFF, SC_PM_WAKE_SRC_IRQSTEER); + else + sc_pm_req_cpu_low_power_mode(ipc_handle, ap_core_index[cpu_id], + SC_PM_PW_MODE_OFF, SC_PM_WAKE_SRC_SCU); + } void imx_domain_suspend_finish(const psci_power_state_t *target_state) |