uboot-d1: add bootloader for upcoming d1 target
[openwrt/staging/mans0n.git] / package / boot / uboot-d1 / patches / 0037-sunxi-psci-Add-support-for-H3-CPU-0-hotplug.patch
1 From d11c5971f60d482c05f807c24f3ccd37cf7d0f70 Mon Sep 17 00:00:00 2001
2 From: Samuel Holland <samuel@sholland.org>
3 Date: Sat, 9 Oct 2021 17:12:57 -0500
4 Subject: [PATCH 37/90] sunxi: psci: Add support for H3 CPU 0 hotplug
5
6 Due to a bug in the H3 SoC, where the CPU 0 hotplug flag cannot be
7 written, resuming CPU 0 requires using the "Super Standby" code path in
8 the BROM instead of the hotplug path. This path requires jumping to an
9 eGON image in SRAM.
10
11 Add support to the build system to generate this eGON image and include
12 it in the FIT, and add code to direct the BROM to its location in SRAM.
13
14 Since the Super Standby code path in the BROM initializes the CPU and
15 AHB1 clocks to 24 MHz, those registers need to be restored after control
16 passes back to U-Boot. Furthermore, because the BROM lowers the AHB1
17 clock divider to /1 before switching to the lower-frequency parent,
18 PLL_PERIPH0 must be bypassed to prevent AHB1 from temporarily running at
19 600 MHz. Otherwise, this locks up the SoC.
20
21 Signed-off-by: Samuel Holland <samuel@sholland.org>
22 ---
23 Makefile | 17 +++++++++++++++++
24 arch/arm/cpu/armv7/sunxi/psci.c | 31 +++++++++++++++++++++++++++++++
25 arch/arm/dts/sunxi-u-boot.dtsi | 23 ++++++++++++++++++++++-
26 include/configs/sun8i.h | 4 ++++
27 4 files changed, 74 insertions(+), 1 deletion(-)
28
29 --- a/Makefile
30 +++ b/Makefile
31 @@ -1013,6 +1013,23 @@ INPUTS-y += u-boot.img
32 endif
33 endif
34
35 +ifeq ($(CONFIG_MACH_SUN8I_H3)$(CONFIG_ARMV7_PSCI),yy)
36 +INPUTS-$(CONFIG_ARMV7_PSCI) += u-boot-resume.img
37 +
38 +MKIMAGEFLAGS_u-boot-resume.img := -B 0x400 -T sunxi_egon
39 +
40 +u-boot-resume.img: u-boot-resume.bin
41 + $(call if_changed,mkimage)
42 +
43 +OBJCOPYFLAGS_u-boot-resume.bin := -O binary
44 +
45 +u-boot-resume.bin: u-boot-resume.o
46 + $(call if_changed,objcopy)
47 +
48 +u-boot-resume.S: u-boot
49 + @sed -En 's/(0x[[:xdigit:]]+) +psci_cpu_entry/ldr pc, =\1/p' $<.map > $@
50 +endif
51 +
52 INPUTS-$(CONFIG_X86) += u-boot-x86-start16.bin u-boot-x86-reset16.bin \
53 $(if $(CONFIG_SPL_X86_16BIT_INIT),spl/u-boot-spl.bin) \
54 $(if $(CONFIG_TPL_X86_16BIT_INIT),tpl/u-boot-tpl.bin)
55 --- a/arch/arm/cpu/armv7/sunxi/psci.c
56 +++ b/arch/arm/cpu/armv7/sunxi/psci.c
57 @@ -10,6 +10,7 @@
58 #include <common.h>
59 #include <asm/cache.h>
60
61 +#include <asm/arch/clock.h>
62 #include <asm/arch/cpu.h>
63 #include <asm/arch/cpucfg.h>
64 #include <asm/arch/prcm.h>
65 @@ -141,6 +142,13 @@ static void __secure sunxi_set_entry_add
66 (struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE;
67
68 writel((u32)entry, &cpucfg->priv0);
69 +
70 +#ifdef CONFIG_MACH_SUN8I_H3
71 + /* Redirect CPU 0 to the secure monitor via the resume shim. */
72 + writel(0x16aaefe8, &cpucfg->super_standy_flag);
73 + writel(0xaa16efe8, &cpucfg->super_standy_flag);
74 + writel(SUNXI_RESUME_BASE, &cpucfg->priv1);
75 +#endif
76 }
77 #endif
78
79 @@ -255,9 +263,12 @@ out:
80 int __secure psci_cpu_on(u32 __always_unused unused, u32 mpidr, u32 pc,
81 u32 context_id)
82 {
83 + struct sunxi_ccm_reg *ccu = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
84 struct sunxi_cpucfg_reg *cpucfg =
85 (struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE;
86 u32 cpu = (mpidr & 0x3);
87 + u32 cpu_clk;
88 + u32 bus_clk;
89
90 /* store target PC and context id */
91 psci_save(cpu, pc, context_id);
92 @@ -274,12 +285,32 @@ int __secure psci_cpu_on(u32 __always_un
93 /* Lock CPU (Disable external debug access) */
94 clrbits_le32(&cpucfg->dbg_ctrl1, BIT(cpu));
95
96 + if (IS_ENABLED(CONFIG_MACH_SUN8I_H3) && cpu == 0) {
97 + /* Save registers that will be clobbered by the BROM. */
98 + cpu_clk = readl(&ccu->cpu_axi_cfg);
99 + bus_clk = readl(&ccu->ahb1_apb1_div);
100 +
101 + /* Bypass PLL_PERIPH0 so AHB1 frequency does not spike. */
102 + setbits_le32(&ccu->pll6_cfg, BIT(25));
103 + }
104 +
105 /* Power up target CPU */
106 sunxi_cpu_set_power(cpu, true);
107
108 /* De-assert reset on target CPU */
109 writel(BIT(1) | BIT(0), &cpucfg->cpu[cpu].rst);
110
111 + if (IS_ENABLED(CONFIG_MACH_SUN8I_H3) && cpu == 0) {
112 + /* Spin until the BROM has clobbered the clock registers. */
113 + while (readl(&ccu->ahb1_apb1_div) != 0x00001100);
114 +
115 + /* Restore the registers and turn off PLL_PERIPH0 bypass. */
116 + writel(cpu_clk, &ccu->cpu_axi_cfg);
117 + writel(bus_clk, &ccu->ahb1_apb1_div);
118 +
119 + clrbits_le32(&ccu->pll6_cfg, BIT(25));
120 + }
121 +
122 /* Unlock CPU (Disable external debug access) */
123 setbits_le32(&cpucfg->dbg_ctrl1, BIT(cpu));
124
125 --- a/arch/arm/dts/sunxi-u-boot.dtsi
126 +++ b/arch/arm/dts/sunxi-u-boot.dtsi
127 @@ -6,7 +6,11 @@
128 #define ARCH "arm"
129 #endif
130
131 -#if defined(CONFIG_MACH_SUN50I) || defined(CONFIG_MACH_SUN50I_H5)
132 +#if defined(CONFIG_MACH_SUN8I_H3)
133 +#ifdef CONFIG_ARMV7_PSCI
134 +#define RESUME_ADDR SUNXI_RESUME_BASE
135 +#endif
136 +#elif defined(CONFIG_MACH_SUN50I) || defined(CONFIG_MACH_SUN50I_H5)
137 #define BL31_ADDR 0x00044000
138 #define SCP_ADDR 0x00050000
139 #elif defined(CONFIG_MACH_SUN50I_H6)
140 @@ -78,6 +82,20 @@
141 };
142 #endif
143
144 +#ifdef RESUME_ADDR
145 + resume {
146 + description = "Super Standby resume image";
147 + type = "standalone";
148 + arch = ARCH;
149 + compression = "none";
150 + load = <RESUME_ADDR>;
151 +
152 + blob-ext {
153 + filename = "u-boot-resume.img";
154 + };
155 + };
156 +#endif
157 +
158 #ifdef SCP_ADDR
159 scp {
160 description = "SCP firmware";
161 @@ -111,6 +129,9 @@
162 firmware = "uboot";
163 #endif
164 loadables =
165 +#ifdef RESUME_ADDR
166 + "resume",
167 +#endif
168 #ifdef SCP_ADDR
169 "scp",
170 #endif
171 --- a/include/configs/sun8i.h
172 +++ b/include/configs/sun8i.h
173 @@ -8,6 +8,10 @@
174 #ifndef __CONFIG_H
175 #define __CONFIG_H
176
177 +#define SUNXI_RESUME_BASE (CONFIG_ARMV7_SECURE_BASE + \
178 + CONFIG_ARMV7_SECURE_MAX_SIZE)
179 +#define SUNXI_RESUME_SIZE 1024
180 +
181 #include <configs/sunxi-common.h>
182
183 #endif /* __CONFIG_H */