Merge branch '2019-07-29-master-imports'

- Assorted bug fixes
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 95fc689..f59dc40 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -2,12 +2,12 @@
 
 # Grab our configured image.  The source for this is found at:
 # https://gitlab.denx.de/u-boot/gitlab-ci-runner
-image: trini/u-boot-gitlab-ci-runner:xenial-20190720-24Jul2019
+image: trini/u-boot-gitlab-ci-runner:xenial-20190720-29Jul2019
 
 # We run some tests in different order, to catch some failures quicker.
 stages:
-  - test.py
   - testsuites
+  - test.py
   - world build
 
 .buildman_and_testpy_template: &buildman_and_testpy_dfn
@@ -28,17 +28,9 @@
     - ( cd ~/grub2-arm; wget -O - http://download.opensuse.org/ports/armv7hl/distribution/leap/42.2/repo/oss/suse/armv7hl/grub2-arm-efi-2.02~beta2-87.1.armv7hl.rpm | rpm2cpio | cpio -di )
     - mkdir ~/grub2-arm64
     - ( cd ~/grub2-arm64; wget -O - http://download.opensuse.org/ports/aarch64/distribution/leap/42.2/repo/oss/suse/aarch64/grub2-arm64-efi-2.02~beta2-87.1.aarch64.rpm | rpm2cpio | cpio -di )
-    - if [[ "${QEMU_TARGET}" != "" ]]; then
-        git clone git://git.qemu.org/qemu.git /tmp/qemu;
-        pushd /tmp/qemu;
-        git submodule update --init dtc &&
-        git checkout ${QEMU_VERSION} &&
-        ./configure --prefix=/tmp/qemu-install --target-list=${QEMU_TARGET} &&
-        make -j$(nproc) all install;
-        popd;
-      fi
+
   after_script:
-    - rm -rf ~/grub2* /tmp/uboot-test-hooks /tmp/qemu /tmp/venv
+    - rm -rf ~/grub2* /tmp/uboot-test-hooks /tmp/venv
   script:
     # From buildman, exit code 129 means warnings only.  If we've been asked to
     # use clang only do one configuration.
@@ -55,7 +47,7 @@
     # "-k something" even when $TEST_PY_TEST_SPEC doesnt need a custom
     # value.
     - export UBOOT_TRAVIS_BUILD_DIR=`cd .. && pwd`/.bm-work/${TEST_PY_BD};
-      export PATH=/tmp/qemu-install/bin:/tmp/uboot-test-hooks/bin:/usr/bin:/bin;
+      export PATH=/opt/qemu/bin:/tmp/uboot-test-hooks/bin:/usr/bin:/bin;
       export PYTHONPATH=/tmp/uboot-test-hooks/py/travis-ci;
       if [[ "${TEST_PY_BD}" != "" ]]; then
         ./test/py/test.py --bd ${TEST_PY_BD} ${TEST_PY_ID}
@@ -203,8 +195,6 @@
   variables:
     TEST_PY_BD: "evb-ast2500"
     TEST_PY_ID: "--id qemu"
-    QEMU_TARGET: "arm-softmmu"
-    QEMU_VERSION: "506179e42112be77bfd071f050b15762d3b2cd43"
     BUILDMAN: "^evb-ast2500$"
   <<: *buildman_and_testpy_dfn
 
@@ -220,8 +210,6 @@
   variables:
     TEST_PY_BD: "vexpress_ca15_tc2"
     TEST_PY_ID: "--id qemu"
-    QEMU_TARGET: "arm-softmmu"
-    QEMU_VERSION: "v3.0.0"
     BUILDMAN: "^vexpress_ca15_tc2$"
   <<: *buildman_and_testpy_dfn
 
@@ -230,7 +218,6 @@
   variables:
     TEST_PY_BD: "vexpress_ca9x4"
     TEST_PY_ID: "--id qemu"
-    QEMU_TARGET: "arm-softmmu"
     BUILDMAN: "^vexpress_ca9x4$"
   <<: *buildman_and_testpy_dfn
 
@@ -240,7 +227,6 @@
     TEST_PY_BD: "integratorcp_cm926ejs"
     TEST_PY_TEST_SPEC: "not sleep"
     TEST_PY_ID: "--id qemu"
-    QEMU_TARGET: "arm-softmmu"
     BUILDMAN: "^integratorcp_cm926ejs$"
   <<: *buildman_and_testpy_dfn
 
@@ -249,7 +235,6 @@
   variables:
     TEST_PY_BD: "qemu_arm"
     TEST_PY_TEST_SPEC: "not sleep"
-    QEMU_TARGET: "arm-softmmu"
     BUILDMAN: "^qemu_arm$"
   <<: *buildman_and_testpy_dfn
 
@@ -258,7 +243,6 @@
   variables:
     TEST_PY_BD: "qemu_arm64"
     TEST_PY_TEST_SPEC: "not sleep"
-    QEMU_TARGET: "aarch64-softmmu"
     BUILDMAN: "^qemu_arm64$"
   <<: *buildman_and_testpy_dfn
 
@@ -267,7 +251,6 @@
   variables:
     TEST_PY_BD: "qemu_mips"
     TEST_PY_TEST_SPEC: "not sleep"
-    QEMU_TARGET: "mips-softmmu"
     BUILDMAN: "^qemu_mips$"
     TOOLCHAIN: "mips"
   <<: *buildman_and_testpy_dfn
@@ -277,7 +260,6 @@
   variables:
     TEST_PY_BD: "qemu_mipsel"
     TEST_PY_TEST_SPEC: "not sleep"
-    QEMU_TARGET: "mipsel-softmmu"
     BUILDMAN: "^qemu_mipsel$"
     TOOLCHAIN: "mips"
   <<: *buildman_and_testpy_dfn
@@ -287,7 +269,6 @@
   variables:
     TEST_PY_BD: "qemu_mips64"
     TEST_PY_TEST_SPEC: "not sleep"
-    QEMU_TARGET: "mips64-softmmu"
     BUILDMAN: "^qemu_mips64$"
     TOOLCHAIN: "mips"
   <<: *buildman_and_testpy_dfn
@@ -297,7 +278,6 @@
   variables:
     TEST_PY_BD: "qemu_mips64el"
     TEST_PY_TEST_SPEC: "not sleep"
-    QEMU_TARGET: "mips64el-softmmu"
     BUILDMAN: "^qemu_mips64el$"
     TOOLCHAIN: "mips"
   <<: *buildman_and_testpy_dfn
@@ -307,7 +287,6 @@
   variables:
     TEST_PY_BD: "qemu-ppce500"
     TEST_PY_TEST_SPEC: "not sleep"
-    QEMU_TARGET: "ppc-softmmu"
     BUILDMAN: "^qemu-ppce500$"
     TOOLCHAIN: "powerpc"
   <<: *buildman_and_testpy_dfn
@@ -317,7 +296,6 @@
   variables:
     TEST_PY_BD: "qemu-x86"
     TEST_PY_TEST_SPEC: "not sleep"
-    QEMU_TARGET: "i386-softmmu"
     BUILDMAN: "^qemu-x86$"
     TOOLCHAIN: "i386"
   <<: *buildman_and_testpy_dfn
@@ -327,7 +305,6 @@
   variables:
     TEST_PY_BD: "qemu-x86_64"
     TEST_PY_TEST_SPEC: "not sleep"
-    QEMU_TARGET: "x86_64-softmmu"
     BUILDMAN: "^qemu-x86_64$"
     TOOLCHAIN: "i386"
   <<: *buildman_and_testpy_dfn
@@ -337,7 +314,6 @@
   variables:
     TEST_PY_BD: "zynq_zc702"
     TEST_PY_TEST_SPEC: "not sleep"
-    QEMU_TARGET: "arm-softmmu"
     TEST_PY_ID: "--id qemu"
     BUILDMAN: "^zynq_zc702$"
   <<: *buildman_and_testpy_dfn
@@ -347,7 +323,6 @@
   variables:
     TEST_PY_BD: "xilinx_versal_virt"
     TEST_PY_TEST_SPEC: "not sleep"
-    QEMU_TARGET: "aarch64-softmmu"
     TEST_PY_ID: "--id qemu"
     BUILDMAN: "^xilinx_versal_virt$"
   <<: *buildman_and_testpy_dfn
@@ -357,7 +332,6 @@
   variables:
     TEST_PY_BD: "xtfpga"
     TEST_PY_TEST_SPEC: "not sleep"
-    QEMU_TARGET: "xtensa-softmmu"
     TEST_PY_ID: "--id qemu"
     BUILDMAN: "^xtfpga$"
     TOOLCHAIN: "xtensa-dc233c-elf"
diff --git a/MAINTAINERS b/MAINTAINERS
index 4285d56..c28251e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -94,6 +94,7 @@
 S:	Maintainted
 T:	git https://gitlab.denx.de/u-boot/custodians/u-boot-socfpga.git
 F:	arch/arm/mach-socfpga/
+F:	drivers/sysreset/sysreset_socfpga*
 
 ARM AMLOGIC SOC SUPPORT
 M:	Neil Armstrong <narmstrong@baylibre.com>
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 1cd7aeb..3f0e301 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -895,10 +895,14 @@
 	select SPL_OF_CONTROL
 	select SPL_SEPARATE_BSS if TARGET_SOCFPGA_STRATIX10
 	select SPL_SERIAL_SUPPORT
+	select SPL_SYSRESET
 	select SPL_WATCHDOG_SUPPORT
 	select SUPPORT_SPL
 	select SYS_NS16550
 	select SYS_THUMB_BUILD if TARGET_SOCFPGA_GEN5 || TARGET_SOCFPGA_ARRIA10
+	select SYSRESET
+	select SYSRESET_SOCFPGA if TARGET_SOCFPGA_GEN5 || TARGET_SOCFPGA_ARRIA10
+	select SYSRESET_SOCFPGA_STRATIX10 if TARGET_SOCFPGA_STRATIX10
 	imply CMD_DM
 	imply CMD_MTDPARTS
 	imply CRC32_VERIFY
diff --git a/arch/arm/dts/imx6ull-colibri.dts b/arch/arm/dts/imx6ull-colibri.dts
index 6c847ab..262205a 100644
--- a/arch/arm/dts/imx6ull-colibri.dts
+++ b/arch/arm/dts/imx6ull-colibri.dts
@@ -12,8 +12,10 @@
 	compatible = "toradex,colibri-imx6ull", "fsl,imx6ull";
 
 	aliases {
+		u-boot,dm-pre-reloc;
 		mmc0 = &usdhc1;
 		usb0 = &usbotg1; /* required for ums */
+		display0 = &lcdif;
 	};
 
 	chosen {
@@ -156,6 +158,36 @@
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_lcdif_dat
 		     &pinctrl_lcdif_ctrl>;
+	status = "okay";
+	display = <&display0>;
+	u-boot,dm-pre-reloc;
+
+	display0: display0 {
+		bits-per-pixel = <18>;
+		bus-width = <24>;
+		status = "okay";
+
+		display-timings {
+			native-mode = <&timing_vga>;
+			timing_vga: 640x480 {
+				u-boot,dm-pre-reloc;
+				clock-frequency = <25175000>;
+				hactive = <640>;
+				vactive = <480>;
+				hback-porch = <48>;
+				hfront-porch = <16>;
+				vback-porch = <33>;
+				vfront-porch = <10>;
+				hsync-len = <96>;
+				vsync-len = <2>;
+
+				de-active = <1>;
+				hsync-active = <0>;
+				vsync-active = <0>;
+				pixelclk-active = <0>;
+			};
+		};
+	};
 };
 
 /* PWM <A> */
diff --git a/arch/arm/dts/imx7-colibri.dtsi b/arch/arm/dts/imx7-colibri.dtsi
index 81717c2..308e0b2 100644
--- a/arch/arm/dts/imx7-colibri.dtsi
+++ b/arch/arm/dts/imx7-colibri.dtsi
@@ -113,29 +113,34 @@
 };
 
 &lcdif {
-	u-boot,dm-pre-reloc;
 	status = "okay";
+	display = <&display0>;
+	u-boot,dm-pre-reloc;
 
-	display-timings {
-		native-mode = <&timing_vga>;
+	display0: display0 {
+		bits-per-pixel = <18>;
+		bus-width = <24>;
+		status = "okay";
 
-		/* Standard VGA timing */
-		timing_vga: 640x480 {
-			u-boot,dm-pre-reloc;
-			clock-frequency = <25175000>;
-			hactive = <640>;
-			vactive = <480>;
-			hback-porch = <48>;
-			hfront-porch = <16>;
-			vback-porch = <33>;
-			vfront-porch = <10>;
-			hsync-len = <96>;
-			vsync-len = <2>;
+		display-timings {
+			native-mode = <&timing_vga>;
+			timing_vga: 640x480 {
+				u-boot,dm-pre-reloc;
+				clock-frequency = <25175000>;
+				hactive = <640>;
+				vactive = <480>;
+				hback-porch = <48>;
+				hfront-porch = <16>;
+				vback-porch = <33>;
+				vfront-porch = <10>;
+				hsync-len = <96>;
+				vsync-len = <2>;
 
-			de-active = <1>;
-			hsync-active = <0>;
-			vsync-active = <0>;
-			pixelclk-active = <0>;
+				de-active = <1>;
+				hsync-active = <0>;
+				vsync-active = <0>;
+				pixelclk-active = <0>;
+			};
 		};
 	};
 };
diff --git a/arch/arm/dts/rk3288-phycore-rdk.dts b/arch/arm/dts/rk3288-phycore-rdk.dts
index f2bb7b5..cc39210 100644
--- a/arch/arm/dts/rk3288-phycore-rdk.dts
+++ b/arch/arm/dts/rk3288-phycore-rdk.dts
@@ -55,11 +55,6 @@
 		stdout-path = &uart2;
 	};
 
-	config {
-		u-boot,dm-pre-reloc;
-		u-boot,boot0 = &emmc;
-	};
-
 	user_buttons: user-buttons {
 		compatible = "gpio-keys";
 		pinctrl-names = "default";
diff --git a/arch/arm/dts/rk3288-veyron.dtsi b/arch/arm/dts/rk3288-veyron.dtsi
index 916dd48..8754043 100644
--- a/arch/arm/dts/rk3288-veyron.dtsi
+++ b/arch/arm/dts/rk3288-veyron.dtsi
@@ -16,11 +16,7 @@
 
 	chosen {
 		stdout-path = &uart2;
-	};
-
-	config {
-		u-boot,dm-pre-reloc;
-		u-boot,boot0 = &spi_flash;
+		u-boot,spl-boot-order = &spi_flash;
 	};
 
 	firmware {
diff --git a/arch/arm/dts/vf-colibri-u-boot.dtsi b/arch/arm/dts/vf-colibri-u-boot.dtsi
index db86739..2294ee9 100644
--- a/arch/arm/dts/vf-colibri-u-boot.dtsi
+++ b/arch/arm/dts/vf-colibri-u-boot.dtsi
@@ -21,3 +21,7 @@
 &uart0 {
 	u-boot,dm-pre-reloc;
 };
+
+&dcu0 {
+	u-boot,dm-pre-reloc;
+};
diff --git a/arch/arm/dts/vf-colibri.dtsi b/arch/arm/dts/vf-colibri.dtsi
index 91ca4e4..9de4b28 100644
--- a/arch/arm/dts/vf-colibri.dtsi
+++ b/arch/arm/dts/vf-colibri.dtsi
@@ -14,6 +14,7 @@
 
 	aliases {
 		usb0 = &ehci0; /* required for ums */
+		display1 = &dcu0;
 	};
 
 	reg_usbh_vbus: regulator-usbh-vbus {
@@ -241,3 +242,7 @@
 	pinctrl-0 = <&pinctrl_uart0>;
 	status = "okay";
 };
+
+&dcu0 {
+	status = "okay";
+};
diff --git a/arch/arm/dts/vf.dtsi b/arch/arm/dts/vf.dtsi
index 5e3b2c5..5f69d0f 100644
--- a/arch/arm/dts/vf.dtsi
+++ b/arch/arm/dts/vf.dtsi
@@ -145,6 +145,12 @@
 				#gpio-cells = <2>;
 			};
 
+			dcu0: dcu@40058000 {
+				compatible = "fsl,vf610-dcu";
+				reg = <0x40058000 0x1200>;
+				status = "disabled";
+			};
+
 			ehci0: ehci@40034000 {
 				compatible = "fsl,vf610-usb";
 				reg = <0x40034000 0x800>;
diff --git a/arch/arm/include/asm/arch-rockchip/bootrom.h b/arch/arm/include/asm/arch-rockchip/bootrom.h
index d67f43f..0da78f3 100644
--- a/arch/arm/include/asm/arch-rockchip/bootrom.h
+++ b/arch/arm/include/asm/arch-rockchip/bootrom.h
@@ -52,9 +52,11 @@
 	BROM_LAST_BOOTSOURCE = BROM_BOOTSOURCE_USB
 };
 
+extern const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1];
+
 /**
  * Locations of the boot-device identifier in SRAM
  */
-#define RK3399_BROM_BOOTSOURCE_ID_ADDR   0xff8c0010
+#define BROM_BOOTSOURCE_ID_ADDR   (CONFIG_IRAM_BASE + 0x10)
 
 #endif
diff --git a/arch/arm/include/asm/arch-rockchip/sys_proto.h b/arch/arm/include/asm/arch-rockchip/sys_proto.h
index 905c774..de5a8f1 100644
--- a/arch/arm/include/asm/arch-rockchip/sys_proto.h
+++ b/arch/arm/include/asm/arch-rockchip/sys_proto.h
@@ -6,8 +6,4 @@
 #ifndef _ASM_ARCH_SYS_PROTO_H
 #define _ASM_ARCH_SYS_PROTO_H
 
-
-/* provided to defeat compiler optimisation in board_init_f() */
-void gru_dummy_function(int i);
-
 #endif /* _ASM_ARCH_SYS_PROTO_H */
diff --git a/arch/arm/mach-imx/mx6/soc.c b/arch/arm/mach-imx/mx6/soc.c
index 4084ab7..075d246 100644
--- a/arch/arm/mach-imx/mx6/soc.c
+++ b/arch/arm/mach-imx/mx6/soc.c
@@ -554,7 +554,7 @@
 void reset_misc(void)
 {
 #ifndef CONFIG_SPL_BUILD
-#ifdef CONFIG_VIDEO_MXS
+#if defined(CONFIG_VIDEO_MXS) && !defined(CONFIG_DM_VIDEO)
 	lcdif_power_down();
 #endif
 #endif
diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig
index 17f31e8..e337d06 100644
--- a/arch/arm/mach-rockchip/Kconfig
+++ b/arch/arm/mach-rockchip/Kconfig
@@ -7,6 +7,7 @@
 	select SPL
 	imply USB_FUNCTION_ROCKUSB
 	imply CMD_ROCKUSB
+	imply ROCKCHIP_COMMON_BOARD
 	help
 	  The Rockchip RK3036 is a ARM-based SoC with a dual-core Cortex-A7
 	  including NEON and GPU, Mali-400 graphics, several DDR3 options
@@ -16,6 +17,7 @@
 config ROCKCHIP_RK3128
 	bool "Support Rockchip RK3128"
 	select CPU_V7A
+	imply ROCKCHIP_COMMON_BOARD
 	help
 	  The Rockchip RK3128 is a ARM-based SoC with a quad-core Cortex-A7
 	  including NEON and GPU, Mali-400 graphics, several DDR3 options
@@ -34,8 +36,10 @@
 	select SPL_RAM
 	select SPL_DRIVERS_MISC_SUPPORT
 	select SPL_ROCKCHIP_EARLYRETURN_TO_BROM
+	select SPL_ROCKCHIP_BACK_TO_BROM
 	select BOARD_LATE_INIT
-	select ROCKCHIP_BROM_HELPER
+	imply ROCKCHIP_COMMON_BOARD
+	imply SPL_ROCKCHIP_COMMON_BOARD
 	help
 	  The Rockchip RK3188 is a ARM-based SoC with a quad-core Cortex-A9
 	  including NEON and GPU, 512KB L2 cache, Mali-400 graphics, two
@@ -57,11 +61,11 @@
 	select TPL_NEEDS_SEPARATE_TEXT_BASE if SPL
 	select TPL_NEEDS_SEPARATE_STACK if TPL
 	select SPL_DRIVERS_MISC_SUPPORT
+	imply ROCKCHIP_COMMON_BOARD
 	imply SPL_SERIAL_SUPPORT
+	imply SPL_ROCKCHIP_COMMON_BOARD
 	imply TPL_SERIAL_SUPPORT
-	imply TPL_BOOTROM_SUPPORT
 	imply TPL_ROCKCHIP_COMMON_BOARD
-	select ROCKCHIP_BROM_HELPER
 	select TPL_LIBCOMMON_SUPPORT
 	select TPL_LIBGENERIC_SUPPORT
 	help
@@ -73,11 +77,11 @@
 config ROCKCHIP_RK3288
 	bool "Support Rockchip RK3288"
 	select CPU_V7A
-	select SPL_BOARD_INIT if SPL
 	select SUPPORT_SPL
 	select SPL
 	select SUPPORT_TPL
-	imply TPL_BOOTROM_SUPPORT
+	imply ROCKCHIP_COMMON_BOARD
+	imply SPL_ROCKCHIP_COMMON_BOARD
 	imply TPL_CLK
 	imply TPL_DM
 	imply TPL_DRIVERS_MISC_SUPPORT
@@ -106,6 +110,8 @@
 	select ARM64
 	select SUPPORT_SPL
 	select SPL
+	imply ROCKCHIP_COMMON_BOARD
+	imply SPL_ROCKCHIP_COMMON_BOARD
 	imply SPL_SERIAL_SUPPORT
 	imply SPL_SEPARATE_BSS
 	select ENABLE_ARM_SOC_BOOT0_HOOK
@@ -125,6 +131,8 @@
 	select SUPPORT_TPL
 	select TPL_NEEDS_SEPARATE_TEXT_BASE if SPL
 	select TPL_NEEDS_SEPARATE_STACK if TPL
+	imply ROCKCHIP_COMMON_BOARD
+	imply SPL_ROCKCHIP_COMMON_BOARD
 	imply SPL_SEPARATE_BSS
 	imply SPL_SERIAL_SUPPORT
 	imply TPL_SERIAL_SUPPORT
@@ -169,12 +177,12 @@
 	select DM_PMIC
 	select DM_REGULATOR_FIXED
 	select BOARD_LATE_INIT
-	select ROCKCHIP_BROM_HELPER
+	imply ROCKCHIP_COMMON_BOARD
+	imply SPL_ROCKCHIP_COMMON_BOARD
 	imply TPL_SERIAL_SUPPORT
 	imply TPL_LIBCOMMON_SUPPORT
 	imply TPL_LIBGENERIC_SUPPORT
 	imply TPL_SYS_MALLOC_SIMPLE
-	imply TPL_BOOTROM_SUPPORT
 	imply TPL_DRIVERS_MISC_SUPPORT
 	imply TPL_OF_CONTROL
 	imply TPL_DM
@@ -195,6 +203,7 @@
 config ROCKCHIP_RV1108
 	bool "Support Rockchip RV1108"
 	select CPU_V7A
+	imply ROCKCHIP_COMMON_BOARD
 	help
 	  The Rockchip RV1108 is a ARM-based SoC with a single-core Cortex-A7
 	  and a DSP.
@@ -211,6 +220,7 @@
 	bool "SPL returns to bootrom"
 	default y if ROCKCHIP_RK3036
 	select ROCKCHIP_BROM_HELPER
+	select SPL_BOOTROM_SUPPORT
 	depends on SPL
 	help
 	  Rockchip SoCs have ability to load SPL & U-Boot binary. If enabled,
@@ -221,12 +231,28 @@
 	bool "TPL returns to bootrom"
 	default y
 	select ROCKCHIP_BROM_HELPER
+	select TPL_BOOTROM_SUPPORT
 	depends on TPL
 	help
 	  Rockchip SoCs have ability to load SPL & U-Boot binary. If enabled,
           SPL will return to the boot rom, which will then load the U-Boot
           binary to keep going on.
 
+config ROCKCHIP_COMMON_BOARD
+	bool "Rockchip common board file"
+	help
+	  Rockchip SoCs have similar boot process, Common board file is mainly
+	  in charge of common process of board_init() and board_late_init() for
+	  U-Boot proper.
+
+config SPL_ROCKCHIP_COMMON_BOARD
+	bool "Rockchip SPL common board file"
+	depends on SPL
+	help
+	  Rockchip SoCs have similar boot process, SPL is mainly in charge of
+	  load and boot Trust ATF/U-Boot firmware, and DRAM init if there is
+	  no TPL for the board.
+
 config TPL_ROCKCHIP_COMMON_BOARD
 	bool ""
 	depends on TPL
diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile
index a12b8d4..aed379a 100644
--- a/arch/arm/mach-rockchip/Makefile
+++ b/arch/arm/mach-rockchip/Makefile
@@ -7,16 +7,11 @@
 # inaccessible/protected memory (and the bootrom-helper assumes that
 # the stack-pointer is valid before switching to the U-Boot stack).
 obj-spl-$(CONFIG_ROCKCHIP_BROM_HELPER) += bootrom.o
+obj-spl-$(CONFIG_SPL_ROCKCHIP_COMMON_BOARD) += spl.o spl-boot-order.o
 obj-tpl-$(CONFIG_ROCKCHIP_BROM_HELPER) += bootrom.o
 obj-tpl-$(CONFIG_TPL_ROCKCHIP_COMMON_BOARD) += tpl.o
 
 obj-spl-$(CONFIG_ROCKCHIP_RK3036) += rk3036-board-spl.o
-obj-spl-$(CONFIG_ROCKCHIP_RK3188) += rk3188-board-spl.o
-obj-spl-$(CONFIG_ROCKCHIP_RK322X) += rk322x-board-spl.o spl-boot-order.o
-obj-spl-$(CONFIG_ROCKCHIP_RK3288) += rk3288-board-spl.o spl-boot-order.o
-obj-spl-$(CONFIG_ROCKCHIP_RK3328) += rk3328-board-spl.o
-obj-spl-$(CONFIG_ROCKCHIP_RK3368) += rk3368-board-spl.o spl-boot-order.o
-obj-spl-$(CONFIG_ROCKCHIP_RK3399) += rk3399-board-spl.o spl-boot-order.o
 
 ifeq ($(CONFIG_SPL_BUILD)$(CONFIG_TPL_BUILD),)
 
@@ -25,14 +20,7 @@
 # we can have the preprocessor correctly recognise both 0x0 and 0
 # meaning "turn it off".
 obj-y += boot_mode.o
-
-obj-$(CONFIG_ROCKCHIP_RK3188) += rk3188-board.o
-obj-$(CONFIG_ROCKCHIP_RK3128) += rk3128-board.o
-obj-$(CONFIG_ROCKCHIP_RK322X) += rk322x-board.o
-obj-$(CONFIG_ROCKCHIP_RK3288) += rk3288-board.o
-obj-$(CONFIG_ROCKCHIP_RK3036) += rk3036-board.o
-obj-$(CONFIG_ROCKCHIP_RK3399) += rk3399-board.o
-obj-$(CONFIG_ROCKCHIP_RV1108) += rv1108-board.o
+obj-$(CONFIG_ROCKCHIP_COMMON_BOARD) += board.o
 endif
 
 obj-$(CONFIG_$(SPL_TPL_)RAM) += sdram_common.o
diff --git a/arch/arm/mach-rockchip/rk3036-board.c b/arch/arm/mach-rockchip/board.c
similarity index 61%
rename from arch/arm/mach-rockchip/rk3036-board.c
rename to arch/arm/mach-rockchip/board.c
index c594c4d..b2a88e7 100644
--- a/arch/arm/mach-rockchip/rk3036-board.c
+++ b/arch/arm/mach-rockchip/board.c
@@ -1,19 +1,17 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- * (C) Copyright 2015 Rockchip Electronics Co., Ltd
+ * (C) Copyright 2019 Rockchip Electronics Co., Ltd.
  */
-
 #include <common.h>
 #include <clk.h>
 #include <dm.h>
 #include <ram.h>
-#include <asm/gpio.h>
+#include <syscon.h>
 #include <asm/io.h>
+#include <asm/arch-rockchip/boot_mode.h>
 #include <asm/arch-rockchip/clock.h>
 #include <asm/arch-rockchip/periph.h>
-#include <asm/arch-rockchip/grf_rk3036.h>
-#include <asm/arch-rockchip/boot_mode.h>
-#include <asm/arch-rockchip/sdram_rk3036.h>
+#include <power/regulator.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -31,23 +29,18 @@
 
 int board_init(void)
 {
-	return 0;
-}
+	int ret;
 
-#if !CONFIG_IS_ENABLED(RAM)
-/*
- * When CONFIG_RAM is enabled, the dram_init() function is implemented
- * in sdram_common.c.
- */
-int dram_init(void)
-{
-	gd->ram_size = sdram_size();
-
-	return 0;
-}
+#ifdef CONFIG_DM_REGULATOR
+	ret = regulators_enable_boot_on(false);
+	if (ret)
+		debug("%s: Cannot enable boot on regulator\n", __func__);
 #endif
 
-#if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
+	return 0;
+}
+
+#if !defined(CONFIG_SYS_DCACHE_OFF) && !defined(CONFIG_ARM64)
 void enable_caches(void)
 {
 	/* Enable D-cache. I-cache is already enabled in start.S */
@@ -59,7 +52,7 @@
 #include <usb.h>
 #include <usb/dwc2_udc.h>
 
-static struct dwc2_plat_otg_data rk3036_otg_data = {
+static struct dwc2_plat_otg_data otg_data = {
 	.rx_fifo_sz	= 512,
 	.np_tx_fifo_sz	= 16,
 	.tx_fifo_sz	= 128,
@@ -73,8 +66,7 @@
 	const void *blob = gd->fdt_blob;
 
 	/* find the usb_otg node */
-	node = fdt_node_offset_by_compatible(blob, -1,
-					"rockchip,rk3288-usb");
+	node = fdt_node_offset_by_compatible(blob, -1, "snps,dwc2");
 
 	while (node > 0) {
 		mode = fdt_getprop(blob, node, "dr_mode", NULL);
@@ -83,16 +75,15 @@
 			break;
 		}
 
-		node = fdt_node_offset_by_compatible(blob, node,
-					"rockchip,rk3288-usb");
+		node = fdt_node_offset_by_compatible(blob, node, "snps,dwc2");
 	}
 	if (!matched) {
 		debug("Not found usb_otg device\n");
 		return -ENODEV;
 	}
-	rk3036_otg_data.regs_otg = fdtdec_get_addr(blob, node, "reg");
+	otg_data.regs_otg = fdtdec_get_addr(blob, node, "reg");
 
-	return dwc2_udc_probe(&rk3036_otg_data);
+	return dwc2_udc_probe(&otg_data);
 }
 
 int board_usb_cleanup(int index, enum usb_init_type init)
@@ -100,3 +91,14 @@
 	return 0;
 }
 #endif
+
+#if CONFIG_IS_ENABLED(FASTBOOT)
+int fastboot_set_reboot_flag(void)
+{
+	printf("Setting reboot to fastboot flag ...\n");
+	/* Set boot mode to fastboot */
+	writel(BOOT_FASTBOOT, CONFIG_ROCKCHIP_BOOT_MODE_REG);
+
+	return 0;
+}
+#endif
diff --git a/arch/arm/mach-rockchip/fit_spl_optee.its b/arch/arm/mach-rockchip/fit_spl_optee.its
index 9be4b3c..6ed5d48 100644
--- a/arch/arm/mach-rockchip/fit_spl_optee.its
+++ b/arch/arm/mach-rockchip/fit_spl_optee.its
@@ -11,7 +11,7 @@
 	#address-cells = <1>;
 
 	images {
-		uboot@1 {
+		uboot {
 			description = "U-Boot";
 			data = /incbin/("../../../u-boot-nodtb.bin");
 			type = "standalone";
@@ -20,7 +20,7 @@
 			compression = "none";
 			load = <0x61000000>;
 		};
-		optee@1 {
+		optee {
 			description = "OP-TEE";
 			data = /incbin/("../../../tee.bin");
 			type = "firmware";
@@ -30,7 +30,7 @@
 			load = <0x68400000>;
 			entry = <0x68400000>;
 		};
-		fdt@1 {
+		fdt {
 			description = "dtb";
 			data = /incbin/("../../../u-boot.dtb");
 			type = "flat_dt";
@@ -39,12 +39,12 @@
 	};
 
 	configurations {
-		default = "conf@1";
-		conf@1 {
+		default = "conf";
+		conf {
 			description = "Rockchip armv7 with OP-TEE";
-			firmware = "optee@1";
-			loadables = "uboot@1";
-			fdt = "fdt@1";
+			firmware = "optee";
+			loadables = "uboot";
+			fdt = "fdt";
 		};
 	};
 };
diff --git a/arch/arm/mach-rockchip/rk3036/rk3036.c b/arch/arm/mach-rockchip/rk3036/rk3036.c
index 481af8a..be458cf 100644
--- a/arch/arm/mach-rockchip/rk3036/rk3036.c
+++ b/arch/arm/mach-rockchip/rk3036/rk3036.c
@@ -5,6 +5,9 @@
 #include <asm/io.h>
 #include <asm/arch-rockchip/grf_rk3036.h>
 #include <asm/arch-rockchip/hardware.h>
+#include <asm/arch-rockchip/sdram_rk3036.h>
+
+DECLARE_GLOBAL_DATA_PTR;
 
 #ifdef CONFIG_DEBUG_UART_BOARD_INIT
 void board_debug_uart_init(void)
@@ -36,3 +39,16 @@
 		     GPIO1C2_UART2_SIN << GPIO1C2_SHIFT);
 }
 #endif
+
+#if !CONFIG_IS_ENABLED(RAM)
+/*
+ * When CONFIG_RAM is enabled, the dram_init() function is implemented
+ * in sdram_common.c.
+ */
+int dram_init(void)
+{
+	gd->ram_size = sdram_size();
+
+	return 0;
+}
+#endif
diff --git a/arch/arm/mach-rockchip/rk3128-board.c b/arch/arm/mach-rockchip/rk3128-board.c
deleted file mode 100644
index 0945829..0000000
--- a/arch/arm/mach-rockchip/rk3128-board.c
+++ /dev/null
@@ -1,123 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * (C) Copyright 2017 Rockchip Electronics Co., Ltd.
- */
-#include <common.h>
-#include <clk.h>
-#include <dm.h>
-#include <ram.h>
-#include <syscon.h>
-#include <asm/io.h>
-#include <asm/arch-rockchip/clock.h>
-#include <asm/arch-rockchip/periph.h>
-#include <asm/arch-rockchip/grf_rk3128.h>
-#include <asm/arch-rockchip/boot_mode.h>
-#include <power/regulator.h>
-
-DECLARE_GLOBAL_DATA_PTR;
-
-__weak int rk_board_late_init(void)
-{
-	return 0;
-}
-
-int board_late_init(void)
-{
-	setup_boot_mode();
-
-	return rk_board_late_init();
-}
-
-int board_init(void)
-{
-	int ret = 0;
-
-	ret = regulators_enable_boot_on(false);
-	if (ret) {
-		debug("%s: Cannot enable boot on regulator\n", __func__);
-		return ret;
-	}
-
-	return 0;
-}
-
-int dram_init_banksize(void)
-{
-	gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
-	gd->bd->bi_dram[0].size = 0x8400000;
-	/* Reserve 0xe00000(14MB) for OPTEE with TA enabled, otherwise 2MB */
-	gd->bd->bi_dram[1].start = CONFIG_SYS_SDRAM_BASE
-				+ gd->bd->bi_dram[0].size + 0xe00000;
-	gd->bd->bi_dram[1].size = gd->bd->bi_dram[0].start
-				+ gd->ram_size - gd->bd->bi_dram[1].start;
-
-	return 0;
-}
-
-#if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
-void enable_caches(void)
-{
-	/* Enable D-cache. I-cache is already enabled in start.S */
-	dcache_enable();
-}
-#endif
-
-#if defined(CONFIG_USB_GADGET) && defined(CONFIG_USB_GADGET_DWC2_OTG)
-#include <usb.h>
-#include <usb/dwc2_udc.h>
-
-static struct dwc2_plat_otg_data rk3128_otg_data = {
-	.rx_fifo_sz	= 512,
-	.np_tx_fifo_sz	= 16,
-	.tx_fifo_sz	= 128,
-};
-
-int board_usb_init(int index, enum usb_init_type init)
-{
-	int node;
-	const char *mode;
-	bool matched = false;
-	const void *blob = gd->fdt_blob;
-
-	/* find the usb_otg node */
-	node = fdt_node_offset_by_compatible(blob, -1,
-					     "rockchip,rk3128-usb");
-
-	while (node > 0) {
-		mode = fdt_getprop(blob, node, "dr_mode", NULL);
-		if (mode && strcmp(mode, "otg") == 0) {
-			matched = true;
-			break;
-		}
-
-		node = fdt_node_offset_by_compatible(blob, node,
-						     "rockchip,rk3128-usb");
-	}
-	if (!matched) {
-		debug("Not found usb_otg device\n");
-		return -ENODEV;
-	}
-	rk3128_otg_data.regs_otg = fdtdec_get_addr(blob, node, "reg");
-
-	return dwc2_udc_probe(&rk3128_otg_data);
-}
-
-int board_usb_cleanup(int index, enum usb_init_type init)
-{
-	return 0;
-}
-#endif
-
-#if CONFIG_IS_ENABLED(FASTBOOT)
-int fastboot_set_reboot_flag(void)
-{
-	struct rk3128_grf *grf;
-
-	printf("Setting reboot to fastboot flag ...\n");
-	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
-	/* Set boot mode to fastboot */
-	writel(BOOT_FASTBOOT, &grf->os_reg[0]);
-
-	return 0;
-}
-#endif
diff --git a/arch/arm/mach-rockchip/rk3128/rk3128.c b/arch/arm/mach-rockchip/rk3128/rk3128.c
index 11bba14..ee176de 100644
--- a/arch/arm/mach-rockchip/rk3128/rk3128.c
+++ b/arch/arm/mach-rockchip/rk3128/rk3128.c
@@ -2,6 +2,9 @@
 /*
  * Copyright (c) 2017 Rockchip Electronics Co., Ltd
  */
+#include <common.h>
+
+DECLARE_GLOBAL_DATA_PTR;
 
 int arch_cpu_init(void)
 {
diff --git a/arch/arm/mach-rockchip/rk3188-board-spl.c b/arch/arm/mach-rockchip/rk3188-board-spl.c
deleted file mode 100644
index c3efe0d..0000000
--- a/arch/arm/mach-rockchip/rk3188-board-spl.c
+++ /dev/null
@@ -1,193 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * (C) Copyright 2015 Google, Inc
- */
-
-#include <clk.h>
-#include <common.h>
-#include <debug_uart.h>
-#include <dm.h>
-#include <fdtdec.h>
-#include <led.h>
-#include <malloc.h>
-#include <ram.h>
-#include <spl.h>
-#include <syscon.h>
-#include <asm/gpio.h>
-#include <asm/io.h>
-#include <asm/arch-rockchip/bootrom.h>
-#include <asm/arch-rockchip/clock.h>
-#include <asm/arch-rockchip/grf_rk3188.h>
-#include <asm/arch-rockchip/hardware.h>
-#include <asm/arch-rockchip/periph.h>
-#include <asm/arch-rockchip/pmu_rk3188.h>
-#include <asm/arch-rockchip/sdram.h>
-#include <dm/root.h>
-#include <dm/test.h>
-#include <dm/util.h>
-#include <power/regulator.h>
-
-DECLARE_GLOBAL_DATA_PTR;
-
-u32 spl_boot_device(void)
-{
-#if !CONFIG_IS_ENABLED(OF_PLATDATA)
-	const void *blob = gd->fdt_blob;
-	struct udevice *dev;
-	const char *bootdev;
-	int node;
-	int ret;
-
-	bootdev = fdtdec_get_config_string(blob, "u-boot,boot0");
-	debug("Boot device %s\n", bootdev);
-	if (!bootdev)
-		goto fallback;
-
-	node = fdt_path_offset(blob, bootdev);
-	if (node < 0) {
-		debug("node=%d\n", node);
-		goto fallback;
-	}
-	ret = device_get_global_by_ofnode(offset_to_ofnode(node), &dev);
-	if (ret) {
-		debug("device at node %s/%d not found: %d\n", bootdev, node,
-		      ret);
-		goto fallback;
-	}
-	debug("Found device %s\n", dev->name);
-	switch (device_get_uclass_id(dev)) {
-	case UCLASS_SPI_FLASH:
-		return BOOT_DEVICE_SPI;
-	case UCLASS_MMC:
-		return BOOT_DEVICE_MMC1;
-	default:
-		debug("Booting from device uclass '%s' not supported\n",
-		      dev_get_uclass_name(dev));
-	}
-
-fallback:
-#endif
-	return BOOT_DEVICE_MMC1;
-}
-
-static int setup_arm_clock(void)
-{
-	struct udevice *dev;
-	struct clk clk;
-	int ret;
-
-	ret = rockchip_get_clk(&dev);
-	if (ret)
-		return ret;
-
-	clk.id = CLK_ARM;
-	ret = clk_request(dev, &clk);
-	if (ret < 0)
-		return ret;
-
-	ret = clk_set_rate(&clk, 600000000);
-
-	clk_free(&clk);
-	return ret;
-}
-
-void board_init_f(ulong dummy)
-{
-	struct udevice *dev;
-	int ret;
-
-#ifdef CONFIG_DEBUG_UART
-	/*
-	 * Debug UART can be used from here if required:
-	 *
-	 * debug_uart_init();
-	 * printch('a');
-	 * printhex8(0x1234);
-	 * printascii("string");
-	 */
-	debug_uart_init();
-	printascii("U-Boot SPL board init");
-#endif
-
-#ifdef CONFIG_ROCKCHIP_USB_UART
-	rk_clrsetreg(&grf->uoc0_con[0],
-		     SIDDQ_MASK | UOC_DISABLE_MASK | COMMON_ON_N_MASK,
-		     1 << SIDDQ_SHIFT | 1 << UOC_DISABLE_SHIFT |
-		     1 << COMMON_ON_N_SHIFT);
-	rk_clrsetreg(&grf->uoc0_con[2],
-		     SOFT_CON_SEL_MASK, 1 << SOFT_CON_SEL_SHIFT);
-	rk_clrsetreg(&grf->uoc0_con[3],
-		     OPMODE_MASK | XCVRSELECT_MASK |
-		     TERMSEL_FULLSPEED_MASK | SUSPENDN_MASK,
-		     OPMODE_NODRIVING << OPMODE_SHIFT |
-		     XCVRSELECT_FSTRANSC << XCVRSELECT_SHIFT |
-		     1 << TERMSEL_FULLSPEED_SHIFT |
-		     1 << SUSPENDN_SHIFT);
-	rk_clrsetreg(&grf->uoc0_con[0],
-		     BYPASSSEL_MASK | BYPASSDMEN_MASK,
-		     1 << BYPASSSEL_SHIFT | 1 << BYPASSDMEN_SHIFT);
-#endif
-
-	ret = spl_early_init();
-	if (ret) {
-		debug("spl_early_init() failed: %d\n", ret);
-		hang();
-	}
-
-	ret = rockchip_get_clk(&dev);
-	if (ret) {
-		debug("CLK init failed: %d\n", ret);
-		return;
-	}
-
-	ret = uclass_get_device(UCLASS_RAM, 0, &dev);
-	if (ret) {
-		debug("DRAM init failed: %d\n", ret);
-		return;
-	}
-
-	setup_arm_clock();
-#if CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM) && !defined(CONFIG_SPL_BOARD_INIT)
-	back_to_bootrom(BROM_BOOT_NEXTSTAGE);
-#endif
-}
-
-static int setup_led(void)
-{
-#ifdef CONFIG_SPL_LED
-	struct udevice *dev;
-	char *led_name;
-	int ret;
-
-	led_name = fdtdec_get_config_string(gd->fdt_blob, "u-boot,boot-led");
-	if (!led_name)
-		return 0;
-	ret = led_get_by_label(led_name, &dev);
-	if (ret) {
-		debug("%s: get=%d\n", __func__, ret);
-		return ret;
-	}
-	ret = led_set_on(dev, 1);
-	if (ret)
-		return ret;
-#endif
-
-	return 0;
-}
-
-void spl_board_init(void)
-{
-	int ret;
-
-	ret = setup_led();
-	if (ret) {
-		debug("LED ret=%d\n", ret);
-		hang();
-	}
-
-	preloader_console_init();
-#if CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM)
-	back_to_bootrom(BROM_BOOT_NEXTSTAGE);
-#endif
-	return;
-}
diff --git a/arch/arm/mach-rockchip/rk3188-board.c b/arch/arm/mach-rockchip/rk3188-board.c
deleted file mode 100644
index 94fd6c0..0000000
--- a/arch/arm/mach-rockchip/rk3188-board.c
+++ /dev/null
@@ -1,53 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * (C) Copyright 2015 Google, Inc
- */
-
-#include <common.h>
-#include <clk.h>
-#include <dm.h>
-#include <ram.h>
-#include <syscon.h>
-#include <asm/gpio.h>
-#include <asm/io.h>
-#include <asm/arch-rockchip/clock.h>
-#include <asm/arch-rockchip/grf_rk3188.h>
-#include <asm/arch-rockchip/periph.h>
-#include <asm/arch-rockchip/pmu_rk3288.h>
-#include <asm/arch-rockchip/boot_mode.h>
-
-__weak int rk_board_late_init(void)
-{
-	return 0;
-}
-
-int board_late_init(void)
-{
-	struct rk3188_grf *grf;
-
-	setup_boot_mode();
-	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
-	if (IS_ERR(grf)) {
-		pr_err("grf syscon returned %ld\n", PTR_ERR(grf));
-	} else {
-		/* enable noc remap to mimic legacy loaders */
-		rk_clrsetreg(&grf->soc_con0,
-			NOC_REMAP_MASK << NOC_REMAP_SHIFT,
-			NOC_REMAP_MASK << NOC_REMAP_SHIFT);
-	}
-
-	return rk_board_late_init();
-}
-
-int board_init(void)
-{
-	return 0;
-}
-
-#if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
-void enable_caches(void)
-{
-	/* Enable D-cache. I-cache is already enabled in start.S */
-	dcache_enable();
-}
-#endif
diff --git a/arch/arm/mach-rockchip/rk3188/rk3188.c b/arch/arm/mach-rockchip/rk3188/rk3188.c
index 933484e..95f0e3c 100644
--- a/arch/arm/mach-rockchip/rk3188/rk3188.c
+++ b/arch/arm/mach-rockchip/rk3188/rk3188.c
@@ -3,15 +3,25 @@
  * (C) Copyright 2019 Rockchip Electronics Co., Ltd
  */
 #include <common.h>
+#include <dm.h>
+#include <syscon.h>
 #include <asm/io.h>
+#include <asm/arch-rockchip/bootrom.h>
+#include <asm/arch-rockchip/clock.h>
 #include <asm/arch-rockchip/grf_rk3188.h>
 #include <asm/arch-rockchip/hardware.h>
 
+#define GRF_BASE	0x20008000
+
+const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = {
+	[BROM_BOOTSOURCE_EMMC] = "dwmmc@1021c000",
+	[BROM_BOOTSOURCE_SD] = "dwmmc@10214000",
+};
+
 #ifdef CONFIG_DEBUG_UART_BOARD_INIT
 void board_debug_uart_init(void)
 {
 	/* Enable early UART on the RK3188 */
-#define GRF_BASE	0x20008000
 	struct rk3188_grf * const grf = (void *)GRF_BASE;
 	enum {
 		GPIO1B1_SHIFT		= 2,
@@ -34,3 +44,77 @@
 		     GPIO1B0_UART2_SIN << GPIO1B0_SHIFT);
 }
 #endif
+
+#ifdef CONFIG_SPL_BUILD
+int arch_cpu_init(void)
+{
+	struct rk3188_grf *grf;
+
+	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+	if (IS_ERR(grf)) {
+		pr_err("grf syscon returned %ld\n", PTR_ERR(grf));
+		return 0;
+	}
+#ifdef CONFIG_ROCKCHIP_USB_UART
+	rk_clrsetreg(&grf->uoc0_con[0],
+		     SIDDQ_MASK | UOC_DISABLE_MASK | COMMON_ON_N_MASK,
+		     1 << SIDDQ_SHIFT | 1 << UOC_DISABLE_SHIFT |
+		     1 << COMMON_ON_N_SHIFT);
+	rk_clrsetreg(&grf->uoc0_con[2],
+		     SOFT_CON_SEL_MASK, 1 << SOFT_CON_SEL_SHIFT);
+	rk_clrsetreg(&grf->uoc0_con[3],
+		     OPMODE_MASK | XCVRSELECT_MASK |
+		     TERMSEL_FULLSPEED_MASK | SUSPENDN_MASK,
+		     OPMODE_NODRIVING << OPMODE_SHIFT |
+		     XCVRSELECT_FSTRANSC << XCVRSELECT_SHIFT |
+		     1 << TERMSEL_FULLSPEED_SHIFT |
+		     1 << SUSPENDN_SHIFT);
+	rk_clrsetreg(&grf->uoc0_con[0],
+		     BYPASSSEL_MASK | BYPASSDMEN_MASK,
+		     1 << BYPASSSEL_SHIFT | 1 << BYPASSDMEN_SHIFT);
+#endif
+
+	/* enable noc remap to mimic legacy loaders */
+	rk_clrsetreg(&grf->soc_con0,
+		     NOC_REMAP_MASK << NOC_REMAP_SHIFT,
+		     NOC_REMAP_MASK << NOC_REMAP_SHIFT);
+
+	return 0;
+}
+#endif
+
+#ifdef CONFIG_SPL_BUILD
+static int setup_led(void)
+{
+#ifdef CONFIG_SPL_LED
+	struct udevice *dev;
+	char *led_name;
+	int ret;
+
+	led_name = fdtdec_get_config_string(gd->fdt_blob, "u-boot,boot-led");
+	if (!led_name)
+		return 0;
+	ret = led_get_by_label(led_name, &dev);
+	if (ret) {
+		debug("%s: get=%d\n", __func__, ret);
+		return ret;
+	}
+	ret = led_set_on(dev, 1);
+	if (ret)
+		return ret;
+#endif
+
+	return 0;
+}
+
+void spl_board_init(void)
+{
+	int ret;
+
+	ret = setup_led();
+	if (ret) {
+		debug("LED ret=%d\n", ret);
+		hang();
+	}
+}
+#endif
diff --git a/arch/arm/mach-rockchip/rk322x-board-spl.c b/arch/arm/mach-rockchip/rk322x-board-spl.c
deleted file mode 100644
index c825e31..0000000
--- a/arch/arm/mach-rockchip/rk322x-board-spl.c
+++ /dev/null
@@ -1,76 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * (C) Copyright 2017 Rockchip Electronics Co., Ltd
- */
-
-#include <common.h>
-#include <dm.h>
-#include <spl.h>
-#include <asm/io.h>
-#include <asm/arch-rockchip/hardware.h>
-
-u32 spl_boot_device(void)
-{
-	return BOOT_DEVICE_MMC1;
-}
-
-u32 spl_boot_mode(const u32 boot_device)
-{
-	return MMCSD_MODE_RAW;
-}
-
-#define TIMER_LOAD_COUNT_L	0x00
-#define TIMER_LOAD_COUNT_H	0x04
-#define TIMER_CONTROL_REG	0x10
-#define TIMER_EN	0x1
-#define	TIMER_FMODE	BIT(0)
-#define	TIMER_RMODE	BIT(1)
-
-void rockchip_stimer_init(void)
-{
-	/* If Timer already enabled, don't re-init it */
-	u32 reg = readl(CONFIG_ROCKCHIP_STIMER_BASE + TIMER_CONTROL_REG);
-
-	if (reg & TIMER_EN)
-		return;
-
-	asm volatile("mcr p15, 0, %0, c14, c0, 0"
-		     : : "r"(COUNTER_FREQUENCY));
-
-	writel(0, CONFIG_ROCKCHIP_STIMER_BASE + TIMER_CONTROL_REG);
-	writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE);
-	writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE + 4);
-	writel(TIMER_EN | TIMER_FMODE, CONFIG_ROCKCHIP_STIMER_BASE +
-	       TIMER_CONTROL_REG);
-}
-
-#define SGRF_DDR_CON0 0x10150000
-void board_init_f(ulong dummy)
-{
-	int ret;
-
-	ret = spl_early_init();
-	if (ret) {
-		printf("spl_early_init() failed: %d\n", ret);
-		hang();
-	}
-	preloader_console_init();
-
-	/* Init secure timer */
-	rockchip_stimer_init();
-	/* Init ARM arch timer in arch/arm/cpu/armv7/arch_timer.c */
-	timer_init();
-
-	/* Disable the ddr secure region setting to make it non-secure */
-	rk_clrreg(SGRF_DDR_CON0, 0x4000);
-}
-
-#ifdef CONFIG_SPL_LOAD_FIT
-int board_fit_config_name_match(const char *name)
-{
-	/* Just empty function now - can't decide what to choose */
-	debug("%s: %s\n", __func__, name);
-
-	return 0;
-}
-#endif
diff --git a/arch/arm/mach-rockchip/rk322x-board.c b/arch/arm/mach-rockchip/rk322x-board.c
deleted file mode 100644
index e7a1e54..0000000
--- a/arch/arm/mach-rockchip/rk322x-board.c
+++ /dev/null
@@ -1,127 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * (C) Copyright 2017 Rockchip Electronics Co., Ltd.
- */
-#include <common.h>
-#include <clk.h>
-#include <dm.h>
-#include <ram.h>
-#include <syscon.h>
-#include <asm/io.h>
-#include <asm/arch-rockchip/boot_mode.h>
-#include <asm/arch-rockchip/clock.h>
-#include <asm/arch-rockchip/grf_rk322x.h>
-#include <asm/arch-rockchip/periph.h>
-
-DECLARE_GLOBAL_DATA_PTR;
-
-__weak int rk_board_late_init(void)
-{
-	return 0;
-}
-
-int board_late_init(void)
-{
-	setup_boot_mode();
-
-	return rk_board_late_init();
-}
-
-int board_init(void)
-{
-#include <asm/arch-rockchip/grf_rk322x.h>
-	/* Enable early UART2 channel 1 on the RK322x */
-#define GRF_BASE	0x11000000
-	static struct rk322x_grf * const grf = (void *)GRF_BASE;
-
-	/*
-	* The integrated macphy is enabled by default, disable it
-	* for saving power consuming.
-	*/
-	rk_clrsetreg(&grf->macphy_con[0],
-		     MACPHY_CFG_ENABLE_MASK,
-		     0 << MACPHY_CFG_ENABLE_SHIFT);
-
-	return 0;
-}
-
-int dram_init_banksize(void)
-{
-	gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
-	gd->bd->bi_dram[0].size = 0x8400000;
-	/* Reserve 0x200000 for OPTEE */
-	gd->bd->bi_dram[1].start = CONFIG_SYS_SDRAM_BASE
-				+ gd->bd->bi_dram[0].size + 0x200000;
-	gd->bd->bi_dram[1].size = gd->bd->bi_dram[0].start
-				+ gd->ram_size - gd->bd->bi_dram[1].start;
-
-	return 0;
-}
-
-#if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
-void enable_caches(void)
-{
-	/* Enable D-cache. I-cache is already enabled in start.S */
-	dcache_enable();
-}
-#endif
-
-#if defined(CONFIG_USB_GADGET) && defined(CONFIG_USB_GADGET_DWC2_OTG)
-#include <usb.h>
-#include <usb/dwc2_udc.h>
-
-static struct dwc2_plat_otg_data rk322x_otg_data = {
-	.rx_fifo_sz	= 512,
-	.np_tx_fifo_sz	= 16,
-	.tx_fifo_sz	= 128,
-};
-
-int board_usb_init(int index, enum usb_init_type init)
-{
-	int node;
-	const char *mode;
-	bool matched = false;
-	const void *blob = gd->fdt_blob;
-
-	/* find the usb_otg node */
-	node = fdt_node_offset_by_compatible(blob, -1,
-					"rockchip,rk3288-usb");
-
-	while (node > 0) {
-		mode = fdt_getprop(blob, node, "dr_mode", NULL);
-		if (mode && strcmp(mode, "otg") == 0) {
-			matched = true;
-			break;
-		}
-
-		node = fdt_node_offset_by_compatible(blob, node,
-					"rockchip,rk3288-usb");
-	}
-	if (!matched) {
-		debug("Not found usb_otg device\n");
-		return -ENODEV;
-	}
-	rk322x_otg_data.regs_otg = fdtdec_get_addr(blob, node, "reg");
-
-	return dwc2_udc_probe(&rk322x_otg_data);
-}
-
-int board_usb_cleanup(int index, enum usb_init_type init)
-{
-	return 0;
-}
-#endif
-
-#if CONFIG_IS_ENABLED(FASTBOOT)
-int fastboot_set_reboot_flag(void)
-{
-	struct rk322x_grf *grf;
-
-	printf("Setting reboot to fastboot flag ...\n");
-	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
-	/* Set boot mode to fastboot */
-	writel(BOOT_FASTBOOT, &grf->os_reg[0]);
-
-	return 0;
-}
-#endif
diff --git a/arch/arm/mach-rockchip/rk322x/rk322x.c b/arch/arm/mach-rockchip/rk322x/rk322x.c
index e5250bc..cd0bf8a 100644
--- a/arch/arm/mach-rockchip/rk322x/rk322x.c
+++ b/arch/arm/mach-rockchip/rk322x/rk322x.c
@@ -3,9 +3,15 @@
  * (C) Copyright 2019 Rockchip Electronics Co., Ltd
  */
 #include <asm/io.h>
+#include <asm/arch-rockchip/bootrom.h>
 #include <asm/arch-rockchip/grf_rk322x.h>
 #include <asm/arch-rockchip/hardware.h>
 
+const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = {
+	[BROM_BOOTSOURCE_EMMC] = "dwmmc@30020000",
+	[BROM_BOOTSOURCE_SD] = "dwmmc@30000000",
+};
+
 #ifdef CONFIG_DEBUG_UART_BOARD_INIT
 void board_debug_uart_init(void)
 {
@@ -42,3 +48,26 @@
 		     CON_IOMUX_UART2SEL_21 << CON_IOMUX_UART2SEL_SHIFT);
 }
 #endif
+
+int arch_cpu_init(void)
+{
+#ifdef CONFIG_SPL_BUILD
+#define SGRF_BASE	0x10150000
+	static struct rk322x_sgrf * const sgrf = (void *)SGRF_BASE;
+
+	/* Disable the ddr secure region setting to make it non-secure */
+	rk_clrreg(&sgrf->soc_con[0], 0x4000);
+#else
+#define GRF_BASE	0x11000000
+	static struct rk322x_grf * const grf = (void *)GRF_BASE;
+	/*
+	 * The integrated macphy is enabled by default, disable it
+	 * for saving power consuming.
+	 */
+	rk_clrsetreg(&grf->macphy_con[0],
+		     MACPHY_CFG_ENABLE_MASK,
+		     0 << MACPHY_CFG_ENABLE_SHIFT);
+
+#endif
+	return 0;
+}
diff --git a/arch/arm/mach-rockchip/rk3288-board-spl.c b/arch/arm/mach-rockchip/rk3288-board-spl.c
deleted file mode 100644
index c2e1681..0000000
--- a/arch/arm/mach-rockchip/rk3288-board-spl.c
+++ /dev/null
@@ -1,249 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * (C) Copyright 2015 Google, Inc
- */
-
-#include <common.h>
-#include <debug_uart.h>
-#include <dm.h>
-#include <fdtdec.h>
-#include <i2c.h>
-#include <led.h>
-#include <malloc.h>
-#include <ram.h>
-#include <spl.h>
-#include <asm/gpio.h>
-#include <asm/io.h>
-#include <asm/arch-rockchip/bootrom.h>
-#include <asm/arch-rockchip/clock.h>
-#include <asm/arch-rockchip/hardware.h>
-#include <asm/arch-rockchip/periph.h>
-#include <asm/arch-rockchip/pmu_rk3288.h>
-#include <asm/arch-rockchip/sdram.h>
-#include <asm/arch-rockchip/sdram_common.h>
-#include <asm/arch-rockchip/sys_proto.h>
-#include <dm/root.h>
-#include <dm/test.h>
-#include <dm/util.h>
-#include <power/regulator.h>
-#include <power/rk8xx_pmic.h>
-
-DECLARE_GLOBAL_DATA_PTR;
-
-u32 spl_boot_device(void)
-{
-#if !CONFIG_IS_ENABLED(OF_PLATDATA)
-	const void *blob = gd->fdt_blob;
-	struct udevice *dev;
-	const char *bootdev;
-	int node;
-	int ret;
-
-	bootdev = fdtdec_get_config_string(blob, "u-boot,boot0");
-	debug("Boot device %s\n", bootdev);
-	if (!bootdev)
-		goto fallback;
-
-	node = fdt_path_offset(blob, bootdev);
-	if (node < 0) {
-		debug("node=%d\n", node);
-		goto fallback;
-	}
-	ret = device_get_global_by_ofnode(offset_to_ofnode(node), &dev);
-	if (ret) {
-		debug("device at node %s/%d not found: %d\n", bootdev, node,
-		      ret);
-		goto fallback;
-	}
-	debug("Found device %s\n", dev->name);
-	switch (device_get_uclass_id(dev)) {
-	case UCLASS_SPI_FLASH:
-		return BOOT_DEVICE_SPI;
-	case UCLASS_MMC:
-		return BOOT_DEVICE_MMC1;
-	default:
-		debug("Booting from device uclass '%s' not supported\n",
-		      dev_get_uclass_name(dev));
-	}
-
-fallback:
-#elif defined(CONFIG_TARGET_CHROMEBOOK_JERRY) || \
-		defined(CONFIG_TARGET_CHROMEBIT_MICKEY) || \
-		defined(CONFIG_TARGET_CHROMEBOOK_MINNIE) || \
-		defined(CONFIG_TARGET_CHROMEBOOK_SPEEDY)
-	return BOOT_DEVICE_SPI;
-#endif
-	return BOOT_DEVICE_MMC1;
-}
-
-#if !defined(CONFIG_SPL_OF_PLATDATA)
-static int phycore_init(void)
-{
-	struct udevice *pmic;
-	int ret;
-
-	ret = uclass_first_device_err(UCLASS_PMIC, &pmic);
-	if (ret)
-		return ret;
-
-#if defined(CONFIG_SPL_POWER_SUPPORT)
-	/* Increase USB input current to 2A */
-	ret = rk818_spl_configure_usb_input_current(pmic, 2000);
-	if (ret)
-		return ret;
-
-	/* Close charger when USB lower then 3.26V */
-	ret = rk818_spl_configure_usb_chrg_shutdown(pmic, 3260000);
-	if (ret)
-		return ret;
-#endif
-
-	return 0;
-}
-#endif
-
-__weak int arch_cpu_init(void)
-{
-	return 0;
-}
-
-#define TIMER_LOAD_COUNT_L	0x00
-#define TIMER_LOAD_COUNT_H	0x04
-#define TIMER_CONTROL_REG	0x10
-#define TIMER_EN	0x1
-#define	TIMER_FMODE	BIT(0)
-#define	TIMER_RMODE	BIT(1)
-
-void rockchip_stimer_init(void)
-{
-	/* If Timer already enabled, don't re-init it */
-	u32 reg = readl(CONFIG_ROCKCHIP_STIMER_BASE + TIMER_CONTROL_REG);
-
-	if (reg & TIMER_EN)
-		return;
-
-	asm volatile("mcr p15, 0, %0, c14, c0, 0"
-		     : : "r"(COUNTER_FREQUENCY));
-
-	writel(0, CONFIG_ROCKCHIP_STIMER_BASE + TIMER_CONTROL_REG);
-	writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE);
-	writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE + 4);
-	writel(TIMER_EN | TIMER_FMODE, CONFIG_ROCKCHIP_STIMER_BASE +
-	       TIMER_CONTROL_REG);
-}
-
-void board_init_f(ulong dummy)
-{
-	struct udevice *dev;
-	int ret;
-
-#ifdef CONFIG_DEBUG_UART
-	/*
-	 * Debug UART can be used from here if required:
-	 *
-	 * debug_uart_init();
-	 * printch('a');
-	 * printhex8(0x1234);
-	 * printascii("string");
-	 */
-	debug_uart_init();
-	debug("\nspl:debug uart enabled in %s\n", __func__);
-#endif
-	ret = spl_early_init();
-	if (ret) {
-		debug("spl_early_init() failed: %d\n", ret);
-		hang();
-	}
-
-	/* Init secure timer */
-	rockchip_stimer_init();
-	/* Init ARM arch timer in arch/arm/cpu/armv7/arch_timer.c */
-	timer_init();
-
-	arch_cpu_init();
-
-	ret = rockchip_get_clk(&dev);
-	if (ret) {
-		debug("CLK init failed: %d\n", ret);
-		return;
-	}
-
-#if !defined(CONFIG_SPL_OF_PLATDATA)
-	if (of_machine_is_compatible("phytec,rk3288-phycore-som")) {
-		ret = phycore_init();
-		if (ret) {
-			debug("Failed to set up phycore power settings: %d\n",
-			      ret);
-			return;
-		}
-	}
-#endif
-
-#if !defined(CONFIG_SUPPORT_TPL)
-	debug("\nspl:init dram\n");
-	ret = uclass_get_device(UCLASS_RAM, 0, &dev);
-	if (ret) {
-		debug("DRAM init failed: %d\n", ret);
-		return;
-	}
-#endif
-
-#if CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM) && !defined(CONFIG_SPL_BOARD_INIT)
-	back_to_bootrom(BROM_BOOT_NEXTSTAGE);
-#endif
-}
-
-static int setup_led(void)
-{
-#ifdef CONFIG_SPL_LED
-	struct udevice *dev;
-	char *led_name;
-	int ret;
-
-	led_name = fdtdec_get_config_string(gd->fdt_blob, "u-boot,boot-led");
-	if (!led_name)
-		return 0;
-	ret = led_get_by_label(led_name, &dev);
-	if (ret) {
-		debug("%s: get=%d\n", __func__, ret);
-		return ret;
-	}
-	ret = led_set_on(dev, 1);
-	if (ret)
-		return ret;
-#endif
-
-	return 0;
-}
-
-void spl_board_init(void)
-{
-	int ret;
-
-	ret = setup_led();
-	if (ret) {
-		debug("LED ret=%d\n", ret);
-		hang();
-	}
-
-	preloader_console_init();
-#if CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM)
-	back_to_bootrom(BROM_BOOT_NEXTSTAGE);
-#endif
-	return;
-}
-
-#ifdef CONFIG_SPL_OS_BOOT
-
-#define PMU_BASE		0xff730000
-int dram_init_banksize(void)
-{
-	struct rk3288_pmu *const pmu = (void *)PMU_BASE;
-	size_t size = rockchip_sdram_size((phys_addr_t)&pmu->sys_reg[2]);
-
-	gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
-	gd->bd->bi_dram[0].size = size;
-
-	return 0;
-}
-#endif
diff --git a/arch/arm/mach-rockchip/rk3288-board.c b/arch/arm/mach-rockchip/rk3288-board.c
deleted file mode 100644
index a250d50..0000000
--- a/arch/arm/mach-rockchip/rk3288-board.c
+++ /dev/null
@@ -1,320 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * (C) Copyright 2015 Google, Inc
- */
-
-#include <common.h>
-#include <clk.h>
-#include <dm.h>
-#include <ram.h>
-#include <syscon.h>
-#include <asm/io.h>
-#include <asm/arch-rockchip/clock.h>
-#include <asm/arch-rockchip/cru_rk3288.h>
-#include <asm/arch-rockchip/periph.h>
-#include <asm/arch-rockchip/pmu_rk3288.h>
-#include <asm/arch-rockchip/qos_rk3288.h>
-#include <asm/arch-rockchip/boot_mode.h>
-#include <asm/gpio.h>
-#include <dt-bindings/clock/rk3288-cru.h>
-#include <power/regulator.h>
-
-DECLARE_GLOBAL_DATA_PTR;
-
-__weak int rk_board_late_init(void)
-{
-	return 0;
-}
-
-int rk3288_qos_init(void)
-{
-	int val = 2 << PRIORITY_HIGH_SHIFT | 2 << PRIORITY_LOW_SHIFT;
-	/* set vop qos to higher priority */
-	writel(val, CPU_AXI_QOS_PRIORITY + VIO0_VOP_QOS);
-	writel(val, CPU_AXI_QOS_PRIORITY + VIO1_VOP_QOS);
-
-	if (!fdt_node_check_compatible(gd->fdt_blob, 0,
-				       "rockchip,rk3288-tinker"))
-	{
-		/* set isp qos to higher priority */
-		writel(val, CPU_AXI_QOS_PRIORITY + VIO1_ISP_R_QOS);
-		writel(val, CPU_AXI_QOS_PRIORITY + VIO1_ISP_W0_QOS);
-		writel(val, CPU_AXI_QOS_PRIORITY + VIO1_ISP_W1_QOS);
-	}
-	return 0;
-}
-
-static void rk3288_detect_reset_reason(void)
-{
-	struct rk3288_cru *cru = rockchip_get_cru();
-	const char *reason;
-
-	if (IS_ERR(cru))
-		return;
-
-	switch (cru->cru_glb_rst_st) {
-	case GLB_POR_RST:
-		reason = "POR";
-		break;
-	case FST_GLB_RST_ST:
-	case SND_GLB_RST_ST:
-		reason = "RST";
-		break;
-	case FST_GLB_TSADC_RST_ST:
-	case SND_GLB_TSADC_RST_ST:
-		reason = "THERMAL";
-		break;
-	case FST_GLB_WDT_RST_ST:
-	case SND_GLB_WDT_RST_ST:
-		reason = "WDOG";
-		break;
-	default:
-		reason = "unknown reset";
-	}
-
-	env_set("reset_reason", reason);
-
-	/*
-	 * Clear cru_glb_rst_st, so we can determine the last reset cause
-	 * for following resets.
-	 */
-	rk_clrreg(&cru->cru_glb_rst_st, GLB_RST_ST_MASK);
-}
-
-int board_late_init(void)
-{
-	setup_boot_mode();
-	rk3288_qos_init();
-	rk3288_detect_reset_reason();
-
-	return rk_board_late_init();
-}
-
-#if !CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM)
-static int veyron_init(void)
-{
-	struct udevice *dev;
-	struct clk clk;
-	int ret;
-
-	ret = regulator_get_by_platname("vdd_arm", &dev);
-	if (ret) {
-		debug("Cannot set regulator name\n");
-		return ret;
-	}
-
-	/* Slowly raise to max CPU voltage to prevent overshoot */
-	ret = regulator_set_value(dev, 1200000);
-	if (ret)
-		return ret;
-	udelay(175); /* Must wait for voltage to stabilize, 2mV/us */
-	ret = regulator_set_value(dev, 1400000);
-	if (ret)
-		return ret;
-	udelay(100); /* Must wait for voltage to stabilize, 2mV/us */
-
-	ret = rockchip_get_clk(&clk.dev);
-	if (ret)
-		return ret;
-	clk.id = PLL_APLL;
-	ret = clk_set_rate(&clk, 1800000000);
-	if (IS_ERR_VALUE(ret))
-		return ret;
-
-	ret = regulator_get_by_platname("vcc33_sd", &dev);
-	if (ret) {
-		debug("Cannot get regulator name\n");
-		return ret;
-	}
-
-	ret = regulator_set_value(dev, 3300000);
-	if (ret)
-		return ret;
-
-	ret = regulators_enable_boot_on(false);
-	if (ret) {
-		debug("%s: Cannot enable boot on regulators\n", __func__);
-		return ret;
-	}
-
-	return 0;
-}
-#endif
-
-int board_init(void)
-{
-#if CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM)
-	return 0;
-#else
-	int ret;
-
-	/* We do some SoC one time setting here */
-	if (!fdt_node_check_compatible(gd->fdt_blob, 0, "google,veyron")) {
-		ret = veyron_init();
-		if (ret)
-			return ret;
-	}
-
-	return 0;
-#endif
-}
-
-#if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
-void enable_caches(void)
-{
-	/* Enable D-cache. I-cache is already enabled in start.S */
-	dcache_enable();
-}
-#endif
-
-#if defined(CONFIG_USB_GADGET) && defined(CONFIG_USB_GADGET_DWC2_OTG)
-#include <usb.h>
-#include <usb/dwc2_udc.h>
-
-static struct dwc2_plat_otg_data rk3288_otg_data = {
-	.rx_fifo_sz	= 512,
-	.np_tx_fifo_sz	= 16,
-	.tx_fifo_sz	= 128,
-};
-
-int board_usb_init(int index, enum usb_init_type init)
-{
-	int node, phy_node;
-	const char *mode;
-	bool matched = false;
-	const void *blob = gd->fdt_blob;
-	u32 grf_phy_offset;
-
-	/* find the usb_otg node */
-	node = fdt_node_offset_by_compatible(blob, -1,
-					"rockchip,rk3288-usb");
-
-	while (node > 0) {
-		mode = fdt_getprop(blob, node, "dr_mode", NULL);
-		if (mode && strcmp(mode, "otg") == 0) {
-			matched = true;
-			break;
-		}
-
-		node = fdt_node_offset_by_compatible(blob, node,
-					"rockchip,rk3288-usb");
-	}
-	if (!matched) {
-		debug("Not found usb_otg device\n");
-		return -ENODEV;
-	}
-	rk3288_otg_data.regs_otg = fdtdec_get_addr(blob, node, "reg");
-
-	node = fdtdec_lookup_phandle(blob, node, "phys");
-	if (node <= 0) {
-		debug("Not found usb phy device\n");
-		return -ENODEV;
-	}
-
-	phy_node = fdt_parent_offset(blob, node);
-	if (phy_node <= 0) {
-		debug("Not found usb phy device\n");
-		return -ENODEV;
-	}
-
-	rk3288_otg_data.phy_of_node = phy_node;
-	grf_phy_offset = fdtdec_get_addr(blob, node, "reg");
-
-	/* find the grf node */
-	node = fdt_node_offset_by_compatible(blob, -1,
-					"rockchip,rk3288-grf");
-	if (node <= 0) {
-		debug("Not found grf device\n");
-		return -ENODEV;
-	}
-	rk3288_otg_data.regs_phy = grf_phy_offset +
-				fdtdec_get_addr(blob, node, "reg");
-
-	return dwc2_udc_probe(&rk3288_otg_data);
-}
-
-int board_usb_cleanup(int index, enum usb_init_type init)
-{
-	return 0;
-}
-#endif
-
-static int do_clock(cmd_tbl_t *cmdtp, int flag, int argc,
-		       char * const argv[])
-{
-	static const struct {
-		char *name;
-		int id;
-	} clks[] = {
-		{ "osc", CLK_OSC },
-		{ "apll", CLK_ARM },
-		{ "dpll", CLK_DDR },
-		{ "cpll", CLK_CODEC },
-		{ "gpll", CLK_GENERAL },
-#ifdef CONFIG_ROCKCHIP_RK3036
-		{ "mpll", CLK_NEW },
-#else
-		{ "npll", CLK_NEW },
-#endif
-	};
-	int ret, i;
-	struct udevice *dev;
-
-	ret = rockchip_get_clk(&dev);
-	if (ret) {
-		printf("clk-uclass not found\n");
-		return 0;
-	}
-
-	for (i = 0; i < ARRAY_SIZE(clks); i++) {
-		struct clk clk;
-		ulong rate;
-
-		clk.id = clks[i].id;
-		ret = clk_request(dev, &clk);
-		if (ret < 0)
-			continue;
-
-		rate = clk_get_rate(&clk);
-		printf("%s: %lu\n", clks[i].name, rate);
-
-		clk_free(&clk);
-	}
-
-	return 0;
-}
-
-U_BOOT_CMD(
-	clock, 2, 1, do_clock,
-	"display information about clocks",
-	""
-);
-
-int board_early_init_f(void)
-{
-	const uintptr_t GRF_SOC_CON0 = 0xff770244;
-	const uintptr_t GRF_SOC_CON2 = 0xff77024c;
-	struct udevice *dev;
-	int ret;
-
-	/*
-	 * This init is done in SPL, but when chain-loading U-Boot SPL will
-	 * have been skipped. Allow the clock driver to check if it needs
-	 * setting up.
-	 */
-	ret = rockchip_get_clk(&dev);
-	if (ret) {
-		debug("CLK init failed: %d\n", ret);
-		return ret;
-	}
-
-	rk_setreg(GRF_SOC_CON2, 1 << 0);
-
-	/*
-	 * Disable JTAG on sdmmc0 IO. The SDMMC won't work until this bit is
-	 * cleared
-	 */
-	rk_clrreg(GRF_SOC_CON0, 1 << 12);
-
-	return 0;
-}
diff --git a/arch/arm/mach-rockchip/rk3288/Kconfig b/arch/arm/mach-rockchip/rk3288/Kconfig
index de8d9c2..87d0786 100644
--- a/arch/arm/mach-rockchip/rk3288/Kconfig
+++ b/arch/arm/mach-rockchip/rk3288/Kconfig
@@ -66,6 +66,7 @@
 config TARGET_FIREFLY_RK3288
 	bool "Firefly-RK3288"
 	select BOARD_LATE_INIT
+	select SPL_BOARD_INIT if SPL
 	help
 	  Firefly is a RK3288-based development board with 2 USB ports,
 	  HDMI, VGA, micro-SD card, audio, WiFi  and Gigabit Ethernet, It
@@ -84,6 +85,7 @@
 config TARGET_PHYCORE_RK3288
 	bool "phyCORE-RK3288"
         select BOARD_LATE_INIT
+	select SPL_BOARD_INIT if SPL
 	help
 	  Add basic support for the PCM-947 carrier board, a RK3288 based
 	  development board made by PHYTEC. This board works in a combination
diff --git a/arch/arm/mach-rockchip/rk3288/rk3288.c b/arch/arm/mach-rockchip/rk3288/rk3288.c
index 7552472..b462c09 100644
--- a/arch/arm/mach-rockchip/rk3288/rk3288.c
+++ b/arch/arm/mach-rockchip/rk3288/rk3288.c
@@ -2,13 +2,29 @@
 /*
  * Copyright (c) 2016 Rockchip Electronics Co., Ltd
  */
+#include <common.h>
+#include <dm.h>
+#include <clk.h>
 #include <asm/armv7.h>
 #include <asm/io.h>
+#include <asm/arch-rockchip/bootrom.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/cru_rk3288.h>
 #include <asm/arch-rockchip/hardware.h>
 #include <asm/arch-rockchip/grf_rk3288.h>
+#include <asm/arch-rockchip/pmu_rk3288.h>
+#include <asm/arch-rockchip/qos_rk3288.h>
+#include <asm/arch-rockchip/sdram_common.h>
+
+DECLARE_GLOBAL_DATA_PTR;
 
 #define GRF_BASE	0xff770000
 
+const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = {
+	[BROM_BOOTSOURCE_EMMC] = "dwmmc@ff0f0000",
+	[BROM_BOOTSOURCE_SD] = "dwmmc@ff0c0000",
+};
+
 #ifdef CONFIG_SPL_BUILD
 static void configure_l2ctlr(void)
 {
@@ -30,6 +46,24 @@
 }
 #endif
 
+int rk3288_qos_init(void)
+{
+	int val = 2 << PRIORITY_HIGH_SHIFT | 2 << PRIORITY_LOW_SHIFT;
+	/* set vop qos to higher priority */
+	writel(val, CPU_AXI_QOS_PRIORITY + VIO0_VOP_QOS);
+	writel(val, CPU_AXI_QOS_PRIORITY + VIO1_VOP_QOS);
+
+	if (!fdt_node_check_compatible(gd->fdt_blob, 0,
+				       "rockchip,rk3288-tinker")) {
+		/* set isp qos to higher priority */
+		writel(val, CPU_AXI_QOS_PRIORITY + VIO1_ISP_R_QOS);
+		writel(val, CPU_AXI_QOS_PRIORITY + VIO1_ISP_W0_QOS);
+		writel(val, CPU_AXI_QOS_PRIORITY + VIO1_ISP_W1_QOS);
+	}
+
+	return 0;
+}
+
 int arch_cpu_init(void)
 {
 #ifdef CONFIG_SPL_BUILD
@@ -40,6 +74,14 @@
 
 	/* Use rkpwm by default */
 	rk_setreg(&grf->soc_con2, 1 << 0);
+
+	/*
+	 * Disable JTAG on sdmmc0 IO. The SDMMC won't work until this bit is
+	 * cleared
+	 */
+	rk_clrreg(&grf->soc_con0, 1 << 12);
+
+	rk3288_qos_init();
 #endif
 
 	return 0;
@@ -57,3 +99,103 @@
 		     GPIO7C6_UART2DBG_SIN << GPIO7C6_SHIFT);
 }
 #endif
+
+static void rk3288_detect_reset_reason(void)
+{
+	struct rk3288_cru *cru = rockchip_get_cru();
+	const char *reason;
+
+	if (IS_ERR(cru))
+		return;
+
+	switch (cru->cru_glb_rst_st) {
+	case GLB_POR_RST:
+		reason = "POR";
+		break;
+	case FST_GLB_RST_ST:
+	case SND_GLB_RST_ST:
+		reason = "RST";
+		break;
+	case FST_GLB_TSADC_RST_ST:
+	case SND_GLB_TSADC_RST_ST:
+		reason = "THERMAL";
+		break;
+	case FST_GLB_WDT_RST_ST:
+	case SND_GLB_WDT_RST_ST:
+		reason = "WDOG";
+		break;
+	default:
+		reason = "unknown reset";
+	}
+
+	env_set("reset_reason", reason);
+
+	/*
+	 * Clear cru_glb_rst_st, so we can determine the last reset cause
+	 * for following resets.
+	 */
+	rk_clrreg(&cru->cru_glb_rst_st, GLB_RST_ST_MASK);
+}
+
+__weak int rk3288_board_late_init(void)
+{
+	return 0;
+}
+
+int rk_board_late_init(void)
+{
+	rk3288_detect_reset_reason();
+
+	return rk3288_board_late_init();
+}
+
+static int do_clock(cmd_tbl_t *cmdtp, int flag, int argc,
+		       char * const argv[])
+{
+	static const struct {
+		char *name;
+		int id;
+	} clks[] = {
+		{ "osc", CLK_OSC },
+		{ "apll", CLK_ARM },
+		{ "dpll", CLK_DDR },
+		{ "cpll", CLK_CODEC },
+		{ "gpll", CLK_GENERAL },
+#ifdef CONFIG_ROCKCHIP_RK3036
+		{ "mpll", CLK_NEW },
+#else
+		{ "npll", CLK_NEW },
+#endif
+	};
+	int ret, i;
+	struct udevice *dev;
+
+	ret = rockchip_get_clk(&dev);
+	if (ret) {
+		printf("clk-uclass not found\n");
+		return 0;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(clks); i++) {
+		struct clk clk;
+		ulong rate;
+
+		clk.id = clks[i].id;
+		ret = clk_request(dev, &clk);
+		if (ret < 0)
+			continue;
+
+		rate = clk_get_rate(&clk);
+		printf("%s: %lu\n", clks[i].name, rate);
+
+		clk_free(&clk);
+	}
+
+	return 0;
+}
+
+U_BOOT_CMD(
+	clock, 2, 1, do_clock,
+	"display information about clocks",
+	""
+);
diff --git a/arch/arm/mach-rockchip/rk3328-board-spl.c b/arch/arm/mach-rockchip/rk3328-board-spl.c
deleted file mode 100644
index f24fd89..0000000
--- a/arch/arm/mach-rockchip/rk3328-board-spl.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * (C) Copyright 2016 Rockchip Electronics Co., Ltd
- *
- * SPDX-License-Identifier:     GPL-2.0+
- */
-
-#include <common.h>
-#include <debug_uart.h>
-#include <dm.h>
-#include <ram.h>
-#include <spl.h>
-#include <asm/io.h>
-
-DECLARE_GLOBAL_DATA_PTR;
-
-void board_debug_uart_init(void)
-{
-}
-
-void board_init_f(ulong dummy)
-{
-	struct udevice *dev;
-	int ret;
-
-	ret = spl_early_init();
-	if (ret) {
-		debug("spl_early_init() failed: %d\n", ret);
-		hang();
-	}
-
-	preloader_console_init();
-
-	ret = uclass_get_device(UCLASS_RAM, 0, &dev);
-	if (ret) {
-		debug("DRAM init failed: %d\n", ret);
-		return;
-	}
-}
-
-u32 spl_boot_mode(const u32 boot_device)
-{
-	return MMCSD_MODE_RAW;
-}
-
-u32 spl_boot_device(void)
-{
-	return BOOT_DEVICE_MMC1;
-}
-
-#ifdef CONFIG_SPL_LOAD_FIT
-int board_fit_config_name_match(const char *name)
-{
-	/* Just empty function now - can't decide what to choose */
-	debug("%s: %s\n", __func__, name);
-
-	return 0;
-}
-#endif
diff --git a/arch/arm/mach-rockchip/rk3328/rk3328.c b/arch/arm/mach-rockchip/rk3328/rk3328.c
index 1cf829d..592f287 100644
--- a/arch/arm/mach-rockchip/rk3328/rk3328.c
+++ b/arch/arm/mach-rockchip/rk3328/rk3328.c
@@ -4,12 +4,24 @@
  */
 
 #include <common.h>
+#include <asm/arch-rockchip/bootrom.h>
 #include <asm/arch-rockchip/hardware.h>
+#include <asm/arch-rockchip/grf_rk3328.h>
+#include <asm/arch-rockchip/uart.h>
 #include <asm/armv8/mmu.h>
 #include <asm/io.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
+#define CRU_BASE		0xFF440000
+#define GRF_BASE		0xFF100000
+#define UART2_BASE		0xFF130000
+
+const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = {
+	[BROM_BOOTSOURCE_EMMC] = "rksdmmc@ff520000",
+	[BROM_BOOTSOURCE_SD] = "rksdmmc@ff500000",
+};
+
 static struct mm_region rk3328_mem_map[] = {
 	{
 		.virt = 0x0UL,
@@ -32,20 +44,52 @@
 
 struct mm_region *mem_map = rk3328_mem_map;
 
-int dram_init_banksize(void)
-{
-	size_t max_size = min((unsigned long)gd->ram_size, gd->ram_top);
-
-	/* Reserve 0x200000 for ATF bl31 */
-	gd->bd->bi_dram[0].start = 0x200000;
-	gd->bd->bi_dram[0].size = max_size - gd->bd->bi_dram[0].start;
-
-	return 0;
-}
-
 int arch_cpu_init(void)
 {
 	/* We do some SoC one time setting here. */
 
 	return 0;
 }
+
+void board_debug_uart_init(void)
+{
+	struct rk3328_grf_regs * const grf = (void *)GRF_BASE;
+	struct rk_uart * const uart = (void *)UART2_BASE;
+	enum{
+		GPIO2A0_SEL_SHIFT       = 0,
+		GPIO2A0_SEL_MASK        = 3 << GPIO2A0_SEL_SHIFT,
+		GPIO2A0_UART2_TX_M1     = 1,
+
+		GPIO2A1_SEL_SHIFT       = 2,
+		GPIO2A1_SEL_MASK        = 3 << GPIO2A1_SEL_SHIFT,
+		GPIO2A1_UART2_RX_M1     = 1,
+	};
+	enum {
+		IOMUX_SEL_UART2_SHIFT   = 0,
+		IOMUX_SEL_UART2_MASK    = 3 << IOMUX_SEL_UART2_SHIFT,
+		IOMUX_SEL_UART2_M0      = 0,
+		IOMUX_SEL_UART2_M1,
+	};
+
+	/* uart_sel_clk default select 24MHz */
+	writel((3 << (8 + 16)) | (2 << 8), CRU_BASE + 0x148);
+
+	/* init uart baud rate 1500000 */
+	writel(0x83, &uart->lcr);
+	writel(0x1, &uart->rbr);
+	writel(0x3, &uart->lcr);
+
+	/* Enable early UART2 */
+	rk_clrsetreg(&grf->com_iomux,
+		     IOMUX_SEL_UART2_MASK,
+		     IOMUX_SEL_UART2_M1 << IOMUX_SEL_UART2_SHIFT);
+	rk_clrsetreg(&grf->gpio2a_iomux,
+		     GPIO2A0_SEL_MASK,
+		     GPIO2A0_UART2_TX_M1 << GPIO2A0_SEL_SHIFT);
+	rk_clrsetreg(&grf->gpio2a_iomux,
+		     GPIO2A1_SEL_MASK,
+		     GPIO2A1_UART2_RX_M1 << GPIO2A1_SEL_SHIFT);
+
+	/* enable FIFO */
+	writel(0x1, &uart->sfe);
+}
diff --git a/arch/arm/mach-rockchip/rk3368-board-spl.c b/arch/arm/mach-rockchip/rk3368-board-spl.c
deleted file mode 100644
index 6ba106c..0000000
--- a/arch/arm/mach-rockchip/rk3368-board-spl.c
+++ /dev/null
@@ -1,80 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * (C) Copyright 2017 Theobroma Systems Design und Consulting GmbH
- */
-
-#include <common.h>
-#include <debug_uart.h>
-#include <dm.h>
-#include <ram.h>
-#include <spl.h>
-#include <asm/io.h>
-#include <asm/arch-rockchip/periph.h>
-
-__weak int arch_cpu_init(void)
-{
-	return 0;
-}
-
-#define TIMER_LOAD_COUNT_L	0x00
-#define TIMER_LOAD_COUNT_H	0x04
-#define TIMER_CONTROL_REG	0x10
-#define TIMER_EN	0x1
-#define	TIMER_FMODE	BIT(0)
-#define	TIMER_RMODE	BIT(1)
-
-void rockchip_stimer_init(void)
-{
-	/* If Timer already enabled, don't re-init it */
-	u32 reg = readl(CONFIG_ROCKCHIP_STIMER_BASE + TIMER_CONTROL_REG);
-
-	if (reg & TIMER_EN)
-		return;
-
-	writel(0, CONFIG_ROCKCHIP_STIMER_BASE + TIMER_CONTROL_REG);
-	writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE);
-	writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE + 4);
-	writel(TIMER_EN | TIMER_FMODE, CONFIG_ROCKCHIP_STIMER_BASE +
-	       TIMER_CONTROL_REG);
-}
-
-void board_init_f(ulong dummy)
-{
-	struct udevice *dev;
-	int ret;
-
-	ret = spl_early_init();
-	if (ret) {
-		debug("spl_early_init() failed: %d\n", ret);
-		hang();
-	}
-
-	/* Init secure timer */
-	rockchip_stimer_init();
-	/* Init ARM arch timer in arch/arm/cpu/armv7/arch_timer.c */
-	timer_init();
-
-	arch_cpu_init();
-	preloader_console_init();
-
-	ret = uclass_get_device(UCLASS_RAM, 0, &dev);
-	if (ret) {
-		debug("DRAM init failed: %d\n", ret);
-		return;
-	}
-}
-
-u32 spl_boot_device(void)
-{
-	return BOOT_DEVICE_MMC1;
-}
-
-#ifdef CONFIG_SPL_LOAD_FIT
-int board_fit_config_name_match(const char *name)
-{
-	/* Just empty function now - can't decide what to choose */
-	debug("%s: %s\n", __func__, name);
-
-	return 0;
-}
-#endif
diff --git a/arch/arm/mach-rockchip/rk3368/rk3368.c b/arch/arm/mach-rockchip/rk3368/rk3368.c
index 47786f5..7ccd417 100644
--- a/arch/arm/mach-rockchip/rk3368/rk3368.c
+++ b/arch/arm/mach-rockchip/rk3368/rk3368.c
@@ -8,6 +8,7 @@
 #include <syscon.h>
 #include <asm/armv8/mmu.h>
 #include <asm/io.h>
+#include <asm/arch-rockchip/bootrom.h>
 #include <asm/arch-rockchip/clock.h>
 #include <asm/arch-rockchip/cru_rk3368.h>
 #include <asm/arch-rockchip/grf_rk3368.h>
@@ -52,16 +53,10 @@
 
 struct mm_region *mem_map = rk3368_mem_map;
 
-int dram_init_banksize(void)
-{
-	size_t max_size = min((unsigned long)gd->ram_size, gd->ram_top);
-
-	/* Reserve 0x200000 for ATF bl31 */
-	gd->bd->bi_dram[0].start = 0x200000;
-	gd->bd->bi_dram[0].size = max_size - gd->bd->bi_dram[0].start;
-
-	return 0;
-}
+const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = {
+	[BROM_BOOTSOURCE_EMMC] = "dwmmc@ff0f0000",
+	[BROM_BOOTSOURCE_SD] = "dwmmc@ff0c0000",
+};
 
 #ifdef CONFIG_ARCH_EARLY_INIT_R
 static int mcu_init(void)
diff --git a/arch/arm/mach-rockchip/rk3399-board-spl.c b/arch/arm/mach-rockchip/rk3399-board-spl.c
deleted file mode 100644
index 7154d8e..0000000
--- a/arch/arm/mach-rockchip/rk3399-board-spl.c
+++ /dev/null
@@ -1,251 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * (C) Copyright 2016 Rockchip Electronics Co., Ltd
- * (C) Copyright 2017 Theobroma Systems Design und Consulting GmbH
- */
-
-#include <common.h>
-#include <debug_uart.h>
-#include <dm.h>
-#include <ram.h>
-#include <spl.h>
-#include <spl_gpio.h>
-#include <syscon.h>
-#include <asm/gpio.h>
-#include <asm/io.h>
-#include <asm/arch-rockchip/bootrom.h>
-#include <asm/arch-rockchip/clock.h>
-#include <asm/arch-rockchip/cru_rk3399.h>
-#include <asm/arch-rockchip/grf_rk3399.h>
-#include <asm/arch-rockchip/hardware.h>
-#include <asm/arch-rockchip/periph.h>
-#include <asm/arch-rockchip/sys_proto.h>
-#include <power/regulator.h>
-
-void board_return_to_bootrom(void)
-{
-	back_to_bootrom(BROM_BOOT_NEXTSTAGE);
-}
-
-static const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = {
-	[BROM_BOOTSOURCE_EMMC] = "/sdhci@fe330000",
-	[BROM_BOOTSOURCE_SPINOR] = "/spi@ff1d0000",
-	[BROM_BOOTSOURCE_SD] = "/dwmmc@fe320000",
-};
-
-const char *board_spl_was_booted_from(void)
-{
-	u32  bootdevice_brom_id = readl(RK3399_BROM_BOOTSOURCE_ID_ADDR);
-	const char *bootdevice_ofpath = NULL;
-
-	if (bootdevice_brom_id < ARRAY_SIZE(boot_devices))
-		bootdevice_ofpath = boot_devices[bootdevice_brom_id];
-
-	if (bootdevice_ofpath)
-		debug("%s: brom_bootdevice_id %x maps to '%s'\n",
-		      __func__, bootdevice_brom_id, bootdevice_ofpath);
-	else
-		debug("%s: failed to resolve brom_bootdevice_id %x\n",
-		      __func__, bootdevice_brom_id);
-
-	return bootdevice_ofpath;
-}
-
-u32 spl_boot_device(void)
-{
-	u32 boot_device = BOOT_DEVICE_MMC1;
-
-	if (CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM))
-		return BOOT_DEVICE_BOOTROM;
-
-	return boot_device;
-}
-
-const char *spl_decode_boot_device(u32 boot_device)
-{
-	int i;
-	static const struct {
-		u32 boot_device;
-		const char *ofpath;
-	} spl_boot_devices_tbl[] = {
-		{ BOOT_DEVICE_MMC1, "/dwmmc@fe320000" },
-		{ BOOT_DEVICE_MMC2, "/sdhci@fe330000" },
-		{ BOOT_DEVICE_SPI, "/spi@ff1d0000" },
-	};
-
-	for (i = 0; i < ARRAY_SIZE(spl_boot_devices_tbl); ++i)
-		if (spl_boot_devices_tbl[i].boot_device == boot_device)
-			return spl_boot_devices_tbl[i].ofpath;
-
-	return NULL;
-}
-
-void spl_perform_fixups(struct spl_image_info *spl_image)
-{
-	void *blob = spl_image->fdt_addr;
-	const char *boot_ofpath;
-	int chosen;
-
-	/*
-	 * Inject the ofpath of the device the full U-Boot (or Linux in
-	 * Falcon-mode) was booted from into the FDT, if a FDT has been
-	 * loaded at the same time.
-	 */
-	if (!blob)
-		return;
-
-	boot_ofpath = spl_decode_boot_device(spl_image->boot_device);
-	if (!boot_ofpath) {
-		pr_err("%s: could not map boot_device to ofpath\n", __func__);
-		return;
-	}
-
-	chosen = fdt_find_or_add_subnode(blob, 0, "chosen");
-	if (chosen < 0) {
-		pr_err("%s: could not find/create '/chosen'\n", __func__);
-		return;
-	}
-	fdt_setprop_string(blob, chosen,
-			   "u-boot,spl-boot-device", boot_ofpath);
-}
-
-__weak void rockchip_stimer_init(void)
-{
-}
-
-void board_init_f(ulong dummy)
-{
-	struct udevice *dev;
-	struct rk3399_pmusgrf_regs *sgrf;
-	struct rk3399_grf_regs *grf;
-	int ret;
-
-#ifdef CONFIG_DEBUG_UART
-	debug_uart_init();
-
-# ifdef CONFIG_TARGET_CHROMEBOOK_BOB
-	int sum, i;
-
-	/*
-	 * Add a delay and ensure that the compiler does not optimise this out.
-	 * This is needed since the power rails tail a while to turn on, and
-	 * we get garbage serial output otherwise.
-	 */
-	sum = 0;
-	for (i = 0; i < 150000; i++)
-		sum += i;
-	gru_dummy_function(sum);
-#endif /* CONFIG_TARGET_CHROMEBOOK_BOB */
-
-	/*
-	 * Debug UART can be used from here if required:
-	 *
-	 * debug_uart_init();
-	 * printch('a');
-	 * printhex8(0x1234);
-	 * printascii("string");
-	 */
-	debug("U-Boot SPL board init\n");
-#endif
-
-	ret = spl_early_init();
-	if (ret) {
-		debug("spl_early_init() failed: %d\n", ret);
-		hang();
-	}
-
-	/*
-	 * Disable DDR and SRAM security regions.
-	 *
-	 * As we are entered from the BootROM, the region from
-	 * 0x0 through 0xfffff (i.e. the first MB of memory) will
-	 * be protected. This will cause issues with the DW_MMC
-	 * driver, which tries to DMA from/to the stack (likely)
-	 * located in this range.
-	 */
-	sgrf = syscon_get_first_range(ROCKCHIP_SYSCON_PMUSGRF);
-	rk_clrsetreg(&sgrf->ddr_rgn_con[16], 0x1ff, 0);
-	rk_clrreg(&sgrf->slv_secure_con4, 0x2000);
-
-	/*  eMMC clock generator: disable the clock multipilier */
-	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
-	rk_clrreg(&grf->emmccore_con[11], 0x0ff);
-
-	rockchip_stimer_init();
-
-	ret = uclass_get_device(UCLASS_RAM, 0, &dev);
-	if (ret) {
-		pr_err("DRAM init failed: %d\n", ret);
-		return;
-	}
-}
-
-#if defined(SPL_GPIO_SUPPORT)
-static void rk3399_force_power_on_reset(void)
-{
-	ofnode node;
-	struct gpio_desc sysreset_gpio;
-
-	debug("%s: trying to force a power-on reset\n", __func__);
-
-	node = ofnode_path("/config");
-	if (!ofnode_valid(node)) {
-		debug("%s: no /config node?\n", __func__);
-		return;
-	}
-
-	if (gpio_request_by_name_nodev(node, "sysreset-gpio", 0,
-				       &sysreset_gpio, GPIOD_IS_OUT)) {
-		debug("%s: could not find a /config/sysreset-gpio\n", __func__);
-		return;
-	}
-
-	dm_gpio_set_value(&sysreset_gpio, 1);
-}
-#endif
-
-void spl_board_init(void)
-{
-#if defined(SPL_GPIO_SUPPORT)
-	struct rk3399_cru *cru = rockchip_get_cru();
-
-	/*
-	 * The RK3399 resets only 'almost all logic' (see also in the TRM
-	 * "3.9.4 Global software reset"), when issuing a software reset.
-	 * This may cause issues during boot-up for some configurations of
-	 * the application software stack.
-	 *
-	 * To work around this, we test whether the last reset reason was
-	 * a power-on reset and (if not) issue an overtemp-reset to reset
-	 * the entire module.
-	 *
-	 * While this was previously fixed by modifying the various places
-	 * that could generate a software reset (e.g. U-Boot's sysreset
-	 * driver, the ATF or Linux), we now have it here to ensure that
-	 * we no longer have to track this through the various components.
-	 */
-	if (cru->glb_rst_st != 0)
-		rk3399_force_power_on_reset();
-#endif
-
-#if defined(SPL_DM_REGULATOR)
-	/*
-	 * Turning the eMMC and SPI back on (if disabled via the Qseven
-	 * BIOS_ENABLE) signal is done through a always-on regulator).
-	 */
-	if (regulators_enable_boot_on(false))
-		debug("%s: Cannot enable boot on regulator\n", __func__);
-#endif
-
-	preloader_console_init();
-}
-
-#ifdef CONFIG_SPL_LOAD_FIT
-int board_fit_config_name_match(const char *name)
-{
-	/* Just empty function now - can't decide what to choose */
-	debug("%s: %s\n", __func__, name);
-
-	return 0;
-}
-#endif
diff --git a/arch/arm/mach-rockchip/rk3399-board.c b/arch/arm/mach-rockchip/rk3399-board.c
deleted file mode 100644
index 443c87c..0000000
--- a/arch/arm/mach-rockchip/rk3399-board.c
+++ /dev/null
@@ -1,13 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright (c) 2017 Rockchip Electronics Co., Ltd
- */
-
-#include <common.h>
-#include <asm/arch-rockchip/boot_mode.h>
-
-int board_late_init(void)
-{
-	setup_boot_mode();
-	return 0;
-}
diff --git a/arch/arm/mach-rockchip/rk3399/rk3399.c b/arch/arm/mach-rockchip/rk3399/rk3399.c
index 0f09ea5..863024d 100644
--- a/arch/arm/mach-rockchip/rk3399/rk3399.c
+++ b/arch/arm/mach-rockchip/rk3399/rk3399.c
@@ -4,18 +4,29 @@
  */
 
 #include <common.h>
+#include <spl.h>
 #include <spl_gpio.h>
+#include <syscon.h>
 #include <asm/armv8/mmu.h>
 #include <asm/io.h>
+#include <asm/arch-rockchip/bootrom.h>
+#include <asm/arch-rockchip/clock.h>
 #include <asm/arch-rockchip/gpio.h>
 #include <asm/arch-rockchip/grf_rk3399.h>
 #include <asm/arch-rockchip/hardware.h>
+#include <power/regulator.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
 #define GRF_EMMCCORE_CON11 0xff77f02c
 #define GRF_BASE	0xff770000
 
+const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = {
+	[BROM_BOOTSOURCE_EMMC] = "/sdhci@fe330000",
+	[BROM_BOOTSOURCE_SPINOR] = "/spi@ff1d0000",
+	[BROM_BOOTSOURCE_SD] = "/dwmmc@fe320000",
+};
+
 static struct mm_region rk3399_mem_map[] = {
 	{
 		.virt = 0x0UL,
@@ -67,24 +78,30 @@
 }
 #endif
 
-int dram_init_banksize(void)
-{
-	size_t max_size = min((unsigned long)gd->ram_size, gd->ram_top);
-
-	/* Reserve 0x200000 for ATF bl31 */
-	gd->bd->bi_dram[0].start = 0x200000;
-	gd->bd->bi_dram[0].size = max_size - gd->bd->bi_dram[0].start;
-
-	return 0;
-}
-
 int arch_cpu_init(void)
 {
-	/* We do some SoC one time setting here. */
-	struct rk3399_grf_regs * const grf = (void *)GRF_BASE;
 
-	/* Emmc clock generator: disable the clock multipilier */
+#ifdef CONFIG_SPL_BUILD
+	struct rk3399_pmusgrf_regs *sgrf;
+	struct rk3399_grf_regs *grf;
+
+	/*
+	 * Disable DDR and SRAM security regions.
+	 *
+	 * As we are entered from the BootROM, the region from
+	 * 0x0 through 0xfffff (i.e. the first MB of memory) will
+	 * be protected. This will cause issues with the DW_MMC
+	 * driver, which tries to DMA from/to the stack (likely)
+	 * located in this range.
+	 */
+	sgrf = syscon_get_first_range(ROCKCHIP_SYSCON_PMUSGRF);
+	rk_clrsetreg(&sgrf->ddr_rgn_con[16], 0x1ff, 0);
+	rk_clrreg(&sgrf->slv_secure_con4, 0x2000);
+
+	/*  eMMC clock generator: disable the clock multipilier */
+	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
 	rk_clrreg(&grf->emmccore_con[11], 0x0ff);
+#endif
 
 	return 0;
 }
@@ -146,3 +163,111 @@
 #endif
 }
 #endif
+
+#if defined(CONFIG_SPL_BUILD) && !defined(CONFIG_TPL_BUILD)
+const char *spl_decode_boot_device(u32 boot_device)
+{
+	int i;
+	static const struct {
+		u32 boot_device;
+		const char *ofpath;
+	} spl_boot_devices_tbl[] = {
+		{ BOOT_DEVICE_MMC1, "/dwmmc@fe320000" },
+		{ BOOT_DEVICE_MMC2, "/sdhci@fe330000" },
+		{ BOOT_DEVICE_SPI, "/spi@ff1d0000" },
+	};
+
+	for (i = 0; i < ARRAY_SIZE(spl_boot_devices_tbl); ++i)
+		if (spl_boot_devices_tbl[i].boot_device == boot_device)
+			return spl_boot_devices_tbl[i].ofpath;
+
+	return NULL;
+}
+
+void spl_perform_fixups(struct spl_image_info *spl_image)
+{
+	void *blob = spl_image->fdt_addr;
+	const char *boot_ofpath;
+	int chosen;
+
+	/*
+	 * Inject the ofpath of the device the full U-Boot (or Linux in
+	 * Falcon-mode) was booted from into the FDT, if a FDT has been
+	 * loaded at the same time.
+	 */
+	if (!blob)
+		return;
+
+	boot_ofpath = spl_decode_boot_device(spl_image->boot_device);
+	if (!boot_ofpath) {
+		pr_err("%s: could not map boot_device to ofpath\n", __func__);
+		return;
+	}
+
+	chosen = fdt_find_or_add_subnode(blob, 0, "chosen");
+	if (chosen < 0) {
+		pr_err("%s: could not find/create '/chosen'\n", __func__);
+		return;
+	}
+	fdt_setprop_string(blob, chosen,
+			   "u-boot,spl-boot-device", boot_ofpath);
+}
+
+#if defined(SPL_GPIO_SUPPORT)
+static void rk3399_force_power_on_reset(void)
+{
+	ofnode node;
+	struct gpio_desc sysreset_gpio;
+
+	debug("%s: trying to force a power-on reset\n", __func__);
+
+	node = ofnode_path("/config");
+	if (!ofnode_valid(node)) {
+		debug("%s: no /config node?\n", __func__);
+		return;
+	}
+
+	if (gpio_request_by_name_nodev(node, "sysreset-gpio", 0,
+				       &sysreset_gpio, GPIOD_IS_OUT)) {
+		debug("%s: could not find a /config/sysreset-gpio\n", __func__);
+		return;
+	}
+
+	dm_gpio_set_value(&sysreset_gpio, 1);
+}
+#endif
+
+void spl_board_init(void)
+{
+#if defined(SPL_GPIO_SUPPORT)
+	struct rk3399_cru *cru = rockchip_get_cru();
+
+	/*
+	 * The RK3399 resets only 'almost all logic' (see also in the TRM
+	 * "3.9.4 Global software reset"), when issuing a software reset.
+	 * This may cause issues during boot-up for some configurations of
+	 * the application software stack.
+	 *
+	 * To work around this, we test whether the last reset reason was
+	 * a power-on reset and (if not) issue an overtemp-reset to reset
+	 * the entire module.
+	 *
+	 * While this was previously fixed by modifying the various places
+	 * that could generate a software reset (e.g. U-Boot's sysreset
+	 * driver, the ATF or Linux), we now have it here to ensure that
+	 * we no longer have to track this through the various components.
+	 */
+	if (cru->glb_rst_st != 0)
+		rk3399_force_power_on_reset();
+#endif
+
+#if defined(SPL_DM_REGULATOR)
+	/*
+	 * Turning the eMMC and SPI back on (if disabled via the Qseven
+	 * BIOS_ENABLE) signal is done through a always-on regulator).
+	 */
+	if (regulators_enable_boot_on(false))
+		debug("%s: Cannot enable boot on regulator\n", __func__);
+#endif
+}
+#endif
diff --git a/arch/arm/mach-rockchip/rv1108-board.c b/arch/arm/mach-rockchip/rv1108-board.c
deleted file mode 100644
index 3412f2c..0000000
--- a/arch/arm/mach-rockchip/rv1108-board.c
+++ /dev/null
@@ -1,81 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * (C) Copyright 2015 Google, Inc
- */
-
-#include <common.h>
-
-DECLARE_GLOBAL_DATA_PTR;
-
-#if defined(CONFIG_USB_GADGET) && defined(CONFIG_USB_GADGET_DWC2_OTG)
-#include <usb.h>
-#include <usb/dwc2_udc.h>
-
-static struct dwc2_plat_otg_data rv1108_otg_data = {
-	.rx_fifo_sz	= 512,
-	.np_tx_fifo_sz	= 16,
-	.tx_fifo_sz	= 128,
-};
-
-int board_usb_init(int index, enum usb_init_type init)
-{
-	const void *blob = gd->fdt_blob;
-	bool matched = false;
-	int node, phy_node;
-	u32 grf_phy_offset;
-	const char *mode;
-
-	/* find the usb_otg node */
-	node = fdt_node_offset_by_compatible(blob, -1, "rockchip,rk3066-usb");
-	while (node > 0) {
-		mode = fdt_getprop(blob, node, "dr_mode", NULL);
-		if (mode && strcmp(mode, "otg") == 0) {
-			matched = true;
-			break;
-		}
-
-		node = fdt_node_offset_by_compatible(blob, node,
-						     "rockchip,rk3066-usb");
-	}
-
-	if (!matched) {
-		debug("usb_otg device not found\n");
-		return -ENODEV;
-	}
-
-	rv1108_otg_data.regs_otg = fdtdec_get_addr(blob, node, "reg");
-
-	node = fdtdec_lookup_phandle(blob, node, "phys");
-	if (node <= 0) {
-		debug("phys node not found\n");
-		return -ENODEV;
-	}
-
-	phy_node = fdt_parent_offset(blob, node);
-	if (phy_node <= 0) {
-		debug("usb phy node not found\n");
-		return -ENODEV;
-	}
-
-	rv1108_otg_data.phy_of_node = phy_node;
-	grf_phy_offset = fdtdec_get_addr(blob, node, "reg");
-
-	/* find the grf node */
-	node = fdt_node_offset_by_compatible(blob, -1,
-					     "rockchip,rv1108-grf");
-	if (node <= 0) {
-		debug("grf node not found\n");
-		return -ENODEV;
-	}
-
-	rv1108_otg_data.regs_phy = grf_phy_offset + fdtdec_get_addr(blob, node,
-								    "reg");
-
-	return dwc2_udc_probe(&rv1108_otg_data);
-}
-
-int board_usb_cleanup(int index, enum usb_init_type init)
-{
-	return 0;
-}
-#endif
diff --git a/arch/arm/mach-rockchip/rv1108/rv1108.c b/arch/arm/mach-rockchip/rv1108/rv1108.c
index 66aeb3f..6362af9 100644
--- a/arch/arm/mach-rockchip/rv1108/rv1108.c
+++ b/arch/arm/mach-rockchip/rv1108/rv1108.c
@@ -3,13 +3,3 @@
  * (C) Copyright 2016 Rockchip Electronics Co., Ltd
  * Author: Andy Yan <andy.yan@rock-chips.com>
  */
-
-#include <common.h>
-
-#if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
-void enable_caches(void)
-{
-	/* Enable D-cache. I-cache is already enabled in start.S */
-	dcache_enable();
-}
-#endif
diff --git a/arch/arm/mach-rockchip/sdram_common.c b/arch/arm/mach-rockchip/sdram_common.c
index 8684dbd..22a4aca 100644
--- a/arch/arm/mach-rockchip/sdram_common.c
+++ b/arch/arm/mach-rockchip/sdram_common.c
@@ -11,6 +11,69 @@
 #include <dm/uclass-internal.h>
 
 DECLARE_GLOBAL_DATA_PTR;
+
+#define TRUST_PARAMETER_OFFSET    (34 * 1024 * 1024)
+
+struct tos_parameter_t {
+	u32 version;
+	u32 checksum;
+	struct {
+		char name[8];
+		s64 phy_addr;
+		u32 size;
+		u32 flags;
+	} tee_mem;
+	struct {
+		char name[8];
+		s64 phy_addr;
+		u32 size;
+		u32 flags;
+	} drm_mem;
+	s64 reserve[8];
+};
+
+int dram_init_banksize(void)
+{
+	size_t top = min((unsigned long)(gd->ram_size + CONFIG_SYS_SDRAM_BASE),
+			 gd->ram_top);
+
+#ifdef CONFIG_ARM64
+	/* Reserve 0x200000 for ATF bl31 */
+	gd->bd->bi_dram[0].start = 0x200000;
+	gd->bd->bi_dram[0].size = top - gd->bd->bi_dram[0].start;
+#else
+#ifdef CONFIG_SPL_OPTEE
+	struct tos_parameter_t *tos_parameter;
+
+	tos_parameter = (struct tos_parameter_t *)(CONFIG_SYS_SDRAM_BASE +
+			TRUST_PARAMETER_OFFSET);
+
+	if (tos_parameter->tee_mem.flags == 1) {
+		gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
+		gd->bd->bi_dram[0].size = tos_parameter->tee_mem.phy_addr
+					- CONFIG_SYS_SDRAM_BASE;
+		gd->bd->bi_dram[1].start = tos_parameter->tee_mem.phy_addr +
+					tos_parameter->tee_mem.size;
+		gd->bd->bi_dram[1].size = gd->bd->bi_dram[0].start
+					+ top - gd->bd->bi_dram[1].start;
+	} else {
+		gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
+		gd->bd->bi_dram[0].size = 0x8400000;
+		/* Reserve 32M for OPTEE with TA */
+		gd->bd->bi_dram[1].start = CONFIG_SYS_SDRAM_BASE
+					+ gd->bd->bi_dram[0].size + 0x2000000;
+		gd->bd->bi_dram[1].size = gd->bd->bi_dram[0].start
+					+ top - gd->bd->bi_dram[1].start;
+	}
+#else
+	gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
+	gd->bd->bi_dram[0].size = top - gd->bd->bi_dram[0].start;
+#endif
+#endif
+
+	return 0;
+}
+
 size_t rockchip_sdram_size(phys_addr_t reg)
 {
 	u32 rank, col, bk, cs0_row, cs1_row, bw, row_3_4;
diff --git a/arch/arm/mach-rockchip/spl.c b/arch/arm/mach-rockchip/spl.c
new file mode 100644
index 0000000..33137cc
--- /dev/null
+++ b/arch/arm/mach-rockchip/spl.c
@@ -0,0 +1,154 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2019 Rockchip Electronics Co., Ltd
+ */
+
+#include <common.h>
+#include <debug_uart.h>
+#include <dm.h>
+#include <ram.h>
+#include <spl.h>
+#include <asm/arch-rockchip/bootrom.h>
+#include <asm/arch-rockchip/sdram.h>
+#include <asm/io.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void board_return_to_bootrom(void)
+{
+	back_to_bootrom(BROM_BOOT_NEXTSTAGE);
+}
+
+__weak const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = {
+};
+
+const char *board_spl_was_booted_from(void)
+{
+	u32  bootdevice_brom_id = readl(BROM_BOOTSOURCE_ID_ADDR);
+	const char *bootdevice_ofpath = NULL;
+
+	if (bootdevice_brom_id < ARRAY_SIZE(boot_devices))
+		bootdevice_ofpath = boot_devices[bootdevice_brom_id];
+
+	if (bootdevice_ofpath)
+		debug("%s: brom_bootdevice_id %x maps to '%s'\n",
+		      __func__, bootdevice_brom_id, bootdevice_ofpath);
+	else
+		debug("%s: failed to resolve brom_bootdevice_id %x\n",
+		      __func__, bootdevice_brom_id);
+
+	return bootdevice_ofpath;
+}
+
+u32 spl_boot_device(void)
+{
+	u32 boot_device = BOOT_DEVICE_MMC1;
+
+#if defined(CONFIG_TARGET_CHROMEBOOK_JERRY) || \
+		defined(CONFIG_TARGET_CHROMEBIT_MICKEY) || \
+		defined(CONFIG_TARGET_CHROMEBOOK_MINNIE)
+	return BOOT_DEVICE_SPI;
+#endif
+	if (CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM))
+		return BOOT_DEVICE_BOOTROM;
+
+	return boot_device;
+}
+
+u32 spl_boot_mode(const u32 boot_device)
+{
+	return MMCSD_MODE_RAW;
+}
+
+#if !defined(CONFIG_ROCKCHIP_RK3188)
+#define TIMER_LOAD_COUNT_L	0x00
+#define TIMER_LOAD_COUNT_H	0x04
+#define TIMER_CONTROL_REG	0x10
+#define TIMER_EN	0x1
+#define	TIMER_FMODE	BIT(0)
+#define	TIMER_RMODE	BIT(1)
+
+__weak void rockchip_stimer_init(void)
+{
+	/* If Timer already enabled, don't re-init it */
+	u32 reg = readl(CONFIG_ROCKCHIP_STIMER_BASE + TIMER_CONTROL_REG);
+
+	if (reg & TIMER_EN)
+		return;
+#ifndef CONFIG_ARM64
+	asm volatile("mcr p15, 0, %0, c14, c0, 0"
+		     : : "r"(COUNTER_FREQUENCY));
+#endif
+	writel(0, CONFIG_ROCKCHIP_STIMER_BASE + TIMER_CONTROL_REG);
+	writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE);
+	writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE + 4);
+	writel(TIMER_EN | TIMER_FMODE, CONFIG_ROCKCHIP_STIMER_BASE +
+	       TIMER_CONTROL_REG);
+}
+#endif
+
+__weak int board_early_init_f(void)
+{
+	return 0;
+}
+
+__weak int arch_cpu_init(void)
+{
+	return 0;
+}
+
+void board_init_f(ulong dummy)
+{
+	int ret;
+#if !defined(CONFIG_SUPPORT_TPL) || defined(CONFIG_SPL_OS_BOOT)
+	struct udevice *dev;
+#endif
+
+#ifdef CONFIG_DEBUG_UART
+	/*
+	 * Debug UART can be used from here if required:
+	 *
+	 * debug_uart_init();
+	 * printch('a');
+	 * printhex8(0x1234);
+	 * printascii("string");
+	 */
+	debug_uart_init();
+	debug("\nspl:debug uart enabled in %s\n", __func__);
+#endif
+
+	board_early_init_f();
+
+	ret = spl_early_init();
+	if (ret) {
+		printf("spl_early_init() failed: %d\n", ret);
+		hang();
+	}
+	arch_cpu_init();
+#if !defined(CONFIG_SUPPORT_TPL) || defined(CONFIG_SPL_OS_BOOT)
+	debug("\nspl:init dram\n");
+	ret = uclass_get_device(UCLASS_RAM, 0, &dev);
+	if (ret) {
+		printf("DRAM init failed: %d\n", ret);
+		return;
+	}
+#endif
+#if !defined(CONFIG_ROCKCHIP_RK3188)
+	rockchip_stimer_init();
+#endif
+#ifdef CONFIG_SYS_ARCH_TIMER
+	/* Init ARM arch timer in arch/arm/cpu/armv7/arch_timer.c */
+	timer_init();
+#endif
+	preloader_console_init();
+}
+
+#ifdef CONFIG_SPL_LOAD_FIT
+int board_fit_config_name_match(const char *name)
+{
+	/* Just empty function now - can't decide what to choose */
+	debug("%s: %s\n", __func__, name);
+
+	return 0;
+}
+#endif
diff --git a/arch/arm/mach-socfpga/Makefile b/arch/arm/mach-socfpga/Makefile
index e667204..fc1181c 100644
--- a/arch/arm/mach-socfpga/Makefile
+++ b/arch/arm/mach-socfpga/Makefile
@@ -8,7 +8,6 @@
 obj-y	+= board.o
 obj-y	+= clock_manager.o
 obj-y	+= misc.o
-obj-y	+= reset_manager.o
 
 ifdef CONFIG_TARGET_SOCFPGA_GEN5
 obj-y	+= clock_manager_gen5.o
diff --git a/arch/arm/mach-socfpga/include/mach/reset_manager.h b/arch/arm/mach-socfpga/include/mach/reset_manager.h
index 42beaec..6ad037e 100644
--- a/arch/arm/mach-socfpga/include/mach/reset_manager.h
+++ b/arch/arm/mach-socfpga/include/mach/reset_manager.h
@@ -11,6 +11,7 @@
 void socfpga_per_reset(u32 reset, int set);
 void socfpga_per_reset_all(void);
 
+#define RSTMGR_CTRL_SWCOLDRSTREQ_LSB 0
 #define RSTMGR_CTRL_SWWARMRSTREQ_LSB 1
 
 /*
diff --git a/arch/arm/mach-socfpga/reset_manager.c b/arch/arm/mach-socfpga/reset_manager.c
deleted file mode 100644
index e0a01ed..0000000
--- a/arch/arm/mach-socfpga/reset_manager.c
+++ /dev/null
@@ -1,41 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- *  Copyright (C) 2013 Altera Corporation <www.altera.com>
- */
-
-
-#include <common.h>
-#include <asm/io.h>
-#include <asm/arch/reset_manager.h>
-
-#if defined(CONFIG_TARGET_SOCFPGA_STRATIX10)
-#include <asm/arch/mailbox_s10.h>
-#endif
-
-DECLARE_GLOBAL_DATA_PTR;
-
-#if !defined(CONFIG_TARGET_SOCFPGA_STRATIX10)
-static const struct socfpga_reset_manager *reset_manager_base =
-		(void *)SOCFPGA_RSTMGR_ADDRESS;
-#endif
-
-/*
- * Write the reset manager register to cause reset
- */
-void reset_cpu(ulong addr)
-{
-	/* request a warm reset */
-#if defined(CONFIG_TARGET_SOCFPGA_STRATIX10)
-	puts("Mailbox: Issuing mailbox cmd REBOOT_HPS\n");
-	mbox_reset_cold();
-#else
-	writel(1 << RSTMGR_CTRL_SWWARMRSTREQ_LSB,
-	       &reset_manager_base->ctrl);
-#endif
-	/*
-	 * infinite loop here as watchdog will trigger and reset
-	 * the processor
-	 */
-	while (1)
-		;
-}
diff --git a/board/chipspark/popmetal_rk3288/popmetal-rk3288.c b/board/chipspark/popmetal_rk3288/popmetal-rk3288.c
index 9ba1fbd..47b921a 100644
--- a/board/chipspark/popmetal_rk3288/popmetal-rk3288.c
+++ b/board/chipspark/popmetal_rk3288/popmetal-rk3288.c
@@ -8,7 +8,7 @@
 
 #define GPIO7A3_HUB_RST	227
 
-int rk_board_late_init(void)
+int rk3288_board_late_init(void)
 {
 	int ret;
 
diff --git a/board/elgin/elgin_rv1108/elgin_rv1108.c b/board/elgin/elgin_rv1108/elgin_rv1108.c
index 0de1f42..607667a 100644
--- a/board/elgin/elgin_rv1108/elgin_rv1108.c
+++ b/board/elgin/elgin_rv1108/elgin_rv1108.c
@@ -50,7 +50,7 @@
 
 #define MODEM_ENABLE_GPIO 111
 
-int board_init(void)
+int board_early_init_f(void)
 {
 	gpio_request(MODEM_ENABLE_GPIO, "modem_enable");
 	gpio_direction_output(MODEM_ENABLE_GPIO, 0);
diff --git a/board/firefly/firefly-rk3288/firefly-rk3288.c b/board/firefly/firefly-rk3288/firefly-rk3288.c
index bdc02a6..a3f784f 100644
--- a/board/firefly/firefly-rk3288/firefly-rk3288.c
+++ b/board/firefly/firefly-rk3288/firefly-rk3288.c
@@ -4,3 +4,39 @@
  */
 
 #include <common.h>
+
+#ifdef CONFIG_SPL_BUILD
+static int setup_led(void)
+{
+#ifdef CONFIG_SPL_LED
+	struct udevice *dev;
+	char *led_name;
+	int ret;
+
+	led_name = fdtdec_get_config_string(gd->fdt_blob, "u-boot,boot-led");
+	if (!led_name)
+		return 0;
+	ret = led_get_by_label(led_name, &dev);
+	if (ret) {
+		debug("%s: get=%d\n", __func__, ret);
+		return ret;
+	}
+	ret = led_set_on(dev, 1);
+	if (ret)
+		return ret;
+#endif
+
+	return 0;
+}
+
+void spl_board_init(void)
+{
+	int ret;
+
+	ret = setup_led();
+	if (ret) {
+		debug("LED ret=%d\n", ret);
+		hang();
+	}
+}
+#endif
diff --git a/board/freescale/ls1021aiot/dcu.c b/board/freescale/ls1021aiot/dcu.c
index 9aeee0e..77732a6 100644
--- a/board/freescale/ls1021aiot/dcu.c
+++ b/board/freescale/ls1021aiot/dcu.c
@@ -23,9 +23,10 @@
 	return div;
 }
 
-int platform_dcu_init(unsigned int xres, unsigned int yres,
-		const char *port,
-		struct fb_videomode *dcu_fb_videomode)
+int platform_dcu_init(struct fb_info *fbinfo,
+		      unsigned int xres, unsigned int yres,
+		      const char *port,
+		      struct fb_videomode *dcu_fb_videomode)
 {
 	const char *name;
 	unsigned int pixel_format;
@@ -40,7 +41,7 @@
 	printf("DCU: Switching to %s monitor @ %ux%u\n", name, xres, yres);
 
 	pixel_format = 32;
-	fsl_dcu_init(xres, yres, pixel_format);
+	fsl_dcu_init(fbinfo, xres, yres, pixel_format);
 
 	return 0;
 }
diff --git a/board/freescale/ls1021aqds/dcu.c b/board/freescale/ls1021aqds/dcu.c
index 14855ea..c4eac5e 100644
--- a/board/freescale/ls1021aqds/dcu.c
+++ b/board/freescale/ls1021aqds/dcu.c
@@ -39,7 +39,9 @@
 	return div;
 }
 
-int platform_dcu_init(unsigned int xres, unsigned int yres,
+int platform_dcu_init(struct fb_info *fbinfo,
+		      unsigned int xres,
+		      unsigned int yres,
 		      const char *port,
 		      struct fb_videomode *dcu_fb_videomode)
 {
@@ -85,7 +87,7 @@
 	printf("DCU: Switching to %s monitor @ %ux%u\n", name, xres, yres);
 
 	pixel_format = 32;
-	fsl_dcu_init(xres, yres, pixel_format);
+	fsl_dcu_init(fbinfo, xres, yres, pixel_format);
 
 	return 0;
 }
diff --git a/board/freescale/ls1021atwr/dcu.c b/board/freescale/ls1021atwr/dcu.c
index e1191f1..bdf7f76 100644
--- a/board/freescale/ls1021atwr/dcu.c
+++ b/board/freescale/ls1021atwr/dcu.c
@@ -23,7 +23,8 @@
 	return div;
 }
 
-int platform_dcu_init(unsigned int xres, unsigned int yres,
+int platform_dcu_init(struct fb_info *fbinfo,
+		      unsigned int xres, unsigned int yres,
 		      const char *port,
 		      struct fb_videomode *dcu_fb_videomode)
 {
@@ -40,7 +41,7 @@
 	printf("DCU: Switching to %s monitor @ %ux%u\n", name, xres, yres);
 
 	pixel_format = 32;
-	fsl_dcu_init(xres, yres, pixel_format);
+	fsl_dcu_init(fbinfo, xres, yres, pixel_format);
 
 	return 0;
 }
diff --git a/board/geekbuying/geekbox/geekbox.c b/board/geekbuying/geekbox/geekbox.c
index 10b04a1..b0f9a5f 100644
--- a/board/geekbuying/geekbox/geekbox.c
+++ b/board/geekbuying/geekbox/geekbox.c
@@ -4,8 +4,3 @@
  */
 
 #include <common.h>
-
-int board_init(void)
-{
-	return 0;
-}
diff --git a/board/google/gru/gru.c b/board/google/gru/gru.c
index b116b1a..b6b4f19 100644
--- a/board/google/gru/gru.c
+++ b/board/google/gru/gru.c
@@ -5,12 +5,28 @@
 
 #include <common.h>
 
-int board_init(void)
-{
-	return 0;
-}
-
+#ifdef CONFIG_SPL_BUILD
 /* provided to defeat compiler optimisation in board_init_f() */
 void gru_dummy_function(int i)
 {
 }
+
+int board_early_init_f(void)
+{
+# ifdef CONFIG_TARGET_CHROMEBOOK_BOB
+	int sum, i;
+
+	/*
+	 * Add a delay and ensure that the compiler does not optimise this out.
+	 * This is needed since the power rails tail a while to turn on, and
+	 * we get garbage serial output otherwise.
+	 */
+	sum = 0;
+	for (i = 0; i < 150000; i++)
+		sum += i;
+	gru_dummy_function(sum);
+#endif /* CONFIG_TARGET_CHROMEBOOK_BOB */
+
+	return 0;
+}
+#endif
diff --git a/board/google/veyron/veyron.c b/board/google/veyron/veyron.c
index 19edb18..dd2c014 100644
--- a/board/google/veyron/veyron.c
+++ b/board/google/veyron/veyron.c
@@ -3,10 +3,93 @@
  * (C) Copyright 2015 Google, Inc
  */
 
+#include <clk.h>
 #include <common.h>
+#include <dm.h>
+#include <asm/arch-rockchip/clock.h>
+#include <dt-bindings/clock/rk3288-cru.h>
+#include <power/regulator.h>
 
 /*
  * We should increase the DDR voltage to 1.2V using the PWM regulator.
  * There is a U-Boot driver for this but it may need to add support for the
  * 'voltage-table' property.
  */
+#ifndef CONFIG_SPL_BUILD
+#if !CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM)
+static int veyron_init(void)
+{
+	struct udevice *dev;
+	struct clk clk;
+	int ret;
+
+	ret = regulator_get_by_platname("vdd_arm", &dev);
+	if (ret) {
+		debug("Cannot set regulator name\n");
+		return ret;
+	}
+
+	/* Slowly raise to max CPU voltage to prevent overshoot */
+	ret = regulator_set_value(dev, 1200000);
+	if (ret)
+		return ret;
+	udelay(175); /* Must wait for voltage to stabilize, 2mV/us */
+	ret = regulator_set_value(dev, 1400000);
+	if (ret)
+		return ret;
+	udelay(100); /* Must wait for voltage to stabilize, 2mV/us */
+
+	ret = rockchip_get_clk(&clk.dev);
+	if (ret)
+		return ret;
+	clk.id = PLL_APLL;
+	ret = clk_set_rate(&clk, 1800000000);
+	if (IS_ERR_VALUE(ret))
+		return ret;
+
+	ret = regulator_get_by_platname("vcc33_sd", &dev);
+	if (ret) {
+		debug("Cannot get regulator name\n");
+		return ret;
+	}
+
+	ret = regulator_set_value(dev, 3300000);
+	if (ret)
+		return ret;
+
+	ret = regulators_enable_boot_on(false);
+	if (ret) {
+		debug("%s: Cannot enable boot on regulators\n", __func__);
+		return ret;
+	}
+
+	return 0;
+}
+#endif
+
+int board_early_init_f(void)
+{
+	struct udevice *dev;
+	int ret;
+
+#if !CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM)
+	if (!fdt_node_check_compatible(gd->fdt_blob, 0, "google,veyron")) {
+		ret = veyron_init();
+		if (ret)
+			return ret;
+	}
+#endif
+	/*
+	 * This init is done in SPL, but when chain-loading U-Boot SPL will
+	 * have been skipped. Allow the clock driver to check if it needs
+	 * setting up.
+	 */
+	ret = rockchip_get_clk(&dev);
+	if (ret) {
+		debug("CLK init failed: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+#endif
diff --git a/board/phytec/phycore_rk3288/phycore-rk3288.c b/board/phytec/phycore_rk3288/phycore-rk3288.c
index ffe1833..92f3bd2 100644
--- a/board/phytec/phycore_rk3288/phycore-rk3288.c
+++ b/board/phytec/phycore_rk3288/phycore-rk3288.c
@@ -8,10 +8,13 @@
 #include <common.h>
 #include <dm.h>
 #include <environment.h>
+#include <fdtdec.h>
 #include <i2c.h>
 #include <i2c_eeprom.h>
 #include <netdev.h>
 #include "som.h"
+#include <power/regulator.h>
+#include <power/rk8xx_pmic.h>
 
 static int valid_rk3288_som(struct rk3288_som *som)
 {
@@ -27,7 +30,7 @@
 	return hw == som->bs;
 }
 
-int rk_board_late_init(void)
+int rk3288_board_late_init(void)
 {
 	int ret;
 	struct udevice *dev;
@@ -68,3 +71,47 @@
 
 	return 0;
 }
+
+#ifdef CONFIG_SPL_BUILD
+#if !defined(CONFIG_SPL_OF_PLATDATA)
+static int phycore_init(void)
+{
+	struct udevice *pmic;
+	int ret;
+
+	ret = uclass_first_device_err(UCLASS_PMIC, &pmic);
+	if (ret)
+		return ret;
+
+#if defined(CONFIG_SPL_POWER_SUPPORT)
+	/* Increase USB input current to 2A */
+	ret = rk818_spl_configure_usb_input_current(pmic, 2000);
+	if (ret)
+		return ret;
+
+	/* Close charger when USB lower then 3.26V */
+	ret = rk818_spl_configure_usb_chrg_shutdown(pmic, 3260000);
+	if (ret)
+		return ret;
+#endif
+
+	return 0;
+}
+#endif
+
+void spl_board_init(void)
+{
+#if !defined(CONFIG_SPL_OF_PLATDATA)
+	int ret;
+
+	if (of_machine_is_compatible("phytec,rk3288-phycore-som")) {
+		ret = phycore_init();
+		if (ret) {
+			debug("Failed to set up phycore power settings: %d\n",
+			      ret);
+			return;
+		}
+	}
+#endif
+}
+#endif
diff --git a/board/rockchip/evb_px5/evb-px5.c b/board/rockchip/evb_px5/evb-px5.c
index 53e753f..b81f970 100644
--- a/board/rockchip/evb_px5/evb-px5.c
+++ b/board/rockchip/evb_px5/evb-px5.c
@@ -2,9 +2,3 @@
 /*
  * Copyright (c) 2017 Andy Yan
  */
-#include <common.h>
-
-int board_init(void)
-{
-	return 0;
-}
diff --git a/board/rockchip/evb_rk3328/evb-rk3328.c b/board/rockchip/evb_rk3328/evb-rk3328.c
index bc9ef5e..779bc64 100644
--- a/board/rockchip/evb_rk3328/evb-rk3328.c
+++ b/board/rockchip/evb_rk3328/evb-rk3328.c
@@ -3,68 +3,3 @@
  * (C) Copyright 2016 Rockchip Electronics Co., Ltd
  */
 
-#include <common.h>
-#include <asm/armv8/mmu.h>
-#include <dwc3-uboot.h>
-#include <power/regulator.h>
-#include <usb.h>
-
-DECLARE_GLOBAL_DATA_PTR;
-
-int board_init(void)
-{
-	int ret;
-
-	ret = regulators_enable_boot_on(false);
-	if (ret)
-		debug("%s: Cannot enable boot on regulator\n", __func__);
-
-	return ret;
-}
-
-#if defined(CONFIG_USB_GADGET) && defined(CONFIG_USB_GADGET_DWC2_OTG)
-#include <usb.h>
-#include <usb/dwc2_udc.h>
-
-static struct dwc2_plat_otg_data rk3328_otg_data = {
-	.rx_fifo_sz	= 512,
-	.np_tx_fifo_sz	= 16,
-	.tx_fifo_sz	= 128,
-};
-
-int board_usb_init(int index, enum usb_init_type init)
-{
-	int node;
-	const char *mode;
-	bool matched = false;
-	const void *blob = gd->fdt_blob;
-
-	/* find the usb_otg node */
-	node = fdt_node_offset_by_compatible(blob, -1,
-					"rockchip,rk3328-usb");
-
-	while (node > 0) {
-		mode = fdt_getprop(blob, node, "dr_mode", NULL);
-		if (mode && strcmp(mode, "otg") == 0) {
-			matched = true;
-			break;
-		}
-
-		node = fdt_node_offset_by_compatible(blob, node,
-					"rockchip,rk3328-usb");
-	}
-	if (!matched) {
-		debug("Not found usb_otg device\n");
-		return -ENODEV;
-	}
-
-	rk3328_otg_data.regs_otg = fdtdec_get_addr(blob, node, "reg");
-
-	return dwc2_udc_probe(&rk3328_otg_data);
-}
-
-int board_usb_cleanup(int index, enum usb_init_type init)
-{
-	return 0;
-}
-#endif
diff --git a/board/rockchip/evb_rk3399/evb-rk3399.c b/board/rockchip/evb_rk3399/evb-rk3399.c
index eb1b832..b9049ab 100644
--- a/board/rockchip/evb_rk3399/evb-rk3399.c
+++ b/board/rockchip/evb_rk3399/evb-rk3399.c
@@ -5,19 +5,15 @@
 
 #include <common.h>
 #include <dm.h>
-#include <dm/pinctrl.h>
 #include <asm/arch-rockchip/periph.h>
 #include <power/regulator.h>
 
-int board_init(void)
+#ifndef CONFIG_SPL_BUILD
+int board_early_init_f(void)
 {
 	struct udevice *regulator;
 	int ret;
 
-	ret = regulators_enable_boot_on(false);
-	if (ret)
-		debug("%s: Cannot enable boot on regulator\n", __func__);
-
 	ret = regulator_get_by_platname("vcc5v0_host", &regulator);
 	if (ret) {
 		debug("%s vcc5v0_host init fail! ret %d\n", __func__, ret);
@@ -25,11 +21,10 @@
 	}
 
 	ret = regulator_set_enable(regulator, true);
-	if (ret) {
-		debug("%s vcc5v0-host-en set fail!\n", __func__);
-		goto out;
-	}
+	if (ret)
+		debug("%s vcc5v0-host-en set fail! ret %d\n", __func__, ret);
 
 out:
 	return 0;
 }
+#endif
diff --git a/board/rockchip/evb_rv1108/evb_rv1108.c b/board/rockchip/evb_rv1108/evb_rv1108.c
index 457b110..733f293 100644
--- a/board/rockchip/evb_rv1108/evb_rv1108.c
+++ b/board/rockchip/evb_rv1108/evb_rv1108.c
@@ -47,23 +47,9 @@
 	return 0;
 }
 
-
-int board_init(void)
-{
-	return 0;
-}
-
 int dram_init(void)
 {
 	gd->ram_size = 0x8000000;
 
 	return 0;
 }
-
-int dram_init_banksize(void)
-{
-	gd->bd->bi_dram[0].start = 0x60000000;
-	gd->bd->bi_dram[0].size = 0x8000000;
-
-	return 0;
-}
diff --git a/board/rockchip/sheep_rk3368/sheep_rk3368.c b/board/rockchip/sheep_rk3368/sheep_rk3368.c
index 9bb93c7..b81f970 100644
--- a/board/rockchip/sheep_rk3368/sheep_rk3368.c
+++ b/board/rockchip/sheep_rk3368/sheep_rk3368.c
@@ -2,18 +2,3 @@
 /*
  * Copyright (c) 2017 Andy Yan
  */
-#include <common.h>
-#include <asm/io.h>
-#include <asm/arch-rockchip/clock.h>
-#include <asm/arch-rockchip/grf_rk3368.h>
-#include <syscon.h>
-
-int mach_cpu_init(void)
-{
-	return 0;
-}
-
-int board_init(void)
-{
-	return 0;
-}
diff --git a/board/rockchip/tinker_rk3288/tinker-rk3288.c b/board/rockchip/tinker_rk3288/tinker-rk3288.c
index 44f1318..e6b018d 100644
--- a/board/rockchip/tinker_rk3288/tinker-rk3288.c
+++ b/board/rockchip/tinker_rk3288/tinker-rk3288.c
@@ -21,7 +21,7 @@
 	return i2c_eeprom_read(dev, 0, addr, 6);
 }
 
-int rk_board_late_init(void)
+int rk3288_board_late_init(void)
 {
 	u8 ethaddr[6];
 
diff --git a/board/theobroma-systems/lion_rk3368/lion_rk3368.c b/board/theobroma-systems/lion_rk3368/lion_rk3368.c
index 6cd5a5f..1b0d504 100644
--- a/board/theobroma-systems/lion_rk3368/lion_rk3368.c
+++ b/board/theobroma-systems/lion_rk3368/lion_rk3368.c
@@ -2,21 +2,3 @@
 /*
  * Copyright (c) 2017 Theobroma Systems Design und Consulting GmbH
  */
-#include <common.h>
-#include <dm.h>
-#include <ram.h>
-#include <asm/io.h>
-#include <asm/arch-rockchip/clock.h>
-#include <asm/arch-rockchip/grf_rk3368.h>
-#include <asm/arch-rockchip/timer.h>
-#include <syscon.h>
-
-int mach_cpu_init(void)
-{
-	return 0;
-}
-
-int board_init(void)
-{
-	return 0;
-}
diff --git a/board/theobroma-systems/puma_rk3399/puma-rk3399.c b/board/theobroma-systems/puma_rk3399/puma-rk3399.c
index 251cd2d..a7e7f02 100644
--- a/board/theobroma-systems/puma_rk3399/puma-rk3399.c
+++ b/board/theobroma-systems/puma_rk3399/puma-rk3399.c
@@ -21,21 +21,6 @@
 #include <power/regulator.h>
 #include <u-boot/sha256.h>
 
-int board_init(void)
-{
-	int ret;
-
-	/*
-	 * We need to call into regulators_enable_boot_on() again, as the call
-	 * during SPL may have not included all regulators.
-	 */
-	ret = regulators_enable_boot_on(false);
-	if (ret)
-		debug("%s: Cannot enable boot on regulator\n", __func__);
-
-	return 0;
-}
-
 static void setup_macaddr(void)
 {
 #if CONFIG_IS_ENABLED(CMD_NET)
diff --git a/board/toradex/colibri_vf/colibri_vf.c b/board/toradex/colibri_vf/colibri_vf.c
index 9d63fbf..dad754b 100644
--- a/board/toradex/colibri_vf/colibri_vf.c
+++ b/board/toradex/colibri_vf/colibri_vf.c
@@ -430,7 +430,9 @@
 #if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP)
 int ft_board_setup(void *blob, bd_t *bd)
 {
+#ifndef CONFIG_DM_VIDEO
 	int ret = 0;
+#endif
 #ifdef CONFIG_FDT_FIXUP_PARTITIONS
 	static const struct node_info nodes[] = {
 		{ "fsl,vf610-nfc", MTD_DEV_TYPE_NAND, }, /* NAND flash */
@@ -440,7 +442,7 @@
 	puts("   Updating MTD partitions...\n");
 	fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes));
 #endif
-#ifdef CONFIG_VIDEO_FSL_DCU_FB
+#if defined(CONFIG_VIDEO_FSL_DCU_FB) && !defined(CONFIG_DM_VIDEO)
 	ret = fsl_dcu_fixedfb_setup(blob);
 	if (ret)
 		return ret;
diff --git a/board/toradex/colibri_vf/dcu.c b/board/toradex/colibri_vf/dcu.c
index c36e90c..c688ed7 100644
--- a/board/toradex/colibri_vf/dcu.c
+++ b/board/toradex/colibri_vf/dcu.c
@@ -26,11 +26,13 @@
 	return div;
 }
 
-int platform_dcu_init(unsigned int xres, unsigned int yres,
+int platform_dcu_init(struct fb_info *fbinfo,
+		      unsigned int xres,
+		      unsigned int yres,
 		      const char *port,
 		      struct fb_videomode *dcu_fb_videomode)
 {
-	fsl_dcu_init(xres, yres, 32);
+	fsl_dcu_init(fbinfo, xres, yres, 32);
 
 	return 0;
 }
diff --git a/board/vamrs/rock960_rk3399/rock960-rk3399.c b/board/vamrs/rock960_rk3399/rock960-rk3399.c
index 2eb7120..68a127b 100644
--- a/board/vamrs/rock960_rk3399/rock960-rk3399.c
+++ b/board/vamrs/rock960_rk3399/rock960-rk3399.c
@@ -2,18 +2,3 @@
 /*
  * Copyright (C) 2018 Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
  */
-
-#include <common.h>
-#include <dm.h>
-#include <power/regulator.h>
-
-int board_init(void)
-{
-	int ret;
-
-	ret = regulators_enable_boot_on(false);
-	if (ret)
-		debug("%s: Cannot enable boot on regulator\n", __func__);
-
-	return 0;
-}
diff --git a/common/edid.c b/common/edid.c
index 90d1167..f244d26 100644
--- a/common/edid.c
+++ b/common/edid.c
@@ -168,8 +168,12 @@
 	return false;
 }
 
-int edid_get_timing(u8 *buf, int buf_size, struct display_timing *timing,
-		    int *panel_bits_per_colourp)
+int edid_get_timing_validate(u8 *buf, int buf_size,
+			     struct display_timing *timing,
+			     int *panel_bits_per_colourp,
+			     bool (*mode_valid)(void *priv,
+					const struct display_timing *timing),
+			     void *mode_valid_priv)
 {
 	struct edid1_info *edid = (struct edid1_info *)buf;
 	bool timing_done;
@@ -193,7 +197,11 @@
 		desc = &edid->monitor_details.descriptor[i];
 		if (desc->zero_flag_1 != 0) {
 			decode_timing((u8 *)desc, timing);
-			timing_done = true;
+			if (mode_valid)
+				timing_done = mode_valid(mode_valid_priv,
+							 timing);
+			else
+				timing_done = true;
 			break;
 		}
 	}
@@ -225,6 +233,14 @@
 	return 0;
 }
 
+int edid_get_timing(u8 *buf, int buf_size, struct display_timing *timing,
+		    int *panel_bits_per_colourp)
+{
+	return edid_get_timing_validate(buf, buf_size, timing,
+					panel_bits_per_colourp, NULL, NULL);
+}
+
+
 /**
  * Snip the tailing whitespace/return of a string.
  *
diff --git a/configs/colibri-imx6ull_defconfig b/configs/colibri-imx6ull_defconfig
index 2b57b5e..e184223 100644
--- a/configs/colibri-imx6ull_defconfig
+++ b/configs/colibri-imx6ull_defconfig
@@ -78,6 +78,6 @@
 CONFIG_USB_GADGET_PRODUCT_NUM=0x4000
 CONFIG_CI_UDC=y
 CONFIG_USB_GADGET_DOWNLOAD=y
-CONFIG_VIDEO=y
+CONFIG_DM_VIDEO=y
 CONFIG_OF_LIBFDT_OVERLAY=y
 CONFIG_FDT_FIXUP_PARTITIONS=y
diff --git a/configs/colibri_imx7_defconfig b/configs/colibri_imx7_defconfig
index c303c06..8e769cd 100644
--- a/configs/colibri_imx7_defconfig
+++ b/configs/colibri_imx7_defconfig
@@ -74,6 +74,6 @@
 CONFIG_USB_GADGET_PRODUCT_NUM=0x4000
 CONFIG_CI_UDC=y
 CONFIG_USB_GADGET_DOWNLOAD=y
-CONFIG_VIDEO=y
+CONFIG_DM_VIDEO=y
 CONFIG_OF_LIBFDT_OVERLAY=y
 CONFIG_FDT_FIXUP_PARTITIONS=y
diff --git a/configs/colibri_vf_defconfig b/configs/colibri_vf_defconfig
index 1d48fc9..d11104a 100644
--- a/configs/colibri_vf_defconfig
+++ b/configs/colibri_vf_defconfig
@@ -89,7 +89,7 @@
 CONFIG_CI_UDC=y
 CONFIG_USB_GADGET_DOWNLOAD=y
 CONFIG_VIDEO_FSL_DCU_FB=y
-CONFIG_VIDEO=y
+CONFIG_DM_VIDEO=y
 CONFIG_SYS_CONSOLE_FG_COL=0x00
 CONFIG_OF_LIBFDT_OVERLAY=y
 CONFIG_FDT_FIXUP_PARTITIONS=y
diff --git a/configs/evb-rk3036_defconfig b/configs/evb-rk3036_defconfig
index 5e6bb54..0eb7384 100644
--- a/configs/evb-rk3036_defconfig
+++ b/configs/evb-rk3036_defconfig
@@ -47,6 +47,7 @@
 CONFIG_SF_DEFAULT_SPEED=20000000
 CONFIG_PINCTRL=y
 # CONFIG_SPL_DM_SERIAL is not set
+# CONFIG_SPL_SYSRESET is not set
 CONFIG_DEBUG_UART_SHIFT=2
 CONFIG_SYSRESET=y
 CONFIG_USB=y
diff --git a/configs/kylin-rk3036_defconfig b/configs/kylin-rk3036_defconfig
index 921af0d..a76ae9d 100644
--- a/configs/kylin-rk3036_defconfig
+++ b/configs/kylin-rk3036_defconfig
@@ -49,6 +49,7 @@
 CONFIG_PINCTRL=y
 CONFIG_DM_REGULATOR_FIXED=y
 # CONFIG_SPL_DM_SERIAL is not set
+# CONFIG_SPL_SYSRESET is not set
 CONFIG_DEBUG_UART_SHIFT=2
 CONFIG_SYSRESET=y
 CONFIG_USB=y
diff --git a/configs/sandbox_spl_defconfig b/configs/sandbox_spl_defconfig
index 27034cf..5b7dae9 100644
--- a/configs/sandbox_spl_defconfig
+++ b/configs/sandbox_spl_defconfig
@@ -3,6 +3,7 @@
 CONFIG_SPL_LIBGENERIC_SUPPORT=y
 CONFIG_SPL_SERIAL_SUPPORT=y
 CONFIG_SPL_DRIVERS_MISC_SUPPORT=y
+CONFIG_SPL_FIRMWARE=y
 CONFIG_NR_DRAM_BANKS=1
 CONFIG_SPL=y
 CONFIG_BOOTSTAGE_STASH_ADDR=0x0
diff --git a/drivers/Makefile b/drivers/Makefile
index 603aa98..4193360 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -4,7 +4,9 @@
 obj-$(CONFIG_$(SPL_TPL_)DM) += core/
 obj-$(CONFIG_$(SPL_TPL_)DFU) += dfu/
 obj-$(CONFIG_$(SPL_TPL_)GPIO_SUPPORT) += gpio/
-obj-$(CONFIG_$(SPL_TPL_)DRIVERS_MISC_SUPPORT) += misc/ sysreset/ firmware/
+obj-$(CONFIG_$(SPL_TPL_)DRIVERS_MISC_SUPPORT) += misc/
+obj-$(CONFIG_$(SPL_TPL_)SYSRESET) += sysreset/
+obj-$(CONFIG_$(SPL_TPL_)FIRMWARE) +=firmware/
 obj-$(CONFIG_$(SPL_TPL_)I2C_SUPPORT) += i2c/
 obj-$(CONFIG_$(SPL_TPL_)INPUT) += input/
 obj-$(CONFIG_$(SPL_TPL_)LED) += led/
@@ -81,7 +83,6 @@
 obj-$(CONFIG_CPU) += cpu/
 obj-y += crypto/
 obj-$(CONFIG_FASTBOOT) += fastboot/
-obj-y += firmware/
 obj-$(CONFIG_FPGA) += fpga/
 obj-y += misc/
 obj-$(CONFIG_MMC) += mmc/
@@ -96,7 +97,6 @@
 obj-y += scsi/
 obj-y += sound/
 obj-y += spmi/
-obj-y += sysreset/
 obj-y += video/
 obj-y += watchdog/
 obj-$(CONFIG_QE) += qe/
diff --git a/drivers/clk/rockchip/clk_rk3188.c b/drivers/clk/rockchip/clk_rk3188.c
index 9bb9959..dda686c 100644
--- a/drivers/clk/rockchip/clk_rk3188.c
+++ b/drivers/clk/rockchip/clk_rk3188.c
@@ -562,6 +562,9 @@
 #endif
 
 	rkclk_init(priv->cru, priv->grf, priv->has_bwadj);
+
+	/* Init CPU frequency */
+	rkclk_configure_cpu(priv->cru, priv->grf, APLL_HZ, priv->has_bwadj);
 #endif
 
 	return 0;
diff --git a/drivers/ddr/altera/sequencer.c b/drivers/ddr/altera/sequencer.c
index 0e45262..b85b56e 100644
--- a/drivers/ddr/altera/sequencer.c
+++ b/drivers/ddr/altera/sequencer.c
@@ -9,31 +9,27 @@
 #include <errno.h>
 #include "sequencer.h"
 
-static struct socfpga_sdr_rw_load_manager *sdr_rw_load_mgr_regs =
+static const struct socfpga_sdr_rw_load_manager *sdr_rw_load_mgr_regs =
 	(struct socfpga_sdr_rw_load_manager *)
 		(SDR_PHYGRP_RWMGRGRP_ADDRESS | 0x800);
-static struct socfpga_sdr_rw_load_jump_manager *sdr_rw_load_jump_mgr_regs =
-	(struct socfpga_sdr_rw_load_jump_manager *)
+static const struct socfpga_sdr_rw_load_jump_manager *sdr_rw_load_jump_mgr_regs
+	= (struct socfpga_sdr_rw_load_jump_manager *)
 		(SDR_PHYGRP_RWMGRGRP_ADDRESS | 0xC00);
-static struct socfpga_sdr_reg_file *sdr_reg_file =
+static const struct socfpga_sdr_reg_file *sdr_reg_file =
 	(struct socfpga_sdr_reg_file *)SDR_PHYGRP_REGFILEGRP_ADDRESS;
-static struct socfpga_sdr_scc_mgr *sdr_scc_mgr =
+static const struct socfpga_sdr_scc_mgr *sdr_scc_mgr =
 	(struct socfpga_sdr_scc_mgr *)
 		(SDR_PHYGRP_SCCGRP_ADDRESS | 0xe00);
-static struct socfpga_phy_mgr_cmd *phy_mgr_cmd =
+static const struct socfpga_phy_mgr_cmd *phy_mgr_cmd =
 	(struct socfpga_phy_mgr_cmd *)SDR_PHYGRP_PHYMGRGRP_ADDRESS;
-static struct socfpga_phy_mgr_cfg *phy_mgr_cfg =
+static const struct socfpga_phy_mgr_cfg *phy_mgr_cfg =
 	(struct socfpga_phy_mgr_cfg *)
 		(SDR_PHYGRP_PHYMGRGRP_ADDRESS | 0x40);
-static struct socfpga_data_mgr *data_mgr =
+static const struct socfpga_data_mgr *data_mgr =
 	(struct socfpga_data_mgr *)SDR_PHYGRP_DATAMGRGRP_ADDRESS;
-static struct socfpga_sdr_ctrl *sdr_ctrl =
+static const struct socfpga_sdr_ctrl *sdr_ctrl =
 	(struct socfpga_sdr_ctrl *)SDR_CTRLGRP_ADDRESS;
 
-const struct socfpga_sdram_rw_mgr_config *rwcfg;
-const struct socfpga_sdram_io_config *iocfg;
-const struct socfpga_sdram_misc_config *misccfg;
-
 #define DELTA_D		1
 
 /*
@@ -55,37 +51,20 @@
 #define STATIC_CALIB_STEPS (STATIC_IN_RTL_SIM | CALIB_SKIP_FULL_TEST | \
 	STATIC_SKIP_DELAY_LOOPS)
 
-/* calibration steps requested by the rtl */
-static u16 dyn_calib_steps;
-
-/*
- * To make CALIB_SKIP_DELAY_LOOPS a dynamic conditional option
- * instead of static, we use boolean logic to select between
- * non-skip and skip values
- *
- * The mask is set to include all bits when not-skipping, but is
- * zero when skipping
- */
-
-static u16 skip_delay_mask;	/* mask off bits when skipping/not-skipping */
-
 #define SKIP_DELAY_LOOP_VALUE_OR_ZERO(non_skip_value) \
-	((non_skip_value) & skip_delay_mask)
+	((non_skip_value) & seq->skip_delay_mask)
 
-static struct gbl_type *gbl;
-static struct param_type *param;
-
-static void set_failing_group_stage(u32 group, u32 stage,
-	u32 substage)
+static void set_failing_group_stage(struct socfpga_sdrseq *seq,
+				    u32 group, u32 stage, u32 substage)
 {
 	/*
 	 * Only set the global stage if there was not been any other
 	 * failing group
 	 */
-	if (gbl->error_stage == CAL_STAGE_NIL)	{
-		gbl->error_substage = substage;
-		gbl->error_stage = stage;
-		gbl->error_group = group;
+	if (seq->gbl.error_stage == CAL_STAGE_NIL)	{
+		seq->gbl.error_substage = substage;
+		seq->gbl.error_stage = stage;
+		seq->gbl.error_group = group;
 	}
 }
 
@@ -110,7 +89,7 @@
  *
  * Initialize PHY Manager.
  */
-static void phy_mgr_initialize(void)
+static void phy_mgr_initialize(struct socfpga_sdrseq *seq)
 {
 	u32 ratio;
 
@@ -132,15 +111,17 @@
 	writel(0, &phy_mgr_cfg->cal_debug_info);
 
 	/* Init params only if we do NOT skip calibration. */
-	if ((dyn_calib_steps & CALIB_SKIP_ALL) == CALIB_SKIP_ALL)
+	if ((seq->dyn_calib_steps & CALIB_SKIP_ALL) == CALIB_SKIP_ALL)
 		return;
 
-	ratio = rwcfg->mem_dq_per_read_dqs /
-		rwcfg->mem_virtual_groups_per_read_dqs;
-	param->read_correct_mask_vg = (1 << ratio) - 1;
-	param->write_correct_mask_vg = (1 << ratio) - 1;
-	param->read_correct_mask = (1 << rwcfg->mem_dq_per_read_dqs) - 1;
-	param->write_correct_mask = (1 << rwcfg->mem_dq_per_write_dqs) - 1;
+	ratio = seq->rwcfg->mem_dq_per_read_dqs /
+		seq->rwcfg->mem_virtual_groups_per_read_dqs;
+	seq->param.read_correct_mask_vg = (1 << ratio) - 1;
+	seq->param.write_correct_mask_vg = (1 << ratio) - 1;
+	seq->param.read_correct_mask = (1 << seq->rwcfg->mem_dq_per_read_dqs)
+		- 1;
+	seq->param.write_correct_mask = (1 << seq->rwcfg->mem_dq_per_write_dqs)
+		- 1;
 }
 
 /**
@@ -150,7 +131,8 @@
  *
  * Set Rank and ODT mask (On-Die Termination).
  */
-static void set_rank_and_odt_mask(const u32 rank, const u32 odt_mode)
+static void set_rank_and_odt_mask(struct socfpga_sdrseq *seq,
+				  const u32 rank, const u32 odt_mode)
 {
 	u32 odt_mask_0 = 0;
 	u32 odt_mask_1 = 0;
@@ -160,14 +142,14 @@
 		odt_mask_0 = 0x0;
 		odt_mask_1 = 0x0;
 	} else {	/* RW_MGR_ODT_MODE_READ_WRITE */
-		switch (rwcfg->mem_number_of_ranks) {
+		switch (seq->rwcfg->mem_number_of_ranks) {
 		case 1:	/* 1 Rank */
 			/* Read: ODT = 0 ; Write: ODT = 1 */
 			odt_mask_0 = 0x0;
 			odt_mask_1 = 0x1;
 			break;
 		case 2:	/* 2 Ranks */
-			if (rwcfg->mem_number_of_cs_per_dimm == 1) {
+			if (seq->rwcfg->mem_number_of_cs_per_dimm == 1) {
 				/*
 				 * - Dual-Slot , Single-Rank (1 CS per DIMM)
 				 *   OR
@@ -307,16 +289,18 @@
 	scc_mgr_set(SCC_MGR_IO_IN_DELAY_OFFSET, dq_in_group, delay);
 }
 
-static void scc_mgr_set_dqs_io_in_delay(u32 delay)
-{
-	scc_mgr_set(SCC_MGR_IO_IN_DELAY_OFFSET, rwcfg->mem_dq_per_write_dqs,
-		    delay);
-}
-
-static void scc_mgr_set_dm_in_delay(u32 dm, u32 delay)
+static void scc_mgr_set_dqs_io_in_delay(struct socfpga_sdrseq *seq,
+					u32 delay)
 {
 	scc_mgr_set(SCC_MGR_IO_IN_DELAY_OFFSET,
-		    rwcfg->mem_dq_per_write_dqs + 1 + dm,
+		    seq->rwcfg->mem_dq_per_write_dqs, delay);
+}
+
+static void scc_mgr_set_dm_in_delay(struct socfpga_sdrseq *seq, u32 dm,
+				    u32 delay)
+{
+	scc_mgr_set(SCC_MGR_IO_IN_DELAY_OFFSET,
+		    seq->rwcfg->mem_dq_per_write_dqs + 1 + dm,
 		    delay);
 }
 
@@ -325,16 +309,18 @@
 	scc_mgr_set(SCC_MGR_IO_OUT1_DELAY_OFFSET, dq_in_group, delay);
 }
 
-static void scc_mgr_set_dqs_out1_delay(u32 delay)
-{
-	scc_mgr_set(SCC_MGR_IO_OUT1_DELAY_OFFSET, rwcfg->mem_dq_per_write_dqs,
-		    delay);
-}
-
-static void scc_mgr_set_dm_out1_delay(u32 dm, u32 delay)
+static void scc_mgr_set_dqs_out1_delay(struct socfpga_sdrseq *seq,
+				       u32 delay)
 {
 	scc_mgr_set(SCC_MGR_IO_OUT1_DELAY_OFFSET,
-		    rwcfg->mem_dq_per_write_dqs + 1 + dm,
+		    seq->rwcfg->mem_dq_per_write_dqs, delay);
+}
+
+static void scc_mgr_set_dm_out1_delay(struct socfpga_sdrseq *seq, u32 dm,
+				      u32 delay)
+{
+	scc_mgr_set(SCC_MGR_IO_OUT1_DELAY_OFFSET,
+		    seq->rwcfg->mem_dq_per_write_dqs + 1 + dm,
 		    delay);
 }
 
@@ -372,12 +358,13 @@
  * This function sets the SCC Manager (Scan Chain Control Manager) register
  * and optionally triggers the SCC update for all ranks.
  */
-static void scc_mgr_set_all_ranks(const u32 off, const u32 grp, const u32 val,
+static void scc_mgr_set_all_ranks(struct socfpga_sdrseq *seq,
+				  const u32 off, const u32 grp, const u32 val,
 				  const int update)
 {
 	u32 r;
 
-	for (r = 0; r < rwcfg->mem_number_of_ranks;
+	for (r = 0; r < seq->rwcfg->mem_number_of_ranks;
 	     r += NUM_RANKS_PER_SHADOW_REG) {
 		scc_mgr_set(off, grp, val);
 
@@ -388,7 +375,8 @@
 	}
 }
 
-static void scc_mgr_set_dqs_en_phase_all_ranks(u32 read_group, u32 phase)
+static void scc_mgr_set_dqs_en_phase_all_ranks(struct socfpga_sdrseq *seq,
+					       u32 read_group, u32 phase)
 {
 	/*
 	 * USER although the h/w doesn't support different phases per
@@ -398,12 +386,12 @@
 	 * for efficiency, the scan chain update should occur only
 	 * once to sr0.
 	 */
-	scc_mgr_set_all_ranks(SCC_MGR_DQS_EN_PHASE_OFFSET,
+	scc_mgr_set_all_ranks(seq, SCC_MGR_DQS_EN_PHASE_OFFSET,
 			      read_group, phase, 0);
 }
 
-static void scc_mgr_set_dqdqs_output_phase_all_ranks(u32 write_group,
-						     u32 phase)
+static void scc_mgr_set_dqdqs_output_phase_all_ranks(struct socfpga_sdrseq *seq,
+						     u32 write_group, u32 phase)
 {
 	/*
 	 * USER although the h/w doesn't support different phases per
@@ -413,12 +401,12 @@
 	 * for efficiency, the scan chain update should occur only
 	 * once to sr0.
 	 */
-	scc_mgr_set_all_ranks(SCC_MGR_DQDQS_OUT_PHASE_OFFSET,
+	scc_mgr_set_all_ranks(seq, SCC_MGR_DQDQS_OUT_PHASE_OFFSET,
 			      write_group, phase, 0);
 }
 
-static void scc_mgr_set_dqs_en_delay_all_ranks(u32 read_group,
-					       u32 delay)
+static void scc_mgr_set_dqs_en_delay_all_ranks(struct socfpga_sdrseq *seq,
+					       u32 read_group, u32 delay)
 {
 	/*
 	 * In shadow register mode, the T11 settings are stored in
@@ -428,7 +416,7 @@
 	 * select_shadow_regs_for_update with update_scan_chains
 	 * set to 0.
 	 */
-	scc_mgr_set_all_ranks(SCC_MGR_DQS_EN_DELAY_OFFSET,
+	scc_mgr_set_all_ranks(seq, SCC_MGR_DQS_EN_DELAY_OFFSET,
 			      read_group, delay, 1);
 }
 
@@ -439,10 +427,11 @@
  *
  * This function sets the OCT output delay in SCC manager.
  */
-static void scc_mgr_set_oct_out1_delay(const u32 write_group, const u32 delay)
+static void scc_mgr_set_oct_out1_delay(struct socfpga_sdrseq *seq,
+				       const u32 write_group, const u32 delay)
 {
-	const int ratio = rwcfg->mem_if_read_dqs_width /
-			  rwcfg->mem_if_write_dqs_width;
+	const int ratio = seq->rwcfg->mem_if_read_dqs_width /
+			 seq->rwcfg->mem_if_write_dqs_width;
 	const int base = write_group * ratio;
 	int i;
 	/*
@@ -490,7 +479,7 @@
  *
  * Zero all DQS config.
  */
-static void scc_mgr_zero_all(void)
+static void scc_mgr_zero_all(struct socfpga_sdrseq *seq)
 {
 	int i, r;
 
@@ -498,23 +487,26 @@
 	 * USER Zero all DQS config settings, across all groups and all
 	 * shadow registers
 	 */
-	for (r = 0; r < rwcfg->mem_number_of_ranks;
+	for (r = 0; r < seq->rwcfg->mem_number_of_ranks;
 	     r += NUM_RANKS_PER_SHADOW_REG) {
-		for (i = 0; i < rwcfg->mem_if_read_dqs_width; i++) {
+		for (i = 0; i < seq->rwcfg->mem_if_read_dqs_width; i++) {
 			/*
 			 * The phases actually don't exist on a per-rank basis,
 			 * but there's no harm updating them several times, so
 			 * let's keep the code simple.
 			 */
-			scc_mgr_set_dqs_bus_in_delay(i, iocfg->dqs_in_reserve);
+			scc_mgr_set_dqs_bus_in_delay(i,
+						     seq->iocfg->dqs_in_reserve
+						     );
 			scc_mgr_set_dqs_en_phase(i, 0);
 			scc_mgr_set_dqs_en_delay(i, 0);
 		}
 
-		for (i = 0; i < rwcfg->mem_if_write_dqs_width; i++) {
+		for (i = 0; i < seq->rwcfg->mem_if_write_dqs_width; i++) {
 			scc_mgr_set_dqdqs_output_phase(i, 0);
 			/* Arria V/Cyclone V don't have out2. */
-			scc_mgr_set_oct_out1_delay(i, iocfg->dqs_out_reserve);
+			scc_mgr_set_oct_out1_delay(seq, i,
+						   seq->iocfg->dqs_out_reserve);
 		}
 	}
 
@@ -551,10 +543,11 @@
  *
  * Load DQS settings for Write Group, do not trigger SCC update.
  */
-static void scc_mgr_load_dqs_for_write_group(const u32 write_group)
+static void scc_mgr_load_dqs_for_write_group(struct socfpga_sdrseq *seq,
+					     const u32 write_group)
 {
-	const int ratio = rwcfg->mem_if_read_dqs_width /
-			  rwcfg->mem_if_write_dqs_width;
+	const int ratio = seq->rwcfg->mem_if_read_dqs_width /
+			  seq->rwcfg->mem_if_write_dqs_width;
 	const int base = write_group * ratio;
 	int i;
 	/*
@@ -573,14 +566,15 @@
  *
  * Zero DQ, DM, DQS and OCT configs for a group.
  */
-static void scc_mgr_zero_group(const u32 write_group, const int out_only)
+static void scc_mgr_zero_group(struct socfpga_sdrseq *seq,
+			       const u32 write_group, const int out_only)
 {
 	int i, r;
 
-	for (r = 0; r < rwcfg->mem_number_of_ranks;
+	for (r = 0; r < seq->rwcfg->mem_number_of_ranks;
 	     r += NUM_RANKS_PER_SHADOW_REG) {
 		/* Zero all DQ config settings. */
-		for (i = 0; i < rwcfg->mem_dq_per_write_dqs; i++) {
+		for (i = 0; i < seq->rwcfg->mem_dq_per_write_dqs; i++) {
 			scc_mgr_set_dq_out1_delay(i, 0);
 			if (!out_only)
 				scc_mgr_set_dq_in_delay(i, 0);
@@ -592,8 +586,8 @@
 		/* Zero all DM config settings. */
 		for (i = 0; i < RW_MGR_NUM_DM_PER_WRITE_GROUP; i++) {
 			if (!out_only)
-				scc_mgr_set_dm_in_delay(i, 0);
-			scc_mgr_set_dm_out1_delay(i, 0);
+				scc_mgr_set_dm_in_delay(seq, i, 0);
+			scc_mgr_set_dm_out1_delay(seq, i, 0);
 		}
 
 		/* Multicast to all DM enables. */
@@ -601,12 +595,13 @@
 
 		/* Zero all DQS IO settings. */
 		if (!out_only)
-			scc_mgr_set_dqs_io_in_delay(0);
+			scc_mgr_set_dqs_io_in_delay(seq, 0);
 
 		/* Arria V/Cyclone V don't have out2. */
-		scc_mgr_set_dqs_out1_delay(iocfg->dqs_out_reserve);
-		scc_mgr_set_oct_out1_delay(write_group, iocfg->dqs_out_reserve);
-		scc_mgr_load_dqs_for_write_group(write_group);
+		scc_mgr_set_dqs_out1_delay(seq, seq->iocfg->dqs_out_reserve);
+		scc_mgr_set_oct_out1_delay(seq, write_group,
+					   seq->iocfg->dqs_out_reserve);
+		scc_mgr_load_dqs_for_write_group(seq, write_group);
 
 		/* Multicast to all DQS IO enables (only 1 in total). */
 		writel(0, &sdr_scc_mgr->dqs_io_ena);
@@ -620,69 +615,76 @@
  * apply and load a particular input delay for the DQ pins in a group
  * group_bgn is the index of the first dq pin (in the write group)
  */
-static void scc_mgr_apply_group_dq_in_delay(u32 group_bgn, u32 delay)
+static void scc_mgr_apply_group_dq_in_delay(struct socfpga_sdrseq *seq,
+					    u32 group_bgn, u32 delay)
 {
 	u32 i, p;
 
-	for (i = 0, p = group_bgn; i < rwcfg->mem_dq_per_read_dqs; i++, p++) {
+	for (i = 0, p = group_bgn; i < seq->rwcfg->mem_dq_per_read_dqs;
+	     i++, p++) {
 		scc_mgr_set_dq_in_delay(p, delay);
 		scc_mgr_load_dq(p);
 	}
 }
 
 /**
- * scc_mgr_apply_group_dq_out1_delay() - Apply and load an output delay for the DQ pins in a group
+ * scc_mgr_apply_group_dq_out1_delay() - Apply and load an output delay for the
+ * DQ pins in a group
  * @delay:		Delay value
  *
  * Apply and load a particular output delay for the DQ pins in a group.
  */
-static void scc_mgr_apply_group_dq_out1_delay(const u32 delay)
+static void scc_mgr_apply_group_dq_out1_delay(struct socfpga_sdrseq *seq,
+					      const u32 delay)
 {
 	int i;
 
-	for (i = 0; i < rwcfg->mem_dq_per_write_dqs; i++) {
+	for (i = 0; i < seq->rwcfg->mem_dq_per_write_dqs; i++) {
 		scc_mgr_set_dq_out1_delay(i, delay);
 		scc_mgr_load_dq(i);
 	}
 }
 
 /* apply and load a particular output delay for the DM pins in a group */
-static void scc_mgr_apply_group_dm_out1_delay(u32 delay1)
+static void scc_mgr_apply_group_dm_out1_delay(struct socfpga_sdrseq *seq,
+					      u32 delay1)
 {
 	u32 i;
 
 	for (i = 0; i < RW_MGR_NUM_DM_PER_WRITE_GROUP; i++) {
-		scc_mgr_set_dm_out1_delay(i, delay1);
+		scc_mgr_set_dm_out1_delay(seq, i, delay1);
 		scc_mgr_load_dm(i);
 	}
 }
 
 
 /* apply and load delay on both DQS and OCT out1 */
-static void scc_mgr_apply_group_dqs_io_and_oct_out1(u32 write_group,
-						    u32 delay)
+static void scc_mgr_apply_group_dqs_io_and_oct_out1(struct socfpga_sdrseq *seq,
+						    u32 write_group, u32 delay)
 {
-	scc_mgr_set_dqs_out1_delay(delay);
+	scc_mgr_set_dqs_out1_delay(seq, delay);
 	scc_mgr_load_dqs_io();
 
-	scc_mgr_set_oct_out1_delay(write_group, delay);
-	scc_mgr_load_dqs_for_write_group(write_group);
+	scc_mgr_set_oct_out1_delay(seq, write_group, delay);
+	scc_mgr_load_dqs_for_write_group(seq, write_group);
 }
 
 /**
- * scc_mgr_apply_group_all_out_delay_add() - Apply a delay to the entire output side: DQ, DM, DQS, OCT
+ * scc_mgr_apply_group_all_out_delay_add() - Apply a delay to the entire output
+ * side: DQ, DM, DQS, OCT
  * @write_group:	Write group
  * @delay:		Delay value
  *
  * Apply a delay to the entire output side: DQ, DM, DQS, OCT.
  */
-static void scc_mgr_apply_group_all_out_delay_add(const u32 write_group,
+static void scc_mgr_apply_group_all_out_delay_add(struct socfpga_sdrseq *seq,
+						  const u32 write_group,
 						  const u32 delay)
 {
 	u32 i, new_delay;
 
 	/* DQ shift */
-	for (i = 0; i < rwcfg->mem_dq_per_write_dqs; i++)
+	for (i = 0; i < seq->rwcfg->mem_dq_per_write_dqs; i++)
 		scc_mgr_load_dq(i);
 
 	/* DM shift */
@@ -691,49 +693,51 @@
 
 	/* DQS shift */
 	new_delay = READ_SCC_DQS_IO_OUT2_DELAY + delay;
-	if (new_delay > iocfg->io_out2_delay_max) {
+	if (new_delay > seq->iocfg->io_out2_delay_max) {
 		debug_cond(DLEVEL >= 1,
 			   "%s:%d (%u, %u) DQS: %u > %d; adding %u to OUT1\n",
 			   __func__, __LINE__, write_group, delay, new_delay,
-			   iocfg->io_out2_delay_max,
-			   new_delay - iocfg->io_out2_delay_max);
-		new_delay -= iocfg->io_out2_delay_max;
-		scc_mgr_set_dqs_out1_delay(new_delay);
+			   seq->iocfg->io_out2_delay_max,
+			   new_delay - seq->iocfg->io_out2_delay_max);
+		new_delay -= seq->iocfg->io_out2_delay_max;
+		scc_mgr_set_dqs_out1_delay(seq, new_delay);
 	}
 
 	scc_mgr_load_dqs_io();
 
 	/* OCT shift */
 	new_delay = READ_SCC_OCT_OUT2_DELAY + delay;
-	if (new_delay > iocfg->io_out2_delay_max) {
+	if (new_delay > seq->iocfg->io_out2_delay_max) {
 		debug_cond(DLEVEL >= 1,
 			   "%s:%d (%u, %u) DQS: %u > %d; adding %u to OUT1\n",
 			   __func__, __LINE__, write_group, delay,
-			   new_delay, iocfg->io_out2_delay_max,
-			   new_delay - iocfg->io_out2_delay_max);
-		new_delay -= iocfg->io_out2_delay_max;
-		scc_mgr_set_oct_out1_delay(write_group, new_delay);
+			   new_delay, seq->iocfg->io_out2_delay_max,
+			   new_delay - seq->iocfg->io_out2_delay_max);
+		new_delay -= seq->iocfg->io_out2_delay_max;
+		scc_mgr_set_oct_out1_delay(seq, write_group, new_delay);
 	}
 
-	scc_mgr_load_dqs_for_write_group(write_group);
+	scc_mgr_load_dqs_for_write_group(seq, write_group);
 }
 
 /**
- * scc_mgr_apply_group_all_out_delay_add() - Apply a delay to the entire output side to all ranks
+ * scc_mgr_apply_group_all_out_delay_add() - Apply a delay to the entire output
+ * side to all ranks
  * @write_group:	Write group
  * @delay:		Delay value
  *
  * Apply a delay to the entire output side (DQ, DM, DQS, OCT) to all ranks.
  */
 static void
-scc_mgr_apply_group_all_out_delay_add_all_ranks(const u32 write_group,
+scc_mgr_apply_group_all_out_delay_add_all_ranks(struct socfpga_sdrseq *seq,
+						const u32 write_group,
 						const u32 delay)
 {
 	int r;
 
-	for (r = 0; r < rwcfg->mem_number_of_ranks;
+	for (r = 0; r < seq->rwcfg->mem_number_of_ranks;
 	     r += NUM_RANKS_PER_SHADOW_REG) {
-		scc_mgr_apply_group_all_out_delay_add(write_group, delay);
+		scc_mgr_apply_group_all_out_delay_add(seq, write_group, delay);
 		writel(0, &sdr_scc_mgr->update);
 	}
 }
@@ -744,7 +748,7 @@
  * Optimization used to recover some slots in ddr3 inst_rom could be
  * applied to other protocols if we wanted to
  */
-static void set_jump_as_return(void)
+static void set_jump_as_return(struct socfpga_sdrseq *seq)
 {
 	/*
 	 * To save space, we replace return with jump to special shared
@@ -752,7 +756,7 @@
 	 * we always jump.
 	 */
 	writel(0xff, &sdr_rw_load_mgr_regs->load_cntr0);
-	writel(rwcfg->rreturn, &sdr_rw_load_jump_mgr_regs->load_jump_add0);
+	writel(seq->rwcfg->rreturn, &sdr_rw_load_jump_mgr_regs->load_jump_add0);
 }
 
 /**
@@ -761,7 +765,8 @@
  *
  * Delay for N memory clocks.
  */
-static void delay_for_n_mem_clocks(const u32 clocks)
+static void delay_for_n_mem_clocks(struct socfpga_sdrseq *seq,
+				   const u32 clocks)
 {
 	u32 afi_clocks;
 	u16 c_loop;
@@ -771,7 +776,7 @@
 	debug("%s:%d: clocks=%u ... start\n", __func__, __LINE__, clocks);
 
 	/* Scale (rounding up) to get afi clocks. */
-	afi_clocks = DIV_ROUND_UP(clocks, misccfg->afi_rate_ratio);
+	afi_clocks = DIV_ROUND_UP(clocks, seq->misccfg->afi_rate_ratio);
 	if (afi_clocks)	/* Temporary underflow protection */
 		afi_clocks--;
 
@@ -807,10 +812,10 @@
 		writel(SKIP_DELAY_LOOP_VALUE_OR_ZERO(inner),
 		       &sdr_rw_load_mgr_regs->load_cntr1);
 
-		writel(rwcfg->idle_loop1,
+		writel(seq->rwcfg->idle_loop1,
 		       &sdr_rw_load_jump_mgr_regs->load_jump_add1);
 
-		writel(rwcfg->idle_loop1, SDR_PHYGRP_RWMGRGRP_ADDRESS |
+		writel(seq->rwcfg->idle_loop1, SDR_PHYGRP_RWMGRGRP_ADDRESS |
 					  RW_MGR_RUN_SINGLE_GROUP_OFFSET);
 	} else {
 		writel(SKIP_DELAY_LOOP_VALUE_OR_ZERO(inner),
@@ -819,14 +824,14 @@
 		writel(SKIP_DELAY_LOOP_VALUE_OR_ZERO(outer),
 		       &sdr_rw_load_mgr_regs->load_cntr1);
 
-		writel(rwcfg->idle_loop2,
+		writel(seq->rwcfg->idle_loop2,
 		       &sdr_rw_load_jump_mgr_regs->load_jump_add0);
 
-		writel(rwcfg->idle_loop2,
+		writel(seq->rwcfg->idle_loop2,
 		       &sdr_rw_load_jump_mgr_regs->load_jump_add1);
 
 		do {
-			writel(rwcfg->idle_loop2,
+			writel(seq->rwcfg->idle_loop2,
 			       SDR_PHYGRP_RWMGRGRP_ADDRESS |
 			       RW_MGR_RUN_SINGLE_GROUP_OFFSET);
 		} while (c_loop-- != 0);
@@ -843,7 +848,8 @@
  *
  * Load instruction registers.
  */
-static void rw_mgr_mem_init_load_regs(u32 cntr0, u32 cntr1, u32 cntr2, u32 jump)
+static void rw_mgr_mem_init_load_regs(struct socfpga_sdrseq *seq,
+				      u32 cntr0, u32 cntr1, u32 cntr2, u32 jump)
 {
 	u32 grpaddr = SDR_PHYGRP_RWMGRGRP_ADDRESS |
 			   RW_MGR_RUN_SINGLE_GROUP_OFFSET;
@@ -873,58 +879,59 @@
  *
  * Load user calibration values and optionally precharge the banks.
  */
-static void rw_mgr_mem_load_user(const u32 fin1, const u32 fin2,
+static void rw_mgr_mem_load_user(struct socfpga_sdrseq *seq,
+				 const u32 fin1, const u32 fin2,
 				 const int precharge)
 {
 	u32 grpaddr = SDR_PHYGRP_RWMGRGRP_ADDRESS |
 		      RW_MGR_RUN_SINGLE_GROUP_OFFSET;
 	u32 r;
 
-	for (r = 0; r < rwcfg->mem_number_of_ranks; r++) {
+	for (r = 0; r < seq->rwcfg->mem_number_of_ranks; r++) {
 		/* set rank */
-		set_rank_and_odt_mask(r, RW_MGR_ODT_MODE_OFF);
+		set_rank_and_odt_mask(seq, r, RW_MGR_ODT_MODE_OFF);
 
 		/* precharge all banks ... */
 		if (precharge)
-			writel(rwcfg->precharge_all, grpaddr);
+			writel(seq->rwcfg->precharge_all, grpaddr);
 
 		/*
 		 * USER Use Mirror-ed commands for odd ranks if address
 		 * mirrorring is on
 		 */
-		if ((rwcfg->mem_address_mirroring >> r) & 0x1) {
-			set_jump_as_return();
-			writel(rwcfg->mrs2_mirr, grpaddr);
-			delay_for_n_mem_clocks(4);
-			set_jump_as_return();
-			writel(rwcfg->mrs3_mirr, grpaddr);
-			delay_for_n_mem_clocks(4);
-			set_jump_as_return();
-			writel(rwcfg->mrs1_mirr, grpaddr);
-			delay_for_n_mem_clocks(4);
-			set_jump_as_return();
+		if ((seq->rwcfg->mem_address_mirroring >> r) & 0x1) {
+			set_jump_as_return(seq);
+			writel(seq->rwcfg->mrs2_mirr, grpaddr);
+			delay_for_n_mem_clocks(seq, 4);
+			set_jump_as_return(seq);
+			writel(seq->rwcfg->mrs3_mirr, grpaddr);
+			delay_for_n_mem_clocks(seq, 4);
+			set_jump_as_return(seq);
+			writel(seq->rwcfg->mrs1_mirr, grpaddr);
+			delay_for_n_mem_clocks(seq, 4);
+			set_jump_as_return(seq);
 			writel(fin1, grpaddr);
 		} else {
-			set_jump_as_return();
-			writel(rwcfg->mrs2, grpaddr);
-			delay_for_n_mem_clocks(4);
-			set_jump_as_return();
-			writel(rwcfg->mrs3, grpaddr);
-			delay_for_n_mem_clocks(4);
-			set_jump_as_return();
-			writel(rwcfg->mrs1, grpaddr);
-			set_jump_as_return();
+			set_jump_as_return(seq);
+			writel(seq->rwcfg->mrs2, grpaddr);
+			delay_for_n_mem_clocks(seq, 4);
+			set_jump_as_return(seq);
+			writel(seq->rwcfg->mrs3, grpaddr);
+			delay_for_n_mem_clocks(seq, 4);
+			set_jump_as_return(seq);
+			writel(seq->rwcfg->mrs1, grpaddr);
+			set_jump_as_return(seq);
 			writel(fin2, grpaddr);
 		}
 
 		if (precharge)
 			continue;
 
-		set_jump_as_return();
-		writel(rwcfg->zqcl, grpaddr);
+		set_jump_as_return(seq);
+		writel(seq->rwcfg->zqcl, grpaddr);
 
 		/* tZQinit = tDLLK = 512 ck cycles */
-		delay_for_n_mem_clocks(512);
+		delay_for_n_mem_clocks(seq, 512);
 	}
 }
 
@@ -933,7 +940,7 @@
  *
  * Initialize RW Manager.
  */
-static void rw_mgr_mem_initialize(void)
+static void rw_mgr_mem_initialize(struct socfpga_sdrseq *seq)
 {
 	debug("%s:%d\n", __func__, __LINE__);
 
@@ -964,10 +971,10 @@
 	 * One possible solution is n = 0 , a = 256 , b = 106 => a = FF,
 	 * b = 6A
 	 */
-	rw_mgr_mem_init_load_regs(misccfg->tinit_cntr0_val,
-				  misccfg->tinit_cntr1_val,
-				  misccfg->tinit_cntr2_val,
-				  rwcfg->init_reset_0_cke_0);
+	rw_mgr_mem_init_load_regs(seq, seq->misccfg->tinit_cntr0_val,
+				  seq->misccfg->tinit_cntr1_val,
+				  seq->misccfg->tinit_cntr2_val,
+				  seq->rwcfg->init_reset_0_cke_0);
 
 	/* Indicate that memory is stable. */
 	writel(1, &phy_mgr_cfg->reset_mem_stbl);
@@ -986,18 +993,18 @@
 	 * One possible solution is n = 2 , a = 131 , b = 256 => a = 83,
 	 * b = FF
 	 */
-	rw_mgr_mem_init_load_regs(misccfg->treset_cntr0_val,
-				  misccfg->treset_cntr1_val,
-				  misccfg->treset_cntr2_val,
-				  rwcfg->init_reset_1_cke_0);
+	rw_mgr_mem_init_load_regs(seq, seq->misccfg->treset_cntr0_val,
+				  seq->misccfg->treset_cntr1_val,
+				  seq->misccfg->treset_cntr2_val,
+				  seq->rwcfg->init_reset_1_cke_0);
 
 	/* Bring up clock enable. */
 
 	/* tXRP < 250 ck cycles */
-	delay_for_n_mem_clocks(250);
+	delay_for_n_mem_clocks(seq, 250);
 
-	rw_mgr_mem_load_user(rwcfg->mrs0_dll_reset_mirr, rwcfg->mrs0_dll_reset,
-			     0);
+	rw_mgr_mem_load_user(seq, seq->rwcfg->mrs0_dll_reset_mirr,
+			     seq->rwcfg->mrs0_dll_reset, 0);
 }
 
 /**
@@ -1006,9 +1013,10 @@
  * At the end of calibration we have to program the user settings in
  * and hand off the memory to the user.
  */
-static void rw_mgr_mem_handoff(void)
+static void rw_mgr_mem_handoff(struct socfpga_sdrseq *seq)
 {
-	rw_mgr_mem_load_user(rwcfg->mrs0_user_mirr, rwcfg->mrs0_user, 1);
+	rw_mgr_mem_load_user(seq, seq->rwcfg->mrs0_user_mirr,
+			     seq->rwcfg->mrs0_user, 1);
 	/*
 	 * Need to wait tMOD (12CK or 15ns) time before issuing other
 	 * commands, but we will have plenty of NIOS cycles before actual
@@ -1024,12 +1032,12 @@
  * Issue write test command. Two variants are provided, one that just tests
  * a write pattern and another that tests datamask functionality.
  */
-static void rw_mgr_mem_calibrate_write_test_issue(u32 group,
-						  u32 test_dm)
+static void rw_mgr_mem_calibrate_write_test_issue(struct socfpga_sdrseq *seq,
+						  u32 group, u32 test_dm)
 {
 	const u32 quick_write_mode =
 		(STATIC_CALIB_STEPS & CALIB_SKIP_WRITES) &&
-		misccfg->enable_super_quick_calibration;
+		seq->misccfg->enable_super_quick_calibration;
 	u32 mcc_instruction;
 	u32 rw_wl_nop_cycles;
 
@@ -1059,7 +1067,7 @@
 	 *       one counter left to issue this command in "multiple-group" mode
 	 */
 
-	rw_wl_nop_cycles = gbl->rw_wl_nop_cycles;
+	rw_wl_nop_cycles = seq->gbl.rw_wl_nop_cycles;
 
 	if (rw_wl_nop_cycles == -1) {
 		/*
@@ -1072,16 +1080,16 @@
 
 		/* CNTR 3 - Not used */
 		if (test_dm) {
-			mcc_instruction = rwcfg->lfsr_wr_rd_dm_bank_0_wl_1;
-			writel(rwcfg->lfsr_wr_rd_dm_bank_0_data,
+			mcc_instruction = seq->rwcfg->lfsr_wr_rd_dm_bank_0_wl_1;
+			writel(seq->rwcfg->lfsr_wr_rd_dm_bank_0_data,
 			       &sdr_rw_load_jump_mgr_regs->load_jump_add2);
-			writel(rwcfg->lfsr_wr_rd_dm_bank_0_nop,
+			writel(seq->rwcfg->lfsr_wr_rd_dm_bank_0_nop,
 			       &sdr_rw_load_jump_mgr_regs->load_jump_add3);
 		} else {
-			mcc_instruction = rwcfg->lfsr_wr_rd_bank_0_wl_1;
-			writel(rwcfg->lfsr_wr_rd_bank_0_data,
+			mcc_instruction = seq->rwcfg->lfsr_wr_rd_bank_0_wl_1;
+			writel(seq->rwcfg->lfsr_wr_rd_bank_0_data,
 			       &sdr_rw_load_jump_mgr_regs->load_jump_add2);
-			writel(rwcfg->lfsr_wr_rd_bank_0_nop,
+			writel(seq->rwcfg->lfsr_wr_rd_bank_0_nop,
 			       &sdr_rw_load_jump_mgr_regs->load_jump_add3);
 		}
 	} else if (rw_wl_nop_cycles == 0) {
@@ -1094,12 +1102,12 @@
 
 		/* CNTR 3 - Not used */
 		if (test_dm) {
-			mcc_instruction = rwcfg->lfsr_wr_rd_dm_bank_0;
-			writel(rwcfg->lfsr_wr_rd_dm_bank_0_dqs,
+			mcc_instruction = seq->rwcfg->lfsr_wr_rd_dm_bank_0;
+			writel(seq->rwcfg->lfsr_wr_rd_dm_bank_0_dqs,
 			       &sdr_rw_load_jump_mgr_regs->load_jump_add2);
 		} else {
-			mcc_instruction = rwcfg->lfsr_wr_rd_bank_0;
-			writel(rwcfg->lfsr_wr_rd_bank_0_dqs,
+			mcc_instruction = seq->rwcfg->lfsr_wr_rd_bank_0;
+			writel(seq->rwcfg->lfsr_wr_rd_bank_0_dqs,
 			       &sdr_rw_load_jump_mgr_regs->load_jump_add2);
 		}
 	} else {
@@ -1117,12 +1125,12 @@
 		 */
 		writel(rw_wl_nop_cycles - 1, &sdr_rw_load_mgr_regs->load_cntr3);
 		if (test_dm) {
-			mcc_instruction = rwcfg->lfsr_wr_rd_dm_bank_0;
-			writel(rwcfg->lfsr_wr_rd_dm_bank_0_nop,
+			mcc_instruction = seq->rwcfg->lfsr_wr_rd_dm_bank_0;
+			writel(seq->rwcfg->lfsr_wr_rd_dm_bank_0_nop,
 			       &sdr_rw_load_jump_mgr_regs->load_jump_add3);
 		} else {
-			mcc_instruction = rwcfg->lfsr_wr_rd_bank_0;
-			writel(rwcfg->lfsr_wr_rd_bank_0_nop,
+			mcc_instruction = seq->rwcfg->lfsr_wr_rd_bank_0;
+			writel(seq->rwcfg->lfsr_wr_rd_bank_0_nop,
 			       &sdr_rw_load_jump_mgr_regs->load_jump_add3);
 		}
 	}
@@ -1144,10 +1152,10 @@
 	writel(0x30, &sdr_rw_load_mgr_regs->load_cntr1);
 
 	if (test_dm) {
-		writel(rwcfg->lfsr_wr_rd_dm_bank_0_wait,
+		writel(seq->rwcfg->lfsr_wr_rd_dm_bank_0_wait,
 		       &sdr_rw_load_jump_mgr_regs->load_jump_add1);
 	} else {
-		writel(rwcfg->lfsr_wr_rd_bank_0_wait,
+		writel(seq->rwcfg->lfsr_wr_rd_bank_0_wait,
 		       &sdr_rw_load_jump_mgr_regs->load_jump_add1);
 	}
 
@@ -1157,7 +1165,8 @@
 }
 
 /**
- * rw_mgr_mem_calibrate_write_test() - Test writes, check for single/multiple pass
+ * rw_mgr_mem_calibrate_write_test() - Test writes, check for single/multiple
+ * pass
  * @rank_bgn:		Rank number
  * @write_group:	Write Group
  * @use_dm:		Use DM
@@ -1168,36 +1177,38 @@
  * Test writes, can check for a single bit pass or multiple bit pass.
  */
 static int
-rw_mgr_mem_calibrate_write_test(const u32 rank_bgn, const u32 write_group,
+rw_mgr_mem_calibrate_write_test(struct socfpga_sdrseq *seq,
+				const u32 rank_bgn, const u32 write_group,
 				const u32 use_dm, const u32 all_correct,
 				u32 *bit_chk, const u32 all_ranks)
 {
 	const u32 rank_end = all_ranks ?
-				rwcfg->mem_number_of_ranks :
+				seq->rwcfg->mem_number_of_ranks :
 				(rank_bgn + NUM_RANKS_PER_SHADOW_REG);
-	const u32 shift_ratio = rwcfg->mem_dq_per_write_dqs /
-				rwcfg->mem_virtual_groups_per_write_dqs;
-	const u32 correct_mask_vg = param->write_correct_mask_vg;
+	const u32 shift_ratio = seq->rwcfg->mem_dq_per_write_dqs /
+				seq->rwcfg->mem_virtual_groups_per_write_dqs;
+	const u32 correct_mask_vg = seq->param.write_correct_mask_vg;
 
-	u32 tmp_bit_chk, base_rw_mgr;
+	u32 tmp_bit_chk, base_rw_mgr, group;
 	int vg, r;
 
-	*bit_chk = param->write_correct_mask;
+	*bit_chk = seq->param.write_correct_mask;
 
 	for (r = rank_bgn; r < rank_end; r++) {
 		/* Set rank */
-		set_rank_and_odt_mask(r, RW_MGR_ODT_MODE_READ_WRITE);
+		set_rank_and_odt_mask(seq, r, RW_MGR_ODT_MODE_READ_WRITE);
 
 		tmp_bit_chk = 0;
-		for (vg = rwcfg->mem_virtual_groups_per_write_dqs - 1;
+		for (vg = seq->rwcfg->mem_virtual_groups_per_write_dqs - 1;
 		     vg >= 0; vg--) {
 			/* Reset the FIFOs to get pointers to known state. */
 			writel(0, &phy_mgr_cmd->fifo_reset);
 
-			rw_mgr_mem_calibrate_write_test_issue(
-				write_group *
-				rwcfg->mem_virtual_groups_per_write_dqs + vg,
-				use_dm);
+			group = write_group *
+				seq->rwcfg->mem_virtual_groups_per_write_dqs
+				+ vg;
+			rw_mgr_mem_calibrate_write_test_issue(seq, group,
+							      use_dm);
 
 			base_rw_mgr = readl(SDR_PHYGRP_RWMGRGRP_ADDRESS);
 			tmp_bit_chk <<= shift_ratio;
@@ -1207,14 +1218,14 @@
 		*bit_chk &= tmp_bit_chk;
 	}
 
-	set_rank_and_odt_mask(0, RW_MGR_ODT_MODE_OFF);
+	set_rank_and_odt_mask(seq, 0, RW_MGR_ODT_MODE_OFF);
 	if (all_correct) {
 		debug_cond(DLEVEL >= 2,
 			   "write_test(%u,%u,ALL) : %u == %u => %i\n",
 			   write_group, use_dm, *bit_chk,
-			   param->write_correct_mask,
-			   *bit_chk == param->write_correct_mask);
-		return *bit_chk == param->write_correct_mask;
+			   seq->param.write_correct_mask,
+			   *bit_chk == seq->param.write_correct_mask);
+		return *bit_chk == seq->param.write_correct_mask;
 	} else {
 		debug_cond(DLEVEL >= 2,
 			   "write_test(%u,%u,ONE) : %u != %i => %i\n",
@@ -1233,47 +1244,49 @@
  * read test to ensure memory works.
  */
 static int
-rw_mgr_mem_calibrate_read_test_patterns(const u32 rank_bgn, const u32 group,
+rw_mgr_mem_calibrate_read_test_patterns(struct socfpga_sdrseq *seq,
+					const u32 rank_bgn, const u32 group,
 					const u32 all_ranks)
 {
 	const u32 addr = SDR_PHYGRP_RWMGRGRP_ADDRESS |
 			 RW_MGR_RUN_SINGLE_GROUP_OFFSET;
 	const u32 addr_offset =
-			 (group * rwcfg->mem_virtual_groups_per_read_dqs) << 2;
+			 (group * seq->rwcfg->mem_virtual_groups_per_read_dqs)
+			 << 2;
 	const u32 rank_end = all_ranks ?
-				rwcfg->mem_number_of_ranks :
+				seq->rwcfg->mem_number_of_ranks :
 				(rank_bgn + NUM_RANKS_PER_SHADOW_REG);
-	const u32 shift_ratio = rwcfg->mem_dq_per_read_dqs /
-				rwcfg->mem_virtual_groups_per_read_dqs;
-	const u32 correct_mask_vg = param->read_correct_mask_vg;
+	const u32 shift_ratio = seq->rwcfg->mem_dq_per_read_dqs /
+				seq->rwcfg->mem_virtual_groups_per_read_dqs;
+	const u32 correct_mask_vg = seq->param.read_correct_mask_vg;
 
 	u32 tmp_bit_chk, base_rw_mgr, bit_chk;
 	int vg, r;
 	int ret = 0;
 
-	bit_chk = param->read_correct_mask;
+	bit_chk = seq->param.read_correct_mask;
 
 	for (r = rank_bgn; r < rank_end; r++) {
 		/* Set rank */
-		set_rank_and_odt_mask(r, RW_MGR_ODT_MODE_READ_WRITE);
+		set_rank_and_odt_mask(seq, r, RW_MGR_ODT_MODE_READ_WRITE);
 
 		/* Load up a constant bursts of read commands */
 		writel(0x20, &sdr_rw_load_mgr_regs->load_cntr0);
-		writel(rwcfg->guaranteed_read,
+		writel(seq->rwcfg->guaranteed_read,
 		       &sdr_rw_load_jump_mgr_regs->load_jump_add0);
 
 		writel(0x20, &sdr_rw_load_mgr_regs->load_cntr1);
-		writel(rwcfg->guaranteed_read_cont,
+		writel(seq->rwcfg->guaranteed_read_cont,
 		       &sdr_rw_load_jump_mgr_regs->load_jump_add1);
 
 		tmp_bit_chk = 0;
-		for (vg = rwcfg->mem_virtual_groups_per_read_dqs - 1;
+		for (vg = seq->rwcfg->mem_virtual_groups_per_read_dqs - 1;
 		     vg >= 0; vg--) {
 			/* Reset the FIFOs to get pointers to known state. */
 			writel(0, &phy_mgr_cmd->fifo_reset);
 			writel(0, SDR_PHYGRP_RWMGRGRP_ADDRESS |
 				  RW_MGR_RESET_READ_DATAPATH_OFFSET);
-			writel(rwcfg->guaranteed_read,
+			writel(seq->rwcfg->guaranteed_read,
 			       addr + addr_offset + (vg << 2));
 
 			base_rw_mgr = readl(SDR_PHYGRP_RWMGRGRP_ADDRESS);
@@ -1284,33 +1297,35 @@
 		bit_chk &= tmp_bit_chk;
 	}
 
-	writel(rwcfg->clear_dqs_enable, addr + (group << 2));
+	writel(seq->rwcfg->clear_dqs_enable, addr + (group << 2));
 
-	set_rank_and_odt_mask(0, RW_MGR_ODT_MODE_OFF);
+	set_rank_and_odt_mask(seq, 0, RW_MGR_ODT_MODE_OFF);
 
-	if (bit_chk != param->read_correct_mask)
+	if (bit_chk != seq->param.read_correct_mask)
 		ret = -EIO;
 
 	debug_cond(DLEVEL >= 1,
 		   "%s:%d test_load_patterns(%u,ALL) => (%u == %u) => %i\n",
 		   __func__, __LINE__, group, bit_chk,
-		   param->read_correct_mask, ret);
+		   seq->param.read_correct_mask, ret);
 
 	return ret;
 }
 
 /**
- * rw_mgr_mem_calibrate_read_load_patterns() - Load up the patterns for read test
+ * rw_mgr_mem_calibrate_read_load_patterns() - Load up the patterns for read
+ * test
  * @rank_bgn:	Rank number
  * @all_ranks:	Test all ranks
  *
  * Load up the patterns we are going to use during a read test.
  */
-static void rw_mgr_mem_calibrate_read_load_patterns(const u32 rank_bgn,
+static void rw_mgr_mem_calibrate_read_load_patterns(struct socfpga_sdrseq *seq,
+						    const u32 rank_bgn,
 						    const int all_ranks)
 {
 	const u32 rank_end = all_ranks ?
-			rwcfg->mem_number_of_ranks :
+			seq->rwcfg->mem_number_of_ranks :
 			(rank_bgn + NUM_RANKS_PER_SHADOW_REG);
 	u32 r;
 
@@ -1318,34 +1333,35 @@
 
 	for (r = rank_bgn; r < rank_end; r++) {
 		/* set rank */
-		set_rank_and_odt_mask(r, RW_MGR_ODT_MODE_READ_WRITE);
+		set_rank_and_odt_mask(seq, r, RW_MGR_ODT_MODE_READ_WRITE);
 
 		/* Load up a constant bursts */
 		writel(0x20, &sdr_rw_load_mgr_regs->load_cntr0);
 
-		writel(rwcfg->guaranteed_write_wait0,
+		writel(seq->rwcfg->guaranteed_write_wait0,
 		       &sdr_rw_load_jump_mgr_regs->load_jump_add0);
 
 		writel(0x20, &sdr_rw_load_mgr_regs->load_cntr1);
 
-		writel(rwcfg->guaranteed_write_wait1,
+		writel(seq->rwcfg->guaranteed_write_wait1,
 		       &sdr_rw_load_jump_mgr_regs->load_jump_add1);
 
 		writel(0x04, &sdr_rw_load_mgr_regs->load_cntr2);
 
-		writel(rwcfg->guaranteed_write_wait2,
+		writel(seq->rwcfg->guaranteed_write_wait2,
 		       &sdr_rw_load_jump_mgr_regs->load_jump_add2);
 
 		writel(0x04, &sdr_rw_load_mgr_regs->load_cntr3);
 
-		writel(rwcfg->guaranteed_write_wait3,
+		writel(seq->rwcfg->guaranteed_write_wait3,
 		       &sdr_rw_load_jump_mgr_regs->load_jump_add3);
 
-		writel(rwcfg->guaranteed_write, SDR_PHYGRP_RWMGRGRP_ADDRESS |
-						RW_MGR_RUN_SINGLE_GROUP_OFFSET);
+		writel(seq->rwcfg->guaranteed_write,
+		       SDR_PHYGRP_RWMGRGRP_ADDRESS |
+		       RW_MGR_RUN_SINGLE_GROUP_OFFSET);
 	}
 
-	set_rank_and_odt_mask(0, RW_MGR_ODT_MODE_OFF);
+	set_rank_and_odt_mask(seq, 0, RW_MGR_ODT_MODE_OFF);
 }
 
 /**
@@ -1363,36 +1379,37 @@
  * checks than the regular read test.
  */
 static int
-rw_mgr_mem_calibrate_read_test(const u32 rank_bgn, const u32 group,
+rw_mgr_mem_calibrate_read_test(struct socfpga_sdrseq *seq,
+			       const u32 rank_bgn, const u32 group,
 			       const u32 num_tries, const u32 all_correct,
 			       u32 *bit_chk,
 			       const u32 all_groups, const u32 all_ranks)
 {
-	const u32 rank_end = all_ranks ? rwcfg->mem_number_of_ranks :
+	const u32 rank_end = all_ranks ? seq->rwcfg->mem_number_of_ranks :
 		(rank_bgn + NUM_RANKS_PER_SHADOW_REG);
 	const u32 quick_read_mode =
 		((STATIC_CALIB_STEPS & CALIB_SKIP_DELAY_SWEEPS) &&
-		 misccfg->enable_super_quick_calibration);
-	u32 correct_mask_vg = param->read_correct_mask_vg;
+		 seq->misccfg->enable_super_quick_calibration);
+	u32 correct_mask_vg = seq->param.read_correct_mask_vg;
 	u32 tmp_bit_chk;
 	u32 base_rw_mgr;
 	u32 addr;
 
 	int r, vg, ret;
 
-	*bit_chk = param->read_correct_mask;
+	*bit_chk = seq->param.read_correct_mask;
 
 	for (r = rank_bgn; r < rank_end; r++) {
 		/* set rank */
-		set_rank_and_odt_mask(r, RW_MGR_ODT_MODE_READ_WRITE);
+		set_rank_and_odt_mask(seq, r, RW_MGR_ODT_MODE_READ_WRITE);
 
 		writel(0x10, &sdr_rw_load_mgr_regs->load_cntr1);
 
-		writel(rwcfg->read_b2b_wait1,
+		writel(seq->rwcfg->read_b2b_wait1,
 		       &sdr_rw_load_jump_mgr_regs->load_jump_add1);
 
 		writel(0x10, &sdr_rw_load_mgr_regs->load_cntr2);
-		writel(rwcfg->read_b2b_wait2,
+		writel(seq->rwcfg->read_b2b_wait2,
 		       &sdr_rw_load_jump_mgr_regs->load_jump_add2);
 
 		if (quick_read_mode)
@@ -1403,21 +1420,21 @@
 		else
 			writel(0x32, &sdr_rw_load_mgr_regs->load_cntr0);
 
-		writel(rwcfg->read_b2b,
+		writel(seq->rwcfg->read_b2b,
 		       &sdr_rw_load_jump_mgr_regs->load_jump_add0);
 		if (all_groups)
-			writel(rwcfg->mem_if_read_dqs_width *
-			       rwcfg->mem_virtual_groups_per_read_dqs - 1,
+			writel(seq->rwcfg->mem_if_read_dqs_width *
+			       seq->rwcfg->mem_virtual_groups_per_read_dqs - 1,
 			       &sdr_rw_load_mgr_regs->load_cntr3);
 		else
 			writel(0x0, &sdr_rw_load_mgr_regs->load_cntr3);
 
-		writel(rwcfg->read_b2b,
+		writel(seq->rwcfg->read_b2b,
 		       &sdr_rw_load_jump_mgr_regs->load_jump_add3);
 
 		tmp_bit_chk = 0;
-		for (vg = rwcfg->mem_virtual_groups_per_read_dqs - 1; vg >= 0;
-		     vg--) {
+		for (vg = seq->rwcfg->mem_virtual_groups_per_read_dqs - 1;
+		     vg >= 0; vg--) {
 			/* Reset the FIFOs to get pointers to known state. */
 			writel(0, &phy_mgr_cmd->fifo_reset);
 			writel(0, SDR_PHYGRP_RWMGRGRP_ADDRESS |
@@ -1431,14 +1448,15 @@
 				       RW_MGR_RUN_SINGLE_GROUP_OFFSET;
 			}
 
-			writel(rwcfg->read_b2b, addr +
+			writel(seq->rwcfg->read_b2b, addr +
 			       ((group *
-				 rwcfg->mem_virtual_groups_per_read_dqs +
+				 seq->rwcfg->mem_virtual_groups_per_read_dqs +
 				 vg) << 2));
 
 			base_rw_mgr = readl(SDR_PHYGRP_RWMGRGRP_ADDRESS);
-			tmp_bit_chk <<= rwcfg->mem_dq_per_read_dqs /
-					rwcfg->mem_virtual_groups_per_read_dqs;
+			tmp_bit_chk <<=
+				seq->rwcfg->mem_dq_per_read_dqs /
+				seq->rwcfg->mem_virtual_groups_per_read_dqs;
 			tmp_bit_chk |= correct_mask_vg & ~(base_rw_mgr);
 		}
 
@@ -1446,16 +1464,16 @@
 	}
 
 	addr = SDR_PHYGRP_RWMGRGRP_ADDRESS | RW_MGR_RUN_SINGLE_GROUP_OFFSET;
-	writel(rwcfg->clear_dqs_enable, addr + (group << 2));
+	writel(seq->rwcfg->clear_dqs_enable, addr + (group << 2));
 
-	set_rank_and_odt_mask(0, RW_MGR_ODT_MODE_OFF);
+	set_rank_and_odt_mask(seq, 0, RW_MGR_ODT_MODE_OFF);
 
 	if (all_correct) {
-		ret = (*bit_chk == param->read_correct_mask);
+		ret = (*bit_chk == seq->param.read_correct_mask);
 		debug_cond(DLEVEL >= 2,
 			   "%s:%d read_test(%u,ALL,%u) => (%u == %u) => %i\n",
 			   __func__, __LINE__, group, all_groups, *bit_chk,
-			   param->read_correct_mask, ret);
+			   seq->param.read_correct_mask, ret);
 	} else	{
 		ret = (*bit_chk != 0x00);
 		debug_cond(DLEVEL >= 2,
@@ -1477,13 +1495,15 @@
  * Perform a READ test across all memory ranks.
  */
 static int
-rw_mgr_mem_calibrate_read_test_all_ranks(const u32 grp, const u32 num_tries,
+rw_mgr_mem_calibrate_read_test_all_ranks(struct socfpga_sdrseq *seq,
+					 const u32 grp, const u32 num_tries,
 					 const u32 all_correct,
 					 const u32 all_groups)
 {
 	u32 bit_chk;
-	return rw_mgr_mem_calibrate_read_test(0, grp, num_tries, all_correct,
-					      &bit_chk, all_groups, 1);
+	return rw_mgr_mem_calibrate_read_test(seq, 0, grp, num_tries,
+					      all_correct, &bit_chk, all_groups,
+					      1);
 }
 
 /**
@@ -1503,11 +1523,11 @@
  *
  * Decrease VFIFO value.
  */
-static void rw_mgr_decr_vfifo(const u32 grp)
+static void rw_mgr_decr_vfifo(struct socfpga_sdrseq *seq, const u32 grp)
 {
 	u32 i;
 
-	for (i = 0; i < misccfg->read_valid_fifo_size - 1; i++)
+	for (i = 0; i < seq->misccfg->read_valid_fifo_size - 1; i++)
 		rw_mgr_incr_vfifo(grp);
 }
 
@@ -1517,15 +1537,16 @@
  *
  * Push VFIFO until a failing read happens.
  */
-static int find_vfifo_failing_read(const u32 grp)
+static int find_vfifo_failing_read(struct socfpga_sdrseq *seq,
+				   const u32 grp)
 {
 	u32 v, ret, fail_cnt = 0;
 
-	for (v = 0; v < misccfg->read_valid_fifo_size; v++) {
+	for (v = 0; v < seq->misccfg->read_valid_fifo_size; v++) {
 		debug_cond(DLEVEL >= 2, "%s:%d: vfifo %u\n",
 			   __func__, __LINE__, v);
-		ret = rw_mgr_mem_calibrate_read_test_all_ranks(grp, 1,
-						PASS_ONE_BIT, 0);
+		ret = rw_mgr_mem_calibrate_read_test_all_ranks(seq, grp, 1,
+							       PASS_ONE_BIT, 0);
 		if (!ret) {
 			fail_cnt++;
 
@@ -1553,21 +1574,22 @@
  *
  * Find working or non-working DQS enable phase setting.
  */
-static int sdr_find_phase_delay(int working, int delay, const u32 grp,
-				u32 *work, const u32 work_inc, u32 *pd)
+static int sdr_find_phase_delay(struct socfpga_sdrseq *seq, int working,
+				int delay, const u32 grp, u32 *work,
+				const u32 work_inc, u32 *pd)
 {
-	const u32 max = delay ? iocfg->dqs_en_delay_max :
-				iocfg->dqs_en_phase_max;
+	const u32 max = delay ? seq->iocfg->dqs_en_delay_max :
+				seq->iocfg->dqs_en_phase_max;
 	u32 ret;
 
 	for (; *pd <= max; (*pd)++) {
 		if (delay)
-			scc_mgr_set_dqs_en_delay_all_ranks(grp, *pd);
+			scc_mgr_set_dqs_en_delay_all_ranks(seq, grp, *pd);
 		else
-			scc_mgr_set_dqs_en_phase_all_ranks(grp, *pd);
+			scc_mgr_set_dqs_en_phase_all_ranks(seq, grp, *pd);
 
-		ret = rw_mgr_mem_calibrate_read_test_all_ranks(grp, 1,
-					PASS_ONE_BIT, 0);
+		ret = rw_mgr_mem_calibrate_read_test_all_ranks(seq, grp, 1,
+							       PASS_ONE_BIT, 0);
 		if (!working)
 			ret = !ret;
 
@@ -1590,22 +1612,22 @@
  *
  * Find working or non-working DQS enable phase setting.
  */
-static int sdr_find_phase(int working, const u32 grp, u32 *work,
-			  u32 *i, u32 *p)
+static int sdr_find_phase(struct socfpga_sdrseq *seq, int working,
+			  const u32 grp, u32 *work, u32 *i, u32 *p)
 {
-	const u32 end = misccfg->read_valid_fifo_size + (working ? 0 : 1);
+	const u32 end = seq->misccfg->read_valid_fifo_size + (working ? 0 : 1);
 	int ret;
 
 	for (; *i < end; (*i)++) {
 		if (working)
 			*p = 0;
 
-		ret = sdr_find_phase_delay(working, 0, grp, work,
-					   iocfg->delay_per_opa_tap, p);
+		ret = sdr_find_phase_delay(seq, working, 0, grp, work,
+					   seq->iocfg->delay_per_opa_tap, p);
 		if (!ret)
 			return 0;
 
-		if (*p > iocfg->dqs_en_phase_max) {
+		if (*p > seq->iocfg->dqs_en_phase_max) {
 			/* Fiddle with FIFO. */
 			rw_mgr_incr_vfifo(grp);
 			if (!working)
@@ -1626,22 +1648,22 @@
  *
  * Find working DQS enable phase setting.
  */
-static int sdr_working_phase(const u32 grp, u32 *work_bgn, u32 *d,
-			     u32 *p, u32 *i)
+static int sdr_working_phase(struct socfpga_sdrseq *seq, const u32 grp,
+			     u32 *work_bgn, u32 *d, u32 *p, u32 *i)
 {
-	const u32 dtaps_per_ptap = iocfg->delay_per_opa_tap /
-				   iocfg->delay_per_dqs_en_dchain_tap;
+	const u32 dtaps_per_ptap = seq->iocfg->delay_per_opa_tap /
+				   seq->iocfg->delay_per_dqs_en_dchain_tap;
 	int ret;
 
 	*work_bgn = 0;
 
 	for (*d = 0; *d <= dtaps_per_ptap; (*d)++) {
 		*i = 0;
-		scc_mgr_set_dqs_en_delay_all_ranks(grp, *d);
-		ret = sdr_find_phase(1, grp, work_bgn, i, p);
+		scc_mgr_set_dqs_en_delay_all_ranks(seq, grp, *d);
+		ret = sdr_find_phase(seq, 1, grp, work_bgn, i, p);
 		if (!ret)
 			return 0;
-		*work_bgn += iocfg->delay_per_dqs_en_dchain_tap;
+		*work_bgn += seq->iocfg->delay_per_dqs_en_dchain_tap;
 	}
 
 	/* Cannot find working solution */
@@ -1658,43 +1680,44 @@
  *
  * Find DQS enable backup phase setting.
  */
-static void sdr_backup_phase(const u32 grp, u32 *work_bgn, u32 *p)
+static void sdr_backup_phase(struct socfpga_sdrseq *seq, const u32 grp,
+			     u32 *work_bgn, u32 *p)
 {
 	u32 tmp_delay, d;
 	int ret;
 
 	/* Special case code for backing up a phase */
 	if (*p == 0) {
-		*p = iocfg->dqs_en_phase_max;
-		rw_mgr_decr_vfifo(grp);
+		*p = seq->iocfg->dqs_en_phase_max;
+		rw_mgr_decr_vfifo(seq, grp);
 	} else {
 		(*p)--;
 	}
-	tmp_delay = *work_bgn - iocfg->delay_per_opa_tap;
-	scc_mgr_set_dqs_en_phase_all_ranks(grp, *p);
+	tmp_delay = *work_bgn - seq->iocfg->delay_per_opa_tap;
+	scc_mgr_set_dqs_en_phase_all_ranks(seq, grp, *p);
 
-	for (d = 0; d <= iocfg->dqs_en_delay_max && tmp_delay < *work_bgn;
+	for (d = 0; d <= seq->iocfg->dqs_en_delay_max && tmp_delay < *work_bgn;
 	     d++) {
-		scc_mgr_set_dqs_en_delay_all_ranks(grp, d);
+		scc_mgr_set_dqs_en_delay_all_ranks(seq, grp, d);
 
-		ret = rw_mgr_mem_calibrate_read_test_all_ranks(grp, 1,
-					PASS_ONE_BIT, 0);
+		ret = rw_mgr_mem_calibrate_read_test_all_ranks(seq, grp, 1,
+							       PASS_ONE_BIT, 0);
 		if (ret) {
 			*work_bgn = tmp_delay;
 			break;
 		}
 
-		tmp_delay += iocfg->delay_per_dqs_en_dchain_tap;
+		tmp_delay += seq->iocfg->delay_per_dqs_en_dchain_tap;
 	}
 
 	/* Restore VFIFO to old state before we decremented it (if needed). */
 	(*p)++;
-	if (*p > iocfg->dqs_en_phase_max) {
+	if (*p > seq->iocfg->dqs_en_phase_max) {
 		*p = 0;
 		rw_mgr_incr_vfifo(grp);
 	}
 
-	scc_mgr_set_dqs_en_delay_all_ranks(grp, 0);
+	scc_mgr_set_dqs_en_delay_all_ranks(seq, grp, 0);
 }
 
 /**
@@ -1706,19 +1729,20 @@
  *
  * Find non-working DQS enable phase setting.
  */
-static int sdr_nonworking_phase(const u32 grp, u32 *work_end, u32 *p, u32 *i)
+static int sdr_nonworking_phase(struct socfpga_sdrseq *seq,
+				const u32 grp, u32 *work_end, u32 *p, u32 *i)
 {
 	int ret;
 
 	(*p)++;
-	*work_end += iocfg->delay_per_opa_tap;
-	if (*p > iocfg->dqs_en_phase_max) {
+	*work_end += seq->iocfg->delay_per_opa_tap;
+	if (*p > seq->iocfg->dqs_en_phase_max) {
 		/* Fiddle with FIFO. */
 		*p = 0;
 		rw_mgr_incr_vfifo(grp);
 	}
 
-	ret = sdr_find_phase(0, grp, work_end, i, p);
+	ret = sdr_find_phase(seq, 0, grp, work_end, i, p);
 	if (ret) {
 		/* Cannot see edge of failing read. */
 		debug_cond(DLEVEL >= 2, "%s:%d: end: failed\n",
@@ -1736,7 +1760,8 @@
  *
  * Find center of the working DQS enable window.
  */
-static int sdr_find_window_center(const u32 grp, const u32 work_bgn,
+static int sdr_find_window_center(struct socfpga_sdrseq *seq,
+				  const u32 grp, const u32 work_bgn,
 				  const u32 work_end)
 {
 	u32 work_mid;
@@ -1748,37 +1773,41 @@
 	debug_cond(DLEVEL >= 2, "work_bgn=%d work_end=%d work_mid=%d\n",
 		   work_bgn, work_end, work_mid);
 	/* Get the middle delay to be less than a VFIFO delay */
-	tmp_delay = (iocfg->dqs_en_phase_max + 1) * iocfg->delay_per_opa_tap;
+	tmp_delay = (seq->iocfg->dqs_en_phase_max + 1)
+		* seq->iocfg->delay_per_opa_tap;
 
 	debug_cond(DLEVEL >= 2, "vfifo ptap delay %d\n", tmp_delay);
 	work_mid %= tmp_delay;
 	debug_cond(DLEVEL >= 2, "new work_mid %d\n", work_mid);
 
-	tmp_delay = rounddown(work_mid, iocfg->delay_per_opa_tap);
-	if (tmp_delay > iocfg->dqs_en_phase_max * iocfg->delay_per_opa_tap)
-		tmp_delay = iocfg->dqs_en_phase_max * iocfg->delay_per_opa_tap;
-	p = tmp_delay / iocfg->delay_per_opa_tap;
+	tmp_delay = rounddown(work_mid, seq->iocfg->delay_per_opa_tap);
+	if (tmp_delay > seq->iocfg->dqs_en_phase_max
+		* seq->iocfg->delay_per_opa_tap) {
+		tmp_delay = seq->iocfg->dqs_en_phase_max
+			* seq->iocfg->delay_per_opa_tap;
+	}
+	p = tmp_delay / seq->iocfg->delay_per_opa_tap;
 
 	debug_cond(DLEVEL >= 2, "new p %d, tmp_delay=%d\n", p, tmp_delay);
 
 	d = DIV_ROUND_UP(work_mid - tmp_delay,
-			 iocfg->delay_per_dqs_en_dchain_tap);
-	if (d > iocfg->dqs_en_delay_max)
-		d = iocfg->dqs_en_delay_max;
-	tmp_delay += d * iocfg->delay_per_dqs_en_dchain_tap;
+			 seq->iocfg->delay_per_dqs_en_dchain_tap);
+	if (d > seq->iocfg->dqs_en_delay_max)
+		d = seq->iocfg->dqs_en_delay_max;
+	tmp_delay += d * seq->iocfg->delay_per_dqs_en_dchain_tap;
 
 	debug_cond(DLEVEL >= 2, "new d %d, tmp_delay=%d\n", d, tmp_delay);
 
-	scc_mgr_set_dqs_en_phase_all_ranks(grp, p);
-	scc_mgr_set_dqs_en_delay_all_ranks(grp, d);
+	scc_mgr_set_dqs_en_phase_all_ranks(seq, grp, p);
+	scc_mgr_set_dqs_en_delay_all_ranks(seq, grp, d);
 
 	/*
 	 * push vfifo until we can successfully calibrate. We can do this
 	 * because the largest possible margin in 1 VFIFO cycle.
 	 */
-	for (i = 0; i < misccfg->read_valid_fifo_size; i++) {
+	for (i = 0; i < seq->misccfg->read_valid_fifo_size; i++) {
 		debug_cond(DLEVEL >= 2, "find_dqs_en_phase: center\n");
-		if (rw_mgr_mem_calibrate_read_test_all_ranks(grp, 1,
+		if (rw_mgr_mem_calibrate_read_test_all_ranks(seq, grp, 1,
 							     PASS_ONE_BIT,
 							     0)) {
 			debug_cond(DLEVEL >= 2,
@@ -1797,12 +1826,15 @@
 }
 
 /**
- * rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase() - Find a good DQS enable to use
+ * rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase() - Find a good DQS enable to
+ * use
  * @grp:	Read/Write Group
  *
  * Find a good DQS enable to use.
  */
-static int rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(const u32 grp)
+static int
+rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(struct socfpga_sdrseq *seq,
+					     const u32 grp)
 {
 	u32 d, p, i;
 	u32 dtaps_per_ptap;
@@ -1814,19 +1846,19 @@
 
 	reg_file_set_sub_stage(CAL_SUBSTAGE_VFIFO_CENTER);
 
-	scc_mgr_set_dqs_en_delay_all_ranks(grp, 0);
-	scc_mgr_set_dqs_en_phase_all_ranks(grp, 0);
+	scc_mgr_set_dqs_en_delay_all_ranks(seq, grp, 0);
+	scc_mgr_set_dqs_en_phase_all_ranks(seq, grp, 0);
 
 	/* Step 0: Determine number of delay taps for each phase tap. */
-	dtaps_per_ptap = iocfg->delay_per_opa_tap /
-			 iocfg->delay_per_dqs_en_dchain_tap;
+	dtaps_per_ptap = seq->iocfg->delay_per_opa_tap /
+			 seq->iocfg->delay_per_dqs_en_dchain_tap;
 
 	/* Step 1: First push vfifo until we get a failing read. */
-	find_vfifo_failing_read(grp);
+	find_vfifo_failing_read(seq, grp);
 
 	/* Step 2: Find first working phase, increment in ptaps. */
 	work_bgn = 0;
-	ret = sdr_working_phase(grp, &work_bgn, &d, &p, &i);
+	ret = sdr_working_phase(seq, grp, &work_bgn, &d, &p, &i);
 	if (ret)
 		return ret;
 
@@ -1842,13 +1874,13 @@
 		 * Step 3a: If we have room, back off by one and
 		 *          increment in dtaps.
 		 */
-		sdr_backup_phase(grp, &work_bgn, &p);
+		sdr_backup_phase(seq, grp, &work_bgn, &p);
 
 		/*
 		 * Step 4a: go forward from working phase to non working
 		 * phase, increment in ptaps.
 		 */
-		ret = sdr_nonworking_phase(grp, &work_end, &p, &i);
+		ret = sdr_nonworking_phase(seq, grp, &work_end, &p, &i);
 		if (ret)
 			return ret;
 
@@ -1856,14 +1888,14 @@
 
 		/* Special case code for backing up a phase */
 		if (p == 0) {
-			p = iocfg->dqs_en_phase_max;
-			rw_mgr_decr_vfifo(grp);
+			p = seq->iocfg->dqs_en_phase_max;
+			rw_mgr_decr_vfifo(seq, grp);
 		} else {
 			p = p - 1;
 		}
 
-		work_end -= iocfg->delay_per_opa_tap;
-		scc_mgr_set_dqs_en_phase_all_ranks(grp, p);
+		work_end -= seq->iocfg->delay_per_opa_tap;
+		scc_mgr_set_dqs_en_phase_all_ranks(seq, grp, p);
 
 		d = 0;
 
@@ -1872,12 +1904,12 @@
 	}
 
 	/* The dtap increment to find the failing edge is done here. */
-	sdr_find_phase_delay(0, 1, grp, &work_end,
-			     iocfg->delay_per_dqs_en_dchain_tap, &d);
+	sdr_find_phase_delay(seq, 0, 1, grp, &work_end,
+			     seq->iocfg->delay_per_dqs_en_dchain_tap, &d);
 
 	/* Go back to working dtap */
 	if (d != 0)
-		work_end -= iocfg->delay_per_dqs_en_dchain_tap;
+		work_end -= seq->iocfg->delay_per_dqs_en_dchain_tap;
 
 	debug_cond(DLEVEL >= 2,
 		   "%s:%d p/d: ptap=%u dtap=%u end=%u\n",
@@ -1903,8 +1935,8 @@
 
 	/* Special case code for backing up a phase */
 	if (p == 0) {
-		p = iocfg->dqs_en_phase_max;
-		rw_mgr_decr_vfifo(grp);
+		p = seq->iocfg->dqs_en_phase_max;
+		rw_mgr_decr_vfifo(seq, grp);
 		debug_cond(DLEVEL >= 2, "%s:%d backedup cycle/phase: p=%u\n",
 			   __func__, __LINE__, p);
 	} else {
@@ -1913,7 +1945,7 @@
 			   __func__, __LINE__, p);
 	}
 
-	scc_mgr_set_dqs_en_phase_all_ranks(grp, p);
+	scc_mgr_set_dqs_en_phase_all_ranks(seq, grp, p);
 
 	/*
 	 * Increase dtap until we first see a passing read (in case the
@@ -1927,14 +1959,14 @@
 
 	initial_failing_dtap = d;
 
-	found_passing_read = !sdr_find_phase_delay(1, 1, grp, NULL, 0, &d);
+	found_passing_read = !sdr_find_phase_delay(seq, 1, 1, grp, NULL, 0, &d);
 	if (found_passing_read) {
 		/* Find a failing read. */
 		debug_cond(DLEVEL >= 2, "%s:%d find failing read\n",
 			   __func__, __LINE__);
 		d++;
-		found_failing_read = !sdr_find_phase_delay(0, 1, grp, NULL, 0,
-							   &d);
+		found_failing_read = !sdr_find_phase_delay(seq, 0, 1, grp, NULL,
+							   0, &d);
 	} else {
 		debug_cond(DLEVEL >= 1,
 			   "%s:%d failed to calculate dtaps per ptap. Fall back on static value\n",
@@ -1944,7 +1976,7 @@
 	/*
 	 * The dynamically calculated dtaps_per_ptap is only valid if we
 	 * found a passing/failing read. If we didn't, it means d hit the max
-	 * (iocfg->dqs_en_delay_max). Otherwise, dtaps_per_ptap retains its
+	 * (seq->iocfg->dqs_en_delay_max). Otherwise, dtaps_per_ptap retains its
 	 * statically calculated value.
 	 */
 	if (found_passing_read && found_failing_read)
@@ -1955,7 +1987,7 @@
 		   __func__, __LINE__, d, initial_failing_dtap, dtaps_per_ptap);
 
 	/* Step 6: Find the centre of the window. */
-	ret = sdr_find_window_center(grp, work_bgn, work_end);
+	ret = sdr_find_window_center(seq, grp, work_bgn, work_end);
 
 	return ret;
 }
@@ -1973,33 +2005,35 @@
  *
  * Test if the found edge is valid.
  */
-static u32 search_stop_check(const int write, const int d, const int rank_bgn,
+static u32 search_stop_check(struct socfpga_sdrseq *seq, const int write,
+			     const int d, const int rank_bgn,
 			     const u32 write_group, const u32 read_group,
 			     u32 *bit_chk, u32 *sticky_bit_chk,
 			     const u32 use_read_test)
 {
-	const u32 ratio = rwcfg->mem_if_read_dqs_width /
-			  rwcfg->mem_if_write_dqs_width;
-	const u32 correct_mask = write ? param->write_correct_mask :
-					 param->read_correct_mask;
-	const u32 per_dqs = write ? rwcfg->mem_dq_per_write_dqs :
-				    rwcfg->mem_dq_per_read_dqs;
+	const u32 ratio = seq->rwcfg->mem_if_read_dqs_width /
+			  seq->rwcfg->mem_if_write_dqs_width;
+	const u32 correct_mask = write ? seq->param.write_correct_mask :
+					 seq->param.read_correct_mask;
+	const u32 per_dqs = write ? seq->rwcfg->mem_dq_per_write_dqs :
+				    seq->rwcfg->mem_dq_per_read_dqs;
 	u32 ret;
 	/*
 	 * Stop searching when the read test doesn't pass AND when
 	 * we've seen a passing read on every bit.
 	 */
 	if (write) {			/* WRITE-ONLY */
-		ret = !rw_mgr_mem_calibrate_write_test(rank_bgn, write_group,
-							 0, PASS_ONE_BIT,
-							 bit_chk, 0);
+		ret = !rw_mgr_mem_calibrate_write_test(seq, rank_bgn,
+							 write_group, 0,
+							 PASS_ONE_BIT, bit_chk,
+							 0);
 	} else if (use_read_test) {	/* READ-ONLY */
-		ret = !rw_mgr_mem_calibrate_read_test(rank_bgn, read_group,
+		ret = !rw_mgr_mem_calibrate_read_test(seq, rank_bgn, read_group,
 							NUM_READ_PB_TESTS,
 							PASS_ONE_BIT, bit_chk,
 							0, 0);
 	} else {			/* READ-ONLY */
-		rw_mgr_mem_calibrate_write_test(rank_bgn, write_group, 0,
+		rw_mgr_mem_calibrate_write_test(seq, rank_bgn, write_group, 0,
 						PASS_ONE_BIT, bit_chk, 0);
 		*bit_chk = *bit_chk >> (per_dqs *
 			(read_group - (write_group * ratio)));
@@ -2028,29 +2062,30 @@
  *
  * Find left edge of DQ/DQS working phase.
  */
-static void search_left_edge(const int write, const int rank_bgn,
-	const u32 write_group, const u32 read_group, const u32 test_bgn,
-	u32 *sticky_bit_chk,
-	int *left_edge, int *right_edge, const u32 use_read_test)
+static void search_left_edge(struct socfpga_sdrseq *seq, const int write,
+			     const int rank_bgn, const u32 write_group,
+			     const u32 read_group, const u32 test_bgn,
+			     u32 *sticky_bit_chk, int *left_edge,
+			     int *right_edge, const u32 use_read_test)
 {
-	const u32 delay_max = write ? iocfg->io_out1_delay_max :
-				      iocfg->io_in_delay_max;
-	const u32 dqs_max = write ? iocfg->io_out1_delay_max :
-				    iocfg->dqs_in_delay_max;
-	const u32 per_dqs = write ? rwcfg->mem_dq_per_write_dqs :
-				    rwcfg->mem_dq_per_read_dqs;
+	const u32 delay_max = write ? seq->iocfg->io_out1_delay_max :
+				      seq->iocfg->io_in_delay_max;
+	const u32 dqs_max = write ? seq->iocfg->io_out1_delay_max :
+				    seq->iocfg->dqs_in_delay_max;
+	const u32 per_dqs = write ? seq->rwcfg->mem_dq_per_write_dqs :
+				    seq->rwcfg->mem_dq_per_read_dqs;
 	u32 stop, bit_chk;
 	int i, d;
 
 	for (d = 0; d <= dqs_max; d++) {
 		if (write)
-			scc_mgr_apply_group_dq_out1_delay(d);
+			scc_mgr_apply_group_dq_out1_delay(seq, d);
 		else
-			scc_mgr_apply_group_dq_in_delay(test_bgn, d);
+			scc_mgr_apply_group_dq_in_delay(seq, test_bgn, d);
 
 		writel(0, &sdr_scc_mgr->update);
 
-		stop = search_stop_check(write, d, rank_bgn, write_group,
+		stop = search_stop_check(seq, write, d, rank_bgn, write_group,
 					 read_group, &bit_chk, sticky_bit_chk,
 					 use_read_test);
 		if (stop == 1)
@@ -2080,9 +2115,9 @@
 
 	/* Reset DQ delay chains to 0 */
 	if (write)
-		scc_mgr_apply_group_dq_out1_delay(0);
+		scc_mgr_apply_group_dq_out1_delay(seq, 0);
 	else
-		scc_mgr_apply_group_dq_in_delay(test_bgn, 0);
+		scc_mgr_apply_group_dq_in_delay(seq, test_bgn, 0);
 
 	*sticky_bit_chk = 0;
 	for (i = per_dqs - 1; i >= 0; i--) {
@@ -2138,31 +2173,33 @@
  *
  * Find right edge of DQ/DQS working phase.
  */
-static int search_right_edge(const int write, const int rank_bgn,
-	const u32 write_group, const u32 read_group,
-	const int start_dqs, const int start_dqs_en,
-	u32 *sticky_bit_chk,
-	int *left_edge, int *right_edge, const u32 use_read_test)
+static int search_right_edge(struct socfpga_sdrseq *seq, const int write,
+			     const int rank_bgn, const u32 write_group,
+			     const u32 read_group, const int start_dqs,
+			     const int start_dqs_en, u32 *sticky_bit_chk,
+			     int *left_edge, int *right_edge,
+			     const u32 use_read_test)
 {
-	const u32 delay_max = write ? iocfg->io_out1_delay_max :
-				      iocfg->io_in_delay_max;
-	const u32 dqs_max = write ? iocfg->io_out1_delay_max :
-				    iocfg->dqs_in_delay_max;
-	const u32 per_dqs = write ? rwcfg->mem_dq_per_write_dqs :
-				    rwcfg->mem_dq_per_read_dqs;
+	const u32 delay_max = write ? seq->iocfg->io_out1_delay_max :
+				      seq->iocfg->io_in_delay_max;
+	const u32 dqs_max = write ? seq->iocfg->io_out1_delay_max :
+				    seq->iocfg->dqs_in_delay_max;
+	const u32 per_dqs = write ? seq->rwcfg->mem_dq_per_write_dqs :
+				    seq->rwcfg->mem_dq_per_read_dqs;
 	u32 stop, bit_chk;
 	int i, d;
 
 	for (d = 0; d <= dqs_max - start_dqs; d++) {
 		if (write) {	/* WRITE-ONLY */
-			scc_mgr_apply_group_dqs_io_and_oct_out1(write_group,
+			scc_mgr_apply_group_dqs_io_and_oct_out1(seq,
+								write_group,
 								d + start_dqs);
 		} else {	/* READ-ONLY */
 			scc_mgr_set_dqs_bus_in_delay(read_group, d + start_dqs);
-			if (iocfg->shift_dqs_en_when_shift_dqs) {
+			if (seq->iocfg->shift_dqs_en_when_shift_dqs) {
 				u32 delay = d + start_dqs_en;
-				if (delay > iocfg->dqs_en_delay_max)
-					delay = iocfg->dqs_en_delay_max;
+				if (delay > seq->iocfg->dqs_en_delay_max)
+					delay = seq->iocfg->dqs_en_delay_max;
 				scc_mgr_set_dqs_en_delay(read_group, delay);
 			}
 			scc_mgr_load_dqs(read_group);
@@ -2170,12 +2207,13 @@
 
 		writel(0, &sdr_scc_mgr->update);
 
-		stop = search_stop_check(write, d, rank_bgn, write_group,
+		stop = search_stop_check(seq, write, d, rank_bgn, write_group,
 					 read_group, &bit_chk, sticky_bit_chk,
 					 use_read_test);
 		if (stop == 1) {
 			if (write && (d == 0)) {	/* WRITE-ONLY */
-				for (i = 0; i < rwcfg->mem_dq_per_write_dqs;
+				for (i = 0;
+				     i < seq->rwcfg->mem_dq_per_write_dqs;
 				     i++) {
 					/*
 					 * d = 0 failed, but it passed when
@@ -2263,11 +2301,12 @@
  *
  * Find index and value of the middle of the DQ/DQS working phase.
  */
-static int get_window_mid_index(const int write, int *left_edge,
+static int get_window_mid_index(struct socfpga_sdrseq *seq,
+				const int write, int *left_edge,
 				int *right_edge, int *mid_min)
 {
-	const u32 per_dqs = write ? rwcfg->mem_dq_per_write_dqs :
-				    rwcfg->mem_dq_per_read_dqs;
+	const u32 per_dqs = write ? seq->rwcfg->mem_dq_per_write_dqs :
+				    seq->rwcfg->mem_dq_per_read_dqs;
 	int i, mid, min_index;
 
 	/* Find middle of window for each DQ bit */
@@ -2310,15 +2349,16 @@
  *
  * Align the DQ/DQS windows in each group.
  */
-static void center_dq_windows(const int write, int *left_edge, int *right_edge,
+static void center_dq_windows(struct socfpga_sdrseq *seq,
+			      const int write, int *left_edge, int *right_edge,
 			      const int mid_min, const int orig_mid_min,
 			      const int min_index, const int test_bgn,
 			      int *dq_margin, int *dqs_margin)
 {
-	const s32 delay_max = write ? iocfg->io_out1_delay_max :
-				      iocfg->io_in_delay_max;
-	const s32 per_dqs = write ? rwcfg->mem_dq_per_write_dqs :
-				    rwcfg->mem_dq_per_read_dqs;
+	const s32 delay_max = write ? seq->iocfg->io_out1_delay_max :
+				      seq->iocfg->io_in_delay_max;
+	const s32 per_dqs = write ? seq->rwcfg->mem_dq_per_write_dqs :
+				    seq->rwcfg->mem_dq_per_read_dqs;
 	const s32 delay_off = write ? SCC_MGR_IO_OUT1_DELAY_OFFSET :
 				      SCC_MGR_IO_IN_DELAY_OFFSET;
 	const s32 addr = SDR_PHYGRP_SCCGRP_ADDRESS | delay_off;
@@ -2385,9 +2425,12 @@
  *
  * Per-bit deskew DQ and centering.
  */
-static int rw_mgr_mem_calibrate_vfifo_center(const u32 rank_bgn,
-			const u32 rw_group, const u32 test_bgn,
-			const int use_read_test, const int update_fom)
+static int rw_mgr_mem_calibrate_vfifo_center(struct socfpga_sdrseq *seq,
+					     const u32 rank_bgn,
+					     const u32 rw_group,
+					     const u32 test_bgn,
+					     const int use_read_test,
+					     const int update_fom)
 {
 	const u32 addr =
 		SDR_PHYGRP_SCCGRP_ADDRESS + SCC_MGR_DQS_IN_DELAY_OFFSET +
@@ -2397,36 +2440,36 @@
 	 * signed numbers.
 	 */
 	u32 sticky_bit_chk;
-	int32_t left_edge[rwcfg->mem_dq_per_read_dqs];
-	int32_t right_edge[rwcfg->mem_dq_per_read_dqs];
-	int32_t orig_mid_min, mid_min;
-	int32_t new_dqs, start_dqs, start_dqs_en = 0, final_dqs_en;
-	int32_t dq_margin, dqs_margin;
+	s32 left_edge[seq->rwcfg->mem_dq_per_read_dqs];
+	s32 right_edge[seq->rwcfg->mem_dq_per_read_dqs];
+	s32 orig_mid_min, mid_min;
+	s32 new_dqs, start_dqs, start_dqs_en = 0, final_dqs_en;
+	s32 dq_margin, dqs_margin;
 	int i, min_index;
 	int ret;
 
 	debug("%s:%d: %u %u", __func__, __LINE__, rw_group, test_bgn);
 
 	start_dqs = readl(addr);
-	if (iocfg->shift_dqs_en_when_shift_dqs)
-		start_dqs_en = readl(addr - iocfg->dqs_en_delay_offset);
+	if (seq->iocfg->shift_dqs_en_when_shift_dqs)
+		start_dqs_en = readl(addr - seq->iocfg->dqs_en_delay_offset);
 
 	/* set the left and right edge of each bit to an illegal value */
-	/* use (iocfg->io_in_delay_max + 1) as an illegal value */
+	/* use (seq->iocfg->io_in_delay_max + 1) as an illegal value */
 	sticky_bit_chk = 0;
-	for (i = 0; i < rwcfg->mem_dq_per_read_dqs; i++) {
-		left_edge[i]  = iocfg->io_in_delay_max + 1;
-		right_edge[i] = iocfg->io_in_delay_max + 1;
+	for (i = 0; i < seq->rwcfg->mem_dq_per_read_dqs; i++) {
+		left_edge[i]  = seq->iocfg->io_in_delay_max + 1;
+		right_edge[i] = seq->iocfg->io_in_delay_max + 1;
 	}
 
 	/* Search for the left edge of the window for each bit */
-	search_left_edge(0, rank_bgn, rw_group, rw_group, test_bgn,
+	search_left_edge(seq, 0, rank_bgn, rw_group, rw_group, test_bgn,
 			 &sticky_bit_chk,
 			 left_edge, right_edge, use_read_test);
 
 
 	/* Search for the right edge of the window for each bit */
-	ret = search_right_edge(0, rank_bgn, rw_group, rw_group,
+	ret = search_right_edge(seq, 0, rank_bgn, rw_group, rw_group,
 				start_dqs, start_dqs_en,
 				&sticky_bit_chk,
 				left_edge, right_edge, use_read_test);
@@ -2437,7 +2480,7 @@
 		 * dqs/ck relationships.
 		 */
 		scc_mgr_set_dqs_bus_in_delay(rw_group, start_dqs);
-		if (iocfg->shift_dqs_en_when_shift_dqs)
+		if (seq->iocfg->shift_dqs_en_when_shift_dqs)
 			scc_mgr_set_dqs_en_delay(rw_group, start_dqs_en);
 
 		scc_mgr_load_dqs(rw_group);
@@ -2447,26 +2490,27 @@
 			   "%s:%d vfifo_center: failed to find edge [%u]: %d %d",
 			   __func__, __LINE__, i, left_edge[i], right_edge[i]);
 		if (use_read_test) {
-			set_failing_group_stage(rw_group *
-				rwcfg->mem_dq_per_read_dqs + i,
+			set_failing_group_stage(seq, rw_group *
+				seq->rwcfg->mem_dq_per_read_dqs + i,
 				CAL_STAGE_VFIFO,
 				CAL_SUBSTAGE_VFIFO_CENTER);
 		} else {
-			set_failing_group_stage(rw_group *
-				rwcfg->mem_dq_per_read_dqs + i,
+			set_failing_group_stage(seq, rw_group *
+				seq->rwcfg->mem_dq_per_read_dqs + i,
 				CAL_STAGE_VFIFO_AFTER_WRITES,
 				CAL_SUBSTAGE_VFIFO_CENTER);
 		}
 		return -EIO;
 	}
 
-	min_index = get_window_mid_index(0, left_edge, right_edge, &mid_min);
+	min_index = get_window_mid_index(seq, 0, left_edge, right_edge,
+					 &mid_min);
 
 	/* Determine the amount we can change DQS (which is -mid_min) */
 	orig_mid_min = mid_min;
 	new_dqs = start_dqs - mid_min;
-	if (new_dqs > iocfg->dqs_in_delay_max)
-		new_dqs = iocfg->dqs_in_delay_max;
+	if (new_dqs > seq->iocfg->dqs_in_delay_max)
+		new_dqs = seq->iocfg->dqs_in_delay_max;
 	else if (new_dqs < 0)
 		new_dqs = 0;
 
@@ -2474,10 +2518,10 @@
 	debug_cond(DLEVEL >= 1, "vfifo_center: new mid_min=%d new_dqs=%d\n",
 		   mid_min, new_dqs);
 
-	if (iocfg->shift_dqs_en_when_shift_dqs) {
-		if (start_dqs_en - mid_min > iocfg->dqs_en_delay_max)
+	if (seq->iocfg->shift_dqs_en_when_shift_dqs) {
+		if (start_dqs_en - mid_min > seq->iocfg->dqs_en_delay_max)
 			mid_min += start_dqs_en - mid_min -
-				   iocfg->dqs_en_delay_max;
+				   seq->iocfg->dqs_en_delay_max;
 		else if (start_dqs_en - mid_min < 0)
 			mid_min += start_dqs_en - mid_min;
 	}
@@ -2486,15 +2530,15 @@
 	debug_cond(DLEVEL >= 1,
 		   "vfifo_center: start_dqs=%d start_dqs_en=%d new_dqs=%d mid_min=%d\n",
 		   start_dqs,
-		   iocfg->shift_dqs_en_when_shift_dqs ? start_dqs_en : -1,
+		   seq->iocfg->shift_dqs_en_when_shift_dqs ? start_dqs_en : -1,
 		   new_dqs, mid_min);
 
 	/* Add delay to bring centre of all DQ windows to the same "level". */
-	center_dq_windows(0, left_edge, right_edge, mid_min, orig_mid_min,
+	center_dq_windows(seq, 0, left_edge, right_edge, mid_min, orig_mid_min,
 			  min_index, test_bgn, &dq_margin, &dqs_margin);
 
 	/* Move DQS-en */
-	if (iocfg->shift_dqs_en_when_shift_dqs) {
+	if (seq->iocfg->shift_dqs_en_when_shift_dqs) {
 		final_dqs_en = start_dqs_en - mid_min;
 		scc_mgr_set_dqs_en_delay(rw_group, final_dqs_en);
 		scc_mgr_load_dqs(rw_group);
@@ -2520,7 +2564,8 @@
 }
 
 /**
- * rw_mgr_mem_calibrate_guaranteed_write() - Perform guaranteed write into the device
+ * rw_mgr_mem_calibrate_guaranteed_write() - Perform guaranteed write into the
+ * device
  * @rw_group:	Read/Write Group
  * @phase:	DQ/DQS phase
  *
@@ -2528,13 +2573,14 @@
  * device, the sequencer uses a guaranteed write mechanism to write data into
  * the memory device.
  */
-static int rw_mgr_mem_calibrate_guaranteed_write(const u32 rw_group,
+static int rw_mgr_mem_calibrate_guaranteed_write(struct socfpga_sdrseq *seq,
+						 const u32 rw_group,
 						 const u32 phase)
 {
 	int ret;
 
 	/* Set a particular DQ/DQS phase. */
-	scc_mgr_set_dqdqs_output_phase_all_ranks(rw_group, phase);
+	scc_mgr_set_dqdqs_output_phase_all_ranks(seq, rw_group, phase);
 
 	debug_cond(DLEVEL >= 1, "%s:%d guaranteed write: g=%u p=%u\n",
 		   __func__, __LINE__, rw_group, phase);
@@ -2544,16 +2590,16 @@
 	 * Load up the patterns used by read calibration using the
 	 * current DQDQS phase.
 	 */
-	rw_mgr_mem_calibrate_read_load_patterns(0, 1);
+	rw_mgr_mem_calibrate_read_load_patterns(seq, 0, 1);
 
-	if (gbl->phy_debug_mode_flags & PHY_DEBUG_DISABLE_GUARANTEED_READ)
+	if (seq->gbl.phy_debug_mode_flags & PHY_DEBUG_DISABLE_GUARANTEED_READ)
 		return 0;
 
 	/*
 	 * Altera EMI_RM 2015.05.04 :: Figure 1-26
 	 * Back-to-Back reads of the patterns used for calibration.
 	 */
-	ret = rw_mgr_mem_calibrate_read_test_patterns(0, rw_group, 1);
+	ret = rw_mgr_mem_calibrate_read_test_patterns(seq, 0, rw_group, 1);
 	if (ret)
 		debug_cond(DLEVEL >= 1,
 			   "%s:%d Guaranteed read test failed: g=%u p=%u\n",
@@ -2569,8 +2615,10 @@
  * DQS enable calibration ensures reliable capture of the DQ signal without
  * glitches on the DQS line.
  */
-static int rw_mgr_mem_calibrate_dqs_enable_calibration(const u32 rw_group,
-						       const u32 test_bgn)
+static int
+rw_mgr_mem_calibrate_dqs_enable_calibration(struct socfpga_sdrseq *seq,
+					    const u32 rw_group,
+					    const u32 test_bgn)
 {
 	/*
 	 * Altera EMI_RM 2015.05.04 :: Figure 1-27
@@ -2578,18 +2626,18 @@
 	 */
 
 	/* We start at zero, so have one less dq to devide among */
-	const u32 delay_step = iocfg->io_in_delay_max /
-			       (rwcfg->mem_dq_per_read_dqs - 1);
+	const u32 delay_step = seq->iocfg->io_in_delay_max /
+			       (seq->rwcfg->mem_dq_per_read_dqs - 1);
 	int ret;
 	u32 i, p, d, r;
 
 	debug("%s:%d (%u,%u)\n", __func__, __LINE__, rw_group, test_bgn);
 
 	/* Try different dq_in_delays since the DQ path is shorter than DQS. */
-	for (r = 0; r < rwcfg->mem_number_of_ranks;
+	for (r = 0; r < seq->rwcfg->mem_number_of_ranks;
 	     r += NUM_RANKS_PER_SHADOW_REG) {
 		for (i = 0, p = test_bgn, d = 0;
-		     i < rwcfg->mem_dq_per_read_dqs;
+		     i < seq->rwcfg->mem_dq_per_read_dqs;
 		     i++, p++, d += delay_step) {
 			debug_cond(DLEVEL >= 1,
 				   "%s:%d: g=%u r=%u i=%u p=%u d=%u\n",
@@ -2606,15 +2654,15 @@
 	 * Try rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase across different
 	 * dq_in_delay values
 	 */
-	ret = rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(rw_group);
+	ret = rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(seq, rw_group);
 
 	debug_cond(DLEVEL >= 1,
 		   "%s:%d: g=%u found=%u; Reseting delay chain to zero\n",
 		   __func__, __LINE__, rw_group, !ret);
 
-	for (r = 0; r < rwcfg->mem_number_of_ranks;
+	for (r = 0; r < seq->rwcfg->mem_number_of_ranks;
 	     r += NUM_RANKS_PER_SHADOW_REG) {
-		scc_mgr_apply_group_dq_in_delay(test_bgn, 0);
+		scc_mgr_apply_group_dq_in_delay(seq, test_bgn, 0);
 		writel(0, &sdr_scc_mgr->update);
 	}
 
@@ -2632,7 +2680,8 @@
  * within a group.
  */
 static int
-rw_mgr_mem_calibrate_dq_dqs_centering(const u32 rw_group, const u32 test_bgn,
+rw_mgr_mem_calibrate_dq_dqs_centering(struct socfpga_sdrseq *seq,
+				      const u32 rw_group, const u32 test_bgn,
 				      const int use_read_test,
 				      const int update_fom)
 
@@ -2646,9 +2695,9 @@
 	 */
 	grp_calibrated = 1;
 	for (rank_bgn = 0, sr = 0;
-	     rank_bgn < rwcfg->mem_number_of_ranks;
+	     rank_bgn < seq->rwcfg->mem_number_of_ranks;
 	     rank_bgn += NUM_RANKS_PER_SHADOW_REG, sr++) {
-		ret = rw_mgr_mem_calibrate_vfifo_center(rank_bgn, rw_group,
+		ret = rw_mgr_mem_calibrate_vfifo_center(seq, rank_bgn, rw_group,
 							test_bgn,
 							use_read_test,
 							update_fom);
@@ -2679,7 +2728,8 @@
  *   - DQS input phase  and DQS input delay (DQ/DQS Centering)
  *  - we also do a per-bit deskew on the DQ lines.
  */
-static int rw_mgr_mem_calibrate_vfifo(const u32 rw_group, const u32 test_bgn)
+static int rw_mgr_mem_calibrate_vfifo(struct socfpga_sdrseq *seq,
+				      const u32 rw_group, const u32 test_bgn)
 {
 	u32 p, d;
 	u32 dtaps_per_ptap;
@@ -2697,8 +2747,9 @@
 	failed_substage = CAL_SUBSTAGE_GUARANTEED_READ;
 
 	/* USER Determine number of delay taps for each phase tap. */
-	dtaps_per_ptap = DIV_ROUND_UP(iocfg->delay_per_opa_tap,
-				      iocfg->delay_per_dqs_en_dchain_tap) - 1;
+	dtaps_per_ptap = DIV_ROUND_UP(seq->iocfg->delay_per_opa_tap,
+				      seq->iocfg->delay_per_dqs_en_dchain_tap)
+				      - 1;
 
 	for (d = 0; d <= dtaps_per_ptap; d += 2) {
 		/*
@@ -2708,18 +2759,22 @@
 		 * output side yet.
 		 */
 		if (d > 0) {
-			scc_mgr_apply_group_all_out_delay_add_all_ranks(
-								rw_group, d);
+			scc_mgr_apply_group_all_out_delay_add_all_ranks(seq,
+									rw_group,
+									d);
 		}
 
-		for (p = 0; p <= iocfg->dqdqs_out_phase_max; p++) {
+		for (p = 0; p <= seq->iocfg->dqdqs_out_phase_max; p++) {
 			/* 1) Guaranteed Write */
-			ret = rw_mgr_mem_calibrate_guaranteed_write(rw_group, p);
+			ret = rw_mgr_mem_calibrate_guaranteed_write(seq,
+								    rw_group,
+								    p);
 			if (ret)
 				break;
 
 			/* 2) DQS Enable Calibration */
-			ret = rw_mgr_mem_calibrate_dqs_enable_calibration(rw_group,
+			ret = rw_mgr_mem_calibrate_dqs_enable_calibration(seq,
+									  rw_group,
 									  test_bgn);
 			if (ret) {
 				failed_substage = CAL_SUBSTAGE_DQS_EN_PHASE;
@@ -2731,8 +2786,10 @@
 			 * If doing read after write calibration, do not update
 			 * FOM now. Do it then.
 			 */
-			ret = rw_mgr_mem_calibrate_dq_dqs_centering(rw_group,
-								test_bgn, 1, 0);
+			ret = rw_mgr_mem_calibrate_dq_dqs_centering(seq,
+								    rw_group,
+								    test_bgn,
+								    1, 0);
 			if (ret) {
 				failed_substage = CAL_SUBSTAGE_VFIFO_CENTER;
 				continue;
@@ -2744,7 +2801,8 @@
 	}
 
 	/* Calibration Stage 1 failed. */
-	set_failing_group_stage(rw_group, CAL_STAGE_VFIFO, failed_substage);
+	set_failing_group_stage(seq, rw_group, CAL_STAGE_VFIFO,
+				failed_substage);
 	return 0;
 
 	/* Calibration Stage 1 completed OK. */
@@ -2755,7 +2813,7 @@
 	 * first case).
 	 */
 	if (d > 2)
-		scc_mgr_zero_group(rw_group, 1);
+		scc_mgr_zero_group(seq, rw_group, 1);
 
 	return 1;
 }
@@ -2770,7 +2828,8 @@
  * This function implements UniPHY calibration Stage 3, as explained in
  * detail in Altera EMI_RM 2015.05.04 , "UniPHY Calibration Stages".
  */
-static int rw_mgr_mem_calibrate_vfifo_end(const u32 rw_group,
+static int rw_mgr_mem_calibrate_vfifo_end(struct socfpga_sdrseq *seq,
+					  const u32 rw_group,
 					  const u32 test_bgn)
 {
 	int ret;
@@ -2782,9 +2841,10 @@
 	reg_file_set_stage(CAL_STAGE_VFIFO_AFTER_WRITES);
 	reg_file_set_sub_stage(CAL_SUBSTAGE_VFIFO_CENTER);
 
-	ret = rw_mgr_mem_calibrate_dq_dqs_centering(rw_group, test_bgn, 0, 1);
+	ret = rw_mgr_mem_calibrate_dq_dqs_centering(seq, rw_group, test_bgn, 0,
+						    1);
 	if (ret)
-		set_failing_group_stage(rw_group,
+		set_failing_group_stage(seq, rw_group,
 					CAL_STAGE_VFIFO_AFTER_WRITES,
 					CAL_SUBSTAGE_VFIFO_CENTER);
 	return ret;
@@ -2799,7 +2859,7 @@
  * detail in Altera EMI_RM 2015.05.04 , "UniPHY Calibration Stages".
  * Calibrate LFIFO to find smallest read latency.
  */
-static u32 rw_mgr_mem_calibrate_lfifo(void)
+static u32 rw_mgr_mem_calibrate_lfifo(struct socfpga_sdrseq *seq)
 {
 	int found_one = 0;
 
@@ -2810,14 +2870,15 @@
 	reg_file_set_sub_stage(CAL_SUBSTAGE_READ_LATENCY);
 
 	/* Load up the patterns used by read calibration for all ranks */
-	rw_mgr_mem_calibrate_read_load_patterns(0, 1);
+	rw_mgr_mem_calibrate_read_load_patterns(seq, 0, 1);
 
 	do {
-		writel(gbl->curr_read_lat, &phy_mgr_cfg->phy_rlat);
+		writel(seq->gbl.curr_read_lat, &phy_mgr_cfg->phy_rlat);
 		debug_cond(DLEVEL >= 2, "%s:%d lfifo: read_lat=%u",
-			   __func__, __LINE__, gbl->curr_read_lat);
+			   __func__, __LINE__, seq->gbl.curr_read_lat);
 
-		if (!rw_mgr_mem_calibrate_read_test_all_ranks(0, NUM_READ_TESTS,
+		if (!rw_mgr_mem_calibrate_read_test_all_ranks(seq, 0,
+							      NUM_READ_TESTS,
 							      PASS_ALL_BITS, 1))
 			break;
 
@@ -2826,26 +2887,26 @@
 		 * Reduce read latency and see if things are
 		 * working correctly.
 		 */
-		gbl->curr_read_lat--;
-	} while (gbl->curr_read_lat > 0);
+		seq->gbl.curr_read_lat--;
+	} while (seq->gbl.curr_read_lat > 0);
 
 	/* Reset the fifos to get pointers to known state. */
 	writel(0, &phy_mgr_cmd->fifo_reset);
 
 	if (found_one) {
 		/* Add a fudge factor to the read latency that was determined */
-		gbl->curr_read_lat += 2;
-		writel(gbl->curr_read_lat, &phy_mgr_cfg->phy_rlat);
+		seq->gbl.curr_read_lat += 2;
+		writel(seq->gbl.curr_read_lat, &phy_mgr_cfg->phy_rlat);
 		debug_cond(DLEVEL >= 2,
 			   "%s:%d lfifo: success: using read_lat=%u\n",
-			   __func__, __LINE__, gbl->curr_read_lat);
+			   __func__, __LINE__, seq->gbl.curr_read_lat);
 	} else {
-		set_failing_group_stage(0xff, CAL_STAGE_LFIFO,
+		set_failing_group_stage(seq, 0xff, CAL_STAGE_LFIFO,
 					CAL_SUBSTAGE_READ_LATENCY);
 
 		debug_cond(DLEVEL >= 2,
 			   "%s:%d lfifo: failed at initial read_lat=%u\n",
-			   __func__, __LINE__, gbl->curr_read_lat);
+			   __func__, __LINE__, seq->gbl.curr_read_lat);
 	}
 
 	return found_one;
@@ -2853,7 +2914,8 @@
 
 /**
  * search_window() - Search for the/part of the window with DM/DQS shift
- * @search_dm:		If 1, search for the DM shift, if 0, search for DQS shift
+ * @search_dm:		If 1, search for the DM shift, if 0, search for DQS
+ *			shift
  * @rank_bgn:		Rank number
  * @write_group:	Write Group
  * @bgn_curr:		Current window begin
@@ -2865,20 +2927,21 @@
  *
  * Search for the/part of the window with DM/DQS shift.
  */
-static void search_window(const int search_dm,
-			  const u32 rank_bgn, const u32 write_group,
-			  int *bgn_curr, int *end_curr, int *bgn_best,
-			  int *end_best, int *win_best, int new_dqs)
+static void search_window(struct socfpga_sdrseq *seq,
+			  const int search_dm, const u32 rank_bgn,
+			  const u32 write_group, int *bgn_curr, int *end_curr,
+			  int *bgn_best, int *end_best, int *win_best,
+			  int new_dqs)
 {
 	u32 bit_chk;
-	const int max = iocfg->io_out1_delay_max - new_dqs;
+	const int max = seq->iocfg->io_out1_delay_max - new_dqs;
 	int d, di;
 
 	/* Search for the/part of the window with DM/DQS shift. */
 	for (di = max; di >= 0; di -= DELTA_D) {
 		if (search_dm) {
 			d = di;
-			scc_mgr_apply_group_dm_out1_delay(d);
+			scc_mgr_apply_group_dm_out1_delay(seq, d);
 		} else {
 			/* For DQS, we go from 0...max */
 			d = max - di;
@@ -2886,14 +2949,15 @@
 			 * Note: This only shifts DQS, so are we limiting
 			 *       ourselves to width of DQ unnecessarily.
 			 */
-			scc_mgr_apply_group_dqs_io_and_oct_out1(write_group,
+			scc_mgr_apply_group_dqs_io_and_oct_out1(seq,
+								write_group,
 								d + new_dqs);
 		}
 
 		writel(0, &sdr_scc_mgr->update);
 
-		if (rw_mgr_mem_calibrate_write_test(rank_bgn, write_group, 1,
-						    PASS_ALL_BITS, &bit_chk,
+		if (rw_mgr_mem_calibrate_write_test(seq, rank_bgn, write_group,
+						    1, PASS_ALL_BITS, &bit_chk,
 						    0)) {
 			/* Set current end of the window. */
 			*end_curr = search_dm ? -d : d;
@@ -2902,7 +2966,7 @@
 			 * If a starting edge of our window has not been seen
 			 * this is our current start of the DM window.
 			 */
-			if (*bgn_curr == iocfg->io_out1_delay_max + 1)
+			if (*bgn_curr == seq->iocfg->io_out1_delay_max + 1)
 				*bgn_curr = search_dm ? -d : d;
 
 			/*
@@ -2916,8 +2980,8 @@
 			}
 		} else {
 			/* We just saw a failing test. Reset temp edge. */
-			*bgn_curr = iocfg->io_out1_delay_max + 1;
-			*end_curr = iocfg->io_out1_delay_max + 1;
+			*bgn_curr = seq->iocfg->io_out1_delay_max + 1;
+			*end_curr = seq->iocfg->io_out1_delay_max + 1;
 
 			/* Early exit is only applicable to DQS. */
 			if (search_dm)
@@ -2928,7 +2992,8 @@
 			 * chain space is less than already seen largest
 			 * window we can exit.
 			 */
-			if (*win_best - 1 > iocfg->io_out1_delay_max - new_dqs - d)
+			if (*win_best - 1 > seq->iocfg->io_out1_delay_max
+				- new_dqs - d)
 				break;
 		}
 	}
@@ -2944,22 +3009,23 @@
  * certain windows.
  */
 static int
-rw_mgr_mem_calibrate_writes_center(const u32 rank_bgn, const u32 write_group,
+rw_mgr_mem_calibrate_writes_center(struct socfpga_sdrseq *seq,
+				   const u32 rank_bgn, const u32 write_group,
 				   const u32 test_bgn)
 {
 	int i;
 	u32 sticky_bit_chk;
 	u32 min_index;
-	int left_edge[rwcfg->mem_dq_per_write_dqs];
-	int right_edge[rwcfg->mem_dq_per_write_dqs];
+	int left_edge[seq->rwcfg->mem_dq_per_write_dqs];
+	int right_edge[seq->rwcfg->mem_dq_per_write_dqs];
 	int mid;
 	int mid_min, orig_mid_min;
 	int new_dqs, start_dqs;
 	int dq_margin, dqs_margin, dm_margin;
-	int bgn_curr = iocfg->io_out1_delay_max + 1;
-	int end_curr = iocfg->io_out1_delay_max + 1;
-	int bgn_best = iocfg->io_out1_delay_max + 1;
-	int end_best = iocfg->io_out1_delay_max + 1;
+	int bgn_curr = seq->iocfg->io_out1_delay_max + 1;
+	int end_curr = seq->iocfg->io_out1_delay_max + 1;
+	int bgn_best = seq->iocfg->io_out1_delay_max + 1;
+	int end_best = seq->iocfg->io_out1_delay_max + 1;
 	int win_best = 0;
 
 	int ret;
@@ -2970,37 +3036,39 @@
 
 	start_dqs = readl((SDR_PHYGRP_SCCGRP_ADDRESS |
 			  SCC_MGR_IO_OUT1_DELAY_OFFSET) +
-			  (rwcfg->mem_dq_per_write_dqs << 2));
+			  (seq->rwcfg->mem_dq_per_write_dqs << 2));
 
 	/* Per-bit deskew. */
 
 	/*
 	 * Set the left and right edge of each bit to an illegal value.
-	 * Use (iocfg->io_out1_delay_max + 1) as an illegal value.
+	 * Use (seq->iocfg->io_out1_delay_max + 1) as an illegal value.
 	 */
 	sticky_bit_chk = 0;
-	for (i = 0; i < rwcfg->mem_dq_per_write_dqs; i++) {
-		left_edge[i]  = iocfg->io_out1_delay_max + 1;
-		right_edge[i] = iocfg->io_out1_delay_max + 1;
+	for (i = 0; i < seq->rwcfg->mem_dq_per_write_dqs; i++) {
+		left_edge[i]  = seq->iocfg->io_out1_delay_max + 1;
+		right_edge[i] = seq->iocfg->io_out1_delay_max + 1;
 	}
 
 	/* Search for the left edge of the window for each bit. */
-	search_left_edge(1, rank_bgn, write_group, 0, test_bgn,
+	search_left_edge(seq, 1, rank_bgn, write_group, 0, test_bgn,
 			 &sticky_bit_chk,
 			 left_edge, right_edge, 0);
 
 	/* Search for the right edge of the window for each bit. */
-	ret = search_right_edge(1, rank_bgn, write_group, 0,
+	ret = search_right_edge(seq, 1, rank_bgn, write_group, 0,
 				start_dqs, 0,
 				&sticky_bit_chk,
 				left_edge, right_edge, 0);
 	if (ret) {
-		set_failing_group_stage(test_bgn + ret - 1, CAL_STAGE_WRITES,
+		set_failing_group_stage(seq, test_bgn + ret - 1,
+					CAL_STAGE_WRITES,
 					CAL_SUBSTAGE_WRITES_CENTER);
 		return -EINVAL;
 	}
 
-	min_index = get_window_mid_index(1, left_edge, right_edge, &mid_min);
+	min_index = get_window_mid_index(seq, 1, left_edge, right_edge,
+					 &mid_min);
 
 	/* Determine the amount we can change DQS (which is -mid_min). */
 	orig_mid_min = mid_min;
@@ -3011,11 +3079,11 @@
 		   __func__, __LINE__, start_dqs, new_dqs, mid_min);
 
 	/* Add delay to bring centre of all DQ windows to the same "level". */
-	center_dq_windows(1, left_edge, right_edge, mid_min, orig_mid_min,
+	center_dq_windows(seq, 1, left_edge, right_edge, mid_min, orig_mid_min,
 			  min_index, 0, &dq_margin, &dqs_margin);
 
 	/* Move DQS */
-	scc_mgr_apply_group_dqs_io_and_oct_out1(write_group, new_dqs);
+	scc_mgr_apply_group_dqs_io_and_oct_out1(seq, write_group, new_dqs);
 	writel(0, &sdr_scc_mgr->update);
 
 	/* Centre DM */
@@ -3023,17 +3091,17 @@
 
 	/*
 	 * Set the left and right edge of each bit to an illegal value.
-	 * Use (iocfg->io_out1_delay_max + 1) as an illegal value.
+	 * Use (seq->iocfg->io_out1_delay_max + 1) as an illegal value.
 	 */
-	left_edge[0]  = iocfg->io_out1_delay_max + 1;
-	right_edge[0] = iocfg->io_out1_delay_max + 1;
+	left_edge[0]  = seq->iocfg->io_out1_delay_max + 1;
+	right_edge[0] = seq->iocfg->io_out1_delay_max + 1;
 
 	/* Search for the/part of the window with DM shift. */
-	search_window(1, rank_bgn, write_group, &bgn_curr, &end_curr,
+	search_window(seq, 1, rank_bgn, write_group, &bgn_curr, &end_curr,
 		      &bgn_best, &end_best, &win_best, 0);
 
 	/* Reset DM delay chains to 0. */
-	scc_mgr_apply_group_dm_out1_delay(0);
+	scc_mgr_apply_group_dm_out1_delay(seq, 0);
 
 	/*
 	 * Check to see if the current window nudges up aganist 0 delay.
@@ -3041,12 +3109,12 @@
 	 * search begins as a new search.
 	 */
 	if (end_curr != 0) {
-		bgn_curr = iocfg->io_out1_delay_max + 1;
-		end_curr = iocfg->io_out1_delay_max + 1;
+		bgn_curr = seq->iocfg->io_out1_delay_max + 1;
+		end_curr = seq->iocfg->io_out1_delay_max + 1;
 	}
 
 	/* Search for the/part of the window with DQS shifts. */
-	search_window(0, rank_bgn, write_group, &bgn_curr, &end_curr,
+	search_window(seq, 0, rank_bgn, write_group, &bgn_curr, &end_curr,
 		      &bgn_best, &end_best, &win_best, new_dqs);
 
 	/* Assign left and right edge for cal and reporting. */
@@ -3057,7 +3125,7 @@
 		   __func__, __LINE__, left_edge[0], right_edge[0]);
 
 	/* Move DQS (back to orig). */
-	scc_mgr_apply_group_dqs_io_and_oct_out1(write_group, new_dqs);
+	scc_mgr_apply_group_dqs_io_and_oct_out1(seq, write_group, new_dqs);
 
 	/* Move DM */
 
@@ -3074,7 +3142,7 @@
 	else
 		dm_margin = left_edge[0] - mid;
 
-	scc_mgr_apply_group_dm_out1_delay(mid);
+	scc_mgr_apply_group_dm_out1_delay(seq, mid);
 	writel(0, &sdr_scc_mgr->update);
 
 	debug_cond(DLEVEL >= 2,
@@ -3082,7 +3150,7 @@
 		   __func__, __LINE__, left_edge[0], right_edge[0],
 		   mid, dm_margin);
 	/* Export values. */
-	gbl->fom_out += dq_margin + dqs_margin;
+	seq->gbl.fom_out += dq_margin + dqs_margin;
 
 	debug_cond(DLEVEL >= 2,
 		   "%s:%d write_center: dq_margin=%d dqs_margin=%d dm_margin=%d\n",
@@ -3111,7 +3179,8 @@
  * This function implements UniPHY calibration Stage 2, as explained in
  * detail in Altera EMI_RM 2015.05.04 , "UniPHY Calibration Stages".
  */
-static int rw_mgr_mem_calibrate_writes(const u32 rank_bgn, const u32 group,
+static int rw_mgr_mem_calibrate_writes(struct socfpga_sdrseq *seq,
+				       const u32 rank_bgn, const u32 group,
 				       const u32 test_bgn)
 {
 	int ret;
@@ -3123,9 +3192,10 @@
 	reg_file_set_stage(CAL_STAGE_WRITES);
 	reg_file_set_sub_stage(CAL_SUBSTAGE_WRITES_CENTER);
 
-	ret = rw_mgr_mem_calibrate_writes_center(rank_bgn, group, test_bgn);
+	ret = rw_mgr_mem_calibrate_writes_center(seq, rank_bgn, group,
+						 test_bgn);
 	if (ret)
-		set_failing_group_stage(group, CAL_STAGE_WRITES,
+		set_failing_group_stage(seq, group, CAL_STAGE_WRITES,
 					CAL_SUBSTAGE_WRITES_CENTER);
 
 	return ret;
@@ -3136,29 +3206,30 @@
  *
  * Precharge all banks and activate row 0 in bank "000..." and bank "111...".
  */
-static void mem_precharge_and_activate(void)
+static void mem_precharge_and_activate(struct socfpga_sdrseq *seq)
 {
 	int r;
 
-	for (r = 0; r < rwcfg->mem_number_of_ranks; r++) {
+	for (r = 0; r < seq->rwcfg->mem_number_of_ranks; r++) {
 		/* Set rank. */
-		set_rank_and_odt_mask(r, RW_MGR_ODT_MODE_OFF);
+		set_rank_and_odt_mask(seq, r, RW_MGR_ODT_MODE_OFF);
 
 		/* Precharge all banks. */
-		writel(rwcfg->precharge_all, SDR_PHYGRP_RWMGRGRP_ADDRESS |
+		writel(seq->rwcfg->precharge_all, SDR_PHYGRP_RWMGRGRP_ADDRESS |
 					     RW_MGR_RUN_SINGLE_GROUP_OFFSET);
 
 		writel(0x0F, &sdr_rw_load_mgr_regs->load_cntr0);
-		writel(rwcfg->activate_0_and_1_wait1,
+		writel(seq->rwcfg->activate_0_and_1_wait1,
 		       &sdr_rw_load_jump_mgr_regs->load_jump_add0);
 
 		writel(0x0F, &sdr_rw_load_mgr_regs->load_cntr1);
-		writel(rwcfg->activate_0_and_1_wait2,
+		writel(seq->rwcfg->activate_0_and_1_wait2,
 		       &sdr_rw_load_jump_mgr_regs->load_jump_add1);
 
 		/* Activate rows. */
-		writel(rwcfg->activate_0_and_1, SDR_PHYGRP_RWMGRGRP_ADDRESS |
-						RW_MGR_RUN_SINGLE_GROUP_OFFSET);
+		writel(seq->rwcfg->activate_0_and_1,
+		       SDR_PHYGRP_RWMGRGRP_ADDRESS |
+		       RW_MGR_RUN_SINGLE_GROUP_OFFSET);
 	}
 }
 
@@ -3167,14 +3238,15 @@
  *
  * Configure memory RLAT and WLAT parameters.
  */
-static void mem_init_latency(void)
+static void mem_init_latency(struct socfpga_sdrseq *seq)
 {
 	/*
 	 * For AV/CV, LFIFO is hardened and always runs at full rate
 	 * so max latency in AFI clocks, used here, is correspondingly
 	 * smaller.
 	 */
-	const u32 max_latency = (1 << misccfg->max_latency_count_width) - 1;
+	const u32 max_latency = (1 << seq->misccfg->max_latency_count_width)
+		- 1;
 	u32 rlat, wlat;
 
 	debug("%s:%d\n", __func__, __LINE__);
@@ -3186,17 +3258,17 @@
 	wlat = readl(&data_mgr->t_wl_add);
 	wlat += readl(&data_mgr->mem_t_add);
 
-	gbl->rw_wl_nop_cycles = wlat - 1;
+	seq->gbl.rw_wl_nop_cycles = wlat - 1;
 
 	/* Read in readl latency. */
 	rlat = readl(&data_mgr->t_rl_add);
 
 	/* Set a pretty high read latency initially. */
-	gbl->curr_read_lat = rlat + 16;
-	if (gbl->curr_read_lat > max_latency)
-		gbl->curr_read_lat = max_latency;
+	seq->gbl.curr_read_lat = rlat + 16;
+	if (seq->gbl.curr_read_lat > max_latency)
+		seq->gbl.curr_read_lat = max_latency;
 
-	writel(gbl->curr_read_lat, &phy_mgr_cfg->phy_rlat);
+	writel(seq->gbl.curr_read_lat, &phy_mgr_cfg->phy_rlat);
 
 	/* Advertise write latency. */
 	writel(wlat, &phy_mgr_cfg->afi_wlat);
@@ -3207,22 +3279,22 @@
  *
  * Set VFIFO and LFIFO to instant-on settings in skip calibration mode.
  */
-static void mem_skip_calibrate(void)
+static void mem_skip_calibrate(struct socfpga_sdrseq *seq)
 {
 	u32 vfifo_offset;
 	u32 i, j, r;
 
 	debug("%s:%d\n", __func__, __LINE__);
 	/* Need to update every shadow register set used by the interface */
-	for (r = 0; r < rwcfg->mem_number_of_ranks;
+	for (r = 0; r < seq->rwcfg->mem_number_of_ranks;
 	     r += NUM_RANKS_PER_SHADOW_REG) {
 		/*
 		 * Set output phase alignment settings appropriate for
 		 * skip calibration.
 		 */
-		for (i = 0; i < rwcfg->mem_if_read_dqs_width; i++) {
+		for (i = 0; i < seq->rwcfg->mem_if_read_dqs_width; i++) {
 			scc_mgr_set_dqs_en_phase(i, 0);
-			if (iocfg->dll_chain_length == 6)
+			if (seq->iocfg->dll_chain_length == 6)
 				scc_mgr_set_dqdqs_output_phase(i, 6);
 			else
 				scc_mgr_set_dqdqs_output_phase(i, 7);
@@ -3245,20 +3317,22 @@
 			 * Hence, to make DQS aligned to CK, we need to delay
 			 * DQS by:
 			 *    (720 - 90 - 180 - 2) *
-			 *      (360 / iocfg->dll_chain_length)
+			 *      (360 / seq->iocfg->dll_chain_length)
 			 *
-			 * Dividing the above by (360 / iocfg->dll_chain_length)
+			 * Dividing the above by
+			 (360 / seq->iocfg->dll_chain_length)
 			 * gives us the number of ptaps, which simplies to:
 			 *
-			 *    (1.25 * iocfg->dll_chain_length - 2)
+			 *    (1.25 * seq->iocfg->dll_chain_length - 2)
 			 */
 			scc_mgr_set_dqdqs_output_phase(i,
-				       ((125 * iocfg->dll_chain_length) / 100) - 2);
+				       ((125 * seq->iocfg->dll_chain_length)
+				       / 100) - 2);
 		}
 		writel(0xff, &sdr_scc_mgr->dqs_ena);
 		writel(0xff, &sdr_scc_mgr->dqs_io_ena);
 
-		for (i = 0; i < rwcfg->mem_if_write_dqs_width; i++) {
+		for (i = 0; i < seq->rwcfg->mem_if_write_dqs_width; i++) {
 			writel(i, SDR_PHYGRP_SCCGRP_ADDRESS |
 				  SCC_MGR_GROUP_COUNTER_OFFSET);
 		}
@@ -3268,7 +3342,7 @@
 	}
 
 	/* Compensate for simulation model behaviour */
-	for (i = 0; i < rwcfg->mem_if_read_dqs_width; i++) {
+	for (i = 0; i < seq->rwcfg->mem_if_read_dqs_width; i++) {
 		scc_mgr_set_dqs_bus_in_delay(i, 10);
 		scc_mgr_load_dqs(i);
 	}
@@ -3278,7 +3352,7 @@
 	 * ArriaV has hard FIFOs that can only be initialized by incrementing
 	 * in sequencer.
 	 */
-	vfifo_offset = misccfg->calib_vfifo_offset;
+	vfifo_offset = seq->misccfg->calib_vfifo_offset;
 	for (j = 0; j < vfifo_offset; j++)
 		writel(0xff, &phy_mgr_cmd->inc_vfifo_hard_phy);
 	writel(0, &phy_mgr_cmd->fifo_reset);
@@ -3287,8 +3361,8 @@
 	 * For Arria V and Cyclone V with hard LFIFO, we get the skip-cal
 	 * setting from generation-time constant.
 	 */
-	gbl->curr_read_lat = misccfg->calib_lfifo_offset;
-	writel(gbl->curr_read_lat, &phy_mgr_cfg->phy_rlat);
+	seq->gbl.curr_read_lat = seq->misccfg->calib_lfifo_offset;
+	writel(seq->gbl.curr_read_lat, &phy_mgr_cfg->phy_rlat);
 }
 
 /**
@@ -3296,7 +3370,7 @@
  *
  * Perform memory calibration.
  */
-static u32 mem_calibrate(void)
+static u32 mem_calibrate(struct socfpga_sdrseq *seq)
 {
 	u32 i;
 	u32 rank_bgn, sr;
@@ -3306,25 +3380,25 @@
 	u32 failing_groups = 0;
 	u32 group_failed = 0;
 
-	const u32 rwdqs_ratio = rwcfg->mem_if_read_dqs_width /
-				rwcfg->mem_if_write_dqs_width;
+	const u32 rwdqs_ratio = seq->rwcfg->mem_if_read_dqs_width /
+				seq->rwcfg->mem_if_write_dqs_width;
 
 	debug("%s:%d\n", __func__, __LINE__);
 
 	/* Initialize the data settings */
-	gbl->error_substage = CAL_SUBSTAGE_NIL;
-	gbl->error_stage = CAL_STAGE_NIL;
-	gbl->error_group = 0xff;
-	gbl->fom_in = 0;
-	gbl->fom_out = 0;
+	seq->gbl.error_substage = CAL_SUBSTAGE_NIL;
+	seq->gbl.error_stage = CAL_STAGE_NIL;
+	seq->gbl.error_group = 0xff;
+	seq->gbl.fom_in = 0;
+	seq->gbl.fom_out = 0;
 
 	/* Initialize WLAT and RLAT. */
-	mem_init_latency();
+	mem_init_latency(seq);
 
 	/* Initialize bit slips. */
-	mem_precharge_and_activate();
+	mem_precharge_and_activate(seq);
 
-	for (i = 0; i < rwcfg->mem_if_read_dqs_width; i++) {
+	for (i = 0; i < seq->rwcfg->mem_if_read_dqs_width; i++) {
 		writel(i, SDR_PHYGRP_SCCGRP_ADDRESS |
 			  SCC_MGR_GROUP_COUNTER_OFFSET);
 		/* Only needed once to set all groups, pins, DQ, DQS, DM. */
@@ -3335,12 +3409,12 @@
 	}
 
 	/* Calibration is skipped. */
-	if ((dyn_calib_steps & CALIB_SKIP_ALL) == CALIB_SKIP_ALL) {
+	if ((seq->dyn_calib_steps & CALIB_SKIP_ALL) == CALIB_SKIP_ALL) {
 		/*
 		 * Set VFIFO and LFIFO to instant-on settings in skip
 		 * calibration mode.
 		 */
-		mem_skip_calibrate();
+		mem_skip_calibrate(seq);
 
 		/*
 		 * Do not remove this line as it makes sure all of our
@@ -3356,13 +3430,13 @@
 		 * Zero all delay chain/phase settings for all
 		 * groups and all shadow register sets.
 		 */
-		scc_mgr_zero_all();
+		scc_mgr_zero_all(seq);
 
 		run_groups = ~0;
 
 		for (write_group = 0, write_test_bgn = 0; write_group
-			< rwcfg->mem_if_write_dqs_width; write_group++,
-			write_test_bgn += rwcfg->mem_dq_per_write_dqs) {
+			< seq->rwcfg->mem_if_write_dqs_width; write_group++,
+			write_test_bgn += seq->rwcfg->mem_dq_per_write_dqs) {
 			/* Initialize the group failure */
 			group_failed = 0;
 
@@ -3376,22 +3450,22 @@
 
 			writel(write_group, SDR_PHYGRP_SCCGRP_ADDRESS |
 					    SCC_MGR_GROUP_COUNTER_OFFSET);
-			scc_mgr_zero_group(write_group, 0);
+			scc_mgr_zero_group(seq, write_group, 0);
 
 			for (read_group = write_group * rwdqs_ratio,
 			     read_test_bgn = 0;
 			     read_group < (write_group + 1) * rwdqs_ratio;
 			     read_group++,
-			     read_test_bgn += rwcfg->mem_dq_per_read_dqs) {
+			     read_test_bgn += seq->rwcfg->mem_dq_per_read_dqs) {
 				if (STATIC_CALIB_STEPS & CALIB_SKIP_VFIFO)
 					continue;
 
 				/* Calibrate the VFIFO */
-				if (rw_mgr_mem_calibrate_vfifo(read_group,
+				if (rw_mgr_mem_calibrate_vfifo(seq, read_group,
 							       read_test_bgn))
 					continue;
 
-				if (!(gbl->phy_debug_mode_flags &
+				if (!(seq->gbl.phy_debug_mode_flags &
 				      PHY_DEBUG_SWEEP_ALL_GROUPS))
 					return 0;
 
@@ -3401,7 +3475,7 @@
 
 			/* Calibrate the output side */
 			for (rank_bgn = 0, sr = 0;
-			     rank_bgn < rwcfg->mem_number_of_ranks;
+			     rank_bgn < seq->rwcfg->mem_number_of_ranks;
 			     rank_bgn += NUM_RANKS_PER_SHADOW_REG, sr++) {
 				if (STATIC_CALIB_STEPS & CALIB_SKIP_WRITES)
 					continue;
@@ -3412,13 +3486,13 @@
 					continue;
 
 				/* Calibrate WRITEs */
-				if (!rw_mgr_mem_calibrate_writes(rank_bgn,
+				if (!rw_mgr_mem_calibrate_writes(seq, rank_bgn,
 								 write_group,
 								 write_test_bgn))
 					continue;
 
 				group_failed = 1;
-				if (!(gbl->phy_debug_mode_flags &
+				if (!(seq->gbl.phy_debug_mode_flags &
 				      PHY_DEBUG_SWEEP_ALL_GROUPS))
 					return 0;
 			}
@@ -3431,15 +3505,16 @@
 			     read_test_bgn = 0;
 			     read_group < (write_group + 1) * rwdqs_ratio;
 			     read_group++,
-			     read_test_bgn += rwcfg->mem_dq_per_read_dqs) {
+			     read_test_bgn += seq->rwcfg->mem_dq_per_read_dqs) {
 				if (STATIC_CALIB_STEPS & CALIB_SKIP_WRITES)
 					continue;
 
-				if (!rw_mgr_mem_calibrate_vfifo_end(read_group,
+				if (!rw_mgr_mem_calibrate_vfifo_end(seq,
+								    read_group,
 								    read_test_bgn))
 					continue;
 
-				if (!(gbl->phy_debug_mode_flags &
+				if (!(seq->gbl.phy_debug_mode_flags &
 				      PHY_DEBUG_SWEEP_ALL_GROUPS))
 					return 0;
 
@@ -3465,7 +3540,7 @@
 			continue;
 
 		/* Calibrate the LFIFO */
-		if (!rw_mgr_mem_calibrate_lfifo())
+		if (!rw_mgr_mem_calibrate_lfifo(seq))
 			return 0;
 	}
 
@@ -3482,7 +3557,7 @@
  *
  * This function triggers the entire memory calibration procedure.
  */
-static int run_mem_calibrate(void)
+static int run_mem_calibrate(struct socfpga_sdrseq *seq)
 {
 	int pass;
 	u32 ctrl_cfg;
@@ -3497,17 +3572,17 @@
 	writel(ctrl_cfg & ~SDR_CTRLGRP_CTRLCFG_DQSTRKEN_MASK,
 	       &sdr_ctrl->ctrl_cfg);
 
-	phy_mgr_initialize();
-	rw_mgr_mem_initialize();
+	phy_mgr_initialize(seq);
+	rw_mgr_mem_initialize(seq);
 
 	/* Perform the actual memory calibration. */
-	pass = mem_calibrate();
+	pass = mem_calibrate(seq);
 
-	mem_precharge_and_activate();
+	mem_precharge_and_activate(seq);
 	writel(0, &phy_mgr_cmd->fifo_reset);
 
 	/* Handoff. */
-	rw_mgr_mem_handoff();
+	rw_mgr_mem_handoff(seq);
 	/*
 	 * In Hard PHY this is a 2-bit control:
 	 * 0: AFI Mux Select
@@ -3528,25 +3603,25 @@
  * This function reports the results of the memory calibration
  * and writes debug information into the register file.
  */
-static void debug_mem_calibrate(int pass)
+static void debug_mem_calibrate(struct socfpga_sdrseq *seq, int pass)
 {
 	u32 debug_info;
 
 	if (pass) {
 		debug("%s: CALIBRATION PASSED\n", __FILE__);
 
-		gbl->fom_in /= 2;
-		gbl->fom_out /= 2;
+		seq->gbl.fom_in /= 2;
+		seq->gbl.fom_out /= 2;
 
-		if (gbl->fom_in > 0xff)
-			gbl->fom_in = 0xff;
+		if (seq->gbl.fom_in > 0xff)
+			seq->gbl.fom_in = 0xff;
 
-		if (gbl->fom_out > 0xff)
-			gbl->fom_out = 0xff;
+		if (seq->gbl.fom_out > 0xff)
+			seq->gbl.fom_out = 0xff;
 
 		/* Update the FOM in the register file */
-		debug_info = gbl->fom_in;
-		debug_info |= gbl->fom_out << 8;
+		debug_info = seq->gbl.fom_in;
+		debug_info |= seq->gbl.fom_out << 8;
 		writel(debug_info, &sdr_reg_file->fom);
 
 		writel(debug_info, &phy_mgr_cfg->cal_debug_info);
@@ -3554,18 +3629,18 @@
 	} else {
 		debug("%s: CALIBRATION FAILED\n", __FILE__);
 
-		debug_info = gbl->error_stage;
-		debug_info |= gbl->error_substage << 8;
-		debug_info |= gbl->error_group << 16;
+		debug_info = seq->gbl.error_stage;
+		debug_info |= seq->gbl.error_substage << 8;
+		debug_info |= seq->gbl.error_group << 16;
 
 		writel(debug_info, &sdr_reg_file->failing_stage);
 		writel(debug_info, &phy_mgr_cfg->cal_debug_info);
 		writel(PHY_MGR_CAL_FAIL, &phy_mgr_cfg->cal_status);
 
 		/* Update the failing group/stage in the register file */
-		debug_info = gbl->error_stage;
-		debug_info |= gbl->error_substage << 8;
-		debug_info |= gbl->error_group << 16;
+		debug_info = seq->gbl.error_stage;
+		debug_info |= seq->gbl.error_substage << 8;
+		debug_info |= seq->gbl.error_group << 16;
 		writel(debug_info, &sdr_reg_file->failing_stage);
 	}
 
@@ -3599,10 +3674,11 @@
  *
  * Initialize SDR register file.
  */
-static void initialize_reg_file(void)
+static void initialize_reg_file(struct socfpga_sdrseq *seq)
 {
 	/* Initialize the register file with the correct data */
-	writel(misccfg->reg_file_init_seq_signature, &sdr_reg_file->signature);
+	writel(seq->misccfg->reg_file_init_seq_signature,
+	       &sdr_reg_file->signature);
 	writel(0, &sdr_reg_file->debug_data_addr);
 	writel(0, &sdr_reg_file->cur_stage);
 	writel(0, &sdr_reg_file->fom);
@@ -3666,15 +3742,15 @@
  *
  * Initialize the register file with usable initial data.
  */
-static void initialize_tracking(void)
+static void initialize_tracking(struct socfpga_sdrseq *seq)
 {
 	/*
 	 * Initialize the register file with the correct data.
 	 * Compute usable version of value in case we skip full
 	 * computation later.
 	 */
-	writel(DIV_ROUND_UP(iocfg->delay_per_opa_tap,
-			    iocfg->delay_per_dchain_tap) - 1,
+	writel(DIV_ROUND_UP(seq->iocfg->delay_per_opa_tap,
+			    seq->iocfg->delay_per_dchain_tap) - 1,
 	       &sdr_reg_file->dtaps_per_ptap);
 
 	/* trk_sample_count */
@@ -3693,23 +3769,22 @@
 	       &sdr_reg_file->delays);
 
 	/* mux delay */
-	writel((rwcfg->idle << 24) | (rwcfg->activate_1 << 16) |
-	       (rwcfg->sgle_read << 8) | (rwcfg->precharge_all << 0),
+	writel((seq->rwcfg->idle << 24) | (seq->rwcfg->activate_1 << 16) |
+	       (seq->rwcfg->sgle_read << 8) | (seq->rwcfg->precharge_all << 0),
 	       &sdr_reg_file->trk_rw_mgr_addr);
 
-	writel(rwcfg->mem_if_read_dqs_width,
+	writel(seq->rwcfg->mem_if_read_dqs_width,
 	       &sdr_reg_file->trk_read_dqs_width);
 
 	/* trefi [7:0] */
-	writel((rwcfg->refresh_all << 24) | (1000 << 0),
+	writel((seq->rwcfg->refresh_all << 24) | (1000 << 0),
 	       &sdr_reg_file->trk_rfsh);
 }
 
 int sdram_calibration_full(struct socfpga_sdr *sdr)
 {
-	struct param_type my_param;
-	struct gbl_type my_gbl;
 	u32 pass;
+	struct socfpga_sdrseq seq;
 
 	/*
 	 * For size reasons, this file uses hard coded addresses.
@@ -3718,60 +3793,61 @@
 	if (sdr != (struct socfpga_sdr *)SOCFPGA_SDR_ADDRESS)
 		return -ENODEV;
 
-	memset(&my_param, 0, sizeof(my_param));
-	memset(&my_gbl, 0, sizeof(my_gbl));
+	memset(&seq, 0, sizeof(seq));
 
-	param = &my_param;
-	gbl = &my_gbl;
-
-	rwcfg = socfpga_get_sdram_rwmgr_config();
-	iocfg = socfpga_get_sdram_io_config();
-	misccfg = socfpga_get_sdram_misc_config();
+	seq.rwcfg = socfpga_get_sdram_rwmgr_config();
+	seq.iocfg = socfpga_get_sdram_io_config();
+	seq.misccfg = socfpga_get_sdram_misc_config();
 
 	/* Set the calibration enabled by default */
-	gbl->phy_debug_mode_flags |= PHY_DEBUG_ENABLE_CAL_RPT;
+	seq.gbl.phy_debug_mode_flags |= PHY_DEBUG_ENABLE_CAL_RPT;
 	/*
 	 * Only sweep all groups (regardless of fail state) by default
 	 * Set enabled read test by default.
 	 */
 #if DISABLE_GUARANTEED_READ
-	gbl->phy_debug_mode_flags |= PHY_DEBUG_DISABLE_GUARANTEED_READ;
+	seq.gbl.phy_debug_mode_flags |= PHY_DEBUG_DISABLE_GUARANTEED_READ;
 #endif
 	/* Initialize the register file */
-	initialize_reg_file();
+	initialize_reg_file(&seq);
 
 	/* Initialize any PHY CSR */
 	initialize_hps_phy();
 
 	scc_mgr_initialize();
 
-	initialize_tracking();
+	initialize_tracking(&seq);
 
 	debug("%s: Preparing to start memory calibration\n", __FILE__);
 
 	debug("%s:%d\n", __func__, __LINE__);
 	debug_cond(DLEVEL >= 1,
 		   "DDR3 FULL_RATE ranks=%u cs/dimm=%u dq/dqs=%u,%u vg/dqs=%u,%u ",
-		   rwcfg->mem_number_of_ranks, rwcfg->mem_number_of_cs_per_dimm,
-		   rwcfg->mem_dq_per_read_dqs, rwcfg->mem_dq_per_write_dqs,
-		   rwcfg->mem_virtual_groups_per_read_dqs,
-		   rwcfg->mem_virtual_groups_per_write_dqs);
+		   seq.rwcfg->mem_number_of_ranks,
+		   seq.rwcfg->mem_number_of_cs_per_dimm,
+		   seq.rwcfg->mem_dq_per_read_dqs,
+		   seq.rwcfg->mem_dq_per_write_dqs,
+		   seq.rwcfg->mem_virtual_groups_per_read_dqs,
+		   seq.rwcfg->mem_virtual_groups_per_write_dqs);
 	debug_cond(DLEVEL >= 1,
 		   "dqs=%u,%u dq=%u dm=%u ptap_delay=%u dtap_delay=%u ",
-		   rwcfg->mem_if_read_dqs_width, rwcfg->mem_if_write_dqs_width,
-		   rwcfg->mem_data_width, rwcfg->mem_data_mask_width,
-		   iocfg->delay_per_opa_tap, iocfg->delay_per_dchain_tap);
+		   seq.rwcfg->mem_if_read_dqs_width,
+		   seq.rwcfg->mem_if_write_dqs_width,
+		   seq.rwcfg->mem_data_width, seq.rwcfg->mem_data_mask_width,
+		   seq.iocfg->delay_per_opa_tap,
+		   seq.iocfg->delay_per_dchain_tap);
 	debug_cond(DLEVEL >= 1, "dtap_dqsen_delay=%u, dll=%u",
-		   iocfg->delay_per_dqs_en_dchain_tap, iocfg->dll_chain_length);
+		   seq.iocfg->delay_per_dqs_en_dchain_tap,
+		   seq.iocfg->dll_chain_length);
 	debug_cond(DLEVEL >= 1,
 		   "max values: en_p=%u dqdqs_p=%u en_d=%u dqs_in_d=%u ",
-		   iocfg->dqs_en_phase_max, iocfg->dqdqs_out_phase_max,
-		   iocfg->dqs_en_delay_max, iocfg->dqs_in_delay_max);
+		   seq.iocfg->dqs_en_phase_max, seq.iocfg->dqdqs_out_phase_max,
+		   seq.iocfg->dqs_en_delay_max, seq.iocfg->dqs_in_delay_max);
 	debug_cond(DLEVEL >= 1, "io_in_d=%u io_out1_d=%u io_out2_d=%u ",
-		   iocfg->io_in_delay_max, iocfg->io_out1_delay_max,
-		   iocfg->io_out2_delay_max);
+		   seq.iocfg->io_in_delay_max, seq.iocfg->io_out1_delay_max,
+		   seq.iocfg->io_out2_delay_max);
 	debug_cond(DLEVEL >= 1, "dqs_in_reserve=%u dqs_out_reserve=%u\n",
-		   iocfg->dqs_in_reserve, iocfg->dqs_out_reserve);
+		   seq.iocfg->dqs_in_reserve, seq.iocfg->dqs_out_reserve);
 
 	hc_initialize_rom_data();
 
@@ -3783,17 +3859,17 @@
 	 * Load global needed for those actions that require
 	 * some dynamic calibration support.
 	 */
-	dyn_calib_steps = STATIC_CALIB_STEPS;
+	seq.dyn_calib_steps = STATIC_CALIB_STEPS;
 	/*
 	 * Load global to allow dynamic selection of delay loop settings
 	 * based on calibration mode.
 	 */
-	if (!(dyn_calib_steps & CALIB_SKIP_DELAY_LOOPS))
-		skip_delay_mask = 0xff;
+	if (!(seq.dyn_calib_steps & CALIB_SKIP_DELAY_LOOPS))
+		seq.skip_delay_mask = 0xff;
 	else
-		skip_delay_mask = 0x0;
+		seq.skip_delay_mask = 0x0;
 
-	pass = run_mem_calibrate();
-	debug_mem_calibrate(pass);
+	pass = run_mem_calibrate(&seq);
+	debug_mem_calibrate(&seq, pass);
 	return pass;
 }
diff --git a/drivers/ddr/altera/sequencer.h b/drivers/ddr/altera/sequencer.h
index d7f6935..4a03c3f 100644
--- a/drivers/ddr/altera/sequencer.h
+++ b/drivers/ddr/altera/sequencer.h
@@ -6,14 +6,16 @@
 #ifndef _SEQUENCER_H_
 #define _SEQUENCER_H_
 
-#define RW_MGR_NUM_DM_PER_WRITE_GROUP (rwcfg->mem_data_mask_width \
-	/ rwcfg->mem_if_write_dqs_width)
-#define RW_MGR_NUM_TRUE_DM_PER_WRITE_GROUP (rwcfg->true_mem_data_mask_width \
-	/ rwcfg->mem_if_write_dqs_width)
+#define RW_MGR_NUM_DM_PER_WRITE_GROUP (seq->rwcfg->mem_data_mask_width \
+	/ seq->rwcfg->mem_if_write_dqs_width)
+#define RW_MGR_NUM_TRUE_DM_PER_WRITE_GROUP ( \
+	seq->rwcfg->true_mem_data_mask_width \
+	/ seq->rwcfg->mem_if_write_dqs_width)
 
-#define RW_MGR_NUM_DQS_PER_WRITE_GROUP (rwcfg->mem_if_read_dqs_width \
-	/ rwcfg->mem_if_write_dqs_width)
-#define NUM_RANKS_PER_SHADOW_REG (rwcfg->mem_number_of_ranks / NUM_SHADOW_REGS)
+#define RW_MGR_NUM_DQS_PER_WRITE_GROUP (seq->rwcfg->mem_if_read_dqs_width \
+	/ seq->rwcfg->mem_if_write_dqs_width)
+#define NUM_RANKS_PER_SHADOW_REG (seq->rwcfg->mem_number_of_ranks \
+	/ NUM_SHADOW_REGS)
 
 #define RW_MGR_RUN_SINGLE_GROUP_OFFSET		0x0
 #define RW_MGR_RUN_ALL_GROUPS_OFFSET		0x0400
@@ -256,6 +258,26 @@
 	u8 _align9[0xea4];
 };
 
+struct socfpga_sdrseq {
+	const struct socfpga_sdram_rw_mgr_config *rwcfg;
+	const struct socfpga_sdram_io_config *iocfg;
+	const struct socfpga_sdram_misc_config *misccfg;
+	/* calibration steps requested by the rtl */
+	u16 dyn_calib_steps;
+	/*
+	 * To make CALIB_SKIP_DELAY_LOOPS a dynamic conditional option
+	 * instead of static, we use boolean logic to select between
+	 * non-skip and skip values
+	 *
+	 * The mask is set to include all bits when not-skipping, but is
+	 * zero when skipping
+	 */
+
+	u16 skip_delay_mask;	/* mask off bits when skipping/not-skipping */
+	struct gbl_type gbl;
+	struct param_type param;
+};
+
 int sdram_calibration_full(struct socfpga_sdr *sdr);
 
 #endif /* _SEQUENCER_H_ */
diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index 7d8f161..873bc8c 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -1,9 +1,13 @@
 config FIRMWARE
 	bool "Enable Firmware driver support"
 
+config SPL_FIRMWARE
+	bool "Enable Firmware driver support in SPL"
+	depends on FIRMWARE
+
 config SPL_ARM_PSCI_FW
 	bool
-	select FIRMWARE
+	select SPL_FIRMWARE
 
 config ARM_PSCI_FW
 	bool
@@ -13,6 +17,7 @@
 	tristate "TI System Control Interface (TISCI) Message Protocol"
 	depends on K3_SEC_PROXY
 	select FIRMWARE
+	select SPL_FIRMWARE if SPL
 	help
 	  TI System Control Interface (TISCI) Message Protocol is used to manage
 	  compute systems such as ARM, DSP etc with the system controller in
diff --git a/drivers/fpga/socfpga_arria10.c b/drivers/fpga/socfpga_arria10.c
index 285280e..5fb9d6a 100644
--- a/drivers/fpga/socfpga_arria10.c
+++ b/drivers/fpga/socfpga_arria10.c
@@ -936,10 +936,11 @@
 	fpgamgr_program_write(rbf_data, rbf_size);
 
 	status = fpgamgr_program_finish();
-	if (status) {
-		config_pins(gd->fdt_blob, "fpga");
-		puts("FPGA: Enter user mode.\n");
-	}
+	if (status)
+		return status;
+
+	config_pins(gd->fdt_blob, "fpga");
+	puts("FPGA: Enter user mode.\n");
 
 	return status;
 }
diff --git a/drivers/reset/reset-socfpga.c b/drivers/reset/reset-socfpga.c
index ee4cbcb..822a3fe 100644
--- a/drivers/reset/reset-socfpga.c
+++ b/drivers/reset/reset-socfpga.c
@@ -14,6 +14,7 @@
 
 #include <common.h>
 #include <dm.h>
+#include <dm/lists.h>
 #include <dm/of_access.h>
 #include <reset-uclass.h>
 #include <linux/bitops.h>
@@ -130,6 +131,23 @@
 	return 0;
 }
 
+static int socfpga_reset_bind(struct udevice *dev)
+{
+	int ret;
+	struct udevice *sys_child;
+
+	/*
+	 * The sysreset driver does not have a device node, so bind it here.
+	 * Bind it to the node, too, so that it can get its base address.
+	 */
+	ret = device_bind_driver_to_node(dev, "socfpga_sysreset", "sysreset",
+					 dev->node, &sys_child);
+	if (ret)
+		debug("Warning: No sysreset driver: ret=%d\n", ret);
+
+	return 0;
+}
+
 static const struct udevice_id socfpga_reset_match[] = {
 	{ .compatible = "altr,rst-mgr" },
 	{ /* sentinel */ },
@@ -139,6 +157,7 @@
 	.name = "socfpga-reset",
 	.id = UCLASS_RESET,
 	.of_match = socfpga_reset_match,
+	.bind = socfpga_reset_bind,
 	.probe = socfpga_reset_probe,
 	.priv_auto_alloc_size = sizeof(struct socfpga_reset_data),
 	.ops = &socfpga_reset_ops,
diff --git a/drivers/sysreset/Kconfig b/drivers/sysreset/Kconfig
index 30aed2c..90c41ab 100644
--- a/drivers/sysreset/Kconfig
+++ b/drivers/sysreset/Kconfig
@@ -50,10 +50,25 @@
 config SYSRESET_PSCI
 	bool "Enable support for PSCI System Reset"
 	depends on ARM_PSCI_FW
+	select SPL_ARM_PSCI_FW if SPL
 	help
 	  Enable PSCI SYSTEM_RESET function call.  To use this, PSCI firmware
 	  must be running on your system.
 
+config SYSRESET_SOCFPGA
+	bool "Enable support for Intel SOCFPGA family"
+	depends on ARCH_SOCFPGA && (TARGET_SOCFPGA_GEN5 || TARGET_SOCFPGA_ARRIA10)
+	help
+	  This enables the system reset driver support for Intel SOCFPGA SoCs
+	  (Cyclone 5, Arria 5 and Arria 10).
+
+config SYSRESET_SOCFPGA_S10
+	bool "Enable support for Intel SOCFPGA Stratix 10"
+	depends on ARCH_SOCFPGA && TARGET_SOCFPGA_STRATIX10
+	help
+	  This enables the system reset driver support for Intel SOCFPGA
+	  Stratix SoCs.
+
 config SYSRESET_TI_SCI
 	bool "TI System Control Interface (TI SCI) system reset driver"
 	depends on TI_SCI_PROTOCOL
diff --git a/drivers/sysreset/Makefile b/drivers/sysreset/Makefile
index 8e1c845..cf01492 100644
--- a/drivers/sysreset/Makefile
+++ b/drivers/sysreset/Makefile
@@ -11,6 +11,8 @@
 obj-$(CONFIG_SYSRESET_MCP83XX) += sysreset_mpc83xx.o
 obj-$(CONFIG_SYSRESET_MICROBLAZE) += sysreset_microblaze.o
 obj-$(CONFIG_SYSRESET_PSCI) += sysreset_psci.o
+obj-$(CONFIG_SYSRESET_SOCFPGA) += sysreset_socfpga.o
+obj-$(CONFIG_SYSRESET_SOCFPGA_S10) += sysreset_socfpga_s10.o
 obj-$(CONFIG_SYSRESET_TI_SCI) += sysreset-ti-sci.o
 obj-$(CONFIG_SYSRESET_SYSCON) += sysreset_syscon.o
 obj-$(CONFIG_SYSRESET_WATCHDOG) += sysreset_watchdog.o
diff --git a/drivers/sysreset/sysreset_socfpga.c b/drivers/sysreset/sysreset_socfpga.c
new file mode 100644
index 0000000..d6c26a5
--- /dev/null
+++ b/drivers/sysreset/sysreset_socfpga.c
@@ -0,0 +1,56 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019 Pepperl+Fuchs
+ * Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <sysreset.h>
+#include <asm/io.h>
+#include <asm/arch/reset_manager.h>
+
+struct socfpga_sysreset_data {
+	struct socfpga_reset_manager *rstmgr_base;
+};
+
+static int socfpga_sysreset_request(struct udevice *dev,
+				    enum sysreset_t type)
+{
+	struct socfpga_sysreset_data *data = dev_get_priv(dev);
+
+	switch (type) {
+	case SYSRESET_WARM:
+		writel(BIT(RSTMGR_CTRL_SWWARMRSTREQ_LSB),
+		       &data->rstmgr_base->ctrl);
+		break;
+	case SYSRESET_COLD:
+		writel(BIT(RSTMGR_CTRL_SWCOLDRSTREQ_LSB),
+		       &data->rstmgr_base->ctrl);
+		break;
+	default:
+		return -EPROTONOSUPPORT;
+	}
+	return -EINPROGRESS;
+}
+
+static int socfpga_sysreset_probe(struct udevice *dev)
+{
+	struct socfpga_sysreset_data *data = dev_get_priv(dev);
+
+	data->rstmgr_base = devfdt_get_addr_ptr(dev);
+	return 0;
+}
+
+static struct sysreset_ops socfpga_sysreset = {
+	.request = socfpga_sysreset_request,
+};
+
+U_BOOT_DRIVER(sysreset_socfpga) = {
+	.id	= UCLASS_SYSRESET,
+	.name	= "socfpga_sysreset",
+	.priv_auto_alloc_size = sizeof(struct socfpga_sysreset_data),
+	.ops	= &socfpga_sysreset,
+	.probe	= socfpga_sysreset_probe,
+};
diff --git a/drivers/sysreset/sysreset_socfpga_s10.c b/drivers/sysreset/sysreset_socfpga_s10.c
new file mode 100644
index 0000000..9837aad
--- /dev/null
+++ b/drivers/sysreset/sysreset_socfpga_s10.c
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019 Pepperl+Fuchs
+ * Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <sysreset.h>
+#include <asm/arch/mailbox_s10.h>
+
+static int socfpga_sysreset_request(struct udevice *dev,
+				    enum sysreset_t type)
+{
+	puts("Mailbox: Issuing mailbox cmd REBOOT_HPS\n");
+	mbox_reset_cold();
+	return -EINPROGRESS;
+}
+
+static struct sysreset_ops socfpga_sysreset = {
+	.request = socfpga_sysreset_request,
+};
+
+U_BOOT_DRIVER(sysreset_socfpga) = {
+	.id	= UCLASS_SYSRESET,
+	.name	= "socfpga_sysreset",
+	.ops	= &socfpga_sysreset,
+};
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index c3781b1..261fa98 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -484,7 +484,7 @@
 
 config VIDEO_FSL_DCU_FB
 	bool "Enable Freescale Display Control Unit"
-	depends on VIDEO
+	depends on VIDEO || DM_VIDEO
 	help
 	 This enables support for Freescale Display Control Unit (DCU4)
 	 module found on Freescale Vybrid and QorIQ family of SoCs.
diff --git a/drivers/video/bcm2835.c b/drivers/video/bcm2835.c
index bc41090..1d2eda0 100644
--- a/drivers/video/bcm2835.c
+++ b/drivers/video/bcm2835.c
@@ -19,13 +19,15 @@
 
 	debug("bcm2835: Query resolution...\n");
 	ret = bcm2835_get_video_size(&w, &h);
-	if (ret)
+	if (ret || w == 0 || h == 0)
 		return -EIO;
 
 	debug("bcm2835: Setting up display for %d x %d\n", w, h);
 	ret = bcm2835_set_video_params(&w, &h, 32, BCM2835_MBOX_PIXEL_ORDER_RGB,
 				       BCM2835_MBOX_ALPHA_MODE_IGNORED,
 				       &fb_base, &fb_size, &pitch);
+	if (ret)
+		return -EIO;
 
 	debug("bcm2835: Final resolution is %d x %d\n", w, h);
 
diff --git a/drivers/video/display-uclass.c b/drivers/video/display-uclass.c
index 99ef5e7..1a29ce5 100644
--- a/drivers/video/display-uclass.c
+++ b/drivers/video/display-uclass.c
@@ -37,6 +37,17 @@
 	return 0;
 }
 
+static bool display_mode_valid(void *priv, const struct display_timing *timing)
+{
+	struct udevice *dev = priv;
+	struct dm_display_ops *ops = display_get_ops(dev);
+
+	if (ops && ops->mode_valid)
+		return ops->mode_valid(dev, timing);
+
+	return true;
+}
+
 int display_read_timing(struct udevice *dev, struct display_timing *timing)
 {
 	struct dm_display_ops *ops = display_get_ops(dev);
@@ -53,7 +64,9 @@
 	if (ret < 0)
 		return ret;
 
-	return edid_get_timing(buf, ret, timing, &panel_bits_per_colour);
+	return edid_get_timing_validate(buf, ret, timing,
+					&panel_bits_per_colour,
+					display_mode_valid, dev);
 }
 
 bool display_in_use(struct udevice *dev)
diff --git a/drivers/video/dw_hdmi.c b/drivers/video/dw_hdmi.c
index 463436e..bf74d6a 100644
--- a/drivers/video/dw_hdmi.c
+++ b/drivers/video/dw_hdmi.c
@@ -8,6 +8,7 @@
 #include <common.h>
 #include <fdtdec.h>
 #include <asm/io.h>
+#include <i2c.h>
 #include <media_bus_format.h>
 #include "dw_hdmi.h"
 
@@ -812,6 +813,18 @@
 	u32 trytime = 5;
 	u32 n;
 
+	if (CONFIG_IS_ENABLED(DM_I2C) && hdmi->ddc_bus) {
+		struct udevice *chip;
+
+		edid_read_err = i2c_get_chip(hdmi->ddc_bus,
+					     HDMI_I2CM_SLAVE_DDC_ADDR,
+					     1, &chip);
+		if (edid_read_err)
+			return edid_read_err;
+
+		return dm_i2c_read(chip, shift, buff, HDMI_EDID_BLOCK_SIZE);
+	}
+
 	/* set ddc i2c clk which devided from ddc_clk to 100khz */
 	hdmi_write(hdmi, hdmi->i2c_clk_high, HDMI_I2CM_SS_SCL_HCNT_0_ADDR);
 	hdmi_write(hdmi, hdmi->i2c_clk_low, HDMI_I2CM_SS_SCL_LCNT_0_ADDR);
diff --git a/drivers/video/fsl_dcu_fb.c b/drivers/video/fsl_dcu_fb.c
index 9f6e7f8..add64b8 100644
--- a/drivers/video/fsl_dcu_fb.c
+++ b/drivers/video/fsl_dcu_fb.c
@@ -1,16 +1,19 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
  * Copyright 2014 Freescale Semiconductor, Inc.
+ * Copyright 2019 Toradex AG
  *
  * FSL DCU Framebuffer driver
  */
 
 #include <asm/io.h>
 #include <common.h>
+#include <dm.h>
 #include <fdt_support.h>
 #include <fsl_dcu_fb.h>
 #include <linux/fb.h>
 #include <malloc.h>
+#include <video.h>
 #include <video_fb.h>
 #include "videomodes.h"
 
@@ -218,8 +221,6 @@
 	u32 ctrldescl[DCU_LAYER_MAX_NUM][16];
 };
 
-static struct fb_info info;
-
 static void reset_total_layers(void)
 {
 	struct dcu_reg *regs = (struct dcu_reg *)CONFIG_SYS_DCU_ADDR;
@@ -240,20 +241,22 @@
 	}
 }
 
-static int layer_ctrldesc_init(int index, u32 pixel_format)
+static int layer_ctrldesc_init(struct fb_info fbinfo,
+			       int index, u32 pixel_format)
 {
 	struct dcu_reg *regs = (struct dcu_reg *)CONFIG_SYS_DCU_ADDR;
 	unsigned int bpp = BPP_24_RGB888;
 
 	dcu_write32(&regs->ctrldescl[index][0],
-		    DCU_CTRLDESCLN_1_HEIGHT(info.var.yres) |
-		    DCU_CTRLDESCLN_1_WIDTH(info.var.xres));
+		    DCU_CTRLDESCLN_1_HEIGHT(fbinfo.var.yres) |
+		    DCU_CTRLDESCLN_1_WIDTH(fbinfo.var.xres));
 
 	dcu_write32(&regs->ctrldescl[index][1],
 		    DCU_CTRLDESCLN_2_POSY(0) |
 		    DCU_CTRLDESCLN_2_POSX(0));
 
-	dcu_write32(&regs->ctrldescl[index][2], (unsigned int)info.screen_base);
+	dcu_write32(&regs->ctrldescl[index][2],
+		    (unsigned int)fbinfo.screen_base);
 
 	switch (pixel_format) {
 	case 16:
@@ -294,42 +297,46 @@
 	return 0;
 }
 
-int fsl_dcu_init(unsigned int xres, unsigned int yres,
-		 unsigned int pixel_format)
+int fsl_dcu_init(struct fb_info *fbinfo, unsigned int xres,
+		 unsigned int yres, unsigned int pixel_format)
 {
 	struct dcu_reg *regs = (struct dcu_reg *)CONFIG_SYS_DCU_ADDR;
 	unsigned int div, mode;
+/*
+ * When DM_VIDEO is enabled reservation of framebuffer is done
+ * in advance during bind() call.
+ */
+#if !CONFIG_IS_ENABLED(DM_VIDEO)
+	fbinfo->screen_size = fbinfo->var.xres * fbinfo->var.yres *
+			     (fbinfo->var.bits_per_pixel / 8);
 
-	info.screen_size =
-		info.var.xres * info.var.yres * (info.var.bits_per_pixel / 8);
-
-	if (info.screen_size > CONFIG_VIDEO_FSL_DCU_MAX_FB_SIZE_MB) {
-		info.screen_size = 0;
+	if (fbinfo->screen_size > CONFIG_VIDEO_FSL_DCU_MAX_FB_SIZE_MB) {
+		fbinfo->screen_size = 0;
 		return -ENOMEM;
 	}
-
 	/* Reserve framebuffer at the end of memory */
 	gd->fb_base = gd->bd->bi_dram[0].start +
-			gd->bd->bi_dram[0].size - info.screen_size;
-	info.screen_base = (char *)gd->fb_base;
+			gd->bd->bi_dram[0].size - fbinfo->screen_size;
+	fbinfo->screen_base = (char *)gd->fb_base;
 
-	memset(info.screen_base, 0, info.screen_size);
+	memset(fbinfo->screen_base, 0, fbinfo->screen_size);
+#endif
 
 	reset_total_layers();
 
 	dcu_write32(&regs->disp_size,
-		    DCU_DISP_SIZE_DELTA_Y(info.var.yres) |
-		    DCU_DISP_SIZE_DELTA_X(info.var.xres / 16));
+		    DCU_DISP_SIZE_DELTA_Y(fbinfo->var.yres) |
+		    DCU_DISP_SIZE_DELTA_X(fbinfo->var.xres / 16));
 
 	dcu_write32(&regs->hsyn_para,
-		    DCU_HSYN_PARA_BP(info.var.left_margin) |
-		    DCU_HSYN_PARA_PW(info.var.hsync_len) |
-		    DCU_HSYN_PARA_FP(info.var.right_margin));
+		    DCU_HSYN_PARA_BP(fbinfo->var.left_margin) |
+		    DCU_HSYN_PARA_PW(fbinfo->var.hsync_len) |
+		    DCU_HSYN_PARA_FP(fbinfo->var.right_margin));
 
 	dcu_write32(&regs->vsyn_para,
-		    DCU_VSYN_PARA_BP(info.var.upper_margin) |
-		    DCU_VSYN_PARA_PW(info.var.vsync_len) |
-		    DCU_VSYN_PARA_FP(info.var.lower_margin));
+		    DCU_VSYN_PARA_BP(fbinfo->var.upper_margin) |
+		    DCU_VSYN_PARA_PW(fbinfo->var.vsync_len) |
+		    DCU_VSYN_PARA_FP(fbinfo->var.lower_margin));
 
 	dcu_write32(&regs->synpol,
 		    DCU_SYN_POL_INV_PXCK_FALL |
@@ -352,9 +359,9 @@
 	mode = dcu_read32(&regs->mode);
 	dcu_write32(&regs->mode, mode | DCU_MODE_NORMAL);
 
-	layer_ctrldesc_init(0, pixel_format);
+	layer_ctrldesc_init(*fbinfo, 0, pixel_format);
 
-	div = dcu_set_pixel_clock(info.var.pixclock);
+	div = dcu_set_pixel_clock(fbinfo->var.pixclock);
 	dcu_write32(&regs->div_ratio, (div - 1));
 
 	dcu_write32(&regs->update_mode, DCU_UPDATE_MODE_READREG);
@@ -367,24 +374,26 @@
 	return gd->ram_top - CONFIG_VIDEO_FSL_DCU_MAX_FB_SIZE_MB;
 }
 
-void *video_hw_init(void)
+int fsl_probe_common(struct fb_info *fbinfo, unsigned int *win_x,
+		     unsigned int *win_y)
 {
-	static GraphicDevice ctfb;
 	const char *options;
 	unsigned int depth = 0, freq = 0;
+
 	struct fb_videomode *fsl_dcu_mode_db = &fsl_dcu_mode_480_272;
 
-	if (!video_get_video_mode(&ctfb.winSizeX, &ctfb.winSizeY, &depth, &freq,
+	if (!video_get_video_mode(win_x, win_y, &depth, &freq,
 				  &options))
-		return NULL;
+		return -EINVAL;
 
 	/* Find the monitor port, which is a required option */
 	if (!options)
-		return NULL;
-	if (strncmp(options, "monitor=", 8) != 0)
-		return NULL;
+		return -EINVAL;
 
-	switch (RESOLUTION(ctfb.winSizeX, ctfb.winSizeY)) {
+	if (strncmp(options, "monitor=", 8) != 0)
+		return -EINVAL;
+
+	switch (RESOLUTION(*win_x, *win_y)) {
 	case RESOLUTION(480, 272):
 		fsl_dcu_mode_db = &fsl_dcu_mode_480_272;
 		break;
@@ -402,39 +411,31 @@
 		break;
 	default:
 		printf("unsupported resolution %ux%u\n",
-		       ctfb.winSizeX, ctfb.winSizeY);
+		       *win_x, *win_y);
 	}
 
-	info.var.xres = fsl_dcu_mode_db->xres;
-	info.var.yres = fsl_dcu_mode_db->yres;
-	info.var.bits_per_pixel = 32;
-	info.var.pixclock = fsl_dcu_mode_db->pixclock;
-	info.var.left_margin = fsl_dcu_mode_db->left_margin;
-	info.var.right_margin = fsl_dcu_mode_db->right_margin;
-	info.var.upper_margin = fsl_dcu_mode_db->upper_margin;
-	info.var.lower_margin = fsl_dcu_mode_db->lower_margin;
-	info.var.hsync_len = fsl_dcu_mode_db->hsync_len;
-	info.var.vsync_len = fsl_dcu_mode_db->vsync_len;
-	info.var.sync = fsl_dcu_mode_db->sync;
-	info.var.vmode = fsl_dcu_mode_db->vmode;
-	info.fix.line_length = info.var.xres * info.var.bits_per_pixel / 8;
+	fbinfo->var.xres = fsl_dcu_mode_db->xres;
+	fbinfo->var.yres = fsl_dcu_mode_db->yres;
+	fbinfo->var.bits_per_pixel = 32;
+	fbinfo->var.pixclock = fsl_dcu_mode_db->pixclock;
+	fbinfo->var.left_margin = fsl_dcu_mode_db->left_margin;
+	fbinfo->var.right_margin = fsl_dcu_mode_db->right_margin;
+	fbinfo->var.upper_margin = fsl_dcu_mode_db->upper_margin;
+	fbinfo->var.lower_margin = fsl_dcu_mode_db->lower_margin;
+	fbinfo->var.hsync_len = fsl_dcu_mode_db->hsync_len;
+	fbinfo->var.vsync_len = fsl_dcu_mode_db->vsync_len;
+	fbinfo->var.sync = fsl_dcu_mode_db->sync;
+	fbinfo->var.vmode = fsl_dcu_mode_db->vmode;
+	fbinfo->fix.line_length = fbinfo->var.xres *
+				  fbinfo->var.bits_per_pixel / 8;
 
-	if (platform_dcu_init(ctfb.winSizeX, ctfb.winSizeY,
-			      options + 8, fsl_dcu_mode_db) < 0)
-		return NULL;
-
-	ctfb.frameAdrs = (unsigned int)info.screen_base;
-	ctfb.plnSizeX = ctfb.winSizeX;
-	ctfb.plnSizeY = ctfb.winSizeY;
-
-	ctfb.gdfBytesPP = 4;
-	ctfb.gdfIndex = GDF_32BIT_X888RGB;
-
-	ctfb.memSize = info.screen_size;
-
-	return &ctfb;
+	return platform_dcu_init(fbinfo, *win_x, *win_y,
+				 options + 8, fsl_dcu_mode_db);
 }
 
+#ifndef CONFIG_DM_VIDEO
+static struct fb_info info;
+
 #if defined(CONFIG_OF_BOARD_SETUP)
 int fsl_dcu_fixedfb_setup(void *blob)
 {
@@ -457,3 +458,89 @@
 	return 0;
 }
 #endif
+
+void *video_hw_init(void)
+{
+	static GraphicDevice ctfb;
+
+	if (fsl_probe_common(&info, &ctfb.winSizeX, &ctfb.winSizeY) < 0)
+		return NULL;
+
+	ctfb.frameAdrs = (unsigned int)info.screen_base;
+	ctfb.plnSizeX = ctfb.winSizeX;
+	ctfb.plnSizeY = ctfb.winSizeY;
+
+	ctfb.gdfBytesPP = 4;
+	ctfb.gdfIndex = GDF_32BIT_X888RGB;
+
+	ctfb.memSize = info.screen_size;
+
+	return &ctfb;
+}
+
+#else /* ifndef CONFIG_DM_VIDEO */
+
+static int fsl_dcu_video_probe(struct udevice *dev)
+{
+	struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
+	struct video_priv *uc_priv = dev_get_uclass_priv(dev);
+	struct fb_info fbinfo = { 0 };
+	unsigned int win_x;
+	unsigned int win_y;
+	u32 fb_start, fb_end;
+	int ret = 0;
+
+	fb_start = plat->base & ~(MMU_SECTION_SIZE - 1);
+	fb_end = plat->base + plat->size;
+	fb_end = ALIGN(fb_end, 1 << MMU_SECTION_SHIFT);
+
+	fbinfo.screen_base = (char *)fb_start;
+	fbinfo.screen_size = plat->size;
+
+	ret = fsl_probe_common(&fbinfo, &win_x, &win_y);
+	if (ret < 0)
+		return ret;
+
+	uc_priv->bpix = VIDEO_BPP32;
+	uc_priv->xsize = win_x;
+	uc_priv->ysize = win_y;
+
+	/* Enable dcache for the frame buffer */
+	mmu_set_region_dcache_behaviour(fb_start, fb_end - fb_start,
+					DCACHE_WRITEBACK);
+	video_set_flush_dcache(dev, true);
+	return ret;
+}
+
+static int fsl_dcu_video_bind(struct udevice *dev)
+{
+	struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
+	unsigned int win_x;
+	unsigned int win_y;
+	unsigned int depth = 0, freq = 0;
+	const char *options;
+	int ret = 0;
+
+	ret = video_get_video_mode(&win_x, &win_y, &depth, &freq, &options);
+	if (ret < 0)
+		return ret;
+
+	plat->size = win_x * win_y * 32;
+
+	return 0;
+}
+
+static const struct udevice_id fsl_dcu_video_ids[] = {
+	{ .compatible = "fsl,vf610-dcu" },
+	{ /* sentinel */ }
+};
+
+U_BOOT_DRIVER(fsl_dcu_video) = {
+	.name	= "fsl_dcu_video",
+	.id	= UCLASS_VIDEO,
+	.of_match = fsl_dcu_video_ids,
+	.bind	= fsl_dcu_video_bind,
+	.probe	= fsl_dcu_video_probe,
+	.flags	= DM_FLAG_PRE_RELOC,
+};
+#endif /* ifndef CONFIG_DM_VIDEO */
diff --git a/drivers/video/meson/meson_dw_hdmi.c b/drivers/video/meson/meson_dw_hdmi.c
index 483c93f..9831d97 100644
--- a/drivers/video/meson/meson_dw_hdmi.c
+++ b/drivers/video/meson/meson_dw_hdmi.c
@@ -375,6 +375,9 @@
 	}
 #endif
 
+	uclass_get_device_by_phandle(UCLASS_I2C, dev, "ddc-i2c-bus",
+				     &priv->hdmi.ddc_bus);
+
 	ret = reset_get_bulk(dev, &resets);
 	if (ret)
 		return ret;
@@ -426,9 +429,16 @@
 	return ret;
 }
 
+static bool meson_dw_hdmi_mode_valid(struct udevice *dev,
+				     const struct display_timing *timing)
+{
+	return meson_venc_hdmi_supported_mode(timing);
+}
+
 static const struct dm_display_ops meson_dw_hdmi_ops = {
 	.read_edid = meson_dw_hdmi_read_edid,
 	.enable = meson_dw_hdmi_enable,
+	.mode_valid = meson_dw_hdmi_mode_valid,
 };
 
 static const struct udevice_id meson_dw_hdmi_ids[] = {
diff --git a/drivers/video/mxsfb.c b/drivers/video/mxsfb.c
index f02ba20..6c9a7c0 100644
--- a/drivers/video/mxsfb.c
+++ b/drivers/video/mxsfb.c
@@ -271,6 +271,42 @@
 }
 #else /* ifndef CONFIG_DM_VIDEO */
 
+static int mxs_of_get_timings(struct udevice *dev,
+			      struct display_timing *timings,
+			      u32 *bpp)
+{
+	int ret = 0;
+	u32 display_phandle;
+	ofnode display_node;
+
+	ret = ofnode_read_u32(dev_ofnode(dev), "display", &display_phandle);
+	if (ret) {
+		dev_err(dev, "required display property isn't provided\n");
+		return -EINVAL;
+	}
+
+	display_node = ofnode_get_by_phandle(display_phandle);
+	if (!ofnode_valid(display_node)) {
+		dev_err(dev, "failed to find display subnode\n");
+		return -EINVAL;
+	}
+
+	ret = ofnode_read_u32(display_node, "bits-per-pixel", bpp);
+	if (ret) {
+		dev_err(dev,
+			"required bits-per-pixel property isn't provided\n");
+		return -EINVAL;
+	}
+
+	ret = ofnode_decode_display_timing(display_node, 0, timings);
+	if (ret) {
+		dev_err(dev, "failed to get any display timings\n");
+		return -EINVAL;
+	}
+
+	return ret;
+}
+
 static int mxs_video_probe(struct udevice *dev)
 {
 	struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
@@ -278,18 +314,16 @@
 
 	struct ctfb_res_modes mode;
 	struct display_timing timings;
-	int bpp = -1;
+	u32 bpp = 0;
 	u32 fb_start, fb_end;
 	int ret;
 
 	debug("%s() plat: base 0x%lx, size 0x%x\n",
 	       __func__, plat->base, plat->size);
 
-	ret = ofnode_decode_display_timing(dev_ofnode(dev), 0, &timings);
-	if (ret) {
-		dev_err(dev, "failed to get any display timings\n");
-		return -EINVAL;
-	}
+	ret = mxs_of_get_timings(dev, &timings, &bpp);
+	if (ret)
+		return ret;
 
 	mode.xres = timings.hactive.typ;
 	mode.yres = timings.vactive.typ;
@@ -301,13 +335,12 @@
 	mode.vsync_len = timings.vsync_len.typ;
 	mode.pixclock = HZ2PS(timings.pixelclock.typ);
 
-	bpp = BITS_PP;
-
 	ret = mxs_probe_common(&mode, bpp, plat->base);
 	if (ret)
 		return ret;
 
 	switch (bpp) {
+	case 32:
 	case 24:
 	case 18:
 		uc_priv->bpix = VIDEO_BPP32;
@@ -341,15 +374,32 @@
 {
 	struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
 	struct display_timing timings;
+	u32 bpp = 0;
+	u32 bytes_pp = 0;
 	int ret;
 
-	ret = ofnode_decode_display_timing(dev_ofnode(dev), 0, &timings);
-	if (ret) {
-		dev_err(dev, "failed to get any display timings\n");
+	ret = mxs_of_get_timings(dev, &timings, &bpp);
+	if (ret)
+		return ret;
+
+	switch (bpp) {
+	case 32:
+	case 24:
+	case 18:
+		bytes_pp = 4;
+		break;
+	case 16:
+		bytes_pp = 2;
+		break;
+	case 8:
+		bytes_pp = 1;
+		break;
+	default:
+		dev_err(dev, "invalid bpp specified (bpp = %i)\n", bpp);
 		return -EINVAL;
 	}
 
-	plat->size = timings.hactive.typ * timings.vactive.typ * BYTES_PP;
+	plat->size = timings.hactive.typ * timings.vactive.typ * bytes_pp;
 
 	return 0;
 }
diff --git a/drivers/video/rockchip/rk_hdmi.c b/drivers/video/rockchip/rk_hdmi.c
index 51931ce..5b44a7e 100644
--- a/drivers/video/rockchip/rk_hdmi.c
+++ b/drivers/video/rockchip/rk_hdmi.c
@@ -93,6 +93,9 @@
 
 	priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
 
+	uclass_get_device_by_phandle(UCLASS_I2C, dev, "ddc-i2c-bus",
+				     &hdmi->ddc_bus);
+
 	return 0;
 }
 
diff --git a/drivers/video/simple_panel.c b/drivers/video/simple_panel.c
index 7a968e7..c3c0e84 100644
--- a/drivers/video/simple_panel.c
+++ b/drivers/video/simple_panel.c
@@ -105,6 +105,7 @@
 	{ .compatible = "auo,b133xtn01" },
 	{ .compatible = "auo,b116xw03" },
 	{ .compatible = "auo,b133htn01" },
+	{ .compatible = "lg,lb070wv8" },
 	{ }
 };
 
diff --git a/drivers/video/sunxi/sunxi_dw_hdmi.c b/drivers/video/sunxi/sunxi_dw_hdmi.c
index 6fe1aa7..cec2329 100644
--- a/drivers/video/sunxi/sunxi_dw_hdmi.c
+++ b/drivers/video/sunxi/sunxi_dw_hdmi.c
@@ -373,6 +373,9 @@
 	priv->hdmi.phy_set = sunxi_dw_hdmi_phy_cfg;
 	priv->mux = uc_plat->source_id;
 
+	uclass_get_device_by_phandle(UCLASS_I2C, dev, "ddc-i2c-bus",
+				     &priv->hdmi.ddc_bus);
+
 	dw_hdmi_init(&priv->hdmi);
 
 	return 0;
diff --git a/include/configs/colibri-imx6ull.h b/include/configs/colibri-imx6ull.h
index 2c43862..05af222 100644
--- a/include/configs/colibri-imx6ull.h
+++ b/include/configs/colibri-imx6ull.h
@@ -170,7 +170,7 @@
 #define CONFIG_SYS_DFU_DATA_BUF_SIZE	SZ_16M
 #define DFU_DEFAULT_POLL_TIMEOUT	300
 
-#ifdef CONFIG_VIDEO
+#if defined(CONFIG_VIDEO) || defined(CONFIG_DM_VIDEO)
 #define CONFIG_VIDEO_MXS
 #define MXS_LCDIF_BASE MX6UL_LCDIF1_BASE_ADDR
 #define CONFIG_VIDEO_LOGO
diff --git a/include/configs/rk3128_common.h b/include/configs/rk3128_common.h
index 20d6243..d12696d 100644
--- a/include/configs/rk3128_common.h
+++ b/include/configs/rk3128_common.h
@@ -19,6 +19,8 @@
 #define CONFIG_SYS_ARCH_TIMER
 #define CONFIG_SYS_HZ_CLOCK		24000000
 
+#define CONFIG_IRAM_BASE		0x10080000
+
 #define CONFIG_SYS_INIT_SP_ADDR		0x60100000
 #define CONFIG_SYS_LOAD_ADDR		0x60800800
 
diff --git a/include/configs/rk3188_common.h b/include/configs/rk3188_common.h
index 1d41702..92524b0 100644
--- a/include/configs/rk3188_common.h
+++ b/include/configs/rk3188_common.h
@@ -15,8 +15,6 @@
 #define CONFIG_SYS_MALLOC_LEN		(32 << 20)
 #define CONFIG_SYS_CBSIZE		1024
 
-#define CONFIG_SYS_NS16550_MEM32
-
 #ifdef CONFIG_SPL_ROCKCHIP_BACK_TO_BROM
 /* Bootrom will load u-boot binary to 0x60000000 once return from SPL */
 #endif
@@ -25,6 +23,7 @@
 
 #define CONFIG_ROCKCHIP_MAX_INIT_SIZE	(0x8000 - 0x800)
 #define CONFIG_ROCKCHIP_CHIP_TAG	"RK31"
+#define CONFIG_IRAM_BASE	0x10080000
 
 /* spl size 32kb sram - 2kb bootrom */
 #define CONFIG_SPL_MAX_SIZE		(0x8000 - 0x800)
diff --git a/include/configs/rk322x_common.h b/include/configs/rk322x_common.h
index cc08699..9582cdf 100644
--- a/include/configs/rk322x_common.h
+++ b/include/configs/rk322x_common.h
@@ -24,6 +24,7 @@
 
 #define CONFIG_ROCKCHIP_MAX_INIT_SIZE	(28 << 10)
 #define CONFIG_ROCKCHIP_CHIP_TAG	"RK32"
+#define CONFIG_IRAM_BASE		0x10080000
 
 #define CONFIG_SYS_SDRAM_BASE		0x60000000
 #define SDRAM_BANK_SIZE			(512UL << 20UL)
diff --git a/include/configs/rk3288_common.h b/include/configs/rk3288_common.h
index 5472a90..da10e29 100644
--- a/include/configs/rk3288_common.h
+++ b/include/configs/rk3288_common.h
@@ -9,6 +9,8 @@
 #include <asm/arch-rockchip/hardware.h>
 #include "rockchip-common.h"
 
+#define CONFIG_SYS_BOOTM_LEN (16 << 20) /* 16MB */
+
 #define CONFIG_SKIP_LOWLEVEL_INIT_ONLY
 #define CONFIG_SYS_MALLOC_LEN		(32 << 20)
 #define CONFIG_SYS_CBSIZE		1024
@@ -25,6 +27,8 @@
 #define CONFIG_SYS_LOAD_ADDR		0x00800800
 #define CONFIG_SPL_STACK		0xff718000
 
+#define CONFIG_IRAM_BASE		0xff700000
+
 /* RAW SD card / eMMC locations. */
 #define CONFIG_SYS_SPI_U_BOOT_OFFS	(128 << 10)
 
diff --git a/include/configs/rk3328_common.h b/include/configs/rk3328_common.h
index 2a81c80..6ed7525 100644
--- a/include/configs/rk3328_common.h
+++ b/include/configs/rk3328_common.h
@@ -8,12 +8,14 @@
 
 #include "rockchip-common.h"
 
+#define CONFIG_IRAM_BASE		0xff090000
+
+#define CONFIG_ROCKCHIP_STIMER_BASE    0xff1d0020
+
 #define CONFIG_SYS_MALLOC_LEN		(32 << 20)
 #define CONFIG_SYS_CBSIZE		1024
 #define CONFIG_SKIP_LOWLEVEL_INIT
 
-#define CONFIG_SYS_NS16550_MEM32
-
 #define CONFIG_SYS_INIT_SP_ADDR		0x00300000
 #define CONFIG_SYS_LOAD_ADDR		0x00800800
 #define CONFIG_SPL_STACK		0x00400000
diff --git a/include/configs/rk3368_common.h b/include/configs/rk3368_common.h
index 8a1e311..340413d 100644
--- a/include/configs/rk3368_common.h
+++ b/include/configs/rk3368_common.h
@@ -23,7 +23,7 @@
 #define CONFIG_ROCKCHIP_STIMER_BASE	0xff830020
 #define COUNTER_FREQUENCY		24000000
 
-#define CONFIG_SYS_NS16550_MEM32
+#define CONFIG_IRAM_BASE		0xff8c0000
 
 #define CONFIG_SYS_INIT_SP_ADDR		0x00300000
 #define CONFIG_SYS_LOAD_ADDR		0x00280000
diff --git a/include/configs/rk3399_common.h b/include/configs/rk3399_common.h
index 8df0180..12ad60d 100644
--- a/include/configs/rk3399_common.h
+++ b/include/configs/rk3399_common.h
@@ -15,7 +15,7 @@
 #define COUNTER_FREQUENCY               24000000
 #define CONFIG_ROCKCHIP_STIMER_BASE	0xff8680a0
 
-#define CONFIG_SYS_NS16550_MEM32
+#define CONFIG_IRAM_BASE		0xff8c0000
 
 #define CONFIG_SYS_INIT_SP_ADDR		0x00300000
 #define CONFIG_SYS_LOAD_ADDR		0x00800800
diff --git a/include/configs/rv1108_common.h b/include/configs/rv1108_common.h
index 6f61f01..691aa51 100644
--- a/include/configs/rv1108_common.h
+++ b/include/configs/rv1108_common.h
@@ -8,6 +8,8 @@
 #include <asm/arch-rockchip/hardware.h>
 #include "rockchip-common.h"
 
+#define CONFIG_IRAM_BASE		0x10080000
+
 #define CONFIG_SYS_MALLOC_LEN		(32 << 20)
 #define CONFIG_SYS_CBSIZE		1024
 #define CONFIG_SKIP_LOWLEVEL_INIT
diff --git a/include/configs/socfpga_dbm_soc1.h b/include/configs/socfpga_dbm_soc1.h
index b36d7e5..fc1db24 100644
--- a/include/configs/socfpga_dbm_soc1.h
+++ b/include/configs/socfpga_dbm_soc1.h
@@ -87,7 +87,8 @@
 			"echo Running bootscript... ; "			\
 			"source ${kernel_addr_r} ; "			\
 		"fi ; "							\
-		"fi\0"
+		"fi\0"							\
+	"socfpga_legacy_reset_compat=1\0"
 
 /* The rest of the configuration is shared */
 #include <configs/socfpga_common.h>
diff --git a/include/configs/socfpga_stratix10_socdk.h b/include/configs/socfpga_stratix10_socdk.h
index 8d2971c..90ad817 100644
--- a/include/configs/socfpga_stratix10_socdk.h
+++ b/include/configs/socfpga_stratix10_socdk.h
@@ -113,7 +113,8 @@
 	"scriptaddr=0x02100000\0" \
 	"scriptfile=u-boot.scr\0" \
 	"fatscript=if fatload mmc 0:1 ${scriptaddr} ${scriptfile};" \
-		   "then source ${scriptaddr}; fi\0"
+		   "then source ${scriptaddr}; fi\0" \
+	"socfpga_legacy_reset_compat=1\0"
 
 /*
  * Generic Interrupt Controller Definitions
diff --git a/include/configs/socfpga_vining_fpga.h b/include/configs/socfpga_vining_fpga.h
index 29a92b9..5416c4b 100644
--- a/include/configs/socfpga_vining_fpga.h
+++ b/include/configs/socfpga_vining_fpga.h
@@ -145,6 +145,7 @@
 			"run ubi_ubi ; "				\
 		"else echo \"Unsupported boot mode: \"${bootmode} ; "	\
 		"fi\0"							\
+		"socfpga_legacy_reset_compat=1\0"
 
 #define CONFIG_SYS_REDUNDAND_ENVIRONMENT
 #define CONFIG_ENV_SIZE_REDUND		CONFIG_ENV_SIZE
diff --git a/include/display.h b/include/display.h
index 16f317c..6629461 100644
--- a/include/display.h
+++ b/include/display.h
@@ -80,6 +80,16 @@
 	 */
 	int (*enable)(struct udevice *dev, int panel_bpp,
 		      const struct display_timing *timing);
+
+	/**
+	 * mode_valid() - Check if mode is supported
+	 *
+	 * @dev:	Device to enable
+	 * @timing:	Display timings
+	 * @return true if supported, false if not
+	 */
+	bool (*mode_valid)(struct udevice *dev,
+			   const struct display_timing *timing);
 };
 
 #define display_get_ops(dev)	((struct dm_display_ops *)(dev)->driver->ops)
diff --git a/include/dw_hdmi.h b/include/dw_hdmi.h
index 90fb64b..8acae38 100644
--- a/include/dw_hdmi.h
+++ b/include/dw_hdmi.h
@@ -542,6 +542,7 @@
 	u8 i2c_clk_low;
 	u8 reg_io_width;
 	struct hdmi_data_info hdmi_data;
+	struct udevice *ddc_bus;
 
 	int (*phy_set)(struct dw_hdmi *hdmi, uint mpixelclock);
 	void (*write_reg)(struct dw_hdmi *hdmi, u8 val, int offset);
diff --git a/include/edid.h b/include/edid.h
index f05d2b8..2562733 100644
--- a/include/edid.h
+++ b/include/edid.h
@@ -307,6 +307,28 @@
 struct display_timing;
 
 /**
+ * edid_get_timing_validate() - Get basic digital display parameters with
+ * mode selection callback
+ *
+ * @param buf		Buffer containing EDID data
+ * @param buf_size	Size of buffer in bytes
+ * @param timing	Place to put preferring timing information
+ * @param panel_bits_per_colourp	Place to put the number of bits per
+ *			colour supported by the panel. This will be set to
+ *			-1 if not available
+ * @param mode_valid	Callback validating mode, returning true is mode is
+ *			supported, false otherwise.
+ * @parem valid_priv	Pointer to private data for mode_valid callback
+ * @return 0 if timings are OK, -ve on error
+ */
+int edid_get_timing_validate(u8 *buf, int buf_size,
+			     struct display_timing *timing,
+			     int *panel_bits_per_colourp,
+			     bool (*mode_valid)(void *priv,
+					const struct display_timing *timing),
+			     void *mode_valid_priv);
+
+/**
  * edid_get_timing() - Get basic digital display parameters
  *
  * @param buf		Buffer containing EDID data
diff --git a/include/fsl_dcu_fb.h b/include/fsl_dcu_fb.h
index 2dd5f54..7a5347a 100644
--- a/include/fsl_dcu_fb.h
+++ b/include/fsl_dcu_fb.h
@@ -6,11 +6,17 @@
  */
 #include <linux/fb.h>
 
-int fsl_dcu_init(unsigned int xres, unsigned int yres,
+int fsl_dcu_init(struct fb_info *fbinfo,
+		 unsigned int xres,
+		 unsigned int yres,
 		 unsigned int pixel_format);
+
 int fsl_dcu_fixedfb_setup(void *blob);
 
 /* Prototypes for external board-specific functions */
-int platform_dcu_init(unsigned int xres, unsigned int yres,
-		      const char *port, struct fb_videomode *dcu_fb_videomode);
+int platform_dcu_init(struct fb_info *fbinfo,
+		      unsigned int xres,
+		      unsigned int yres,
+		      const char *port,
+		      struct fb_videomode *dcu_fb_videomode);
 unsigned int dcu_set_pixel_clock(unsigned int pixclock);
diff --git a/tools/Makefile b/tools/Makefile
index 87d81a3..c7afe8a 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -269,8 +269,14 @@
 $(LOGO_H):	$(obj)/bmp_logo $(LOGO_BMP)
 	$(obj)/bmp_logo --gen-info $(LOGO_BMP) > $@
 
+ifeq ($(CONFIG_DM_VIDEO),y)
+$(LOGO_DATA_H):	$(obj)/bmp_logo $(LOGO_BMP)
+	$(obj)/bmp_logo --gen-bmp $(LOGO_BMP) > $@
+else
 $(LOGO_DATA_H):	$(obj)/bmp_logo $(LOGO_BMP)
 	$(obj)/bmp_logo --gen-data $(LOGO_BMP) > $@
+#endif
+endif
 
 # Let clean descend into subdirs
 subdir- += env
diff --git a/tools/bmp_logo.c b/tools/bmp_logo.c
index 55f833f..74fcadc 100644
--- a/tools/bmp_logo.c
+++ b/tools/bmp_logo.c
@@ -2,7 +2,8 @@
 
 enum {
 	MODE_GEN_INFO,
-	MODE_GEN_DATA
+	MODE_GEN_DATA,
+	MODE_GEN_BMP
 };
 
 typedef struct bitmap_s {		/* bitmap description */
@@ -16,7 +17,8 @@
 
 void usage(const char *prog)
 {
-	fprintf(stderr, "Usage: %s [--gen-info|--gen-data] file\n", prog);
+	fprintf(stderr, "Usage: %s [--gen-info|--gen-data|--gen-bmp] file\n",
+		prog);
 }
 
 /*
@@ -73,6 +75,7 @@
 int main (int argc, char *argv[])
 {
 	int	mode, i, x;
+	int	size;
 	FILE	*fp;
 	bitmap_t bmp;
 	bitmap_t *b = &bmp;
@@ -87,6 +90,8 @@
 		mode = MODE_GEN_INFO;
 	else if (!strcmp(argv[1], "--gen-data"))
 		mode = MODE_GEN_DATA;
+	else if (!strcmp(argv[1], "--gen-bmp"))
+		mode = MODE_GEN_BMP;
 	else {
 		usage(argv[0]);
 		exit(EXIT_FAILURE);
@@ -131,6 +136,7 @@
 	b->width = le_short(b->width);
 	b->height = le_short(b->height);
 	n_colors = le_short(n_colors);
+	size = b->width * b->height;
 
 	/* assume we are working with an 8-bit file */
 	if ((n_colors == 0) || (n_colors > 256 - DEFAULT_CMAP_SIZE)) {
@@ -152,10 +158,6 @@
 		"#ifndef __BMP_LOGO_DATA_H__\n"
 		"#define __BMP_LOGO_DATA_H__\n\n");
 
-	/* allocate memory */
-	if ((b->data = (uint8_t *)malloc(b->width * b->height)) == NULL)
-		error ("Error allocating memory for file", fp);
-
 	/* read and print the palette information */
 	printf("unsigned short bmp_logo_palette[] = {\n");
 
@@ -175,21 +177,39 @@
 	}
 
 	/* seek to offset indicated by file header */
-	fseek(fp, (long)data_offset, SEEK_SET);
+	if (mode == MODE_GEN_BMP) {
+		/* copy full bmp file */
+		fseek(fp, 0L, SEEK_END);
+		size = ftell(fp);
+		fseek(fp, 0L, SEEK_SET);
+	} else {
+		fseek(fp, (long)data_offset, SEEK_SET);
+	}
+
+	/* allocate memory */
+	b->data = (uint8_t *)malloc(size);
+	if (!b->data)
+		error("Error allocating memory for file", fp);
 
 	/* read the bitmap; leave room for default color map */
 	printf ("\n");
 	printf ("};\n");
 	printf ("\n");
 	printf("unsigned char bmp_logo_bitmap[] = {\n");
-	for (i=(b->height-1)*b->width; i>=0; i-=b->width) {
-		for (x = 0; x < b->width; x++) {
-			b->data[i + x] = (uint8_t) fgetc(fp)
+	if (mode == MODE_GEN_BMP) {
+		/* write full bmp */
+		for (i = 0; i < size; i++)
+			b->data[i] = (uint8_t)fgetc(fp);
+	} else {
+		for (i = (b->height - 1) * b->width; i >= 0; i -= b->width) {
+			for (x = 0; x < b->width; x++) {
+				b->data[i + x] = (uint8_t)fgetc(fp)
 						+ DEFAULT_CMAP_SIZE;
+			}
 		}
 	}
 
-	for (i=0; i<(b->height*b->width); ++i) {
+	for (i = 0; i < size; ++i) {
 		if ((i%8) == 0)
 			putchar ('\t');
 		printf ("0x%02X,%c",