diff mbox series

arm64: zynqmp: Fix split mode reset functionality

Message ID d99cbd7f2394ac055ef27457298f554ff0747ba7.1651648344.git.michal.simek@amd.com
State Accepted
Commit 67bdaa016514f020b717a3ba350696ded44a10a3
Delegated to: Michal Simek
Headers show
Series arm64: zynqmp: Fix split mode reset functionality | expand

Commit Message

Michal Simek May 4, 2022, 7:12 a.m. UTC
From: Neal Frager <neal.frager@amd.com>

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>
---

 arch/arm/mach-zynqmp/mp.c | 31 +++++++++++++++++++++++++------
 1 file changed, 25 insertions(+), 6 deletions(-)

Comments

Michal Simek May 16, 2022, 12:01 p.m. UTC | #1
st 4. 5. 2022 v 9:12 odesílatel Michal Simek <monstr@monstr.eu> napsal:
>
> From: Neal Frager <neal.frager@amd.com>
>
> 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>
> ---
>
>  arch/arm/mach-zynqmp/mp.c | 31 +++++++++++++++++++++++++------
>  1 file changed, 25 insertions(+), 6 deletions(-)
>
> diff --git a/arch/arm/mach-zynqmp/mp.c b/arch/arm/mach-zynqmp/mp.c
> index 704520e7a3c9..4f1ed44afb6b 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;
> --
> 2.36.0
>

Applied,
Michal
diff mbox series

Patch

diff --git a/arch/arm/mach-zynqmp/mp.c b/arch/arm/mach-zynqmp/mp.c
index 704520e7a3c9..4f1ed44afb6b 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;