Merge tag 'fixes-v2020.01' of https://gitlab.denx.de/u-boot/custodians/u-boot-video

- fix missing graphics output on some x86 boards
- avoid using #ifdef in video code
- add .gitignore for video font *.S files
diff --git a/.gitignore b/.gitignore
index f980ae6..2e1c8bf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,6 +7,7 @@
 #
 .*
 *.a
+*.asn1.[ch]
 *.bin
 *.cfgout
 *.dtb
diff --git a/.mailmap b/.mailmap
index 98d2131..61802f9 100644
--- a/.mailmap
+++ b/.mailmap
@@ -29,6 +29,7 @@
 Jagan Teki <jaganna@xilinx.com>
 Jagan Teki <jagannadh.teki@gmail.com>
 Jagan Teki <jagannadha.sutradharudu-teki@xilinx.com>
+Igor Opaniuk <igor.opaniuk@gmail.com> <igor.opaniuk@linaro.org>
 Markus Klotzbuecher <mk@denx.de>
 Paul Burton <paul.burton@mips.com> <paul.burton@imgtec.com>
 Prabhakar Kushwaha <prabhakar@freescale.com>
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index f9dab07..36c9c2f 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -17,7 +17,7 @@
 	  be loaded to and run from that address. This option lifts that
 	  restriction, thus allowing the code to be loaded to and executed
 	  from almost any address. This logic relies on the relocation
-	  information that is embedded into the binary to support U-Boot
+	  information that is embedded in the binary to support U-Boot
 	  relocating itself to the top-of-RAM later during execution.
 
 config INIT_SP_RELATIVE
@@ -26,7 +26,7 @@
 	  U-Boot typically uses a hard-coded value for the stack pointer
 	  before relocation. Enable this option to instead calculate the
 	  initial SP at run-time. This is useful to avoid hard-coding addresses
-	  into U-Boot, so that can be loaded and executed at arbitrary
+	  into U-Boot, so that it can be loaded and executed at arbitrary
 	  addresses and thus avoid using arbitrary addresses at runtime.
 
 	  If this option is enabled, the early stack pointer is set to
@@ -57,7 +57,7 @@
 	hex
 	help
 	  The value subtracted from CONFIG_SYS_TEXT_BASE to calculate the
-	  TEXT_OFFSET value written in to the Linux kernel image header.
+	  TEXT_OFFSET value written to the Linux kernel image header.
 endif
 endif
 
@@ -121,7 +121,7 @@
 	select SYS_ARM_CACHE_CP15
 	help
 	  Select if you want MMU-based virtualised addressing space
-	  support by paged memory management.
+	  support via paged memory management.
 
 config SYS_ARM_MPU
 	bool 'Use the ARM v7 PMSA Compliant MPU'
@@ -136,8 +136,8 @@
 # startup. Note that in general these options force the workarounds to be
 # applied; no CPU-type/version detection exists, unlike the similar options in
 # the Linux kernel. Do not set these options unless they apply!  Also note that
-# the following can be machine specific errata. These do have ability to
-# provide rudimentary version and machine specific checks, but expect no
+# the following can be machine-specific errata. These do have ability to
+# provide rudimentary version and machine-specific checks, but expect no
 # product checks:
 # CONFIG_ARM_ERRATA_430973
 # CONFIG_ARM_ERRATA_454179
@@ -332,7 +332,7 @@
 config ARCH_CPU_INIT
 	bool "Enable ARCH_CPU_INIT"
 	help
-	  Some architectures require a call to arch_cpu_init()
+	  Some architectures require a call to arch_cpu_init().
 	  Say Y here to enable it
 
 config SYS_ARCH_TIMER
@@ -342,7 +342,7 @@
 	help
 	  The ARM Generic Timer (aka arch-timer) provides an architected
 	  interface to a timer source on an SoC.
-	  It is mandantory for ARMv8 implementation and widely available
+	  It is mandatory for ARMv8 implementation and widely available
 	  on ARMv7 systems.
 
 config ARM_SMCCC
@@ -385,7 +385,7 @@
 	default y if SYS_THUMB_BUILD
 	depends on TPL && !ARM64
 	help
-	   Use this flag to build SPL using the Thumb instruction set for
+	   Use this flag to build TPL using the Thumb instruction set for
 	   ARM architectures. Thumb instruction set provides better code
 	   density. For ARM architectures that support Thumb2 this flag will
 	   result in Thumb2 code generated by GCC.
@@ -394,7 +394,7 @@
 config SYS_L2CACHE_OFF
 	bool "L2cache off"
 	help
-	  If SoC does not support L2CACHE or one do not want to enable
+	  If SoC does not support L2CACHE or one does not want to enable
 	  L2CACHE, choose this option.
 
 config ENABLE_ARM_SOC_BOOT0_HOOK
@@ -414,7 +414,7 @@
 	depends on !ARM64
 	help
 	  Enable the generation of an optimized version of memcpy.
-	  Such implementation may be faster under some conditions
+	  Such an implementation may be faster under some conditions
 	  but may increase the binary size.
 
 config SPL_USE_ARCH_MEMCPY
@@ -423,7 +423,7 @@
 	depends on !ARM64 && SPL
 	help
 	  Enable the generation of an optimized version of memcpy.
-	  Such implementation may be faster under some conditions
+	  Such an implementation may be faster under some conditions
 	  but may increase the binary size.
 
 config TPL_USE_ARCH_MEMCPY
@@ -432,7 +432,7 @@
 	depends on !ARM64 && TPL
 	help
 	  Enable the generation of an optimized version of memcpy.
-	  Such implementation may be faster under some conditions
+	  Such an implementation may be faster under some conditions
 	  but may increase the binary size.
 
 config USE_ARCH_MEMSET
@@ -441,7 +441,7 @@
 	depends on !ARM64
 	help
 	  Enable the generation of an optimized version of memset.
-	  Such implementation may be faster under some conditions
+	  Such an implementation may be faster under some conditions
 	  but may increase the binary size.
 
 config SPL_USE_ARCH_MEMSET
@@ -450,7 +450,7 @@
 	depends on !ARM64 && SPL
 	help
 	  Enable the generation of an optimized version of memset.
-	  Such implementation may be faster under some conditions
+	  Such an implementation may be faster under some conditions
 	  but may increase the binary size.
 
 config TPL_USE_ARCH_MEMSET
@@ -459,7 +459,7 @@
 	depends on !ARM64 && TPL
 	help
 	  Enable the generation of an optimized version of memset.
-	  Such implementation may be faster under some conditions
+	  Such an implementation may be faster under some conditions
 	  but may increase the binary size.
 
 config SET_STACK_SIZE
@@ -467,14 +467,14 @@
 	default y if ARCH_VERSAL || ARCH_ZYNQMP
 	help
 	  This will enable an option to set max stack size that can be
-	  used by u-boot.
+	  used by U-Boot.
 
 config STACK_SIZE
-	hex "Define max stack size that can be used by u-boot"
+	hex "Define max stack size that can be used by U-Boot"
 	depends on SET_STACK_SIZE
 	default 0x4000000 if ARCH_VERSAL || ARCH_ZYNQMP
 	help
-	  Defines Max stack size that can be used by u-boot so that the
+	  Define Max stack size that can be used by U-Boot so that the
 	  initrd_high will be calculated as base stack pointer minus this
 	  stack size.
 
@@ -689,7 +689,7 @@
 	help
 	  Support for Broadcom Northstar 2 SoCs.  NS2 is a quad-core 64-bit
 	  ARMv8 Cortex-A57 processors targeting a broad range of networking
-	  applications
+	  applications.
 
 config ARCH_EXYNOS
 	bool "Samsung EXYNOS"
@@ -1101,8 +1101,8 @@
 	select ARMV8_MULTIENTRY
 	select FSL_DDR_SYNC_REFRESH
 	help
-	  Support for Freescale LS2080A_EMU platform
-	  The LS2080A Development System (EMULATOR) is a pre silicon
+	  Support for Freescale LS2080A_EMU platform.
+	  The LS2080A Development System (EMULATOR) is a pre-silicon
 	  development platform that supports the QorIQ LS2080A
 	  Layerscape Architecture processor.
 
@@ -1114,7 +1114,7 @@
 	select ARMV8_MULTIENTRY
 	select BOARD_LATE_INIT
 	help
-	  Support for Freescale LS2080A_SIMU platform
+	  Support for Freescale LS2080A_SIMU platform.
 	  The LS2080A Development System (QDS) is a pre silicon
 	  development platform that supports the QorIQ LS2080A
 	  Layerscape Architecture processor.
@@ -1130,7 +1130,7 @@
 	select SUPPORT_SPL
 	select FSL_DDR_INTERACTIVE if !SD_BOOT
 	help
-	  Support for NXP LS1088AQDS platform
+	  Support for NXP LS1088AQDS platform.
 	  The LS1088A Development System (QDS) is a high-performance
 	  development platform that supports the QorIQ LS1088A
 	  Layerscape Architecture processor.
@@ -1149,7 +1149,7 @@
 	select FSL_DDR_BIST
 	select FSL_DDR_INTERACTIVE if !SPL
 	help
-	  Support for Freescale LS2080AQDS platform
+	  Support for Freescale LS2080AQDS platform.
 	  The LS2080A Development System (QDS) is a high-performance
 	  development platform that supports the QorIQ LS2080A
 	  Layerscape Architecture processor.
@@ -1649,7 +1649,7 @@
 	default n
 	help
 	  Enabling this will make a U-Boot binary that is capable of being
-	  booted via TF-A.
+	  booted via TF-A (Trusted Firmware for Cortex-A).
 
 config TI_SECURE_DEVICE
 	bool "HS Device Type Support"
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 88c750a..0127a91 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -68,7 +68,8 @@
 	bubblegum_96.dtb
 
 dtb-$(CONFIG_ROCKCHIP_PX30) += \
-	px30-evb.dtb
+	px30-evb.dtb \
+	px30-firefly.dtb
 
 dtb-$(CONFIG_ROCKCHIP_RK3036) += \
 	rk3036-sdk.dtb
diff --git a/arch/arm/dts/px30-firefly-u-boot.dtsi b/arch/arm/dts/px30-firefly-u-boot.dtsi
new file mode 100644
index 0000000..bb782b4
--- /dev/null
+++ b/arch/arm/dts/px30-firefly-u-boot.dtsi
@@ -0,0 +1,84 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * (C) Copyright 2019 Rockchip Electronics Co., Ltd
+ */
+
+/ {
+	aliases {
+		mmc0 = &emmc;
+		mmc1 = &sdmmc;
+	};
+
+	chosen {
+		u-boot,spl-boot-order = &emmc, &sdmmc;
+	};
+};
+
+&dmc {
+	u-boot,dm-pre-reloc;
+};
+
+&uart2 {
+	clock-frequency = <24000000>;
+	u-boot,dm-pre-reloc;
+};
+
+&uart5 {
+	clock-frequency = <24000000>;
+	u-boot,dm-pre-reloc;
+};
+
+&sdmmc {
+	u-boot,dm-pre-reloc;
+
+	/* mmc to sram can't do dma, prevent aborts transferring TF-A parts */
+	u-boot,spl-fifo-mode;
+};
+
+&emmc {
+	u-boot,dm-pre-reloc;
+
+	/* mmc to sram can't do dma, prevent aborts transferring TF-A parts */
+	u-boot,spl-fifo-mode;
+};
+
+&grf {
+	u-boot,dm-pre-reloc;
+};
+
+&pmugrf {
+	u-boot,dm-pre-reloc;
+};
+
+&xin24m {
+	u-boot,dm-pre-reloc;
+};
+
+&cru {
+	u-boot,dm-pre-reloc;
+};
+
+&pmucru {
+	u-boot,dm-pre-reloc;
+};
+
+&saradc {
+	u-boot,dm-pre-reloc;
+	status = "okay";
+};
+
+&gpio0 {
+	u-boot,dm-pre-reloc;
+};
+
+&gpio1 {
+	u-boot,dm-pre-reloc;
+};
+
+&gpio2 {
+	u-boot,dm-pre-reloc;
+};
+
+&gpio3 {
+	u-boot,dm-pre-reloc;
+};
diff --git a/arch/arm/dts/px30-firefly.dts b/arch/arm/dts/px30-firefly.dts
new file mode 100644
index 0000000..c0a8e300
--- /dev/null
+++ b/arch/arm/dts/px30-firefly.dts
@@ -0,0 +1,531 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
+ */
+
+/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include "px30.dtsi"
+
+/ {
+	model = "Firefly Core-PX30-JD4";
+	compatible = "rockchip,px30-firefly", "rockchip,px30";
+
+	chosen {
+		stdout-path = "serial2:115200n8";
+	};
+
+	adc-keys {
+		compatible = "adc-keys";
+		io-channels = <&saradc 2>;
+		io-channel-names = "buttons";
+		keyup-threshold-microvolt = <1800000>;
+		poll-interval = <100>;
+
+		esc-key {
+			label = "esc";
+			linux,code = <KEY_ESC>;
+			press-threshold-microvolt = <1310000>;
+		};
+
+		home-key {
+			label = "home";
+			linux,code = <KEY_HOME>;
+			press-threshold-microvolt = <624000>;
+		};
+
+		menu-key {
+			label = "menu";
+			linux,code = <KEY_MENU>;
+			press-threshold-microvolt = <987000>;
+		};
+
+		vol-down-key {
+			label = "volume down";
+			linux,code = <KEY_VOLUMEDOWN>;
+			press-threshold-microvolt = <300000>;
+		};
+
+		vol-up-key {
+			label = "volume up";
+			linux,code = <KEY_VOLUMEUP>;
+			press-threshold-microvolt = <17000>;
+		};
+	};
+
+	backlight: backlight {
+		compatible = "pwm-backlight";
+		pwms = <&pwm1 0 25000 0>;
+		power-supply = <&vcc3v3_lcd>;
+	};
+
+	emmc_pwrseq: emmc-pwrseq {
+		compatible = "mmc-pwrseq-emmc";
+		pinctrl-0 = <&emmc_reset>;
+		pinctrl-names = "default";
+		reset-gpios = <&gpio1 RK_PB3 GPIO_ACTIVE_HIGH>;
+	};
+
+	sdio_pwrseq: sdio-pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		pinctrl-names = "default";
+		pinctrl-0 = <&wifi_enable_h>;
+
+		/*
+		 * On the module itself this is one of these (depending
+		 * on the actual card populated):
+		 * - SDIO_RESET_L_WL_REG_ON
+		 * - PDN (power down when low)
+		 */
+		reset-gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_LOW>; /* GPIO3_A4 */
+	};
+
+	vcc5v0_sys: vccsys {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc5v0_sys";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+	};
+};
+
+&cpu0 {
+	cpu-supply = <&vdd_arm>;
+};
+
+&cpu1 {
+	cpu-supply = <&vdd_arm>;
+};
+
+&cpu2 {
+	cpu-supply = <&vdd_arm>;
+};
+
+&cpu3 {
+	cpu-supply = <&vdd_arm>;
+};
+
+&display_subsystem {
+	status = "okay";
+};
+
+&dsi {
+	status = "okay";
+
+	ports {
+		mipi_out: port@1 {
+			reg = <1>;
+
+			mipi_out_panel: endpoint {
+				remote-endpoint = <&mipi_in_panel>;
+			};
+		};
+	};
+
+	panel@0 {
+		compatible = "sitronix,st7703";
+		reg = <0>;
+		backlight = <&backlight>;
+		iovcc-supply = <&vcc_1v8>;
+		vci-supply = <&vcc3v3_lcd>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+
+				mipi_in_panel: endpoint {
+					remote-endpoint = <&mipi_out_panel>;
+				};
+			};
+		};
+	};
+};
+
+&dsi_dphy {
+	status = "okay";
+};
+
+&emmc {
+	bus-width = <8>;
+	cap-mmc-highspeed;
+	mmc-hs200-1_8v;
+	non-removable;
+	mmc-pwrseq = <&emmc_pwrseq>;
+	vmmc-supply = <&vcc_3v0>;
+	vqmmc-supply = <&vccio_flash>;
+	status = "okay";
+};
+
+&gmac {
+	clock_in_out = "output";
+	phy-supply = <&vcc_rmii>;
+	snps,reset-gpio = <&gpio2 13 GPIO_ACTIVE_LOW>;
+	snps,reset-active-low;
+	snps,reset-delays-us = <0 50000 50000>;
+	status = "okay";
+};
+
+&i2c0 {
+	status = "okay";
+
+	rk809: pmic@20 {
+		compatible = "rockchip,rk809";
+		reg = <0x20>;
+		interrupt-parent = <&gpio0>;
+		interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pmic_int>;
+		rockchip,system-power-controller;
+		wakeup-source;
+		#clock-cells = <0>;
+		clock-output-names = "xin32k";
+
+		vcc1-supply = <&vcc5v0_sys>;
+		vcc2-supply = <&vcc5v0_sys>;
+		vcc3-supply = <&vcc5v0_sys>;
+		vcc4-supply = <&vcc5v0_sys>;
+		vcc5-supply = <&vcc3v3_sys>;
+		vcc6-supply = <&vcc3v3_sys>;
+		vcc7-supply = <&vcc3v3_sys>;
+		vcc8-supply = <&vcc3v3_sys>;
+		vcc9-supply = <&vcc5v0_sys>;
+
+		regulators {
+			vdd_log: DCDC_REG1 {
+				regulator-name = "vdd_log";
+				regulator-min-microvolt = <950000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-ramp-delay = <6001>;
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <950000>;
+				};
+			};
+
+			vdd_arm: DCDC_REG2 {
+				regulator-name = "vdd_arm";
+				regulator-min-microvolt = <950000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-ramp-delay = <6001>;
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+					regulator-suspend-microvolt = <950000>;
+				};
+			};
+
+			vcc_ddr: DCDC_REG3 {
+				regulator-name = "vcc_ddr";
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+				};
+			};
+
+			vcc_3v0: vcc_rmii: DCDC_REG4 {
+				regulator-name = "vcc_3v0";
+				regulator-min-microvolt = <3000000>;
+				regulator-max-microvolt = <3000000>;
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <3000000>;
+				};
+			};
+
+			vcc3v3_sys: DCDC_REG5 {
+				regulator-name = "vcc3v3_sys";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <3300000>;
+				};
+			};
+
+			vcc_1v0: LDO_REG1 {
+				regulator-name = "vcc_1v0";
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <1000000>;
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <1000000>;
+				};
+			};
+
+			vcc_1v8: vccio_flash: vccio_sdio: LDO_REG2 {
+				regulator-name = "vcc_1v8";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <1800000>;
+				};
+			};
+
+			vdd_1v0: LDO_REG3 {
+				regulator-name = "vdd_1v0";
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <1000000>;
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <1000000>;
+				};
+			};
+
+			vcc3v0_pmu: LDO_REG4 {
+				regulator-name = "vcc3v0_pmu";
+				regulator-min-microvolt = <3000000>;
+				regulator-max-microvolt = <3000000>;
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <3000000>;
+				};
+			};
+
+			vccio_sd: LDO_REG5 {
+				regulator-name = "vccio_sd";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <3300000>;
+				};
+			};
+
+			vcc_sd: LDO_REG6 {
+				regulator-name = "vcc_sd";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <3300000>;
+				};
+			};
+
+			vcc2v8_dvp: LDO_REG7 {
+				regulator-name = "vcc2v8_dvp";
+				regulator-min-microvolt = <2800000>;
+				regulator-max-microvolt = <2800000>;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+					regulator-suspend-microvolt = <2800000>;
+				};
+			};
+
+			vcc1v8_dvp: LDO_REG8 {
+				regulator-name = "vcc1v8_dvp";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <1800000>;
+				};
+			};
+
+			vcc1v5_dvp: LDO_REG9 {
+				regulator-name = "vcc1v5_dvp";
+				regulator-min-microvolt = <1500000>;
+				regulator-max-microvolt = <1500000>;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+					regulator-suspend-microvolt = <1500000>;
+				};
+			};
+
+			vcc3v3_lcd: SWITCH_REG1 {
+				regulator-name = "vcc3v3_lcd";
+				regulator-boot-on;
+			};
+
+			vcc5v0_host: SWITCH_REG2 {
+				regulator-name = "vcc5v0_host";
+				regulator-always-on;
+				regulator-boot-on;
+			};
+		};
+	};
+};
+
+&i2s1_2ch {
+	status = "okay";
+};
+
+&io_domains {
+	status = "okay";
+
+	vccio1-supply = <&vccio_sdio>;
+	vccio2-supply = <&vccio_sd>;
+	vccio3-supply = <&vcc_3v0>;
+	vccio4-supply = <&vcc3v0_pmu>;
+	vccio5-supply = <&vcc_3v0>;
+	vccio6-supply = <&vccio_flash>;
+};
+
+&pinctrl {
+	headphone {
+		hp_det: hp-det {
+			rockchip,pins =
+				<2 RK_PB0 RK_FUNC_GPIO &pcfg_pull_down>;
+		};
+	};
+
+	emmc {
+		emmc_reset: emmc-reset {
+			rockchip,pins = <1 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	pmic {
+		pmic_int: pmic_int {
+			rockchip,pins =
+				<0 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+
+		soc_slppin_gpio: soc_slppin_gpio {
+			rockchip,pins =
+				<0 RK_PA4 RK_FUNC_GPIO &pcfg_output_low>;
+		};
+
+		soc_slppin_slp: soc_slppin_slp {
+			rockchip,pins =
+				<0 RK_PA4 1 &pcfg_pull_none>;
+		};
+
+		soc_slppin_rst: soc_slppin_rst {
+			rockchip,pins =
+				<0 RK_PA4 2 &pcfg_pull_none>;
+		};
+	};
+
+	sdio-pwrseq {
+		wifi_enable_h: wifi-enable-h {
+			rockchip,pins =
+				<0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+};
+
+&pmu_io_domains {
+	status = "okay";
+
+	pmuio1-supply = <&vcc3v0_pmu>;
+	pmuio2-supply = <&vcc3v0_pmu>;
+};
+
+&pwm1 {
+	status = "okay";
+};
+
+&saradc {
+	vref-supply = <&vcc_1v8>;
+	status = "okay";
+};
+
+&sdmmc {
+	bus-width = <4>;
+	cap-mmc-highspeed;
+	cap-sd-highspeed;
+	card-detect-delay = <800>;
+	sd-uhs-sdr12;
+	sd-uhs-sdr25;
+	sd-uhs-sdr50;
+	sd-uhs-sdr104;
+	vmmc-supply = <&vcc_sd>;
+	vqmmc-supply = <&vccio_sd>;
+};
+
+&sdio {
+	bus-width = <4>;
+	cap-sd-highspeed;
+	keep-power-in-suspend;
+	non-removable;
+	mmc-pwrseq = <&sdio_pwrseq>;
+	sd-uhs-sdr104;
+	status = "okay";
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart1_xfer &uart1_cts>;
+	status = "okay";
+};
+
+&uart2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart2m1_xfer>;
+	status = "okay";
+};
+
+&uart5 {
+	status = "okay";
+};
+
+&usb20_otg {
+	status = "okay";
+};
+
+&usb_host0_ehci {
+	status = "okay";
+};
+
+&usb_host0_ohci {
+	status = "okay";
+};
+
+&vopb {
+	status = "okay";
+};
+
+&vopb_mmu {
+	status = "okay";
+};
+
+&vopl {
+	status = "okay";
+};
+
+&vopl_mmu {
+	status = "okay";
+};
diff --git a/arch/arm/dts/rk3328-u-boot.dtsi b/arch/arm/dts/rk3328-u-boot.dtsi
index ffbd657..6d5b3ec 100644
--- a/arch/arm/dts/rk3328-u-boot.dtsi
+++ b/arch/arm/dts/rk3328-u-boot.dtsi
@@ -51,8 +51,14 @@
 
 &emmc {
 	u-boot,dm-pre-reloc;
+
+	/* mmc to sram can't do dma, prevent aborts transfering TF-A parts */
+	u-boot,spl-fifo-mode;
 };
 
 &sdmmc {
 	u-boot,dm-pre-reloc;
+
+	/* mmc to sram can't do dma, prevent aborts transfering TF-A parts */
+	u-boot,spl-fifo-mode;
 };
diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig
index d8d68ba..b689a42 100644
--- a/arch/arm/mach-rockchip/Kconfig
+++ b/arch/arm/mach-rockchip/Kconfig
@@ -306,7 +306,7 @@
 	  no TPL for the board.
 
 config TPL_ROCKCHIP_COMMON_BOARD
-	bool ""
+	bool "Rockchip TPL common board file"
 	depends on TPL
 	help
 	  Rockchip SoCs have similar boot process, prefer to use TPL for DRAM
diff --git a/arch/arm/mach-rockchip/fit_spl_optee.sh b/arch/arm/mach-rockchip/fit_spl_optee.sh
index 89ef043..4118472 100755
--- a/arch/arm/mach-rockchip/fit_spl_optee.sh
+++ b/arch/arm/mach-rockchip/fit_spl_optee.sh
@@ -17,6 +17,12 @@
 fi
 
 dtname=$1
+text_base=`sed -n "/SYS_TEXT_BASE=/s/CONFIG_SYS_TEXT_BASE=//p" .config \
+	   |tr -d '\r'`
+dram_base=`sed -n "/SYS_SDRAM_BASE=/s/CONFIG_SYS_SDRAM_BASE=//p" \
+	   include/autoconf.mk|tr -d '\r'`
+tee_base=`echo "obase=16;$(($dram_base+0x8400000))"|bc`
+tee_base='0x'$tee_base
 
 cat << __HEADER_EOF
 /*
@@ -39,7 +45,7 @@
 			os = "U-Boot";
 			arch = "arm";
 			compression = "none";
-			load = <0x61000000>;
+			load = <$text_base>;
 		};
 		optee {
 			description = "OP-TEE";
@@ -48,8 +54,8 @@
 			arch = "arm";
 			os = "tee";
 			compression = "none";
-			load = <0x68400000>;
-			entry = <0x68400000>;
+			load = <$tee_base>;
+			entry = <$tee_base>;
 		};
 		fdt {
 			description = "$(basename $dtname .dtb)";
diff --git a/arch/arm/mach-rockchip/make_fit_atf.py b/arch/arm/mach-rockchip/make_fit_atf.py
index 3c045a5..c79317d 100755
--- a/arch/arm/mach-rockchip/make_fit_atf.py
+++ b/arch/arm/mach-rockchip/make_fit_atf.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 """
 # SPDX-License-Identifier: GPL-2.0+
 #
diff --git a/configs/evb-rk3288_defconfig b/configs/evb-rk3288_defconfig
index 1fa4054..fe0ee3d 100644
--- a/configs/evb-rk3288_defconfig
+++ b/configs/evb-rk3288_defconfig
@@ -4,20 +4,25 @@
 CONFIG_ROCKCHIP_RK3288=y
 CONFIG_TARGET_EVB_RK3288=y
 CONFIG_ENV_OFFSET=0x3F8000
-CONFIG_SPL_STACK_R_ADDR=0x80000
-CONFIG_NR_DRAM_BANKS=1
+CONFIG_SPL_STACK_R_ADDR=0x04000000
+CONFIG_NR_DRAM_BANKS=2
 CONFIG_SPL_SIZE_LIMIT=0x4b000
 CONFIG_DEBUG_UART_BASE=0xff690000
 CONFIG_DEBUG_UART_CLOCK=24000000
 CONFIG_DEBUG_UART=y
 # CONFIG_ANDROID_BOOT_IMAGE is not set
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_SPL_LOAD_FIT=y
+CONFIG_SPL_FIT_GENERATOR="arch/arm/mach-rockchip/fit_spl_optee.sh"
 CONFIG_USE_PREBOOT=y
 CONFIG_SILENT_CONSOLE=y
 CONFIG_DEFAULT_FDT_FILE="rk3288-evb-rk808.dtb"
 # CONFIG_DISPLAY_CPUINFO is not set
 CONFIG_DISPLAY_BOARDINFO_LATE=y
 CONFIG_SPL_STACK_R=y
-CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x2000
+CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x10000
+CONFIG_SPL_OPTEE=y
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_GPT=y
 CONFIG_CMD_I2C=y
diff --git a/configs/evb-rk3328_defconfig b/configs/evb-rk3328_defconfig
index 3e19135..3db40a9 100644
--- a/configs/evb-rk3328_defconfig
+++ b/configs/evb-rk3328_defconfig
@@ -7,7 +7,8 @@
 CONFIG_TPL_LIBGENERIC_SUPPORT=y
 CONFIG_SPL_DRIVERS_MISC_SUPPORT=y
 CONFIG_ENV_OFFSET=0x3F8000
-CONFIG_SPL_STACK_R_ADDR=0x600000
+CONFIG_SPL_STACK_R_ADDR=0x4000000
+CONFIG_SPL_SYS_MALLOC_F_LEN=0x4000
 CONFIG_NR_DRAM_BANKS=1
 CONFIG_DEBUG_UART_BASE=0xFF130000
 CONFIG_DEBUG_UART_CLOCK=24000000
@@ -23,6 +24,9 @@
 # CONFIG_SPL_RAW_IMAGE_SUPPORT is not set
 CONFIG_TPL_SYS_MALLOC_SIMPLE=y
 CONFIG_SPL_STACK_R=y
+CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x10000
+CONFIG_SPL_ATF=y
+CONFIG_SPL_ATF_NO_PLATFORM_PARAM=y
 CONFIG_TPL_DRIVERS_MISC_SUPPORT=y
 CONFIG_CMD_BOOTZ=y
 CONFIG_CMD_GPT=y
diff --git a/configs/firefly-px30_defconfig b/configs/firefly-px30_defconfig
index fa4ac75..e24f1cf 100644
--- a/configs/firefly-px30_defconfig
+++ b/configs/firefly-px30_defconfig
@@ -20,7 +20,7 @@
 CONFIG_FIT_VERBOSE=y
 CONFIG_SPL_LOAD_FIT=y
 # CONFIG_CONSOLE_MUX is not set
-CONFIG_DEFAULT_FDT_FILE="rockchip/px30-evb.dtb"
+CONFIG_DEFAULT_FDT_FILE="rockchip/px30-firefly.dtb"
 CONFIG_MISC_INIT_R=y
 # CONFIG_DISPLAY_CPUINFO is not set
 CONFIG_DISPLAY_BOARDINFO_LATE=y
@@ -32,7 +32,7 @@
 CONFIG_SPL_ATF=y
 # CONFIG_TPL_FRAMEWORK is not set
 # CONFIG_CMD_BOOTD is not set
-CONFIG_DEBUG_UART2_CHANNEL=1
+CONFIG_DEBUG_UART_CHANNEL=1
 # CONFIG_CMD_ELF is not set
 # CONFIG_CMD_IMI is not set
 # CONFIG_CMD_XIMG is not set
@@ -53,7 +53,7 @@
 CONFIG_EFI_PARTITION_ENTRIES_NUMBERS=64
 CONFIG_SPL_OF_CONTROL=y
 CONFIG_OF_LIVE=y
-CONFIG_DEFAULT_DEVICE_TREE="px30-evb"
+CONFIG_DEFAULT_DEVICE_TREE="px30-firefly"
 CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents"
 CONFIG_ENV_IS_IN_MMC=y
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
diff --git a/doc/README.rockchip b/doc/README.rockchip
index dae4ebc..9b699b9 100644
--- a/doc/README.rockchip
+++ b/doc/README.rockchip
@@ -50,7 +50,7 @@
 Two RK3308 boards are supported:
 
    - EVB RK3308 - use evb-rk3308 configuration
-   - ROC-CC-RK3308 - use roc-rk3308-cc configuration
+   - ROC-CC-RK3308 - use roc-cc-rk3308 configuration
 
 Two RK3328 board are supported:
 
@@ -106,7 +106,7 @@
    - Compile U-Boot
      => cd /path/to/u-boot
      => export BL31=/path/to/rkbin/bin/rk33/rk3308_bl31_v2.22.elf
-     => make roc-rk3308-cc_defconfig
+     => make roc-cc-rk3308_defconfig
      => make CROSS_COMPILE=aarch64-linux-gnu- all
      => ./tools/mkimage -n rk3308 -T rksd -d /path/to/rkbin/bin/rk33/rk3308_ddr_589MHz_uart2_m0_v1.26.bin idbloader.img
      => cat spl/u-boot-spl.bin  >> idbloader.img
@@ -340,6 +340,12 @@
    cat firefly-rk3288/u-boot-dtb.bin >> out && \
    sudo dd if=out of=/dev/sdc seek=64
 
+Or:
+   ./firefly-rk3288/tools/mkimage -n rk3288 -T rksd -d \
+	firefly-rk3288/spl/u-boot-spl-dtb.bin:firefly-rk3288/u-boot-dtb.bin \
+	out && \
+   sudo dd if=out of=/dev/sdc seek=64
+
 If you have an HDMI cable attached you should see a video console.
 
 For evb_rk3036 board:
@@ -347,6 +353,11 @@
 	cat evb-rk3036/u-boot-dtb.bin >> out && \
 	sudo dd if=out of=/dev/sdc seek=64
 
+Or:
+	./evb-rk3036/tools/mkimage -n rk3036 -T rksd -d \
+		evb-rk3036/spl/u-boot-spl.bin:evb-rk3036/u-boot-dtb.bin out && \
+	sudo dd if=out of=/dev/sdc seek=64
+
 Note: rk3036 SDMMC and debug uart use the same iomux, so if you boot from SD, the
       debug uart must be disabled
 
diff --git a/include/configs/rk3308_common.h b/include/configs/rk3308_common.h
index a67d3d7..bd9ac82 100644
--- a/include/configs/rk3308_common.h
+++ b/include/configs/rk3308_common.h
@@ -42,7 +42,7 @@
 #define ENV_MEM_LAYOUT_SETTINGS \
 	"scriptaddr=0x00500000\0" \
 	"pxefile_addr_r=0x00600000\0" \
-	"fdt_addr_r=0x01f00000\0" \
+	"fdt_addr_r=0x02800000\0" \
 	"kernel_addr_r=0x00680000\0" \
 	"ramdisk_addr_r=0x04000000\0"
 
diff --git a/include/configs/rk3328_common.h b/include/configs/rk3328_common.h
index b14da3a..407e5d2 100644
--- a/include/configs/rk3328_common.h
+++ b/include/configs/rk3328_common.h
@@ -11,6 +11,7 @@
 #define CONFIG_IRAM_BASE		0xff090000
 
 #define CONFIG_ROCKCHIP_STIMER_BASE    0xff1d0020
+#define COUNTER_FREQUENCY		24000000
 
 #define CONFIG_SYS_CBSIZE		1024
 #define CONFIG_SKIP_LOWLEVEL_INIT
diff --git a/test/py/tests/test_env.py b/test/py/tests/test_env.py
index 9bdaef9..6ff38f1 100644
--- a/test/py/tests/test_env.py
+++ b/test/py/tests/test_env.py
@@ -49,7 +49,7 @@
         for l in response.splitlines():
             if not '=' in l:
                 continue
-            (var, value) = l.strip().split('=', 1)
+            (var, value) = l.split('=', 1)
             self.env[var] = value
 
     def get_existent_var(self):
diff --git a/test/py/tests/test_handoff.py b/test/py/tests/test_handoff.py
index 0ee9722..038f030 100644
--- a/test/py/tests/test_handoff.py
+++ b/test/py/tests/test_handoff.py
@@ -6,7 +6,7 @@
 # Magic number to check that SPL handoff is working
 TEST_HANDOFF_MAGIC = 0x14f93c7b
 
-@pytest.mark.boardspec('sandbox')
+@pytest.mark.boardspec('sandbox_spl')
 @pytest.mark.buildconfigspec('spl')
 def test_handoff(u_boot_console):
     """Test that of-platdata can be generated and used in sandbox"""
diff --git a/tools/.gitignore b/tools/.gitignore
index d0176a7..82bdce2 100644
--- a/tools/.gitignore
+++ b/tools/.gitignore
@@ -1,3 +1,4 @@
+/asn1_compiler
 /atmel_pmecc_params
 /bin2header
 /bmp_logo
diff --git a/tools/imagetool.h b/tools/imagetool.h
index 2689a40..e1c778b 100644
--- a/tools/imagetool.h
+++ b/tools/imagetool.h
@@ -253,6 +253,7 @@
 int zynqmpbif_copy_image(int fd, struct image_tool_params *mparams);
 int imx8image_copy_image(int fd, struct image_tool_params *mparams);
 int imx8mimage_copy_image(int fd, struct image_tool_params *mparams);
+int rockchip_copy_image(int fd, struct image_tool_params *mparams);
 
 #define ___cat(a, b) a ## b
 #define __cat(a, b) ___cat(a, b)
diff --git a/tools/mkimage.c b/tools/mkimage.c
index 4217188..5f51d2c 100644
--- a/tools/mkimage.c
+++ b/tools/mkimage.c
@@ -544,6 +544,14 @@
 			ret = imx8mimage_copy_image(ifd, &params);
 			if (ret)
 				return ret;
+		} else if ((params.type == IH_TYPE_RKSD) ||
+				(params.type == IH_TYPE_RKSPI)) {
+			/* Rockchip has special Image format */
+			int ret;
+
+			ret = rockchip_copy_image(ifd, &params);
+			if (ret)
+				return ret;
 		} else {
 			copy_file(ifd, params.datafile, pad_len);
 		}
diff --git a/tools/rkcommon.c b/tools/rkcommon.c
index 0d908da..c2382df 100644
--- a/tools/rkcommon.c
+++ b/tools/rkcommon.c
@@ -14,8 +14,6 @@
 #include "mkimage.h"
 #include "rkcommon.h"
 
-#define DIV_ROUND_UP(n, d)	(((n) + (d) - 1) / (d))
-
 enum {
 	RK_SIGNATURE		= 0x0ff0aa55,
 };
@@ -80,6 +78,24 @@
 	{ "rv1108", "RK11", 0x1800, false },
 };
 
+/**
+ * struct spl_params - spl params parsed in check_params()
+ *
+ * @init_file:		Init data file path
+ * @init_size:		Aligned size of init data in bytes
+ * @boot_file:		Boot data file path
+ * @boot_size:		Aligned size of boot data in bytes
+ */
+
+struct spl_params {
+	char *init_file;
+	uint32_t init_size;
+	char *boot_file;
+	uint32_t boot_size;
+};
+
+static struct spl_params spl_params = { 0 };
+
 static unsigned char rc4_key[16] = {
 	124, 78, 3, 4, 85, 5, 9, 7,
 	45, 44, 123, 56, 23, 13, 23, 17
@@ -99,13 +115,26 @@
 	return NULL;
 }
 
+static int rkcommon_get_aligned_size(struct image_tool_params *params,
+				     const char *fname)
+{
+	int size;
+
+	size = imagetool_get_filesize(params, fname);
+	if (size < 0)
+		return -1;
+
+	/*
+	 * Pad to a 2KB alignment, as required for init/boot size by the ROM
+	 * (see https://lists.denx.de/pipermail/u-boot/2017-May/293268.html)
+	 */
+	return ROUND(size, RK_SIZE_ALIGN);
+}
+
 int rkcommon_check_params(struct image_tool_params *params)
 {
 	int i;
 
-	if (rkcommon_get_spl_info(params->imagename) != NULL)
-		return EXIT_SUCCESS;
-
 	/*
 	 * If this is a operation (list or extract), the don't require
 	 * imagename to be set.
@@ -113,6 +142,40 @@
 	if (params->lflag || params->iflag)
 		return EXIT_SUCCESS;
 
+	if (!rkcommon_get_spl_info(params->imagename))
+		goto err_spl_info;
+
+	spl_params.init_file = params->datafile;
+
+	spl_params.boot_file = strchr(spl_params.init_file, ':');
+	if (spl_params.boot_file) {
+		*spl_params.boot_file = '\0';
+		spl_params.boot_file += 1;
+	}
+
+	spl_params.init_size =
+		rkcommon_get_aligned_size(params, spl_params.init_file);
+	if (spl_params.init_size < 0)
+		return EXIT_FAILURE;
+
+	/* Boot file is optional, and only for back-to-bootrom functionality. */
+	if (spl_params.boot_file) {
+		spl_params.boot_size =
+			rkcommon_get_aligned_size(params, spl_params.boot_file);
+		if (spl_params.boot_size < 0)
+			return EXIT_FAILURE;
+	}
+
+	if (spl_params.init_size > rkcommon_get_spl_size(params)) {
+		fprintf(stderr,
+			"Error: SPL image is too large (size %#x than %#x)\n",
+			spl_params.init_size, rkcommon_get_spl_size(params));
+		return EXIT_FAILURE;
+	}
+
+	return EXIT_SUCCESS;
+
+err_spl_info:
 	fprintf(stderr, "ERROR: imagename (%s) is not supported!\n",
 		params->imagename ? params->imagename : "NULL");
 
@@ -155,8 +218,7 @@
 	return info->spl_rc4;
 }
 
-static void rkcommon_set_header0(void *buf, uint file_size,
-				 struct image_tool_params *params)
+static void rkcommon_set_header0(void *buf, struct image_tool_params *params)
 {
 	struct header0_info *hdr = buf;
 
@@ -164,16 +226,8 @@
 	hdr->signature = RK_SIGNATURE;
 	hdr->disable_rc4 = !rkcommon_need_rc4_spl(params);
 	hdr->init_offset = RK_INIT_OFFSET;
+	hdr->init_size = spl_params.init_size / RK_BLK_SIZE;
 
-	hdr->init_size = DIV_ROUND_UP(file_size, RK_BLK_SIZE);
-	/*
-	 * The init_size has to be a multiple of 4 blocks (i.e. of 2K)
-	 * or the BootROM will not boot the image.
-	 *
-	 * Note: To verify that this is not a legacy constraint, we
-	 *       rechecked this against the RK3399 BootROM.
-	 */
-	hdr->init_size = ROUND(hdr->init_size, 4);
 	/*
 	 * init_boot_size needs to be set, as it is read by the BootROM
 	 * to determine the size of the next-stage bootloader (e.g. U-Boot
@@ -182,29 +236,36 @@
 	 * see https://lists.denx.de/pipermail/u-boot/2017-May/293267.html
 	 * for a more detailed explanation by Andy Yan
 	 */
-	hdr->init_boot_size = hdr->init_size + RK_MAX_BOOT_SIZE / RK_BLK_SIZE;
+	if (spl_params.boot_file)
+		hdr->init_boot_size =
+			hdr->init_size + spl_params.boot_size / RK_BLK_SIZE;
+	else
+		hdr->init_boot_size =
+			hdr->init_size + RK_MAX_BOOT_SIZE / RK_BLK_SIZE;
 
 	rc4_encode(buf, RK_BLK_SIZE, rc4_key);
 }
 
-int rkcommon_set_header(void *buf, uint file_size,
-			struct image_tool_params *params)
+void rkcommon_set_header(void *buf,  struct stat *sbuf,  int ifd,
+			 struct image_tool_params *params)
 {
 	struct header1_info *hdr = buf + RK_SPL_HDR_START;
 
-	if (file_size > rkcommon_get_spl_size(params))
-		return -ENOSPC;
-
-	rkcommon_set_header0(buf, file_size, params);
+	rkcommon_set_header0(buf, params);
 
 	/* Set up the SPL name (i.e. copy spl_hdr over) */
 	memcpy(&hdr->magic, rkcommon_get_spl_hdr(params), RK_SPL_HDR_SIZE);
 
 	if (rkcommon_need_rc4_spl(params))
 		rkcommon_rc4_encode_spl(buf, RK_SPL_HDR_START,
-					params->file_size - RK_SPL_HDR_START);
+					spl_params.init_size);
 
-	return 0;
+	if (spl_params.boot_file) {
+		if (rkcommon_need_rc4_spl(params))
+			rkcommon_rc4_encode_spl(buf + RK_SPL_HDR_START,
+						spl_params.init_size,
+						spl_params.boot_size);
+	}
 }
 
 static inline unsigned rkcommon_offset_to_spi(unsigned offset)
@@ -296,7 +357,7 @@
 	struct header0_info header0;
 	struct spl_info *spl_info;
 	uint8_t image_type;
-	int ret;
+	int ret, boot_size;
 
 	ret = rkcommon_parse_header(buf, &header0, &spl_info);
 
@@ -314,7 +375,11 @@
 	printf("Image Type:   Rockchip %s (%s) boot image\n",
 	       spl_info->spl_hdr,
 	       (image_type == IH_TYPE_RKSD) ? "SD/MMC" : "SPI");
-	printf("Data Size:    %d bytes\n", header0.init_size * RK_BLK_SIZE);
+	printf("Init Data Size: %d bytes\n", header0.init_size * RK_BLK_SIZE);
+
+	boot_size = (header0.init_boot_size - header0.init_size) * RK_BLK_SIZE;
+	if (boot_size != RK_MAX_BOOT_SIZE)
+		printf("Boot Data Size: %d bytes\n", boot_size);
 }
 
 void rkcommon_rc4_encode_spl(void *buf, unsigned int offset, unsigned int size)
@@ -331,12 +396,8 @@
 }
 
 int rkcommon_vrec_header(struct image_tool_params *params,
-			 struct image_type_params *tparams,
-			 unsigned int alignment)
+			 struct image_type_params *tparams)
 {
-	unsigned int  unpadded_size;
-	unsigned int  padded_size;
-
 	/*
 	 * The SPL image looks as follows:
 	 *
@@ -362,19 +423,118 @@
 
 	/* Allocate, clear and install the header */
 	tparams->hdr = malloc(tparams->header_size);
-	if (!tparams->hdr)
-		return -ENOMEM;
+	if (!tparams->hdr) {
+		fprintf(stderr, "%s: Can't alloc header: %s\n",
+			params->cmdname, strerror(errno));
+		exit(EXIT_FAILURE);
+	}
 	memset(tparams->hdr, 0, tparams->header_size);
 
 	/*
-	 * If someone passed in 0 for the alignment, we'd better handle
-	 * it correctly...
+	 * We need to store the original file-size (i.e. before padding), as
+	 * imagetool does not set this during its adjustment of file_size.
 	 */
-	if (!alignment)
-		alignment = 1;
+	params->orig_file_size = tparams->header_size +
+		spl_params.init_size + spl_params.boot_size;
 
-	unpadded_size = tparams->header_size + params->file_size;
-	padded_size = ROUND(unpadded_size, alignment);
+	params->file_size = ROUND(params->orig_file_size, RK_SIZE_ALIGN);
+
+	/* Ignoring pad len, since we are using our own copy_image() */
+	return 0;
+}
+
+static int pad_file(struct image_tool_params *params, int ifd, int pad)
+{
+	uint8_t zeros[4096];
+
+	memset(zeros, 0, sizeof(zeros));
+
+	while (pad > 0) {
+		int todo = sizeof(zeros);
+
+		if (todo > pad)
+			todo = pad;
+		if (write(ifd, (char *)&zeros, todo) != todo) {
+			fprintf(stderr, "%s: Write error on %s: %s\n",
+				params->cmdname, params->imagefile,
+				strerror(errno));
+			return -1;
+		}
+		pad -= todo;
+	}
+
+	return 0;
+}
+
+static int copy_file(struct image_tool_params *params, int ifd,
+		     const char *file, int padded_size)
+{
+	int dfd;
+	struct stat sbuf;
+	unsigned char *ptr;
+	int size;
+
+	if (params->vflag)
+		fprintf(stderr, "Adding Image %s\n", file);
+
+	dfd = open(file, O_RDONLY | O_BINARY);
+	if (dfd < 0) {
+		fprintf(stderr, "%s: Can't open %s: %s\n",
+			params->cmdname, file, strerror(errno));
+		return -1;
+	}
+
+	if (fstat(dfd, &sbuf) < 0) {
+		fprintf(stderr, "%s: Can't stat %s: %s\n",
+			params->cmdname, file, strerror(errno));
+		goto err_close;
+	}
+
+	if (params->vflag)
+		fprintf(stderr, "Size %u(pad to %u)\n",
+			(int)sbuf.st_size, padded_size);
+
+	ptr = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, dfd, 0);
+	if (ptr == MAP_FAILED) {
+		fprintf(stderr, "%s: Can't read %s: %s\n",
+			params->cmdname, file, strerror(errno));
+		goto err_munmap;
+	}
+
+	size = sbuf.st_size;
+	if (write(ifd, ptr, size) != size) {
+		fprintf(stderr, "%s: Write error on %s: %s\n",
+			params->cmdname, params->imagefile, strerror(errno));
+		goto err_munmap;
+	}
+
+	munmap((void *)ptr, sbuf.st_size);
+	close(dfd);
+	return pad_file(params, ifd, padded_size - size);
+
+err_munmap:
+	munmap((void *)ptr, sbuf.st_size);
+err_close:
+	close(dfd);
+	return -1;
+}
+
+int rockchip_copy_image(int ifd, struct image_tool_params *params)
+{
+	int ret;
+
+	ret = copy_file(params, ifd, spl_params.init_file,
+			spl_params.init_size);
+	if (ret)
+		return ret;
+
+	if (spl_params.boot_file) {
+		ret = copy_file(params, ifd, spl_params.boot_file,
+				spl_params.boot_size);
+		if (ret)
+			return ret;
+	}
 
-	return padded_size - unpadded_size;
+	return pad_file(params, ifd,
+			params->file_size - params->orig_file_size);
 }
