diff --git a/plat/imx/imx8m/gpc_common.c b/plat/imx/imx8m/gpc_common.c index babcecf..1e55f05 100644 --- a/plat/imx/imx8m/gpc_common.c +++ b/plat/imx/imx8m/gpc_common.c @@ -18,6 +18,8 @@ static uint32_t gpc_imr_offset[] = { IMR1_CORE0_A53, IMR1_CORE1_A53, IMR1_CORE2_A53, IMR1_CORE3_A53, }; +DEFINE_BAKERY_LOCK(gpc_lock); + #pragma weak imx_set_cpu_pwr_off #pragma weak imx_set_cpu_pwr_on #pragma weak imx_set_cpu_lpm @@ -38,16 +40,27 @@ void imx_set_cpu_pwr_off(unsigned int core_id) { + + bakery_lock_get(&gpc_lock); + /* enable the wfi power down of the core */ mmio_setbits_32(IMX_GPC_BASE + LPCR_A53_AD, COREx_WFI_PDN(core_id)); + + bakery_lock_release(&gpc_lock); + /* assert the pcg pcr bit of the core */ mmio_setbits_32(IMX_GPC_BASE + COREx_PGC_PCR(core_id), 0x1); } void imx_set_cpu_pwr_on(unsigned int core_id) { + bakery_lock_get(&gpc_lock); + /* clear the wfi power down bit of the core */ mmio_clrbits_32(IMX_GPC_BASE + LPCR_A53_AD, COREx_WFI_PDN(core_id)); + + bakery_lock_release(&gpc_lock); + /* assert the ncpuporeset */ mmio_clrbits_32(IMX_SRC_BASE + SRC_A53RCR1, (1 << core_id)); /* assert the pcg pcr bit of the core */ @@ -67,6 +80,8 @@ void imx_set_cpu_lpm(unsigned int core_id, bool pdn) { + bakery_lock_get(&gpc_lock); + if (pdn) { /* enable the core WFI PDN & IRQ PUP */ mmio_setbits_32(IMX_GPC_BASE + LPCR_A53_AD, COREx_WFI_PDN(core_id) | @@ -80,6 +95,8 @@ /* deassert the pcg pcr bit of the core */ mmio_clrbits_32(IMX_GPC_BASE + COREx_PGC_PCR(core_id), 0x1); } + + bakery_lock_release(&gpc_lock); } /* diff --git a/plat/imx/imx8m/imx8mq/gpc.c b/plat/imx/imx8m/imx8mq/gpc.c index 942ae45..367c941 100644 --- a/plat/imx/imx8m/imx8mq/gpc.c +++ b/plat/imx/imx8m/imx8mq/gpc.c @@ -19,9 +19,14 @@ /* use wfi power down the core */ void imx_set_cpu_pwr_off(unsigned int core_id) { + bakery_lock_get(&gpc_lock); + /* enable the wfi power down of the core */ mmio_setbits_32(IMX_GPC_BASE + LPCR_A53_AD, COREx_WFI_PDN(core_id) | (1 << (core_id + 20))); + + bakery_lock_release(&gpc_lock); + /* assert the pcg pcr bit of the core */ mmio_setbits_32(IMX_GPC_BASE + COREx_PGC_PCR(core_id), 0x1); }; @@ -29,6 +34,8 @@ /* if out of lpm, we need to do reverse steps */ void imx_set_cpu_lpm(unsigned int core_id, bool pdn) { + bakery_lock_get(&gpc_lock); + if (pdn) { /* enable the core WFI PDN & IRQ PUP */ mmio_setbits_32(IMX_GPC_BASE + LPCR_A53_AD, COREx_WFI_PDN(core_id) | @@ -42,6 +49,8 @@ /* deassert the pcg pcr bit of the core */ mmio_setbits_32(IMX_GPC_BASE + COREx_PGC_PCR(core_id), 0x1); } + + bakery_lock_release(&gpc_lock); } void imx_pup_pdn_slot_config(int last_core, bool pdn) diff --git a/plat/imx/imx8m/include/gpc.h b/plat/imx/imx8m/include/gpc.h index 6f86e1d..075da91 100644 --- a/plat/imx/imx8m/include/gpc.h +++ b/plat/imx/imx8m/include/gpc.h @@ -54,6 +54,8 @@ bool always_on; }; +DECLARE_BAKERY_LOCK(gpc_lock); + /* function declare */ void imx_gpc_init(void); void imx_set_cpu_secure_entry(unsigned int core_index, uintptr_t sec_entrypoint);