[PATCH 3/3] sunxi: Add support for including SCP firmware

Samuel Holland samuel at sholland.org
Fri May 8 01:20:35 CEST 2020

Allwinner sun50i SoCs contain an OpenRISC 1000 CPU that functions as a
System Control Processor, or SCP. ARM Trusted Firmware (ATF)
communicates with the SCP over SCPI to implement the PSCI system suspend
and shutdown functionality. Currently, SCP firmware is optional; the
system will boot and run without it, but system suspend will be

Since all communication with the SCP is mediated by ATF, the only thing
U-Boot needs to do is load the firmware into SRAM. The SCP firmware
occupies the last 16KiB of SRAM A2, immediately following ATF.

Signed-off-by: Samuel Holland <samuel at sholland.org>
 board/sunxi/README.sunxi64     | 43 ++++++++++++++++++++++++++++------
 board/sunxi/mksunxi_fit_atf.sh | 23 +++++++++++++++---
 2 files changed, 56 insertions(+), 10 deletions(-)

diff --git a/board/sunxi/README.sunxi64 b/board/sunxi/README.sunxi64
index 258921af22..9a67e5301e 100644
--- a/board/sunxi/README.sunxi64
+++ b/board/sunxi/README.sunxi64
@@ -14,8 +14,12 @@ Quick Start / Overview
 - Build the ARM Trusted Firmware binary (see "ARM Trusted Firmware (ATF)" below)
   $ cd /src/arm-trusted-firmware
   $ make PLAT=sun50i_a64 DEBUG=1 bl31
+- Build the SCP firmware binary (see "SCP firmware (Crust)" below)
+  $ cd /src/crust
+  $ make pine64_plus_defconfig && make -j5 scp
 - Build U-Boot (see "SPL/U-Boot" below)
   $ export BL31=/path/to/bl31.bin
+  $ export SCP=/src/crust/build/scp/scp.bin
   $ make pine64_plus_defconfig && make -j5
 - Transfer to an uSD card (see "microSD card" below)
   $ dd if=u-boot-sunxi-with-spl.bin of=/dev/sdx bs=8k seek=1
@@ -24,13 +28,17 @@ Quick Start / Overview
 Building the firmware
-The Allwinner A64/H5 firmware consists of three parts: U-Boot's SPL, an
-ARM Trusted Firmware (ATF) build and the U-Boot proper.
-The SPL will load both ATF and U-Boot proper along with the right device
-tree blob (.dtb) and will pass execution to ATF (in EL3), which in turn will
-drop into the U-Boot proper (in EL2).
-As the ATF binary will become part of the U-Boot image file, you will need
-to build it first.
+The Allwinner A64/H5/H6 firmware consists of several parts: U-Boot's SPL,
+ARM Trusted Firmware (ATF), optional System Control Processor (SCP) firmware
+(e.g. Crust), and the U-Boot proper.
+The SPL will load all of the other firmware binaries into RAM, along with the
+right device tree blob (.dtb), and will pass execution to ATF (in EL3). If SCP
+firmware was loaded, ATF will power on the SCP and wait for it to boot.
+ATF will then drop into U-Boot proper (in EL2).
+As the ATF binary and SCP firmware will become part of the U-Boot image file,
+you will need to build them first.
  ARM Trusted Firmware (ATF)
@@ -53,6 +61,27 @@ As sometimes the ATF build process is a bit picky about the toolchain used,
 or if you can't be bothered with building ATF, there are known working
 binaries in the firmware repository[3], purely for convenience reasons.
+ SCP firmware (Crust)
+SCP firmware is responsible for implementing system suspend/resume, and (on
+boards without a PMIC) soft poweroff/on. ATF contains fallback code for CPU
+power control, so SCP firmware is optional if you don't need either of these
+features. It runs on the AR100, with is an or1k CPU, not ARM, so it needs a
+different cross toolchain.
+There is one SCP firmware implementation currently available, Crust:
+$ git clone https://github.com/crust-firmware/crust
+$ cd crust
+$ export CROSS_COMPILE=or1k-linux-musl-
+$ make pine64_plus_defconfig
+$ make scp
+The same configuration generally works on any board with the same SoC (A64, H5,
+or H6), so if there is no config for your board, use one for a similar board.
+Like for ATF, U-Boot finds the SCP firmware binary via an environment variable:
+$ export SCP=/src/crust/build/scp/scp.bin
 Both U-Boot proper and the SPL are using the 64-bit mode. As the boot ROM
diff --git a/board/sunxi/mksunxi_fit_atf.sh b/board/sunxi/mksunxi_fit_atf.sh
index 4dfd22db78..07a2e619ee 100755
--- a/board/sunxi/mksunxi_fit_atf.sh
+++ b/board/sunxi/mksunxi_fit_atf.sh
@@ -1,11 +1,12 @@
-# script to generate FIT image source for 64-bit sunxi boards with
-# ARM Trusted Firmware and multiple device trees (given on the command line)
+# script to generate FIT image source for 64-bit sunxi boards with ARM Trusted
+# Firmware, SCP firmware, and multiple device trees (given on the command line)
 # usage: $0 <dt_name> [<dt_name> [<dt_name] ...]
 [ -z "$BL31" ] && BL31="bl31.bin"
+[ -z "$SCP" ] && SCP="scp.bin"
 if [ ! -f $BL31 ]; then
 	echo "WARNING: BL31 file $BL31 NOT found, resulting binary is non-functional" >&2
@@ -13,10 +14,18 @@ if [ ! -f $BL31 ]; then
+if [ ! -f $SCP ]; then
+	echo "WARNING: SCP firmware file $SCP NOT found, system suspend will be unavailable" >&2
+	echo "Please read the section on SCP firmware in board/sunxi/README.sunxi64" >&2
+	SCP=/dev/null
 if grep -q "^CONFIG_MACH_SUN50I_H6=y" .config; then
+	SCP_ADDR=0x114000
+	SCP_ADDR=0x50000
 cat << __HEADER_EOF
@@ -46,6 +55,14 @@ cat << __HEADER_EOF
 			load = <$BL31_ADDR>;
 			entry = <$BL31_ADDR>;
+		scp {
+			description = "SCP firmware";
+			data = /incbin/("$SCP");
+			type = "firmware";
+			arch = "or1k";
+			compression = "none";
+			load = <$SCP_ADDR>;
+		};
@@ -76,7 +93,7 @@ do
 		config_$cnt {
 			description = "$(basename $dtname .dtb)";
 			firmware = "atf";
-			loadables = "uboot";
+			loadables = "scp", "uboot";
 			fdt = "fdt_$cnt";

More information about the U-Boot mailing list