diff --git a/tools/rkcommon.h b/tools/rkcommon.h
index 47f47a5..9351882 100644
--- a/tools/rkcommon.h
+++ b/tools/rkcommon.h
@@ -9,13 +9,11 @@
 
 enum {
 	RK_BLK_SIZE		= 512,
-	RK_INIT_SIZE_ALIGN      = 2048,
+	RK_SIZE_ALIGN		= 2048,
 	RK_INIT_OFFSET		= 4,
 	RK_MAX_BOOT_SIZE	= 512 << 10,
 	RK_SPL_HDR_START	= RK_INIT_OFFSET * RK_BLK_SIZE,
 	RK_SPL_HDR_SIZE		= 4,
-	RK_SPL_START		= RK_SPL_HDR_START + RK_SPL_HDR_SIZE,
-	RK_IMAGE_HEADER_LEN	= RK_SPL_START,
 };
 
 /**
@@ -49,11 +47,9 @@
  * This sets up a 2KB header which can be interpreted by the Rockchip boot ROM.
  *
  * @buf:	Pointer to header place (must be at least 2KB in size)
- * @file_size:	Size of the file we want the boot ROM to load, in bytes
- * @return 0 if OK, -ENOSPC if too large
  */
-int rkcommon_set_header(void *buf, uint file_size,
-			struct image_tool_params *params);
+void rkcommon_set_header(void *buf,  struct stat *sbuf,  int ifd,
+			 struct image_tool_params *params);
 
 /**
  * rkcommon_verify_header() - verify the header for a Rockchip boot image
@@ -102,14 +98,10 @@
  * @params:     Pointer to the tool params structure
  * @tparams:    Pointer tot the image type structure (for setting
  *              the header and header_size)
- * @alignment:  Alignment (a power of two) that the image should be
- *              padded to (e.g. 512 if we want to align with SD/MMC
- *              blocksizes or 2048 for the SPI format)
  *
- * @return bytes of padding required/added (does not include the header_size)
+ * @return 0 (always)
  */
 int rkcommon_vrec_header(struct image_tool_params *params,
-			 struct image_type_params *tparams,
-			 unsigned int alignment);
+			 struct image_type_params *tparams);
 
 #endif
