Commit fe5e1c14 authored by Jacky Bai's avatar Jacky Bai Committed by Manish Pandey
Browse files

plat: imx8m: Fix the race condition during cpu hotplug



CPU hotplug & cpuidle have some race condition when doing CPU hotplug
stress test. different CPU cores have the chance to access the same
GPC register(A53_AD), so lock is necessary to do exlusive access.
Signed-off-by: default avatarJacky Bai <ping.bai@nxp.com>
Change-Id: I1296592e05fa78429c3f0fac066951521db755e3
parent 15e54af3
......@@ -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_secure_entry(unsigned int core_id, uintptr_t sec_entrypoint)
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_pwr_on(unsigned int core_id)
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 @@ void imx_set_cpu_lpm(unsigned int core_id, bool pdn)
/* 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);
}
/*
......
......@@ -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 @@ void imx_set_cpu_pwr_off(unsigned int core_id)
/* 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 @@ void imx_set_cpu_lpm(unsigned int core_id, bool pdn)
/* 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)
......
......@@ -54,6 +54,8 @@ struct imx_pwr_domain {
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);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment