public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
* [PATCH v4 0/4] Allwinner R528/T113s PSCI
@ 2023-10-12  1:47 Sam Edwards
  2023-10-12  1:47 ` [PATCH v4 1/4] sunxi: psci: clean away preprocessor macros Sam Edwards
                   ` (4 more replies)
  0 siblings, 5 replies; 9+ messages in thread
From: Sam Edwards @ 2023-10-12  1:47 UTC (permalink / raw)
  To: u-boot, Andre Przywara, Jagan Teki
  Cc: Samuel Holland, Jernej Skrabec, Icenowy Zheng, Maksim Kiselev,
	Sam Edwards

Hi list,

This is the third, and hopefully final, version of my patchset for PSCI support
on R528/T113-s3. This one, as always, depends on Andre Przywara's T113s support
series (v2), available on the list and also located on a Git branch at:
https://source.denx.de/u-boot/custodians/u-boot-sunxi.git t113s-v2

NOTE THAT THIS ALSO depends on the following commit on master:
3d5e52bd97 ("ARM: psci: move GIC address override to Kconfig")

For testing: I can confirm that patch 2/4 results in no change to machine code
whatsoever on any supported target. Patch 1/4 results in a minor machine code
change on R40 only. Patch 3/4 will likely require testing on each of the 4
"special case" sunxi targets (sun6i, sun7i, R40, H3) to ensure that register
offsets are kept consistent. Patch 4/4 needs testing on R528 only.

Warm regards,
Sam

Changes v3->v4:
- The GIC base address override is done through Kconfig, instead of in
  sunxi-common.h

Changes v2->v3:
- Fix missing `cpu=0;` for the sun7i power management case.
- Make sunxi_cpu_power_off() a static function, per feedback on v2.
- Kevin Amadiva of MEC electronics got in touch with me off-list, reported
  success bringing up CPU1 of a T113 with this patchset, and kindly provided
  me with a Tested-by tag for patch 4/4.
- Remove a comment about R40/R528 being special, per feedback on v2.
- Simplify an if statement, per feedback on v2.
- Add missing 'select' directives to the R528 Kconfig, per feedback on v2.

Changes v1->v2:
- Power clamp is now adjusted ONLY on sun{6,7}i, H3, R40. The previous version
  was mistakenly doing this EXCEPT on those machines.
- Flattened sunxi_power_switch() into sunxi_cpu_set_power() for simplicity's
  sake.
- Moved the "power clamp is not NULL" conditional into sunxi_cpu_set_power().
- Removed unnecessary H6 special-case, since H6 is actually ARM64.
- Renamed SUNXI_CPUX_BASE to SUNXI_CPUCFG_BASE, to mirror expected changes in
  Andre's v2 of the R528 series (we decided against using a new name for this
  block).
- Removed sunxi_cpucfg_reg struct, and stopped using the PRCM struct in psci.c.

Sam Edwards (4):
  sunxi: psci: clean away preprocessor macros
  sunxi: psci: refactor register access to separate functions
  sunxi: psci: stop modeling register layout with C structs
  sunxi: psci: implement PSCI on R528

 arch/arm/cpu/armv7/Kconfig               |   3 +-
 arch/arm/cpu/armv7/sunxi/psci.c          | 185 ++++++++++++++---------
 arch/arm/include/asm/arch-sunxi/cpucfg.h |  67 --------
 arch/arm/mach-sunxi/Kconfig              |   4 +
 4 files changed, 121 insertions(+), 138 deletions(-)
 delete mode 100644 arch/arm/include/asm/arch-sunxi/cpucfg.h

-- 
2.41.0


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v4 1/4] sunxi: psci: clean away preprocessor macros
  2023-10-12  1:47 [PATCH v4 0/4] Allwinner R528/T113s PSCI Sam Edwards
@ 2023-10-12  1:47 ` Sam Edwards
  2023-10-12  1:47 ` [PATCH v4 2/4] sunxi: psci: refactor register access to separate functions Sam Edwards
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 9+ messages in thread
From: Sam Edwards @ 2023-10-12  1:47 UTC (permalink / raw)
  To: u-boot, Andre Przywara, Jagan Teki
  Cc: Samuel Holland, Jernej Skrabec, Icenowy Zheng, Maksim Kiselev,
	Sam Edwards

This patch restructures psci.c to get away from the "many different
function definitions switched by #ifdef" paradigm to the preferred style
of having a single function definition with `if (IS_ENABLED(...))` to
make the optimizer include only the appropriate function bodies instead.

There are no functional changes here.

Signed-off-by: Sam Edwards <CFSworks@gmail.com>
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
---
 arch/arm/cpu/armv7/sunxi/psci.c | 103 +++++++++++++-------------------
 1 file changed, 43 insertions(+), 60 deletions(-)

diff --git a/arch/arm/cpu/armv7/sunxi/psci.c b/arch/arm/cpu/armv7/sunxi/psci.c
index e1d3638b5c..69fa3f3c2e 100644
--- a/arch/arm/cpu/armv7/sunxi/psci.c
+++ b/arch/arm/cpu/armv7/sunxi/psci.c
@@ -76,11 +76,8 @@ static void __secure __mdelay(u32 ms)
 	isb();
 }
 
-static void __secure clamp_release(u32 __maybe_unused *clamp)
+static void __secure clamp_release(u32 *clamp)
 {
-#if defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN7I) || \
-	defined(CONFIG_MACH_SUN8I_H3) || \
-	defined(CONFIG_MACH_SUN8I_R40)
 	u32 tmp = 0x1ff;
 	do {
 		tmp >>= 1;
@@ -88,83 +85,69 @@ static void __secure clamp_release(u32 __maybe_unused *clamp)
 	} while (tmp);
 
 	__mdelay(10);
-#endif
 }
 
-static void __secure clamp_set(u32 __maybe_unused *clamp)
+static void __secure clamp_set(u32 *clamp)
 {
-#if defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN7I) || \
-	defined(CONFIG_MACH_SUN8I_H3) || \
-	defined(CONFIG_MACH_SUN8I_R40)
 	writel(0xff, clamp);
-#endif
 }
 
-static void __secure sunxi_power_switch(u32 *clamp, u32 *pwroff, bool on,
-					int cpu)
+static void __secure sunxi_set_entry_address(void *entry)
 {
-	if (on) {
-		/* Release power clamp */
-		clamp_release(clamp);
-
-		/* Clear power gating */
-		clrbits_le32(pwroff, BIT(cpu));
+	/* secondary core entry address is programmed differently on R40 */
+	if (IS_ENABLED(CONFIG_MACH_SUN8I_R40)) {
+		writel((u32)entry,
+		       SUNXI_SRAMC_BASE + SUN8I_R40_SRAMC_SOFT_ENTRY_REG0);
 	} else {
-		/* Set power gating */
-		setbits_le32(pwroff, BIT(cpu));
+		struct sunxi_cpucfg_reg *cpucfg =
+			(struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE;
 
-		/* Activate power clamp */
-		clamp_set(clamp);
+		writel((u32)entry, &cpucfg->priv0);
 	}
 }
 
-#ifdef CONFIG_MACH_SUN8I_R40
-/* secondary core entry address is programmed differently on R40 */
-static void __secure sunxi_set_entry_address(void *entry)
-{
-	writel((u32)entry,
-	       SUNXI_SRAMC_BASE + SUN8I_R40_SRAMC_SOFT_ENTRY_REG0);
-}
-#else
-static void __secure sunxi_set_entry_address(void *entry)
+static void __secure sunxi_cpu_set_power(int cpu, bool on)
 {
+	u32 *clamp = NULL;
+	u32 *pwroff;
 	struct sunxi_cpucfg_reg *cpucfg =
 		(struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE;
 
-	writel((u32)entry, &cpucfg->priv0);
-}
-#endif
+	/* sun7i (A20) is different from other single cluster SoCs */
+	if (IS_ENABLED(CONFIG_MACH_SUN7I)) {
+		clamp = &cpucfg->cpu1_pwr_clamp;
+		pwroff = &cpucfg->cpu1_pwroff;
+		cpu = 0;
+	} else if (IS_ENABLED(CONFIG_MACH_SUN8I_R40)) {
+		clamp = (void *)cpucfg + SUN8I_R40_PWR_CLAMP(cpu);
+		pwroff = (void *)cpucfg + SUN8I_R40_PWROFF;
+	} else {
+		struct sunxi_prcm_reg *prcm =
+			(struct sunxi_prcm_reg *)SUNXI_PRCM_BASE;
 
-#ifdef CONFIG_MACH_SUN7I
-/* sun7i (A20) is different from other single cluster SoCs */
-static void __secure sunxi_cpu_set_power(int __always_unused cpu, bool on)
-{
-	struct sunxi_cpucfg_reg *cpucfg =
-		(struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE;
+		if (IS_ENABLED(CONFIG_MACH_SUN6I) ||
+		    IS_ENABLED(CONFIG_MACH_SUN8I_H3))
+			clamp = &prcm->cpu_pwr_clamp[cpu];
 
-	sunxi_power_switch(&cpucfg->cpu1_pwr_clamp, &cpucfg->cpu1_pwroff,
-			   on, 0);
-}
-#elif defined CONFIG_MACH_SUN8I_R40
-static void __secure sunxi_cpu_set_power(int cpu, bool on)
-{
-	struct sunxi_cpucfg_reg *cpucfg =
-		(struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE;
+		pwroff = &prcm->cpu_pwroff;
+	}
 
-	sunxi_power_switch((void *)cpucfg + SUN8I_R40_PWR_CLAMP(cpu),
-			   (void *)cpucfg + SUN8I_R40_PWROFF,
-			   on, cpu);
-}
-#else /* ! CONFIG_MACH_SUN7I && ! CONFIG_MACH_SUN8I_R40 */
-static void __secure sunxi_cpu_set_power(int cpu, bool on)
-{
-	struct sunxi_prcm_reg *prcm =
-		(struct sunxi_prcm_reg *)SUNXI_PRCM_BASE;
+	if (on) {
+		/* Release power clamp */
+		if (clamp)
+			clamp_release(clamp);
 
-	sunxi_power_switch(&prcm->cpu_pwr_clamp[cpu], &prcm->cpu_pwroff,
-			   on, cpu);
+		/* Clear power gating */
+		clrbits_le32(pwroff, BIT(cpu));
+	} else {
+		/* Set power gating */
+		setbits_le32(pwroff, BIT(cpu));
+
+		/* Activate power clamp */
+		if (clamp)
+			clamp_set(clamp);
+	}
 }
-#endif /* CONFIG_MACH_SUN7I */
 
 void __secure sunxi_cpu_power_off(u32 cpuid)
 {
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v4 2/4] sunxi: psci: refactor register access to separate functions
  2023-10-12  1:47 [PATCH v4 0/4] Allwinner R528/T113s PSCI Sam Edwards
  2023-10-12  1:47 ` [PATCH v4 1/4] sunxi: psci: clean away preprocessor macros Sam Edwards
@ 2023-10-12  1:47 ` Sam Edwards
  2023-10-12  1:47 ` [PATCH v4 3/4] sunxi: psci: stop modeling register layout with C structs Sam Edwards
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 9+ messages in thread
From: Sam Edwards @ 2023-10-12  1:47 UTC (permalink / raw)
  To: u-boot, Andre Przywara, Jagan Teki
  Cc: Samuel Holland, Jernej Skrabec, Icenowy Zheng, Maksim Kiselev,
	Sam Edwards

This is to prepare for R528, which does not have the typical
"CPUCFG" block; it has a "CPUX" block which provides these
same functions but is organized differently.

Moving the hardware-access bits to their own functions separates the
logic from the hardware so we can reuse the same logic.

Signed-off-by: Sam Edwards <CFSworks@gmail.com>
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
---
 arch/arm/cpu/armv7/sunxi/psci.c | 66 +++++++++++++++++++++++----------
 1 file changed, 47 insertions(+), 19 deletions(-)

diff --git a/arch/arm/cpu/armv7/sunxi/psci.c b/arch/arm/cpu/armv7/sunxi/psci.c
index 69fa3f3c2e..27ca9c39e1 100644
--- a/arch/arm/cpu/armv7/sunxi/psci.c
+++ b/arch/arm/cpu/armv7/sunxi/psci.c
@@ -92,7 +92,7 @@ static void __secure clamp_set(u32 *clamp)
 	writel(0xff, clamp);
 }
 
-static void __secure sunxi_set_entry_address(void *entry)
+static void __secure sunxi_cpu_set_entry(int __always_unused cpu, void *entry)
 {
 	/* secondary core entry address is programmed differently on R40 */
 	if (IS_ENABLED(CONFIG_MACH_SUN8I_R40)) {
@@ -149,30 +149,60 @@ static void __secure sunxi_cpu_set_power(int cpu, bool on)
 	}
 }
 
-void __secure sunxi_cpu_power_off(u32 cpuid)
+static void __secure sunxi_cpu_set_reset(int cpu, bool reset)
 {
 	struct sunxi_cpucfg_reg *cpucfg =
 		(struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE;
+
+	writel(reset ? 0b00 : 0b11, &cpucfg->cpu[cpu].rst);
+}
+
+static void __secure sunxi_cpu_set_locking(int cpu, bool lock)
+{
+	struct sunxi_cpucfg_reg *cpucfg =
+		(struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE;
+
+	if (lock)
+		clrbits_le32(&cpucfg->dbg_ctrl1, BIT(cpu));
+	else
+		setbits_le32(&cpucfg->dbg_ctrl1, BIT(cpu));
+}
+
+static bool __secure sunxi_cpu_poll_wfi(int cpu)
+{
+	struct sunxi_cpucfg_reg *cpucfg =
+		(struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE;
+
+	return !!(readl(&cpucfg->cpu[cpu].status) & BIT(2));
+}
+
+static void __secure sunxi_cpu_invalidate_cache(int cpu)
+{
+	struct sunxi_cpucfg_reg *cpucfg =
+		(struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE;
+
+	clrbits_le32(&cpucfg->gen_ctrl, BIT(cpu));
+}
+
+static void __secure sunxi_cpu_power_off(u32 cpuid)
+{
 	u32 cpu = cpuid & 0x3;
 
 	/* Wait for the core to enter WFI */
-	while (1) {
-		if (readl(&cpucfg->cpu[cpu].status) & BIT(2))
-			break;
+	while (!sunxi_cpu_poll_wfi(cpu))
 		__mdelay(1);
-	}
 
 	/* Assert reset on target CPU */
-	writel(0, &cpucfg->cpu[cpu].rst);
+	sunxi_cpu_set_reset(cpu, true);
 
 	/* Lock CPU (Disable external debug access) */
-	clrbits_le32(&cpucfg->dbg_ctrl1, BIT(cpu));
+	sunxi_cpu_set_locking(cpu, true);
 
 	/* Power down CPU */
 	sunxi_cpu_set_power(cpuid, false);
 
-	/* Unlock CPU (Disable external debug access) */
-	setbits_le32(&cpucfg->dbg_ctrl1, BIT(cpu));
+	/* Unlock CPU (Reenable external debug access) */
+	sunxi_cpu_set_locking(cpu, false);
 }
 
 static u32 __secure cp15_read_scr(void)
@@ -229,33 +259,31 @@ out:
 int __secure psci_cpu_on(u32 __always_unused unused, u32 mpidr, u32 pc,
 			 u32 context_id)
 {
-	struct sunxi_cpucfg_reg *cpucfg =
-		(struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE;
 	u32 cpu = (mpidr & 0x3);
 
 	/* store target PC and context id */
 	psci_save(cpu, pc, context_id);
 
 	/* Set secondary core power on PC */
-	sunxi_set_entry_address(&psci_cpu_entry);
+	sunxi_cpu_set_entry(cpu, &psci_cpu_entry);
 
 	/* Assert reset on target CPU */
-	writel(0, &cpucfg->cpu[cpu].rst);
+	sunxi_cpu_set_reset(cpu, true);
 
 	/* Invalidate L1 cache */
-	clrbits_le32(&cpucfg->gen_ctrl, BIT(cpu));
+	sunxi_cpu_invalidate_cache(cpu);
 
 	/* Lock CPU (Disable external debug access) */
-	clrbits_le32(&cpucfg->dbg_ctrl1, BIT(cpu));
+	sunxi_cpu_set_locking(cpu, true);
 
 	/* Power up target CPU */
 	sunxi_cpu_set_power(cpu, true);
 
 	/* De-assert reset on target CPU */
-	writel(BIT(1) | BIT(0), &cpucfg->cpu[cpu].rst);
+	sunxi_cpu_set_reset(cpu, false);
 
-	/* Unlock CPU (Disable external debug access) */
-	setbits_le32(&cpucfg->dbg_ctrl1, BIT(cpu));
+	/* Unlock CPU (Reenable external debug access) */
+	sunxi_cpu_set_locking(cpu, false);
 
 	return ARM_PSCI_RET_SUCCESS;
 }
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v4 3/4] sunxi: psci: stop modeling register layout with C structs
  2023-10-12  1:47 [PATCH v4 0/4] Allwinner R528/T113s PSCI Sam Edwards
  2023-10-12  1:47 ` [PATCH v4 1/4] sunxi: psci: clean away preprocessor macros Sam Edwards
  2023-10-12  1:47 ` [PATCH v4 2/4] sunxi: psci: refactor register access to separate functions Sam Edwards
@ 2023-10-12  1:47 ` Sam Edwards
  2023-10-22  0:48   ` Andre Przywara
  2023-10-12  1:47 ` [PATCH v4 4/4] sunxi: psci: implement PSCI on R528 Sam Edwards
  2023-10-22  0:53 ` [PATCH v4 0/4] Allwinner R528/T113s PSCI Andre Przywara
  4 siblings, 1 reply; 9+ messages in thread
From: Sam Edwards @ 2023-10-12  1:47 UTC (permalink / raw)
  To: u-boot, Andre Przywara, Jagan Teki
  Cc: Samuel Holland, Jernej Skrabec, Icenowy Zheng, Maksim Kiselev,
	Sam Edwards

Since the sunxi support nowadays generally prefers #defined register
offsets instead of modeling register layouts using C structs, now is a
good time to do this for PSCI as well. This patch moves away from using
the structs `sunxi_cpucfg_reg` and `sunxi_prcm_reg` in psci.c.

The former struct and its associated header file existed only to support
PSCI code, so also delete them altogether.

Signed-off-by: Sam Edwards <CFSworks@gmail.com>
---
 arch/arm/cpu/armv7/sunxi/psci.c          | 57 ++++++++------------
 arch/arm/include/asm/arch-sunxi/cpucfg.h | 67 ------------------------
 2 files changed, 23 insertions(+), 101 deletions(-)
 delete mode 100644 arch/arm/include/asm/arch-sunxi/cpucfg.h

diff --git a/arch/arm/cpu/armv7/sunxi/psci.c b/arch/arm/cpu/armv7/sunxi/psci.c
index 27ca9c39e1..207aa6bc4b 100644
--- a/arch/arm/cpu/armv7/sunxi/psci.c
+++ b/arch/arm/cpu/armv7/sunxi/psci.c
@@ -11,8 +11,6 @@
 #include <asm/cache.h>
 
 #include <asm/arch/cpu.h>
-#include <asm/arch/cpucfg.h>
-#include <asm/arch/prcm.h>
 #include <asm/armv7.h>
 #include <asm/gic.h>
 #include <asm/io.h>
@@ -27,6 +25,17 @@
 #define	GICD_BASE	(SUNXI_GIC400_BASE + GIC_DIST_OFFSET)
 #define	GICC_BASE	(SUNXI_GIC400_BASE + GIC_CPU_OFFSET_A15)
 
+/*
+ * Offsets into the CPUCFG block applicable to most SUNXIs.
+ */
+#define SUNXI_CPU_RST(cpu)			(0x40 + (cpu) * 0x40 + 0x0)
+#define SUNXI_CPU_STATUS(cpu)			(0x40 + (cpu) * 0x40 + 0x8)
+#define SUNXI_GEN_CTRL				(0x184)
+#define SUNXI_PRIV0				(0x1a4)
+#define SUN7I_CPU1_PWR_CLAMP			(0x1b0)
+#define SUN7I_CPU1_PWROFF			(0x1b4)
+#define SUNXI_DBG_CTRL1				(0x1e4)
+
 /*
  * R40 is different from other single cluster SoCs.
  *
@@ -99,10 +108,7 @@ static void __secure sunxi_cpu_set_entry(int __always_unused cpu, void *entry)
 		writel((u32)entry,
 		       SUNXI_SRAMC_BASE + SUN8I_R40_SRAMC_SOFT_ENTRY_REG0);
 	} else {
-		struct sunxi_cpucfg_reg *cpucfg =
-			(struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE;
-
-		writel((u32)entry, &cpucfg->priv0);
+		writel((u32)entry, SUNXI_CPUCFG_BASE + SUNXI_PRIV0);
 	}
 }
 
@@ -110,26 +116,21 @@ static void __secure sunxi_cpu_set_power(int cpu, bool on)
 {
 	u32 *clamp = NULL;
 	u32 *pwroff;
-	struct sunxi_cpucfg_reg *cpucfg =
-		(struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE;
 
 	/* sun7i (A20) is different from other single cluster SoCs */
 	if (IS_ENABLED(CONFIG_MACH_SUN7I)) {
-		clamp = &cpucfg->cpu1_pwr_clamp;
-		pwroff = &cpucfg->cpu1_pwroff;
+		clamp = (void *)SUNXI_CPUCFG_BASE + SUN7I_CPU1_PWR_CLAMP;
+		pwroff = (void *)SUNXI_CPUCFG_BASE + SUN7I_CPU1_PWROFF;
 		cpu = 0;
 	} else if (IS_ENABLED(CONFIG_MACH_SUN8I_R40)) {
-		clamp = (void *)cpucfg + SUN8I_R40_PWR_CLAMP(cpu);
-		pwroff = (void *)cpucfg + SUN8I_R40_PWROFF;
+		clamp = (void *)SUNXI_CPUCFG_BASE + SUN8I_R40_PWR_CLAMP(cpu);
+		pwroff = (void *)SUNXI_CPUCFG_BASE + SUN8I_R40_PWROFF;
 	} else {
-		struct sunxi_prcm_reg *prcm =
-			(struct sunxi_prcm_reg *)SUNXI_PRCM_BASE;
-
 		if (IS_ENABLED(CONFIG_MACH_SUN6I) ||
 		    IS_ENABLED(CONFIG_MACH_SUN8I_H3))
-			clamp = &prcm->cpu_pwr_clamp[cpu];
+			clamp = (void *)SUNXI_PRCM_BASE + 0x140 + cpu * 0x4;
 
-		pwroff = &prcm->cpu_pwroff;
+		pwroff = (void *)SUNXI_PRCM_BASE + 0x100;
 	}
 
 	if (on) {
@@ -151,37 +152,25 @@ static void __secure sunxi_cpu_set_power(int cpu, bool on)
 
 static void __secure sunxi_cpu_set_reset(int cpu, bool reset)
 {
-	struct sunxi_cpucfg_reg *cpucfg =
-		(struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE;
-
-	writel(reset ? 0b00 : 0b11, &cpucfg->cpu[cpu].rst);
+	writel(reset ? 0b00 : 0b11, SUNXI_CPUCFG_BASE + SUNXI_CPU_RST(cpu));
 }
 
 static void __secure sunxi_cpu_set_locking(int cpu, bool lock)
 {
-	struct sunxi_cpucfg_reg *cpucfg =
-		(struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE;
-
 	if (lock)
-		clrbits_le32(&cpucfg->dbg_ctrl1, BIT(cpu));
+		clrbits_le32(SUNXI_CPUCFG_BASE + SUNXI_DBG_CTRL1, BIT(cpu));
 	else
-		setbits_le32(&cpucfg->dbg_ctrl1, BIT(cpu));
+		setbits_le32(SUNXI_CPUCFG_BASE + SUNXI_DBG_CTRL1, BIT(cpu));
 }
 
 static bool __secure sunxi_cpu_poll_wfi(int cpu)
 {
-	struct sunxi_cpucfg_reg *cpucfg =
-		(struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE;
-
-	return !!(readl(&cpucfg->cpu[cpu].status) & BIT(2));
+	return !!(readl(SUNXI_CPUCFG_BASE + SUNXI_CPU_STATUS(cpu)) & BIT(2));
 }
 
 static void __secure sunxi_cpu_invalidate_cache(int cpu)
 {
-	struct sunxi_cpucfg_reg *cpucfg =
-		(struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE;
-
-	clrbits_le32(&cpucfg->gen_ctrl, BIT(cpu));
+	clrbits_le32(SUNXI_CPUCFG_BASE + SUNXI_GEN_CTRL, BIT(cpu));
 }
 
 static void __secure sunxi_cpu_power_off(u32 cpuid)
diff --git a/arch/arm/include/asm/arch-sunxi/cpucfg.h b/arch/arm/include/asm/arch-sunxi/cpucfg.h
deleted file mode 100644
index 4aaebe0a97..0000000000
--- a/arch/arm/include/asm/arch-sunxi/cpucfg.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Sunxi A31 CPUCFG register definition.
- *
- * (C) Copyright 2014 Hans de Goede <hdegoede@redhat.com
- */
-
-#ifndef _SUNXI_CPUCFG_H
-#define _SUNXI_CPUCFG_H
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-
-#ifndef __ASSEMBLY__
-
-struct __packed sunxi_cpucfg_cpu {
-	u32 rst;		/* base + 0x0 */
-	u32 ctrl;		/* base + 0x4 */
-	u32 status;		/* base + 0x8 */
-	u8 res[0x34];		/* base + 0xc */
-};
-
-struct __packed sunxi_cpucfg_reg {
-	u8 res0[0x40];		/* 0x000 */
-	struct sunxi_cpucfg_cpu cpu[4];		/* 0x040 */
-	u8 res1[0x44];		/* 0x140 */
-	u32 gen_ctrl;		/* 0x184 */
-	u32 l2_status;		/* 0x188 */
-	u8 res2[0x4];		/* 0x18c */
-	u32 event_in;		/* 0x190 */
-	u8 res3[0xc];		/* 0x194 */
-	u32 super_standy_flag;	/* 0x1a0 */
-	u32 priv0;		/* 0x1a4 */
-	u32 priv1;		/* 0x1a8 */
-	u8 res4[0x4];		/* 0x1ac */
-	u32 cpu1_pwr_clamp;	/* 0x1b0 sun7i only */
-	u32 cpu1_pwroff;	/* 0x1b4 sun7i only */
-	u8 res5[0x2c];		/* 0x1b8 */
-	u32 dbg_ctrl1;		/* 0x1e4 */
-	u8 res6[0x18];		/* 0x1e8 */
-	u32 idle_cnt0_low;	/* 0x200 */
-	u32 idle_cnt0_high;	/* 0x204 */
-	u32 idle_cnt0_ctrl;	/* 0x208 */
-	u8 res8[0x4];		/* 0x20c */
-	u32 idle_cnt1_low;	/* 0x210 */
-	u32 idle_cnt1_high;	/* 0x214 */
-	u32 idle_cnt1_ctrl;	/* 0x218 */
-	u8 res9[0x4];		/* 0x21c */
-	u32 idle_cnt2_low;	/* 0x220 */
-	u32 idle_cnt2_high;	/* 0x224 */
-	u32 idle_cnt2_ctrl;	/* 0x228 */
-	u8 res10[0x4];		/* 0x22c */
-	u32 idle_cnt3_low;	/* 0x230 */
-	u32 idle_cnt3_high;	/* 0x234 */
-	u32 idle_cnt3_ctrl;	/* 0x238 */
-	u8 res11[0x4];		/* 0x23c */
-	u32 idle_cnt4_low;	/* 0x240 */
-	u32 idle_cnt4_high;	/* 0x244 */
-	u32 idle_cnt4_ctrl;	/* 0x248 */
-	u8 res12[0x34];		/* 0x24c */
-	u32 cnt64_ctrl;		/* 0x280 */
-	u32 cnt64_low;		/* 0x284 */
-	u32 cnt64_high;		/* 0x288 */
-};
-
-#endif /* __ASSEMBLY__ */
-#endif /* _SUNXI_CPUCFG_H */
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v4 4/4] sunxi: psci: implement PSCI on R528
  2023-10-12  1:47 [PATCH v4 0/4] Allwinner R528/T113s PSCI Sam Edwards
                   ` (2 preceding siblings ...)
  2023-10-12  1:47 ` [PATCH v4 3/4] sunxi: psci: stop modeling register layout with C structs Sam Edwards
@ 2023-10-12  1:47 ` Sam Edwards
  2023-10-22  0:49   ` Andre Przywara
  2023-10-22  0:53 ` [PATCH v4 0/4] Allwinner R528/T113s PSCI Andre Przywara
  4 siblings, 1 reply; 9+ messages in thread
From: Sam Edwards @ 2023-10-12  1:47 UTC (permalink / raw)
  To: u-boot, Andre Przywara, Jagan Teki
  Cc: Samuel Holland, Jernej Skrabec, Icenowy Zheng, Maksim Kiselev,
	Sam Edwards, Kevin Amadiva

This patch adds the necessary code to make nonsec booting and PSCI
secondary core management functional on the R528/T113.

Signed-off-by: Sam Edwards <CFSworks@gmail.com>
Tested-by: Maksim Kiselev <bigunclemax@gmail.com>
Tested-by: Kevin Amadiva <kevin.amadiva@mec.at>
---
 arch/arm/cpu/armv7/Kconfig      |  3 ++-
 arch/arm/cpu/armv7/sunxi/psci.c | 47 ++++++++++++++++++++++++++++++++-
 arch/arm/mach-sunxi/Kconfig     |  4 +++
 3 files changed, 52 insertions(+), 2 deletions(-)

diff --git a/arch/arm/cpu/armv7/Kconfig b/arch/arm/cpu/armv7/Kconfig
index f015d133cb..4eb34b7b44 100644
--- a/arch/arm/cpu/armv7/Kconfig
+++ b/arch/arm/cpu/armv7/Kconfig
@@ -61,8 +61,9 @@ config ARMV7_SECURE_MAX_SIZE
 config ARM_GIC_BASE_ADDRESS
 	hex
 	depends on ARMV7_NONSEC
-	depends on ARCH_EXYNOS5
+	depends on ARCH_EXYNOS5 || MACH_SUN8I_R528
 	default 0x10480000 if ARCH_EXYNOS5
+	default 0x03020000 if MACH_SUN8I_R528
 	help
 	  Override the GIC base address if the Arm Cortex defined
 	  CBAR/PERIPHBASE system register holds the wrong value.
diff --git a/arch/arm/cpu/armv7/sunxi/psci.c b/arch/arm/cpu/armv7/sunxi/psci.c
index 207aa6bc4b..b03a865483 100644
--- a/arch/arm/cpu/armv7/sunxi/psci.c
+++ b/arch/arm/cpu/armv7/sunxi/psci.c
@@ -47,6 +47,19 @@
 #define SUN8I_R40_PWR_CLAMP(cpu)		(0x120 + (cpu) * 0x4)
 #define SUN8I_R40_SRAMC_SOFT_ENTRY_REG0		(0xbc)
 
+/*
+ * R528 is also different, as it has both cores powered up (but held in reset
+ * state) after the SoC is reset. Like the R40, it uses a "soft" entry point
+ * address register, but unlike the R40, it uses a newer "CPUX" block to manage
+ * CPU state, rather than the older CPUCFG system.
+ */
+#define SUN8I_R528_SOFT_ENTRY			(0x1c8)
+#define SUN8I_R528_C0_RST_CTRL			(0x0000)
+#define SUN8I_R528_C0_CTRL_REG0			(0x0010)
+#define SUN8I_R528_C0_CPU_STATUS		(0x0080)
+
+#define SUN8I_R528_C0_STATUS_STANDBYWFI		(16)
+
 static void __secure cp15_write_cntp_tval(u32 tval)
 {
 	asm volatile ("mcr p15, 0, %0, c14, c2, 0" : : "r" (tval));
@@ -103,10 +116,12 @@ static void __secure clamp_set(u32 *clamp)
 
 static void __secure sunxi_cpu_set_entry(int __always_unused cpu, void *entry)
 {
-	/* secondary core entry address is programmed differently on R40 */
 	if (IS_ENABLED(CONFIG_MACH_SUN8I_R40)) {
 		writel((u32)entry,
 		       SUNXI_SRAMC_BASE + SUN8I_R40_SRAMC_SOFT_ENTRY_REG0);
+	} else if (IS_ENABLED(CONFIG_MACH_SUN8I_R528)) {
+		writel((u32)entry,
+		       SUNXI_R_CPUCFG_BASE + SUN8I_R528_SOFT_ENTRY);
 	} else {
 		writel((u32)entry, SUNXI_CPUCFG_BASE + SUNXI_PRIV0);
 	}
@@ -125,6 +140,9 @@ static void __secure sunxi_cpu_set_power(int cpu, bool on)
 	} else if (IS_ENABLED(CONFIG_MACH_SUN8I_R40)) {
 		clamp = (void *)SUNXI_CPUCFG_BASE + SUN8I_R40_PWR_CLAMP(cpu);
 		pwroff = (void *)SUNXI_CPUCFG_BASE + SUN8I_R40_PWROFF;
+	} else if (IS_ENABLED(CONFIG_MACH_SUN8I_R528)) {
+		/* R528 leaves both cores powered up, manages them via reset */
+		return;
 	} else {
 		if (IS_ENABLED(CONFIG_MACH_SUN6I) ||
 		    IS_ENABLED(CONFIG_MACH_SUN8I_H3))
@@ -152,11 +170,27 @@ static void __secure sunxi_cpu_set_power(int cpu, bool on)
 
 static void __secure sunxi_cpu_set_reset(int cpu, bool reset)
 {
+	if (IS_ENABLED(CONFIG_MACH_SUN8I_R528)) {
+		if (reset)
+			clrbits_le32(SUNXI_CPUCFG_BASE + SUN8I_R528_C0_RST_CTRL,
+				     BIT(cpu));
+		else
+			setbits_le32(SUNXI_CPUCFG_BASE + SUN8I_R528_C0_RST_CTRL,
+				     BIT(cpu));
+
+		return;
+	}
+
 	writel(reset ? 0b00 : 0b11, SUNXI_CPUCFG_BASE + SUNXI_CPU_RST(cpu));
 }
 
 static void __secure sunxi_cpu_set_locking(int cpu, bool lock)
 {
+	if (IS_ENABLED(CONFIG_MACH_SUN8I_R528)) {
+		/* Not required on R528 */
+		return;
+	}
+
 	if (lock)
 		clrbits_le32(SUNXI_CPUCFG_BASE + SUNXI_DBG_CTRL1, BIT(cpu));
 	else
@@ -165,11 +199,22 @@ static void __secure sunxi_cpu_set_locking(int cpu, bool lock)
 
 static bool __secure sunxi_cpu_poll_wfi(int cpu)
 {
+	if (IS_ENABLED(CONFIG_MACH_SUN8I_R528)) {
+		return !!(readl(SUNXI_CPUCFG_BASE + SUN8I_R528_C0_CPU_STATUS) &
+			  BIT(SUN8I_R528_C0_STATUS_STANDBYWFI + cpu));
+	}
+
 	return !!(readl(SUNXI_CPUCFG_BASE + SUNXI_CPU_STATUS(cpu)) & BIT(2));
 }
 
 static void __secure sunxi_cpu_invalidate_cache(int cpu)
 {
+	if (IS_ENABLED(CONFIG_MACH_SUN8I_R528)) {
+		clrbits_le32(SUNXI_CPUCFG_BASE + SUN8I_R528_C0_CTRL_REG0,
+			     BIT(cpu));
+		return;
+	}
+
 	clrbits_le32(SUNXI_CPUCFG_BASE + SUNXI_GEN_CTRL, BIT(cpu));
 }
 
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index e891e291f1..23b5b27b97 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -355,6 +355,10 @@ config MACH_SUN8I_R40
 config MACH_SUN8I_R528
 	bool "sun8i (Allwinner R528)"
 	select CPU_V7A
+	select CPU_V7_HAS_NONSEC
+	select CPU_V7_HAS_VIRT
+	select ARCH_SUPPORT_PSCI
+	select SPL_ARMV7_SET_CORTEX_SMPEN
 	select SUNXI_GEN_NCAT2
 	select SUNXI_NEW_PINCTRL
 	select MMC_SUNXI_HAS_NEW_MODE
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v4 3/4] sunxi: psci: stop modeling register layout with C structs
  2023-10-12  1:47 ` [PATCH v4 3/4] sunxi: psci: stop modeling register layout with C structs Sam Edwards
@ 2023-10-22  0:48   ` Andre Przywara
  0 siblings, 0 replies; 9+ messages in thread
From: Andre Przywara @ 2023-10-22  0:48 UTC (permalink / raw)
  To: Sam Edwards
  Cc: u-boot, Jagan Teki, Samuel Holland, Jernej Skrabec, Icenowy Zheng,
	Maksim Kiselev

On Wed, 11 Oct 2023 19:47:55 -0600
Sam Edwards <cfsworks@gmail.com> wrote:

> Since the sunxi support nowadays generally prefers #defined register
> offsets instead of modeling register layouts using C structs, now is a
> good time to do this for PSCI as well. This patch moves away from using
> the structs `sunxi_cpucfg_reg` and `sunxi_prcm_reg` in psci.c.
> 
> The former struct and its associated header file existed only to support
> PSCI code, so also delete them altogether.
> 
> Signed-off-by: Sam Edwards <CFSworks@gmail.com>

Thanks for doing this!

Reviewed-by: Andre Przywara <andre.przywara@arm.com>

Cheers,
Andre

> ---
>  arch/arm/cpu/armv7/sunxi/psci.c          | 57 ++++++++------------
>  arch/arm/include/asm/arch-sunxi/cpucfg.h | 67 ------------------------
>  2 files changed, 23 insertions(+), 101 deletions(-)
>  delete mode 100644 arch/arm/include/asm/arch-sunxi/cpucfg.h
> 
> diff --git a/arch/arm/cpu/armv7/sunxi/psci.c b/arch/arm/cpu/armv7/sunxi/psci.c
> index 27ca9c39e1..207aa6bc4b 100644
> --- a/arch/arm/cpu/armv7/sunxi/psci.c
> +++ b/arch/arm/cpu/armv7/sunxi/psci.c
> @@ -11,8 +11,6 @@
>  #include <asm/cache.h>
>  
>  #include <asm/arch/cpu.h>
> -#include <asm/arch/cpucfg.h>
> -#include <asm/arch/prcm.h>
>  #include <asm/armv7.h>
>  #include <asm/gic.h>
>  #include <asm/io.h>
> @@ -27,6 +25,17 @@
>  #define	GICD_BASE	(SUNXI_GIC400_BASE + GIC_DIST_OFFSET)
>  #define	GICC_BASE	(SUNXI_GIC400_BASE + GIC_CPU_OFFSET_A15)
>  
> +/*
> + * Offsets into the CPUCFG block applicable to most SUNXIs.
> + */
> +#define SUNXI_CPU_RST(cpu)			(0x40 + (cpu) * 0x40 + 0x0)
> +#define SUNXI_CPU_STATUS(cpu)			(0x40 + (cpu) * 0x40 + 0x8)
> +#define SUNXI_GEN_CTRL				(0x184)
> +#define SUNXI_PRIV0				(0x1a4)
> +#define SUN7I_CPU1_PWR_CLAMP			(0x1b0)
> +#define SUN7I_CPU1_PWROFF			(0x1b4)
> +#define SUNXI_DBG_CTRL1				(0x1e4)
> +
>  /*
>   * R40 is different from other single cluster SoCs.
>   *
> @@ -99,10 +108,7 @@ static void __secure sunxi_cpu_set_entry(int __always_unused cpu, void *entry)
>  		writel((u32)entry,
>  		       SUNXI_SRAMC_BASE + SUN8I_R40_SRAMC_SOFT_ENTRY_REG0);
>  	} else {
> -		struct sunxi_cpucfg_reg *cpucfg =
> -			(struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE;
> -
> -		writel((u32)entry, &cpucfg->priv0);
> +		writel((u32)entry, SUNXI_CPUCFG_BASE + SUNXI_PRIV0);
>  	}
>  }
>  
> @@ -110,26 +116,21 @@ static void __secure sunxi_cpu_set_power(int cpu, bool on)
>  {
>  	u32 *clamp = NULL;
>  	u32 *pwroff;
> -	struct sunxi_cpucfg_reg *cpucfg =
> -		(struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE;
>  
>  	/* sun7i (A20) is different from other single cluster SoCs */
>  	if (IS_ENABLED(CONFIG_MACH_SUN7I)) {
> -		clamp = &cpucfg->cpu1_pwr_clamp;
> -		pwroff = &cpucfg->cpu1_pwroff;
> +		clamp = (void *)SUNXI_CPUCFG_BASE + SUN7I_CPU1_PWR_CLAMP;
> +		pwroff = (void *)SUNXI_CPUCFG_BASE + SUN7I_CPU1_PWROFF;
>  		cpu = 0;
>  	} else if (IS_ENABLED(CONFIG_MACH_SUN8I_R40)) {
> -		clamp = (void *)cpucfg + SUN8I_R40_PWR_CLAMP(cpu);
> -		pwroff = (void *)cpucfg + SUN8I_R40_PWROFF;
> +		clamp = (void *)SUNXI_CPUCFG_BASE + SUN8I_R40_PWR_CLAMP(cpu);
> +		pwroff = (void *)SUNXI_CPUCFG_BASE + SUN8I_R40_PWROFF;
>  	} else {
> -		struct sunxi_prcm_reg *prcm =
> -			(struct sunxi_prcm_reg *)SUNXI_PRCM_BASE;
> -
>  		if (IS_ENABLED(CONFIG_MACH_SUN6I) ||
>  		    IS_ENABLED(CONFIG_MACH_SUN8I_H3))
> -			clamp = &prcm->cpu_pwr_clamp[cpu];
> +			clamp = (void *)SUNXI_PRCM_BASE + 0x140 + cpu * 0x4;
>  
> -		pwroff = &prcm->cpu_pwroff;
> +		pwroff = (void *)SUNXI_PRCM_BASE + 0x100;
>  	}
>  
>  	if (on) {
> @@ -151,37 +152,25 @@ static void __secure sunxi_cpu_set_power(int cpu, bool on)
>  
>  static void __secure sunxi_cpu_set_reset(int cpu, bool reset)
>  {
> -	struct sunxi_cpucfg_reg *cpucfg =
> -		(struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE;
> -
> -	writel(reset ? 0b00 : 0b11, &cpucfg->cpu[cpu].rst);
> +	writel(reset ? 0b00 : 0b11, SUNXI_CPUCFG_BASE + SUNXI_CPU_RST(cpu));
>  }
>  
>  static void __secure sunxi_cpu_set_locking(int cpu, bool lock)
>  {
> -	struct sunxi_cpucfg_reg *cpucfg =
> -		(struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE;
> -
>  	if (lock)
> -		clrbits_le32(&cpucfg->dbg_ctrl1, BIT(cpu));
> +		clrbits_le32(SUNXI_CPUCFG_BASE + SUNXI_DBG_CTRL1, BIT(cpu));
>  	else
> -		setbits_le32(&cpucfg->dbg_ctrl1, BIT(cpu));
> +		setbits_le32(SUNXI_CPUCFG_BASE + SUNXI_DBG_CTRL1, BIT(cpu));
>  }
>  
>  static bool __secure sunxi_cpu_poll_wfi(int cpu)
>  {
> -	struct sunxi_cpucfg_reg *cpucfg =
> -		(struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE;
> -
> -	return !!(readl(&cpucfg->cpu[cpu].status) & BIT(2));
> +	return !!(readl(SUNXI_CPUCFG_BASE + SUNXI_CPU_STATUS(cpu)) & BIT(2));
>  }
>  
>  static void __secure sunxi_cpu_invalidate_cache(int cpu)
>  {
> -	struct sunxi_cpucfg_reg *cpucfg =
> -		(struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE;
> -
> -	clrbits_le32(&cpucfg->gen_ctrl, BIT(cpu));
> +	clrbits_le32(SUNXI_CPUCFG_BASE + SUNXI_GEN_CTRL, BIT(cpu));
>  }
>  
>  static void __secure sunxi_cpu_power_off(u32 cpuid)
> diff --git a/arch/arm/include/asm/arch-sunxi/cpucfg.h b/arch/arm/include/asm/arch-sunxi/cpucfg.h
> deleted file mode 100644
> index 4aaebe0a97..0000000000
> --- a/arch/arm/include/asm/arch-sunxi/cpucfg.h
> +++ /dev/null
> @@ -1,67 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0+ */
> -/*
> - * Sunxi A31 CPUCFG register definition.
> - *
> - * (C) Copyright 2014 Hans de Goede <hdegoede@redhat.com
> - */
> -
> -#ifndef _SUNXI_CPUCFG_H
> -#define _SUNXI_CPUCFG_H
> -
> -#include <linux/compiler.h>
> -#include <linux/types.h>
> -
> -#ifndef __ASSEMBLY__
> -
> -struct __packed sunxi_cpucfg_cpu {
> -	u32 rst;		/* base + 0x0 */
> -	u32 ctrl;		/* base + 0x4 */
> -	u32 status;		/* base + 0x8 */
> -	u8 res[0x34];		/* base + 0xc */
> -};
> -
> -struct __packed sunxi_cpucfg_reg {
> -	u8 res0[0x40];		/* 0x000 */
> -	struct sunxi_cpucfg_cpu cpu[4];		/* 0x040 */
> -	u8 res1[0x44];		/* 0x140 */
> -	u32 gen_ctrl;		/* 0x184 */
> -	u32 l2_status;		/* 0x188 */
> -	u8 res2[0x4];		/* 0x18c */
> -	u32 event_in;		/* 0x190 */
> -	u8 res3[0xc];		/* 0x194 */
> -	u32 super_standy_flag;	/* 0x1a0 */
> -	u32 priv0;		/* 0x1a4 */
> -	u32 priv1;		/* 0x1a8 */
> -	u8 res4[0x4];		/* 0x1ac */
> -	u32 cpu1_pwr_clamp;	/* 0x1b0 sun7i only */
> -	u32 cpu1_pwroff;	/* 0x1b4 sun7i only */
> -	u8 res5[0x2c];		/* 0x1b8 */
> -	u32 dbg_ctrl1;		/* 0x1e4 */
> -	u8 res6[0x18];		/* 0x1e8 */
> -	u32 idle_cnt0_low;	/* 0x200 */
> -	u32 idle_cnt0_high;	/* 0x204 */
> -	u32 idle_cnt0_ctrl;	/* 0x208 */
> -	u8 res8[0x4];		/* 0x20c */
> -	u32 idle_cnt1_low;	/* 0x210 */
> -	u32 idle_cnt1_high;	/* 0x214 */
> -	u32 idle_cnt1_ctrl;	/* 0x218 */
> -	u8 res9[0x4];		/* 0x21c */
> -	u32 idle_cnt2_low;	/* 0x220 */
> -	u32 idle_cnt2_high;	/* 0x224 */
> -	u32 idle_cnt2_ctrl;	/* 0x228 */
> -	u8 res10[0x4];		/* 0x22c */
> -	u32 idle_cnt3_low;	/* 0x230 */
> -	u32 idle_cnt3_high;	/* 0x234 */
> -	u32 idle_cnt3_ctrl;	/* 0x238 */
> -	u8 res11[0x4];		/* 0x23c */
> -	u32 idle_cnt4_low;	/* 0x240 */
> -	u32 idle_cnt4_high;	/* 0x244 */
> -	u32 idle_cnt4_ctrl;	/* 0x248 */
> -	u8 res12[0x34];		/* 0x24c */
> -	u32 cnt64_ctrl;		/* 0x280 */
> -	u32 cnt64_low;		/* 0x284 */
> -	u32 cnt64_high;		/* 0x288 */
> -};
> -
> -#endif /* __ASSEMBLY__ */
> -#endif /* _SUNXI_CPUCFG_H */


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v4 4/4] sunxi: psci: implement PSCI on R528
  2023-10-12  1:47 ` [PATCH v4 4/4] sunxi: psci: implement PSCI on R528 Sam Edwards
@ 2023-10-22  0:49   ` Andre Przywara
  2023-10-24 22:16     ` Andre Przywara
  0 siblings, 1 reply; 9+ messages in thread
From: Andre Przywara @ 2023-10-22  0:49 UTC (permalink / raw)
  To: Sam Edwards
  Cc: u-boot, Jagan Teki, Samuel Holland, Jernej Skrabec, Icenowy Zheng,
	Maksim Kiselev, Kevin Amadiva

On Wed, 11 Oct 2023 19:47:56 -0600
Sam Edwards <cfsworks@gmail.com> wrote:

> This patch adds the necessary code to make nonsec booting and PSCI
> secondary core management functional on the R528/T113.
> 
> Signed-off-by: Sam Edwards <CFSworks@gmail.com>
> Tested-by: Maksim Kiselev <bigunclemax@gmail.com>
> Tested-by: Kevin Amadiva <kevin.amadiva@mec.at>

Thanks, that looks good now. It's debatable whether the Kconfig depends
on should be NCAT2 instead, but we can fix this when the need arises.

Reviewed-by: Andre Przywara <andre.przywara@arm.com>

Cheers,
Andre

> ---
>  arch/arm/cpu/armv7/Kconfig      |  3 ++-
>  arch/arm/cpu/armv7/sunxi/psci.c | 47 ++++++++++++++++++++++++++++++++-
>  arch/arm/mach-sunxi/Kconfig     |  4 +++
>  3 files changed, 52 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm/cpu/armv7/Kconfig b/arch/arm/cpu/armv7/Kconfig
> index f015d133cb..4eb34b7b44 100644
> --- a/arch/arm/cpu/armv7/Kconfig
> +++ b/arch/arm/cpu/armv7/Kconfig
> @@ -61,8 +61,9 @@ config ARMV7_SECURE_MAX_SIZE
>  config ARM_GIC_BASE_ADDRESS
>  	hex
>  	depends on ARMV7_NONSEC
> -	depends on ARCH_EXYNOS5
> +	depends on ARCH_EXYNOS5 || MACH_SUN8I_R528
>  	default 0x10480000 if ARCH_EXYNOS5
> +	default 0x03020000 if MACH_SUN8I_R528
>  	help
>  	  Override the GIC base address if the Arm Cortex defined
>  	  CBAR/PERIPHBASE system register holds the wrong value.
> diff --git a/arch/arm/cpu/armv7/sunxi/psci.c b/arch/arm/cpu/armv7/sunxi/psci.c
> index 207aa6bc4b..b03a865483 100644
> --- a/arch/arm/cpu/armv7/sunxi/psci.c
> +++ b/arch/arm/cpu/armv7/sunxi/psci.c
> @@ -47,6 +47,19 @@
>  #define SUN8I_R40_PWR_CLAMP(cpu)		(0x120 + (cpu) * 0x4)
>  #define SUN8I_R40_SRAMC_SOFT_ENTRY_REG0		(0xbc)
>  
> +/*
> + * R528 is also different, as it has both cores powered up (but held in reset
> + * state) after the SoC is reset. Like the R40, it uses a "soft" entry point
> + * address register, but unlike the R40, it uses a newer "CPUX" block to manage
> + * CPU state, rather than the older CPUCFG system.
> + */
> +#define SUN8I_R528_SOFT_ENTRY			(0x1c8)
> +#define SUN8I_R528_C0_RST_CTRL			(0x0000)
> +#define SUN8I_R528_C0_CTRL_REG0			(0x0010)
> +#define SUN8I_R528_C0_CPU_STATUS		(0x0080)
> +
> +#define SUN8I_R528_C0_STATUS_STANDBYWFI		(16)
> +
>  static void __secure cp15_write_cntp_tval(u32 tval)
>  {
>  	asm volatile ("mcr p15, 0, %0, c14, c2, 0" : : "r" (tval));
> @@ -103,10 +116,12 @@ static void __secure clamp_set(u32 *clamp)
>  
>  static void __secure sunxi_cpu_set_entry(int __always_unused cpu, void *entry)
>  {
> -	/* secondary core entry address is programmed differently on R40 */
>  	if (IS_ENABLED(CONFIG_MACH_SUN8I_R40)) {
>  		writel((u32)entry,
>  		       SUNXI_SRAMC_BASE + SUN8I_R40_SRAMC_SOFT_ENTRY_REG0);
> +	} else if (IS_ENABLED(CONFIG_MACH_SUN8I_R528)) {
> +		writel((u32)entry,
> +		       SUNXI_R_CPUCFG_BASE + SUN8I_R528_SOFT_ENTRY);
>  	} else {
>  		writel((u32)entry, SUNXI_CPUCFG_BASE + SUNXI_PRIV0);
>  	}
> @@ -125,6 +140,9 @@ static void __secure sunxi_cpu_set_power(int cpu, bool on)
>  	} else if (IS_ENABLED(CONFIG_MACH_SUN8I_R40)) {
>  		clamp = (void *)SUNXI_CPUCFG_BASE + SUN8I_R40_PWR_CLAMP(cpu);
>  		pwroff = (void *)SUNXI_CPUCFG_BASE + SUN8I_R40_PWROFF;
> +	} else if (IS_ENABLED(CONFIG_MACH_SUN8I_R528)) {
> +		/* R528 leaves both cores powered up, manages them via reset */
> +		return;
>  	} else {
>  		if (IS_ENABLED(CONFIG_MACH_SUN6I) ||
>  		    IS_ENABLED(CONFIG_MACH_SUN8I_H3))
> @@ -152,11 +170,27 @@ static void __secure sunxi_cpu_set_power(int cpu, bool on)
>  
>  static void __secure sunxi_cpu_set_reset(int cpu, bool reset)
>  {
> +	if (IS_ENABLED(CONFIG_MACH_SUN8I_R528)) {
> +		if (reset)
> +			clrbits_le32(SUNXI_CPUCFG_BASE + SUN8I_R528_C0_RST_CTRL,
> +				     BIT(cpu));
> +		else
> +			setbits_le32(SUNXI_CPUCFG_BASE + SUN8I_R528_C0_RST_CTRL,
> +				     BIT(cpu));
> +
> +		return;
> +	}
> +
>  	writel(reset ? 0b00 : 0b11, SUNXI_CPUCFG_BASE + SUNXI_CPU_RST(cpu));
>  }
>  
>  static void __secure sunxi_cpu_set_locking(int cpu, bool lock)
>  {
> +	if (IS_ENABLED(CONFIG_MACH_SUN8I_R528)) {
> +		/* Not required on R528 */
> +		return;
> +	}
> +
>  	if (lock)
>  		clrbits_le32(SUNXI_CPUCFG_BASE + SUNXI_DBG_CTRL1, BIT(cpu));
>  	else
> @@ -165,11 +199,22 @@ static void __secure sunxi_cpu_set_locking(int cpu, bool lock)
>  
>  static bool __secure sunxi_cpu_poll_wfi(int cpu)
>  {
> +	if (IS_ENABLED(CONFIG_MACH_SUN8I_R528)) {
> +		return !!(readl(SUNXI_CPUCFG_BASE + SUN8I_R528_C0_CPU_STATUS) &
> +			  BIT(SUN8I_R528_C0_STATUS_STANDBYWFI + cpu));
> +	}
> +
>  	return !!(readl(SUNXI_CPUCFG_BASE + SUNXI_CPU_STATUS(cpu)) & BIT(2));
>  }
>  
>  static void __secure sunxi_cpu_invalidate_cache(int cpu)
>  {
> +	if (IS_ENABLED(CONFIG_MACH_SUN8I_R528)) {
> +		clrbits_le32(SUNXI_CPUCFG_BASE + SUN8I_R528_C0_CTRL_REG0,
> +			     BIT(cpu));
> +		return;
> +	}
> +
>  	clrbits_le32(SUNXI_CPUCFG_BASE + SUNXI_GEN_CTRL, BIT(cpu));
>  }
>  
> diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
> index e891e291f1..23b5b27b97 100644
> --- a/arch/arm/mach-sunxi/Kconfig
> +++ b/arch/arm/mach-sunxi/Kconfig
> @@ -355,6 +355,10 @@ config MACH_SUN8I_R40
>  config MACH_SUN8I_R528
>  	bool "sun8i (Allwinner R528)"
>  	select CPU_V7A
> +	select CPU_V7_HAS_NONSEC
> +	select CPU_V7_HAS_VIRT
> +	select ARCH_SUPPORT_PSCI
> +	select SPL_ARMV7_SET_CORTEX_SMPEN
>  	select SUNXI_GEN_NCAT2
>  	select SUNXI_NEW_PINCTRL
>  	select MMC_SUNXI_HAS_NEW_MODE


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v4 0/4] Allwinner R528/T113s PSCI
  2023-10-12  1:47 [PATCH v4 0/4] Allwinner R528/T113s PSCI Sam Edwards
                   ` (3 preceding siblings ...)
  2023-10-12  1:47 ` [PATCH v4 4/4] sunxi: psci: implement PSCI on R528 Sam Edwards
@ 2023-10-22  0:53 ` Andre Przywara
  4 siblings, 0 replies; 9+ messages in thread
From: Andre Przywara @ 2023-10-22  0:53 UTC (permalink / raw)
  To: Sam Edwards
  Cc: u-boot, Jagan Teki, Samuel Holland, Jernej Skrabec, Icenowy Zheng,
	Maksim Kiselev

On Wed, 11 Oct 2023 19:47:52 -0600
Sam Edwards <cfsworks@gmail.com> wrote:

Hi Sam,

> Hi list,
> 
> This is the third, and hopefully final, version of my patchset for PSCI support
> on R528/T113-s3. This one, as always, depends on Andre Przywara's T113s support
> series (v2), available on the list and also located on a Git branch at:
> https://source.denx.de/u-boot/custodians/u-boot-sunxi.git t113s-v2
> 
> NOTE THAT THIS ALSO depends on the following commit on master:
> 3d5e52bd97 ("ARM: psci: move GIC address override to Kconfig")
> 
> For testing: I can confirm that patch 2/4 results in no change to machine code
> whatsoever on any supported target. Patch 1/4 results in a minor machine code
> change on R40 only. Patch 3/4 will likely require testing on each of the 4
> "special case" sunxi targets (sun6i, sun7i, R40, H3) to ensure that register
> offsets are kept consistent. Patch 4/4 needs testing on R528 only.

For now I have included this series into the T113s support series and
pushed this to sunxi/master, to trigger the CI.

I will do some final testing here on the MangoPi and other boards (for
regressions), but I am hopeful to send a pull request in the next day
to two.

Thanks again for your persistent work on this, much appreciated!

Cheers,
Andre

 > 
> Warm regards,
> Sam
> 
> Changes v3->v4:
> - The GIC base address override is done through Kconfig, instead of in
>   sunxi-common.h
> 
> Changes v2->v3:
> - Fix missing `cpu=0;` for the sun7i power management case.
> - Make sunxi_cpu_power_off() a static function, per feedback on v2.
> - Kevin Amadiva of MEC electronics got in touch with me off-list,
> reported success bringing up CPU1 of a T113 with this patchset, and
> kindly provided me with a Tested-by tag for patch 4/4.
> - Remove a comment about R40/R528 being special, per feedback on v2.
> - Simplify an if statement, per feedback on v2.
> - Add missing 'select' directives to the R528 Kconfig, per feedback
> on v2.
> 
> Changes v1->v2:
> - Power clamp is now adjusted ONLY on sun{6,7}i, H3, R40. The
> previous version was mistakenly doing this EXCEPT on those machines.
> - Flattened sunxi_power_switch() into sunxi_cpu_set_power() for
> simplicity's sake.
> - Moved the "power clamp is not NULL" conditional into
> sunxi_cpu_set_power().
> - Removed unnecessary H6 special-case, since H6 is actually ARM64.
> - Renamed SUNXI_CPUX_BASE to SUNXI_CPUCFG_BASE, to mirror expected
> changes in Andre's v2 of the R528 series (we decided against using a
> new name for this block).
> - Removed sunxi_cpucfg_reg struct, and stopped using the PRCM struct
> in psci.c.
> 
> Sam Edwards (4):
>   sunxi: psci: clean away preprocessor macros
>   sunxi: psci: refactor register access to separate functions
>   sunxi: psci: stop modeling register layout with C structs
>   sunxi: psci: implement PSCI on R528
> 
>  arch/arm/cpu/armv7/Kconfig               |   3 +-
>  arch/arm/cpu/armv7/sunxi/psci.c          | 185
> ++++++++++++++--------- arch/arm/include/asm/arch-sunxi/cpucfg.h |
> 67 -------- arch/arm/mach-sunxi/Kconfig              |   4 +
>  4 files changed, 121 insertions(+), 138 deletions(-)
>  delete mode 100644 arch/arm/include/asm/arch-sunxi/cpucfg.h
> 


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v4 4/4] sunxi: psci: implement PSCI on R528
  2023-10-22  0:49   ` Andre Przywara
@ 2023-10-24 22:16     ` Andre Przywara
  0 siblings, 0 replies; 9+ messages in thread
From: Andre Przywara @ 2023-10-24 22:16 UTC (permalink / raw)
  To: Sam Edwards
  Cc: u-boot, Jagan Teki, Samuel Holland, Jernej Skrabec, Icenowy Zheng,
	Maksim Kiselev, Kevin Amadiva

On Sun, 22 Oct 2023 01:49:49 +0100
Andre Przywara <andre.przywara@arm.com> wrote:

> On Wed, 11 Oct 2023 19:47:56 -0600
> Sam Edwards <cfsworks@gmail.com> wrote:
> 
> > This patch adds the necessary code to make nonsec booting and PSCI
> > secondary core management functional on the R528/T113.
> > 
> > Signed-off-by: Sam Edwards <CFSworks@gmail.com>
> > Tested-by: Maksim Kiselev <bigunclemax@gmail.com>
> > Tested-by: Kevin Amadiva <kevin.amadiva@mec.at>  
> 
> Thanks, that looks good now. It's debatable whether the Kconfig depends
> on should be NCAT2 instead, but we can fix this when the need arises.
> 
> Reviewed-by: Andre Przywara <andre.przywara@arm.com>

For the records, this patch was missing the definition of
SUNXI_R_CPUCFG_BASE, which broke the build of all other 32-bit sunxi boards.
I fixed that here:
https://lore.kernel.org/u-boot/20231023132449.813863-24-andre.przywara@arm.com/
and this version was also merged.

Cheers,
Andre

> 
> > ---
> >  arch/arm/cpu/armv7/Kconfig      |  3 ++-
> >  arch/arm/cpu/armv7/sunxi/psci.c | 47 ++++++++++++++++++++++++++++++++-
> >  arch/arm/mach-sunxi/Kconfig     |  4 +++
> >  3 files changed, 52 insertions(+), 2 deletions(-)
> > 
> > diff --git a/arch/arm/cpu/armv7/Kconfig b/arch/arm/cpu/armv7/Kconfig
> > index f015d133cb..4eb34b7b44 100644
> > --- a/arch/arm/cpu/armv7/Kconfig
> > +++ b/arch/arm/cpu/armv7/Kconfig
> > @@ -61,8 +61,9 @@ config ARMV7_SECURE_MAX_SIZE
> >  config ARM_GIC_BASE_ADDRESS
> >  	hex
> >  	depends on ARMV7_NONSEC
> > -	depends on ARCH_EXYNOS5
> > +	depends on ARCH_EXYNOS5 || MACH_SUN8I_R528
> >  	default 0x10480000 if ARCH_EXYNOS5
> > +	default 0x03020000 if MACH_SUN8I_R528
> >  	help
> >  	  Override the GIC base address if the Arm Cortex defined
> >  	  CBAR/PERIPHBASE system register holds the wrong value.
> > diff --git a/arch/arm/cpu/armv7/sunxi/psci.c b/arch/arm/cpu/armv7/sunxi/psci.c
> > index 207aa6bc4b..b03a865483 100644
> > --- a/arch/arm/cpu/armv7/sunxi/psci.c
> > +++ b/arch/arm/cpu/armv7/sunxi/psci.c
> > @@ -47,6 +47,19 @@
> >  #define SUN8I_R40_PWR_CLAMP(cpu)		(0x120 + (cpu) * 0x4)
> >  #define SUN8I_R40_SRAMC_SOFT_ENTRY_REG0		(0xbc)
> >  
> > +/*
> > + * R528 is also different, as it has both cores powered up (but held in reset
> > + * state) after the SoC is reset. Like the R40, it uses a "soft" entry point
> > + * address register, but unlike the R40, it uses a newer "CPUX" block to manage
> > + * CPU state, rather than the older CPUCFG system.
> > + */
> > +#define SUN8I_R528_SOFT_ENTRY			(0x1c8)
> > +#define SUN8I_R528_C0_RST_CTRL			(0x0000)
> > +#define SUN8I_R528_C0_CTRL_REG0			(0x0010)
> > +#define SUN8I_R528_C0_CPU_STATUS		(0x0080)
> > +
> > +#define SUN8I_R528_C0_STATUS_STANDBYWFI		(16)
> > +
> >  static void __secure cp15_write_cntp_tval(u32 tval)
> >  {
> >  	asm volatile ("mcr p15, 0, %0, c14, c2, 0" : : "r" (tval));
> > @@ -103,10 +116,12 @@ static void __secure clamp_set(u32 *clamp)
> >  
> >  static void __secure sunxi_cpu_set_entry(int __always_unused cpu, void *entry)
> >  {
> > -	/* secondary core entry address is programmed differently on R40 */
> >  	if (IS_ENABLED(CONFIG_MACH_SUN8I_R40)) {
> >  		writel((u32)entry,
> >  		       SUNXI_SRAMC_BASE + SUN8I_R40_SRAMC_SOFT_ENTRY_REG0);
> > +	} else if (IS_ENABLED(CONFIG_MACH_SUN8I_R528)) {
> > +		writel((u32)entry,
> > +		       SUNXI_R_CPUCFG_BASE + SUN8I_R528_SOFT_ENTRY);
> >  	} else {
> >  		writel((u32)entry, SUNXI_CPUCFG_BASE + SUNXI_PRIV0);
> >  	}
> > @@ -125,6 +140,9 @@ static void __secure sunxi_cpu_set_power(int cpu, bool on)
> >  	} else if (IS_ENABLED(CONFIG_MACH_SUN8I_R40)) {
> >  		clamp = (void *)SUNXI_CPUCFG_BASE + SUN8I_R40_PWR_CLAMP(cpu);
> >  		pwroff = (void *)SUNXI_CPUCFG_BASE + SUN8I_R40_PWROFF;
> > +	} else if (IS_ENABLED(CONFIG_MACH_SUN8I_R528)) {
> > +		/* R528 leaves both cores powered up, manages them via reset */
> > +		return;
> >  	} else {
> >  		if (IS_ENABLED(CONFIG_MACH_SUN6I) ||
> >  		    IS_ENABLED(CONFIG_MACH_SUN8I_H3))
> > @@ -152,11 +170,27 @@ static void __secure sunxi_cpu_set_power(int cpu, bool on)
> >  
> >  static void __secure sunxi_cpu_set_reset(int cpu, bool reset)
> >  {
> > +	if (IS_ENABLED(CONFIG_MACH_SUN8I_R528)) {
> > +		if (reset)
> > +			clrbits_le32(SUNXI_CPUCFG_BASE + SUN8I_R528_C0_RST_CTRL,
> > +				     BIT(cpu));
> > +		else
> > +			setbits_le32(SUNXI_CPUCFG_BASE + SUN8I_R528_C0_RST_CTRL,
> > +				     BIT(cpu));
> > +
> > +		return;
> > +	}
> > +
> >  	writel(reset ? 0b00 : 0b11, SUNXI_CPUCFG_BASE + SUNXI_CPU_RST(cpu));
> >  }
> >  
> >  static void __secure sunxi_cpu_set_locking(int cpu, bool lock)
> >  {
> > +	if (IS_ENABLED(CONFIG_MACH_SUN8I_R528)) {
> > +		/* Not required on R528 */
> > +		return;
> > +	}
> > +
> >  	if (lock)
> >  		clrbits_le32(SUNXI_CPUCFG_BASE + SUNXI_DBG_CTRL1, BIT(cpu));
> >  	else
> > @@ -165,11 +199,22 @@ static void __secure sunxi_cpu_set_locking(int cpu, bool lock)
> >  
> >  static bool __secure sunxi_cpu_poll_wfi(int cpu)
> >  {
> > +	if (IS_ENABLED(CONFIG_MACH_SUN8I_R528)) {
> > +		return !!(readl(SUNXI_CPUCFG_BASE + SUN8I_R528_C0_CPU_STATUS) &
> > +			  BIT(SUN8I_R528_C0_STATUS_STANDBYWFI + cpu));
> > +	}
> > +
> >  	return !!(readl(SUNXI_CPUCFG_BASE + SUNXI_CPU_STATUS(cpu)) & BIT(2));
> >  }
> >  
> >  static void __secure sunxi_cpu_invalidate_cache(int cpu)
> >  {
> > +	if (IS_ENABLED(CONFIG_MACH_SUN8I_R528)) {
> > +		clrbits_le32(SUNXI_CPUCFG_BASE + SUN8I_R528_C0_CTRL_REG0,
> > +			     BIT(cpu));
> > +		return;
> > +	}
> > +
> >  	clrbits_le32(SUNXI_CPUCFG_BASE + SUNXI_GEN_CTRL, BIT(cpu));
> >  }
> >  
> > diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
> > index e891e291f1..23b5b27b97 100644
> > --- a/arch/arm/mach-sunxi/Kconfig
> > +++ b/arch/arm/mach-sunxi/Kconfig
> > @@ -355,6 +355,10 @@ config MACH_SUN8I_R40
> >  config MACH_SUN8I_R528
> >  	bool "sun8i (Allwinner R528)"
> >  	select CPU_V7A
> > +	select CPU_V7_HAS_NONSEC
> > +	select CPU_V7_HAS_VIRT
> > +	select ARCH_SUPPORT_PSCI
> > +	select SPL_ARMV7_SET_CORTEX_SMPEN
> >  	select SUNXI_GEN_NCAT2
> >  	select SUNXI_NEW_PINCTRL
> >  	select MMC_SUNXI_HAS_NEW_MODE  
> 


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2023-10-24 22:18 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-10-12  1:47 [PATCH v4 0/4] Allwinner R528/T113s PSCI Sam Edwards
2023-10-12  1:47 ` [PATCH v4 1/4] sunxi: psci: clean away preprocessor macros Sam Edwards
2023-10-12  1:47 ` [PATCH v4 2/4] sunxi: psci: refactor register access to separate functions Sam Edwards
2023-10-12  1:47 ` [PATCH v4 3/4] sunxi: psci: stop modeling register layout with C structs Sam Edwards
2023-10-22  0:48   ` Andre Przywara
2023-10-12  1:47 ` [PATCH v4 4/4] sunxi: psci: implement PSCI on R528 Sam Edwards
2023-10-22  0:49   ` Andre Przywara
2023-10-24 22:16     ` Andre Przywara
2023-10-22  0:53 ` [PATCH v4 0/4] Allwinner R528/T113s PSCI Andre Przywara

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox