This is a fix for errata E11171 described here: https://www.nxp.com/docs/en/errata/IMX8MDQLQ_0N14W.pdf
By writing the per-core corresponding bits in GPC register CPU_PGC_UP_TRG, we're able to wake up independently each core.
Signed-off-by: Abel Vesa abel.vesa@nxp.com --- plat/imx/imx8m/imx8mq/gpc.c | 7 +++++++ plat/imx/imx8m/imx8mq/imx8mq_psci.c | 8 ++++++++ plat/imx/imx8m/include/gpc.h | 2 ++ 3 files changed, 17 insertions(+)
diff --git a/plat/imx/imx8m/imx8mq/gpc.c b/plat/imx/imx8m/imx8mq/gpc.c index 02c640b..3eb3efc 100644 --- a/plat/imx/imx8m/imx8mq/gpc.c +++ b/plat/imx/imx8m/imx8mq/gpc.c @@ -26,6 +26,13 @@ void imx_set_cpu_pwr_off(unsigned int core_id) mmio_setbits_32(IMX_GPC_BASE + COREx_PGC_PCR(core_id), 0x1); };
+/* wake up the core */ +void imx_wake_cpu(unsigned int core_id) +{ + /* assert the power up bit for the specific core */ + mmio_setbits_32(IMX_GPC_BASE + CPU_PGC_UP_TRG, COREx_A53_SW_PUP_REQ(core_id)); +} + /* if out of lpm, we need to do reverse steps */ void imx_set_cpu_lpm(unsigned int core_id, bool pdn) { diff --git a/plat/imx/imx8m/imx8mq/imx8mq_psci.c b/plat/imx/imx8m/imx8mq/imx8mq_psci.c index 04e191f..84699cd 100644 --- a/plat/imx/imx8m/imx8mq/imx8mq_psci.c +++ b/plat/imx/imx8m/imx8mq/imx8mq_psci.c @@ -95,6 +95,13 @@ void imx_domain_suspend_finish(const psci_power_state_t *target_state) } }
+int imx_pwr_domain_pwr_down_wfi_wakeup(unsigned int index) +{ + imx_wake_cpu(index); + + return 0; +} + void imx_get_sys_suspend_power_state(psci_power_state_t *req_state) { unsigned int i; @@ -115,6 +122,7 @@ static const plat_psci_ops_t imx_plat_psci_ops = { .pwr_domain_suspend = imx_domain_suspend, .pwr_domain_suspend_finish = imx_domain_suspend_finish, .pwr_domain_pwr_down_wfi = imx_pwr_domain_pwr_down_wfi, + .pwr_domain_pwr_down_wfi_wakeup = imx_pwr_domain_pwr_down_wfi_wakeup, .get_sys_suspend_power_state = imx_get_sys_suspend_power_state, .system_reset = imx_system_reset, .system_off = imx_system_off, diff --git a/plat/imx/imx8m/include/gpc.h b/plat/imx/imx8m/include/gpc.h index 139132c..a51eef6 100644 --- a/plat/imx/imx8m/include/gpc.h +++ b/plat/imx/imx8m/include/gpc.h @@ -86,6 +86,7 @@ #define COREx_LPM_PUP(core_id) ((core_id) < 2 ? (1 << ((core_id) * 2 + 9)) : (1 << ((core_id) * 2 + 21))) #define SLTx_CFG(n) ((SLT0_CFG + ((n) * 4))) #define SLT_COREx_PUP(core_id) (0x2 << ((core_id) * 2)) +#define COREx_A53_SW_PUP_REQ(core_id) (1 << core_id)
#define IRQ_IMR_NUM 4 #define IMR_MASK_ALL 0xffffffff @@ -95,6 +96,7 @@ void imx_gpc_init(void); void imx_set_cpu_secure_entry(unsigned int core_index, uintptr_t sec_entrypoint); void imx_set_cpu_pwr_off(unsigned int core_index); void imx_set_cpu_pwr_on(unsigned int core_index); +void imx_wake_cpu(unsigned int core_id); void imx_set_cpu_lpm(unsigned int core_index, bool pdn); void imx_set_cluster_standby(bool retention); void imx_set_cluster_powerdown(unsigned int last_core, uint8_t power_state);