Mainline U-Boot works with LPDDR4 patch series

With a recently posted (not yet merged) patch series from Jagan Teki adding rank detection, LPDDR4 timings and so on, mainline U-Boot boots Khadas Edge.

The Rockchip miniloader (idbloader.img) is no longer needed and the ARM Trusted Firmware bl31 component is built into U-Boot itself. This results in a less ugly and noisy boot process, and is 100% mainline free software. (The entire system can be blob-free apart from the firmware for the Broadcom wifi module.)

Until all the changes are merged upstream, I have a pre-prepared tree of U-Boot mainline (as of this morning) with the patch series (99 patches), a suitable defconfig and device tree. This can be cloned with

  git clone
  cd u-boot-edge

Alternatively, you can reconstruct this tree yourself like this:

git clone
cd u-boot

git fetch \
  rk3399-lpddr4:amarula-lpddr4 rk3399-build-target:amarula-parent
git cherry-pick amarula-parent..amarula-lpddr4
# There's a merge conflict to resolve; after fixing, remember to git add
# the resolved file before resuming with git cherry-pick --continue.

sed 's/rock-pi-4/khadas-edge/g' configs/rock-pi-4-rk3399_defconfig \
cp arch/arm/dts/rk3399-{rock-pi-4,khadas-edge}-u-boot.dtsi

# Put Edge device tree from Linux at arch/arm/dts/rk3399-khadas-edge.dts
# and add rk3399-khadas-edge.dtb to dtb-$(CONFIG_ROCKCHIP_RK3399) in
# arch/arm/dts/Makefile.

git add configs/khadas-edge-rk3399_defconfig
git add arch/arm/dts/{Makefile,rk3399-khadas-edge*.dts*}
git commit -m 'rockchip: rk3399: Add Khadas Edge board support'

Prerequisites to build U-Boot:

  • cross-compiling needs aarch64-linux-gnu (or -musl) gcc and binutils;
  • the Trusted Firmware Cortex-M0 code needs an arm-none-eabi toolchain;
  • python and pyelftools are used to generate a FIT image from bl31.elf.

Fetch and build ARM Trusted Firmware to get bl31 component:

git clone atf
make -C atf CROSS_COMPILE=aarch64-linux-gnu- PLAT=rk3399 bl31
cp atf/build/rk3399/release/bl31/bl31.elf bl31.elf

Build U-Boot:

make khadas-edge-rk3399_defconfig
make ARCH=arm CROSS_COMPILE=aarch64-linux-gnu-

TPL is needed with the default config as the built SPL is too large for the RK3399 boot ROM to load. Write TPL + SPL + U-Boot to the SD card:

tools/mkimage -n rk3399 -T rksd -d tpl/u-boot-tpl-dtb.bin tpl-spl.img
cat spl/u-boot-spl-dtb.bin >>tpl-spl.img
dd if=tpl-spl.img of=/dev/mmcblkN seek=64 conv=fsync
dd if=u-boot.itb of=/dev/mmcblkN seek=16384 conv=fsync

Assuming the SD card already has a suitable partition table, boot partition with extlinux.conf, kernel and dtb, e.g. by starting with an existing image, U-Boot will happily now boot it.


Here it is booting an Armbian image with a random 5.2-rcN kernel I happened to be testing at the time:

U-Boot TPL 2019.07-rc4-00457-gb45e4f05d6-dirty (Jul 06 2019 - 22:28:03 +0100)
Trying to boot from BOOTROM
Returning to boot ROM...

U-Boot SPL 2019.07-rc4-00457-gb45e4f05d6-dirty (Jul 06 2019 - 22:28:03 +0100)
Trying to boot from MMC1

U-Boot 2019.07-rc4-00457-gb45e4f05d6-dirty (Jul 06 2019 - 22:28:03 +0100)

Model: Khadas Edge
DRAM: 3.9 GiB
Cannot find regulator pwm init_voltage
MMC: dwmmc@fe310000: 2, dwmmc@fe320000: 1, sdhci@fe330000: 0
Loading Environment from MMC... *** Warning - bad CRC, using default environment

In: serial@ff1a0000
Out: serial@ff1a0000
Err: serial@ff1a0000
Model: Khadas Edge
Net: No ethernet found.
Hit any key to stop autoboot: 0
switch to partitions #0, OK
mmc0(part 0) is current device
** No partition table - mmc 0 **
switch to partitions #0, OK
mmc1 is current device
Scanning mmc 1:1...
Found /extlinux/extlinux.conf
Retrieving file: /extlinux/extlinux.conf
248 bytes read in 4 ms (60.5 KiB/s)
1: Armbian
Retrieving file: /testkernel
16517128 bytes read in 709 ms (22.2 MiB/s)
append: root=179:2 rootflags=data=writeback rw console=uart8250,mmio32,0xff1a0000 no_console_suspend consoleblank=0 fsck.fix=yes net.ifnames=0
Retrieving file: /dtb/rk3399-khadas-edge.dtb
57536 bytes read in 8 ms (6.9 MiB/s)
## Flattened Device Tree blob at 01f00000
Booting using the fdt blob at 0x1f00000
Loading Device Tree to 00000000f5f15000, end 00000000f5f260bf ... OK

Starting kernel ...

[System then boots]

It will almost certainly be possible to skip the TPL and get the SPL down to a size where it would directly boot with a less ‘kitchen sink’ configuration of U-Boot than the defconfig.

I will continute upstream the code for Edge when this merged…

Current status:


Yes, I think that sounds sensible to me — mainline U-Boot won’t boot Edge on its own without the ddr4 support, so Jagan’s epic 99-patch lpddr4 series is effectively a dependency.

Nice to see that the existing ddr4 work is completely sufficient to get Edge booting though; there don’t seem to be any other ‘gotchas’ lurking in the shadows!

Given the working device trees in -next and therefore Linux 5.3, it looks like the next releases (Linux 5.3 and U-Boot 2019.10) will fully support Edge in mainline without further patches.

(I think the one remaining issue to debug is the problem with the bcm4359 wifi chipset on the brcmfmac driver. It’s on my list to play with soon, as it’d be nice to get that bug fixed too in time for 5.3.)

1 Like

I’ve updated my tree with an extra patch to remove the slightly annoying/obscure dependency on pyelftools when building u-boot for rockchip, in case it’s useful to anyone.

1 Like