[U-Boot] [PATCH v2 12/13] sunxi: Add PSCI support for R40
Chen-Yu Tsai
wens at csie.org
Mon Mar 6 08:05:17 UTC 2017
The R40's CPU controls are a combination of sun6i and sun7i.
All controls are in the CPUCFG block, and it seems the R40 does not
have a PRCM block. The core reset, power gating and clamp controls
are grouped like sun6i.
Last, the R40 does not have a secure SRAM block.
This patch adds a PSCI implementation for CPU bring-up and hotplug
for the R40.
Signed-off-by: Chen-Yu Tsai <wens at csie.org>
Acked-by: Maxime Ripard <maxime.ripard at free-electrons.com>
---
arch/arm/cpu/armv7/sunxi/psci.c | 35 ++++++++++++++++++++++++++++++++---
board/sunxi/Kconfig | 3 +++
2 files changed, 35 insertions(+), 3 deletions(-)
diff --git a/arch/arm/cpu/armv7/sunxi/psci.c b/arch/arm/cpu/armv7/sunxi/psci.c
index 104dc909bc53..b3a34de1aafe 100644
--- a/arch/arm/cpu/armv7/sunxi/psci.c
+++ b/arch/arm/cpu/armv7/sunxi/psci.c
@@ -27,6 +27,17 @@
#define GICD_BASE (SUNXI_GIC400_BASE + GIC_DIST_OFFSET)
#define GICC_BASE (SUNXI_GIC400_BASE + GIC_CPU_OFFSET_A15)
+/*
+ * R40 is different from other single cluster SoCs.
+ *
+ * The power clamps are located in the unused space after the per-core
+ * reset controls for core 3. The secondary core entry address register
+ * is in the SRAM controller address range.
+ */
+#define SUN8I_R40_PWROFF (0x110)
+#define SUN8I_R40_PWR_CLAMP(cpu) (0x120 + (cpu) * 0x4)
+#define SUN8I_R40_SRAMC_SOFT_ENTRY_REG0 (0xbc)
+
static void __secure cp15_write_cntp_tval(u32 tval)
{
asm volatile ("mcr p15, 0, %0, c14, c2, 0" : : "r" (tval));
@@ -68,7 +79,8 @@ static void __secure __mdelay(u32 ms)
static void __secure clamp_release(u32 __maybe_unused *clamp)
{
#if defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN7I) || \
- defined(CONFIG_MACH_SUN8I_H3)
+ defined(CONFIG_MACH_SUN8I_H3) || \
+ defined(CONFIG_MACH_SUN8I_R40)
u32 tmp = 0x1ff;
do {
tmp >>= 1;
@@ -82,7 +94,8 @@ static void __secure clamp_release(u32 __maybe_unused *clamp)
static void __secure clamp_set(u32 __maybe_unused *clamp)
{
#if defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN7I) || \
- defined(CONFIG_MACH_SUN8I_H3)
+ defined(CONFIG_MACH_SUN8I_H3) || \
+ defined(CONFIG_MACH_SUN8I_R40)
writel(0xff, clamp);
#endif
}
@@ -115,7 +128,17 @@ static void __secure sunxi_cpu_set_power(int __always_unused cpu, bool on)
sunxi_power_switch(&cpucfg->cpu1_pwr_clamp, &cpucfg->cpu1_pwroff,
on, 0);
}
-#else /* ! CONFIG_MACH_SUN7I */
+#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;
+
+ sunxi_power_switch((void *)cpucfg + SUN8I_R40_PWR_CLAMP(cpu),
+ (void *)cpucfg + SUN8I_R40_PWROFF,
+ on, 0);
+}
+#else /* ! CONFIG_MACH_SUN7I && ! CONFIG_MACH_SUN8I_R40 */
static void __secure sunxi_cpu_set_power(int cpu, bool on)
{
struct sunxi_prcm_reg *prcm =
@@ -213,7 +236,13 @@ int __secure psci_cpu_on(u32 __always_unused unused, u32 mpidr, u32 pc)
psci_save_target_pc(cpu, pc);
/* Set secondary core power on PC */
+#ifdef CONFIG_MACH_SUN8I_R40
+ /* secondary core entry address is programmed differently */
+ writel((u32)&psci_cpu_entry,
+ SUNXI_SRAMC_BASE + SUN8I_R40_SRAMC_SOFT_ENTRY_REG0);
+#else
writel((u32)&psci_cpu_entry, &cpucfg->priv0);
+#endif
/* Assert reset on target CPU */
writel(0, &cpucfg->cpu[cpu].rst);
diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig
index 333872006918..07a40dad26fc 100644
--- a/board/sunxi/Kconfig
+++ b/board/sunxi/Kconfig
@@ -135,6 +135,9 @@ config MACH_SUN8I_H3
config MACH_SUN8I_R40
bool "sun8i (Allwinner R40)"
select CPU_V7
+ select CPU_V7_HAS_NONSEC
+ select CPU_V7_HAS_VIRT
+ select ARCH_SUPPORT_PSCI
select SUNXI_GEN_SUN6I
select SUPPORT_SPL
--
2.11.0
More information about the U-Boot
mailing list