From eff5fb71af047d2e2e958f727e65e45833999dca Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Sun, 29 Jan 2023 09:23:34 +0100 Subject: [PATCH] Allwinner: u-boot: Add missing patches for H2+ --- ...sci-Add-support-for-H3-CPU-0-hotplug.patch | 196 ++++++++++++++++++ ...nable-support-for-SCP-firmware-on-H3.patch | 72 +++++++ 2 files changed, 268 insertions(+) create mode 100644 projects/Allwinner/devices/H2-plus/patches/u-boot/0007-sunxi-psci-Add-support-for-H3-CPU-0-hotplug.patch create mode 100644 projects/Allwinner/devices/H2-plus/patches/u-boot/0010-sunxi-Enable-support-for-SCP-firmware-on-H3.patch diff --git a/projects/Allwinner/devices/H2-plus/patches/u-boot/0007-sunxi-psci-Add-support-for-H3-CPU-0-hotplug.patch b/projects/Allwinner/devices/H2-plus/patches/u-boot/0007-sunxi-psci-Add-support-for-H3-CPU-0-hotplug.patch new file mode 100644 index 0000000000..154a616cb5 --- /dev/null +++ b/projects/Allwinner/devices/H2-plus/patches/u-boot/0007-sunxi-psci-Add-support-for-H3-CPU-0-hotplug.patch @@ -0,0 +1,196 @@ +From f15f4f36e023aaaeacdbebe16736119d1be3ac6b Mon Sep 17 00:00:00 2001 +From: Samuel Holland +Date: Sat, 9 Oct 2021 17:12:57 -0500 +Subject: [PATCH 07/13] sunxi: psci: Add support for H3 CPU 0 hotplug + +Due to a bug in the H3 SoC, where the CPU 0 hotplug flag cannot be +written, resuming CPU 0 requires using the "Super Standby" code path in +the BROM instead of the hotplug path. This path requires jumping to an +eGON image in SRAM. + +Add support to the build system to generate this eGON image and include +it in the FIT, and add code to direct the BROM to its location in SRAM. + +Since the Super Standby code path in the BROM initializes the CPU and +AHB1 clocks to 24 MHz, those registers need to be restored after control +passes back to U-Boot. Furthermore, because the BROM lowers the AHB1 +clock divider to /1 before switching to the lower-frequency parent, +PLL_PERIPH0 must be bypassed to prevent AHB1 from temporarily running at +600 MHz. Otherwise, this locks up the SoC. + +Signed-off-by: Samuel Holland +--- + Makefile | 17 +++++++++++++++++ + arch/arm/cpu/armv7/sunxi/psci.c | 31 +++++++++++++++++++++++++++++++ + arch/arm/dts/sunxi-u-boot.dtsi | 23 ++++++++++++++++++++++- + include/configs/sun8i.h | 4 ++++ + 4 files changed, 74 insertions(+), 1 deletion(-) + +diff --git a/Makefile b/Makefile +index f911f7034430..9edcadfa9c47 100644 +--- a/Makefile ++++ b/Makefile +@@ -984,6 +984,23 @@ endif + endif + endif + ++ifeq ($(CONFIG_MACH_SUN8I_H3)$(CONFIG_ARMV7_PSCI),yy) ++INPUTS-$(CONFIG_ARMV7_PSCI) += u-boot-resume.img ++ ++MKIMAGEFLAGS_u-boot-resume.img := -B 0x400 -T sunxi_egon ++ ++u-boot-resume.img: u-boot-resume.bin ++ $(call if_changed,mkimage) ++ ++OBJCOPYFLAGS_u-boot-resume.bin := -O binary ++ ++u-boot-resume.bin: u-boot-resume.o ++ $(call if_changed,objcopy) ++ ++u-boot-resume.S: u-boot ++ @sed -En 's/(0x[[:xdigit:]]+) +psci_cpu_entry/ldr pc, =\1/p' $<.map > $@ ++endif ++ + INPUTS-$(CONFIG_X86) += u-boot-x86-start16.bin u-boot-x86-reset16.bin \ + $(if $(CONFIG_SPL_X86_16BIT_INIT),spl/u-boot-spl.bin) \ + $(if $(CONFIG_TPL_X86_16BIT_INIT),tpl/u-boot-tpl.bin) +diff --git a/arch/arm/cpu/armv7/sunxi/psci.c b/arch/arm/cpu/armv7/sunxi/psci.c +index 3448fe2edcaa..299bd3ba65e0 100644 +--- a/arch/arm/cpu/armv7/sunxi/psci.c ++++ b/arch/arm/cpu/armv7/sunxi/psci.c +@@ -10,6 +10,7 @@ + #include + #include + ++#include + #include + #include + #include +@@ -141,6 +142,13 @@ static void __secure sunxi_set_entry_address(void *entry) + (struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE; + + writel((u32)entry, &cpucfg->priv0); ++ ++ if (IS_ENABLED(CONFIG_MACH_SUN8I_H3)) { ++ /* Redirect CPU 0 to the secure monitor via the resume shim. */ ++ writel(0x16aaefe8, &cpucfg->super_standy_flag); ++ writel(0xaa16efe8, &cpucfg->super_standy_flag); ++ writel(SUNXI_RESUME_BASE, &cpucfg->priv1); ++ } + } + #endif + +@@ -255,9 +263,12 @@ out: + int __secure psci_cpu_on(u32 __always_unused unused, u32 mpidr, u32 pc, + u32 context_id) + { ++ struct sunxi_ccm_reg *ccu = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + struct sunxi_cpucfg_reg *cpucfg = + (struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE; + u32 cpu = (mpidr & 0x3); ++ u32 cpu_clk; ++ u32 bus_clk; + + /* store target PC and context id */ + psci_save(cpu, pc, context_id); +@@ -274,12 +285,32 @@ int __secure psci_cpu_on(u32 __always_unused unused, u32 mpidr, u32 pc, + /* Lock CPU (Disable external debug access) */ + clrbits_le32(&cpucfg->dbg_ctrl1, BIT(cpu)); + ++ if (IS_ENABLED(CONFIG_MACH_SUN8I_H3) && cpu == 0) { ++ /* Save registers that will be clobbered by the BROM. */ ++ cpu_clk = readl(&ccu->cpu_axi_cfg); ++ bus_clk = readl(&ccu->ahb1_apb1_div); ++ ++ /* Bypass PLL_PERIPH0 so AHB1 frequency does not spike. */ ++ setbits_le32(&ccu->pll6_cfg, BIT(25)); ++ } ++ + /* 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); + ++ if (IS_ENABLED(CONFIG_MACH_SUN8I_H3) && cpu == 0) { ++ /* Spin until the BROM has clobbered the clock registers. */ ++ while (readl(&ccu->ahb1_apb1_div) != 0x00001100); ++ ++ /* Restore the registers and turn off PLL_PERIPH0 bypass. */ ++ writel(cpu_clk, &ccu->cpu_axi_cfg); ++ writel(bus_clk, &ccu->ahb1_apb1_div); ++ ++ clrbits_le32(&ccu->pll6_cfg, BIT(25)); ++ } ++ + /* Unlock CPU (Disable external debug access) */ + setbits_le32(&cpucfg->dbg_ctrl1, BIT(cpu)); + +diff --git a/arch/arm/dts/sunxi-u-boot.dtsi b/arch/arm/dts/sunxi-u-boot.dtsi +index ad1f97632979..a2c74da81aa9 100644 +--- a/arch/arm/dts/sunxi-u-boot.dtsi ++++ b/arch/arm/dts/sunxi-u-boot.dtsi +@@ -6,7 +6,11 @@ + #define ARCH "arm" + #endif + +-#if defined(CONFIG_MACH_SUN50I) || defined(CONFIG_MACH_SUN50I_H5) ++#if defined(CONFIG_MACH_SUN8I_H3) ++#ifdef CONFIG_ARMV7_PSCI ++#define RESUME_ADDR SUNXI_RESUME_BASE ++#endif ++#elif defined(CONFIG_MACH_SUN50I) || defined(CONFIG_MACH_SUN50I_H5) + #define BL31_ADDR 0x00044000 + #define SCP_ADDR 0x00050000 + #elif defined(CONFIG_MACH_SUN50I_H6) +@@ -74,6 +78,20 @@ + }; + #endif + ++#ifdef RESUME_ADDR ++ resume { ++ description = "Super Standby resume image"; ++ type = "standalone"; ++ arch = ARCH; ++ compression = "none"; ++ load = ; ++ ++ blob-ext { ++ filename = "u-boot-resume.img"; ++ }; ++ }; ++#endif ++ + #ifdef SCP_ADDR + scp { + description = "SCP firmware"; +@@ -107,6 +125,9 @@ + firmware = "uboot"; + #endif + loadables = ++#ifdef RESUME_ADDR ++ "resume", ++#endif + #ifdef SCP_ADDR + "scp", + #endif +diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h +index 563635636624..2f0d69bdfce2 100644 +--- a/include/configs/sunxi-common.h ++++ b/include/configs/sunxi-common.h +@@ -15,6 +15,12 @@ + #include + #include + ++#ifdef SUNXI_SRAM_A2_SIZE ++#define SUNXI_RESUME_BASE (CONFIG_ARMV7_SECURE_BASE + \ ++ CONFIG_ARMV7_SECURE_MAX_SIZE) ++#define SUNXI_RESUME_SIZE 1024 ++#endif ++ + /* Serial & console */ + #define CONFIG_SYS_NS16550_SERIAL + /* ns16550 reg in the low bits of cpu reg */ +-- +2.33.0 + diff --git a/projects/Allwinner/devices/H2-plus/patches/u-boot/0010-sunxi-Enable-support-for-SCP-firmware-on-H3.patch b/projects/Allwinner/devices/H2-plus/patches/u-boot/0010-sunxi-Enable-support-for-SCP-firmware-on-H3.patch new file mode 100644 index 0000000000..6c90b79842 --- /dev/null +++ b/projects/Allwinner/devices/H2-plus/patches/u-boot/0010-sunxi-Enable-support-for-SCP-firmware-on-H3.patch @@ -0,0 +1,72 @@ +From 92657de6d2ac3ae100a4d78cc37c729142f1a59b Mon Sep 17 00:00:00 2001 +From: Samuel Holland +Date: Sat, 17 Apr 2021 13:33:54 -0500 +Subject: [PATCH 10/13] sunxi: Enable support for SCP firmware on H3 + +Now that issues with the BROM have been sorted out, we can implement +PSCI system suspend on H3 by delegating to SCP firmware. Let's start by +including the firmware in the FIT image and starting the coprocessor if +valid firmware is loaded. + +Signed-off-by: Samuel Holland +--- + arch/arm/dts/sunxi-u-boot.dtsi | 1 + + board/sunxi/board.c | 8 ++++++++ + include/configs/sun8i.h | 3 +++ + 3 files changed, 12 insertions(+) + +diff --git a/arch/arm/dts/sunxi-u-boot.dtsi b/arch/arm/dts/sunxi-u-boot.dtsi +index a2c74da81aa9..ce062fe94052 100644 +--- a/arch/arm/dts/sunxi-u-boot.dtsi ++++ b/arch/arm/dts/sunxi-u-boot.dtsi +@@ -9,6 +9,7 @@ + #if defined(CONFIG_MACH_SUN8I_H3) + #ifdef CONFIG_ARMV7_PSCI + #define RESUME_ADDR SUNXI_RESUME_BASE ++#define SCP_ADDR SUNXI_SCP_BASE + #endif + #elif defined(CONFIG_MACH_SUN50I) || defined(CONFIG_MACH_SUN50I_H5) + #define BL31_ADDR 0x00044000 +diff --git a/board/sunxi/board.c b/board/sunxi/board.c +index 2b7d655678d0..a25cd11f1124 100644 +--- a/board/sunxi/board.c ++++ b/board/sunxi/board.c +@@ -18,6 +18,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -957,6 +958,13 @@ int board_late_init(void) + usb_ether_init(); + #endif + ++#ifdef SUNXI_SCP_BASE ++ if (!rproc_load(0, SUNXI_SCP_BASE, SUNXI_SCP_MAX_SIZE)) { ++ puts("Starting SCP...\n"); ++ rproc_start(0); ++ } ++#endif ++ + return 0; + } + +diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h +index 2f0d69bdfce2..fda5b235a3e0 100644 +--- a/include/configs/sunxi-common.h ++++ b/include/configs/sunxi-common.h +@@ -26,6 +26,9 @@ + #define SUNXI_RESUME_BASE (CONFIG_ARMV7_SECURE_BASE + \ + CONFIG_ARMV7_SECURE_MAX_SIZE) + #define SUNXI_RESUME_SIZE 1024 ++ ++#define SUNXI_SCP_BASE (SUNXI_RESUME_BASE + SUNXI_RESUME_SIZE) ++#define SUNXI_SCP_MAX_SIZE (16 * 1024) + #endif + + /* +-- +2.33.0 +