Merge pull request #5754 from jernejsk/crust-update

Allwinner: Crust update
This commit is contained in:
CvH 2021-10-21 19:19:34 +02:00 committed by GitHub
commit a8d3ce056f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 1102 additions and 377 deletions

View File

@ -2,12 +2,12 @@
# Copyright (C) 2020-present Team LibreELEC (https://libreelec.tv)
PKG_NAME="crust"
PKG_VERSION="0.4"
PKG_SHA256="68517674bcddd211499c162ad541e7d04c5da8e91e2b1d78b0e6ece5f3d8da3b"
PKG_VERSION="998a157340c2490af0045b001c3d1bf6d541dbd8" # 2021-10-12
PKG_SHA256="c9f63d2221dadec21540531c42280c19cd66cee3ff36afc736a953772fe55837"
PKG_ARCH="arm aarch64"
PKG_LICENSE="BSD-3c"
PKG_SITE="https://github.com/crust-firmware/crust"
PKG_URL="https://github.com/crust-firmware/crust/archive/v${PKG_VERSION}.tar.gz"
PKG_URL="https://github.com/crust-firmware/crust/archive/${PKG_VERSION}.tar.gz"
PKG_DEPENDS_TARGET="gcc-or1k-linux:host"
PKG_LONGDESC="Crust: Libre SCP firmware for Allwinner sunxi SoCs"
PKG_TOOLCHAIN="manual"

View File