diff --git a/tools/rkimage.c b/tools/rkimage.c
index ae50de5..1c5540b 100644
--- a/tools/rkimage.c
+++ b/tools/rkimage.c
@@ -18,7 +18,7 @@
 	memcpy(buf, rkcommon_get_spl_hdr(params), RK_SPL_HDR_SIZE);
 
 	if (rkcommon_need_rc4_spl(params))
-		rkcommon_rc4_encode_spl(buf, 4, params->file_size);
+		rkcommon_rc4_encode_spl(buf, 0, params->file_size);
 }
 
 static int rkimage_check_image_type(uint8_t type)
diff --git a/tools/rksd.c b/tools/rksd.c
index 24411d8..7d46a1b 100644
--- a/tools/rksd.c
+++ b/tools/rksd.c
@@ -12,27 +12,6 @@
 #include "mkimage.h"
 #include "rkcommon.h"
 
-static void rksd_set_header(void *buf,  struct stat *sbuf,  int ifd,
-			    struct image_tool_params *params)
-{
-	unsigned int size;
-	int ret;
-
-	/*
-	 * We need to calculate this using 'RK_SPL_HDR_START' and not using
-	 * 'tparams->header_size', as the additional byte inserted when
-	 * 'is_boot0' is true counts towards the payload (and not towards the
-	 * header).
-	 */
-	size = params->file_size - RK_SPL_HDR_START;
-	ret = rkcommon_set_header(buf, size, params);
-	if (ret) {
-		/* TODO(sjg@chromium.org): This method should return an error */
-		printf("Warning: SPL image is too large (size %#x) and will "
-		       "not boot\n", size);
-	}
-}
-
 static int rksd_check_image_type(uint8_t type)
 {
 	if (type == IH_TYPE_RKSD)
@@ -41,16 +20,6 @@
 		return EXIT_FAILURE;
 }
 
