aboutsummaryrefslogtreecommitdiffstats
path: root/plat/imx/imx8m
diff options
context:
space:
mode:
authorJacky Bai <ping.bai@nxp.com>2020-01-07 11:05:22 +0800
committerManish Pandey <manish.pandey2@arm.com>2020-08-20 14:23:19 +0000
commitfe5e1c145a43f4a07c306535e3f295d88f5a5ec9 (patch)
tree110ed9125f710b68b2f917ca42137e4e157a8c79 /plat/imx/imx8m
parent15e54af35de4a107c05ebd987ed57a3dccb5ff94 (diff)
downloadplatform_external_arm-trusted-firmware-fe5e1c145a43f4a07c306535e3f295d88f5a5ec9.tar.gz
platform_external_arm-trusted-firmware-fe5e1c145a43f4a07c306535e3f295d88f5a5ec9.tar.bz2
platform_external_arm-trusted-firmware-fe5e1c145a43f4a07c306535e3f295d88f5a5ec9.zip
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: Jacky Bai <ping.bai@nxp.com> Change-Id: I1296592e05fa78429c3f0fac066951521db755e3
Diffstat (limited to 'plat/imx/imx8m')
-rw-r--r--plat/imx/imx8m/gpc_common.c17
-rw-r--r--plat/imx/imx8m/imx8mq/gpc.c9
-rw-r--r--plat/imx/imx8m/include/gpc.h2
3 files changed, 28 insertions, 0 deletions
diff --git a/plat/imx/imx8m/gpc_common.c b/plat/imx/imx8m/gpc_common.c
index babcecff0..1e55f058d 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_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);
}
/*
diff --git a/plat/imx/imx8m/imx8mq/gpc.c b/plat/imx/imx8m/imx8mq/gpc.c
index 942ae459c..367c9411d 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 @@ 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)
diff --git a/plat/imx/imx8m/include/gpc.h b/plat/imx/imx8m/include/gpc.h
index 6f86e1d6b..075da91b1 100644
--- a/plat/imx/imx8m/include/gpc.h
+++ b/plat/imx/imx8m/include/gpc.h
@@ -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);