@ -1,29 +1,36 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From 470309271de34eb8c24138f1ac15bd37966ed01a Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Fri, 20 Nov 2020 01:25:26 -0600
Subject: [PATCH] sunxi: A wild PSCI implementation appears...
Date: Sat, 9 Oct 2021 23:01:05 -0500
Subject: [PATCH 13/13] [DO NOT MERGE] sunxi: psci: Delegate PSCI to SCPI
This adds a new PSCI implementation which communicates with SCP firmware
running on the AR100 using the SCPI protocol. This allows it to support
the full set of PSCI v1.1 features, including CPU idle states, system
suspend, and multiple reset methods.
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
arch/arm/cpu/armv7/Kconfig | 1 -
arch/arm/cpu/armv7/Kconfig | 2 +-
arch/arm/cpu/armv7/sunxi/Makefile | 2 +-
arch/arm/cpu/armv7/sunxi/psci-scpi.c | 463 +++++++++++++++++++++++++++
arch/arm/include/asm/psci.h | 9 +-
arch/arm/include/asm/system.h | 13 +-
tools/sunxi_egon.c | 2 +-
6 files changed, 480 insertions(+), 10 deletions(-)
arch/arm/cpu/armv7/sunxi/psci-scpi.c | 451 +++++++++++++++++++++++++++
3 files changed, 453 insertions(+), 2 deletions(-)
create mode 100644 arch/arm/cpu/armv7/sunxi/psci-scpi.c
diff --git a/arch/arm/cpu/armv7/Kconfig b/arch/arm/cpu/armv7/Kconfig
index 06b477619334..948f4e8276fe 100644
--- a/arch/arm/cpu/armv7/Kconfig
+++ b/arch/arm/cpu/armv7/Kconfig
@@ -44,7 +44,6 @@ config ARMV7_PSCI
@@ -44,7 +44,7 @@ config ARMV7_PSCI
choice
prompt "Supported PSCI version"
depends on ARMV7_PSCI
- default ARMV7_PSCI_0_1 if ARCH_SUNXI
+ default ARMV7_PSCI_1_1 if ARCH_SUNXI
default ARMV7_PSCI_1_0
help
Select the supported PSCI version.
diff --git a/arch/arm/cpu/armv7/sunxi/Makefile b/arch/arm/cpu/armv7/sunxi/Makefile
index 1d40d6a18dca..4a0c16deb459 100644
--- a/arch/arm/cpu/armv7/sunxi/Makefile
+++ b/arch/arm/cpu/armv7/sunxi/Makefile
@@ -11,7 +11,7 @@ obj-$(CONFIG_MACH_SUN6I) += tzpc.o
@ -35,25 +42,21 @@ Signed-off-by: Samuel Holland <samuel@sholland.org>
endif
ifdef CONFIG_SPL_BUILD
diff --git a/arch/arm/cpu/armv7/sunxi/psci-scpi.c b/arch/arm/cpu/armv7/sunxi/psci-scpi.c
new file mode 100644
index 000000000000..b3849b366e31
--- /dev/null
+++ b/arch/arm/cpu/armv7/sunxi/psci-scpi.c
@@ -0,0 +1,463 @@
@@ -0,0 +1,451 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2016
+ * Author: Chen-Yu Tsai <wens@csie.org>
+ *
+ * Based on assembly code by Marc Zyngier <marc.zyngier@arm.com>,
+ * which was based on code by Carl van Schaik <carl@ok-labs.com>.
+ * Copyright (C) 2016 Chen-Yu Tsai <wens@csie.org>
+ * Copyright (C) 2018-2021 Samuel Holland <samuel@sholland.org>
+ */
+
+#include <config.h>
+#include <common.h>
+#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>
@ -61,22 +64,34 @@ Signed-off-by: Samuel Holland <samuel@sholland.org>
+#include <asm/secure.h>
+#include <asm/system.h>
+
+#define SUNXI_SCP_BASE 0x00048000
+#define SUNXI_SCP_MAGIC 0xb4400012
+#define GICD_BASE (SUNXI_GIC400_BASE + GIC_DIST_OFFSET)
+#define GICC_BASE (SUNXI_GIC400_BASE + GIC_CPU_OFFSET_A15)
+
+#define OR1K_VEC_FIRST 0x01
+#define OR1K_VEC_LAST 0x0e
+#define OR1K_VEC_ADDR(n) (0x100 * (n))
+#define HW_ON 0
+#define HW_OFF 1
+#define HW_STANDBY 2
+
+#define GICD_BASE (SUNXI_GIC400_BASE + GIC_DIST_OFFSET)
+#define GICC_BASE (SUNXI_GIC400_BASE + GIC_CPU_OFFSET_A15)
+#define MPIDR_AFFLVL0(mpidr) (mpidr & 0xf)
+#define MPIDR_AFFLVL1(mpidr) (mpidr >> 8 & 0xf)
+
+#define HW_ON 0
+#define HW_OFF 1
+#define HW_STANDBY 2
+#define SCPI_SHMEM_BASE 0x0004be00
+#define SCPI_SHMEM ((struct scpi_shmem *)SCPI_SHMEM_BASE)
+
+#define MPIDR_AFFLVL0(mpidr) (mpidr & 0xf)
+#define MPIDR_AFFLVL1(mpidr) (mpidr >> 8 & 0xf)
+#define SCPI_RX_CHANNEL 1
+#define SCPI_TX_CHANNEL 0
+#define SCPI_VIRTUAL_CHANNEL BIT(0)
+
+#define SCPI_MESSAGE_SIZE 0x100
+#define SCPI_PAYLOAD_SIZE (SCPI_MESSAGE_SIZE - sizeof(struct scpi_header))
+
+#define SUNXI_MSGBOX_BASE 0x01c17000
+#define REMOTE_IRQ_STAT_REG (SUNXI_MSGBOX_BASE + 0x0050)
+#define LOCAL_IRQ_STAT_REG (SUNXI_MSGBOX_BASE + 0x0070)
+#define MSG_STAT_REG(n) (SUNXI_MSGBOX_BASE + 0x0140 + 0x4 * (n))
+#define MSG_DATA_REG(n) (SUNXI_MSGBOX_BASE + 0x0180 + 0x4 * (n))
+
+#define RX_IRQ(n) BIT(0 + 2 * (n))
+#define TX_IRQ(n) BIT(1 + 2 * (n))
+
+enum {
+ CORE_POWER_LEVEL = 0,
@ -122,16 +137,6 @@ Signed-off-by: Samuel Holland <samuel@sholland.org>
+ SCPI_SYSTEM_RESET = 0x02,
+};
+
+#define SCPI_SHMEM_BASE 0x0004be00
+#define SCPI_SHMEM ((struct scpi_shmem *)SCPI_SHMEM_BASE)
+
+#define SCPI_MESSAGE_SIZE 0x100
+#define SCPI_PAYLOAD_SIZE (SCPI_MESSAGE_SIZE - sizeof(struct scpi_header))
+
+#define SCPI_RX_CHANNEL 1
+#define SCPI_TX_CHANNEL 0
+#define SCPI_VIRTUAL_CHANNEL BIT(0)
+
+struct scpi_header {
+ u8 command;
+ u8 sender;
@ -149,24 +154,17 @@ Signed-off-by: Samuel Holland <samuel@sholland.org>
+ struct scpi_message tx;
+};
+
+#define SUNXI_MSGBOX_BASE 0x01c17000
+#define REMOTE_IRQ_STAT_REG (SUNXI_MSGBOX_BASE + 0x0050)
+#define LOCAL_IRQ_STAT_REG (SUNXI_MSGBOX_BASE + 0x0070)
+#define MSG_STAT_REG(n) (SUNXI_MSGBOX_BASE + 0x0140 + 0x4 * (n))
+#define MSG_DATA_REG(n) (SUNXI_MSGBOX_BASE + 0x0180 + 0x4 * (n))
+
+#define RX_IRQ(n) BIT(0 + 2 * (n))
+#define TX_IRQ(n) BIT(1 + 2 * (n))
+
+static u32 __secure_data ccu_save[2];
+static bool __secure_data gic_dist_init;
+
+static u32 __secure_data lock;
+
+static inline u32 __secure read_mpidr(void)
+{
+ u32 v;
+ asm volatile ("mrc p15, 0, %0, c0, c0, 5" : "=r" (v));
+ return v;
+ u32 val;
+
+ asm volatile ("mrc p15, 0, %0, c0, c0, 5" : "=r" (val));
+
+ return val;
+}
+
+static void __secure scpi_begin_command(void)
@ -280,15 +278,10 @@ Signed-off-by: Samuel Holland <samuel@sholland.org>
+{
+ u32 target_cpu = read_mpidr();
+
+ if (core_state == SCPI_POWER_OFF) {
+ if (core_state == SCPI_POWER_OFF)
+ psci_save(MPIDR_AFFLVL0(target_cpu), pc, context_id);
+
+ if (MPIDR_AFFLVL0(target_cpu) == 0) {
+ ccu_save[0] = readl(0x1c20050);
+ ccu_save[1] = readl(0x1c20054);
+ writel((ccu_save[1] & ~(3 << 12)) | (1 << 12), 0x1c20054);
+ }
+ }
+ if (css_state == SCPI_POWER_OFF)
+ gic_dist_init = true;
+
+ scpi_set_css_power_state(target_cpu, core_state,
+ cluster_state, css_state);
@ -386,8 +379,8 @@ Signed-off-by: Samuel Holland <samuel@sholland.org>
+s32 __secure psci_cpu_default_suspend(u32 __always_unused function_id,
+ u32 pc, u32 context_id)
+{
+ return psci_suspend_common(pc, context_id, SCPI_POWER_RETENTION,
+ SCPI_POWER_RETENTION, SCPI_POWER_RETENTION);
+ return psci_suspend_common(pc, context_id, SCPI_POWER_OFF,
+ SCPI_POWER_OFF, SCPI_POWER_RETENTION);
+}
+
+s32 __secure psci_node_hw_state(u32 __always_unused function_id,
@ -454,24 +447,21 @@ Signed-off-by: Samuel Holland <samuel@sholland.org>
+ (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
+
+void __secure psci_arch_init(void)
+{
+ static bool __secure_data once;
+
+ /* Be cool with non-secure. */
+ writel(0xff, GICC_BASE + GICC_PMR);
+
+ if (!once) {
+ once = true;
+
+ /* Redirect CPU0 to PSCI. */
+ writel(0x16aaefe8, 0x1f01da0);
+ writel(0xaa16efe8, 0x1f01da0);
+ writel(0x47000, 0x1f01da8);
+ static bool __secure_data one_time_init = true;
+
+ if (one_time_init) {
+ /* Set secondary core power-on PC. */
+ sunxi_set_entry_address(psci_cpu_entry);
+
@ -479,97 +469,36 @@ Signed-off-by: Samuel Holland <samuel@sholland.org>
+ scpi_begin_command();
+ scpi_wait_response();
+ scpi_end_command();
+ } else if (MPIDR_AFFLVL0(read_mpidr()) == 0) {
+ writel(ccu_save[0], 0x1c20050);
+ writel(ccu_save[1], 0x1c20054);
+
+ one_time_init = false;
+ }
+}
+
+void psci_board_init(void)
+{
+ /* Check for a valid SCP firmware, and boot the SCP if found. */
+ if (readl(SUNXI_SCP_BASE) == SUNXI_SCP_MAGIC) {
+ /* Program exception vectors to the firmware entry point. */
+ for (u32 i = OR1K_VEC_FIRST; i <= OR1K_VEC_LAST; ++i) {
+ u32 vector = SUNXI_SRAM_A2_BASE + OR1K_VEC_ADDR(i);
+ u32 offset = SUNXI_SCP_BASE - vector;
+ /*
+ * Copied from arch/arm/cpu/armv7/virt-v7.c
+ * See also gic_resume() in arch/arm/mach-imx/mx7/psci-mx7.c
+ */
+ if (gic_dist_init) {
+ u32 i, itlinesnr;
+
+ writel(offset >> 2, vector);
+ }
+ /* enable the GIC distributor */
+ writel(readl(GICD_BASE + GICD_CTLR) | 0x03, GICD_BASE + GICD_CTLR);
+
+ /* Take the SCP out of reset. */
+ writel(0x1, SUNXI_CPUCFG_BASE);
+ /* TYPER[4:0] contains an encoded number of available interrupts */
+ itlinesnr = readl(GICD_BASE + GICD_TYPER) & 0x1f;
+
+ /* set all bits in the GIC group registers to one to allow access
+ * from non-secure state. The first 32 interrupts are private per
+ * CPU and will be set later when enabling the GIC for each core
+ */
+ for (i = 1; i <= itlinesnr; i++)
+ writel((unsigned)-1, GICD_BASE + GICD_IGROUPRn + 4 * i);
+
+ gic_dist_init = false;
+ }
+
+ /* Be cool with non-secure. */
+ writel(0xff, GICC_BASE + GICC_PMR);
+}
--- a/arch/arm/include/asm/psci.h
+++ b/arch/arm/include/asm/psci.h
@@ -22,8 +22,9 @@
#include <linux/bitops.h>
#endif
-#define ARM_PSCI_VER_1_0 (0x00010000)
#define ARM_PSCI_VER_0_2 (0x00000002)
+#define ARM_PSCI_VER_1_0 (0x00010000)
+#define ARM_PSCI_VER_1_1 (0x00010001)
/* PSCI 0.1 interface */
#define ARM_PSCI_FN_BASE 0x95c1ba5e
@@ -68,7 +69,6 @@
#define ARM_PSCI_0_2_FN64_AFFINITY_INFO ARM_PSCI_0_2_FN64(4)
#define ARM_PSCI_0_2_FN64_MIGRATE ARM_PSCI_0_2_FN64(5)
#define ARM_PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU ARM_PSCI_0_2_FN64(7)
-#define ARM_PSCI_0_2_FN64_SYSTEM_RESET2 ARM_PSCI_0_2_FN64(18)
/* PSCI 1.0 interface */
#define ARM_PSCI_1_0_FN_PSCI_FEATURES ARM_PSCI_0_2_FN(10)
@@ -86,6 +86,11 @@
#define ARM_PSCI_1_0_FN64_STAT_RESIDENCY ARM_PSCI_0_2_FN64(16)
#define ARM_PSCI_1_0_FN64_STAT_COUNT ARM_PSCI_0_2_FN64(17)
+/* PSCI 1.1 interface */
+#define ARM_PSCI_1_1_FN_SYSTEM_RESET2 ARM_PSCI_0_2_FN(18)
+
+#define ARM_PSCI_1_1_FN64_SYSTEM_RESET2 ARM_PSCI_0_2_FN64(18)
+
/* 1KB stack per core */
#define ARM_PSCI_STACK_SHIFT 10
#define ARM_PSCI_STACK_SIZE (1 << ARM_PSCI_STACK_SHIFT)
--- a/arch/arm/include/asm/system.h
+++ b/arch/arm/include/asm/system.h
@@ -535,17 +535,20 @@ void mmu_page_table_flush(unsigned long
#ifdef CONFIG_ARMV7_PSCI
void psci_arch_cpu_entry(void);
void psci_arch_init(void);
+
u32 psci_version(void);
-s32 psci_features(u32 function_id, u32 psci_fid);
+s32 psci_cpu_suspend(u32 function_id, u32 power_state, u32 pc, u32 context_id);
s32 psci_cpu_off(void);
-s32 psci_cpu_on(u32 function_id, u32 target_cpu, u32 pc,
- u32 context_id);
-s32 psci_affinity_info(u32 function_id, u32 target_affinity,
- u32 lowest_affinity_level);
+s32 psci_cpu_on(u32 function_id, u32 target_cpu, u32 pc, u32 context_id);
+s32 psci_affinity_info(u32 function_id, u32 target_affinity, u32 power_level);
u32 psci_migrate_info_type(void);
void psci_system_off(void);
void psci_system_reset(void);
s32 psci_features(u32 function_id, u32 psci_fid);
+s32 psci_cpu_default_suspend(u32 function_id, u32 pc, u32 context_id);
+s32 psci_node_hw_state(u32 function_id, u32 target_cpu, u32 power_level);
+s32 psci_system_suspend(u32 function_id, u32 pc, u32 context_id);
+s32 psci_system_reset2(u32 function_id, u32 reset_type, u32 cookie);
#endif
#endif /* __ASSEMBLY__ */
--- a/tools/sunxi_egon.c
+++ b/tools/sunxi_egon.c
@@ -12,7 +12,7 @@
* NAND requires 8K padding. SD/eMMC gets away with 512 bytes,
* but let's use the larger padding to cover both.
*/
-#define PAD_SIZE 8192
+#define PAD_SIZE 1024
static int egon_check_params(struct image_tool_params *params)
{
--
2.33.0

View File

@ -1,44 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sat, 12 Dec 2020 23:55:04 -0600
Subject: [PATCH] Makefile: Add support for building a sunxi resume shim
---
.gitignore | 1 +
Makefile | 15 +++++++++++++++
2 files changed, 16 insertions(+)
--- a/.gitignore
+++ b/.gitignore
@@ -44,6 +44,7 @@ fit-dtb.blob*
/u-boot*
/boards.cfg
/*.log
+/resume.*
#
# git files that we don't want to ignore even it they are dot-files
--- a/Makefile
+++ b/Makefile
@@ -992,6 +992,21 @@ INPUTS-$(CONFIG_X86) += u-boot-x86-start
$(if $(CONFIG_SPL_X86_16BIT_INIT),spl/u-boot-spl.bin) \
$(if $(CONFIG_TPL_X86_16BIT_INIT),tpl/u-boot-tpl.bin)
+INPUTS-$(CONFIG_ARCH_SUNXI) += resume.egon
+
+MKIMAGEFLAGS_resume.egon := -T sunxi_egon
+
+resume.egon: resume.bin
+ $(call if_changed,mkimage)
+
+OBJCOPYFLAGS_resume.bin := -O binary
+
+resume.bin: resume.o
+ $(call if_changed,objcopy)
+
+resume.S: u-boot
+ @sed -En 's/(0x[[:xdigit:]]+) +psci_cpu_entry/ldr pc, =\1/p' $<.map > $@
+
LDFLAGS_u-boot += $(LDFLAGS_FINAL)
# Avoid 'Not enough room for program headers' error on binutils 2.28 onwards.

View File

@ -1,20 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Wed, 18 Nov 2020 23:27:07 -0600
Subject: [PATCH] sunxi: binman: Explicitly pad SPL to expected size
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
arch/arm/dts/sunxi-u-boot.dtsi | 1 +
1 file changed, 1 insertion(+)
--- a/arch/arm/dts/sunxi-u-boot.dtsi
+++ b/arch/arm/dts/sunxi-u-boot.dtsi
@@ -33,6 +33,7 @@
#ifdef CONFIG_ARM64
fit {
description = "Configuration to load ATF before U-Boot";
+ offset = <CONFIG_SPL_PAD_TO>;
#address-cells = <1>;
fit,fdt-list = "of-list";

View File

@ -1,97 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Wed, 18 Nov 2020 23:31:47 -0600
Subject: [PATCH] sunxi: binman: Support FIT images for 32-bit boards
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
arch/arm/dts/sunxi-u-boot.dtsi | 58 ++++++++++++++++++++++++++++++++++
1 file changed, 58 insertions(+)
--- a/arch/arm/dts/sunxi-u-boot.dtsi
+++ b/arch/arm/dts/sunxi-u-boot.dtsi
@@ -1,5 +1,6 @@
#include <config.h>
+#ifdef CONFIG_ARM64
#ifdef CONFIG_MACH_SUN50I_H6
#define BL31_ADDR 0x104000
#define SCP_ADDR 0x114000
@@ -9,6 +10,9 @@
#define BL31_ADDR 0x44000
#define SCP_ADDR 0x50000
#endif
+#else
+#define SCP_ADDR 0x48000
+#endif
/ {
aliases {
@@ -30,6 +34,7 @@
filename = "spl/sunxi-spl.bin";
};
+#ifdef CONFIG_SPL_FIT
#ifdef CONFIG_ARM64
fit {
description = "Configuration to load ATF before U-Boot";
@@ -103,6 +108,59 @@
};
};
#else
+ fit {
+ description = "Configuration to load SCP firmware with U-Boot";
+ offset = <CONFIG_SPL_PAD_TO>;
+ #address-cells = <1>;
+ fit,fdt-list = "of-list";
+
+ images {
+ uboot {
+ description = "U-Boot (32-bit)";
+ type = "standalone";
+ os = "u-boot";
+ arch = "arm";
+ compression = "none";
+ load = <CONFIG_SYS_TEXT_BASE>;
+
+ u-boot-nodtb {
+ };
+ };
+
+ scp {
+ description = "SCP firmware";
+ type = "firmware";
+ arch = "or1k";
+ compression = "none";
+ load = <SCP_ADDR>;
+
+ scp {
+ filename = "scp.bin";
+ missing-msg = "scp-sunxi";
+ };
+ };
+
+ @fdt-SEQ {
+ description = "NAME";
+ type = "flat_dt";
+ compression = "none";
+
+ };
+ };
+
+ configurations {
+ default = "@config-DEFAULT-SEQ";
+
+ @config-SEQ {
+ description = "NAME";
+ firmware = "uboot";
+ loadables = "scp";
+ fdt = "fdt-SEQ";
+ };
+ };
+ };
+#endif
+#else
u-boot-img {
offset = <CONFIG_SPL_PAD_TO>;
};

View File

@ -1,48 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sun, 13 Dec 2020 00:07:28 -0600
Subject: [PATCH] sunxi: binman: Add a resume shim
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
arch/arm/dts/sunxi-u-boot.dtsi | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
--- a/arch/arm/dts/sunxi-u-boot.dtsi
+++ b/arch/arm/dts/sunxi-u-boot.dtsi
@@ -12,6 +12,7 @@
#endif
#else
#define SCP_ADDR 0x48000
+#define RESUME_ADDR 0x47000
#endif
/ {
@@ -127,6 +128,18 @@
};
};
+ resume {
+ description = "resume shim";
+ type = "standalone";
+ arch = "arm";
+ compression = "none";
+ load = <RESUME_ADDR>;
+
+ blob-ext {
+ filename = "resume.egon";
+ };
+ };
+
scp {
description = "SCP firmware";
type = "firmware";
@@ -154,7 +167,7 @@
@config-SEQ {
description = "NAME";
firmware = "uboot";
- loadables = "scp";
+ loadables = "resume", "scp";
fdt = "fdt-SEQ";
};
};

View File

@ -0,0 +1,29 @@
From 7b4ff873927b131df05449df873cdf91958517a8 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sat, 9 Oct 2021 10:40:45 -0500
Subject: [PATCH 01/13] Kconfig: Remove an impossible condition
ARCH_SUNXI selects BINMAN, so the condition "!BINMAN && ARCH_SUNXI"
is impossible.
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Kconfig b/Kconfig
index 931a22806e4e..ede20d74c948 100644
--- a/Kconfig
+++ b/Kconfig
@@ -359,7 +359,7 @@ config BUILD_TARGET
default "u-boot-spl.kwb" if ARCH_MVEBU && SPL
default "u-boot-elf.srec" if RCAR_GEN3
default "u-boot.itb" if !BINMAN && SPL_LOAD_FIT && (ARCH_ROCKCHIP || \
- ARCH_SUNXI || RISCV || ARCH_ZYNQMP)
+ RISCV || ARCH_ZYNQMP)
default "u-boot.kwb" if ARCH_KIRKWOOD
default "u-boot-with-spl.bin" if ARCH_AT91 && SPL_NAND_SUPPORT
default "u-boot-with-spl.imx" if ARCH_MX6 && SPL
--
2.33.0

View File

@ -0,0 +1,38 @@
From a2f92f02abaae9df68759586102438df6f8d5efb Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sat, 9 Oct 2021 10:43:56 -0500
Subject: [PATCH 02/13] binman: Prevent entries in a section from overlapping
Currently, if the "offset" property is given for an entry, the section's
running offset is completely ignored. This causes entries to overlap if
the provided offset is less than the size of the entries earlier in the
section. Avoid the overlap by only using the provided offset when it is
greater than the running offset.
The motivation for this change is the rule used by SPL to find U-Boot on
sunxi boards: U-Boot starts 32 KiB after the start of SPL, unless SPL is
larger than 32 KiB, in which case U-Boot immediately follows SPL.
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
tools/binman/entry.py | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/tools/binman/entry.py b/tools/binman/entry.py
index 70222718ea93..61822eb5e44f 100644
--- a/tools/binman/entry.py
+++ b/tools/binman/entry.py
@@ -404,7 +404,9 @@ class Entry(object):
if self.offset_unset:
self.Raise('No offset set with offset-unset: should another '
'entry provide this correct offset?')
- self.offset = tools.Align(offset, self.align)
+ elif self.offset > offset:
+ offset = self.offset
+ self.offset = tools.Align(offset, self.align)
needed = self.pad_before + self.contents_size + self.pad_after
needed = tools.Align(needed, self.align_size)
size = self.size
--
2.33.0

View File

@ -0,0 +1,162 @@
From 45a9ce4ec981ab55b4a4374879348496877df75d Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sat, 17 Apr 2021 13:33:54 -0500
Subject: [PATCH 03/13] sunxi: binman: Enable SPL FIT loading for 32-bit SoCs
Now that Crust (SCP firmware) has support for H3, we need a FIT image to
load it. H3 also needs to load a SoC-specific eGon blob to support CPU 0
hotplug.
Update the binman description to work on either 32-bit or 64-bit SoCs:
- Make BL31 optional, since it is not used on 32-bit SoCs (though BL32
may be used in the future).
- Explicitly set the minimum offset of the FIT to 32 KiB, since SPL on
some boards is still only 24 KiB large even with FIT support enabled.
CONFIG_SPL_PAD_TO cannot be used because it is not defined for H616.
FIT unlocks more features (signatures, multiple DTBs, etc.), so enable
it by default. A10 (sun4i) only has 24 KiB of SRAM A1, so it needs
SPL_FIT_IMAGE_TINY. For simplicity, enable that option everywhere.
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
arch/arm/Kconfig | 1 +
arch/arm/dts/sunxi-u-boot.dtsi | 46 ++++++++++++++++++++++------------
common/spl/Kconfig | 3 +--
3 files changed, 32 insertions(+), 18 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index ebb19272708d..cb321b6afac3 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1032,6 +1032,7 @@ config ARCH_SUNXI
imply SPL_GPIO
imply SPL_LIBCOMMON_SUPPORT
imply SPL_LIBGENERIC_SUPPORT
+ imply SPL_LOAD_FIT
imply SPL_MMC_SUPPORT if MMC
imply SPL_POWER
imply SPL_SERIAL_SUPPORT
diff --git a/arch/arm/dts/sunxi-u-boot.dtsi b/arch/arm/dts/sunxi-u-boot.dtsi
index 4a6ed3a7dd5c..ad1f97632979 100644
--- a/arch/arm/dts/sunxi-u-boot.dtsi
+++ b/arch/arm/dts/sunxi-u-boot.dtsi
@@ -1,13 +1,19 @@
#include <config.h>
-#ifdef CONFIG_MACH_SUN50I_H6
-#define BL31_ADDR 0x104000
-#define SCP_ADDR 0x114000
+#ifdef CONFIG_ARM64
+#define ARCH "arm64"
+#else
+#define ARCH "arm"
+#endif
+
+#if defined(CONFIG_MACH_SUN50I) || defined(CONFIG_MACH_SUN50I_H5)
+#define BL31_ADDR 0x00044000
+#define SCP_ADDR 0x00050000
+#elif defined(CONFIG_MACH_SUN50I_H6)
+#define BL31_ADDR 0x00104000
+#define SCP_ADDR 0x00114000
#elif defined(CONFIG_MACH_SUN50I_H616)
-#define BL31_ADDR 0x40000000
-#else
-#define BL31_ADDR 0x44000
-#define SCP_ADDR 0x50000
+#define BL31_ADDR 0x40000000
#endif
/ {
@@ -30,30 +36,33 @@
filename = "spl/sunxi-spl.bin";
};
-#ifdef CONFIG_ARM64
+#ifdef CONFIG_SPL_LOAD_FIT
fit {
- description = "Configuration to load ATF before U-Boot";
+ description = "Configuration to load U-Boot and firmware";
+ offset = <32768>;
#address-cells = <1>;
fit,fdt-list = "of-list";
images {
uboot {
- description = "U-Boot (64-bit)";
+ description = "U-Boot";
type = "standalone";
os = "u-boot";
- arch = "arm64";
+ arch = ARCH;
compression = "none";
load = <CONFIG_SYS_TEXT_BASE>;
+ entry = <CONFIG_SYS_TEXT_BASE>;
u-boot-nodtb {
};
};
+#ifdef BL31_ADDR
atf {
description = "ARM Trusted Firmware";
type = "firmware";
os = "arm-trusted-firmware";
- arch = "arm64";
+ arch = ARCH;
compression = "none";
load = <BL31_ADDR>;
entry = <BL31_ADDR>;
@@ -63,6 +72,7 @@
missing-msg = "atf-bl31-sunxi";
};
};
+#endif
#ifdef SCP_ADDR
scp {
@@ -91,19 +101,23 @@
@config-SEQ {
description = "NAME";
+#ifdef BL31_ADDR
firmware = "atf";
-#ifndef SCP_ADDR
- loadables = "uboot";
#else
- loadables = "scp", "uboot";
+ firmware = "uboot";
#endif
+ loadables =
+#ifdef SCP_ADDR
+ "scp",
+#endif
+ "uboot";
fdt = "fdt-SEQ";
};
};
};
#else
u-boot-img {
- offset = <CONFIG_SPL_PAD_TO>;
+ offset = <32768>;
};
#endif
};
diff --git a/common/spl/Kconfig b/common/spl/Kconfig
index 8a8a971a91e1..374818c05741 100644
--- a/common/spl/Kconfig
+++ b/common/spl/Kconfig
@@ -442,8 +442,7 @@ config SPL_MD5
config SPL_FIT_IMAGE_TINY
bool "Remove functionality from SPL FIT loading to reduce size"
depends on SPL_FIT
- default y if MACH_SUN50I || MACH_SUN50I_H5 || SUN50I_GEN_H6
- default y if ARCH_IMX8M
+ default y if ARCH_IMX8M || ARCH_SUNXI
help
Enable this to reduce the size of the FIT image loading code
in SPL, if space for the SPL binary is very tight.
--
2.33.0

View File

@ -0,0 +1,36 @@
From 0b5a16d893ed0ce5ac1126663c3eb9b1254e008c Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sat, 9 Oct 2021 11:33:46 -0500
Subject: [PATCH 04/13] sunxi: A23/A33/H3: Actually move the secure monitor
commit 1ebfc0c631e3 ("sunxi: A23/A33/H3: Move sun8i secure monitor to
SRAM A2") attempted to move the secure monitor to SRAM A2. But not all
sun8i SoCs have SRAM A2, so a check was put in for SUNXI_SRAM_A2_SIZE to
avoid breaking those SoCs.
However, because the header providing SUNXI_SRAM_A2_SIZE was not
included, this unintentionally skipped the new definitions on all SoCs.
Fix this by including the right header.
Fixes: 1ebfc0c631e3 ("sunxi: A23/A33/H3: Move sun8i secure monitor to SRAM A2")
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
include/configs/sun8i.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/include/configs/sun8i.h b/include/configs/sun8i.h
index 27c9808a494a..563635636624 100644
--- a/include/configs/sun8i.h
+++ b/include/configs/sun8i.h
@@ -12,6 +12,8 @@
* A23 specific configuration
*/
+#include <asm/arch/cpu.h>
+
#ifdef SUNXI_SRAM_A2_SIZE
/*
* If the SoC has enough SRAM A2, use that for the secure monitor.
--
2.33.0

View File

@ -0,0 +1,56 @@
From c7bb6bf4bcee8577c3af0e2345c1bdc0925f9468 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sat, 9 Oct 2021 22:00:22 -0500
Subject: [PATCH 05/13] sunxi: psci: Avoid hanging when CPU 0 is hot-unplugged
Do not try to send an SGI from CPU 0 to itself. Since FIQs are masked
when entering monitor mode, this will hang. Plus, CPU 0 cannot fully
power itself off anyway. Instead, have it turn FIQs back on and continue
servicing SGIs from other cores.
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
arch/arm/cpu/armv7/sunxi/psci.c | 20 +++++++++++++++++---
1 file changed, 17 insertions(+), 3 deletions(-)
diff --git a/arch/arm/cpu/armv7/sunxi/psci.c b/arch/arm/cpu/armv7/sunxi/psci.c
index 1ac50f558a40..3448fe2edcaa 100644
--- a/arch/arm/cpu/armv7/sunxi/psci.c
+++ b/arch/arm/cpu/armv7/sunxi/psci.c
@@ -38,6 +38,15 @@
#define SUN8I_R40_PWR_CLAMP(cpu) (0x120 + (cpu) * 0x4)
#define SUN8I_R40_SRAMC_SOFT_ENTRY_REG0 (0xbc)
+static inline u32 __secure cp15_read_mpidr(void)
+{
+ u32 val;
+
+ asm volatile ("mrc p15, 0, %0, c0, c0, 5" : "=r" (val));
+
+ return val;
+}
+
static void __secure cp15_write_cntp_tval(u32 tval)
{
asm volatile ("mcr p15, 0, %0, c14, c2, 0" : : "r" (tval));
@@ -281,9 +290,14 @@ s32 __secure psci_cpu_off(void)
{
psci_cpu_off_common();
- /* Ask CPU0 via SGI15 to pull the rug... */
- writel(BIT(16) | 15, GICD_BASE + GICD_SGIR);
- dsb();
+ if (cp15_read_mpidr() & 3) {
+ /* Ask CPU0 via SGI15 to pull the rug... */
+ writel(BIT(16) | 15, GICD_BASE + GICD_SGIR);
+ dsb();
+ } else {
+ /* Unmask FIQs to service SGI15. */
+ asm volatile ("cpsie f");
+ }
/* Wait to be turned off */
while (1)
--
2.33.0

View File

@ -0,0 +1,54 @@
From f71f348d1a96baf265e08850320a43c893ac75a4 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sat, 17 Apr 2021 14:50:12 -0500
Subject: [PATCH 06/13] mkimage: sunxi_egon: Allow overriding the padding size
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.
This resume image, whose only purpose is to jump back to the secure
monitor, contains a single instruction. Padding the image to 8 KiB would
be wasteful of SRAM. Hook up the -B (block size) option so users can set
the block/padding size.
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
tools/sunxi_egon.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/tools/sunxi_egon.c b/tools/sunxi_egon.c
index a5299eb6a115..d1398c07fb08 100644
--- a/tools/sunxi_egon.c
+++ b/tools/sunxi_egon.c
@@ -10,9 +10,10 @@
/*
* NAND requires 8K padding. SD/eMMC gets away with 512 bytes,
- * but let's use the larger padding to cover both.
+ * but let's use the larger padding by default to cover both.
*/
#define PAD_SIZE 8192
+#define PAD_SIZE_MIN 512
static int egon_check_params(struct image_tool_params *params)
{
@@ -114,10 +115,12 @@ static int egon_check_image_type(uint8_t type)
static int egon_vrec_header(struct image_tool_params *params,
struct image_type_params *tparams)
{
+ int pad_size = ALIGN(params->bl_len ?: PAD_SIZE, PAD_SIZE_MIN);
+
tparams->hdr = calloc(sizeof(struct boot_file_head), 1);
- /* Return padding to 8K blocks. */
- return ALIGN(params->file_size, PAD_SIZE) - params->file_size;
+ /* Return padding to complete blocks. */
+ return ALIGN(params->file_size, pad_size) - params->file_size;
}
U_BOOT_IMAGE_TYPE(
--
2.33.0

View File

@ -0,0 +1,194 @@
From f15f4f36e023aaaeacdbebe16736119d1be3ac6b Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
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 <samuel@sholland.org>
---
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 <common.h>
#include <asm/cache.h>
+#include <asm/arch/clock.h>
#include <asm/arch/cpu.h>
#include <asm/arch/cpucfg.h>
#include <asm/arch/prcm.h>
@@ -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 = <RESUME_ADDR>;
+
+ 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/sun8i.h b/include/configs/sun8i.h
index 563635636624..2f0d69bdfce2 100644
--- a/include/configs/sun8i.h
+++ b/include/configs/sun8i.h
@@ -22,6 +22,10 @@
*/
#define CONFIG_ARMV7_SECURE_BASE (SUNXI_SRAM_A2_BASE + 16 * 1024)
#define CONFIG_ARMV7_SECURE_MAX_SIZE (SUNXI_SRAM_A2_SIZE - 33 * 1024)
+
+#define SUNXI_RESUME_BASE (CONFIG_ARMV7_SECURE_BASE + \
+ CONFIG_ARMV7_SECURE_MAX_SIZE)
+#define SUNXI_RESUME_SIZE 1024
#endif
/*
--
2.33.0

View File

@ -0,0 +1,165 @@
From 9f1a0739ddd535b25fe07f7be9cc18aeaa5181c7 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sat, 9 Oct 2021 14:58:27 -0500
Subject: [PATCH 08/13] remoteproc: Add a driver for the Allwinner AR100
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
drivers/remoteproc/Kconfig | 9 ++
drivers/remoteproc/Makefile | 1 +
drivers/remoteproc/sun6i_ar100_rproc.c | 111 +++++++++++++++++++++++++
3 files changed, 121 insertions(+)
create mode 100644 drivers/remoteproc/sun6i_ar100_rproc.c
diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index 24e536463bbd..9789623ebee5 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -41,6 +41,15 @@ config REMOTEPROC_STM32_COPRO
Say 'y' here to add support for STM32 Cortex-M4 coprocessors via the
remoteproc framework.
+config REMOTEPROC_SUN6I_AR100
+ bool "Support for Allwinner AR100 SCP"
+ select REMOTEPROC
+ depends on ARCH_SUNXI
+ help
+ Say 'y' here to support Allwinner's AR100 System Control Processor
+ (SCP), found in various sun6i/sun8i/sun50i family SoCs, through the
+ remoteproc framework.
+
config REMOTEPROC_TI_K3_ARM64
bool "Support for TI's K3 based ARM64 remoteproc driver"
select REMOTEPROC
diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
index f0e83451d66f..022e64f2053e 100644
--- a/drivers/remoteproc/Makefile
+++ b/drivers/remoteproc/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_$(SPL_)REMOTEPROC) += rproc-uclass.o rproc-elf-loader.o
obj-$(CONFIG_K3_SYSTEM_CONTROLLER) += k3_system_controller.o
obj-$(CONFIG_REMOTEPROC_SANDBOX) += sandbox_testproc.o
obj-$(CONFIG_REMOTEPROC_STM32_COPRO) += stm32_copro.o
+obj-$(CONFIG_REMOTEPROC_SUN6I_AR100) += sun6i_ar100_rproc.o
obj-$(CONFIG_REMOTEPROC_TI_K3_ARM64) += ti_k3_arm64_rproc.o
obj-$(CONFIG_REMOTEPROC_TI_K3_DSP) += ti_k3_dsp_rproc.o
obj-$(CONFIG_REMOTEPROC_TI_K3_R5F) += ti_k3_r5f_rproc.o
diff --git a/drivers/remoteproc/sun6i_ar100_rproc.c b/drivers/remoteproc/sun6i_ar100_rproc.c
new file mode 100644
index 000000000000..c94f6c752bdd
--- /dev/null
+++ b/drivers/remoteproc/sun6i_ar100_rproc.c
@@ -0,0 +1,111 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <dm.h>
+#include <errno.h>
+#include <remoteproc.h>
+#include <asm/io.h>
+
+#define SUNXI_SCP_MAGIC 0xb4400012
+
+#define OR1K_VEC_FIRST 0x01
+#define OR1K_VEC_LAST 0x0e
+#define OR1K_VEC_ADDR(n) (0x100 * (n))
+
+struct sun6i_ar100_rproc_priv {
+ void *cfg_base;
+ ulong sram_base;
+};
+
+static int sun6i_ar100_rproc_load(struct udevice *dev, ulong addr, ulong size)
+{
+ struct sun6i_ar100_rproc_priv *priv = dev_get_priv(dev);
+
+ /* Check for a valid SCP firmware. */
+ if (readl_relaxed(addr) != SUNXI_SCP_MAGIC)
+ return -ENOENT;
+
+ /* Program exception vectors to the firmware entry point. */
+ for (u32 i = OR1K_VEC_FIRST; i <= OR1K_VEC_LAST; ++i) {
+ ulong vector = priv->sram_base + OR1K_VEC_ADDR(i);
+ ulong offset = addr - vector;
+
+ writel_relaxed(offset >> 2, vector);
+ }
+
+ return 0;
+}
+
+static int sun6i_ar100_rproc_start(struct udevice *dev)
+{
+ struct sun6i_ar100_rproc_priv *priv = dev_get_priv(dev);
+
+ setbits_le32(priv->cfg_base, BIT(0));
+
+ return 0;
+}
+
+static int sun6i_ar100_rproc_stop(struct udevice *dev)
+{
+ struct sun6i_ar100_rproc_priv *priv = dev_get_priv(dev);
+
+ clrbits_le32(priv->cfg_base, BIT(0));
+
+ return 0;
+}
+
+static int sun6i_ar100_rproc_reset(struct udevice *dev)
+{
+ int ret;
+
+ ret = sun6i_ar100_rproc_stop(dev);
+ if (ret)
+ return ret;
+
+ return sun6i_ar100_rproc_start(dev);
+}
+
+static int sun6i_ar100_rproc_is_running(struct udevice *dev)
+{
+ struct sun6i_ar100_rproc_priv *priv = dev_get_priv(dev);
+
+ return !(readl_relaxed(priv->cfg_base) & BIT(0));
+}
+
+static const struct dm_rproc_ops sun6i_ar100_rproc_ops = {
+ .load = sun6i_ar100_rproc_load,
+ .start = sun6i_ar100_rproc_start,
+ .stop = sun6i_ar100_rproc_stop,
+ .reset = sun6i_ar100_rproc_reset,
+ .is_running = sun6i_ar100_rproc_is_running,
+};
+
+static int sun6i_ar100_rproc_probe(struct udevice *dev)
+{
+ struct sun6i_ar100_rproc_priv *priv = dev_get_priv(dev);
+ struct ofnode_phandle_args sram_handle;
+ int ret;
+
+ priv->cfg_base = dev_read_addr_ptr(dev);
+
+ ret = dev_read_phandle_with_args(dev, "sram", NULL, 0, 0, &sram_handle);
+ if (ret)
+ return ret;
+
+ priv->sram_base = ofnode_get_addr(sram_handle.node);
+
+ return 0;
+}
+
+static const struct udevice_id sun6i_ar100_rproc_ids[] = {
+ { .compatible = "allwinner,sun6i-a31-ar100" },
+ { }
+};
+
+U_BOOT_DRIVER(sun6i_ar100_rproc) = {
+ .name = "sun6i_ar100_rproc",
+ .id = UCLASS_REMOTEPROC,
+ .of_match = sun6i_ar100_rproc_ids,
+ .probe = sun6i_ar100_rproc_probe,
+ .priv_auto = sizeof(struct sun6i_ar100_rproc_priv),
+ .ops = &sun6i_ar100_rproc_ops,
+};
--
2.33.0

View File

@ -0,0 +1,45 @@
From 910c452284dfbc086d9dfb18feb1b6c1b95f2eeb Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sat, 9 Oct 2021 15:04:16 -0500
Subject: [PATCH 09/13] arm: dts: sunxi: h3: Add nodes for AR100 remoteproc
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
arch/arm/dts/sun8i-h3.dtsi | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/arch/arm/dts/sun8i-h3.dtsi b/arch/arm/dts/sun8i-h3.dtsi
index 4e89701df91f..076f0716da46 100644
--- a/arch/arm/dts/sun8i-h3.dtsi
+++ b/arch/arm/dts/sun8i-h3.dtsi
@@ -170,6 +170,14 @@
#size-cells = <1>;
ranges;
+ sram_a2: sram@40000 {
+ compatible = "mmio-sram";
+ reg = <0x00040000 0xc000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x00040000 0xc000>;
+ };
+
sram_c: sram@1d00000 {
compatible = "mmio-sram";
reg = <0x01d00000 0x80000>;
@@ -239,6 +247,12 @@
nvmem-cell-names = "calibration";
#thermal-sensor-cells = <0>;
};
+
+ remoteproc@1f01c00 {
+ compatible = "allwinner,sun6i-a31-ar100";
+ reg = <0x01f01c00 0x400>;
+ sram = <&sram_a2>;
+ };
};
thermal-zones {
--
2.33.0

View File

@ -0,0 +1,72 @@
From 92657de6d2ac3ae100a4d78cc37c729142f1a59b Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
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 <samuel@sholland.org>
---
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 <init.h>
#include <log.h>
#include <mmc.h>
+#include <remoteproc.h>
#include <axp_pmic.h>
#include <generic-phy.h>
#include <phy-sun4i-usb.h>
@@ -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/sun8i.h b/include/configs/sun8i.h
index 2f0d69bdfce2..fda5b235a3e0 100644
--- a/include/configs/sun8i.h
+++ b/include/configs/sun8i.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

View File

@ -0,0 +1,129 @@
From 7719c6f06b698b3a32248dea61710f222ee8d7a1 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sat, 9 Oct 2021 22:43:26 -0500
Subject: [PATCH 11/13] arm: psci: Add definitions for PSCI v1.1
Add the new option, function IDs, and prototypes for PSCI v1.1
implementations. In the process, fix some issues with the existing
definitions:
- Fix the incorrectly-named ARM_PSCI_0_2_FN64_SYSTEM_RESET2.
- Replace the deprecated "affinity_level" naming with "power_level".
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
arch/arm/cpu/armv7/Kconfig | 3 +++
arch/arm/cpu/armv8/fwcall.c | 2 +-
arch/arm/include/asm/psci.h | 9 +++++++--
arch/arm/include/asm/system.h | 14 +++++++++-----
arch/arm/lib/psci-dt.c | 2 ++
5 files changed, 22 insertions(+), 8 deletions(-)
diff --git a/arch/arm/cpu/armv7/Kconfig b/arch/arm/cpu/armv7/Kconfig
index 60bb0a9e1ec4..06b477619334 100644
--- a/arch/arm/cpu/armv7/Kconfig
+++ b/arch/arm/cpu/armv7/Kconfig
@@ -49,6 +49,9 @@ choice
help
Select the supported PSCI version.
+config ARMV7_PSCI_1_1
+ bool "PSCI V1.1"
+
config ARMV7_PSCI_1_0
bool "PSCI V1.0"
diff --git a/arch/arm/cpu/armv8/fwcall.c b/arch/arm/cpu/armv8/fwcall.c
index 16914dc1eed6..87de09979b18 100644
--- a/arch/arm/cpu/armv8/fwcall.c
+++ b/arch/arm/cpu/armv8/fwcall.c
@@ -103,7 +103,7 @@ void __noreturn psci_system_reset2(u32 reset_level, u32 cookie)
{
struct pt_regs regs;
- regs.regs[0] = ARM_PSCI_0_2_FN64_SYSTEM_RESET2;
+ regs.regs[0] = ARM_PSCI_1_1_FN64_SYSTEM_RESET2;
regs.regs[1] = PSCI_RESET2_TYPE_VENDOR | reset_level;
regs.regs[2] = cookie;
if (use_smc_for_psci)
diff --git a/arch/arm/include/asm/psci.h b/arch/arm/include/asm/psci.h
index 67e9234066b0..aa351867eee7 100644
--- a/arch/arm/include/asm/psci.h
+++ b/arch/arm/include/asm/psci.h
@@ -22,8 +22,9 @@
#include <linux/bitops.h>
#endif
-#define ARM_PSCI_VER_1_0 (0x00010000)
#define ARM_PSCI_VER_0_2 (0x00000002)
+#define ARM_PSCI_VER_1_0 (0x00010000)
+#define ARM_PSCI_VER_1_1 (0x00010001)
/* PSCI 0.1 interface */
#define ARM_PSCI_FN_BASE 0x95c1ba5e
@@ -68,7 +69,6 @@
#define ARM_PSCI_0_2_FN64_AFFINITY_INFO ARM_PSCI_0_2_FN64(4)
#define ARM_PSCI_0_2_FN64_MIGRATE ARM_PSCI_0_2_FN64(5)
#define ARM_PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU ARM_PSCI_0_2_FN64(7)
-#define ARM_PSCI_0_2_FN64_SYSTEM_RESET2 ARM_PSCI_0_2_FN64(18)
/* PSCI 1.0 interface */
#define ARM_PSCI_1_0_FN_PSCI_FEATURES ARM_PSCI_0_2_FN(10)
@@ -86,6 +86,11 @@
#define ARM_PSCI_1_0_FN64_STAT_RESIDENCY ARM_PSCI_0_2_FN64(16)
#define ARM_PSCI_1_0_FN64_STAT_COUNT ARM_PSCI_0_2_FN64(17)
+/* PSCI 1.1 interface */
+#define ARM_PSCI_1_1_FN_SYSTEM_RESET2 ARM_PSCI_0_2_FN(18)
+
+#define ARM_PSCI_1_1_FN64_SYSTEM_RESET2 ARM_PSCI_0_2_FN64(18)
+
/* 1KB stack per core */
#define ARM_PSCI_STACK_SHIFT 10
#define ARM_PSCI_STACK_SIZE (1 << ARM_PSCI_STACK_SHIFT)
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
index f75eea16b36c..02effcc6cc38 100644
--- a/arch/arm/include/asm/system.h
+++ b/arch/arm/include/asm/system.h
@@ -556,17 +556,20 @@ void mmu_page_table_flush(unsigned long start, unsigned long stop);
#ifdef CONFIG_ARMV7_PSCI
void psci_arch_cpu_entry(void);
void psci_arch_init(void);
+
u32 psci_version(void);
-s32 psci_features(u32 function_id, u32 psci_fid);
+s32 psci_cpu_suspend(u32 function_id, u32 power_state, u32 pc, u32 context_id);
s32 psci_cpu_off(void);
-s32 psci_cpu_on(u32 function_id, u32 target_cpu, u32 pc,
- u32 context_id);
-s32 psci_affinity_info(u32 function_id, u32 target_affinity,
- u32 lowest_affinity_level);
+s32 psci_cpu_on(u32 function_id, u32 target_cpu, u32 pc, u32 context_id);
+s32 psci_affinity_info(u32 function_id, u32 target_affinity, u32 power_level);
u32 psci_migrate_info_type(void);
void psci_system_off(void);
void psci_system_reset(void);
-s32 psci_features(u32 function_id, u32 psci_fid);
+s32 psci_features(u32 function_id, u32 psci_fid);
+s32 psci_cpu_default_suspend(u32 function_id, u32 pc, u32 context_id);
+s32 psci_node_hw_state(u32 function_id, u32 target_cpu, u32 power_level);
+s32 psci_system_suspend(u32 function_id, u32 pc, u32 context_id);
+s32 psci_system_reset2(u32 function_id, u32 reset_type, u32 cookie);
#endif
#endif /* __ASSEMBLY__ */
diff --git a/arch/arm/lib/psci-dt.c b/arch/arm/lib/psci-dt.c
index 903b3357048a..ea9d1c8355c2 100644
--- a/arch/arm/lib/psci-dt.c
+++ b/arch/arm/lib/psci-dt.c
@@ -66,6 +66,8 @@ int fdt_psci(void *fdt)
init_psci_node:
#if CONFIG_IS_ENABLED(ARMV8_SEC_FIRMWARE_SUPPORT)
psci_ver = sec_firmware_support_psci_version();
+#elif defined(CONFIG_ARMV7_PSCI_1_1)
+ psci_ver = ARM_PSCI_VER_1_1;
#elif defined(CONFIG_ARMV7_PSCI_1_0) || defined(CONFIG_ARMV8_PSCI)
psci_ver = ARM_PSCI_VER_1_0;
#elif defined(CONFIG_ARMV7_PSCI_0_2)
--
2.33.0

View File

@ -0,0 +1,25 @@
From 3fe205fc0e4c81cddbd3b7adacf29e0819f3672f Mon Sep 17 00:00:00 2001
From: Jernej Skrabec <jernej.skrabec@gmail.com>
Date: Tue, 12 Oct 2021 20:45:10 +0200
Subject: [PATCH] [DO NOT MERGE] sunxi: Enable remoteproc on H3
Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
---
arch/arm/mach-sunxi/Kconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index 1d4a4fdd0c59..4414b847b7e4 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -295,6 +295,7 @@ config MACH_SUN8I_H3
select CPU_V7_HAS_VIRT
select ARCH_SUPPORT_PSCI
select MACH_SUNXI_H3_H5
+ select REMOTEPROC_SUN6I_AR100
select ARMV7_BOOT_SEC_DEFAULT if OLD_SUNXI_KERNEL_COMPAT
config MACH_SUN8I_R40
--
2.33.0