-static int rksd_vrec_header(struct image_tool_params *params,
-			    struct image_type_params *tparams)
-{
-	/*
-	 * Pad to a 2KB alignment, as required for init_size by the ROM
-	 * (see https://lists.denx.de/pipermail/u-boot/2017-May/293268.html)
-	 */
-	return rkcommon_vrec_header(params, tparams, RK_INIT_SIZE_ALIGN);
-}
-
 /*
  * rk_sd parameters
  */
@@ -62,9 +31,9 @@
 	rkcommon_check_params,
 	rkcommon_verify_header,
 	rkcommon_print_header,
-	rksd_set_header,
+	rkcommon_set_header,
 	NULL,
 	rksd_check_image_type,
 	NULL,
-	rksd_vrec_header
+	rkcommon_vrec_header
 );
diff --git a/tools/rkspi.c b/tools/rkspi.c
index faa18fc..f2530f7 100644
--- a/tools/rkspi.c
+++ b/tools/rkspi.c
@@ -21,22 +21,20 @@
 {
 	int sector;
 	unsigned int size;
-	int ret;
 
 	size = params->orig_file_size;
-	ret = rkcommon_set_header(buf, size, params);
-	debug("size %x\n", size);
-	if (ret) {
-		/* TODO(sjg@chromium.org): This method should return an error */
-		printf("Warning: SPL image is too large (size %#x) and will "
-		       "not boot\n", size);
-	}
+
+	rkcommon_set_header(buf, sbuf, ifd, params);
 
 	/*
 	 * Spread the image out so we only use the first 2KB of each 4KB
 	 * region. This is a feature of the SPI format required by the Rockchip
 	 * boot ROM. Its rationale is unknown.
 	 */
+	if (params->vflag)
+		fprintf(stderr, "Spreading spi image from %u to %u\n",
+			size, params->file_size);
+
 	for (sector = size / RKSPI_SECT_LEN - 1; sector >= 0; sector--) {
 		debug("sector %u\n", sector);
 		memmove(buf + sector * RKSPI_SECT_LEN * 2,
@@ -56,35 +54,23 @@
 }
 
 /*
- * The SPI payload needs to be padded out to make space for odd half-sector
- * layout used in flash (i.e. only the first 2K of each 4K sector is used).
+ * The SPI payload needs to make space for odd half-sector layout used in flash
+ * (i.e. only the first 2K of each 4K sector is used).
  */
 static int rkspi_vrec_header(struct image_tool_params *params,
 			     struct image_type_params *tparams)
 {
-	int padding = rkcommon_vrec_header(params, tparams, RK_INIT_SIZE_ALIGN);
-	/*
-	 * The file size has not been adjusted at this point (our caller will
-	 * eventually add the header/padding to the file_size), so we need to
-	 * add up the header_size, file_size and padding ourselves.
-	 */
-	int padded_size = tparams->header_size + params->file_size + padding;
+	rkcommon_vrec_header(params, tparams);
 
 	/*
-	 * We need to store the original file-size (i.e. before padding), as
-	 * imagetool does not set this during its adjustment of file_size.
-	 */
-	params->orig_file_size = padded_size;
-
-	/*
 	 * Converting to the SPI format (i.e. splitting each 4K page into two
 	 * 2K subpages and then padding these 2K pages up to take a complete
-	 * 4K sector again) will will double the image size.
-	 *
-	 * Thus we return the padded_size as an additional padding requirement
-	 * (be sure to add this to the padding returned from the common code).
+	 * 4K sector again) which will double the image size.
 	 */
-	return padded_size + padding;
+	params->file_size = ROUND(params->file_size, RKSPI_SECT_LEN) << 1;
+
+	/* Ignoring pad len, since we are using our own copy_image() */
+	return 0;
 }
 
 /*