diff options
author | Neal Frager | 2022-05-04 09:12:26 +0200 |
---|---|---|
committer | Michal Simek | 2022-05-18 13:17:18 +0200 |
commit | 67bdaa016514f020b717a3ba350696ded44a10a3 (patch) | |
tree | d953633ed4777448bf9c151a45dd23b34317a49c /arch | |
parent | 2946c551f1d873f40187c042d0c9306e7fef27c5 (diff) |
arm64: zynqmp: Fix split mode reset functionality
This patch fixes two issues in the set_r5_reset function.
1. When in split mode, the lpd_amba_rst bit should only be set when
both r5 cpu cores are in reset. Otherwise, if one r5 core is still
running, setting the lpd_amba_rst bit will cause an error for the
running core. The set_r5_reset function has been modified to check
if the other r5 core is still running before setting the lpd_amba_rst
bit.
2. The cpu_disable function was always assuming that the r5 cores
are in split mode when resetting either core 4 or 5. This is
incorrect for lockstep functionality. This patch adds a function
check_r5_mode to handle the cpu_disable function correctly for
the r5 cores by checking the mode and handling the reset appropriately.
Signed-off-by: Neal Frager <neal.frager@amd.com>
Signed-off-by: Michal Simek <michal.simek@amd.com>
Link: https://lore.kernel.org/r/d99cbd7f2394ac055ef27457298f554ff0747ba7.1651648344.git.michal.simek@amd.com
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-zynqmp/mp.c | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/arch/arm/mach-zynqmp/mp.c b/arch/arm/mach-zynqmp/mp.c index 704520e7a3c..4f1ed44afb6 100644 --- a/arch/arm/mach-zynqmp/mp.c +++ b/arch/arm/mach-zynqmp/mp.c @@ -102,13 +102,21 @@ static void set_r5_reset(u32 nr, u8 mode) u32 tmp; tmp = readl(&crlapb_base->rst_lpd_top); - if (mode == LOCK || nr == ZYNQMP_CORE_RPU0) - tmp |= (ZYNQMP_CRLAPB_RST_LPD_AMBA_RST_MASK | - ZYNQMP_CRLAPB_RST_LPD_R50_RST_MASK); - - if (mode == LOCK || nr == ZYNQMP_CORE_RPU1) + if (mode == LOCK) { tmp |= (ZYNQMP_CRLAPB_RST_LPD_AMBA_RST_MASK | + ZYNQMP_CRLAPB_RST_LPD_R50_RST_MASK | ZYNQMP_CRLAPB_RST_LPD_R51_RST_MASK); + } else { + if (nr == ZYNQMP_CORE_RPU0) { + tmp |= ZYNQMP_CRLAPB_RST_LPD_R50_RST_MASK; + if (tmp & ZYNQMP_CRLAPB_RST_LPD_R51_RST_MASK) + tmp |= ZYNQMP_CRLAPB_RST_LPD_AMBA_RST_MASK; + } else { + tmp |= ZYNQMP_CRLAPB_RST_LPD_R51_RST_MASK; + if (tmp & ZYNQMP_CRLAPB_RST_LPD_R50_RST_MASK) + tmp |= ZYNQMP_CRLAPB_RST_LPD_AMBA_RST_MASK; + } + } writel(tmp, &crlapb_base->rst_lpd_top); } @@ -142,6 +150,17 @@ static void enable_clock_r5(void) udelay(0x500); } +static int check_r5_mode(void) +{ + u32 tmp; + + tmp = readl(&rpu_base->rpu_glbl_ctrl); + if (tmp & ZYNQMP_RPU_GLBL_CTRL_SPLIT_LOCK_MASK) + return SPLIT; + + return LOCK; +} + int cpu_disable(u32 nr) { if (nr >= ZYNQMP_CORE_APU0 && nr <= ZYNQMP_CORE_APU3) { @@ -149,7 +168,7 @@ int cpu_disable(u32 nr) val |= 1 << nr; writel(val, &crfapb_base->rst_fpd_apu); } else { - set_r5_reset(nr, SPLIT); + set_r5_reset(nr, check_r5_mode()); } return 0; |