summaryrefslogtreecommitdiff
path: root/plat/imx/imx8mq
diff options
context:
space:
mode:
authorBai Ping <ping.bai@nxp.com>2017-11-10 16:08:05 +0800
committerAbel Vesa <abel.vesa@nxp.com>2018-06-11 10:08:40 +0300
commit16e7edea57819a2802a528135b1d8f56a2e85bbd (patch)
tree50d2cfc282a92316764301f5f85ca780e635321f /plat/imx/imx8mq
parent34fbf7a35c83c879a0ca385b0200858641ca37b4 (diff)
plat: imx8mq: fix the system wakeup by non-wakeup IRQ.
When system enter suspend, it should be only wakeup by specific wakeup source, so non-wakeup source should be masked before enter suspend. Signed-off-by: Bai Ping <ping.bai@nxp.com>
Diffstat (limited to 'plat/imx/imx8mq')
-rw-r--r--plat/imx/imx8mq/gpc.c65
-rw-r--r--plat/imx/imx8mq/include/soc.h1
2 files changed, 39 insertions, 27 deletions
diff --git a/plat/imx/imx8mq/gpc.c b/plat/imx/imx8mq/gpc.c
index 3da8aadf..4daa89eb 100644
--- a/plat/imx/imx8mq/gpc.c
+++ b/plat/imx/imx8mq/gpc.c
@@ -82,10 +82,9 @@
#define GPC_SLOT0_CFG 0xb0
#define SRC_GPR1_OFFSET 0x74
-static uint32_t gpc_saved_imrs[4];
-static uint32_t gpc_wake_irqs[4];
static bool is_pcie1_power_down = true;
-
+static uint32_t gpc_saved_imrs[16];
+static uint32_t gpc_wake_irqs[4];
static uint32_t gpc_pu_m_core_offset[11] = {
0xc00, 0xc40, 0xc80, 0xcc0,
0xdc0, 0xe00, 0xe40, 0xe80,
@@ -206,6 +205,40 @@ void imx_set_cpu_lpm(int core_id, bool pdn)
}
}
+/*
+ * On i.MX8MQ, only in system suspend mode, the A53 cluster can
+ * enter LPM mode and shutdown the A53 PLAT power domain. So LPM
+ * wakeup only used for system suspend. when system enter suspend,
+ * any A53 CORE can be the last core to suspend the system, But
+ * the LPM wakeup can only use the C0's IMR to wakeup A53 cluster
+ * from LPM, so save C0's IMRs before suspend, restore back after
+ * resume.
+ */
+void inline imx_set_lpm_wakeup(bool pdn)
+{
+ unsigned int i;
+
+ if (pdn) {
+ for (i = 0; i < 4; i++) {
+ gpc_saved_imrs[i] = mmio_read_32(IMX_GPC_BASE + GPC_IMR1_CORE0_A53 + i * 4);
+ gpc_saved_imrs[i + 4] = mmio_read_32(IMX_GPC_BASE + GPC_IMR1_CORE1_A53 + i * 4);
+ gpc_saved_imrs[i + 8] = mmio_read_32(IMX_GPC_BASE + GPC_IMR1_CORE2_A53 + i * 4);
+ gpc_saved_imrs[i + 12] = mmio_read_32(IMX_GPC_BASE + GPC_IMR1_CORE3_A53 + i * 4);
+ mmio_write_32(IMX_GPC_BASE + GPC_IMR1_CORE0_A53 + i * 4, ~gpc_wake_irqs[i]);
+ mmio_write_32(IMX_GPC_BASE + GPC_IMR1_CORE1_A53 + i * 4, ~gpc_wake_irqs[i]);
+ mmio_write_32(IMX_GPC_BASE + GPC_IMR1_CORE2_A53 + i * 4, ~gpc_wake_irqs[i]);
+ mmio_write_32(IMX_GPC_BASE + GPC_IMR1_CORE3_A53 + i * 4, ~gpc_wake_irqs[i]);
+ }
+ } else {
+ for (i = 0; i < 4; i++) {
+ mmio_write_32(IMX_GPC_BASE + GPC_IMR1_CORE0_A53 + i * 4, gpc_saved_imrs[i]);
+ mmio_write_32(IMX_GPC_BASE + GPC_IMR1_CORE1_A53 + i * 4, gpc_saved_imrs[i + 4]);
+ mmio_write_32(IMX_GPC_BASE + GPC_IMR1_CORE2_A53 + i * 4, gpc_saved_imrs[i + 8]);
+ mmio_write_32(IMX_GPC_BASE + GPC_IMR1_CORE3_A53 + i * 4, gpc_saved_imrs[i + 12]);
+ }
+ }
+}
+
/* SLOT 0 is used for A53 PLAT poewr down */
/* SLOT 1 is used for A53 PLAT power up */
/* SLOT 2 is used for A53 last core power up */
@@ -305,6 +338,7 @@ void imx_set_cluster_powerdown(int last_core, bool pdn)
mmio_write_32(IMX_GPC_BASE + LPCR_A53_AD, val);
imx_pup_pdn_slot_config(last_core, true);
+ imx_set_lpm_wakeup(true);
/* enable PLAT PGC */
val = mmio_read_32(IMX_GPC_BASE + 0x900);
@@ -318,6 +352,7 @@ void imx_set_cluster_powerdown(int last_core, bool pdn)
/* clear the slot and ack for cluster power down */
imx_pup_pdn_slot_config(last_core, false);
+ imx_set_lpm_wakeup(false);
/* reverse the cluster level setting */
val = mmio_read_32(IMX_GPC_BASE + LPCR_A53_BSC);
@@ -440,30 +475,6 @@ void imx_anamix_post_resume(void)
mmio_read_32(IMX_ANAMIX_BASE + ANAMIX_HW_ANAMIX_MISC_CFG) & ~0xa);
}
-/*
- * On i.MX8MQ, only in system suspend mode, the A53 cluster can
- * enter LPM mode and shutdown the A53 PLAT power domain. So LPM
- * wakeup only used for system suspend. when system enter suspend,
- * any A53 CORE can be the last core to suspend the system, But
- * the LPM wakeup can only use the C0's IMR to wakeup A53 cluster
- * from LPM, so save C0's IMRs before suspend, restore back after
- * resume.
- */
-void imx_set_lpm_wakeup(bool pdn)
-{
- unsigned int i;
-
- if (pdn) {
- for (i = 0; i < 4; i++) {
- gpc_saved_imrs[i] = mmio_read_32(IMX_GPC_BASE + GPC_IMR1_CORE0_A53 + i * 4);
- mmio_write_32(IMX_GPC_BASE + GPC_IMR1_CORE0_A53 + i * 4, ~gpc_wake_irqs[i]);
- }
- } else {
- for (i = 0; i < 4; i++)
- mmio_write_32(IMX_GPC_BASE + GPC_IMR1_CORE0_A53 + i * 4, gpc_saved_imrs[i]);
- }
-}
-
static void imx_gpc_hwirq_mask(unsigned int hwirq)
{
uintptr_t reg;
diff --git a/plat/imx/imx8mq/include/soc.h b/plat/imx/imx8mq/include/soc.h
index af6fc09e..d2d3b270 100644
--- a/plat/imx/imx8mq/include/soc.h
+++ b/plat/imx/imx8mq/include/soc.h
@@ -16,6 +16,7 @@ void imx_set_cpu_secure_entry(int cpu_id, uintptr_t sec_entrypoint);
void imx_set_cpu_pwr_off(int cpu_id);
void imx_set_cpu_pwr_on(int cpu_id);
void imx_set_cpu_lpm(int cpu_id, bool pdn);
+void imx_set_lpm_wakeup(bool pdn);
void imx_set_cluster_standby(bool pdn);
void imx_set_cluster_powerdown(int last_core, bool pdn);
void imx_set_sys_lpm(bool retention);