diff --git a/projects/Allwinner/bootloader/config b/projects/Allwinner/bootloader/config index 16e79f69ea..a8dbc343fb 100644 --- a/projects/Allwinner/bootloader/config +++ b/projects/Allwinner/bootloader/config @@ -5,3 +5,5 @@ CONFIG_BOOTDELAY=0 CONFIG_MACPWR="" # CONFIG_EFI_LOADER is not set +CONFIG_SPL_LOAD_FIT=y +CONFIG_SPL_FIT_IMAGE_TINY=y diff --git a/projects/Allwinner/devices/H3/patches/u-boot/0001-sunxi-Factor-out-eGON-BROM-header-description.patch b/projects/Allwinner/devices/H3/patches/u-boot/0001-sunxi-Factor-out-eGON-BROM-header-description.patch new file mode 100644 index 0000000000..aa82231de4 --- /dev/null +++ b/projects/Allwinner/devices/H3/patches/u-boot/0001-sunxi-Factor-out-eGON-BROM-header-description.patch @@ -0,0 +1,181 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Andre Przywara +Date: Wed, 18 Nov 2020 17:32:02 +0000 +Subject: [PATCH] sunxi: Factor out eGON BROM header description + +To be able to easily share the Allwinner eGON BROM header structure +between the tools and the SPL code, move the struct definition into a +separate header file. + +Signed-off-by: Andre Przywara +--- + arch/arm/include/asm/arch-sunxi/spl.h | 65 +-------------------- + include/sunxi_image.h | 81 +++++++++++++++++++++++++++ + 2 files changed, 82 insertions(+), 64 deletions(-) + create mode 100644 include/sunxi_image.h + +--- a/arch/arm/include/asm/arch-sunxi/spl.h ++++ b/arch/arm/include/asm/arch-sunxi/spl.h +@@ -7,19 +7,7 @@ + #ifndef _ASM_ARCH_SPL_H_ + #define _ASM_ARCH_SPL_H_ + +-#define BOOT0_MAGIC "eGON.BT0" +-#define SPL_SIGNATURE "SPL" /* marks "sunxi" SPL header */ +-#define SPL_MAJOR_BITS 3 +-#define SPL_MINOR_BITS 5 +-#define SPL_VERSION(maj, min) \ +- ((((maj) & ((1U << SPL_MAJOR_BITS) - 1)) << SPL_MINOR_BITS) | \ +- ((min) & ((1U << SPL_MINOR_BITS) - 1))) +- +-#define SPL_HEADER_VERSION SPL_VERSION(0, 2) +- +-#define SPL_ENV_HEADER_VERSION SPL_VERSION(0, 1) +-#define SPL_DT_HEADER_VERSION SPL_VERSION(0, 2) +-#define SPL_DRAM_HEADER_VERSION SPL_VERSION(0, 3) ++#include + + #define SPL_ADDR CONFIG_SUNXI_SRAM_ADDRESS + +@@ -31,57 +19,6 @@ + #define SUNXI_BOOTED_FROM_MMC0_HIGH 0x10 + #define SUNXI_BOOTED_FROM_MMC2_HIGH 0x12 + +-/* boot head definition from sun4i boot code */ +-struct boot_file_head { +- uint32_t b_instruction; /* one intruction jumping to real code */ +- uint8_t magic[8]; /* ="eGON.BT0" or "eGON.BT1", not C-style str */ +- uint32_t check_sum; /* generated by PC */ +- uint32_t length; /* generated by PC */ +- /* +- * We use a simplified header, only filling in what is needed +- * by the boot ROM. To be compatible with Allwinner tools we +- * would need to implement the proper fields here instead of +- * padding. +- * +- * Actually we want the ability to recognize our "sunxi" variant +- * of the SPL. To do so, let's place a special signature into the +- * "pub_head_size" field. We can reasonably expect Allwinner's +- * boot0 to always have the upper 16 bits of this set to 0 (after +- * all the value shouldn't be larger than the limit imposed by +- * SRAM size). +- * If the signature is present (at 0x14), then we know it's safe +- * to use the remaining 8 bytes (at 0x18) for our own purposes. +- * (E.g. sunxi-tools "fel" utility can pass information there.) +- */ +- union { +- uint32_t pub_head_size; +- uint8_t spl_signature[4]; +- }; +- uint32_t fel_script_address; /* since v0.1, set by sunxi-fel */ +- /* +- * If the fel_uEnv_length member below is set to a non-zero value, +- * it specifies the size (byte count) of data at fel_script_address. +- * At the same time this indicates that the data is in uEnv.txt +- * compatible format, ready to be imported via "env import -t". +- */ +- uint32_t fel_uEnv_length; /* since v0.1, set by sunxi-fel */ +- /* +- * Offset of an ASCIIZ string (relative to the SPL header), which +- * contains the default device tree name (CONFIG_DEFAULT_DEVICE_TREE). +- * This is optional and may be set to NULL. Is intended to be used +- * by flash programming tools for providing nice informative messages +- * to the users. +- */ +- uint32_t dt_name_offset; /* since v0.2, set by mksunxiboot */ +- uint32_t dram_size; /* in MiB, since v0.3, set by SPL */ +- uint32_t boot_media; /* written here by the boot ROM */ +- /* A padding area (may be used for storing text strings) */ +- uint32_t string_pool[13]; /* since v0.2, filled by mksunxiboot */ +- /* The header must be a multiple of 32 bytes (for VBAR alignment) */ +-}; +- +-/* Compile time check to assure proper alignment of structure */ +-typedef char boot_file_head_not_multiple_of_32[1 - 2*(sizeof(struct boot_file_head) % 32)]; + + #define is_boot0_magic(addr) (memcmp((void *)addr, BOOT0_MAGIC, 8) == 0) + +--- /dev/null ++++ b/include/sunxi_image.h +@@ -0,0 +1,81 @@ ++/* SPDX-License-Identifier: GPL-2.0+ */ ++/* ++ * (C) Copyright 2007-2011 ++ * Allwinner Technology Co., Ltd. ++ * Tom Cubie ++ * ++ * Constants and data structures used in Allwinner "eGON" images, as ++ * parsed by the Boot-ROM. ++ * ++ * Shared between mkimage and the SPL. ++ */ ++#ifndef SUNXI_IMAGE_H ++#define SUNXI_IMAGE_H ++ ++#define BOOT0_MAGIC "eGON.BT0" ++#define SPL_SIGNATURE "SPL" /* marks "sunxi" SPL header */ ++#define SPL_MAJOR_BITS 3 ++#define SPL_MINOR_BITS 5 ++#define SPL_VERSION(maj, min) \ ++ ((((maj) & ((1U << SPL_MAJOR_BITS) - 1)) << SPL_MINOR_BITS) | \ ++ ((min) & ((1U << SPL_MINOR_BITS) - 1))) ++ ++#define SPL_HEADER_VERSION SPL_VERSION(0, 2) ++ ++#define SPL_ENV_HEADER_VERSION SPL_VERSION(0, 1) ++#define SPL_DT_HEADER_VERSION SPL_VERSION(0, 2) ++#define SPL_DRAM_HEADER_VERSION SPL_VERSION(0, 3) ++ ++/* boot head definition from sun4i boot code */ ++struct boot_file_head { ++ uint32_t b_instruction; /* one intruction jumping to real code */ ++ uint8_t magic[8]; /* ="eGON.BT0" or "eGON.BT1", not C-style str */ ++ uint32_t check_sum; /* generated by PC */ ++ uint32_t length; /* generated by PC */ ++ /* ++ * We use a simplified header, only filling in what is needed ++ * by the boot ROM. To be compatible with Allwinner tools we ++ * would need to implement the proper fields here instead of ++ * padding. ++ * ++ * Actually we want the ability to recognize our "sunxi" variant ++ * of the SPL. To do so, let's place a special signature into the ++ * "pub_head_size" field. We can reasonably expect Allwinner's ++ * boot0 to always have the upper 16 bits of this set to 0 (after ++ * all the value shouldn't be larger than the limit imposed by ++ * SRAM size). ++ * If the signature is present (at 0x14), then we know it's safe ++ * to use the remaining 8 bytes (at 0x18) for our own purposes. ++ * (E.g. sunxi-tools "fel" utility can pass information there.) ++ */ ++ union { ++ uint32_t pub_head_size; ++ uint8_t spl_signature[4]; ++ }; ++ uint32_t fel_script_address; /* since v0.1, set by sunxi-fel */ ++ /* ++ * If the fel_uEnv_length member below is set to a non-zero value, ++ * it specifies the size (byte count) of data at fel_script_address. ++ * At the same time this indicates that the data is in uEnv.txt ++ * compatible format, ready to be imported via "env import -t". ++ */ ++ uint32_t fel_uEnv_length; /* since v0.1, set by sunxi-fel */ ++ /* ++ * Offset of an ASCIIZ string (relative to the SPL header), which ++ * contains the default device tree name (CONFIG_DEFAULT_DEVICE_TREE). ++ * This is optional and may be set to NULL. Is intended to be used ++ * by flash programming tools for providing nice informative messages ++ * to the users. ++ */ ++ uint32_t dt_name_offset; /* since v0.2, set by mksunxiboot */ ++ uint32_t dram_size; /* in MiB, since v0.3, set by SPL */ ++ uint32_t boot_media; /* written here by the boot ROM */ ++ /* A padding area (may be used for storing text strings) */ ++ uint32_t string_pool[13]; /* since v0.2, filled by mksunxiboot */ ++ /* The header must be a multiple of 32 bytes (for VBAR alignment) */ ++}; ++ ++/* Compile time check to assure proper alignment of structure */ ++typedef char boot_file_head_not_multiple_of_32[1 - 2*(sizeof(struct boot_file_head) % 32)]; ++ ++#endif diff --git a/projects/Allwinner/devices/H3/patches/u-boot/0002-tools-mkimage-Add-Allwinner-eGON-support.patch b/projects/Allwinner/devices/H3/patches/u-boot/0002-tools-mkimage-Add-Allwinner-eGON-support.patch new file mode 100644 index 0000000000..e440e0a716 --- /dev/null +++ b/projects/Allwinner/devices/H3/patches/u-boot/0002-tools-mkimage-Add-Allwinner-eGON-support.patch @@ -0,0 +1,202 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Andre Przywara +Date: Wed, 18 Nov 2020 17:32:03 +0000 +Subject: [PATCH] tools: mkimage: Add Allwinner eGON support + +So far we used the separate mksunxiboot tool for generating a bootable +image for Allwinner SPLs, probably just for historical reasons. + +Use the mkimage framework to generate a so called eGON image the +Allwinner BROM expects. +The new image type is called "sunxi_egon", to differentiate it +from the (still to be implemented) secure boot TOC0 image. + +Signed-off-by: Andre Przywara +--- + common/image.c | 1 + + include/image.h | 1 + + include/sunxi_image.h | 1 + + tools/Makefile | 1 + + tools/sunxi_egon.c | 136 ++++++++++++++++++++++++++++++++++++++++++ + 5 files changed, 140 insertions(+) + create mode 100644 tools/sunxi_egon.c + +--- a/common/image.c ++++ b/common/image.c +@@ -189,6 +189,7 @@ static const table_entry_t uimage_type[] + { IH_TYPE_STM32IMAGE, "stm32image", "STMicroelectronics STM32 Image" }, + { IH_TYPE_MTKIMAGE, "mtk_image", "MediaTek BootROM loadable Image" }, + { IH_TYPE_COPRO, "copro", "Coprocessor Image"}, ++ { IH_TYPE_SUNXI_EGON, "sunxi_egon", "Allwinner eGON Boot Image" }, + { -1, "", "", }, + }; + +--- a/include/image.h ++++ b/include/image.h +@@ -308,6 +308,7 @@ enum { + IH_TYPE_IMX8MIMAGE, /* Freescale IMX8MBoot Image */ + IH_TYPE_IMX8IMAGE, /* Freescale IMX8Boot Image */ + IH_TYPE_COPRO, /* Coprocessor Image for remoteproc*/ ++ IH_TYPE_SUNXI_EGON, /* Allwinner eGON Boot Image */ + + IH_TYPE_COUNT, /* Number of image types */ + }; +--- a/include/sunxi_image.h ++++ b/include/sunxi_image.h +@@ -13,6 +13,7 @@ + #define SUNXI_IMAGE_H + + #define BOOT0_MAGIC "eGON.BT0" ++#define BROM_STAMP_VALUE 0x5f0a6c39 + #define SPL_SIGNATURE "SPL" /* marks "sunxi" SPL header */ + #define SPL_MAJOR_BITS 3 + #define SPL_MINOR_BITS 5 +--- a/tools/Makefile ++++ b/tools/Makefile +@@ -104,6 +104,7 @@ dumpimage-mkimage-objs := aisimage.o \ + stm32image.o \ + $(ROCKCHIP_OBS) \ + socfpgaimage.o \ ++ sunxi_egon.o \ + lib/crc16.o \ + lib/sha1.o \ + lib/sha256.o \ +--- /dev/null ++++ b/tools/sunxi_egon.c +@@ -0,0 +1,136 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * (C) Copyright 2018 Arm Ltd. ++ */ ++ ++#include "imagetool.h" ++#include ++ ++#include ++ ++/* ++ * 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 ++ ++static int egon_check_params(struct image_tool_params *params) ++{ ++ /* We just need a binary image file. */ ++ return !params->dflag; ++} ++ ++static int egon_verify_header(unsigned char *ptr, int image_size, ++ struct image_tool_params *params) ++{ ++ const struct boot_file_head *header = (void *)ptr; ++ uint32_t length; ++ ++ /* First 4 bytes must be an ARM branch instruction. */ ++ if ((le32_to_cpu(header->b_instruction) & 0xff000000) != 0xea000000) ++ return EXIT_FAILURE; ++ ++ if (memcmp(header->magic, BOOT0_MAGIC, sizeof(header->magic))) ++ return EXIT_FAILURE; ++ ++ length = le32_to_cpu(header->length); ++ /* Must be at least 512 byte aligned. */ ++ if (length & 511) ++ return EXIT_FAILURE; ++ ++ /* ++ * Image could also contain U-Boot proper, so could be bigger. ++ * But it must not be shorter. ++ */ ++ if (image_size < length) ++ return EXIT_FAILURE; ++ ++ return EXIT_SUCCESS; ++} ++ ++static void egon_print_header(const void *buf) ++{ ++ const struct boot_file_head *header = buf; ++ ++ printf("Allwinner eGON image, size: %d bytes\n", ++ le32_to_cpu(header->length)); ++ ++ if (memcmp(header->spl_signature, SPL_SIGNATURE, 3)) ++ return; ++ ++ printf("\tSPL header version %d.%d\n", ++ header->spl_signature[3] >> SPL_MINOR_BITS, ++ header->spl_signature[3] & ((1U << SPL_MINOR_BITS) - 1)); ++ if (header->spl_signature[3] >= SPL_DT_HEADER_VERSION) { ++ uint32_t dt_name_offs = le32_to_cpu(header->dt_name_offset); ++ ++ if (dt_name_offs > 0) ++ printf("\tDT name: %s\n", (char *)buf + dt_name_offs); ++ } ++} ++ ++static void egon_set_header(void *buf, struct stat *sbuf, int infd, ++ struct image_tool_params *params) ++{ ++ struct boot_file_head *header = buf; ++ uint32_t *buf32 = buf; ++ uint32_t checksum = 0, value; ++ int i; ++ ++ /* Generate an ARM branch instruction to jump over the header. */ ++ value = 0xea000000 | (sizeof(struct boot_file_head) / 4 - 2); ++ header->b_instruction = cpu_to_le32(value); ++ ++ memcpy(header->magic, BOOT0_MAGIC, sizeof(header->magic)); ++ header->check_sum = cpu_to_le32(BROM_STAMP_VALUE); ++ header->length = cpu_to_le32(params->file_size); ++ ++ memcpy(header->spl_signature, SPL_SIGNATURE, 3); ++ ++ /* If an image name has been provided, use it as the DT name. */ ++ if (params->imagename && params->imagename[0]) { ++ header->spl_signature[3] = SPL_DT_HEADER_VERSION; ++ ++ value = offsetof(struct boot_file_head, string_pool); ++ header->dt_name_offset = cpu_to_le32(value); ++ ++ strncpy((char *)header->string_pool, params->imagename, 52); ++ /* Make sure we have a terminating zero byte. */ ++ ((char *)header->string_pool)[51] = 0; ++ } else ++ header->spl_signature[3] = SPL_ENV_HEADER_VERSION; ++ ++ /* Calculate the checksum. Yes, it's that simple. */ ++ for (i = 0; i < sbuf->st_size / 4; i++) ++ checksum += le32_to_cpu(buf32[i]); ++ header->check_sum = cpu_to_le32(checksum); ++} ++ ++static int egon_check_image_type(uint8_t type) ++{ ++ return type == IH_TYPE_SUNXI_EGON ? 0 : 1; ++} ++ ++static int egon_vrec_header(struct image_tool_params *params, ++ struct image_type_params *tparams) ++{ ++ tparams->hdr = calloc(sizeof(struct boot_file_head), 1); ++ ++ /* Return padding to 8K blocks. */ ++ return ALIGN(params->file_size, PAD_SIZE) - params->file_size; ++} ++ ++U_BOOT_IMAGE_TYPE( ++ sunxi_egon, ++ "Allwinner eGON Boot Image support", ++ sizeof(struct boot_file_head), ++ NULL, ++ egon_check_params, ++ egon_verify_header, ++ egon_print_header, ++ egon_set_header, ++ NULL, ++ egon_check_image_type, ++ NULL, ++ egon_vrec_header ++); diff --git a/projects/Allwinner/devices/H3/patches/u-boot/0003-sunxi-Use-mkimage-for-SPL-boot-image-generation.patch b/projects/Allwinner/devices/H3/patches/u-boot/0003-sunxi-Use-mkimage-for-SPL-boot-image-generation.patch new file mode 100644 index 0000000000..d9de621679 --- /dev/null +++ b/projects/Allwinner/devices/H3/patches/u-boot/0003-sunxi-Use-mkimage-for-SPL-boot-image-generation.patch @@ -0,0 +1,35 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Andre Przywara +Date: Wed, 18 Nov 2020 17:32:04 +0000 +Subject: [PATCH] sunxi: Use mkimage for SPL boot image generation + +Switch the SPL boot image generation from using mksunxiboot to the new +sunxi_egon format of mkimage. + +Verified to create identical results for all 152 Allwinner boards. + +Signed-off-by: Andre Przywara +Reviewed-by: Simon Glass +Reviewed-by: Jagan Teki +--- + scripts/Makefile.spl | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/scripts/Makefile.spl ++++ b/scripts/Makefile.spl +@@ -382,11 +382,11 @@ endif + $(obj)/$(SPL_BIN).sfp: $(obj)/$(SPL_BIN).bin FORCE + $(call if_changed,mkimage) + +-quiet_cmd_mksunxiboot = MKSUNXI $@ +-cmd_mksunxiboot = $(objtree)/tools/mksunxiboot \ +- --default-dt $(CONFIG_DEFAULT_DEVICE_TREE) $< $@ ++MKIMAGEFLAGS_sunxi-spl.bin = -T sunxi_egon \ ++ -n $(CONFIG_DEFAULT_DEVICE_TREE) ++ + $(obj)/sunxi-spl.bin: $(obj)/$(SPL_BIN).bin FORCE +- $(call if_changed,mksunxiboot) ++ $(call if_changed,mkimage) + + quiet_cmd_sunxi_spl_image_builder = SUNXI_SPL_IMAGE_BUILDER $@ + cmd_sunxi_spl_image_builder = $(objtree)/tools/sunxi-spl-image-builder \ diff --git a/projects/Allwinner/devices/H3/patches/u-boot/0004-sunxi-Put-secure-monitor-in-SRAM-A2.patch b/projects/Allwinner/devices/H3/patches/u-boot/0004-sunxi-Put-secure-monitor-in-SRAM-A2.patch new file mode 100644 index 0000000000..09ecd3ecd1 --- /dev/null +++ b/projects/Allwinner/devices/H3/patches/u-boot/0004-sunxi-Put-secure-monitor-in-SRAM-A2.patch @@ -0,0 +1,51 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Samuel Holland +Date: Fri, 20 Nov 2020 01:26:34 -0600 +Subject: [PATCH] sunxi: Put secure monitor in SRAM A2 + +Signed-off-by: Samuel Holland +--- + arch/arm/include/asm/arch-sunxi/cpu.h | 9 +++++++++ + arch/arm/include/asm/arch-sunxi/cpu_sun4i.h | 1 - + include/configs/sunxi-common.h | 2 ++ + 3 files changed, 11 insertions(+), 1 deletion(-) + +--- a/arch/arm/include/asm/arch-sunxi/cpu.h ++++ b/arch/arm/include/asm/arch-sunxi/cpu.h +@@ -14,6 +14,15 @@ + #include + #endif + ++#if defined(CONFIG_MACH_SUN4I) ++#define SUNXI_SRAM_A2_BASE 0x00004000 ++#elif defined(CONFIG_MACH_SUN6I) || \ ++ defined(CONFIG_MACH_SUN8I) || \ ++ defined(CONFIG_MACH_SUN50I) || \ ++ defined(CONFIG_MACH_SUN50I_H5) ++#define SUNXI_SRAM_A2_BASE 0x00040000 ++#endif ++ + #define SOCID_A64 0x1689 + #define SOCID_H3 0x1680 + #define SOCID_V3S 0x1681 +--- a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h ++++ b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h +@@ -11,7 +11,6 @@ + #define SUNXI_SRAM_A1_BASE 0x00000000 + #define SUNXI_SRAM_A1_SIZE (16 * 1024) /* 16 kiB */ + +-#define SUNXI_SRAM_A2_BASE 0x00004000 /* 16 kiB */ + #define SUNXI_SRAM_A3_BASE 0x00008000 /* 13 kiB */ + #define SUNXI_SRAM_A4_BASE 0x0000b400 /* 3 kiB */ + #define SUNXI_SRAM_D_BASE 0x00010000 /* 4 kiB */ +--- a/include/configs/sunxi-common.h ++++ b/include/configs/sunxi-common.h +@@ -192,6 +192,8 @@ + + #define CONFIG_SPL_PAD_TO 32768 /* decimal for 'dd' */ + ++#define CONFIG_ARMV7_SECURE_BASE SUNXI_SRAM_A2_BASE + 0x4000 ++#define CONFIG_ARMV7_SECURE_MAX_SIZE (16 * 1024) /* 16 KB */ + + /* I2C */ + #if defined CONFIG_AXP152_POWER || defined CONFIG_AXP209_POWER || \ diff --git a/projects/Allwinner/devices/H3/patches/u-boot/0005-sunxi-A-wild-PSCI-implementation-appears.patch b/projects/Allwinner/devices/H3/patches/u-boot/0005-sunxi-A-wild-PSCI-implementation-appears.patch new file mode 100644 index 0000000000..587c8a9063 --- /dev/null +++ b/projects/Allwinner/devices/H3/patches/u-boot/0005-sunxi-A-wild-PSCI-implementation-appears.patch @@ -0,0 +1,575 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Samuel Holland +Date: Fri, 20 Nov 2020 01:25:26 -0600 +Subject: [PATCH] sunxi: A wild PSCI implementation appears... + +Signed-off-by: Samuel Holland +--- + arch/arm/cpu/armv7/Kconfig | 1 - + 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(-) + create mode 100644 arch/arm/cpu/armv7/sunxi/psci-scpi.c + +--- a/arch/arm/cpu/armv7/Kconfig ++++ b/arch/arm/cpu/armv7/Kconfig +@@ -44,7 +44,6 @@ config ARMV7_PSCI + choice + prompt "Supported PSCI version" + depends on ARMV7_PSCI +- default ARMV7_PSCI_0_1 if ARCH_SUNXI + default ARMV7_PSCI_1_0 + help + Select the supported PSCI version. +--- a/arch/arm/cpu/armv7/sunxi/Makefile ++++ b/arch/arm/cpu/armv7/sunxi/Makefile +@@ -11,7 +11,7 @@ obj-$(CONFIG_MACH_SUN6I) += tzpc.o + obj-$(CONFIG_MACH_SUN8I_H3) += tzpc.o + + ifndef CONFIG_SPL_BUILD +-obj-$(CONFIG_ARMV7_PSCI) += psci.o ++obj-$(CONFIG_ARMV7_PSCI) += psci-scpi.o + endif + + ifdef CONFIG_SPL_BUILD +--- /dev/null ++++ b/arch/arm/cpu/armv7/sunxi/psci-scpi.c +@@ -0,0 +1,463 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (C) 2016 ++ * Author: Chen-Yu Tsai ++ * ++ * Based on assembly code by Marc Zyngier , ++ * which was based on code by Carl van Schaik . ++ */ ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define SUNXI_SCP_BASE 0x00048000 ++#define SUNXI_SCP_MAGIC 0xb4400012 ++ ++#define OR1K_VEC_FIRST 0x01 ++#define OR1K_VEC_LAST 0x0e ++#define OR1K_VEC_ADDR(n) (0x100 * (n)) ++ ++#define GICD_BASE (SUNXI_GIC400_BASE + GIC_DIST_OFFSET) ++#define GICC_BASE (SUNXI_GIC400_BASE + GIC_CPU_OFFSET_A15) ++ ++#define HW_ON 0 ++#define HW_OFF 1 ++#define HW_STANDBY 2 ++ ++#define MPIDR_AFFLVL0(mpidr) (mpidr & 0xf) ++#define MPIDR_AFFLVL1(mpidr) (mpidr >> 8 & 0xf) ++ ++enum { ++ CORE_POWER_LEVEL = 0, ++ CLUSTER_POWER_LEVEL = 1, ++ CSS_POWER_LEVEL = 2, ++}; ++ ++enum { ++ SCPI_CMD_SCP_READY = 0x01, ++ SCPI_CMD_SET_CSS_POWER_STATE = 0x03, ++ SCPI_CMD_GET_CSS_POWER_STATE = 0x04, ++ SCPI_CMD_SET_SYS_POWER_STATE = 0x05, ++}; ++ ++enum { ++ SCPI_E_OK = 0, ++ SCPI_E_PARAM = 1, ++ SCPI_E_ALIGN = 2, ++ SCPI_E_SIZE = 3, ++ SCPI_E_HANDLER = 4, ++ SCPI_E_ACCESS = 5, ++ SCPI_E_RANGE = 6, ++ SCPI_E_TIMEOUT = 7, ++ SCPI_E_NOMEM = 8, ++ SCPI_E_PWRSTATE = 9, ++ SCPI_E_SUPPORT = 10, ++ SCPI_E_DEVICE = 11, ++ SCPI_E_BUSY = 12, ++ SCPI_E_OS = 13, ++ SCPI_E_DATA = 14, ++ SCPI_E_STATE = 15, ++}; ++ ++enum { ++ SCPI_POWER_ON = 0x00, ++ SCPI_POWER_RETENTION = 0x01, ++ SCPI_POWER_OFF = 0x03, ++}; ++ ++enum { ++ SCPI_SYSTEM_SHUTDOWN = 0x00, ++ SCPI_SYSTEM_REBOOT = 0x01, ++ 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; ++ u16 size; ++ u32 status; ++}; ++ ++struct scpi_message { ++ struct scpi_header header; ++ u8 payload[SCPI_PAYLOAD_SIZE]; ++}; ++ ++struct scpi_shmem { ++ struct scpi_message rx; ++ 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 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; ++} ++ ++static void __secure scpi_begin_command(void) ++{ ++ u32 mpidr = read_mpidr(); ++ ++ do { ++ while (readl(&lock)); ++ writel(mpidr, &lock); ++ dsb(); ++ } while (readl(&lock) != mpidr); ++ while (readl(REMOTE_IRQ_STAT_REG) & RX_IRQ(SCPI_TX_CHANNEL)); ++} ++ ++static void __secure scpi_send_command(void) ++{ ++ writel(SCPI_VIRTUAL_CHANNEL, MSG_DATA_REG(SCPI_TX_CHANNEL)); ++} ++ ++static void __secure scpi_wait_response(void) ++{ ++ while (!readl(MSG_STAT_REG(SCPI_RX_CHANNEL))); ++} ++ ++static void __secure scpi_end_command(void) ++{ ++ while (readl(MSG_STAT_REG(SCPI_RX_CHANNEL))) ++ readl(MSG_DATA_REG(SCPI_RX_CHANNEL)); ++ writel(RX_IRQ(SCPI_RX_CHANNEL), LOCAL_IRQ_STAT_REG); ++ writel(0, &lock); ++} ++ ++static void __secure scpi_set_css_power_state(u32 target_cpu, u32 core_state, ++ u32 cluster_state, u32 css_state) ++{ ++ struct scpi_shmem *shmem = SCPI_SHMEM; ++ ++ scpi_begin_command(); ++ ++ shmem->tx.header.command = SCPI_CMD_SET_CSS_POWER_STATE; ++ shmem->tx.header.size = 4; ++ ++ shmem->tx.payload[0] = target_cpu >> 4 | target_cpu; ++ shmem->tx.payload[1] = cluster_state << 4 | core_state; ++ shmem->tx.payload[2] = css_state; ++ shmem->tx.payload[3] = 0; ++ ++ scpi_send_command(); ++ scpi_end_command(); ++} ++ ++static s32 __secure scpi_get_css_power_state(u32 target_cpu, u8 *core_states, ++ u8 *cluster_state) ++{ ++ struct scpi_shmem *shmem = SCPI_SHMEM; ++ u32 cluster = MPIDR_AFFLVL1(target_cpu); ++ u32 offset; ++ s32 ret; ++ ++ scpi_begin_command(); ++ ++ shmem->tx.header.command = SCPI_CMD_GET_CSS_POWER_STATE; ++ shmem->tx.header.size = 0; ++ ++ scpi_send_command(); ++ scpi_wait_response(); ++ ++ for (offset = 0; offset < shmem->rx.header.size; offset += 2) { ++ if ((shmem->rx.payload[offset] & 0xf) == cluster) { ++ *cluster_state = shmem->rx.payload[offset+0] >> 4; ++ *core_states = shmem->rx.payload[offset+1]; ++ ++ break; ++ } ++ } ++ ++ ret = shmem->rx.header.status; ++ ++ scpi_end_command(); ++ ++ return ret; ++} ++ ++static s32 __secure scpi_set_sys_power_state(u32 sys_state) ++{ ++ struct scpi_shmem *shmem = SCPI_SHMEM; ++ s32 ret; ++ ++ scpi_begin_command(); ++ ++ shmem->tx.header.command = SCPI_CMD_SET_SYS_POWER_STATE; ++ shmem->tx.header.size = 1; ++ ++ shmem->tx.payload[0] = sys_state; ++ ++ scpi_send_command(); ++ scpi_wait_response(); ++ ++ ret = shmem->rx.header.status; ++ ++ scpi_end_command(); ++ ++ return ret; ++} ++ ++void psci_enable_smp(void); ++ ++static s32 __secure psci_suspend_common(u32 pc, u32 context_id, u32 core_state, ++ u32 cluster_state, u32 css_state) ++ ++{ ++ u32 target_cpu = read_mpidr(); ++ ++ 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); ++ } ++ } ++ ++ scpi_set_css_power_state(target_cpu, core_state, ++ cluster_state, css_state); ++ ++ psci_cpu_off_common(); ++ ++ wfi(); ++ ++ psci_enable_smp(); ++ ++ return ARM_PSCI_RET_SUCCESS; ++} ++ ++u32 __secure psci_version(void) ++{ ++ return ARM_PSCI_VER_1_1; ++} ++ ++s32 __secure psci_cpu_suspend(u32 __always_unused function_id, ++ u32 power_state, u32 pc, u32 context_id) ++{ ++ return psci_suspend_common(pc, context_id, ++ power_state >> 0 & 0xf, ++ power_state >> 4 & 0xf, ++ power_state >> 8 & 0xf); ++} ++ ++s32 __secure psci_cpu_off(void) ++{ ++ u32 pc = 0, context_id = 0; ++ ++ return psci_suspend_common(pc, context_id, SCPI_POWER_OFF, ++ SCPI_POWER_OFF, SCPI_POWER_ON); ++} ++ ++s32 __secure psci_cpu_on(u32 __always_unused function_id, ++ u32 target_cpu, u32 pc, u32 context_id) ++{ ++ psci_save(MPIDR_AFFLVL0(target_cpu), pc, context_id); ++ ++ scpi_set_css_power_state(target_cpu, SCPI_POWER_ON, ++ SCPI_POWER_ON, SCPI_POWER_ON); ++ ++ return ARM_PSCI_RET_SUCCESS; ++} ++ ++s32 __secure psci_affinity_info(u32 function_id, ++ u32 target_cpu, u32 power_level) ++{ ++ if (power_level != CORE_POWER_LEVEL) ++ return ARM_PSCI_RET_INVAL; ++ ++ /* This happens to have the same HW_ON/HW_OFF encoding. */ ++ return psci_node_hw_state(function_id, target_cpu, power_level); ++} ++ ++void __secure psci_system_off(void) ++{ ++ scpi_set_sys_power_state(SCPI_SYSTEM_SHUTDOWN); ++ ++ /* Wait to be turned off. */ ++ for (;;) wfi(); ++} ++ ++void __secure psci_system_reset(void) ++{ ++ scpi_set_sys_power_state(SCPI_SYSTEM_REBOOT); ++ ++ /* Wait to be turned off. */ ++ for (;;) wfi(); ++} ++ ++s32 __secure psci_features(u32 __always_unused function_id, ++ u32 psci_fid) ++{ ++ switch (psci_fid) { ++ case ARM_PSCI_0_2_FN_PSCI_VERSION: ++ case ARM_PSCI_0_2_FN_CPU_SUSPEND: ++ case ARM_PSCI_0_2_FN_CPU_OFF: ++ case ARM_PSCI_0_2_FN_CPU_ON: ++ case ARM_PSCI_0_2_FN_AFFINITY_INFO: ++ case ARM_PSCI_0_2_FN_SYSTEM_OFF: ++ case ARM_PSCI_0_2_FN_SYSTEM_RESET: ++ case ARM_PSCI_1_0_FN_PSCI_FEATURES: ++ case ARM_PSCI_1_0_FN_CPU_DEFAULT_SUSPEND: ++ case ARM_PSCI_1_0_FN_NODE_HW_STATE: ++ case ARM_PSCI_1_0_FN_SYSTEM_SUSPEND: ++ case ARM_PSCI_1_1_FN_SYSTEM_RESET2: ++ return ARM_PSCI_RET_SUCCESS; ++ default: ++ return ARM_PSCI_RET_NI; ++ } ++} ++ ++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); ++} ++ ++s32 __secure psci_node_hw_state(u32 __always_unused function_id, ++ u32 target_cpu, u32 power_level) ++{ ++ u32 core = MPIDR_AFFLVL0(target_cpu); ++ u8 core_states, cluster_state; ++ ++ if (power_level >= CSS_POWER_LEVEL) ++ return HW_ON; ++ if (scpi_get_css_power_state(target_cpu, &core_states, &cluster_state)) ++ return ARM_PSCI_RET_NI; ++ if (power_level == CLUSTER_POWER_LEVEL) { ++ if (cluster_state == SCPI_POWER_ON) ++ return HW_ON; ++ if (cluster_state < SCPI_POWER_OFF) ++ return HW_STANDBY; ++ return HW_OFF; ++ } ++ ++ return (core_states & BIT(core)) ? HW_ON : HW_OFF; ++} ++ ++s32 __secure psci_system_suspend(u32 __always_unused function_id, ++ u32 pc, u32 context_id) ++{ ++ return psci_suspend_common(pc, context_id, SCPI_POWER_OFF, ++ SCPI_POWER_OFF, SCPI_POWER_OFF); ++} ++ ++s32 __secure psci_system_reset2(u32 __always_unused function_id, ++ u32 reset_type, u32 cookie) ++{ ++ s32 ret; ++ ++ if (reset_type) ++ return ARM_PSCI_RET_INVAL; ++ ++ ret = scpi_set_sys_power_state(SCPI_SYSTEM_RESET); ++ if (ret) ++ return ARM_PSCI_RET_INVAL; ++ ++ /* Wait to be turned off. */ ++ for (;;) wfi(); ++} ++ ++/* ++ * R40 is different from other single cluster SoCs. The secondary core ++ * entry address register is in the SRAM controller address range. ++ */ ++#define SUN8I_R40_SRAMC_SOFT_ENTRY_REG0 (0xbc) ++ ++#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) ++{ ++ struct sunxi_cpucfg_reg *cpucfg = ++ (struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE; ++ ++ writel((u32)entry, &cpucfg->priv0); ++} ++#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); ++ ++ /* Set secondary core power-on PC. */ ++ sunxi_set_entry_address(psci_cpu_entry); ++ ++ /* Wait for the SCP firmware to boot. */ ++ 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); ++ } ++} ++ ++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; ++ ++ writel(offset >> 2, vector); ++ } ++ ++ /* Take the SCP out of reset. */ ++ writel(0x1, SUNXI_CPUCFG_BASE); ++ } ++} +--- a/arch/arm/include/asm/psci.h ++++ b/arch/arm/include/asm/psci.h +@@ -22,8 +22,9 @@ + #include + #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 +@@ -549,17 +549,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) + { diff --git a/projects/Allwinner/devices/H3/patches/u-boot/0006-Makefile-Add-support-for-building-a-sunxi-resume-shi.patch b/projects/Allwinner/devices/H3/patches/u-boot/0006-Makefile-Add-support-for-building-a-sunxi-resume-shi.patch new file mode 100644 index 0000000000..b51ab23624 --- /dev/null +++ b/projects/Allwinner/devices/H3/patches/u-boot/0006-Makefile-Add-support-for-building-a-sunxi-resume-shi.patch @@ -0,0 +1,44 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Samuel Holland +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 +@@ -961,6 +961,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. diff --git a/projects/Allwinner/devices/H3/patches/u-boot/0007-sunxi-binman-Respect-the-default-FIT-configuration.patch b/projects/Allwinner/devices/H3/patches/u-boot/0007-sunxi-binman-Respect-the-default-FIT-configuration.patch new file mode 100644 index 0000000000..2e934bd7ff --- /dev/null +++ b/projects/Allwinner/devices/H3/patches/u-boot/0007-sunxi-binman-Respect-the-default-FIT-configuration.patch @@ -0,0 +1,21 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Samuel Holland +Date: Wed, 18 Nov 2020 23:00:07 -0600 +Subject: [PATCH] sunxi: binman: Respect the default FIT configuration + +Signed-off-by: Samuel Holland +--- + arch/arm/dts/sunxi-u-boot.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/arm/dts/sunxi-u-boot.dtsi ++++ b/arch/arm/dts/sunxi-u-boot.dtsi +@@ -82,7 +82,7 @@ + }; + + configurations { +- default = "config-1"; ++ default = "@config-DEFAULT-SEQ"; + + @config-SEQ { + description = "NAME"; diff --git a/projects/Allwinner/devices/H3/patches/u-boot/0008-sunxi-binman-Do-not-hardcode-U-Boot-load-address.patch b/projects/Allwinner/devices/H3/patches/u-boot/0008-sunxi-binman-Do-not-hardcode-U-Boot-load-address.patch new file mode 100644 index 0000000000..599be22595 --- /dev/null +++ b/projects/Allwinner/devices/H3/patches/u-boot/0008-sunxi-binman-Do-not-hardcode-U-Boot-load-address.patch @@ -0,0 +1,21 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Samuel Holland +Date: Wed, 18 Nov 2020 23:04:49 -0600 +Subject: [PATCH] sunxi: binman: Do not hardcode U-Boot load address + +Signed-off-by: Samuel Holland +--- + arch/arm/dts/sunxi-u-boot.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/arm/dts/sunxi-u-boot.dtsi ++++ b/arch/arm/dts/sunxi-u-boot.dtsi +@@ -40,7 +40,7 @@ + os = "u-boot"; + arch = "arm64"; + compression = "none"; +- load = <0x4a000000>; ++ load = ; + + u-boot-nodtb { + }; diff --git a/projects/Allwinner/devices/H3/patches/u-boot/0009-sunxi-binman-Explicitly-pad-SPL-to-expected-size.patch b/projects/Allwinner/devices/H3/patches/u-boot/0009-sunxi-binman-Explicitly-pad-SPL-to-expected-size.patch new file mode 100644 index 0000000000..bd1ab82535 --- /dev/null +++ b/projects/Allwinner/devices/H3/patches/u-boot/0009-sunxi-binman-Explicitly-pad-SPL-to-expected-size.patch @@ -0,0 +1,20 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Samuel Holland +Date: Wed, 18 Nov 2020 23:27:07 -0600 +Subject: [PATCH] sunxi: binman: Explicitly pad SPL to expected size + +Signed-off-by: Samuel Holland +--- + 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 +@@ -30,6 +30,7 @@ + #ifdef CONFIG_ARM64 + fit { + description = "Configuration to load ATF before U-Boot"; ++ offset = ; + #address-cells = <1>; + fit,fdt-list = "of-list"; + diff --git a/projects/Allwinner/devices/H3/patches/u-boot/0010-sunxi-binman-Support-FIT-images-for-32-bit-boards.patch b/projects/Allwinner/devices/H3/patches/u-boot/0010-sunxi-binman-Support-FIT-images-for-32-bit-boards.patch new file mode 100644 index 0000000000..e68c7faabe --- /dev/null +++ b/projects/Allwinner/devices/H3/patches/u-boot/0010-sunxi-binman-Support-FIT-images-for-32-bit-boards.patch @@ -0,0 +1,97 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Samuel Holland +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 +--- + 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 + ++#ifdef CONFIG_ARM64 + #ifdef CONFIG_MACH_SUN50I_H6 + #define BL31_ADDR 0x104000 + #define SCP_ADDR 0x114000 +@@ -7,6 +8,9 @@ + #define BL31_ADDR 0x44000 + #define SCP_ADDR 0x50000 + #endif ++#else ++#define SCP_ADDR 0x48000 ++#endif + + / { + aliases { +@@ -27,6 +31,7 @@ + filename = "spl/sunxi-spl.bin"; + }; + ++#ifdef CONFIG_SPL_FIT + #ifdef CONFIG_ARM64 + fit { + description = "Configuration to load ATF before U-Boot"; +@@ -94,6 +99,59 @@ + }; + }; + #else ++ fit { ++ description = "Configuration to load SCP firmware with U-Boot"; ++ offset = ; ++ #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 = ; ++ ++ u-boot-nodtb { ++ }; ++ }; ++ ++ scp { ++ description = "SCP firmware"; ++ type = "firmware"; ++ arch = "or1k"; ++ compression = "none"; ++ load = ; ++ ++ 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 = ; + }; diff --git a/projects/Allwinner/devices/H3/patches/u-boot/0011-sunxi-binman-Add-a-resume-shim.patch b/projects/Allwinner/devices/H3/patches/u-boot/0011-sunxi-binman-Add-a-resume-shim.patch new file mode 100644 index 0000000000..11c5f99ac5 --- /dev/null +++ b/projects/Allwinner/devices/H3/patches/u-boot/0011-sunxi-binman-Add-a-resume-shim.patch @@ -0,0 +1,48 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Samuel Holland +Date: Sun, 13 Dec 2020 00:07:28 -0600 +Subject: [PATCH] sunxi: binman: Add a resume shim + +Signed-off-by: Samuel Holland +--- + 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 +@@ -10,6 +10,7 @@ + #endif + #else + #define SCP_ADDR 0x48000 ++#define RESUME_ADDR 0x47000 + #endif + + / { +@@ -118,6 +119,18 @@ + }; + }; + ++ resume { ++ description = "resume shim"; ++ type = "standalone"; ++ arch = "arm"; ++ compression = "none"; ++ load = ; ++ ++ blob-ext { ++ filename = "resume.egon"; ++ }; ++ }; ++ + scp { + description = "SCP firmware"; + type = "firmware"; +@@ -145,7 +158,7 @@ + @config-SEQ { + description = "NAME"; + firmware = "uboot"; +- loadables = "scp"; ++ loadables = "resume", "scp"; + fdt = "fdt-SEQ"; + }; + };