diff --git a/plat/imx/imx8mn/gpc.c b/plat/imx/imx8mn/gpc.c index eb713e39250609fb70383c3d0ae35c69ce39988e..82dcacd7807e73d5cd5abd81d25161557513eb9d 100644 --- a/plat/imx/imx8mn/gpc.c +++ b/plat/imx/imx8mn/gpc.c @@ -462,7 +462,7 @@ void imx_set_rbc_count(void) val = mmio_read_32(IMX_GPC_BASE + SLPCR); val |= SLPCR_RBC_EN; - val |= (0x8 << SLPCR_RBC_SHIFT); + val |= (0xa << SLPCR_RBC_SHIFT); mmio_write_32(IMX_GPC_BASE + SLPCR, val); } diff --git a/plat/imx/imx8mn/imx8mn_psci.c b/plat/imx/imx8mn/imx8mn_psci.c index f558ff5c8157905dd4e2c409f613dee0012900ce..5df2acc87ac8ce9143b48490eed4400aeb52be45 100644 --- a/plat/imx/imx8mn/imx8mn_psci.c +++ b/plat/imx/imx8mn/imx8mn_psci.c @@ -13,6 +13,7 @@ #include #include #include +#include #define SNVS_LPCR 0x38 @@ -143,15 +144,16 @@ void imx_domain_suspend_finish(const psci_power_state_t *target_state) /* clear the system wakeup setting */ imx_set_sys_wakeup(core_id, false); imx_anamix_post_resume(); - imx_clear_rbc_count(); if (!imx_is_m4_enabled() || !imx_m4_lpa_active()) dram_exit_retention(); noc_wrapper_post_resume(core_id); } /* check the cluster level power status */ - if (!is_local_state_run(CLUSTER_PWR_STATE(target_state))) + if (!is_local_state_run(CLUSTER_PWR_STATE(target_state))) { + imx_clear_rbc_count(); imx_set_cluster_powerdown(core_id, PSCI_LOCAL_STATE_RUN); + } /* check the core level power status */ if (is_local_state_off(CORE_PWR_STATE(target_state))) { @@ -207,8 +209,17 @@ void __dead2 imx_system_off(void) void __dead2 imx_pwr_domain_pwr_down_wfi(const psci_power_state_t *target_state) { - if (is_local_state_off(CLUSTER_PWR_STATE(target_state))) { + /* + * before enter WAIT or STOP mode with PLAT(SCU) power down, + * rbc count need to be enabled to make sure PLAT is + * power down successfully even if the the wakeup IRQ is pending + * early before the power down sequence. the RBC counter is + * drived by the 32K OSC, so delay 30us to make sure the counter + * is really running. + */ + if (!is_local_state_run(CLUSTER_PWR_STATE(target_state))) { imx_set_rbc_count(); + udelay(30); } while (1)