summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnson Huang <Anson.Huang@nxp.com>2018-06-19 11:16:33 +0800
committerAbel Vesa <abel.vesa@nxp.com>2018-06-20 16:30:39 +0300
commit959392911781f3bd4263a01d703097998d0aaa0f (patch)
tree2afff8fb6bfc141f0a75bc90feb290d76d50db63
parent76673d693f8cdadb776e0c89df5d1c6902f47d47 (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.h4
-rw-r--r--plat/imx/common/sip_svc.c27
-rw-r--r--plat/imx/imx8qxp/imx8qxp_psci.c17
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)