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

- fix i.MX6ULL evk black screen observed while reboot stress tests
- remove "synopsys,dw-mipi-dsi" compatible to reduce the device tree
  differences between Linux and U-Boot for stm32mp1 platform
diff --git a/Makefile b/Makefile
index a9a78c3..d512990 100644
--- a/Makefile
+++ b/Makefile
@@ -17,6 +17,25 @@
 # o Look for make include files relative to root of kernel src
 MAKEFLAGS += -rR --include-dir=$(CURDIR)
 
+# Determine host architecture
+include include/host_arch.h
+MK_ARCH="${shell uname -m}"
+unexport HOST_ARCH
+ifeq ("x86_64", $(MK_ARCH))
+  export HOST_ARCH=$(HOST_ARCH_X86_64)
+else ifneq (,$(findstring $(MK_ARCH), "i386" "i486" "i586" "i686"))
+  export HOST_ARCH=$(HOST_ARCH_X86)
+else ifneq (,$(findstring $(MK_ARCH), "aarch64" "armv8l"))
+  export HOST_ARCH=$(HOST_ARCH_AARCH64)
+else ifeq ("armv7l", $(MK_ARCH))
+  export HOST_ARCH=$(HOST_ARCH_ARM)
+else ifeq ("riscv32", $(MK_ARCH))
+  export HOST_ARCH=$(HOST_ARCH_RISCV32)
+else ifeq ("riscv64", $(MK_ARCH))
+  export HOST_ARCH=$(HOST_ARCH_RISCV64)
+endif
+undefine MK_ARCH
+
 # Avoid funny character set dependencies
 unexport LC_ALL
 LC_COLLATE=C
@@ -751,6 +770,7 @@
 libs-$(CONFIG_HAS_POST) += post/
 libs-$(CONFIG_UNIT_TEST) += test/ test/dm/
 libs-$(CONFIG_UT_ENV) += test/env/
+libs-$(CONFIG_UT_OPTEE) += test/optee/
 libs-$(CONFIG_UT_OVERLAY) += test/overlay/
 
 libs-y += $(if $(BOARDDIR),board/$(BOARDDIR)/)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 7b80630..f96841c 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1604,7 +1604,6 @@
 	select OF_CONTROL
 	select SPI
 	select SPL_DM if SPL
-	select SPL_SYS_MALLOC_SIMPLE if SPL
 	select SYS_MALLOC_F
 	select SYS_THUMB_BUILD if !ARM64
 	imply ADC
@@ -1614,6 +1613,7 @@
 	imply FAT_WRITE
 	imply SARADC_ROCKCHIP
 	imply SPL_SYSRESET
+	imply SPL_SYS_MALLOC_SIMPLE
 	imply SYS_NS16550
 	imply TPL_SYSRESET
 	imply USB_FUNCTION_FASTBOOT
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 5a64fcc..d8846df 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -67,6 +67,9 @@
 dtb-$(CONFIG_ARCH_OWL) += \
 	bubblegum_96.dtb
 
+dtb-$(CONFIG_ROCKCHIP_PX30) += \
+	px30-evb.dtb
+
 dtb-$(CONFIG_ROCKCHIP_RK3036) += \
 	rk3036-sdk.dtb
 
@@ -87,12 +90,17 @@
 	rk3288-popmetal.dtb \
 	rk3288-rock2-square.dtb \
 	rk3288-tinker.dtb \
+	rk3288-tinker-s.dtb \
 	rk3288-veyron-jerry.dtb \
 	rk3288-veyron-mickey.dtb \
 	rk3288-veyron-minnie.dtb \
 	rk3288-veyron-speedy.dtb \
 	rk3288-vyasa.dtb
 
+dtb-$(CONFIG_ROCKCHIP_RK3308) += \
+	rk3308-evb.dtb \
+	rk3308-roc-cc.dtb
+
 dtb-$(CONFIG_ROCKCHIP_RK3328) += \
 	rk3328-evb.dtb \
 	rk3328-rock64.dtb
@@ -661,6 +669,7 @@
 
 dtb-$(CONFIG_ARCH_IMX8M) += \
 	imx8mm-evk.dtb \
+	imx8mn-ddr4-evk.dtb \
 	imx8mq-evk.dtb
 
 dtb-$(CONFIG_RCAR_GEN2) += \
diff --git a/arch/arm/dts/armada-388-clearfog-u-boot.dtsi b/arch/arm/dts/armada-388-clearfog-u-boot.dtsi
index cf6c088..38e4f3d 100644
--- a/arch/arm/dts/armada-388-clearfog-u-boot.dtsi
+++ b/arch/arm/dts/armada-388-clearfog-u-boot.dtsi
@@ -12,6 +12,10 @@
 	u-boot,dm-spl;
 };
 
+&gpio0 {
+	u-boot,dm-spl;
+};
+
 &ahci0 {
 	u-boot,dm-spl;
 };
diff --git a/arch/arm/dts/fsl-imx8qm-mek-u-boot.dtsi b/arch/arm/dts/fsl-imx8qm-mek-u-boot.dtsi
index 5d50eb0..80d6475 100644
--- a/arch/arm/dts/fsl-imx8qm-mek-u-boot.dtsi
+++ b/arch/arm/dts/fsl-imx8qm-mek-u-boot.dtsi
@@ -3,6 +3,11 @@
  * Copyright 2018 NXP
  */
 
+&{/imx8qm-pm} {
+
+	u-boot,dm-spl;
+};
+
 &mu {
 	u-boot,dm-spl;
 };
@@ -67,6 +72,14 @@
 	u-boot,dm-spl;
 };
 
+&pd_dma {
+	u-boot,dm-spl;
+};
+
+&pd_dma_lpuart0 {
+	u-boot,dm-spl;
+};
+
 &gpio0 {
 	u-boot,dm-spl;
 };
diff --git a/arch/arm/dts/fsl-imx8qxp-mek-u-boot.dtsi b/arch/arm/dts/fsl-imx8qxp-mek-u-boot.dtsi
index 2015590..771ab63 100644
--- a/arch/arm/dts/fsl-imx8qxp-mek-u-boot.dtsi
+++ b/arch/arm/dts/fsl-imx8qxp-mek-u-boot.dtsi
@@ -72,6 +72,14 @@
 	u-boot,dm-spl;
 };
 
+&pd_dma {
+	u-boot,dm-spl;
+};
+
+&pd_dma_lpuart0 {
+	u-boot,dm-spl;
+};
+
 &gpio0 {
 	u-boot,dm-spl;
 };
diff --git a/arch/arm/dts/imx8mm-evk-u-boot.dtsi b/arch/arm/dts/imx8mm-evk-u-boot.dtsi
index 16093f2..3502602 100644
--- a/arch/arm/dts/imx8mm-evk-u-boot.dtsi
+++ b/arch/arm/dts/imx8mm-evk-u-boot.dtsi
@@ -11,6 +11,9 @@
 &clk {
 	u-boot,dm-spl;
 	u-boot,dm-pre-reloc;
+	/delete-property/ assigned-clocks;
+	/delete-property/ assigned-clock-parents;
+	/delete-property/ assigned-clock-rates;
 };
 
 &osc_24m {
@@ -110,3 +113,7 @@
 &pinctrl_pmic {
 	u-boot,dm-spl;
 };
+
+&fec1 {
+	phy-reset-gpios = <&gpio4 22 GPIO_ACTIVE_LOW>;
+};
diff --git a/arch/arm/dts/imx8mm-evk.dts b/arch/arm/dts/imx8mm-evk.dts
index faefb71..ef249ff 100644
--- a/arch/arm/dts/imx8mm-evk.dts
+++ b/arch/arm/dts/imx8mm-evk.dts
@@ -464,7 +464,7 @@
 			MX8MM_IOMUXC_NAND_CE2_B_USDHC3_DATA5		0x1d0
 			MX8MM_IOMUXC_NAND_CE3_B_USDHC3_DATA6		0x1d0
 			MX8MM_IOMUXC_NAND_CLE_USDHC3_DATA7		0x1d0
-			MX8MM_IOMUXC_NAND_CE1_B_USDHC3_STROBE 		0x190
+			MX8MM_IOMUXC_NAND_CE1_B_USDHC3_STROBE		0x190
 		>;
 	};
 
@@ -480,7 +480,7 @@
 			MX8MM_IOMUXC_NAND_CE2_B_USDHC3_DATA5		0x1d4
 			MX8MM_IOMUXC_NAND_CE3_B_USDHC3_DATA6		0x1d4
 			MX8MM_IOMUXC_NAND_CLE_USDHC3_DATA7		0x1d4
-			MX8MM_IOMUXC_NAND_CE1_B_USDHC3_STROBE 		0x194
+			MX8MM_IOMUXC_NAND_CE1_B_USDHC3_STROBE		0x194
 		>;
 	};
 
@@ -496,7 +496,7 @@
 			MX8MM_IOMUXC_NAND_CE2_B_USDHC3_DATA5		0x1d6
 			MX8MM_IOMUXC_NAND_CE3_B_USDHC3_DATA6		0x1d6
 			MX8MM_IOMUXC_NAND_CLE_USDHC3_DATA7		0x1d6
-			MX8MM_IOMUXC_NAND_CE1_B_USDHC3_STROBE 		0x196
+			MX8MM_IOMUXC_NAND_CE1_B_USDHC3_STROBE		0x196
 		>;
 	};
 
diff --git a/arch/arm/dts/imx8mn-ddr4-evk-u-boot.dtsi b/arch/arm/dts/imx8mn-ddr4-evk-u-boot.dtsi
new file mode 100644
index 0000000..8d61597
--- /dev/null
+++ b/arch/arm/dts/imx8mn-ddr4-evk-u-boot.dtsi
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2019 NXP
+ */
+
+&{/soc@0} {
+	u-boot,dm-pre-reloc;
+	u-boot,dm-spl;
+};
+
+&clk {
+	u-boot,dm-spl;
+	u-boot,dm-pre-reloc;
+};
+
+&osc_24m {
+	u-boot,dm-spl;
+	u-boot,dm-pre-reloc;
+};
+
+&aips1 {
+	u-boot,dm-spl;
+	u-boot,dm-pre-reloc;
+};
+
+&aips2 {
+	u-boot,dm-spl;
+};
+
+&aips3 {
+	u-boot,dm-spl;
+};
+
+&iomuxc {
+	u-boot,dm-spl;
+};
+
+&pinctrl_reg_usdhc2_vmmc {
+	u-boot,dm-spl;
+};
+
+&pinctrl_uart2 {
+	u-boot,dm-spl;
+};
+
+&pinctrl_usdhc2_gpio {
+	u-boot,dm-spl;
+};
+
+&pinctrl_usdhc2 {
+	u-boot,dm-spl;
+};
+
+&pinctrl_usdhc3 {
+	u-boot,dm-spl;
+};
+
+&gpio1 {
+	u-boot,dm-spl;
+};
+
+&gpio2 {
+	u-boot,dm-spl;
+};
+
+&gpio3 {
+	u-boot,dm-spl;
+};
+
+&gpio4 {
+	u-boot,dm-spl;
+};
+
+&gpio5 {
+	u-boot,dm-spl;
+};
+
+&uart2 {
+	u-boot,dm-spl;
+};
+
+&usdhc1 {
+	u-boot,dm-spl;
+};
+
+&usdhc2 {
+	u-boot,dm-spl;
+};
+
+&usdhc3 {
+	u-boot,dm-spl;
+};
diff --git a/arch/arm/dts/imx8mn-ddr4-evk.dts b/arch/arm/dts/imx8mn-ddr4-evk.dts
new file mode 100644
index 0000000..9b2c172
--- /dev/null
+++ b/arch/arm/dts/imx8mn-ddr4-evk.dts
@@ -0,0 +1,221 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2019 NXP
+ */
+
+/dts-v1/;
+
+#include "imx8mn.dtsi"
+
+/ {
+	model = "NXP i.MX8MNano DDR4 EVK board";
+	compatible = "fsl,imx8mn-ddr4-evk", "fsl,imx8mn";
+
+	chosen {
+		stdout-path = &uart2;
+	};
+
+	reg_usdhc2_vmmc: regulator-usdhc2 {
+		compatible = "regulator-fixed";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_reg_usdhc2_vmmc>;
+		regulator-name = "VSD_3V3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		gpio = <&gpio2 19 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+};
+
+&iomuxc {
+	pinctrl-names = "default";
+
+	pinctrl_fec1: fec1grp {
+		fsl,pins = <
+			MX8MN_IOMUXC_ENET_MDC_ENET1_MDC		0x3
+			MX8MN_IOMUXC_ENET_MDIO_ENET1_MDIO	0x3
+			MX8MN_IOMUXC_ENET_TD3_ENET1_RGMII_TD3	0x1f
+			MX8MN_IOMUXC_ENET_TD2_ENET1_RGMII_TD2	0x1f
+			MX8MN_IOMUXC_ENET_TD1_ENET1_RGMII_TD1	0x1f
+			MX8MN_IOMUXC_ENET_TD0_ENET1_RGMII_TD0	0x1f
+			MX8MN_IOMUXC_ENET_RD3_ENET1_RGMII_RD3	0x91
+			MX8MN_IOMUXC_ENET_RD2_ENET1_RGMII_RD2	0x91
+			MX8MN_IOMUXC_ENET_RD1_ENET1_RGMII_RD1	0x91
+			MX8MN_IOMUXC_ENET_RD0_ENET1_RGMII_RD0	0x91
+			MX8MN_IOMUXC_ENET_TXC_ENET1_RGMII_TXC	0x1f
+			MX8MN_IOMUXC_ENET_RXC_ENET1_RGMII_RXC	0x91
+			MX8MN_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL	0x91
+			MX8MN_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL	0x1f
+			MX8MN_IOMUXC_SAI2_RXC_GPIO4_IO22	0x19
+		>;
+	};
+
+	pinctrl_reg_usdhc2_vmmc: regusdhc2vmmc {
+		fsl,pins = <
+			MX8MN_IOMUXC_SD2_RESET_B_GPIO2_IO19	0x41
+		>;
+	};
+
+	pinctrl_uart2: uart2grp {
+		fsl,pins = <
+			MX8MN_IOMUXC_UART2_RXD_UART2_DCE_RX	0x140
+			MX8MN_IOMUXC_UART2_TXD_UART2_DCE_TX	0x140
+		>;
+	};
+
+	pinctrl_usdhc2_gpio: usdhc2grpgpio {
+		fsl,pins = <
+			MX8MN_IOMUXC_GPIO1_IO15_GPIO1_IO15	0x1c4
+		>;
+	};
+
+	pinctrl_usdhc2: usdhc2grp {
+		fsl,pins = <
+			MX8MN_IOMUXC_SD2_CLK_USDHC2_CLK		0x190
+			MX8MN_IOMUXC_SD2_CMD_USDHC2_CMD		0x1d0
+			MX8MN_IOMUXC_SD2_DATA0_USDHC2_DATA0	0x1d0
+			MX8MN_IOMUXC_SD2_DATA1_USDHC2_DATA1	0x1d0
+			MX8MN_IOMUXC_SD2_DATA2_USDHC2_DATA2	0x1d0
+			MX8MN_IOMUXC_SD2_DATA3_USDHC2_DATA3	0x1d0
+			MX8MN_IOMUXC_GPIO1_IO04_USDHC2_VSELECT	0x1d0
+		>;
+	};
+
+	pinctrl_usdhc2_100mhz: usdhc2grp100mhz {
+		fsl,pins = <
+			MX8MN_IOMUXC_SD2_CLK_USDHC2_CLK		0x194
+			MX8MN_IOMUXC_SD2_CMD_USDHC2_CMD		0x1d4
+			MX8MN_IOMUXC_SD2_DATA0_USDHC2_DATA0	0x1d4
+			MX8MN_IOMUXC_SD2_DATA1_USDHC2_DATA1	0x1d4
+			MX8MN_IOMUXC_SD2_DATA2_USDHC2_DATA2	0x1d4
+			MX8MN_IOMUXC_SD2_DATA3_USDHC2_DATA3	0x1d4
+			MX8MN_IOMUXC_GPIO1_IO04_USDHC2_VSELECT	0x1d0
+		>;
+	};
+
+	pinctrl_usdhc2_200mhz: usdhc2grp200mhz {
+		fsl,pins = <
+			MX8MN_IOMUXC_SD2_CLK_USDHC2_CLK		0x196
+			MX8MN_IOMUXC_SD2_CMD_USDHC2_CMD		0x1d6
+			MX8MN_IOMUXC_SD2_DATA0_USDHC2_DATA0	0x1d6
+			MX8MN_IOMUXC_SD2_DATA1_USDHC2_DATA1	0x1d6
+			MX8MN_IOMUXC_SD2_DATA2_USDHC2_DATA2	0x1d6
+			MX8MN_IOMUXC_SD2_DATA3_USDHC2_DATA3	0x1d6
+			MX8MN_IOMUXC_GPIO1_IO04_USDHC2_VSELECT	0x1d0
+		>;
+	};
+
+	pinctrl_usdhc3: usdhc3grp {
+		fsl,pins = <
+			MX8MN_IOMUXC_NAND_WE_B_USDHC3_CLK		0x40000190
+			MX8MN_IOMUXC_NAND_WP_B_USDHC3_CMD		0x1d0
+			MX8MN_IOMUXC_NAND_DATA04_USDHC3_DATA0		0x1d0
+			MX8MN_IOMUXC_NAND_DATA05_USDHC3_DATA1		0x1d0
+			MX8MN_IOMUXC_NAND_DATA06_USDHC3_DATA2		0x1d0
+			MX8MN_IOMUXC_NAND_DATA07_USDHC3_DATA3		0x1d0
+			MX8MN_IOMUXC_NAND_RE_B_USDHC3_DATA4		0x1d0
+			MX8MN_IOMUXC_NAND_CE2_B_USDHC3_DATA5		0x1d0
+			MX8MN_IOMUXC_NAND_CE3_B_USDHC3_DATA6		0x1d0
+			MX8MN_IOMUXC_NAND_CLE_USDHC3_DATA7		0x1d0
+			MX8MN_IOMUXC_NAND_CE1_B_USDHC3_STROBE		0x190
+		>;
+	};
+
+	pinctrl_usdhc3_100mhz: usdhc3grp100mhz {
+		fsl,pins = <
+			MX8MN_IOMUXC_NAND_WE_B_USDHC3_CLK		0x40000194
+			MX8MN_IOMUXC_NAND_WP_B_USDHC3_CMD		0x1d4
+			MX8MN_IOMUXC_NAND_DATA04_USDHC3_DATA0		0x1d4
+			MX8MN_IOMUXC_NAND_DATA05_USDHC3_DATA1		0x1d4
+			MX8MN_IOMUXC_NAND_DATA06_USDHC3_DATA2		0x1d4
+			MX8MN_IOMUXC_NAND_DATA07_USDHC3_DATA3		0x1d4
+			MX8MN_IOMUXC_NAND_RE_B_USDHC3_DATA4		0x1d4
+			MX8MN_IOMUXC_NAND_CE2_B_USDHC3_DATA5		0x1d4
+			MX8MN_IOMUXC_NAND_CE3_B_USDHC3_DATA6		0x1d4
+			MX8MN_IOMUXC_NAND_CLE_USDHC3_DATA7		0x1d4
+			MX8MN_IOMUXC_NAND_CE1_B_USDHC3_STROBE		0x194
+		>;
+	};
+
+	pinctrl_usdhc3_200mhz: usdhc3grp200mhz {
+		fsl,pins = <
+			MX8MN_IOMUXC_NAND_WE_B_USDHC3_CLK		0x40000196
+			MX8MN_IOMUXC_NAND_WP_B_USDHC3_CMD		0x1d6
+			MX8MN_IOMUXC_NAND_DATA04_USDHC3_DATA0		0x1d6
+			MX8MN_IOMUXC_NAND_DATA05_USDHC3_DATA1		0x1d6
+			MX8MN_IOMUXC_NAND_DATA06_USDHC3_DATA2		0x1d6
+			MX8MN_IOMUXC_NAND_DATA07_USDHC3_DATA3		0x1d6
+			MX8MN_IOMUXC_NAND_RE_B_USDHC3_DATA4		0x1d6
+			MX8MN_IOMUXC_NAND_CE2_B_USDHC3_DATA5		0x1d6
+			MX8MN_IOMUXC_NAND_CE3_B_USDHC3_DATA6		0x1d6
+			MX8MN_IOMUXC_NAND_CLE_USDHC3_DATA7		0x1d6
+			MX8MN_IOMUXC_NAND_CE1_B_USDHC3_STROBE		0x196
+		>;
+	};
+
+	pinctrl_wdog: wdoggrp {
+		fsl,pins = <
+			MX8MN_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B		0xc6
+		>;
+	};
+};
+
+&fec1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_fec1>;
+	phy-mode = "rgmii-id";
+	phy-handle = <&ethphy0>;
+	fsl,magic-packet;
+	status = "okay";
+
+	mdio {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		ethphy0: ethernet-phy@0 {
+			compatible = "ethernet-phy-ieee802.3-c22";
+			reg = <0>;
+			at803x,led-act-blind-workaround;
+			at803x,eee-disabled;
+			at803x,vddio-1p8v;
+		};
+	};
+};
+
+&snvs_pwrkey {
+	status = "okay";
+};
+
+&uart2 { /* console */
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart2>;
+	status = "okay";
+};
+
+&usdhc2 {
+	pinctrl-names = "default", "state_100mhz", "state_200mhz";
+	pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
+	pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>;
+	pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>;
+	cd-gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+	bus-width = <4>;
+	vmmc-supply = <&reg_usdhc2_vmmc>;
+	status = "okay";
+};
+
+&usdhc3 {
+	pinctrl-names = "default", "state_100mhz", "state_200mhz";
+	pinctrl-0 = <&pinctrl_usdhc3>;
+	pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
+	pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
+	bus-width = <8>;
+	non-removable;
+	status = "okay";
+};
+
+&wdog1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_wdog>;
+	fsl,ext-reset-output;
+	status = "okay";
+};
diff --git a/arch/arm/dts/imx8mn-pinfunc.h b/arch/arm/dts/imx8mn-pinfunc.h
new file mode 100644
index 0000000..3de8168
--- /dev/null
+++ b/arch/arm/dts/imx8mn-pinfunc.h
@@ -0,0 +1,646 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2019 NXP
+ *
+ */
+
+#ifndef __DTS_IMX8MN_PINFUNC_H
+#define __DTS_IMX8MN_PINFUNC_H
+
+/*
+ * The pin function ID is a tuple of
+ * <mux_reg conf_reg input_reg mux_mode input_val>
+ */
+#define MX8MN_IOMUXC_BOOT_MODE2_CCMSRCGPCMIX_BOOT_MODE2                        0x0020 0x025C 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_BOOT_MODE2_I2C1_SCL                                       0x0020 0x025C 0x055C 0x1 0x3
+#define MX8MN_IOMUXC_BOOT_MODE3_CCMSRCGPCMIX_BOOT_MODE3                        0x0024 0x0260 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_BOOT_MODE3_I2C1_SDA                                       0x0024 0x0260 0x056C 0x1 0x3
+#define MX8MN_IOMUXC_GPIO1_IO00_GPIO1_IO0                                      0x0028 0x0290 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_GPIO1_IO00_CCMSRCGPCMIX_ENET_PHY_REF_CLK_ROOT             0x0028 0x0290 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_GPIO1_IO00_ANAMIX_REF_CLK_32K                             0x0028 0x0290 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_GPIO1_IO00_CCMSRCGPCMIX_EXT_CLK1                          0x0028 0x0290 0x0000 0x6 0x0
+#define MX8MN_IOMUXC_GPIO1_IO01_GPIO1_IO1                                      0x002C 0x0294 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_GPIO1_IO01_PWM1_OUT                                       0x002C 0x0294 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_GPIO1_IO01_ANAMIX_REF_CLK_24M                             0x002C 0x0294 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_GPIO1_IO01_CCMSRCGPCMIX_EXT_CLK2                          0x002C 0x0294 0x0000 0x6 0x0
+#define MX8MN_IOMUXC_GPIO1_IO02_GPIO1_IO2                                      0x0030 0x0298 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B                                   0x0030 0x0298 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_GPIO1_IO02_WDOG1_WDOG_ANY                                 0x0030 0x0298 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_GPIO1_IO03_GPIO1_IO3                                      0x0034 0x029C 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_GPIO1_IO03_USDHC1_VSELECT                                 0x0034 0x029C 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_GPIO1_IO03_SDMA1_EXT_EVENT0                               0x0034 0x029C 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_GPIO1_IO03_ANAMIX_XTAL_OK                                 0x0034 0x029C 0x0000 0x6 0x0
+#define MX8MN_IOMUXC_GPIO1_IO04_GPIO1_IO4                                      0x0038 0x02A0 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_GPIO1_IO04_USDHC2_VSELECT                                 0x0038 0x02A0 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_GPIO1_IO04_SDMA1_EXT_EVENT1                               0x0038 0x02A0 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_GPIO1_IO04_ANAMIX_XTAL_OK_LV                              0x0038 0x02A0 0x0000 0x6 0x0
+#define MX8MN_IOMUXC_GPIO1_IO05_GPIO1_IO5                                      0x003C 0x02A4 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_GPIO1_IO05_M4_NMI                                         0x003C 0x02A4 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_GPIO1_IO05_CCMSRCGPCMIX_PMIC_READY                        0x003C 0x02A4 0x04BC 0x5 0x0
+#define MX8MN_IOMUXC_GPIO1_IO05_CCMSRCGPCMIX_INT_BOOT                          0x003C 0x02A4 0x0000 0x6 0x0
+#define MX8MN_IOMUXC_GPIO1_IO06_GPIO1_IO6                                      0x0040 0x02A8 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_GPIO1_IO06_ENET1_MDC                                      0x0040 0x02A8 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_GPIO1_IO06_USDHC1_CD_B                                    0x0040 0x02A8 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_GPIO1_IO06_CCMSRCGPCMIX_EXT_CLK3                          0x0040 0x02A8 0x0000 0x6 0x0
+#define MX8MN_IOMUXC_GPIO1_IO07_GPIO1_IO7                                      0x0044 0x02AC 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_GPIO1_IO07_ENET1_MDIO                                     0x0044 0x02AC 0x04C0 0x1 0x0
+#define MX8MN_IOMUXC_GPIO1_IO07_USDHC1_WP                                      0x0044 0x02AC 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_GPIO1_IO07_CCMSRCGPCMIX_EXT_CLK4                          0x0044 0x02AC 0x0000 0x6 0x0
+#define MX8MN_IOMUXC_GPIO1_IO08_GPIO1_IO8                                      0x0048 0x02B0 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_GPIO1_IO08_ENET1_1588_EVENT0_IN                           0x0048 0x02B0 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_GPIO1_IO08_PWM1_OUT                                       0x0048 0x02B0 0x0000 0x2 0x0
+#define MX8MN_IOMUXC_GPIO1_IO08_USDHC2_RESET_B                                 0x0048 0x02B0 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_GPIO1_IO08_CCMSRCGPCMIX_WAIT                              0x0048 0x02B0 0x0000 0x6 0x0
+#define MX8MN_IOMUXC_GPIO1_IO09_GPIO1_IO9                                      0x004C 0x02B4 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_GPIO1_IO09_ENET1_1588_EVENT0_OUT                          0x004C 0x02B4 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_GPIO1_IO09_PWM2_OUT                                       0x004C 0x02B4 0x0000 0x2 0x0
+#define MX8MN_IOMUXC_GPIO1_IO09_USDHC3_RESET_B                                 0x004C 0x02B4 0x0000 0x4 0x0
+#define MX8MN_IOMUXC_GPIO1_IO09_SDMA2_EXT_EVENT0                               0x004C 0x02B4 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_GPIO1_IO09_CCMSRCGPCMIX_STOP                              0x004C 0x02B4 0x0000 0x6 0x0
+#define MX8MN_IOMUXC_GPIO1_IO10_GPIO1_IO10                                     0x0050 0x02B8 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_GPIO1_IO10_USB1_OTG_ID                                    0x0050 0x02B8 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_GPIO1_IO10_PWM3_OUT                                       0x0050 0x02B8 0x0000 0x2 0x0
+#define MX8MN_IOMUXC_GPIO1_IO11_GPIO1_IO11                                     0x0054 0x02BC 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_GPIO1_IO11_PWM2_OUT                                       0x0054 0x02BC 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_GPIO1_IO11_USDHC3_VSELECT                                 0x0054 0x02BC 0x0000 0x4 0x0
+#define MX8MN_IOMUXC_GPIO1_IO11_CCMSRCGPCMIX_PMIC_READY                        0x0054 0x02BC 0x04BC 0x5 0x1
+#define MX8MN_IOMUXC_GPIO1_IO11_CCMSRCGPCMIX_OUT0                              0x0054 0x02BC 0x0000 0x6 0x0
+#define MX8MN_IOMUXC_GPIO1_IO12_GPIO1_IO12                                     0x0058 0x02C0 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_GPIO1_IO12_USB1_OTG_PWR                                   0x0058 0x02C0 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_GPIO1_IO12_SDMA2_EXT_EVENT1                               0x0058 0x02C0 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_GPIO1_IO12_CCMSRCGPCMIX_OUT1                              0x0058 0x02C0 0x0000 0x6 0x0
+#define MX8MN_IOMUXC_GPIO1_IO13_GPIO1_IO13                                     0x005C 0x02C4 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_GPIO1_IO13_USB1_OTG_OC                                    0x005C 0x02C4 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_GPIO1_IO13_PWM2_OUT                                       0x005C 0x02C4 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_GPIO1_IO13_CCMSRCGPCMIX_OUT2                              0x005C 0x02C4 0x0000 0x6 0x0
+#define MX8MN_IOMUXC_GPIO1_IO14_GPIO1_IO14                                     0x0060 0x02C8 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_GPIO1_IO14_USDHC3_CD_B                                    0x0060 0x02C8 0x0598 0x4 0x2
+#define MX8MN_IOMUXC_GPIO1_IO14_PWM3_OUT                                       0x0060 0x02C8 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_GPIO1_IO14_CCMSRCGPCMIX_CLKO1                             0x0060 0x02C8 0x0000 0x6 0x0
+#define MX8MN_IOMUXC_GPIO1_IO15_GPIO1_IO15                                     0x0064 0x02CC 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_GPIO1_IO15_USDHC3_WP                                      0x0064 0x02CC 0x05B8 0x4 0x2
+#define MX8MN_IOMUXC_GPIO1_IO15_PWM4_OUT                                       0x0064 0x02CC 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_GPIO1_IO15_CCMSRCGPCMIX_CLKO2                             0x0064 0x02CC 0x0000 0x6 0x0
+#define MX8MN_IOMUXC_ENET_MDC_ENET1_MDC                                        0x0068 0x02D0 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_ENET_MDC_SAI6_TX_DATA0                                    0x0068 0x02D0 0x0000 0x2 0x0
+#define MX8MN_IOMUXC_ENET_MDC_PDM_BIT_STREAM3                                  0x0068 0x02D0 0x0540 0x3 0x1
+#define MX8MN_IOMUXC_ENET_MDC_SPDIF1_OUT                                       0x0068 0x02D0 0x0000 0x4 0x0
+#define MX8MN_IOMUXC_ENET_MDC_GPIO1_IO16                                       0x0068 0x02D0 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_ENET_MDC_USDHC3_STROBE                                    0x0068 0x02D0 0x059C 0x6 0x1
+#define MX8MN_IOMUXC_ENET_MDIO_ENET1_MDIO                                      0x006C 0x02D4 0x04C0 0x0 0x1
+#define MX8MN_IOMUXC_ENET_MDIO_SAI6_TX_SYNC                                    0x006C 0x02D4 0x0000 0x2 0x0
+#define MX8MN_IOMUXC_ENET_MDIO_PDM_BIT_STREAM2                                 0x006C 0x02D4 0x053C 0x3 0x1
+#define MX8MN_IOMUXC_ENET_MDIO_SPDIF1_IN                                       0x006C 0x02D4 0x05CC 0x4 0x1
+#define MX8MN_IOMUXC_ENET_MDIO_GPIO1_IO17                                      0x006C 0x02D4 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_ENET_MDIO_USDHC3_DATA5                                    0x006C 0x02D4 0x0550 0x6 0x1
+#define MX8MN_IOMUXC_ENET_TD3_ENET1_RGMII_TD3                                  0x0070 0x02D8 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_ENET_TD3_SAI6_TX_BCLK                                     0x0070 0x02D8 0x0000 0x2 0x0
+#define MX8MN_IOMUXC_ENET_TD3_PDM_BIT_STREAM1                                  0x0070 0x02D8 0x0538 0x3 0x1
+#define MX8MN_IOMUXC_ENET_TD3_SPDIF1_EXT_CLK                                   0x0070 0x02D8 0x0568 0x4 0x1
+#define MX8MN_IOMUXC_ENET_TD3_GPIO1_IO18                                       0x0070 0x02D8 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_ENET_TD3_USDHC3_DATA6                                     0x0070 0x02D8 0x0584 0x6 0x1
+#define MX8MN_IOMUXC_ENET_TD2_ENET1_RGMII_TD2                                  0x0074 0x02DC 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_ENET_TD2_ENET1_TX_CLK                                     0x0074 0x02DC 0x05A4 0x1 0x0
+#define MX8MN_IOMUXC_ENET_TD2_CCMSRCGPCMIX_ENET_REF_CLK_ROOT                   0x0074 0x02DC 0x05A4 0x1 0x0
+#define MX8MN_IOMUXC_ENET_TD2_SAI6_RX_DATA0                                    0x0074 0x02DC 0x0000 0x2 0x0
+#define MX8MN_IOMUXC_ENET_TD2_PDM_BIT_STREAM3                                  0x0074 0x02DC 0x0540 0x3 0x2
+#define MX8MN_IOMUXC_ENET_TD2_GPIO1_IO19                                       0x0074 0x02DC 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_ENET_TD2_USDHC3_DATA7                                     0x0074 0x02DC 0x054C 0x6 0x1
+#define MX8MN_IOMUXC_ENET_TD1_ENET1_RGMII_TD1                                  0x0078 0x02E0 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_ENET_TD1_SAI6_RX_SYNC                                     0x0078 0x02E0 0x0000 0x2 0x0
+#define MX8MN_IOMUXC_ENET_TD1_PDM_BIT_STREAM2                                  0x0078 0x02E0 0x053C 0x3 0x2
+#define MX8MN_IOMUXC_ENET_TD1_GPIO1_IO20                                       0x0078 0x02E0 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_ENET_TD1_USDHC3_CD_B                                      0x0078 0x02E0 0x0598 0x6 0x3
+#define MX8MN_IOMUXC_ENET_TD0_ENET1_RGMII_TD0                                  0x007C 0x02E4 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_ENET_TD0_SAI6_RX_BCLK                                     0x007C 0x02E4 0x0000 0x2 0x0
+#define MX8MN_IOMUXC_ENET_TD0_PDM_BIT_STREAM1                                  0x007C 0x02E4 0x0538 0x3 0x2
+#define MX8MN_IOMUXC_ENET_TD0_GPIO1_IO21                                       0x007C 0x02E4 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_ENET_TD0_USDHC3_WP                                        0x007C 0x02E4 0x05B8 0x6 0x3
+#define MX8MN_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL                            0x0080 0x02E8 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_ENET_TX_CTL_SAI6_MCLK                                     0x0080 0x02E8 0x0000 0x2 0x0
+#define MX8MN_IOMUXC_ENET_TX_CTL_GPIO1_IO22                                    0x0080 0x02E8 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_ENET_TX_CTL_USDHC3_DATA0                                  0x0080 0x02E8 0x05B4 0x6 0x1
+#define MX8MN_IOMUXC_ENET_TXC_ENET1_RGMII_TXC                                  0x0084 0x02EC 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_ENET_TXC_ENET1_TX_ER                                      0x0084 0x02EC 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_ENET_TXC_SAI7_TX_DATA0                                    0x0084 0x02EC 0x0000 0x2 0x0
+#define MX8MN_IOMUXC_ENET_TXC_GPIO1_IO23                                       0x0084 0x02EC 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_ENET_TXC_USDHC3_DATA1                                     0x0084 0x02EC 0x05B0 0x6 0x1
+#define MX8MN_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL                            0x0088 0x02F0 0x0574 0x0 0x0
+#define MX8MN_IOMUXC_ENET_RX_CTL_SAI7_TX_SYNC                                  0x0088 0x02F0 0x0000 0x2 0x0
+#define MX8MN_IOMUXC_ENET_RX_CTL_PDM_BIT_STREAM3                               0x0088 0x02F0 0x0540 0x3 0x3
+#define MX8MN_IOMUXC_ENET_RX_CTL_GPIO1_IO24                                    0x0088 0x02F0 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_ENET_RX_CTL_USDHC3_DATA2                                  0x0088 0x02F0 0x05E4 0x6 0x1
+#define MX8MN_IOMUXC_ENET_RXC_ENET1_RGMII_RXC                                  0x008C 0x02F4 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_ENET_RXC_ENET1_RX_ER                                      0x008C 0x02F4 0x05C8 0x1 0x0
+#define MX8MN_IOMUXC_ENET_RXC_SAI7_TX_BCLK                                     0x008C 0x02F4 0x0000 0x2 0x0
+#define MX8MN_IOMUXC_ENET_RXC_PDM_BIT_STREAM2                                  0x008C 0x02F4 0x053C 0x3 0x3
+#define MX8MN_IOMUXC_ENET_RXC_GPIO1_IO25                                       0x008C 0x02F4 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_ENET_RXC_USDHC3_DATA3                                     0x008C 0x02F4 0x05E0 0x6 0x1
+#define MX8MN_IOMUXC_ENET_RD0_ENET1_RGMII_RD0                                  0x0090 0x02F8 0x057C 0x0 0x0
+#define MX8MN_IOMUXC_ENET_RD0_SAI7_RX_DATA0                                    0x0090 0x02F8 0x0000 0x2 0x0
+#define MX8MN_IOMUXC_ENET_RD0_PDM_BIT_STREAM1                                  0x0090 0x02F8 0x0538 0x3 0x3
+#define MX8MN_IOMUXC_ENET_RD0_GPIO1_IO26                                       0x0090 0x02F8 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_ENET_RD0_USDHC3_DATA4                                     0x0090 0x02F8 0x0558 0x6 0x1
+#define MX8MN_IOMUXC_ENET_RD1_ENET1_RGMII_RD1                                  0x0094 0x02FC 0x0554 0x0 0x0
+#define MX8MN_IOMUXC_ENET_RD1_SAI7_RX_SYNC                                     0x0094 0x02FC 0x0000 0x2 0x0
+#define MX8MN_IOMUXC_ENET_RD1_PDM_BIT_STREAM0                                  0x0094 0x02FC 0x0534 0x3 0x1
+#define MX8MN_IOMUXC_ENET_RD1_GPIO1_IO27                                       0x0094 0x02FC 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_ENET_RD1_USDHC3_RESET_B                                   0x0094 0x02FC 0x0000 0x6 0x0
+#define MX8MN_IOMUXC_ENET_RD2_ENET1_RGMII_RD2                                  0x0098 0x0300 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_ENET_RD2_SAI7_RX_BCLK                                     0x0098 0x0300 0x0000 0x2 0x0
+#define MX8MN_IOMUXC_ENET_RD2_PDM_CLK                                          0x0098 0x0300 0x0000 0x3 0x0
+#define MX8MN_IOMUXC_ENET_RD2_GPIO1_IO28                                       0x0098 0x0300 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_ENET_RD2_USDHC3_CLK                                       0x0098 0x0300 0x05A0 0x6 0x1
+#define MX8MN_IOMUXC_ENET_RD3_ENET1_RGMII_RD3                                  0x009C 0x0304 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_ENET_RD3_SAI7_MCLK                                        0x009C 0x0304 0x0000 0x2 0x0
+#define MX8MN_IOMUXC_ENET_RD3_SPDIF1_IN                                        0x009C 0x0304 0x05CC 0x3 0x5
+#define MX8MN_IOMUXC_ENET_RD3_GPIO1_IO29                                       0x009C 0x0304 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_ENET_RD3_USDHC3_CMD                                       0x009C 0x0304 0x05DC 0x6 0x1
+#define MX8MN_IOMUXC_SD1_CLK_USDHC1_CLK                                        0x00A0 0x0308 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_SD1_CLK_ENET1_MDC                                         0x00A0 0x0308 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_SD1_CLK_UART1_DCE_TX                                      0x00A0 0x0308 0x0000 0x4 0x0
+#define MX8MN_IOMUXC_SD1_CLK_UART1_DTE_RX                                      0x00A0 0x0308 0x04F4 0x4 0x4
+#define MX8MN_IOMUXC_SD1_CLK_GPIO2_IO0                                         0x00A0 0x0308 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_SD1_CMD_USDHC1_CMD                                        0x00A4 0x030C 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_SD1_CMD_ENET1_MDIO                                        0x00A4 0x030C 0x04C0 0x1 0x3
+#define MX8MN_IOMUXC_SD1_CMD_UART1_DCE_RX                                      0x00A4 0x030C 0x04F4 0x4 0x5
+#define MX8MN_IOMUXC_SD1_CMD_UART1_DTE_TX                                      0x00A4 0x030C 0x0000 0x4 0x0
+#define MX8MN_IOMUXC_SD1_CMD_GPIO2_IO1                                         0x00A4 0x030C 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_SD1_DATA0_USDHC1_DATA0                                    0x00A8 0x0310 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_SD1_DATA0_ENET1_RGMII_TD1                                 0x00A8 0x0310 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_SD1_DATA0_UART1_DCE_RTS_B                                 0x00A8 0x0310 0x04F0 0x4 0x4
+#define MX8MN_IOMUXC_SD1_DATA0_UART1_DTE_CTS_B                                 0x00A8 0x0310 0x0000 0x4 0x0
+#define MX8MN_IOMUXC_SD1_DATA0_GPIO2_IO2                                       0x00A8 0x0310 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_SD1_DATA1_USDHC1_DATA1                                    0x00AC 0x0314 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_SD1_DATA1_ENET1_RGMII_TD0                                 0x00AC 0x0314 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_SD1_DATA1_UART1_DCE_CTS_B                                 0x00AC 0x0314 0x0000 0x4 0x0
+#define MX8MN_IOMUXC_SD1_DATA1_UART1_DTE_RTS_B                                 0x00AC 0x0314 0x04F0 0x4 0x5
+#define MX8MN_IOMUXC_SD1_DATA1_GPIO2_IO3                                       0x00AC 0x0314 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_SD1_DATA2_USDHC1_DATA2                                    0x00B0 0x0318 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_SD1_DATA2_ENET1_RGMII_RD0                                 0x00B0 0x0318 0x057C 0x1 0x1
+#define MX8MN_IOMUXC_SD1_DATA2_UART2_DCE_TX                                    0x00B0 0x0318 0x0000 0x4 0x0
+#define MX8MN_IOMUXC_SD1_DATA2_UART2_DTE_RX                                    0x00B0 0x0318 0x04FC 0x4 0x4
+#define MX8MN_IOMUXC_SD1_DATA2_GPIO2_IO4                                       0x00B0 0x0318 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_SD1_DATA3_USDHC1_DATA3                                    0x00B4 0x031C 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_SD1_DATA3_ENET1_RGMII_RD1                                 0x00B4 0x031C 0x0554 0x1 0x1
+#define MX8MN_IOMUXC_SD1_DATA3_UART2_DCE_RX                                    0x00B4 0x031C 0x04FC 0x4 0x5
+#define MX8MN_IOMUXC_SD1_DATA3_UART2_DTE_TX                                    0x00B4 0x031C 0x0000 0x4 0x0
+#define MX8MN_IOMUXC_SD1_DATA3_GPIO2_IO5                                       0x00B4 0x031C 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_SD1_DATA4_USDHC1_DATA4                                    0x00B8 0x0320 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_SD1_DATA4_ENET1_RGMII_TX_CTL                              0x00B8 0x0320 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_SD1_DATA4_I2C1_SCL                                        0x00B8 0x0320 0x055C 0x3 0x1
+#define MX8MN_IOMUXC_SD1_DATA4_UART2_DCE_RTS_B                                 0x00B8 0x0320 0x04F8 0x4 0x4
+#define MX8MN_IOMUXC_SD1_DATA4_UART2_DTE_CTS_B                                 0x00B8 0x0320 0x0000 0x4 0x0
+#define MX8MN_IOMUXC_SD1_DATA4_GPIO2_IO6                                       0x00B8 0x0320 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_SD1_DATA5_USDHC1_DATA5                                    0x00BC 0x0324 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_SD1_DATA5_ENET1_TX_ER                                     0x00BC 0x0324 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_SD1_DATA5_I2C1_SDA                                        0x00BC 0x0324 0x056C 0x3 0x1
+#define MX8MN_IOMUXC_SD1_DATA5_UART2_DCE_CTS_B                                 0x00BC 0x0324 0x0000 0x4 0x0
+#define MX8MN_IOMUXC_SD1_DATA5_UART2_DTE_RTS_B                                 0x00BC 0x0324 0x04F8 0x4 0x5
+#define MX8MN_IOMUXC_SD1_DATA5_GPIO2_IO7                                       0x00BC 0x0324 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_SD1_DATA6_USDHC1_DATA6                                    0x00C0 0x0328 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_SD1_DATA6_ENET1_RGMII_RX_CTL                              0x00C0 0x0328 0x0574 0x1 0x1
+#define MX8MN_IOMUXC_SD1_DATA6_I2C2_SCL                                        0x00C0 0x0328 0x05D0 0x3 0x1
+#define MX8MN_IOMUXC_SD1_DATA6_UART3_DCE_TX                                    0x00C0 0x0328 0x0000 0x4 0x0
+#define MX8MN_IOMUXC_SD1_DATA6_UART3_DTE_RX                                    0x00C0 0x0328 0x0504 0x4 0x4
+#define MX8MN_IOMUXC_SD1_DATA6_GPIO2_IO8                                       0x00C0 0x0328 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_SD1_DATA7_USDHC1_DATA7                                    0x00C4 0x032C 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_SD1_DATA7_ENET1_RX_ER                                     0x00C4 0x032C 0x05C8 0x1 0x1
+#define MX8MN_IOMUXC_SD1_DATA7_I2C2_SDA                                        0x00C4 0x032C 0x0560 0x3 0x1
+#define MX8MN_IOMUXC_SD1_DATA7_UART3_DCE_RX                                    0x00C4 0x032C 0x0504 0x4 0x5
+#define MX8MN_IOMUXC_SD1_DATA7_UART3_DTE_TX                                    0x00C4 0x032C 0x0000 0x4 0x0
+#define MX8MN_IOMUXC_SD1_DATA7_GPIO2_IO9                                       0x00C4 0x032C 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_SD1_RESET_B_USDHC1_RESET_B                                0x00C8 0x0330 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_SD1_RESET_B_ENET1_TX_CLK                                  0x00C8 0x0330 0x05A4 0x1 0x1
+#define MX8MN_IOMUXC_SD1_RESET_B_CCMSRCGPCMIX_ENET_REF_CLK_ROOT                0x00C8 0x0330 0x05A4 0x1 0x0
+#define MX8MN_IOMUXC_SD1_RESET_B_I2C3_SCL                                      0x00C8 0x0330 0x0588 0x3 0x1
+#define MX8MN_IOMUXC_SD1_RESET_B_UART3_DCE_RTS_B                               0x00C8 0x0330 0x0500 0x4 0x2
+#define MX8MN_IOMUXC_SD1_RESET_B_UART3_DTE_CTS_B                               0x00C8 0x0330 0x0000 0x4 0x0
+#define MX8MN_IOMUXC_SD1_RESET_B_GPIO2_IO10                                    0x00C8 0x0330 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_SD1_STROBE_USDHC1_STROBE                                  0x00CC 0x0334 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_SD1_STROBE_I2C3_SDA                                       0x00CC 0x0334 0x05BC 0x3 0x1
+#define MX8MN_IOMUXC_SD1_STROBE_UART3_DCE_CTS_B                                0x00CC 0x0334 0x0000 0x4 0x0
+#define MX8MN_IOMUXC_SD1_STROBE_UART3_DTE_RTS_B                                0x00CC 0x0334 0x0500 0x4 0x3
+#define MX8MN_IOMUXC_SD1_STROBE_GPIO2_IO11                                     0x00CC 0x0334 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_SD2_CD_B_USDHC2_CD_B                                      0x00D0 0x0338 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_SD2_CD_B_GPIO2_IO12                                       0x00D0 0x0338 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_SD2_CD_B_CCMSRCGPCMIX_TESTER_ACK                          0x00D0 0x0338 0x0000 0x6 0x0
+#define MX8MN_IOMUXC_SD2_CLK_USDHC2_CLK                                        0x00D4 0x033C 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_SD2_CLK_SAI5_RX_SYNC                                      0x00D4 0x033C 0x04E4 0x1 0x1
+#define MX8MN_IOMUXC_SD2_CLK_ECSPI2_SCLK                                       0x00D4 0x033C 0x0580 0x2 0x1
+#define MX8MN_IOMUXC_SD2_CLK_UART4_DCE_RX                                      0x00D4 0x033C 0x050C 0x3 0x4
+#define MX8MN_IOMUXC_SD2_CLK_UART4_DTE_TX                                      0x00D4 0x033C 0x0000 0x3 0x0
+#define MX8MN_IOMUXC_SD2_CLK_SAI5_MCLK                                         0x00D4 0x033C 0x0594 0x4 0x1
+#define MX8MN_IOMUXC_SD2_CLK_GPIO2_IO13                                        0x00D4 0x033C 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_SD2_CLK_CCMSRCGPCMIX_OBSERVE0                             0x00D4 0x033C 0x0000 0x6 0x0
+#define MX8MN_IOMUXC_SD2_CMD_USDHC2_CMD                                        0x00D8 0x0340 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_SD2_CMD_SAI5_RX_BCLK                                      0x00D8 0x0340 0x04D0 0x1 0x1
+#define MX8MN_IOMUXC_SD2_CMD_ECSPI2_MOSI                                       0x00D8 0x0340 0x0590 0x2 0x1
+#define MX8MN_IOMUXC_SD2_CMD_UART4_DCE_TX                                      0x00D8 0x0340 0x0000 0x3 0x0
+#define MX8MN_IOMUXC_SD2_CMD_UART4_DTE_RX                                      0x00D8 0x0340 0x050C 0x3 0x5
+#define MX8MN_IOMUXC_SD2_CMD_PDM_CLK                                           0x00D8 0x0340 0x0000 0x4 0x0
+#define MX8MN_IOMUXC_SD2_CMD_GPIO2_IO14                                        0x00D8 0x0340 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_SD2_CMD_CCMSRCGPCMIX_OBSERVE1                             0x00D8 0x0340 0x0000 0x6 0x0
+#define MX8MN_IOMUXC_SD2_DATA0_USDHC2_DATA0                                    0x00DC 0x0344 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_SD2_DATA0_SAI5_RX_DATA0                                   0x00DC 0x0344 0x04D4 0x1 0x1
+#define MX8MN_IOMUXC_SD2_DATA0_I2C4_SDA                                        0x00DC 0x0344 0x058C 0x2 0x1
+#define MX8MN_IOMUXC_SD2_DATA0_UART2_DCE_RX                                    0x00DC 0x0344 0x04FC 0x3 0x6
+#define MX8MN_IOMUXC_SD2_DATA0_UART2_DTE_TX                                    0x00DC 0x0344 0x0000 0x3 0x0
+#define MX8MN_IOMUXC_SD2_DATA0_PDM_BIT_STREAM0                                 0x00DC 0x0344 0x0534 0x4 0x2
+#define MX8MN_IOMUXC_SD2_DATA0_GPIO2_IO15                                      0x00DC 0x0344 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_SD2_DATA0_CCMSRCGPCMIX_OBSERVE2                           0x00DC 0x0344 0x0000 0x6 0x0
+#define MX8MN_IOMUXC_SD2_DATA1_USDHC2_DATA1                                    0x00E0 0x0348 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_SD2_DATA1_SAI5_TX_SYNC                                    0x00E0 0x0348 0x04EC 0x1 0x1
+#define MX8MN_IOMUXC_SD2_DATA1_I2C4_SCL                                        0x00E0 0x0348 0x05D4 0x2 0x1
+#define MX8MN_IOMUXC_SD2_DATA1_UART2_DCE_TX                                    0x00E0 0x0348 0x0000 0x3 0x0
+#define MX8MN_IOMUXC_SD2_DATA1_UART2_DTE_RX                                    0x00E0 0x0348 0x04FC 0x3 0x7
+#define MX8MN_IOMUXC_SD2_DATA1_PDM_BIT_STREAM1                                 0x00E0 0x0348 0x0538 0x4 0x4
+#define MX8MN_IOMUXC_SD2_DATA1_GPIO2_IO16                                      0x00E0 0x0348 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_SD2_DATA1_CCMSRCGPCMIX_WAIT                               0x00E0 0x0348 0x0000 0x6 0x0
+#define MX8MN_IOMUXC_SD2_DATA2_USDHC2_DATA2                                    0x00E4 0x034C 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_SD2_DATA2_SAI5_TX_BCLK                                    0x00E4 0x034C 0x04E8 0x1 0x1
+#define MX8MN_IOMUXC_SD2_DATA2_ECSPI2_SS0                                      0x00E4 0x034C 0x0570 0x2 0x2
+#define MX8MN_IOMUXC_SD2_DATA2_SPDIF1_OUT                                      0x00E4 0x034C 0x0000 0x3 0x0
+#define MX8MN_IOMUXC_SD2_DATA2_PDM_BIT_STREAM2                                 0x00E4 0x034C 0x053C 0x4 0x4
+#define MX8MN_IOMUXC_SD2_DATA2_GPIO2_IO17                                      0x00E4 0x034C 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_SD2_DATA2_CCMSRCGPCMIX_STOP                               0x00E4 0x034C 0x0000 0x6 0x0
+#define MX8MN_IOMUXC_SD2_DATA3_USDHC2_DATA3                                    0x00E8 0x0350 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_SD2_DATA3_SAI5_TX_DATA0                                   0x00E8 0x0350 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_SD2_DATA3_ECSPI2_MISO                                     0x00E8 0x0350 0x0578 0x2 0x1
+#define MX8MN_IOMUXC_SD2_DATA3_SPDIF1_IN                                       0x00E8 0x0350 0x05CC 0x3 0x2
+#define MX8MN_IOMUXC_SD2_DATA3_PDM_BIT_STREAM3                                 0x00E8 0x0350 0x0540 0x4 0x4
+#define MX8MN_IOMUXC_SD2_DATA3_GPIO2_IO18                                      0x00E8 0x0350 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_SD2_DATA3_CCMSRCGPCMIX_EARLY_RESET                        0x00E8 0x0350 0x0000 0x6 0x0
+#define MX8MN_IOMUXC_SD2_RESET_B_USDHC2_RESET_B                                0x00EC 0x0354 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_SD2_RESET_B_GPIO2_IO19                                    0x00EC 0x0354 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_SD2_RESET_B_CCMSRCGPCMIX_SYSTEM_RESET                     0x00EC 0x0354 0x0000 0x6 0x0
+#define MX8MN_IOMUXC_SD2_WP_USDHC2_WP                                          0x00F0 0x0358 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_SD2_WP_GPIO2_IO20                                         0x00F0 0x0358 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_SD2_WP_CORESIGHT_EVENTI                                   0x00F0 0x0358 0x0000 0x6 0x0
+#define MX8MN_IOMUXC_NAND_ALE_RAWNAND_ALE                                      0x00F4 0x035C 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_NAND_ALE_QSPI_A_SCLK                                      0x00F4 0x035C 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_NAND_ALE_PDM_BIT_STREAM0                                  0x00F4 0x035C 0x0534 0x3 0x3
+#define MX8MN_IOMUXC_NAND_ALE_UART3_DCE_RX                                     0x00F4 0x035C 0x0504 0x4 0x6
+#define MX8MN_IOMUXC_NAND_ALE_UART3_DTE_TX                                     0x00F4 0x035C 0x0000 0x4 0x0
+#define MX8MN_IOMUXC_NAND_ALE_GPIO3_IO0                                        0x00F4 0x035C 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_NAND_ALE_CORESIGHT_TRACE_CLK                              0x00F4 0x035C 0x0000 0x6 0x0
+#define MX8MN_IOMUXC_NAND_CE0_B_RAWNAND_CE0_B                                  0x00F8 0x0360 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_NAND_CE0_B_QSPI_A_SS0_B                                   0x00F8 0x0360 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_NAND_CE0_B_PDM_BIT_STREAM1                                0x00F8 0x0360 0x0538 0x3 0x5
+#define MX8MN_IOMUXC_NAND_CE0_B_UART3_DCE_TX                                   0x00F8 0x0360 0x0000 0x4 0x0
+#define MX8MN_IOMUXC_NAND_CE0_B_UART3_DTE_RX                                   0x00F8 0x0360 0x0504 0x4 0x7
+#define MX8MN_IOMUXC_NAND_CE0_B_GPIO3_IO1                                      0x00F8 0x0360 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_NAND_CE0_B_CORESIGHT_TRACE_CTL                            0x00F8 0x0360 0x0000 0x6 0x0
+#define MX8MN_IOMUXC_NAND_CE1_B_RAWNAND_CE1_B                                  0x00FC 0x0364 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_NAND_CE1_B_QSPI_A_SS1_B                                   0x00FC 0x0364 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_NAND_CE1_B_USDHC3_STROBE                                  0x00FC 0x0364 0x059C 0x2 0x0
+#define MX8MN_IOMUXC_NAND_CE1_B_PDM_BIT_STREAM0                                0x00FC 0x0364 0x0534 0x3 0x4
+#define MX8MN_IOMUXC_NAND_CE1_B_I2C4_SCL                                       0x00FC 0x0364 0x05D4 0x4 0x2
+#define MX8MN_IOMUXC_NAND_CE1_B_GPIO3_IO2                                      0x00FC 0x0364 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_NAND_CE1_B_CORESIGHT_TRACE0                               0x00FC 0x0364 0x0000 0x6 0x0
+#define MX8MN_IOMUXC_NAND_CE2_B_RAWNAND_CE2_B                                  0x0100 0x0368 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_NAND_CE2_B_QSPI_B_SS0_B                                   0x0100 0x0368 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_NAND_CE2_B_USDHC3_DATA5                                   0x0100 0x0368 0x0550 0x2 0x0
+#define MX8MN_IOMUXC_NAND_CE2_B_PDM_BIT_STREAM1                                0x0100 0x0368 0x0538 0x3 0x6
+#define MX8MN_IOMUXC_NAND_CE2_B_I2C4_SDA                                       0x0100 0x0368 0x058C 0x4 0x2
+#define MX8MN_IOMUXC_NAND_CE2_B_GPIO3_IO3                                      0x0100 0x0368 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_NAND_CE2_B_CORESIGHT_TRACE1                               0x0100 0x0368 0x0000 0x6 0x0
+#define MX8MN_IOMUXC_NAND_CE3_B_RAWNAND_CE3_B                                  0x0104 0x036C 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_NAND_CE3_B_QSPI_B_SS1_B                                   0x0104 0x036C 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_NAND_CE3_B_USDHC3_DATA6                                   0x0104 0x036C 0x0584 0x2 0x0
+#define MX8MN_IOMUXC_NAND_CE3_B_PDM_BIT_STREAM2                                0x0104 0x036C 0x053C 0x3 0x5
+#define MX8MN_IOMUXC_NAND_CE3_B_I2C3_SDA                                       0x0104 0x036C 0x05BC 0x4 0x2
+#define MX8MN_IOMUXC_NAND_CE3_B_GPIO3_IO4                                      0x0104 0x036C 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_NAND_CE3_B_CORESIGHT_TRACE2                               0x0104 0x036C 0x0000 0x6 0x0
+#define MX8MN_IOMUXC_NAND_CLE_RAWNAND_CLE                                      0x0108 0x0370 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_NAND_CLE_QSPI_B_SCLK                                      0x0108 0x0370 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_NAND_CLE_USDHC3_DATA7                                     0x0108 0x0370 0x054C 0x2 0x0
+#define MX8MN_IOMUXC_NAND_CLE_GPIO3_IO5                                        0x0108 0x0370 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_NAND_CLE_CORESIGHT_TRACE3                                 0x0108 0x0370 0x0000 0x6 0x0
+#define MX8MN_IOMUXC_NAND_DATA00_RAWNAND_DATA00                                0x010C 0x0374 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_NAND_DATA00_QSPI_A_DATA0                                  0x010C 0x0374 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_NAND_DATA00_PDM_BIT_STREAM2                               0x010C 0x0374 0x053C 0x3 0x6
+#define MX8MN_IOMUXC_NAND_DATA00_UART4_DCE_RX                                  0x010C 0x0374 0x050C 0x4 0x6
+#define MX8MN_IOMUXC_NAND_DATA00_UART4_DTE_TX                                  0x010C 0x0374 0x0000 0x4 0x0
+#define MX8MN_IOMUXC_NAND_DATA00_GPIO3_IO6                                     0x010C 0x0374 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_NAND_DATA00_CORESIGHT_TRACE4                              0x010C 0x0374 0x0000 0x6 0x0
+#define MX8MN_IOMUXC_NAND_DATA01_RAWNAND_DATA01                                0x0110 0x0378 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_NAND_DATA01_QSPI_A_DATA1                                  0x0110 0x0378 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_NAND_DATA01_PDM_BIT_STREAM3                               0x0110 0x0378 0x0540 0x3 0x5
+#define MX8MN_IOMUXC_NAND_DATA01_UART4_DCE_TX                                  0x0110 0x0378 0x0000 0x4 0x0
+#define MX8MN_IOMUXC_NAND_DATA01_UART4_DTE_RX                                  0x0110 0x0378 0x050C 0x4 0x7
+#define MX8MN_IOMUXC_NAND_DATA01_GPIO3_IO7                                     0x0110 0x0378 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_NAND_DATA01_CORESIGHT_TRACE5                              0x0110 0x0378 0x0000 0x6 0x0
+#define MX8MN_IOMUXC_NAND_DATA02_RAWNAND_DATA02                                0x0114 0x037C 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_NAND_DATA02_QSPI_A_DATA2                                  0x0114 0x037C 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_NAND_DATA02_USDHC3_CD_B                                   0x0114 0x037C 0x0598 0x2 0x0
+#define MX8MN_IOMUXC_NAND_DATA02_I2C4_SDA                                      0x0114 0x037C 0x058C 0x4 0x3
+#define MX8MN_IOMUXC_NAND_DATA02_GPIO3_IO8                                     0x0114 0x037C 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_NAND_DATA02_CORESIGHT_TRACE6                              0x0114 0x037C 0x0000 0x6 0x0
+#define MX8MN_IOMUXC_NAND_DATA03_RAWNAND_DATA03                                0x0118 0x0380 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_NAND_DATA03_QSPI_A_DATA3                                  0x0118 0x0380 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_NAND_DATA03_USDHC3_WP                                     0x0118 0x0380 0x05B8 0x2 0x0
+#define MX8MN_IOMUXC_NAND_DATA03_GPIO3_IO9                                     0x0118 0x0380 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_NAND_DATA03_CORESIGHT_TRACE7                              0x0118 0x0380 0x0000 0x6 0x0
+#define MX8MN_IOMUXC_NAND_DATA04_RAWNAND_DATA04                                0x011C 0x0384 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_NAND_DATA04_QSPI_B_DATA0                                  0x011C 0x0384 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_NAND_DATA04_USDHC3_DATA0                                  0x011C 0x0384 0x05B4 0x2 0x0
+#define MX8MN_IOMUXC_NAND_DATA04_GPIO3_IO10                                    0x011C 0x0384 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_NAND_DATA04_CORESIGHT_TRACE8                              0x011C 0x0384 0x0000 0x6 0x0
+#define MX8MN_IOMUXC_NAND_DATA05_RAWNAND_DATA05                                0x0120 0x0388 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_NAND_DATA05_QSPI_B_DATA1                                  0x0120 0x0388 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_NAND_DATA05_USDHC3_DATA1                                  0x0120 0x0388 0x05B0 0x2 0x0
+#define MX8MN_IOMUXC_NAND_DATA05_GPIO3_IO11                                    0x0120 0x0388 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_NAND_DATA05_CORESIGHT_TRACE9                              0x0120 0x0388 0x0000 0x6 0x0
+#define MX8MN_IOMUXC_NAND_DATA06_RAWNAND_DATA06                                0x0124 0x038C 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_NAND_DATA06_QSPI_B_DATA2                                  0x0124 0x038C 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_NAND_DATA06_USDHC3_DATA2                                  0x0124 0x038C 0x05E4 0x2 0x0
+#define MX8MN_IOMUXC_NAND_DATA06_GPIO3_IO12                                    0x0124 0x038C 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_NAND_DATA06_CORESIGHT_TRACE10                             0x0124 0x038C 0x0000 0x6 0x0
+#define MX8MN_IOMUXC_NAND_DATA07_RAWNAND_DATA07                                0x0128 0x0390 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_NAND_DATA07_QSPI_B_DATA3                                  0x0128 0x0390 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_NAND_DATA07_USDHC3_DATA3                                  0x0128 0x0390 0x05E0 0x2 0x0
+#define MX8MN_IOMUXC_NAND_DATA07_GPIO3_IO13                                    0x0128 0x0390 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_NAND_DATA07_CORESIGHT_TRACE11                             0x0128 0x0390 0x0000 0x6 0x0
+#define MX8MN_IOMUXC_NAND_DQS_RAWNAND_DQS                                      0x012C 0x0394 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_NAND_DQS_QSPI_A_DQS                                       0x012C 0x0394 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_NAND_DQS_PDM_CLK                                          0x012C 0x0394 0x0000 0x3 0x0
+#define MX8MN_IOMUXC_NAND_DQS_I2C3_SCL                                         0x012C 0x0394 0x0588 0x4 0x2
+#define MX8MN_IOMUXC_NAND_DQS_GPIO3_IO14                                       0x012C 0x0394 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_NAND_DQS_CORESIGHT_TRACE12                                0x012C 0x0394 0x0000 0x6 0x0
+#define MX8MN_IOMUXC_NAND_RE_B_RAWNAND_RE_B                                    0x0130 0x0398 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_NAND_RE_B_QSPI_B_DQS                                      0x0130 0x0398 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_NAND_RE_B_USDHC3_DATA4                                    0x0130 0x0398 0x0558 0x2 0x0
+#define MX8MN_IOMUXC_NAND_RE_B_PDM_BIT_STREAM1                                 0x0130 0x0398 0x0538 0x3 0x7
+#define MX8MN_IOMUXC_NAND_RE_B_GPIO3_IO15                                      0x0130 0x0398 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_NAND_RE_B_CORESIGHT_TRACE13                               0x0130 0x0398 0x0000 0x6 0x0
+#define MX8MN_IOMUXC_NAND_READY_B_RAWNAND_READY_B                              0x0134 0x039C 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_NAND_READY_B_USDHC3_RESET_B                               0x0134 0x039C 0x0000 0x2 0x0
+#define MX8MN_IOMUXC_NAND_READY_B_PDM_BIT_STREAM3                              0x0134 0x039C 0x0540 0x3 0x6
+#define MX8MN_IOMUXC_NAND_READY_B_I2C3_SCL                                     0x0134 0x039C 0x0588 0x4 0x3
+#define MX8MN_IOMUXC_NAND_READY_B_GPIO3_IO16                                   0x0134 0x039C 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_NAND_READY_B_CORESIGHT_TRACE14                            0x0134 0x039C 0x0000 0x6 0x0
+#define MX8MN_IOMUXC_NAND_WE_B_RAWNAND_WE_B                                    0x0138 0x03A0 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_NAND_WE_B_USDHC3_CLK                                      0x0138 0x03A0 0x05A0 0x2 0x0
+#define MX8MN_IOMUXC_NAND_WE_B_I2C3_SDA                                        0x0138 0x03A0 0x05BC 0x4 0x3
+#define MX8MN_IOMUXC_NAND_WE_B_GPIO3_IO17                                      0x0138 0x03A0 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_NAND_WE_B_CORESIGHT_TRACE15                               0x0138 0x03A0 0x0000 0x6 0x0
+#define MX8MN_IOMUXC_NAND_WP_B_RAWNAND_WP_B                                    0x013C 0x03A4 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_NAND_WP_B_USDHC3_CMD                                      0x013C 0x03A4 0x05DC 0x2 0x0
+#define MX8MN_IOMUXC_NAND_WP_B_I2C4_SDA                                        0x013C 0x03A4 0x058C 0x4 0x4
+#define MX8MN_IOMUXC_NAND_WP_B_GPIO3_IO18                                      0x013C 0x03A4 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_NAND_WP_B_CORESIGHT_EVENTO                                0x013C 0x03A4 0x0000 0x6 0x0
+#define MX8MN_IOMUXC_SAI5_RXFS_SAI5_RX_SYNC                                    0x0140 0x03A8 0x04E4 0x0 0x0
+#define MX8MN_IOMUXC_SAI5_RXFS_GPIO3_IO19                                      0x0140 0x03A8 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_SAI5_RXC_SAI5_RX_BCLK                                     0x0144 0x03AC 0x04D0 0x0 0x0
+#define MX8MN_IOMUXC_SAI5_RXC_PDM_CLK                                          0x0144 0x03AC 0x0000 0x4 0x0
+#define MX8MN_IOMUXC_SAI5_RXC_GPIO3_IO20                                       0x0144 0x03AC 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_SAI5_RXD0_SAI5_RX_DATA0                                   0x0148 0x03B0 0x04D4 0x0 0x0
+#define MX8MN_IOMUXC_SAI5_RXD0_PDM_BIT_STREAM0                                 0x0148 0x03B0 0x0534 0x4 0x0
+#define MX8MN_IOMUXC_SAI5_RXD0_GPIO3_IO21                                      0x0148 0x03B0 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_SAI5_RXD1_SAI5_RX_DATA1                                   0x014C 0x03B4 0x04D8 0x0 0x0
+#define MX8MN_IOMUXC_SAI5_RXD1_SAI5_TX_SYNC                                    0x014C 0x03B4 0x04EC 0x3 0x0
+#define MX8MN_IOMUXC_SAI5_RXD1_PDM_BIT_STREAM1                                 0x014C 0x03B4 0x0538 0x4 0x0
+#define MX8MN_IOMUXC_SAI5_RXD1_GPIO3_IO22                                      0x014C 0x03B4 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_SAI5_RXD2_SAI5_RX_DATA2                                   0x0150 0x03B8 0x04DC 0x0 0x0
+#define MX8MN_IOMUXC_SAI5_RXD2_SAI5_TX_BCLK                                    0x0150 0x03B8 0x04E8 0x3 0x0
+#define MX8MN_IOMUXC_SAI5_RXD2_PDM_BIT_STREAM2                                 0x0150 0x03B8 0x053C 0x4 0x0
+#define MX8MN_IOMUXC_SAI5_RXD2_GPIO3_IO23                                      0x0150 0x03B8 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_SAI5_RXD3_SAI5_RX_DATA3                                   0x0154 0x03BC 0x04E0 0x0 0x0
+#define MX8MN_IOMUXC_SAI5_RXD3_SAI5_TX_DATA0                                   0x0154 0x03BC 0x0000 0x3 0x0
+#define MX8MN_IOMUXC_SAI5_RXD3_PDM_BIT_STREAM3                                 0x0154 0x03BC 0x0540 0x4 0x0
+#define MX8MN_IOMUXC_SAI5_RXD3_GPIO3_IO24                                      0x0154 0x03BC 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_SAI5_MCLK_SAI5_MCLK                                       0x0158 0x03C0 0x0594 0x0 0x0
+#define MX8MN_IOMUXC_SAI5_MCLK_GPIO3_IO25                                      0x0158 0x03C0 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_SAI2_RXFS_SAI2_RX_SYNC                                    0x01B0 0x0418 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_SAI2_RXFS_SAI5_TX_SYNC                                    0x01B0 0x0418 0x04EC 0x1 0x2
+#define MX8MN_IOMUXC_SAI2_RXFS_SAI5_TX_DATA1                                   0x01B0 0x0418 0x0000 0x2 0x0
+#define MX8MN_IOMUXC_SAI2_RXFS_SAI2_RX_DATA1                                   0x01B0 0x0418 0x05AC 0x3 0x0
+#define MX8MN_IOMUXC_SAI2_RXFS_UART1_DCE_TX                                    0x01B0 0x0418 0x0000 0x4 0x0
+#define MX8MN_IOMUXC_SAI2_RXFS_UART1_DTE_RX                                    0x01B0 0x0418 0x04F4 0x4 0x2
+#define MX8MN_IOMUXC_SAI2_RXFS_GPIO4_IO21                                      0x01B0 0x0418 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_SAI2_RXFS_PDM_BIT_STREAM2                                 0x01B0 0x0418 0x053C 0x6 0x7
+#define MX8MN_IOMUXC_SAI2_RXC_SAI2_RX_BCLK                                     0x01B4 0x041C 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_SAI2_RXC_SAI5_TX_BCLK                                     0x01B4 0x041C 0x04E8 0x1 0x2
+#define MX8MN_IOMUXC_SAI2_RXC_UART1_DCE_RX                                     0x01B4 0x041C 0x04F4 0x4 0x3
+#define MX8MN_IOMUXC_SAI2_RXC_UART1_DTE_TX                                     0x01B4 0x041C 0x0000 0x4 0x0
+#define MX8MN_IOMUXC_SAI2_RXC_GPIO4_IO22                                       0x01B4 0x041C 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_SAI2_RXC_PDM_BIT_STREAM1                                  0x01B4 0x041C 0x0538 0x6 0x8
+#define MX8MN_IOMUXC_SAI2_RXD0_SAI2_RX_DATA0                                   0x01B8 0x0420 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_SAI2_RXD0_SAI5_TX_DATA0                                   0x01B8 0x0420 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_SAI2_RXD0_SAI2_TX_DATA1                                   0x01B8 0x0420 0x0000 0x3 0x0
+#define MX8MN_IOMUXC_SAI2_RXD0_UART1_DCE_RTS_B                                 0x01B8 0x0420 0x04F0 0x4 0x2
+#define MX8MN_IOMUXC_SAI2_RXD0_UART1_DTE_CTS_B                                 0x01B8 0x0420 0x0000 0x4 0x0
+#define MX8MN_IOMUXC_SAI2_RXD0_GPIO4_IO23                                      0x01B8 0x0420 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_SAI2_RXD0_PDM_BIT_STREAM3                                 0x01B8 0x0420 0x0540 0x6 0x7
+#define MX8MN_IOMUXC_SAI2_TXFS_SAI2_TX_SYNC                                    0x01BC 0x0424 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_SAI2_TXFS_SAI5_TX_DATA1                                   0x01BC 0x0424 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_SAI2_TXFS_SAI2_TX_DATA1                                   0x01BC 0x0424 0x0000 0x3 0x0
+#define MX8MN_IOMUXC_SAI2_TXFS_UART1_DCE_CTS_B                                 0x01BC 0x0424 0x0000 0x4 0x0
+#define MX8MN_IOMUXC_SAI2_TXFS_UART1_DTE_RTS_B                                 0x01BC 0x0424 0x04F0 0x4 0x3
+#define MX8MN_IOMUXC_SAI2_TXFS_GPIO4_IO24                                      0x01BC 0x0424 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_SAI2_TXFS_PDM_BIT_STREAM2                                 0x01BC 0x0424 0x053C 0x6 0x8
+#define MX8MN_IOMUXC_SAI2_TXC_SAI2_TX_BCLK                                     0x01C0 0x0428 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_SAI2_TXC_SAI5_TX_DATA2                                    0x01C0 0x0428 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_SAI2_TXC_GPIO4_IO25                                       0x01C0 0x0428 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_SAI2_TXC_PDM_BIT_STREAM1                                  0x01C0 0x0428 0x0538 0x6 0x9
+#define MX8MN_IOMUXC_SAI2_TXD0_SAI2_TX_DATA0                                   0x01C4 0x042C 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_SAI2_TXD0_SAI5_TX_DATA3                                   0x01C4 0x042C 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_SAI2_TXD0_GPIO4_IO26                                      0x01C4 0x042C 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_SAI2_TXD0_CCMSRCGPCMIX_BOOT_MODE4                         0x01C4 0x042C 0x0540 0x6 0x8
+#define MX8MN_IOMUXC_SAI2_MCLK_SAI2_MCLK                                       0x01C8 0x0430 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_SAI2_MCLK_SAI5_MCLK                                       0x01C8 0x0430 0x0594 0x1 0x2
+#define MX8MN_IOMUXC_SAI2_MCLK_GPIO4_IO27                                      0x01C8 0x0430 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_SAI2_MCLK_SAI3_MCLK                                       0x01C8 0x0430 0x05C0 0x6 0x1
+#define MX8MN_IOMUXC_SAI3_RXFS_SAI3_RX_SYNC                                    0x01CC 0x0434 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_SAI3_RXFS_GPT1_CAPTURE1                                   0x01CC 0x0434 0x05F0 0x1 0x0
+#define MX8MN_IOMUXC_SAI3_RXFS_SAI5_RX_SYNC                                    0x01CC 0x0434 0x04E4 0x2 0x2
+#define MX8MN_IOMUXC_SAI3_RXFS_SAI3_RX_DATA1                                   0x01CC 0x0434 0x0000 0x3 0x0
+#define MX8MN_IOMUXC_SAI3_RXFS_SPDIF1_IN                                       0x01CC 0x0434 0x05CC 0x4 0x3
+#define MX8MN_IOMUXC_SAI3_RXFS_GPIO4_IO28                                      0x01CC 0x0434 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_SAI3_RXFS_PDM_BIT_STREAM0                                 0x01CC 0x0434 0x0534 0x6 0x5
+#define MX8MN_IOMUXC_SAI3_RXC_SAI3_RX_BCLK                                     0x01D0 0x0438 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_SAI3_RXC_GPT1_CLK                                         0x01D0 0x0438 0x05E8 0x1 0x0
+#define MX8MN_IOMUXC_SAI3_RXC_SAI5_RX_BCLK                                     0x01D0 0x0438 0x04D0 0x2 0x2
+#define MX8MN_IOMUXC_SAI3_RXC_SAI2_RX_DATA1                                    0x01D0 0x0438 0x05AC 0x3 0x2
+#define MX8MN_IOMUXC_SAI3_RXC_UART2_DCE_CTS_B                                  0x01D0 0x0438 0x0000 0x4 0x0
+#define MX8MN_IOMUXC_SAI3_RXC_UART2_DTE_RTS_B                                  0x01D0 0x0438 0x04F8 0x4 0x2
+#define MX8MN_IOMUXC_SAI3_RXC_GPIO4_IO29                                       0x01D0 0x0438 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_SAI3_RXC_PDM_CLK                                          0x01D0 0x0438 0x0000 0x6 0x0
+#define MX8MN_IOMUXC_SAI3_RXD_SAI3_RX_DATA0                                    0x01D4 0x043C 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_SAI3_RXD_GPT1_COMPARE1                                    0x01D4 0x043C 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_SAI3_RXD_SAI5_RX_DATA0                                    0x01D4 0x043C 0x04D4 0x2 0x2
+#define MX8MN_IOMUXC_SAI3_RXD_SAI3_TX_DATA1                                    0x01D4 0x043C 0x0000 0x3 0x0
+#define MX8MN_IOMUXC_SAI3_RXD_UART2_DCE_RTS_B                                  0x01D4 0x043C 0x04F8 0x4 0x3
+#define MX8MN_IOMUXC_SAI3_RXD_UART2_DTE_CTS_B                                  0x01D4 0x043C 0x0000 0x4 0x0
+#define MX8MN_IOMUXC_SAI3_RXD_GPIO4_IO30                                       0x01D4 0x043C 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_SAI3_RXD_PDM_BIT_STREAM1                                  0x01D4 0x043C 0x0538 0x6 0x10
+#define MX8MN_IOMUXC_SAI3_TXFS_SAI3_TX_SYNC                                    0x01D8 0x0440 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_SAI3_TXFS_GPT1_CAPTURE2                                   0x01D8 0x0440 0x05EC 0x1 0x0
+#define MX8MN_IOMUXC_SAI3_TXFS_SAI5_RX_DATA1                                   0x01D8 0x0440 0x04D8 0x2 0x1
+#define MX8MN_IOMUXC_SAI3_TXFS_SAI3_TX_DATA1                                   0x01D8 0x0440 0x0000 0x3 0x0
+#define MX8MN_IOMUXC_SAI3_TXFS_UART2_DCE_RX                                    0x01D8 0x0440 0x04FC 0x4 0x2
+#define MX8MN_IOMUXC_SAI3_TXFS_UART2_DTE_TX                                    0x01D8 0x0440 0x0000 0x4 0x0
+#define MX8MN_IOMUXC_SAI3_TXFS_GPIO4_IO31                                      0x01D8 0x0440 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_SAI3_TXFS_PDM_BIT_STREAM3                                 0x01D8 0x0440 0x0540 0x6 0x9
+#define MX8MN_IOMUXC_SAI3_TXC_SAI3_TX_BCLK                                     0x01DC 0x0444 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_SAI3_TXC_GPT1_COMPARE2                                    0x01DC 0x0444 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_SAI3_TXC_SAI5_RX_DATA2                                    0x01DC 0x0444 0x04DC 0x2 0x1
+#define MX8MN_IOMUXC_SAI3_TXC_SAI2_TX_DATA1                                    0x01DC 0x0444 0x0000 0x3 0x0
+#define MX8MN_IOMUXC_SAI3_TXC_UART2_DCE_TX                                     0x01DC 0x0444 0x0000 0x4 0x0
+#define MX8MN_IOMUXC_SAI3_TXC_UART2_DTE_RX                                     0x01DC 0x0444 0x04FC 0x4 0x3
+#define MX8MN_IOMUXC_SAI3_TXC_GPIO5_IO0                                        0x01DC 0x0444 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_SAI3_TXC_PDM_BIT_STREAM2                                  0x01DC 0x0444 0x053C 0x6 0x9
+#define MX8MN_IOMUXC_SAI3_TXD_SAI3_TX_DATA0                                    0x01E0 0x0448 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_SAI3_TXD_GPT1_COMPARE3                                    0x01E0 0x0448 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_SAI3_TXD_SAI5_RX_DATA3                                    0x01E0 0x0448 0x04E0 0x2 0x1
+#define MX8MN_IOMUXC_SAI3_TXD_SPDIF1_EXT_CLK                                   0x01E0 0x0448 0x0568 0x4 0x2
+#define MX8MN_IOMUXC_SAI3_TXD_GPIO5_IO1                                        0x01E0 0x0448 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_SAI3_TXD_CCMSRCGPCMIX_BOOT_MODE5                          0x01E0 0x0448 0x0000 0x6 0x0
+#define MX8MN_IOMUXC_SAI3_MCLK_SAI3_MCLK                                       0x01E4 0x044C 0x05C0 0x0 0x0
+#define MX8MN_IOMUXC_SAI3_MCLK_PWM4_OUT                                        0x01E4 0x044C 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_SAI3_MCLK_SAI5_MCLK                                       0x01E4 0x044C 0x0594 0x2 0x3
+#define MX8MN_IOMUXC_SAI3_MCLK_SPDIF1_OUT                                      0x01E4 0x044C 0x0000 0x4 0x0
+#define MX8MN_IOMUXC_SAI3_MCLK_GPIO5_IO2                                       0x01E4 0x044C 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_SAI3_MCLK_SPDIF1_IN                                       0x01E4 0x044C 0x05CC 0x6 0x4
+#define MX8MN_IOMUXC_SPDIF_TX_SPDIF1_OUT                                       0x01E8 0x0450 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_SPDIF_TX_PWM3_OUT                                         0x01E8 0x0450 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_SPDIF_TX_GPIO5_IO3                                        0x01E8 0x0450 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_SPDIF_RX_SPDIF1_IN                                        0x01EC 0x0454 0x05CC 0x0 0x0
+#define MX8MN_IOMUXC_SPDIF_RX_PWM2_OUT                                         0x01EC 0x0454 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_SPDIF_RX_GPIO5_IO4                                        0x01EC 0x0454 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_SPDIF_EXT_CLK_SPDIF1_EXT_CLK                              0x01F0 0x0458 0x0568 0x0 0x0
+#define MX8MN_IOMUXC_SPDIF_EXT_CLK_PWM1_OUT                                    0x01F0 0x0458 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_SPDIF_EXT_CLK_GPIO5_IO5                                   0x01F0 0x0458 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_ECSPI1_SCLK_ECSPI1_SCLK                                   0x01F4 0x045C 0x05D8 0x0 0x0
+#define MX8MN_IOMUXC_ECSPI1_SCLK_UART3_DCE_RX                                  0x01F4 0x045C 0x0504 0x1 0x0
+#define MX8MN_IOMUXC_ECSPI1_SCLK_UART3_DTE_TX                                  0x01F4 0x045C 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_ECSPI1_SCLK_I2C1_SCL                                      0x01F4 0x045C 0x055C 0x2 0x2
+#define MX8MN_IOMUXC_ECSPI1_SCLK_SAI5_RX_SYNC                                  0x01F4 0x045C 0x04DC 0x3 0x2
+#define MX8MN_IOMUXC_ECSPI1_SCLK_GPIO5_IO6                                     0x01F4 0x045C 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_ECSPI1_MOSI_ECSPI1_MOSI                                   0x01F8 0x0460 0x05A8 0x0 0x0
+#define MX8MN_IOMUXC_ECSPI1_MOSI_UART3_DCE_TX                                  0x01F8 0x0460 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_ECSPI1_MOSI_UART3_DTE_RX                                  0x01F8 0x0460 0x0504 0x1 0x1
+#define MX8MN_IOMUXC_ECSPI1_MOSI_I2C1_SDA                                      0x01F8 0x0460 0x056C 0x2 0x2
+#define MX8MN_IOMUXC_ECSPI1_MOSI_SAI5_RX_BCLK                                  0x01F8 0x0460 0x04D0 0x3 0x3
+#define MX8MN_IOMUXC_ECSPI1_MOSI_GPIO5_IO7                                     0x01F8 0x0460 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_ECSPI1_MISO_ECSPI1_MISO                                   0x01FC 0x0464 0x05C4 0x0 0x0
+#define MX8MN_IOMUXC_ECSPI1_MISO_UART3_DCE_CTS_B                               0x01FC 0x0464 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_ECSPI1_MISO_UART3_DTE_RTS_B                               0x01FC 0x0464 0x0500 0x1 0x0
+#define MX8MN_IOMUXC_ECSPI1_MISO_I2C2_SCL                                      0x01FC 0x0464 0x05D0 0x2 0x2
+#define MX8MN_IOMUXC_ECSPI1_MISO_SAI5_RX_DATA0                                 0x01FC 0x0464 0x04D4 0x3 0x3
+#define MX8MN_IOMUXC_ECSPI1_MISO_GPIO5_IO8                                     0x01FC 0x0464 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_ECSPI1_SS0_ECSPI1_SS0                                     0x0200 0x0468 0x0564 0x0 0x0
+#define MX8MN_IOMUXC_ECSPI1_SS0_UART3_DCE_RTS_B                                0x0200 0x0468 0x0500 0x1 0x1
+#define MX8MN_IOMUXC_ECSPI1_SS0_UART3_DTE_CTS_B                                0x0200 0x0468 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_ECSPI1_SS0_I2C2_SDA                                       0x0200 0x0468 0x0560 0x2 0x2
+#define MX8MN_IOMUXC_ECSPI1_SS0_SAI5_RX_DATA1                                  0x0200 0x0468 0x04D8 0x3 0x2
+#define MX8MN_IOMUXC_ECSPI1_SS0_SAI5_TX_SYNC                                   0x0200 0x0468 0x04EC 0x4 0x3
+#define MX8MN_IOMUXC_ECSPI1_SS0_GPIO5_IO9                                      0x0200 0x0468 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_ECSPI2_SCLK_ECSPI2_SCLK                                   0x0204 0x046C 0x0580 0x0 0x0
+#define MX8MN_IOMUXC_ECSPI2_SCLK_UART4_DCE_RX                                  0x0204 0x046C 0x050C 0x1 0x0
+#define MX8MN_IOMUXC_ECSPI2_SCLK_UART4_DTE_TX                                  0x0204 0x046C 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_ECSPI2_SCLK_I2C3_SCL                                      0x0204 0x046C 0x0588 0x2 0x4
+#define MX8MN_IOMUXC_ECSPI2_SCLK_SAI5_RX_DATA2                                 0x0204 0x046C 0x0000 0x3 0x0
+#define MX8MN_IOMUXC_ECSPI2_SCLK_SAI5_TX_BCLK                                  0x0204 0x046C 0x04E8 0x4 0x3
+#define MX8MN_IOMUXC_ECSPI2_SCLK_GPIO5_IO10                                    0x0204 0x046C 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_ECSPI2_MOSI_ECSPI2_MOSI                                   0x0208 0x0470 0x0590 0x0 0x0
+#define MX8MN_IOMUXC_ECSPI2_MOSI_UART4_DCE_TX                                  0x0208 0x0470 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_ECSPI2_MOSI_UART4_DTE_RX                                  0x0208 0x0470 0x050C 0x1 0x1
+#define MX8MN_IOMUXC_ECSPI2_MOSI_I2C3_SDA                                      0x0208 0x0470 0x05BC 0x2 0x4
+#define MX8MN_IOMUXC_ECSPI2_MOSI_SAI5_RX_DATA3                                 0x0208 0x0470 0x04E0 0x3 0x2
+#define MX8MN_IOMUXC_ECSPI2_MOSI_SAI5_TX_DATA0                                 0x0208 0x0470 0x0000 0x4 0x0
+#define MX8MN_IOMUXC_ECSPI2_MOSI_GPIO5_IO11                                    0x0208 0x0470 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_ECSPI2_MISO_ECSPI2_MISO                                   0x020C 0x0474 0x0578 0x0 0x0
+#define MX8MN_IOMUXC_ECSPI2_MISO_UART4_DCE_CTS_B                               0x020C 0x0474 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_ECSPI2_MISO_UART4_DTE_RTS_B                               0x020C 0x0474 0x0508 0x1 0x0
+#define MX8MN_IOMUXC_ECSPI2_MISO_I2C4_SCL                                      0x020C 0x0474 0x05D4 0x2 0x3
+#define MX8MN_IOMUXC_ECSPI2_MISO_SAI5_MCLK                                     0x020C 0x0474 0x0594 0x3 0x4
+#define MX8MN_IOMUXC_ECSPI2_MISO_GPIO5_IO12                                    0x020C 0x0474 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_ECSPI2_SS0_ECSPI2_SS0                                     0x0210 0x0478 0x0570 0x0 0x0
+#define MX8MN_IOMUXC_ECSPI2_SS0_UART4_DCE_RTS_B                                0x0210 0x0478 0x0508 0x1 0x1
+#define MX8MN_IOMUXC_ECSPI2_SS0_UART4_DTE_CTS_B                                0x0210 0x0478 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_ECSPI2_SS0_I2C4_SDA                                       0x0210 0x0478 0x058C 0x2 0x5
+#define MX8MN_IOMUXC_ECSPI2_SS0_GPIO5_IO13                                     0x0210 0x0478 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_I2C1_SCL_I2C1_SCL                                         0x0214 0x047C 0x055C 0x0 0x0
+#define MX8MN_IOMUXC_I2C1_SCL_ENET1_MDC                                        0x0214 0x047C 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_I2C1_SCL_ECSPI1_SCLK                                      0x0214 0x047C 0x05D8 0x3 0x1
+#define MX8MN_IOMUXC_I2C1_SCL_GPIO5_IO14                                       0x0214 0x047C 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_I2C1_SDA_I2C1_SDA                                         0x0218 0x0480 0x056C 0x0 0x0
+#define MX8MN_IOMUXC_I2C1_SDA_ENET1_MDIO                                       0x0218 0x0480 0x04C0 0x1 0x2
+#define MX8MN_IOMUXC_I2C1_SDA_ECSPI1_MOSI                                      0x0218 0x0480 0x05A8 0x3 0x1
+#define MX8MN_IOMUXC_I2C1_SDA_GPIO5_IO15                                       0x0218 0x0480 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_I2C2_SCL_I2C2_SCL                                         0x021C 0x0484 0x05D0 0x0 0x0
+#define MX8MN_IOMUXC_I2C2_SCL_ENET1_1588_EVENT1_IN                             0x021C 0x0484 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_I2C2_SCL_USDHC3_CD_B                                      0x021C 0x0484 0x0598 0x2 0x1
+#define MX8MN_IOMUXC_I2C2_SCL_ECSPI1_MISO                                      0x021C 0x0484 0x05C4 0x3 0x1
+#define MX8MN_IOMUXC_I2C2_SCL_GPIO5_IO16                                       0x021C 0x0484 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_I2C2_SDA_I2C2_SDA                                         0x0220 0x0488 0x0560 0x0 0x0
+#define MX8MN_IOMUXC_I2C2_SDA_ENET1_1588_EVENT1_OUT                            0x0220 0x0488 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_I2C2_SDA_USDHC3_WP                                        0x0220 0x0488 0x05B8 0x2 0x1
+#define MX8MN_IOMUXC_I2C2_SDA_ECSPI1_SS0                                       0x0220 0x0488 0x0564 0x3 0x1
+#define MX8MN_IOMUXC_I2C2_SDA_GPIO5_IO17                                       0x0220 0x0488 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_I2C3_SCL_I2C3_SCL                                         0x0224 0x048C 0x0588 0x0 0x0
+#define MX8MN_IOMUXC_I2C3_SCL_PWM4_OUT                                         0x0224 0x048C 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_I2C3_SCL_GPT2_CLK                                         0x0224 0x048C 0x0000 0x2 0x0
+#define MX8MN_IOMUXC_I2C3_SCL_ECSPI2_SCLK                                      0x0224 0x048C 0x0580 0x3 0x2
+#define MX8MN_IOMUXC_I2C3_SCL_GPIO5_IO18                                       0x0224 0x048C 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_I2C3_SDA_I2C3_SDA                                         0x0228 0x0490 0x05BC 0x0 0x0
+#define MX8MN_IOMUXC_I2C3_SDA_PWM3_OUT                                         0x0228 0x0490 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_I2C3_SDA_GPT3_CLK                                         0x0228 0x0490 0x0000 0x2 0x0
+#define MX8MN_IOMUXC_I2C3_SDA_ECSPI2_MOSI                                      0x0228 0x0490 0x0590 0x3 0x2
+#define MX8MN_IOMUXC_I2C3_SDA_GPIO5_IO19                                       0x0228 0x0490 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_I2C4_SCL_I2C4_SCL                                         0x022C 0x0494 0x05D4 0x0 0x0
+#define MX8MN_IOMUXC_I2C4_SCL_PWM2_OUT                                         0x022C 0x0494 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_I2C4_SCL_ECSPI2_MISO                                      0x022C 0x0494 0x0578 0x3 0x2
+#define MX8MN_IOMUXC_I2C4_SCL_GPIO5_IO20                                       0x022C 0x0494 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_I2C4_SDA_I2C4_SDA                                         0x0230 0x0498 0x058C 0x0 0x0
+#define MX8MN_IOMUXC_I2C4_SDA_PWM1_OUT                                         0x0230 0x0498 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_I2C4_SDA_ECSPI2_SS0                                       0x0230 0x0498 0x0570 0x3 0x1
+#define MX8MN_IOMUXC_I2C4_SDA_GPIO5_IO21                                       0x0230 0x0498 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_UART1_RXD_UART1_DCE_RX                                    0x0234 0x049C 0x04F4 0x0 0x0
+#define MX8MN_IOMUXC_UART1_RXD_UART1_DTE_TX                                    0x0234 0x049C 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_UART1_RXD_ECSPI3_SCLK                                     0x0234 0x049C 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_UART1_RXD_GPIO5_IO22                                      0x0234 0x049C 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_UART1_TXD_UART1_DCE_TX                                    0x0238 0x04A0 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_UART1_TXD_UART1_DTE_RX                                    0x0238 0x04A0 0x04F4 0x0 0x1
+#define MX8MN_IOMUXC_UART1_TXD_ECSPI3_MOSI                                     0x0238 0x04A0 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_UART1_TXD_GPIO5_IO23                                      0x0238 0x04A0 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_UART2_RXD_UART2_DCE_RX                                    0x023C 0x04A4 0x04FC 0x0 0x0
+#define MX8MN_IOMUXC_UART2_RXD_UART2_DTE_TX                                    0x023C 0x04A4 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_UART2_RXD_ECSPI3_MISO                                     0x023C 0x04A4 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_UART2_RXD_GPT1_COMPARE3                                   0x023C 0x04A4 0x0000 0x3 0x0
+#define MX8MN_IOMUXC_UART2_RXD_GPIO5_IO24                                      0x023C 0x04A4 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_UART2_TXD_UART2_DCE_TX                                    0x0240 0x04A8 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_UART2_TXD_UART2_DTE_RX                                    0x0240 0x04A8 0x04FC 0x0 0x1
+#define MX8MN_IOMUXC_UART2_TXD_ECSPI3_SS0                                      0x0240 0x04A8 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_UART2_TXD_GPT1_COMPARE2                                   0x0240 0x04A8 0x0000 0x3 0x0
+#define MX8MN_IOMUXC_UART2_TXD_GPIO5_IO25                                      0x0240 0x04A8 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_UART3_RXD_UART3_DCE_RX                                    0x0244 0x04AC 0x0504 0x0 0x2
+#define MX8MN_IOMUXC_UART3_RXD_UART3_DTE_TX                                    0x0244 0x04AC 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_UART3_RXD_UART1_DCE_CTS_B                                 0x0244 0x04AC 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_UART3_RXD_UART1_DTE_RTS_B                                 0x0244 0x04AC 0x04F0 0x1 0x0
+#define MX8MN_IOMUXC_UART3_RXD_USDHC3_RESET_B                                  0x0244 0x04AC 0x0000 0x2 0x0
+#define MX8MN_IOMUXC_UART3_RXD_GPT1_CAPTURE2                                   0x0244 0x04AC 0x05EC 0x3 0x1
+#define MX8MN_IOMUXC_UART3_RXD_GPIO5_IO26                                      0x0244 0x04AC 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_UART3_TXD_UART3_DCE_TX                                    0x0248 0x04B0 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_UART3_TXD_UART3_DTE_RX                                    0x0248 0x04B0 0x0504 0x0 0x3
+#define MX8MN_IOMUXC_UART3_TXD_UART1_DCE_RTS_B                                 0x0248 0x04B0 0x04F0 0x1 0x1
+#define MX8MN_IOMUXC_UART3_TXD_UART1_DTE_CTS_B                                 0x0248 0x04B0 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_UART3_TXD_USDHC3_VSELECT                                  0x0248 0x04B0 0x0000 0x2 0x0
+#define MX8MN_IOMUXC_UART3_TXD_GPT1_CLK                                        0x0248 0x04B0 0x05E8 0x3 0x1
+#define MX8MN_IOMUXC_UART3_TXD_GPIO5_IO27                                      0x0248 0x04B0 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_UART4_RXD_UART4_DCE_RX                                    0x024C 0x04B4 0x050C 0x0 0x2
+#define MX8MN_IOMUXC_UART4_RXD_UART4_DTE_TX                                    0x024C 0x04B4 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_UART4_RXD_UART2_DCE_CTS_B                                 0x024C 0x04B4 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_UART4_RXD_UART2_DTE_RTS_B                                 0x024C 0x04B4 0x04F8 0x1 0x0
+#define MX8MN_IOMUXC_UART4_RXD_GPT1_COMPARE1                                   0x024C 0x04B4 0x0000 0x3 0x0
+#define MX8MN_IOMUXC_UART4_RXD_GPIO5_IO28                                      0x024C 0x04B4 0x0000 0x5 0x0
+#define MX8MN_IOMUXC_UART4_TXD_UART4_DCE_TX                                    0x0250 0x04B8 0x0000 0x0 0x0
+#define MX8MN_IOMUXC_UART4_TXD_UART4_DTE_RX                                    0x0250 0x04B8 0x050C 0x0 0x3
+#define MX8MN_IOMUXC_UART4_TXD_UART2_DCE_RTS_B                                 0x0250 0x04B8 0x04F8 0x1 0x1
+#define MX8MN_IOMUXC_UART4_TXD_UART2_DTE_CTS_B                                 0x0250 0x04B8 0x0000 0x1 0x0
+#define MX8MN_IOMUXC_UART4_TXD_GPT1_CAPTURE1                                   0x0250 0x04B8 0x05F0 0x3 0x1
+#define MX8MN_IOMUXC_UART4_TXD_GPIO5_IO29                                      0x0250 0x04B8 0x0000 0x5 0x0
+
+#endif /* __DTS_IMX8MN_PINFUNC_H */
diff --git a/arch/arm/dts/imx8mn.dtsi b/arch/arm/dts/imx8mn.dtsi
new file mode 100644
index 0000000..f5eff35
--- /dev/null
+++ b/arch/arm/dts/imx8mn.dtsi
@@ -0,0 +1,712 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2019 NXP
+ */
+
+#include <dt-bindings/clock/imx8mn-clock.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "imx8mn-pinfunc.h"
+
+/ {
+	compatible = "fsl,imx8mn";
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	aliases {
+		ethernet0 = &fec1;
+		gpio0 = &gpio1;
+		gpio1 = &gpio2;
+		gpio2 = &gpio3;
+		gpio3 = &gpio4;
+		gpio4 = &gpio5;
+		i2c0 = &i2c1;
+		i2c1 = &i2c2;
+		i2c2 = &i2c3;
+		i2c3 = &i2c4;
+		mmc0 = &usdhc1;
+		mmc1 = &usdhc2;
+		mmc2 = &usdhc3;
+		serial0 = &uart1;
+		serial1 = &uart2;
+		serial2 = &uart3;
+		serial3 = &uart4;
+		spi0 = &ecspi1;
+		spi1 = &ecspi2;
+		spi2 = &ecspi3;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		A53_0: cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			reg = <0x0>;
+			clock-latency = <61036>;
+			clocks = <&clk IMX8MN_CLK_ARM>;
+			enable-method = "psci";
+			next-level-cache = <&A53_L2>;
+		};
+
+		A53_1: cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			reg = <0x1>;
+			clock-latency = <61036>;
+			clocks = <&clk IMX8MN_CLK_ARM>;
+			enable-method = "psci";
+			next-level-cache = <&A53_L2>;
+		};
+
+		A53_2: cpu@2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			reg = <0x2>;
+			clock-latency = <61036>;
+			clocks = <&clk IMX8MN_CLK_ARM>;
+			enable-method = "psci";
+			next-level-cache = <&A53_L2>;
+		};
+
+		A53_3: cpu@3 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			reg = <0x3>;
+			clock-latency = <61036>;
+			clocks = <&clk IMX8MN_CLK_ARM>;
+			enable-method = "psci";
+			next-level-cache = <&A53_L2>;
+		};
+
+		A53_L2: l2-cache0 {
+			compatible = "cache";
+		};
+	};
+
+	memory@40000000 {
+		device_type = "memory";
+		reg = <0x0 0x40000000 0 0x80000000>;
+	};
+
+	osc_32k: clock-osc-32k {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <32768>;
+		clock-output-names = "osc_32k";
+	};
+
+	osc_24m: clock-osc-24m {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <24000000>;
+		clock-output-names = "osc_24m";
+	};
+
+	clk_ext1: clock-ext1 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <133000000>;
+		clock-output-names = "clk_ext1";
+	};
+
+	clk_ext2: clock-ext2 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <133000000>;
+		clock-output-names = "clk_ext2";
+	};
+
+	clk_ext3: clock-ext3 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <133000000>;
+		clock-output-names = "clk_ext3";
+	};
+
+	clk_ext4: clock-ext4 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency= <133000000>;
+		clock-output-names = "clk_ext4";
+	};
+
+	psci {
+		compatible = "arm,psci-1.0";
+		method = "smc";
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>;
+		clock-frequency = <8000000>;
+		arm,no-tick-in-suspend;
+	};
+
+	soc@0 {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0x0 0x0 0x0 0x3e000000>;
+
+		aips1: bus@30000000 {
+			compatible = "fsl,aips-bus", "simple-bus";
+			reg = <0x30000000 0x400000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
+
+			gpio1: gpio@30200000 {
+				compatible = "fsl,imx8mn-gpio", "fsl,imx35-gpio";
+				reg = <0x30200000 0x10000>;
+				interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>,
+					     <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk IMX8MN_CLK_GPIO1_ROOT>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+
+			gpio2: gpio@30210000 {
+				compatible = "fsl,imx8mn-gpio", "fsl,imx35-gpio";
+				reg = <0x30210000 0x10000>;
+				interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>,
+					     <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk IMX8MN_CLK_GPIO2_ROOT>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+
+			gpio3: gpio@30220000 {
+				compatible = "fsl,imx8mn-gpio", "fsl,imx35-gpio";
+				reg = <0x30220000 0x10000>;
+				interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
+					     <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk IMX8MN_CLK_GPIO3_ROOT>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+
+			gpio4: gpio@30230000 {
+				compatible = "fsl,imx8mn-gpio", "fsl,imx35-gpio";
+				reg = <0x30230000 0x10000>;
+				interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>,
+					     <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk IMX8MN_CLK_GPIO4_ROOT>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+
+			gpio5: gpio@30240000 {
+				compatible = "fsl,imx8mn-gpio", "fsl,imx35-gpio";
+				reg = <0x30240000 0x10000>;
+				interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
+					     <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk IMX8MN_CLK_GPIO5_ROOT>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+
+			wdog1: watchdog@30280000 {
+				compatible = "fsl,imx8mn-wdt", "fsl,imx21-wdt";
+				reg = <0x30280000 0x10000>;
+				interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk IMX8MN_CLK_WDOG1_ROOT>;
+				status = "disabled";
+			};
+
+			wdog2: watchdog@30290000 {
+				compatible = "fsl,imx8mn-wdt", "fsl,imx21-wdt";
+				reg = <0x30290000 0x10000>;
+				interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk IMX8MN_CLK_WDOG2_ROOT>;
+				status = "disabled";
+			};
+
+			wdog3: watchdog@302a0000 {
+				compatible = "fsl,imx8mn-wdt", "fsl,imx21-wdt";
+				reg = <0x302a0000 0x10000>;
+				interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk IMX8MN_CLK_WDOG3_ROOT>;
+				status = "disabled";
+			};
+
+			sdma3: dma-controller@302b0000 {
+				compatible = "fsl,imx8mn-sdma", "fsl,imx7d-sdma";
+				reg = <0x302b0000 0x10000>;
+				interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk IMX8MN_CLK_SDMA3_ROOT>,
+				 <&clk IMX8MN_CLK_SDMA3_ROOT>;
+				clock-names = "ipg", "ahb";
+				#dma-cells = <3>;
+				fsl,sdma-ram-script-name = "imx/sdma/sdma-imx7d.bin";
+			};
+
+			sdma2: dma-controller@302c0000 {
+				compatible = "fsl,imx8mn-sdma", "fsl,imx7d-sdma";
+				reg = <0x302c0000 0x10000>;
+				interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk IMX8MN_CLK_SDMA2_ROOT>,
+					 <&clk IMX8MN_CLK_SDMA2_ROOT>;
+				clock-names = "ipg", "ahb";
+				#dma-cells = <3>;
+				fsl,sdma-ram-script-name = "imx/sdma/sdma-imx7d.bin";
+			};
+
+			iomuxc: pinctrl@30330000 {
+				compatible = "fsl,imx8mn-iomuxc";
+				reg = <0x30330000 0x10000>;
+			};
+
+			gpr: iomuxc-gpr@30340000 {
+				compatible = "fsl,imx8mn-iomuxc-gpr", "syscon";
+				reg = <0x30340000 0x10000>;
+			};
+
+			ocotp: ocotp-ctrl@30350000 {
+				compatible = "fsl,imx8mn-ocotp", "fsl,imx7d-ocotp", "syscon";
+				reg = <0x30350000 0x10000>;
+				clocks = <&clk IMX8MN_CLK_OCOTP_ROOT>;
+			};
+
+			anatop: anatop@30360000 {
+				compatible = "fsl,imx8mn-anatop", "fsl,imx8mm-anatop",
+					     "syscon", "simple-bus";
+				reg = <0x30360000 0x10000>;
+			};
+
+			snvs: snvs@30370000 {
+				compatible = "fsl,sec-v4.0-mon","syscon", "simple-mfd";
+				reg = <0x30370000 0x10000>;
+
+				snvs_rtc: snvs-rtc-lp {
+					compatible = "fsl,sec-v4.0-mon-rtc-lp";
+					regmap = <&snvs>;
+					offset = <0x34>;
+					interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
+						     <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+					clock-names = "snvs-rtc";
+				};
+
+				snvs_pwrkey: snvs-powerkey {
+					compatible = "fsl,sec-v4.0-pwrkey";
+					regmap = <&snvs>;
+					interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+					linux,keycode = <KEY_POWER>;
+					wakeup-source;
+					status = "disabled";
+				};
+			};
+
+			clk: clock-controller@30380000 {
+				compatible = "fsl,imx8mn-ccm";
+				reg = <0x30380000 0x10000>;
+				#clock-cells = <1>;
+				clocks = <&osc_32k>, <&osc_24m>, <&clk_ext1>, <&clk_ext2>,
+					 <&clk_ext3>, <&clk_ext4>;
+				clock-names = "osc_32k", "osc_24m", "clk_ext1", "clk_ext2",
+					      "clk_ext3", "clk_ext4";
+			};
+
+			src: reset-controller@30390000 {
+				compatible = "fsl,imx8mn-src", "syscon";
+				reg = <0x30390000 0x10000>;
+				interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
+				#reset-cells = <1>;
+			};
+		};
+
+		aips2: bus@30400000 {
+			compatible = "fsl,aips-bus", "simple-bus";
+			reg = <0x30400000 0x400000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
+
+			pwm1: pwm@30660000 {
+				compatible = "fsl,imx8mn-pwm", "fsl,imx27-pwm";
+				reg = <0x30660000 0x10000>;
+				interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk IMX8MN_CLK_PWM1_ROOT>,
+					<&clk IMX8MN_CLK_PWM1_ROOT>;
+				clock-names = "ipg", "per";
+				#pwm-cells = <2>;
+				status = "disabled";
+			};
+
+			pwm2: pwm@30670000 {
+				compatible = "fsl,imx8mn-pwm", "fsl,imx27-pwm";
+				reg = <0x30670000 0x10000>;
+				interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk IMX8MN_CLK_PWM2_ROOT>,
+					 <&clk IMX8MN_CLK_PWM2_ROOT>;
+				clock-names = "ipg", "per";
+				#pwm-cells = <2>;
+				status = "disabled";
+			};
+
+			pwm3: pwm@30680000 {
+				compatible = "fsl,imx8mn-pwm", "fsl,imx27-pwm";
+				reg = <0x30680000 0x10000>;
+				interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk IMX8MN_CLK_PWM3_ROOT>,
+					 <&clk IMX8MN_CLK_PWM3_ROOT>;
+				clock-names = "ipg", "per";
+				#pwm-cells = <2>;
+				status = "disabled";
+			};
+
+			pwm4: pwm@30690000 {
+				compatible = "fsl,imx8mn-pwm", "fsl,imx27-pwm";
+				reg = <0x30690000 0x10000>;
+				interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk IMX8MN_CLK_PWM4_ROOT>,
+					 <&clk IMX8MN_CLK_PWM4_ROOT>;
+				clock-names = "ipg", "per";
+				#pwm-cells = <2>;
+				status = "disabled";
+			};
+		};
+
+		aips3: bus@30800000 {
+			compatible = "fsl,aips-bus", "simple-bus";
+			reg = <0x30800000 0x400000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
+
+			ecspi1: spi@30820000 {
+				compatible = "fsl,imx8mn-ecspi", "fsl,imx51-ecspi";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <0x30820000 0x10000>;
+				interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk IMX8MN_CLK_ECSPI1_ROOT>,
+					 <&clk IMX8MN_CLK_ECSPI1_ROOT>;
+				clock-names = "ipg", "per";
+				dmas = <&sdma1 0 7 1>, <&sdma1 1 7 2>;
+				dma-names = "rx", "tx";
+				status = "disabled";
+			};
+
+			ecspi2: spi@30830000 {
+				compatible = "fsl,imx8mn-ecspi", "fsl,imx51-ecspi";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <0x30830000 0x10000>;
+				interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk IMX8MN_CLK_ECSPI2_ROOT>,
+					 <&clk IMX8MN_CLK_ECSPI2_ROOT>;
+				clock-names = "ipg", "per";
+				dmas = <&sdma1 2 7 1>, <&sdma1 3 7 2>;
+				dma-names = "rx", "tx";
+				status = "disabled";
+			};
+
+			ecspi3: spi@30840000 {
+				compatible = "fsl,imx8mn-ecspi", "fsl,imx51-ecspi";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <0x30840000 0x10000>;
+				interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk IMX8MN_CLK_ECSPI3_ROOT>,
+					 <&clk IMX8MN_CLK_ECSPI3_ROOT>;
+				clock-names = "ipg", "per";
+				dmas = <&sdma1 4 7 1>, <&sdma1 5 7 2>;
+				dma-names = "rx", "tx";
+				status = "disabled";
+			};
+
+			uart1: serial@30860000 {
+				compatible = "fsl,imx8mn-uart", "fsl,imx6q-uart";
+				reg = <0x30860000 0x10000>;
+				interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk IMX8MN_CLK_UART1_ROOT>,
+					 <&clk IMX8MN_CLK_UART1_ROOT>;
+				clock-names = "ipg", "per";
+				dmas = <&sdma1 22 4 0>, <&sdma1 23 4 0>;
+				dma-names = "rx", "tx";
+				status = "disabled";
+			};
+
+			uart3: serial@30880000 {
+				compatible = "fsl,imx8mn-uart", "fsl,imx6q-uart";
+				reg = <0x30880000 0x10000>;
+				interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk IMX8MN_CLK_UART3_ROOT>,
+					 <&clk IMX8MN_CLK_UART3_ROOT>;
+				clock-names = "ipg", "per";
+				dmas = <&sdma1 26 4 0>, <&sdma1 27 4 0>;
+				dma-names = "rx", "tx";
+				status = "disabled";
+			};
+
+			uart2: serial@30890000 {
+				compatible = "fsl,imx8mn-uart", "fsl,imx6q-uart";
+				reg = <0x30890000 0x10000>;
+				interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk IMX8MN_CLK_UART2_ROOT>,
+					 <&clk IMX8MN_CLK_UART2_ROOT>;
+				clock-names = "ipg", "per";
+				status = "disabled";
+			};
+
+			i2c1: i2c@30a20000 {
+				compatible = "fsl,imx8mn-i2c", "fsl,imx21-i2c";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <0x30a20000 0x10000>;
+				interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk IMX8MN_CLK_I2C1_ROOT>;
+				status = "disabled";
+			};
+
+			i2c2: i2c@30a30000 {
+				compatible = "fsl,imx8mn-i2c", "fsl,imx21-i2c";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <0x30a30000 0x10000>;
+				interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk IMX8MN_CLK_I2C2_ROOT>;
+				status = "disabled";
+			};
+
+			i2c3: i2c@30a40000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,imx8mn-i2c", "fsl,imx21-i2c";
+				reg = <0x30a40000 0x10000>;
+				interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk IMX8MN_CLK_I2C3_ROOT>;
+				status = "disabled";
+			};
+
+			i2c4: i2c@30a50000 {
+				compatible = "fsl,imx8mn-i2c", "fsl,imx21-i2c";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <0x30a50000 0x10000>;
+				interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk IMX8MN_CLK_I2C4_ROOT>;
+				status = "disabled";
+			};
+
+			uart4: serial@30a60000 {
+				compatible = "fsl,imx8mn-uart", "fsl,imx6q-uart";
+				reg = <0x30a60000 0x10000>;
+				interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk IMX8MN_CLK_UART4_ROOT>,
+					 <&clk IMX8MN_CLK_UART4_ROOT>;
+				clock-names = "ipg", "per";
+				dmas = <&sdma1 28 4 0>, <&sdma1 29 4 0>;
+				dma-names = "rx", "tx";
+				status = "disabled";
+			};
+
+			usdhc1: mmc@30b40000 {
+				compatible = "fsl,imx8mn-usdhc", "fsl,imx7d-usdhc";
+				reg = <0x30b40000 0x10000>;
+				interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk IMX8MN_CLK_DUMMY>,
+					 <&clk IMX8MN_CLK_NAND_USDHC_BUS>,
+					 <&clk IMX8MN_CLK_USDHC1_ROOT>;
+				clock-names = "ipg", "ahb", "per";
+				assigned-clocks = <&clk IMX8MN_CLK_USDHC1>;
+				assigned-clock-rates = <400000000>;
+				fsl,tuning-start-tap = <20>;
+				fsl,tuning-step= <2>;
+				bus-width = <4>;
+				status = "disabled";
+			};
+
+			usdhc2: mmc@30b50000 {
+				compatible = "fsl,imx8mn-usdhc", "fsl,imx7d-usdhc";
+				reg = <0x30b50000 0x10000>;
+				interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk IMX8MN_CLK_DUMMY>,
+					 <&clk IMX8MN_CLK_NAND_USDHC_BUS>,
+					 <&clk IMX8MN_CLK_USDHC2_ROOT>;
+				clock-names = "ipg", "ahb", "per";
+				fsl,tuning-start-tap = <20>;
+				fsl,tuning-step= <2>;
+				bus-width = <4>;
+				status = "disabled";
+			};
+
+			usdhc3: mmc@30b60000 {
+				compatible = "fsl,imx8mn-usdhc", "fsl,imx7d-usdhc";
+				reg = <0x30b60000 0x10000>;
+				interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk IMX8MN_CLK_DUMMY>,
+					 <&clk IMX8MN_CLK_NAND_USDHC_BUS>,
+					 <&clk IMX8MN_CLK_USDHC3_ROOT>;
+				clock-names = "ipg", "ahb", "per";
+				assigned-clocks = <&clk IMX8MN_CLK_USDHC3_ROOT>;
+				assigned-clock-rates = <400000000>;
+				fsl,tuning-start-tap = <20>;
+				fsl,tuning-step= <2>;
+				bus-width = <4>;
+				status = "disabled";
+			};
+
+			sdma1: dma-controller@30bd0000 {
+				compatible = "fsl,imx8mn-sdma", "fsl,imx7d-sdma";
+				reg = <0x30bd0000 0x10000>;
+				interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk IMX8MN_CLK_SDMA1_ROOT>,
+					 <&clk IMX8MN_CLK_SDMA1_ROOT>;
+				clock-names = "ipg", "ahb";
+				#dma-cells = <3>;
+				fsl,sdma-ram-script-name = "imx/sdma/sdma-imx7d.bin";
+			};
+
+			fec1: ethernet@30be0000 {
+				compatible = "fsl,imx8mn-fec", "fsl,imx6sx-fec";
+				reg = <0x30be0000 0x10000>;
+				interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
+					     <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>,
+					     <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk IMX8MN_CLK_ENET1_ROOT>,
+					 <&clk IMX8MN_CLK_ENET1_ROOT>,
+					 <&clk IMX8MN_CLK_ENET_TIMER>,
+					 <&clk IMX8MN_CLK_ENET_REF>,
+					 <&clk IMX8MN_CLK_ENET_PHY_REF>;
+				clock-names = "ipg", "ahb", "ptp",
+					      "enet_clk_ref", "enet_out";
+				assigned-clocks = <&clk IMX8MN_CLK_ENET_AXI>,
+						  <&clk IMX8MN_CLK_ENET_TIMER>,
+						  <&clk IMX8MN_CLK_ENET_REF>,
+						  <&clk IMX8MN_CLK_ENET_TIMER>;
+				assigned-clock-parents = <&clk IMX8MN_SYS_PLL1_266M>,
+							 <&clk IMX8MN_SYS_PLL2_100M>,
+							 <&clk IMX8MN_SYS_PLL2_125M>;
+				assigned-clock-rates = <0>, <0>, <125000000>, <100000000>;
+				fsl,num-tx-queues = <3>;
+				fsl,num-rx-queues = <3>;
+				status = "disabled";
+			};
+
+		};
+
+		aips4: bus@32c00000 {
+			compatible = "fsl,aips-bus", "simple-bus";
+			reg = <0x32c00000 0x400000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
+
+			usbotg1: usb@32e40000 {
+				compatible = "fsl,imx8mn-usb", "fsl,imx7d-usb";
+				reg = <0x32e40000 0x200>;
+				interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk IMX8MN_CLK_USB1_CTRL_ROOT>;
+				clock-names = "usb1_ctrl_root_clk";
+				assigned-clocks = <&clk IMX8MN_CLK_USB_BUS>,
+						  <&clk IMX8MN_CLK_USB_CORE_REF>;
+				assigned-clock-parents = <&clk IMX8MN_SYS_PLL2_500M>,
+							 <&clk IMX8MN_SYS_PLL1_100M>;
+				fsl,usbphy = <&usbphynop1>;
+				fsl,usbmisc = <&usbmisc1 0>;
+				status = "disabled";
+			};
+
+			usbmisc1: usbmisc@32e40200 {
+				compatible = "fsl,imx8mn-usbmisc", "fsl,imx7d-usbmisc";
+				#index-cells = <1>;
+				reg = <0x32e40200 0x200>;
+			};
+
+			usbotg2: usb@32e50000 {
+				compatible = "fsl,imx8mn-usb", "fsl,imx7d-usb";
+				reg = <0x32e50000 0x200>;
+				interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk IMX8MN_CLK_USB1_CTRL_ROOT>;
+				clock-names = "usb1_ctrl_root_clk";
+				assigned-clocks = <&clk IMX8MN_CLK_USB_BUS>,
+						  <&clk IMX8MN_CLK_USB_CORE_REF>;
+				assigned-clock-parents = <&clk IMX8MN_SYS_PLL2_500M>,
+							 <&clk IMX8MN_SYS_PLL1_100M>;
+				fsl,usbphy = <&usbphynop2>;
+				fsl,usbmisc = <&usbmisc2 0>;
+				status = "disabled";
+			};
+
+			usbmisc2: usbmisc@32e50200 {
+				compatible = "fsl,imx8mn-usbmisc", "fsl,imx7d-usbmisc";
+				#index-cells = <1>;
+				reg = <0x32e50200 0x200>;
+			};
+
+		};
+
+		dma_apbh: dma-controller@33000000 {
+			compatible = "fsl,imx7d-dma-apbh", "fsl,imx28-dma-apbh";
+			reg = <0x33000000 0x2000>;
+			interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "gpmi0", "gpmi1", "gpmi2", "gpmi3";
+			#dma-cells = <1>;
+			dma-channels = <4>;
+			clocks = <&clk IMX8MN_CLK_NAND_USDHC_BUS_RAWNAND_CLK>;
+		};
+
+		gpmi: nand-controller@33002000 {
+			compatible = "fsl,imx8mn-gpmi-nand", "fsl,imx7d-gpmi-nand";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			reg = <0x33002000 0x2000>, <0x33004000 0x4000>;
+			reg-names = "gpmi-nand", "bch";
+			interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "bch";
+			clocks = <&clk IMX8MN_CLK_NAND_ROOT>,
+				 <&clk IMX8MN_CLK_NAND_USDHC_BUS_RAWNAND_CLK>;
+			clock-names = "gpmi_io", "gpmi_bch_apb";
+			dmas = <&dma_apbh 0>;
+			dma-names = "rx-tx";
+			status = "disabled";
+		};
+
+		gic: interrupt-controller@38800000 {
+			compatible = "arm,gic-v3";
+			reg = <0x38800000 0x10000>,
+			      <0x38880000 0xc0000>;
+			#interrupt-cells = <3>;
+			interrupt-controller;
+			interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+		};
+	};
+
+	usbphynop1: usbphynop1 {
+		compatible = "usb-nop-xceiv";
+		clocks = <&clk IMX8MN_CLK_USB_PHY_REF>;
+		assigned-clocks = <&clk IMX8MN_CLK_USB_PHY_REF>;
+		assigned-clock-parents = <&clk IMX8MN_SYS_PLL1_100M>;
+		clock-names = "main_clk";
+	};
+
+	usbphynop2: usbphynop2 {
+		compatible = "usb-nop-xceiv";
+		clocks = <&clk IMX8MN_CLK_USB_PHY_REF>;
+		assigned-clocks = <&clk IMX8MN_CLK_USB_PHY_REF>;
+		assigned-clock-parents = <&clk IMX8MN_SYS_PLL1_100M>;
+		clock-names = "main_clk";
+	};
+};
diff --git a/arch/arm/dts/px30-evb-u-boot.dtsi b/arch/arm/dts/px30-evb-u-boot.dtsi
new file mode 100644
index 0000000..3de9c70
--- /dev/null
+++ b/arch/arm/dts/px30-evb-u-boot.dtsi
@@ -0,0 +1,81 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * (C) Copyright 2017 Rockchip Electronics Co., Ltd
+ */
+
+/ {
+	aliases {
+		mmc0 = &emmc;
+		mmc1 = &sdmmc;
+	};
+
+	chosen {
+		u-boot,spl-boot-order = &emmc, &sdmmc;
+	};
+};
+
+&dmc {
+	u-boot,dm-pre-reloc;
+};
+
+&uart2 {
+	clock-frequency = <24000000>;
+	u-boot,dm-pre-reloc;
+};
+
+&uart5 {
+	clock-frequency = <24000000>;
+	u-boot,dm-pre-reloc;
+};
+
+&sdmmc {
+	u-boot,dm-pre-reloc;
+
+	/* temporary till I find out why dma mode doesn't work */
+	fifo-mode;
+};
+
+&emmc {
+	u-boot,dm-pre-reloc;
+};
+
+&grf {
+	u-boot,dm-pre-reloc;
+};
+
+&pmugrf {
+	u-boot,dm-pre-reloc;
+};
+
+&xin24m {
+	u-boot,dm-pre-reloc;
+};
+
+&cru {
+	u-boot,dm-pre-reloc;
+};
+
+&pmucru {
+	u-boot,dm-pre-reloc;
+};
+
+&saradc {
+	u-boot,dm-pre-reloc;
+	status = "okay";
+};
+
+&gpio0 {
+	u-boot,dm-pre-reloc;
+};
+
+&gpio1 {
+	u-boot,dm-pre-reloc;
+};
+
+&gpio2 {
+	u-boot,dm-pre-reloc;
+};
+
+&gpio3 {
+	u-boot,dm-pre-reloc;
+};
diff --git a/arch/arm/dts/px30-evb.dts b/arch/arm/dts/px30-evb.dts
new file mode 100644
index 0000000..d886f17
--- /dev/null
+++ b/arch/arm/dts/px30-evb.dts
@@ -0,0 +1,530 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd
+ */
+
+/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include "px30.dtsi"
+#include "px30-evb-u-boot.dtsi"
+
+/ {
+	model = "Rockchip PX30 EVB";
+	compatible = "rockchip,px30-evb", "rockchip,px30";
+
+	chosen {
+		stdout-path = "serial2:115200n8";
+	};
+
+	adc-keys {
+		compatible = "adc-keys";
+		io-channels = <&saradc 2>;
+		io-channel-names = "buttons";
+		keyup-threshold-microvolt = <1800000>;
+		poll-interval = <100>;
+
+		esc-key {
+			label = "esc";
+			linux,code = <KEY_ESC>;
+			press-threshold-microvolt = <1310000>;
+		};
+
+		home-key {
+			label = "home";
+			linux,code = <KEY_HOME>;
+			press-threshold-microvolt = <624000>;
+		};
+
+		menu-key {
+			label = "menu";
+			linux,code = <KEY_MENU>;
+			press-threshold-microvolt = <987000>;
+		};
+
+		vol-down-key {
+			label = "volume down";
+			linux,code = <KEY_VOLUMEDOWN>;
+			press-threshold-microvolt = <300000>;
+		};
+
+		vol-up-key {
+			label = "volume up";
+			linux,code = <KEY_VOLUMEUP>;
+			press-threshold-microvolt = <17000>;
+		};
+	};
+
+	backlight: backlight {
+		compatible = "pwm-backlight";
+		pwms = <&pwm1 0 25000 0>;
+		power-supply = <&vcc3v3_lcd>;
+	};
+
+	emmc_pwrseq: emmc-pwrseq {
+		compatible = "mmc-pwrseq-emmc";
+		pinctrl-0 = <&emmc_reset>;
+		pinctrl-names = "default";
+		reset-gpios = <&gpio1 RK_PB3 GPIO_ACTIVE_HIGH>;
+	};
+
+	sdio_pwrseq: sdio-pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		pinctrl-names = "default";
+		pinctrl-0 = <&wifi_enable_h>;
+
+		/*
+		 * On the module itself this is one of these (depending
+		 * on the actual card populated):
+		 * - SDIO_RESET_L_WL_REG_ON
+		 * - PDN (power down when low)
+		 */
+		reset-gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_LOW>; /* GPIO3_A4 */
+	};
+
+	vcc5v0_sys: vccsys {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc5v0_sys";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+	};
+};
+
+&cpu0 {
+	cpu-supply = <&vdd_arm>;
+};
+
+&cpu1 {
+	cpu-supply = <&vdd_arm>;
+};
+
+&cpu2 {
+	cpu-supply = <&vdd_arm>;
+};
+
+&cpu3 {
+	cpu-supply = <&vdd_arm>;
+};
+
+&display_subsystem {
+	status = "okay";
+};
+
+&dsi {
+	status = "okay";
+
+	ports {
+		mipi_out: port@1 {
+			reg = <1>;
+
+			mipi_out_panel: endpoint {
+				remote-endpoint = <&mipi_in_panel>;
+			};
+		};
+	};
+
+	panel@0 {
+		compatible = "sitronix,st7703";
+		reg = <0>;
+		backlight = <&backlight>;
+		iovcc-supply = <&vcc_1v8>;
+		vci-supply = <&vcc3v3_lcd>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+
+				mipi_in_panel: endpoint {
+					remote-endpoint = <&mipi_out_panel>;
+				};
+			};
+		};
+	};
+};
+
+&dsi_dphy {
+	status = "okay";
+};
+
+&emmc {
+	bus-width = <8>;
+	cap-mmc-highspeed;
+	mmc-hs200-1_8v;
+	non-removable;
+	mmc-pwrseq = <&emmc_pwrseq>;
+	vmmc-supply = <&vcc_3v0>;
+	vqmmc-supply = <&vccio_flash>;
+	status = "okay";
+};
+
+&gmac {
+	clock_in_out = "output";
+	phy-supply = <&vcc_rmii>;
+	snps,reset-gpio = <&gpio2 13 GPIO_ACTIVE_LOW>;
+	snps,reset-active-low;
+	snps,reset-delays-us = <0 50000 50000>;
+	status = "okay";
+};
+
+&i2c0 {
+	status = "okay";
+
+	rk809: pmic@20 {
+		compatible = "rockchip,rk809";
+		reg = <0x20>;
+		interrupt-parent = <&gpio0>;
+		interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pmic_int>;
+		rockchip,system-power-controller;
+		wakeup-source;
+		#clock-cells = <0>;
+		clock-output-names = "xin32k";
+
+		vcc1-supply = <&vcc5v0_sys>;
+		vcc2-supply = <&vcc5v0_sys>;
+		vcc3-supply = <&vcc5v0_sys>;
+		vcc4-supply = <&vcc5v0_sys>;
+		vcc5-supply = <&vcc3v3_sys>;
+		vcc6-supply = <&vcc3v3_sys>;
+		vcc7-supply = <&vcc3v3_sys>;
+		vcc8-supply = <&vcc3v3_sys>;
+		vcc9-supply = <&vcc5v0_sys>;
+
+		regulators {
+			vdd_log: DCDC_REG1 {
+				regulator-name = "vdd_log";
+				regulator-min-microvolt = <950000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-ramp-delay = <6001>;
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <950000>;
+				};
+			};
+
+			vdd_arm: DCDC_REG2 {
+				regulator-name = "vdd_arm";
+				regulator-min-microvolt = <950000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-ramp-delay = <6001>;
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+					regulator-suspend-microvolt = <950000>;
+				};
+			};
+
+			vcc_ddr: DCDC_REG3 {
+				regulator-name = "vcc_ddr";
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+				};
+			};
+
+			vcc_3v0: vcc_rmii: DCDC_REG4 {
+				regulator-name = "vcc_3v0";
+				regulator-min-microvolt = <3000000>;
+				regulator-max-microvolt = <3000000>;
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <3000000>;
+				};
+			};
+
+			vcc3v3_sys: DCDC_REG5 {
+				regulator-name = "vcc3v3_sys";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <3300000>;
+				};
+			};
+
+			vcc_1v0: LDO_REG1 {
+				regulator-name = "vcc_1v0";
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <1000000>;
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <1000000>;
+				};
+			};
+
+			vcc_1v8: vccio_flash: vccio_sdio: LDO_REG2 {
+				regulator-name = "vcc_1v8";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <1800000>;
+				};
+			};
+
+			vdd_1v0: LDO_REG3 {
+				regulator-name = "vdd_1v0";
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <1000000>;
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <1000000>;
+				};
+			};
+
+			vcc3v0_pmu: LDO_REG4 {
+				regulator-name = "vcc3v0_pmu";
+				regulator-min-microvolt = <3000000>;
+				regulator-max-microvolt = <3000000>;
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <3000000>;
+				};
+			};
+
+			vccio_sd: LDO_REG5 {
+				regulator-name = "vccio_sd";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <3300000>;
+				};
+			};
+
+			vcc_sd: LDO_REG6 {
+				regulator-name = "vcc_sd";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <3300000>;
+				};
+			};
+
+			vcc2v8_dvp: LDO_REG7 {
+				regulator-name = "vcc2v8_dvp";
+				regulator-min-microvolt = <2800000>;
+				regulator-max-microvolt = <2800000>;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+					regulator-suspend-microvolt = <2800000>;
+				};
+			};
+
+			vcc1v8_dvp: LDO_REG8 {
+				regulator-name = "vcc1v8_dvp";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <1800000>;
+				};
+			};
+
+			vcc1v5_dvp: LDO_REG9 {
+				regulator-name = "vcc1v5_dvp";
+				regulator-min-microvolt = <1500000>;
+				regulator-max-microvolt = <1500000>;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+					regulator-suspend-microvolt = <1500000>;
+				};
+			};
+
+			vcc3v3_lcd: SWITCH_REG1 {
+				regulator-name = "vcc3v3_lcd";
+				regulator-boot-on;
+			};
+
+			vcc5v0_host: SWITCH_REG2 {
+				regulator-name = "vcc5v0_host";
+				regulator-always-on;
+				regulator-boot-on;
+			};
+		};
+	};
+};
+
+&i2s1_2ch {
+	status = "okay";
+};
+
+&io_domains {
+	status = "okay";
+
+	vccio1-supply = <&vccio_sdio>;
+	vccio2-supply = <&vccio_sd>;
+	vccio3-supply = <&vcc_3v0>;
+	vccio4-supply = <&vcc3v0_pmu>;
+	vccio5-supply = <&vcc_3v0>;
+	vccio6-supply = <&vccio_flash>;
+};
+
+&pinctrl {
+	headphone {
+		hp_det: hp-det {
+			rockchip,pins =
+				<2 RK_PB0 RK_FUNC_GPIO &pcfg_pull_down>;
+		};
+	};
+
+	emmc {
+		emmc_reset: emmc-reset {
+			rockchip,pins = <1 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	pmic {
+		pmic_int: pmic_int {
+			rockchip,pins =
+				<0 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+
+		soc_slppin_gpio: soc_slppin_gpio {
+			rockchip,pins =
+				<0 RK_PA4 RK_FUNC_GPIO &pcfg_output_low>;
+		};
+
+		soc_slppin_slp: soc_slppin_slp {
+			rockchip,pins =
+				<0 RK_PA4 1 &pcfg_pull_none>;
+		};
+
+		soc_slppin_rst: soc_slppin_rst {
+			rockchip,pins =
+				<0 RK_PA4 2 &pcfg_pull_none>;
+		};
+	};
+
+	sdio-pwrseq {
+		wifi_enable_h: wifi-enable-h {
+			rockchip,pins =
+				<0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+};
+
+&pmu_io_domains {
+	status = "okay";
+
+	pmuio1-supply = <&vcc3v0_pmu>;
+	pmuio2-supply = <&vcc3v0_pmu>;
+};
+
+&pwm1 {
+	status = "okay";
+};
+
+&saradc {
+	vref-supply = <&vcc_1v8>;
+	status = "okay";
+};
+
+&sdmmc {
+	bus-width = <4>;
+	cap-mmc-highspeed;
+	cap-sd-highspeed;
+	card-detect-delay = <800>;
+	sd-uhs-sdr12;
+	sd-uhs-sdr25;
+	sd-uhs-sdr50;
+	sd-uhs-sdr104;
+	vmmc-supply = <&vcc_sd>;
+	vqmmc-supply = <&vccio_sd>;
+};
+
+&sdio {
+	bus-width = <4>;
+	cap-sd-highspeed;
+	keep-power-in-suspend;
+	non-removable;
+	mmc-pwrseq = <&sdio_pwrseq>;
+	sd-uhs-sdr104;
+	status = "okay";
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart1_xfer &uart1_cts>;
+	status = "okay";
+};
+
+&uart2 {
+	status = "okay";
+};
+
+&uart5 {
+	status = "okay";
+};
+
+&usb20_otg {
+	status = "okay";
+};
+
+&usb_host0_ehci {
+	status = "okay";
+};
+
+&usb_host0_ohci {
+	status = "okay";
+};
+
+&vopb {
+	status = "okay";
+};
+
+&vopb_mmu {
+	status = "okay";
+};
+
+&vopl {
+	status = "okay";
+};
+
+&vopl_mmu {
+	status = "okay";
+};
diff --git a/arch/arm/dts/px30.dtsi b/arch/arm/dts/px30.dtsi
new file mode 100644
index 0000000..0d2325a
--- /dev/null
+++ b/arch/arm/dts/px30.dtsi
@@ -0,0 +1,2068 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd
+ */
+
+#include <dt-bindings/clock/px30-cru.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/power/px30-power.h>
+#include <dt-bindings/soc/rockchip,boot-mode.h>
+
+/ {
+	compatible = "rockchip,px30";
+
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	aliases {
+		ethernet0 = &gmac;
+		i2c0 = &i2c0;
+		i2c1 = &i2c1;
+		i2c2 = &i2c2;
+		i2c3 = &i2c3;
+		serial0 = &uart0;
+		serial1 = &uart1;
+		serial2 = &uart2;
+		serial3 = &uart3;
+		serial4 = &uart4;
+		serial5 = &uart5;
+		spi0 = &spi0;
+		spi1 = &spi1;
+	};
+
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		cpu0: cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a35";
+			reg = <0x0 0x0>;
+			enable-method = "psci";
+			clocks = <&cru ARMCLK>;
+			#cooling-cells = <2>;
+			cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
+			dynamic-power-coefficient = <90>;
+			operating-points-v2 = <&cpu0_opp_table>;
+		};
+
+		cpu1: cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a35";
+			reg = <0x0 0x1>;
+			enable-method = "psci";
+			clocks = <&cru ARMCLK>;
+			#cooling-cells = <2>;
+			cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
+			dynamic-power-coefficient = <90>;
+			operating-points-v2 = <&cpu0_opp_table>;
+		};
+
+		cpu2: cpu@2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a35";
+			reg = <0x0 0x2>;
+			enable-method = "psci";
+			clocks = <&cru ARMCLK>;
+			#cooling-cells = <2>;
+			cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
+			dynamic-power-coefficient = <90>;
+			operating-points-v2 = <&cpu0_opp_table>;
+		};
+
+		cpu3: cpu@3 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a35";
+			reg = <0x0 0x3>;
+			enable-method = "psci";
+			clocks = <&cru ARMCLK>;
+			#cooling-cells = <2>;
+			cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
+			dynamic-power-coefficient = <90>;
+			operating-points-v2 = <&cpu0_opp_table>;
+		};
+
+		idle-states {
+			entry-method = "psci";
+
+			CPU_SLEEP: cpu-sleep {
+				compatible = "arm,idle-state";
+				local-timer-stop;
+				arm,psci-suspend-param = <0x0010000>;
+				entry-latency-us = <120>;
+				exit-latency-us = <250>;
+				min-residency-us = <900>;
+			};
+
+			CLUSTER_SLEEP: cluster-sleep {
+				compatible = "arm,idle-state";
+				local-timer-stop;
+				arm,psci-suspend-param = <0x1010000>;
+				entry-latency-us = <400>;
+				exit-latency-us = <500>;
+				min-residency-us = <2000>;
+			};
+		};
+	};
+
+	cpu0_opp_table: cpu0-opp-table {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		opp-408000000 {
+			opp-hz = /bits/ 64 <408000000>;
+			opp-microvolt = <950000 950000 1350000>;
+			clock-latency-ns = <40000>;
+			opp-suspend;
+		};
+		opp-600000000 {
+			opp-hz = /bits/ 64 <600000000>;
+			opp-microvolt = <950000 950000 1350000>;
+			clock-latency-ns = <40000>;
+		};
+		opp-816000000 {
+			opp-hz = /bits/ 64 <816000000>;
+			opp-microvolt = <1050000 1050000 1350000>;
+			clock-latency-ns = <40000>;
+		};
+		opp-1008000000 {
+			opp-hz = /bits/ 64 <1008000000>;
+			opp-microvolt = <1175000 1175000 1350000>;
+			clock-latency-ns = <40000>;
+		};
+		opp-1200000000 {
+			opp-hz = /bits/ 64 <1200000000>;
+			opp-microvolt = <1300000 1300000 1350000>;
+			clock-latency-ns = <40000>;
+		};
+		opp-1296000000 {
+			opp-hz = /bits/ 64 <1296000000>;
+			opp-microvolt = <1350000 1350000 1350000>;
+			clock-latency-ns = <40000>;
+		};
+	};
+
+	arm-pmu {
+		compatible = "arm,cortex-a53-pmu";
+		interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;
+	};
+
+	dmc: dmc {
+		compatible = "rockchip,px30-dmc", "syscon";
+		reg = <0x0 0xff2a0000 0x0 0x1000>;
+	};
+
+	display_subsystem: display-subsystem {
+		compatible = "rockchip,display-subsystem";
+		ports = <&vopb_out>, <&vopl_out>;
+		status = "disabled";
+	};
+
+	gmac_clkin: external-gmac-clock {
+		compatible = "fixed-clock";
+		clock-frequency = <50000000>;
+		clock-output-names = "gmac_clkin";
+		#clock-cells = <0>;
+	};
+
+	psci {
+		compatible = "arm,psci-1.0";
+		method = "smc";
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+	};
+
+	xin24m: xin24m {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <24000000>;
+		clock-output-names = "xin24m";
+	};
+
+	pmu: power-management@ff000000 {
+		compatible = "rockchip,px30-pmu", "syscon", "simple-mfd";
+		reg = <0x0 0xff000000 0x0 0x1000>;
+
+		power: power-controller {
+			compatible = "rockchip,px30-power-controller";
+			#power-domain-cells = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			/* These power domains are grouped by VD_LOGIC */
+			pd_usb@PX30_PD_USB {
+				reg = <PX30_PD_USB>;
+				clocks = <&cru HCLK_HOST>,
+					 <&cru HCLK_OTG>,
+					 <&cru SCLK_OTG_ADP>;
+				pm_qos = <&qos_usb_host>, <&qos_usb_otg>;
+			};
+			pd_sdcard@PX30_PD_SDCARD {
+				reg = <PX30_PD_SDCARD>;
+				clocks = <&cru HCLK_SDMMC>,
+					 <&cru SCLK_SDMMC>;
+				pm_qos = <&qos_sdmmc>;
+			};
+			pd_gmac@PX30_PD_GMAC {
+				reg = <PX30_PD_GMAC>;
+				clocks = <&cru ACLK_GMAC>,
+					 <&cru PCLK_GMAC>,
+					 <&cru SCLK_MAC_REF>,
+					 <&cru SCLK_GMAC_RX_TX>;
+				pm_qos = <&qos_gmac>;
+			};
+			pd_mmc_nand@PX30_PD_MMC_NAND {
+				reg = <PX30_PD_MMC_NAND>;
+				clocks =  <&cru HCLK_NANDC>,
+					  <&cru HCLK_EMMC>,
+					  <&cru HCLK_SDIO>,
+					  <&cru HCLK_SFC>,
+					  <&cru SCLK_EMMC>,
+					  <&cru SCLK_NANDC>,
+					  <&cru SCLK_SDIO>,
+					  <&cru SCLK_SFC>;
+				pm_qos = <&qos_emmc>, <&qos_nand>,
+					 <&qos_sdio>, <&qos_sfc>;
+			};
+			pd_vpu@PX30_PD_VPU {
+				reg = <PX30_PD_VPU>;
+				clocks = <&cru ACLK_VPU>,
+					 <&cru HCLK_VPU>,
+					 <&cru SCLK_CORE_VPU>;
+				pm_qos = <&qos_vpu>, <&qos_vpu_r128>;
+			};
+			pd_vo@PX30_PD_VO {
+				reg = <PX30_PD_VO>;
+				clocks = <&cru ACLK_RGA>,
+					 <&cru ACLK_VOPB>,
+					 <&cru ACLK_VOPL>,
+					 <&cru DCLK_VOPB>,
+					 <&cru DCLK_VOPL>,
+					 <&cru HCLK_RGA>,
+					 <&cru HCLK_VOPB>,
+					 <&cru HCLK_VOPL>,
+					 <&cru PCLK_MIPI_DSI>,
+					 <&cru SCLK_RGA_CORE>,
+					 <&cru SCLK_VOPB_PWM>;
+				pm_qos = <&qos_rga_rd>, <&qos_rga_wr>,
+					 <&qos_vop_m0>, <&qos_vop_m1>;
+			};
+			pd_vi@PX30_PD_VI {
+				reg = <PX30_PD_VI>;
+				clocks = <&cru ACLK_CIF>,
+					 <&cru ACLK_ISP>,
+					 <&cru HCLK_CIF>,
+					 <&cru HCLK_ISP>,
+					 <&cru SCLK_ISP>;
+				pm_qos = <&qos_isp_128>, <&qos_isp_rd>,
+					 <&qos_isp_wr>, <&qos_isp_m1>,
+					 <&qos_vip>;
+			};
+			pd_gpu@PX30_PD_GPU {
+				reg = <PX30_PD_GPU>;
+				clocks = <&cru SCLK_GPU>;
+				pm_qos = <&qos_gpu>;
+			};
+		};
+	};
+
+	pmugrf: syscon@ff010000 {
+		compatible = "rockchip,px30-pmugrf", "syscon", "simple-mfd";
+		reg = <0x0 0xff010000 0x0 0x1000>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		pmu_io_domains: io-domains {
+			compatible = "rockchip,px30-pmu-io-voltage-domain";
+			status = "disabled";
+		};
+
+		reboot-mode {
+			compatible = "syscon-reboot-mode";
+			offset = <0x200>;
+			mode-bootloader = <BOOT_BL_DOWNLOAD>;
+			mode-fastboot = <BOOT_FASTBOOT>;
+			mode-loader = <BOOT_BL_DOWNLOAD>;
+			mode-normal = <BOOT_NORMAL>;
+			mode-recovery = <BOOT_RECOVERY>;
+		};
+	};
+
+	uart0: serial@ff030000 {
+		compatible = "rockchip,px30-uart", "snps,dw-apb-uart";
+		reg = <0x0 0xff030000 0x0 0x100>;
+		interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&pmucru SCLK_UART0_PMU>, <&pmucru PCLK_UART0_PMU>;
+		clock-names = "baudclk", "apb_pclk";
+		dmas = <&dmac 0>, <&dmac 1>;
+		dma-names = "tx", "rx";
+		reg-shift = <2>;
+		reg-io-width = <4>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>;
+		status = "disabled";
+	};
+
+	i2s1_2ch: i2s@ff070000 {
+		compatible = "rockchip,px30-i2s", "rockchip,rk3066-i2s";
+		reg = <0x0 0xff070000 0x0 0x1000>;
+		interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru SCLK_I2S1>, <&cru HCLK_I2S1>;
+		clock-names = "i2s_clk", "i2s_hclk";
+		dmas = <&dmac 18>, <&dmac 19>;
+		dma-names = "tx", "rx";
+		pinctrl-names = "default";
+		pinctrl-0 = <&i2s1_2ch_sclk &i2s1_2ch_lrck
+			     &i2s1_2ch_sdi &i2s1_2ch_sdo>;
+		#sound-dai-cells = <0>;
+		status = "disabled";
+	};
+
+	i2s2_2ch: i2s@ff080000 {
+		compatible = "rockchip,px30-i2s", "rockchip,rk3066-i2s";
+		reg = <0x0 0xff080000 0x0 0x1000>;
+		interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru SCLK_I2S2>, <&cru HCLK_I2S2>;
+		clock-names = "i2s_clk", "i2s_hclk";
+		dmas = <&dmac 20>, <&dmac 21>;
+		dma-names = "tx", "rx";
+		pinctrl-names = "default";
+		pinctrl-0 = <&i2s2_2ch_sclk &i2s2_2ch_lrck
+			     &i2s2_2ch_sdi &i2s2_2ch_sdo>;
+		#sound-dai-cells = <0>;
+		status = "disabled";
+	};
+
+	gic: interrupt-controller@ff131000 {
+		compatible = "arm,gic-400";
+		#interrupt-cells = <3>;
+		#address-cells = <0>;
+		interrupt-controller;
+		reg = <0x0 0xff131000 0 0x1000>,
+		      <0x0 0xff132000 0 0x2000>,
+		      <0x0 0xff134000 0 0x2000>,
+		      <0x0 0xff136000 0 0x2000>;
+		interrupts = <GIC_PPI 9
+		      (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+	};
+
+	grf: syscon@ff140000 {
+		compatible = "rockchip,px30-grf", "syscon", "simple-mfd";
+		reg = <0x0 0xff140000 0x0 0x1000>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		io_domains: io-domains {
+			compatible = "rockchip,px30-io-voltage-domain";
+			status = "disabled";
+		};
+	};
+
+	uart1: serial@ff158000 {
+		compatible = "rockchip,px30-uart", "snps,dw-apb-uart";
+		reg = <0x0 0xff158000 0x0 0x100>;
+		interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>;
+		clock-names = "baudclk", "apb_pclk";
+		dmas = <&dmac 2>, <&dmac 3>;
+		dma-names = "tx", "rx";
+		reg-shift = <2>;
+		reg-io-width = <4>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&uart1_xfer &uart1_cts &uart1_rts>;
+		status = "disabled";
+	};
+
+	uart2: serial@ff160000 {
+		compatible = "rockchip,px30-uart", "snps,dw-apb-uart";
+		reg = <0x0 0xff160000 0x0 0x100>;
+		interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>;
+		clock-names = "baudclk", "apb_pclk";
+		dmas = <&dmac 4>, <&dmac 5>;
+		dma-names = "tx", "rx";
+		reg-shift = <2>;
+		reg-io-width = <4>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&uart2m0_xfer>;
+		status = "disabled";
+	};
+
+	uart3: serial@ff168000 {
+		compatible = "rockchip,px30-uart", "snps,dw-apb-uart";
+		reg = <0x0 0xff168000 0x0 0x100>;
+		interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru SCLK_UART3>, <&cru PCLK_UART3>;
+		clock-names = "baudclk", "apb_pclk";
+		dmas = <&dmac 6>, <&dmac 7>;
+		dma-names = "tx", "rx";
+		reg-shift = <2>;
+		reg-io-width = <4>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&uart3m1_xfer &uart3m1_cts &uart3m1_rts>;
+		status = "disabled";
+	};
+
+	uart4: serial@ff170000 {
+		compatible = "rockchip,px30-uart", "snps,dw-apb-uart";
+		reg = <0x0 0xff170000 0x0 0x100>;
+		interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru SCLK_UART4>, <&cru PCLK_UART4>;
+		clock-names = "baudclk", "apb_pclk";
+		dmas = <&dmac 8>, <&dmac 9>;
+		dma-names = "tx", "rx";
+		reg-shift = <2>;
+		reg-io-width = <4>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&uart4_xfer &uart4_cts &uart4_rts>;
+		status = "disabled";
+	};
+
+	uart5: serial@ff178000 {
+		compatible = "rockchip,px30-uart", "snps,dw-apb-uart";
+		reg = <0x0 0xff178000 0x0 0x100>;
+		interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru SCLK_UART5>, <&cru PCLK_UART5>;
+		clock-names = "baudclk", "apb_pclk";
+		dmas = <&dmac 10>, <&dmac 11>;
+		dma-names = "tx", "rx";
+		reg-shift = <2>;
+		reg-io-width = <4>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&uart5_xfer &uart5_cts &uart5_rts>;
+		status = "disabled";
+	};
+
+	i2c0: i2c@ff180000 {
+		compatible = "rockchip,px30-i2c", "rockchip,rk3399-i2c";
+		reg = <0x0 0xff180000 0x0 0x1000>;
+		clocks =  <&cru SCLK_I2C0>, <&cru PCLK_I2C0>;
+		clock-names = "i2c", "pclk";
+		interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&i2c0_xfer>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	i2c1: i2c@ff190000 {
+		compatible = "rockchip,px30-i2c", "rockchip,rk3399-i2c";
+		reg = <0x0 0xff190000 0x0 0x1000>;
+		clocks = <&cru SCLK_I2C1>, <&cru PCLK_I2C1>;
+		clock-names = "i2c", "pclk";
+		interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&i2c1_xfer>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	i2c2: i2c@ff1a0000 {
+		compatible = "rockchip,px30-i2c", "rockchip,rk3399-i2c";
+		reg = <0x0 0xff1a0000 0x0 0x1000>;
+		clocks = <&cru SCLK_I2C2>, <&cru PCLK_I2C2>;
+		clock-names = "i2c", "pclk";
+		interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&i2c2_xfer>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	i2c3: i2c@ff1b0000 {
+		compatible = "rockchip,px30-i2c", "rockchip,rk3399-i2c";
+		reg = <0x0 0xff1b0000 0x0 0x1000>;
+		clocks = <&cru SCLK_I2C3>, <&cru PCLK_I2C3>;
+		clock-names = "i2c", "pclk";
+		interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&i2c3_xfer>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	spi0: spi@ff1d0000 {
+		compatible = "rockchip,px30-spi", "rockchip,rk3066-spi";
+		reg = <0x0 0xff1d0000 0x0 0x1000>;
+		interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru SCLK_SPI0>, <&cru PCLK_SPI0>;
+		clock-names = "spiclk", "apb_pclk";
+		dmas = <&dmac 12>, <&dmac 13>;
+		dma-names = "tx", "rx";
+		pinctrl-names = "default";
+		pinctrl-0 = <&spi0_clk &spi0_csn &spi0_miso &spi0_mosi>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	spi1: spi@ff1d8000 {
+		compatible = "rockchip,px30-spi", "rockchip,rk3066-spi";
+		reg = <0x0 0xff1d8000 0x0 0x1000>;
+		interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru SCLK_SPI1>, <&cru PCLK_SPI1>;
+		clock-names = "spiclk", "apb_pclk";
+		dmas = <&dmac 14>, <&dmac 15>;
+		dma-names = "tx", "rx";
+		pinctrl-names = "default";
+		pinctrl-0 = <&spi1_clk &spi1_csn0 &spi1_csn1 &spi1_miso &spi1_mosi>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	wdt: watchdog@ff1e0000 {
+		compatible = "snps,dw-wdt";
+		reg = <0x0 0xff1e0000 0x0 0x100>;
+		clocks = <&cru PCLK_WDT_NS>;
+		interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+		status = "disabled";
+	};
+
+	pwm0: pwm@ff200000 {
+		compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm";
+		reg = <0x0 0xff200000 0x0 0x10>;
+		clocks = <&cru SCLK_PWM0>, <&cru PCLK_PWM0>;
+		clock-names = "pwm", "pclk";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pwm0_pin>;
+		#pwm-cells = <3>;
+		status = "disabled";
+	};
+
+	pwm1: pwm@ff200010 {
+		compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm";
+		reg = <0x0 0xff200010 0x0 0x10>;
+		clocks = <&cru SCLK_PWM0>, <&cru PCLK_PWM0>;
+		clock-names = "pwm", "pclk";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pwm1_pin>;
+		#pwm-cells = <3>;
+		status = "disabled";
+	};
+
+	pwm2: pwm@ff200020 {
+		compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm";
+		reg = <0x0 0xff200020 0x0 0x10>;
+		clocks = <&cru SCLK_PWM0>, <&cru PCLK_PWM0>;
+		clock-names = "pwm", "pclk";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pwm2_pin>;
+		#pwm-cells = <3>;
+		status = "disabled";
+	};
+
+	pwm3: pwm@ff200030 {
+		compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm";
+		reg = <0x0 0xff200030 0x0 0x10>;
+		clocks = <&cru SCLK_PWM0>, <&cru PCLK_PWM0>;
+		clock-names = "pwm", "pclk";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pwm3_pin>;
+		#pwm-cells = <3>;
+		status = "disabled";
+	};
+
+	pwm4: pwm@ff208000 {
+		compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm";
+		reg = <0x0 0xff208000 0x0 0x10>;
+		clocks = <&cru SCLK_PWM1>, <&cru PCLK_PWM1>;
+		clock-names = "pwm", "pclk";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pwm4_pin>;
+		#pwm-cells = <3>;
+		status = "disabled";
+	};
+
+	pwm5: pwm@ff208010 {
+		compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm";
+		reg = <0x0 0xff208010 0x0 0x10>;
+		clocks = <&cru SCLK_PWM1>, <&cru PCLK_PWM1>;
+		clock-names = "pwm", "pclk";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pwm5_pin>;
+		#pwm-cells = <3>;
+		status = "disabled";
+	};
+
+	pwm6: pwm@ff208020 {
+		compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm";
+		reg = <0x0 0xff208020 0x0 0x10>;
+		clocks = <&cru SCLK_PWM1>, <&cru PCLK_PWM1>;
+		clock-names = "pwm", "pclk";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pwm6_pin>;
+		#pwm-cells = <3>;
+		status = "disabled";
+	};
+
+	pwm7: pwm@ff208030 {
+		compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm";
+		reg = <0x0 0xff208030 0x0 0x10>;
+		clocks = <&cru SCLK_PWM1>, <&cru PCLK_PWM1>;
+		clock-names = "pwm", "pclk";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pwm7_pin>;
+		#pwm-cells = <3>;
+		status = "disabled";
+	};
+
+	rktimer: timer@ff210000 {
+		compatible = "rockchip,px30-timer", "rockchip,rk3288-timer";
+		reg = <0x0 0xff210000 0x0 0x1000>;
+		interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru PCLK_TIMER>, <&cru SCLK_TIMER0>;
+		clock-names = "pclk", "timer";
+	};
+
+	amba {
+		compatible = "simple-bus";
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		dmac: dmac@ff240000 {
+			compatible = "arm,pl330", "arm,primecell";
+			reg = <0x0 0xff240000 0x0 0x4000>;
+			interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cru ACLK_DMAC>;
+			clock-names = "apb_pclk";
+			#dma-cells = <1>;
+		};
+	};
+
+	saradc: saradc@ff288000 {
+		compatible = "rockchip,px30-saradc", "rockchip,rk3399-saradc";
+		reg = <0x0 0xff288000 0x0 0x100>;
+		interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+		#io-channel-cells = <1>;
+		clocks = <&cru SCLK_SARADC>, <&cru PCLK_SARADC>;
+		clock-names = "saradc", "apb_pclk";
+		resets = <&cru SRST_SARADC_P>;
+		reset-names = "saradc-apb";
+		status = "disabled";
+	};
+
+	otp: nvmem@ff290000 {
+		compatible = "rockchip,px30-otp";
+		reg = <0x0 0xff290000 0x0 0x4000>;
+		clocks = <&cru SCLK_OTP_USR>, <&cru PCLK_OTP_NS>,
+			 <&cru PCLK_OTP_PHY>;
+		clock-names = "otp", "apb_pclk", "phy";
+		resets = <&cru SRST_OTP_PHY>;
+		reset-names = "phy";
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		/* Data cells */
+		cpu_id: id@7 {
+			reg = <0x07 0x10>;
+		};
+		cpu_leakage: cpu-leakage@17 {
+			reg = <0x17 0x1>;
+		};
+		performance: performance@1e {
+			reg = <0x1e 0x1>;
+			bits = <4 3>;
+		};
+	};
+
+	cru: clock-controller@ff2b0000 {
+		compatible = "rockchip,px30-cru";
+		reg = <0x0 0xff2b0000 0x0 0x1000>;
+		clocks = <&xin24m>, <&pmucru PLL_GPLL>;
+		clock-names = "xin24m", "gpll";
+		rockchip,grf = <&grf>;
+		#clock-cells = <1>;
+		#reset-cells = <1>;
+	};
+
+	pmucru: clock-controller@ff2bc000 {
+		compatible = "rockchip,px30-pmucru";
+		reg = <0x0 0xff2bc000 0x0 0x1000>;
+		clocks = <&xin24m>;
+		clock-names = "xin24m";
+		rockchip,grf = <&grf>;
+		#clock-cells = <1>;
+		#reset-cells = <1>;
+	};
+
+	dsi_dphy: phy@ff2e0000 {
+		compatible = "rockchip,px30-dsi-dphy";
+		reg = <0x0 0xff2e0000 0x0 0x10000>;
+		clocks = <&pmucru SCLK_MIPIDSIPHY_REF>, <&cru PCLK_MIPIDSIPHY>;
+		clock-names = "ref", "pclk";
+		#clock-cells = <0>;
+		resets = <&cru SRST_MIPIDSIPHY_P>;
+		reset-names = "apb";
+		#phy-cells = <0>;
+		power-domains = <&power PX30_PD_VO>;
+		status = "disabled";
+	};
+
+	usb20_otg: usb@ff300000 {
+		compatible = "rockchip,px30-usb", "rockchip,rk3066-usb",
+			     "snps,dwc2";
+		reg = <0x0 0xff300000 0x0 0x40000>;
+		interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru HCLK_OTG>;
+		clock-names = "otg";
+		dr_mode = "otg";
+		g-np-tx-fifo-size = <16>;
+		g-rx-fifo-size = <280>;
+		g-tx-fifo-size = <256 128 128 64 32 16>;
+		g-use-dma;
+		power-domains = <&power PX30_PD_USB>;
+		status = "disabled";
+	};
+
+	usb_host0_ehci: usb@ff340000 {
+		compatible = "generic-ehci";
+		reg = <0x0 0xff340000 0x0 0x10000>;
+		interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru HCLK_HOST>;
+		clock-names = "usbhost";
+		power-domains = <&power PX30_PD_USB>;
+		status = "disabled";
+	};
+
+	usb_host0_ohci: usb@ff350000 {
+		compatible = "generic-ohci";
+		reg = <0x0 0xff350000 0x0 0x10000>;
+		interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru HCLK_HOST>;
+		clock-names = "usbhost";
+		power-domains = <&power PX30_PD_USB>;
+		status = "disabled";
+	};
+
+	gmac: ethernet@ff360000 {
+		compatible = "rockchip,px30-gmac";
+		reg = <0x0 0xff360000 0x0 0x10000>;
+		interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "macirq";
+		clocks = <&cru SCLK_GMAC>, <&cru SCLK_GMAC_RX_TX>,
+			 <&cru SCLK_GMAC_RX_TX>, <&cru SCLK_MAC_REF>,
+			 <&cru SCLK_MAC_REFOUT>, <&cru ACLK_GMAC>,
+			 <&cru PCLK_GMAC>, <&cru SCLK_GMAC_RMII>;
+		clock-names = "stmmaceth", "mac_clk_rx",
+			      "mac_clk_tx", "clk_mac_ref",
+			      "clk_mac_refout", "aclk_mac",
+			      "pclk_mac", "clk_mac_speed";
+		rockchip,grf = <&grf>;
+		phy-mode = "rmii";
+		pinctrl-names = "default";
+		pinctrl-0 = <&rmii_pins &mac_refclk_12ma>;
+		power-domains = <&power PX30_PD_GMAC>;
+		resets = <&cru SRST_GMAC_A>;
+		reset-names = "stmmaceth";
+		status = "disabled";
+	};
+
+	sdmmc: dwmmc@ff370000 {
+		compatible = "rockchip,px30-dw-mshc", "rockchip,rk3288-dw-mshc";
+		reg = <0x0 0xff370000 0x0 0x4000>;
+		interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>,
+			 <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>;
+		clock-names = "biu", "ciu", "ciu-drv", "ciu-sample";
+		fifo-depth = <0x100>;
+		max-frequency = <150000000>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_det &sdmmc_bus4>;
+		power-domains = <&power PX30_PD_SDCARD>;
+		status = "disabled";
+	};
+
+	sdio: dwmmc@ff380000 {
+		compatible = "rockchip,px30-dw-mshc", "rockchip,rk3288-dw-mshc";
+		reg = <0x0 0xff380000 0x0 0x4000>;
+		interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru HCLK_SDIO>, <&cru SCLK_SDIO>,
+			 <&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>;
+		clock-names = "biu", "ciu", "ciu-drv", "ciu-sample";
+		fifo-depth = <0x100>;
+		max-frequency = <150000000>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&sdio_bus4 &sdio_cmd &sdio_clk>;
+		power-domains = <&power PX30_PD_MMC_NAND>;
+		status = "disabled";
+	};
+
+	emmc: dwmmc@ff390000 {
+		compatible = "rockchip,px30-dw-mshc", "rockchip,rk3288-dw-mshc";
+		reg = <0x0 0xff390000 0x0 0x4000>;
+		interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>,
+			 <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>;
+		clock-names = "biu", "ciu", "ciu-drv", "ciu-sample";
+		fifo-depth = <0x100>;
+		max-frequency = <150000000>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>;
+		power-domains = <&power PX30_PD_MMC_NAND>;
+		status = "disabled";
+	};
+
+	dsi: dsi@ff450000 {
+		compatible = "rockchip,px30-mipi-dsi";
+		reg = <0x0 0xff450000 0x0 0x10000>;
+		interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru PCLK_MIPI_DSI>, <&dsi_dphy>;
+		clock-names = "pclk", "pll";
+		resets = <&cru SRST_MIPIDSI_HOST_P>;
+		reset-names = "apb";
+		phys = <&dsi_dphy>;
+		phy-names = "dphy";
+		power-domains = <&power PX30_PD_VO>;
+		rockchip,grf = <&grf>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				dsi_in_vopb: endpoint@0 {
+					reg = <0>;
+					remote-endpoint = <&vopb_out_dsi>;
+				};
+
+				dsi_in_vopl: endpoint@1 {
+					reg = <1>;
+					remote-endpoint = <&vopl_out_dsi>;
+				};
+			};
+		};
+	};
+
+	vopb: vop@ff460000 {
+		compatible = "rockchip,px30-vop-big";
+		reg = <0x0 0xff460000 0x0 0xefc>;
+		interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru ACLK_VOPB>, <&cru DCLK_VOPB>,
+			 <&cru HCLK_VOPB>;
+		clock-names = "aclk_vop", "dclk_vop", "hclk_vop";
+		resets = <&cru SRST_VOPB_A>, <&cru SRST_VOPB_H>, <&cru SRST_VOPB>;
+		reset-names = "axi", "ahb", "dclk";
+		iommus = <&vopb_mmu>;
+		power-domains = <&power PX30_PD_VO>;
+		rockchip,grf = <&grf>;
+		status = "disabled";
+
+		vopb_out: port {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			vopb_out_dsi: endpoint@0 {
+				reg = <0>;
+				remote-endpoint = <&dsi_in_vopb>;
+			};
+		};
+	};
+
+	vopb_mmu: iommu@ff460f00 {
+		compatible = "rockchip,iommu";
+		reg = <0x0 0xff460f00 0x0 0x100>;
+		interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "vopb_mmu";
+		clocks = <&cru ACLK_VOPB>, <&cru HCLK_VOPB>;
+		clock-names = "aclk", "iface";
+		power-domains = <&power PX30_PD_VO>;
+		#iommu-cells = <0>;
+		status = "disabled";
+	};
+
+	vopl: vop@ff470000 {
+		compatible = "rockchip,px30-vop-lit";
+		reg = <0x0 0xff470000 0x0 0xefc>;
+		interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru ACLK_VOPL>, <&cru DCLK_VOPL>,
+			 <&cru HCLK_VOPL>;
+		clock-names = "aclk_vop", "dclk_vop", "hclk_vop";
+		resets = <&cru SRST_VOPL_A>, <&cru SRST_VOPL_H>, <&cru SRST_VOPL>;
+		reset-names = "axi", "ahb", "dclk";
+		iommus = <&vopl_mmu>;
+		power-domains = <&power PX30_PD_VO>;
+		rockchip,grf = <&grf>;
+		status = "disabled";
+
+		vopl_out: port {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			vopl_out_dsi: endpoint@0 {
+				reg = <0>;
+				remote-endpoint = <&dsi_in_vopl>;
+			};
+		};
+	};
+
+	vopl_mmu: iommu@ff470f00 {
+		compatible = "rockchip,iommu";
+		reg = <0x0 0xff470f00 0x0 0x100>;
+		interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "vopl_mmu";
+		clocks = <&cru ACLK_VOPL>, <&cru HCLK_VOPL>;
+		clock-names = "aclk", "iface";
+		power-domains = <&power PX30_PD_VO>;
+		#iommu-cells = <0>;
+		status = "disabled";
+	};
+
+	qos_gmac: qos@ff518000 {
+		compatible = "syscon";
+		reg = <0x0 0xff518000 0x0 0x20>;
+	};
+
+	qos_gpu: qos@ff520000 {
+		compatible = "syscon";
+		reg = <0x0 0xff520000 0x0 0x20>;
+	};
+
+	qos_sdmmc: qos@ff52c000 {
+		compatible = "syscon";
+		reg = <0x0 0xff52c000 0x0 0x20>;
+	};
+
+	qos_emmc: qos@ff538000 {
+		compatible = "syscon";
+		reg = <0x0 0xff538000 0x0 0x20>;
+	};
+
+	qos_nand: qos@ff538080 {
+		compatible = "syscon";
+		reg = <0x0 0xff538080 0x0 0x20>;
+	};
+
+	qos_sdio: qos@ff538100 {
+		compatible = "syscon";
+		reg = <0x0 0xff538100 0x0 0x20>;
+	};
+
+	qos_sfc: qos@ff538180 {
+		compatible = "syscon";
+		reg = <0x0 0xff538180 0x0 0x20>;
+	};
+
+	qos_usb_host: qos@ff540000 {
+		compatible = "syscon";
+		reg = <0x0 0xff540000 0x0 0x20>;
+	};
+
+	qos_usb_otg: qos@ff540080 {
+		compatible = "syscon";
+		reg = <0x0 0xff540080 0x0 0x20>;
+	};
+
+	qos_isp_128: qos@ff548000 {
+		compatible = "syscon";
+		reg = <0x0 0xff548000 0x0 0x20>;
+	};
+
+	qos_isp_rd: qos@ff548080 {
+		compatible = "syscon";
+		reg = <0x0 0xff548080 0x0 0x20>;
+	};
+
+	qos_isp_wr: qos@ff548100 {
+		compatible = "syscon";
+		reg = <0x0 0xff548100 0x0 0x20>;
+	};
+
+	qos_isp_m1: qos@ff548180 {
+		compatible = "syscon";
+		reg = <0x0 0xff548180 0x0 0x20>;
+	};
+
+	qos_vip: qos@ff548200 {
+		compatible = "syscon";
+		reg = <0x0 0xff548200 0x0 0x20>;
+	};
+
+	qos_rga_rd: qos@ff550000 {
+		compatible = "syscon";
+		reg = <0x0 0xff550000 0x0 0x20>;
+	};
+
+	qos_rga_wr: qos@ff550080 {
+		compatible = "syscon";
+		reg = <0x0 0xff550080 0x0 0x20>;
+	};
+
+	qos_vop_m0: qos@ff550100 {
+		compatible = "syscon";
+		reg = <0x0 0xff550100 0x0 0x20>;
+	};
+
+	qos_vop_m1: qos@ff550180 {
+		compatible = "syscon";
+		reg = <0x0 0xff550180 0x0 0x20>;
+	};
+
+	qos_vpu: qos@ff558000 {
+		compatible = "syscon";
+		reg = <0x0 0xff558000 0x0 0x20>;
+	};
+
+	qos_vpu_r128: qos@ff558080 {
+		compatible = "syscon";
+		reg = <0x0 0xff558080 0x0 0x20>;
+	};
+
+	pinctrl: pinctrl {
+		compatible = "rockchip,px30-pinctrl";
+		rockchip,grf = <&grf>;
+		rockchip,pmu = <&pmugrf>;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		gpio0: gpio0@ff040000 {
+			compatible = "rockchip,gpio-bank";
+			reg = <0x0 0xff040000 0x0 0x100>;
+			interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&pmucru PCLK_GPIO0_PMU>;
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpio1: gpio1@ff250000 {
+			compatible = "rockchip,gpio-bank";
+			reg = <0x0 0xff250000 0x0 0x100>;
+			interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cru PCLK_GPIO1>;
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpio2: gpio2@ff260000 {
+			compatible = "rockchip,gpio-bank";
+			reg = <0x0 0xff260000 0x0 0x100>;
+			interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cru PCLK_GPIO2>;
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpio3: gpio3@ff270000 {
+			compatible = "rockchip,gpio-bank";
+			reg = <0x0 0xff270000 0x0 0x100>;
+			interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cru PCLK_GPIO3>;
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		pcfg_pull_up: pcfg-pull-up {
+			bias-pull-up;
+		};
+
+		pcfg_pull_down: pcfg-pull-down {
+			bias-pull-down;
+		};
+
+		pcfg_pull_none: pcfg-pull-none {
+			bias-disable;
+		};
+
+		pcfg_pull_none_2ma: pcfg-pull-none-2ma {
+			bias-disable;
+			drive-strength = <2>;
+		};
+
+		pcfg_pull_up_2ma: pcfg-pull-up-2ma {
+			bias-pull-up;
+			drive-strength = <2>;
+		};
+
+		pcfg_pull_up_4ma: pcfg-pull-up-4ma {
+			bias-pull-up;
+			drive-strength = <4>;
+		};
+
+		pcfg_pull_none_4ma: pcfg-pull-none-4ma {
+			bias-disable;
+			drive-strength = <4>;
+		};
+
+		pcfg_pull_down_4ma: pcfg-pull-down-4ma {
+			bias-pull-down;
+			drive-strength = <4>;
+		};
+
+		pcfg_pull_none_8ma: pcfg-pull-none-8ma {
+			bias-disable;
+			drive-strength = <8>;
+		};
+
+		pcfg_pull_up_8ma: pcfg-pull-up-8ma {
+			bias-pull-up;
+			drive-strength = <8>;
+		};
+
+		pcfg_pull_none_12ma: pcfg-pull-none-12ma {
+			bias-disable;
+			drive-strength = <12>;
+		};
+
+		pcfg_pull_up_12ma: pcfg-pull-up-12ma {
+			bias-pull-up;
+			drive-strength = <12>;
+		};
+
+		pcfg_pull_none_smt: pcfg-pull-none-smt {
+			bias-disable;
+			input-schmitt-enable;
+		};
+
+		pcfg_output_high: pcfg-output-high {
+			output-high;
+		};
+
+		pcfg_output_low: pcfg-output-low {
+			output-low;
+		};
+
+		pcfg_input_high: pcfg-input-high {
+			bias-pull-up;
+			input-enable;
+		};
+
+		pcfg_input: pcfg-input {
+			input-enable;
+		};
+
+		i2c0 {
+			i2c0_xfer: i2c0-xfer {
+				rockchip,pins =
+					<0 RK_PB0 1 &pcfg_pull_none_smt>,
+					<0 RK_PB1 1 &pcfg_pull_none_smt>;
+			};
+		};
+
+		i2c1 {
+			i2c1_xfer: i2c1-xfer {
+				rockchip,pins =
+					<0 RK_PC2 1 &pcfg_pull_none_smt>,
+					<0 RK_PC3 1 &pcfg_pull_none_smt>;
+			};
+		};
+
+		i2c2 {
+			i2c2_xfer: i2c2-xfer {
+				rockchip,pins =
+					<2 RK_PB7 2 &pcfg_pull_none_smt>,
+					<2 RK_PC0 2 &pcfg_pull_none_smt>;
+			};
+		};
+
+		i2c3 {
+			i2c3_xfer: i2c3-xfer {
+				rockchip,pins =
+					<1 RK_PB4 4 &pcfg_pull_none_smt>,
+					<1 RK_PB5 4 &pcfg_pull_none_smt>;
+			};
+		};
+
+		tsadc {
+			tsadc_otp_gpio: tsadc-otp-gpio {
+				rockchip,pins =
+					<0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
+			};
+
+			tsadc_otp_out: tsadc-otp-out {
+				rockchip,pins =
+					<0 RK_PA6 1 &pcfg_pull_none>;
+			};
+		};
+
+		uart0 {
+			uart0_xfer: uart0-xfer {
+				rockchip,pins =
+					<0 RK_PB2 1 &pcfg_pull_up>,
+					<0 RK_PB3 1 &pcfg_pull_up>;
+			};
+
+			uart0_cts: uart0-cts {
+				rockchip,pins =
+					<0 RK_PB4 1 &pcfg_pull_none>;
+			};
+
+			uart0_rts: uart0-rts {
+				rockchip,pins =
+					<0 RK_PB5 1 &pcfg_pull_none>;
+			};
+		};
+
+		uart1 {
+			uart1_xfer: uart1-xfer {
+				rockchip,pins =
+					<1 RK_PC1 1 &pcfg_pull_up>,
+					<1 RK_PC0 1 &pcfg_pull_up>;
+			};
+
+			uart1_cts: uart1-cts {
+				rockchip,pins =
+					<1 RK_PC2 1 &pcfg_pull_none>;
+			};
+
+			uart1_rts: uart1-rts {
+				rockchip,pins =
+					<1 RK_PC3 1 &pcfg_pull_none>;
+			};
+		};
+
+		uart2-m0 {
+			uart2m0_xfer: uart2m0-xfer {
+				rockchip,pins =
+					<1 RK_PD2 2 &pcfg_pull_up>,
+					<1 RK_PD3 2 &pcfg_pull_up>;
+			};
+		};
+
+		uart2-m1 {
+			uart2m1_xfer: uart2m1-xfer {
+				rockchip,pins =
+					<2 RK_PB4 2 &pcfg_pull_up>,
+					<2 RK_PB6 2 &pcfg_pull_up>;
+			};
+		};
+
+		uart3-m0 {
+			uart3m0_xfer: uart3m0-xfer {
+				rockchip,pins =
+					<0 RK_PC0 2 &pcfg_pull_up>,
+					<0 RK_PC1 2 &pcfg_pull_up>;
+			};
+
+			uart3m0_cts: uart3m0-cts {
+				rockchip,pins =
+					<0 RK_PC2 2 &pcfg_pull_none>;
+			};
+
+			uart3m0_rts: uart3m0-rts {
+				rockchip,pins =
+					<0 RK_PC3 2 &pcfg_pull_none>;
+			};
+		};
+
+		uart3-m1 {
+			uart3m1_xfer: uart3m1-xfer {
+				rockchip,pins =
+					<1 RK_PB6 2 &pcfg_pull_up>,
+					<1 RK_PB7 2 &pcfg_pull_up>;
+			};
+
+			uart3m1_cts: uart3m1-cts {
+				rockchip,pins =
+					<1 RK_PB4 2 &pcfg_pull_none>;
+			};
+
+			uart3m1_rts: uart3m1-rts {
+				rockchip,pins =
+					<1 RK_PB5 2 &pcfg_pull_none>;
+			};
+		};
+
+		uart4 {
+			uart4_xfer: uart4-xfer {
+				rockchip,pins =
+					<1 RK_PD4 2 &pcfg_pull_up>,
+					<1 RK_PD5 2 &pcfg_pull_up>;
+			};
+
+			uart4_cts: uart4-cts {
+				rockchip,pins =
+					<1 RK_PD6 2 &pcfg_pull_none>;
+			};
+
+			uart4_rts: uart4-rts {
+				rockchip,pins =
+					<1 RK_PD7 2 &pcfg_pull_none>;
+			};
+		};
+
+		uart5 {
+			uart5_xfer: uart5-xfer {
+				rockchip,pins =
+					<3 RK_PA2 4 &pcfg_pull_up>,
+					<3 RK_PA1 4 &pcfg_pull_up>;
+			};
+
+			uart5_cts: uart5-cts {
+				rockchip,pins =
+					<3 RK_PA3 4 &pcfg_pull_none>;
+			};
+
+			uart5_rts: uart5-rts {
+				rockchip,pins =
+					<3 RK_PA5 4 &pcfg_pull_none>;
+			};
+		};
+
+		spi0 {
+			spi0_clk: spi0-clk {
+				rockchip,pins =
+					<1 RK_PB7 3 &pcfg_pull_up_4ma>;
+			};
+
+			spi0_csn: spi0-csn {
+				rockchip,pins =
+					<1 RK_PB6 3 &pcfg_pull_up_4ma>;
+			};
+
+			spi0_miso: spi0-miso {
+				rockchip,pins =
+					<1 RK_PB5 3 &pcfg_pull_up_4ma>;
+			};
+
+			spi0_mosi: spi0-mosi {
+				rockchip,pins =
+					<1 RK_PB4 3 &pcfg_pull_up_4ma>;
+			};
+
+			spi0_clk_hs: spi0-clk-hs {
+				rockchip,pins =
+					<1 RK_PB7 3 &pcfg_pull_up_8ma>;
+			};
+
+			spi0_miso_hs: spi0-miso-hs {
+				rockchip,pins =
+					<1 RK_PB5 3 &pcfg_pull_up_8ma>;
+			};
+
+			spi0_mosi_hs: spi0-mosi-hs {
+				rockchip,pins =
+					<1 RK_PB4 3 &pcfg_pull_up_8ma>;
+			};
+		};
+
+		spi1 {
+			spi1_clk: spi1-clk {
+				rockchip,pins =
+					<3 RK_PB7 4 &pcfg_pull_up_4ma>;
+			};
+
+			spi1_csn0: spi1-csn0 {
+				rockchip,pins =
+					<3 RK_PB1 4 &pcfg_pull_up_4ma>;
+			};
+
+			spi1_csn1: spi1-csn1 {
+				rockchip,pins =
+					<3 RK_PB2 2 &pcfg_pull_up_4ma>;
+			};
+
+			spi1_miso: spi1-miso {
+				rockchip,pins =
+					<3 RK_PB6 4 &pcfg_pull_up_4ma>;
+			};
+
+			spi1_mosi: spi1-mosi {
+				rockchip,pins =
+					<3 RK_PB4 4 &pcfg_pull_up_4ma>;
+			};
+
+			spi1_clk_hs: spi1-clk-hs {
+				rockchip,pins =
+					<3 RK_PB7 4 &pcfg_pull_up_8ma>;
+			};
+
+			spi1_miso_hs: spi1-miso-hs {
+				rockchip,pins =
+					<3 RK_PB6 4 &pcfg_pull_up_8ma>;
+			};
+
+			spi1_mosi_hs: spi1-mosi-hs {
+				rockchip,pins =
+					<3 RK_PB4 4 &pcfg_pull_up_8ma>;
+			};
+		};
+
+		pdm {
+			pdm_clk0m0: pdm-clk0m0 {
+				rockchip,pins =
+					<3 RK_PC6 2 &pcfg_pull_none>;
+			};
+
+			pdm_clk0m1: pdm-clk0m1 {
+				rockchip,pins =
+					<2 RK_PC6 1 &pcfg_pull_none>;
+			};
+
+			pdm_clk1: pdm-clk1 {
+				rockchip,pins =
+					<3 RK_PC7 2 &pcfg_pull_none>;
+			};
+
+			pdm_sdi0m0: pdm-sdi0m0 {
+				rockchip,pins =
+					<3 RK_PD3 2 &pcfg_pull_none>;
+			};
+
+			pdm_sdi0m1: pdm-sdi0m1 {
+				rockchip,pins =
+					<2 RK_PC5 2 &pcfg_pull_none>;
+			};
+
+			pdm_sdi1: pdm-sdi1 {
+				rockchip,pins =
+					<3 RK_PD0 2 &pcfg_pull_none>;
+			};
+
+			pdm_sdi2: pdm-sdi2 {
+				rockchip,pins =
+					<3 RK_PD1 2 &pcfg_pull_none>;
+			};
+
+			pdm_sdi3: pdm-sdi3 {
+				rockchip,pins =
+					<3 RK_PD2 2 &pcfg_pull_none>;
+			};
+
+			pdm_clk0m0_sleep: pdm-clk0m0-sleep {
+				rockchip,pins =
+					<3 RK_PC6 RK_FUNC_GPIO &pcfg_input_high>;
+			};
+
+			pdm_clk0m_sleep1: pdm-clk0m1-sleep {
+				rockchip,pins =
+					<2 RK_PC6 RK_FUNC_GPIO &pcfg_input_high>;
+			};
+
+			pdm_clk1_sleep: pdm-clk1-sleep {
+				rockchip,pins =
+					<3 RK_PC7 RK_FUNC_GPIO &pcfg_input_high>;
+			};
+
+			pdm_sdi0m0_sleep: pdm-sdi0m0-sleep {
+				rockchip,pins =
+					<3 RK_PD3 RK_FUNC_GPIO &pcfg_input_high>;
+			};
+
+			pdm_sdi0m1_sleep: pdm-sdi0m1-sleep {
+				rockchip,pins =
+					<2 RK_PC5 RK_FUNC_GPIO &pcfg_input_high>;
+			};
+
+			pdm_sdi1_sleep: pdm-sdi1-sleep {
+				rockchip,pins =
+					<3 RK_PD0 RK_FUNC_GPIO &pcfg_input_high>;
+			};
+
+			pdm_sdi2_sleep: pdm-sdi2-sleep {
+				rockchip,pins =
+					<3 RK_PD1 RK_FUNC_GPIO &pcfg_input_high>;
+			};
+
+			pdm_sdi3_sleep: pdm-sdi3-sleep {
+				rockchip,pins =
+					<3 RK_PD2 RK_FUNC_GPIO &pcfg_input_high>;
+			};
+		};
+
+		i2s0 {
+			i2s0_8ch_mclk: i2s0-8ch-mclk {
+				rockchip,pins =
+					<3 RK_PC1 2 &pcfg_pull_none>;
+			};
+
+			i2s0_8ch_sclktx: i2s0-8ch-sclktx {
+				rockchip,pins =
+					<3 RK_PC3 2 &pcfg_pull_none>;
+			};
+
+			i2s0_8ch_sclkrx: i2s0-8ch-sclkrx {
+				rockchip,pins =
+					<3 RK_PB4 2 &pcfg_pull_none>;
+			};
+
+			i2s0_8ch_lrcktx: i2s0-8ch-lrcktx {
+				rockchip,pins =
+					<3 RK_PC2 2 &pcfg_pull_none>;
+			};
+
+			i2s0_8ch_lrckrx: i2s0-8ch-lrckrx {
+				rockchip,pins =
+					<3 RK_PB5 2 &pcfg_pull_none>;
+			};
+
+			i2s0_8ch_sdo0: i2s0-8ch-sdo0 {
+				rockchip,pins =
+					<3 RK_PC4 2 &pcfg_pull_none>;
+			};
+
+			i2s0_8ch_sdo1: i2s0-8ch-sdo1 {
+				rockchip,pins =
+					<3 RK_PC0 2 &pcfg_pull_none>;
+			};
+
+			i2s0_8ch_sdo2: i2s0-8ch-sdo2 {
+				rockchip,pins =
+					<3 RK_PB7 2 &pcfg_pull_none>;
+			};
+
+			i2s0_8ch_sdo3: i2s0-8ch-sdo3 {
+				rockchip,pins =
+					<3 RK_PB6 2 &pcfg_pull_none>;
+			};
+
+			i2s0_8ch_sdi0: i2s0-8ch-sdi0 {
+				rockchip,pins =
+					<3 RK_PC5 2 &pcfg_pull_none>;
+			};
+
+			i2s0_8ch_sdi1: i2s0-8ch-sdi1 {
+				rockchip,pins =
+					<3 RK_PB3 2 &pcfg_pull_none>;
+			};
+
+			i2s0_8ch_sdi2: i2s0-8ch-sdi2 {
+				rockchip,pins =
+					<3 RK_PB1 2 &pcfg_pull_none>;
+			};
+
+			i2s0_8ch_sdi3: i2s0-8ch-sdi3 {
+				rockchip,pins =
+					<3 RK_PB0 2 &pcfg_pull_none>;
+			};
+		};
+
+		i2s1 {
+			i2s1_2ch_mclk: i2s1-2ch-mclk {
+				rockchip,pins =
+					<2 RK_PC3 1 &pcfg_pull_none>;
+			};
+
+			i2s1_2ch_sclk: i2s1-2ch-sclk {
+				rockchip,pins =
+					<2 RK_PC2 1 &pcfg_pull_none>;
+			};
+
+			i2s1_2ch_lrck: i2s1-2ch-lrck {
+				rockchip,pins =
+					<2 RK_PC1 1 &pcfg_pull_none>;
+			};
+
+			i2s1_2ch_sdi: i2s1-2ch-sdi {
+				rockchip,pins =
+					<2 RK_PC5 1 &pcfg_pull_none>;
+			};
+
+			i2s1_2ch_sdo: i2s1-2ch-sdo {
+				rockchip,pins =
+					<2 RK_PC4 1 &pcfg_pull_none>;
+			};
+		};
+
+		i2s2 {
+			i2s2_2ch_mclk: i2s2-2ch-mclk {
+				rockchip,pins =
+					<3 RK_PA1 2 &pcfg_pull_none>;
+			};
+
+			i2s2_2ch_sclk: i2s2-2ch-sclk {
+				rockchip,pins =
+					<3 RK_PA2 2 &pcfg_pull_none>;
+			};
+
+			i2s2_2ch_lrck: i2s2-2ch-lrck {
+				rockchip,pins =
+					<3 RK_PA3 2 &pcfg_pull_none>;
+			};
+
+			i2s2_2ch_sdi: i2s2-2ch-sdi {
+				rockchip,pins =
+					<3 RK_PA5 2 &pcfg_pull_none>;
+			};
+
+			i2s2_2ch_sdo: i2s2-2ch-sdo {
+				rockchip,pins =
+					<3 RK_PA7 2 &pcfg_pull_none>;
+			};
+		};
+
+		sdmmc {
+			sdmmc_clk: sdmmc-clk {
+				rockchip,pins =
+					<1 RK_PD6 1 &pcfg_pull_none_8ma>;
+			};
+
+			sdmmc_cmd: sdmmc-cmd {
+				rockchip,pins =
+					<1 RK_PD7 1 &pcfg_pull_up_8ma>;
+			};
+
+			sdmmc_det: sdmmc-det {
+				rockchip,pins =
+					<0 RK_PA3 1 &pcfg_pull_up_8ma>;
+			};
+
+			sdmmc_bus1: sdmmc-bus1 {
+				rockchip,pins =
+					<1 RK_PD2 1 &pcfg_pull_up_8ma>;
+			};
+
+			sdmmc_bus4: sdmmc-bus4 {
+				rockchip,pins =
+					<1 RK_PD2 1 &pcfg_pull_up_8ma>,
+					<1 RK_PD3 1 &pcfg_pull_up_8ma>,
+					<1 RK_PD4 1 &pcfg_pull_up_8ma>,
+					<1 RK_PD5 1 &pcfg_pull_up_8ma>;
+			};
+		};
+
+		sdio {
+			sdio_clk: sdio-clk {
+				rockchip,pins =
+					<1 RK_PC5 1 &pcfg_pull_none>;
+			};
+
+			sdio_cmd: sdio-cmd {
+				rockchip,pins =
+					<1 RK_PC4 1 &pcfg_pull_up>;
+			};
+
+			sdio_bus4: sdio-bus4 {
+				rockchip,pins =
+					<1 RK_PC6 1 &pcfg_pull_up>,
+					<1 RK_PC7 1 &pcfg_pull_up>,
+					<1 RK_PD0 1 &pcfg_pull_up>,
+					<1 RK_PD1 1 &pcfg_pull_up>;
+			};
+		};
+
+		emmc {
+			emmc_clk: emmc-clk {
+				rockchip,pins =
+					<1 RK_PB1 2 &pcfg_pull_none_8ma>;
+			};
+
+			emmc_cmd: emmc-cmd {
+				rockchip,pins =
+					<1 RK_PB2 2 &pcfg_pull_up_8ma>;
+			};
+
+			emmc_rstnout: emmc-rstnout {
+				rockchip,pins =
+					<1 RK_PB3 2 &pcfg_pull_none>;
+			};
+
+			emmc_bus1: emmc-bus1 {
+				rockchip,pins =
+					<1 RK_PA0 2 &pcfg_pull_up_8ma>;
+			};
+
+			emmc_bus4: emmc-bus4 {
+				rockchip,pins =
+					<1 RK_PA0 2 &pcfg_pull_up_8ma>,
+					<1 RK_PA1 2 &pcfg_pull_up_8ma>,
+					<1 RK_PA2 2 &pcfg_pull_up_8ma>,
+					<1 RK_PA3 2 &pcfg_pull_up_8ma>;
+			};
+
+			emmc_bus8: emmc-bus8 {
+				rockchip,pins =
+					<1 RK_PA0 2 &pcfg_pull_up_8ma>,
+					<1 RK_PA1 2 &pcfg_pull_up_8ma>,
+					<1 RK_PA2 2 &pcfg_pull_up_8ma>,
+					<1 RK_PA3 2 &pcfg_pull_up_8ma>,
+					<1 RK_PA4 2 &pcfg_pull_up_8ma>,
+					<1 RK_PA5 2 &pcfg_pull_up_8ma>,
+					<1 RK_PA6 2 &pcfg_pull_up_8ma>,
+					<1 RK_PA7 2 &pcfg_pull_up_8ma>;
+			};
+		};
+
+		flash {
+			flash_cs0: flash-cs0 {
+				rockchip,pins =
+					<1 RK_PB0 1 &pcfg_pull_none>;
+			};
+
+			flash_rdy: flash-rdy {
+				rockchip,pins =
+					<1 RK_PB1 1 &pcfg_pull_none>;
+			};
+
+			flash_dqs: flash-dqs {
+				rockchip,pins =
+					<1 RK_PB2 1 &pcfg_pull_none>;
+			};
+
+			flash_ale: flash-ale {
+				rockchip,pins =
+					<1 RK_PB3 1 &pcfg_pull_none>;
+			};
+
+			flash_cle: flash-cle {
+				rockchip,pins =
+					<1 RK_PB4 1 &pcfg_pull_none>;
+			};
+
+			flash_wrn: flash-wrn {
+				rockchip,pins =
+					<1 RK_PB5 1 &pcfg_pull_none>;
+			};
+
+			flash_csl: flash-csl {
+				rockchip,pins =
+					<1 RK_PB6 1 &pcfg_pull_none>;
+			};
+
+			flash_rdn: flash-rdn {
+				rockchip,pins =
+					<1 RK_PB7 1 &pcfg_pull_none>;
+			};
+
+			flash_bus8: flash-bus8 {
+				rockchip,pins =
+					<1 RK_PA0 1 &pcfg_pull_up_12ma>,
+					<1 RK_PA1 1 &pcfg_pull_up_12ma>,
+					<1 RK_PA2 1 &pcfg_pull_up_12ma>,
+					<1 RK_PA3 1 &pcfg_pull_up_12ma>,
+					<1 RK_PA4 1 &pcfg_pull_up_12ma>,
+					<1 RK_PA5 1 &pcfg_pull_up_12ma>,
+					<1 RK_PA6 1 &pcfg_pull_up_12ma>,
+					<1 RK_PA7 1 &pcfg_pull_up_12ma>;
+			};
+		};
+
+		lcdc {
+			lcdc_rgb_dclk_pin: lcdc-rgb-dclk-pin {
+				rockchip,pins =
+					<3 RK_PA0 1 &pcfg_pull_none_12ma>;
+			};
+
+			lcdc_rgb_m0_hsync_pin: lcdc-rgb-m0-hsync-pin {
+				rockchip,pins =
+					<3 RK_PA1 1 &pcfg_pull_none_12ma>;
+			};
+
+			lcdc_rgb_m0_vsync_pin: lcdc-rgb-m0-vsync-pin {
+				rockchip,pins =
+					<3 RK_PA2 1 &pcfg_pull_none_12ma>;
+			};
+
+			lcdc_rgb_m0_den_pin: lcdc-rgb-m0-den-pin {
+				rockchip,pins =
+					<3 RK_PA3 1 &pcfg_pull_none_12ma>;
+			};
+
+			lcdc_rgb888_m0_data_pins: lcdc-rgb888-m0-data-pins {
+				rockchip,pins =
+					<3 RK_PA7 1 &pcfg_pull_none_8ma>, /* lcdc_d3 */
+					<3 RK_PA6 1 &pcfg_pull_none_8ma>, /* lcdc_d2 */
+					<3 RK_PA5 1 &pcfg_pull_none_8ma>, /* lcdc_d1 */
+					<3 RK_PA4 1 &pcfg_pull_none_8ma>, /* lcdc_d0 */
+					<3 RK_PB3 1 &pcfg_pull_none_8ma>, /* lcdc_d7 */
+					<3 RK_PB2 1 &pcfg_pull_none_8ma>, /* lcdc_d6 */
+					<3 RK_PB1 1 &pcfg_pull_none_8ma>, /* lcdc_d5 */
+					<3 RK_PB0 1 &pcfg_pull_none_8ma>, /* lcdc_d4 */
+					<3 RK_PB7 1 &pcfg_pull_none_8ma>, /* lcdc_d11 */
+					<3 RK_PB6 1 &pcfg_pull_none_8ma>, /* lcdc_d10 */
+					<3 RK_PB5 1 &pcfg_pull_none_8ma>, /* lcdc_d9 */
+					<3 RK_PB4 1 &pcfg_pull_none_8ma>, /* lcdc_d8 */
+					<3 RK_PC3 1 &pcfg_pull_none_8ma>, /* lcdc_d15 */
+					<3 RK_PC2 1 &pcfg_pull_none_8ma>, /* lcdc_d14 */
+					<3 RK_PC1 1 &pcfg_pull_none_8ma>, /* lcdc_d13 */
+					<3 RK_PC0 1 &pcfg_pull_none_8ma>, /* lcdc_d12 */
+					<3 RK_PC7 1 &pcfg_pull_none_8ma>, /* lcdc_d19 */
+					<3 RK_PC6 1 &pcfg_pull_none_8ma>, /* lcdc_d18 */
+					<3 RK_PC5 1 &pcfg_pull_none_8ma>, /* lcdc_d17 */
+					<3 RK_PC4 1 &pcfg_pull_none_8ma>, /* lcdc_d16 */
+					<3 RK_PD3 1 &pcfg_pull_none_8ma>, /* lcdc_d23 */
+					<3 RK_PD2 1 &pcfg_pull_none_8ma>, /* lcdc_d22 */
+					<3 RK_PD1 1 &pcfg_pull_none_8ma>, /* lcdc_d21 */
+					<3 RK_PD0 1 &pcfg_pull_none_8ma>; /* lcdc_d20 */
+			};
+
+			lcdc_rgb666_m0_data_pins: lcdc-rgb666-m0-data-pins {
+				rockchip,pins =
+					<3 RK_PA7 1 &pcfg_pull_none_8ma>, /* lcdc_d3 */
+					<3 RK_PA6 1 &pcfg_pull_none_8ma>, /* lcdc_d2 */
+					<3 RK_PA5 1 &pcfg_pull_none_8ma>, /* lcdc_d1 */
+					<3 RK_PA4 1 &pcfg_pull_none_8ma>, /* lcdc_d0 */
+					<3 RK_PB3 1 &pcfg_pull_none_8ma>, /* lcdc_d7 */
+					<3 RK_PB2 1 &pcfg_pull_none_8ma>, /* lcdc_d6 */
+					<3 RK_PB1 1 &pcfg_pull_none_8ma>, /* lcdc_d5 */
+					<3 RK_PB0 1 &pcfg_pull_none_8ma>, /* lcdc_d4 */
+					<3 RK_PB7 1 &pcfg_pull_none_8ma>, /* lcdc_d11 */
+					<3 RK_PB6 1 &pcfg_pull_none_8ma>, /* lcdc_d10 */
+					<3 RK_PB5 1 &pcfg_pull_none_8ma>, /* lcdc_d9 */
+					<3 RK_PB4 1 &pcfg_pull_none_8ma>, /* lcdc_d8 */
+					<3 RK_PC3 1 &pcfg_pull_none_8ma>, /* lcdc_d15 */
+					<3 RK_PC2 1 &pcfg_pull_none_8ma>, /* lcdc_d14 */
+					<3 RK_PC1 1 &pcfg_pull_none_8ma>, /* lcdc_d13 */
+					<3 RK_PC0 1 &pcfg_pull_none_8ma>, /* lcdc_d12 */
+					<3 RK_PC5 1 &pcfg_pull_none_8ma>, /* lcdc_d17 */
+					<3 RK_PC4 1 &pcfg_pull_none_8ma>; /* lcdc_d16 */
+			};
+
+			lcdc_rgb565_m0_data_pins: lcdc-rgb565-m0-data-pins {
+				rockchip,pins =
+					<3 RK_PA7 1 &pcfg_pull_none_8ma>, /* lcdc_d3 */
+					<3 RK_PA6 1 &pcfg_pull_none_8ma>, /* lcdc_d2 */
+					<3 RK_PA5 1 &pcfg_pull_none_8ma>, /* lcdc_d1 */
+					<3 RK_PA4 1 &pcfg_pull_none_8ma>, /* lcdc_d0 */
+					<3 RK_PB3 1 &pcfg_pull_none_8ma>, /* lcdc_d7 */
+					<3 RK_PB2 1 &pcfg_pull_none_8ma>, /* lcdc_d6 */
+					<3 RK_PB1 1 &pcfg_pull_none_8ma>, /* lcdc_d5 */
+					<3 RK_PB0 1 &pcfg_pull_none_8ma>, /* lcdc_d4 */
+					<3 RK_PB7 1 &pcfg_pull_none_8ma>, /* lcdc_d11 */
+					<3 RK_PB6 1 &pcfg_pull_none_8ma>, /* lcdc_d10 */
+					<3 RK_PB5 1 &pcfg_pull_none_8ma>, /* lcdc_d9 */
+					<3 RK_PB4 1 &pcfg_pull_none_8ma>, /* lcdc_d8 */
+					<3 RK_PC3 1 &pcfg_pull_none_8ma>, /* lcdc_d15 */
+					<3 RK_PC2 1 &pcfg_pull_none_8ma>, /* lcdc_d14 */
+					<3 RK_PC1 1 &pcfg_pull_none_8ma>, /* lcdc_d13 */
+					<3 RK_PC0 1 &pcfg_pull_none_8ma>; /* lcdc_d12 */
+			};
+
+			lcdc_rgb888_m1_data_pins: lcdc-rgb888-m1-data-pins {
+				rockchip,pins =
+					<3 RK_PA6 1 &pcfg_pull_none_8ma>, /* lcdc_d2 */
+					<3 RK_PA4 1 &pcfg_pull_none_8ma>, /* lcdc_d0 */
+					<3 RK_PB3 1 &pcfg_pull_none_8ma>, /* lcdc_d7 */
+					<3 RK_PB2 1 &pcfg_pull_none_8ma>, /* lcdc_d6 */
+					<3 RK_PB5 1 &pcfg_pull_none_8ma>, /* lcdc_d9 */
+					<3 RK_PC3 1 &pcfg_pull_none_8ma>, /* lcdc_d15 */
+					<3 RK_PC2 1 &pcfg_pull_none_8ma>, /* lcdc_d14 */
+					<3 RK_PC1 1 &pcfg_pull_none_8ma>, /* lcdc_d13 */
+					<3 RK_PC0 1 &pcfg_pull_none_8ma>, /* lcdc_d12 */
+					<3 RK_PC7 1 &pcfg_pull_none_8ma>, /* lcdc_d19 */
+					<3 RK_PC6 1 &pcfg_pull_none_8ma>, /* lcdc_d18 */
+					<3 RK_PC5 1 &pcfg_pull_none_8ma>, /* lcdc_d17 */
+					<3 RK_PC4 1 &pcfg_pull_none_8ma>, /* lcdc_d16 */
+					<3 RK_PD3 1 &pcfg_pull_none_8ma>, /* lcdc_d23 */
+					<3 RK_PD2 1 &pcfg_pull_none_8ma>, /* lcdc_d22 */
+					<3 RK_PD1 1 &pcfg_pull_none_8ma>, /* lcdc_d21 */
+					<3 RK_PD0 1 &pcfg_pull_none_8ma>; /* lcdc_d20 */
+			};
+
+			lcdc_rgb666_m1_data_pins: lcdc-rgb666-m1-data-pins {
+				rockchip,pins =
+					<3 RK_PA6 1 &pcfg_pull_none_8ma>, /* lcdc_d2 */
+					<3 RK_PA4 1 &pcfg_pull_none_8ma>, /* lcdc_d0 */
+					<3 RK_PB3 1 &pcfg_pull_none_8ma>, /* lcdc_d7 */
+					<3 RK_PB2 1 &pcfg_pull_none_8ma>, /* lcdc_d6 */
+					<3 RK_PB5 1 &pcfg_pull_none_8ma>, /* lcdc_d9 */
+					<3 RK_PC3 1 &pcfg_pull_none_8ma>, /* lcdc_d15 */
+					<3 RK_PC2 1 &pcfg_pull_none_8ma>, /* lcdc_d14 */
+					<3 RK_PC1 1 &pcfg_pull_none_8ma>, /* lcdc_d13 */
+					<3 RK_PC0 1 &pcfg_pull_none_8ma>, /* lcdc_d12 */
+					<3 RK_PC5 1 &pcfg_pull_none_8ma>, /* lcdc_d17 */
+					<3 RK_PC4 1 &pcfg_pull_none_8ma>; /* lcdc_d16 */
+			};
+
+			lcdc_rgb565_m1_data_pins: lcdc-rgb565-m1-data-pins {
+				rockchip,pins =
+					<3 RK_PA6 1 &pcfg_pull_none_8ma>, /* lcdc_d2 */
+					<3 RK_PA4 1 &pcfg_pull_none_8ma>, /* lcdc_d0 */
+					<3 RK_PB3 1 &pcfg_pull_none_8ma>, /* lcdc_d7 */
+					<3 RK_PB2 1 &pcfg_pull_none_8ma>, /* lcdc_d6 */
+					<3 RK_PB5 1 &pcfg_pull_none_8ma>, /* lcdc_d9 */
+					<3 RK_PC3 1 &pcfg_pull_none_8ma>, /* lcdc_d15 */
+					<3 RK_PC2 1 &pcfg_pull_none_8ma>, /* lcdc_d14 */
+					<3 RK_PC1 1 &pcfg_pull_none_8ma>, /* lcdc_d13 */
+					<3 RK_PC0 1 &pcfg_pull_none_8ma>; /* lcdc_d12 */
+			};
+		};
+
+		pwm0 {
+			pwm0_pin: pwm0-pin {
+				rockchip,pins =
+					<0 RK_PB7 1 &pcfg_pull_none>;
+			};
+		};
+
+		pwm1 {
+			pwm1_pin: pwm1-pin {
+				rockchip,pins =
+					<0 RK_PC0 1 &pcfg_pull_none>;
+			};
+		};
+
+		pwm2 {
+			pwm2_pin: pwm2-pin {
+				rockchip,pins =
+					<2 RK_PB5 1 &pcfg_pull_none>;
+			};
+		};
+
+		pwm3 {
+			pwm3_pin: pwm3-pin {
+				rockchip,pins =
+					<0 RK_PC1 1 &pcfg_pull_none>;
+			};
+		};
+
+		pwm4 {
+			pwm4_pin: pwm4-pin {
+				rockchip,pins =
+					<3 RK_PC2 3 &pcfg_pull_none>;
+			};
+		};
+
+		pwm5 {
+			pwm5_pin: pwm5-pin {
+				rockchip,pins =
+					<3 RK_PC3 3 &pcfg_pull_none>;
+			};
+		};
+
+		pwm6 {
+			pwm6_pin: pwm6-pin {
+				rockchip,pins =
+					<3 RK_PC4 3 &pcfg_pull_none>;
+			};
+		};
+
+		pwm7 {
+			pwm7_pin: pwm7-pin {
+				rockchip,pins =
+					<3 RK_PC5 3 &pcfg_pull_none>;
+			};
+		};
+
+		gmac {
+			rmii_pins: rmii-pins {
+				rockchip,pins =
+					<2 RK_PA0 2 &pcfg_pull_none_12ma>, /* mac_txen */
+					<2 RK_PA1 2 &pcfg_pull_none_12ma>, /* mac_txd1 */
+					<2 RK_PA2 2 &pcfg_pull_none_12ma>, /* mac_txd0 */
+					<2 RK_PA3 2 &pcfg_pull_none>, /* mac_rxd0 */
+					<2 RK_PA4 2 &pcfg_pull_none>, /* mac_rxd1 */
+					<2 RK_PA5 2 &pcfg_pull_none>, /* mac_rxer */
+					<2 RK_PA6 2 &pcfg_pull_none>, /* mac_rxdv */
+					<2 RK_PA7 2 &pcfg_pull_none>, /* mac_mdio */
+					<2 RK_PB1 2 &pcfg_pull_none>; /* mac_mdc */
+			};
+
+			mac_refclk_12ma: mac-refclk-12ma {
+				rockchip,pins =
+					<2 RK_PB2 2 &pcfg_pull_none_12ma>;
+			};
+
+			mac_refclk: mac-refclk {
+				rockchip,pins =
+					<2 RK_PB2 2 &pcfg_pull_none>;
+			};
+		};
+
+		cif-m0 {
+			cif_clkout_m0: cif-clkout-m0 {
+				rockchip,pins =
+					<2 RK_PB3 1 &pcfg_pull_none>;
+			};
+
+			dvp_d2d9_m0: dvp-d2d9-m0 {
+				rockchip,pins =
+					<2 RK_PA0 1 &pcfg_pull_none>, /* cif_data2 */
+					<2 RK_PA1 1 &pcfg_pull_none>, /* cif_data3 */
+					<2 RK_PA2 1 &pcfg_pull_none>, /* cif_data4 */
+					<2 RK_PA3 1 &pcfg_pull_none>, /* cif_data5 */
+					<2 RK_PA4 1 &pcfg_pull_none>, /* cif_data6 */
+					<2 RK_PA5 1 &pcfg_pull_none>, /* cif_data7 */
+					<2 RK_PA6 1 &pcfg_pull_none>, /* cif_data8 */
+					<2 RK_PA7 1 &pcfg_pull_none>, /* cif_data9 */
+					<2 RK_PB0 1 &pcfg_pull_none>, /* cif_sync */
+					<2 RK_PB1 1 &pcfg_pull_none>, /* cif_href */
+					<2 RK_PB2 1 &pcfg_pull_none>, /* cif_clkin */
+					<2 RK_PB3 1 &pcfg_pull_none>; /* cif_clkout */
+			};
+
+			dvp_d0d1_m0: dvp-d0d1-m0 {
+				rockchip,pins =
+					<2 RK_PB4 1 &pcfg_pull_none>, /* cif_data0 */
+					<2 RK_PB6 1 &pcfg_pull_none>; /* cif_data1 */
+			};
+
+			dvp_d10d11_m0:d10-d11-m0 {
+				rockchip,pins =
+					<2 RK_PB7 1 &pcfg_pull_none>, /* cif_data10 */
+					<2 RK_PC0 1 &pcfg_pull_none>; /* cif_data11 */
+			};
+		};
+
+		cif-m1 {
+			cif_clkout_m1: cif-clkout-m1 {
+				rockchip,pins =
+					<3 RK_PD0 3 &pcfg_pull_none>;
+			};
+
+			dvp_d2d9_m1: dvp-d2d9-m1 {
+				rockchip,pins =
+					<3 RK_PA3 3 &pcfg_pull_none>, /* cif_data2 */
+					<3 RK_PA5 3 &pcfg_pull_none>, /* cif_data3 */
+					<3 RK_PA7 3 &pcfg_pull_none>, /* cif_data4 */
+					<3 RK_PB0 3 &pcfg_pull_none>, /* cif_data5 */
+					<3 RK_PB1 3 &pcfg_pull_none>, /* cif_data6 */
+					<3 RK_PB4 3 &pcfg_pull_none>, /* cif_data7 */
+					<3 RK_PB6 3 &pcfg_pull_none>, /* cif_data8 */
+					<3 RK_PB7 3 &pcfg_pull_none>, /* cif_data9 */
+					<3 RK_PD1 3 &pcfg_pull_none>, /* cif_sync */
+					<3 RK_PD2 3 &pcfg_pull_none>, /* cif_href */
+					<3 RK_PD3 3 &pcfg_pull_none>, /* cif_clkin */
+					<3 RK_PD0 3 &pcfg_pull_none>; /* cif_clkout */
+			};
+
+			dvp_d0d1_m1: dvp-d0d1-m1 {
+				rockchip,pins =
+					<3 RK_PA1 3 &pcfg_pull_none>, /* cif_data0 */
+					<3 RK_PA2 3 &pcfg_pull_none>; /* cif_data1 */
+			};
+
+			dvp_d10d11_m1:d10-d11-m1 {
+				rockchip,pins =
+					<3 RK_PC6 3 &pcfg_pull_none>, /* cif_data10 */
+					<3 RK_PC7 3 &pcfg_pull_none>; /* cif_data11 */
+			};
+		};
+
+		isp {
+			isp_prelight: isp-prelight {
+				rockchip,pins =
+					<3 RK_PD1 4 &pcfg_pull_none>;
+			};
+		};
+	};
+};
diff --git a/arch/arm/dts/rk3288-tinker-s-u-boot.dtsi b/arch/arm/dts/rk3288-tinker-s-u-boot.dtsi
new file mode 100644
index 0000000..a177fca
--- /dev/null
+++ b/arch/arm/dts/rk3288-tinker-s-u-boot.dtsi
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 Amarula Solutions SRO
+ */
+
+#include "rk3288-u-boot.dtsi"
+#include "rk3288-tinker-u-boot.dtsi"
+
+/ {
+	chosen {
+		u-boot,spl-boot-order = \
+			"same-as-spl", &sdmmc, &emmc;
+	};
+};
+
+&emmc {
+	u-boot,dm-spl;
+};
+
+&emmc_clk {
+	u-boot,dm-spl;
+};
+
+&emmc_cmd {
+	u-boot,dm-spl;
+};
+
+&emmc_pwr {
+	u-boot,dm-spl;
+};
+
+&emmc_bus8 {
+	u-boot,dm-spl;
+};
diff --git a/arch/arm/dts/rk3288-tinker-s.dts b/arch/arm/dts/rk3288-tinker-s.dts
new file mode 100644
index 0000000..cc7ac5f
--- /dev/null
+++ b/arch/arm/dts/rk3288-tinker-s.dts
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd.
+ */
+
+/dts-v1/;
+
+#include "rk3288-tinker.dtsi"
+
+/ {
+	model = "Rockchip RK3288 Asus Tinker Board S";
+	compatible = "asus,rk3288-tinker-s", "rockchip,rk3288";
+
+	chosen {
+		stdout-path = &uart2;
+	};
+};
+
+&emmc {
+	bus-width = <8>;
+	cap-mmc-highspeed;
+	non-removable;
+	pinctrl-names = "default";
+	pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_pwr &emmc_bus8>;
+	max-frequency = <150000000>;
+	mmc-hs200-1_8v;
+	mmc-ddr-1_8v;
+	status = "okay";
+};
diff --git a/arch/arm/dts/rk3288-tinker-u-boot.dtsi b/arch/arm/dts/rk3288-tinker-u-boot.dtsi
index f7f9d6d..732aa4f 100644
--- a/arch/arm/dts/rk3288-tinker-u-boot.dtsi
+++ b/arch/arm/dts/rk3288-tinker-u-boot.dtsi
@@ -5,6 +5,18 @@
 
 #include "rk3288-u-boot.dtsi"
 
+&dmc {
+	u-boot,dm-pre-reloc;
+	rockchip,pctl-timing = <0x215 0xc8 0x0 0x35 0x26 0x2 0x70 0x2000d
+		0x6 0x0 0x8 0x4 0x17 0x24 0xd 0x6
+		0x4 0x8 0x4 0x76 0x4 0x0 0x30 0x0
+		0x1 0x2 0x2 0x4 0x0 0x0 0xc0 0x4
+		0x8 0x1f4>;
+	rockchip,phy-timing = <0x48d7dd93 0x187008d8 0x121076
+		0x0 0xc3 0x6 0x2>;
+	rockchip,sdram-params = <0x20d266a4 0x5b6 2 533000000 6 9 0>;
+};
+
 &pinctrl {
 	u-boot,dm-pre-reloc;
 };
diff --git a/arch/arm/dts/rk3288-tinker.dts b/arch/arm/dts/rk3288-tinker.dts
index 94c3afe..4b8405f 100644
--- a/arch/arm/dts/rk3288-tinker.dts
+++ b/arch/arm/dts/rk3288-tinker.dts
@@ -15,18 +15,6 @@
 	};
 };
 
-&dmc {
-	rockchip,pctl-timing = <0x215 0xc8 0x0 0x35 0x26 0x2 0x70 0x2000d
-		0x6 0x0 0x8 0x4 0x17 0x24 0xd 0x6
-		0x4 0x8 0x4 0x76 0x4 0x0 0x30 0x0
-		0x1 0x2 0x2 0x4 0x0 0x0 0xc0 0x4
-		0x8 0x1f4>;
-	rockchip,phy-timing = <0x48d7dd93 0x187008d8 0x121076
-		0x0 0xc3 0x6 0x2>;
-	rockchip,sdram-params = <0x20d266a4 0x5b6 2 533000000 6 9 0>;
-};
-
-
 &pinctrl {
 	usb {
 		host_vbus_drv: host-vbus-drv {
diff --git a/arch/arm/dts/rk3308-evb-u-boot.dtsi b/arch/arm/dts/rk3308-evb-u-boot.dtsi
new file mode 100644
index 0000000..c6ea746
--- /dev/null
+++ b/arch/arm/dts/rk3308-evb-u-boot.dtsi
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2018-2019 Rockchip Electronics Co., Ltd
+ */
+#include "rk3308-u-boot.dtsi"
+
+/ {
+	chosen {
+		u-boot,spl-boot-order = "same-as-spl", &emmc;
+	};
+};
+
+&uart4 {
+	u-boot,dm-pre-reloc;
+	clock-frequency = <24000000>;
+	status = "okay";
+};
diff --git a/arch/arm/dts/rk3308-evb.dts b/arch/arm/dts/rk3308-evb.dts
new file mode 100644
index 0000000..124a240
--- /dev/null
+++ b/arch/arm/dts/rk3308-evb.dts
@@ -0,0 +1,230 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
+ *
+ */
+
+/dts-v1/;
+#include <dt-bindings/input/input.h>
+#include "rk3308.dtsi"
+
+/ {
+	model = "Rockchip RK3308 EVB";
+	compatible = "rockchip,rk3308-evb", "rockchip,rk3308";
+
+	chosen {
+		stdout-path = "serial4:1500000n8";
+	};
+
+	adc-keys0 {
+		compatible = "adc-keys";
+		io-channels = <&saradc 0>;
+		io-channel-names = "buttons";
+		poll-interval = <100>;
+		keyup-threshold-microvolt = <1800000>;
+
+		func-key {
+			linux,code = <KEY_FN>;
+			label = "function";
+			press-threshold-microvolt = <18000>;
+		};
+	};
+
+	adc-keys1 {
+		compatible = "adc-keys";
+		io-channels = <&saradc 1>;
+		io-channel-names = "buttons";
+		poll-interval = <100>;
+		keyup-threshold-microvolt = <1800000>;
+
+		esc-key {
+			linux,code = <KEY_MICMUTE>;
+			label = "micmute";
+			press-threshold-microvolt = <1130000>;
+		};
+
+		home-key {
+			linux,code = <KEY_MODE>;
+			label = "mode";
+			press-threshold-microvolt = <901000>;
+		};
+
+		menu-key {
+			linux,code = <KEY_PLAY>;
+			label = "play";
+			press-threshold-microvolt = <624000>;
+		};
+
+		vol-down-key {
+			linux,code = <KEY_VOLUMEDOWN>;
+			label = "volume down";
+			press-threshold-microvolt = <300000>;
+		};
+
+		vol-up-key {
+			linux,code = <KEY_VOLUMEUP>;
+			label = "volume up";
+			press-threshold-microvolt = <18000>;
+		};
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+		autorepeat;
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&pwr_key>;
+
+		power {
+			gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_POWER>;
+			label = "GPIO Key Power";
+			wakeup-source;
+			debounce-interval = <100>;
+		};
+	};
+
+	vcc12v_dcin: vcc12v-dcin {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc12v_dcin";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <12000000>;
+		regulator-max-microvolt = <12000000>;
+	};
+
+	vcc5v0_sys: vcc5v0-sys {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc5v0_sys";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&vcc12v_dcin>;
+	};
+
+	vdd_core: vdd-core {
+		compatible = "pwm-regulator";
+		pwms = <&pwm0 0 5000 1>;
+		regulator-name = "vdd_core";
+		regulator-min-microvolt = <827000>;
+		regulator-max-microvolt = <1340000>;
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-settling-time-up-us = <250>;
+		pwm-supply = <&vcc5v0_sys>;
+	};
+
+	vdd_log: vdd-log {
+		compatible = "regulator-fixed";
+		regulator-name = "vdd_log";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <1050000>;
+		regulator-max-microvolt = <1050000>;
+		vin-supply = <&vcc5v0_sys>;
+	};
+
+	vdd_1v0: vdd-1v0 {
+		compatible = "regulator-fixed";
+		regulator-name = "vdd_1v0";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <1000000>;
+		regulator-max-microvolt = <1000000>;
+		vin-supply = <&vcc5v0_sys>;
+	};
+
+	vccio_sdio: vcc_1v8: vcc-1v8 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_1v8";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		vin-supply = <&vcc_io>;
+	};
+
+	vcc_ddr: vcc-ddr {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_ddr";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <1500000>;
+		regulator-max-microvolt = <1500000>;
+		vin-supply = <&vcc5v0_sys>;
+	};
+
+	vcc_io: vcc-io {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_io";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&vcc5v0_sys>;
+	};
+
+	vccio_flash: vccio-flash {
+		compatible = "regulator-fixed";
+		regulator-name = "vccio_flash";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&vcc_io>;
+	};
+
+	vcc5v0_host: vcc5v0-host {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&usb_drv>;
+		regulator-name = "vbus_host";
+		vin-supply = <&vcc5v0_sys>;
+	};
+};
+
+&cpu0 {
+	cpu-supply = <&vdd_core>;
+};
+
+&saradc {
+	status = "okay";
+	vref-supply = <&vcc_1v8>;
+};
+
+&pinctrl {
+	pinctrl-names = "default";
+	pinctrl-0 = <&rtc_32k>;
+
+	buttons {
+		pwr_key: pwr-key {
+			rockchip,pins = <0 RK_PA6 0 &pcfg_pull_up>;
+		};
+	};
+
+	usb {
+		usb_drv: usb-drv {
+			rockchip,pins = <0 RK_PC5 0 &pcfg_pull_none>;
+		};
+	};
+
+	sdio-pwrseq {
+		wifi_enable_h: wifi-enable-h {
+			rockchip,pins = <0 RK_PA2 0 &pcfg_pull_none>;
+		};
+	};
+};
+
+&pwm0 {
+	status = "okay";
+	pinctrl-0 = <&pwm0_pin_pull_down>;
+};
+
+&uart4 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart4_xfer>;
+	status = "okay";
+};
diff --git a/arch/arm/dts/rk3308-roc-cc-u-boot.dtsi b/arch/arm/dts/rk3308-roc-cc-u-boot.dtsi
new file mode 100644
index 0000000..ffbe742
--- /dev/null
+++ b/arch/arm/dts/rk3308-roc-cc-u-boot.dtsi
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2018-2019 Rockchip Electronics Co., Ltd
+ */
+#include "rk3308-u-boot.dtsi"
+
+/ {
+	chosen {
+		u-boot,spl-boot-order = "same-as-spl", &emmc;
+	};
+};
+
+&uart2 {
+	u-boot,dm-pre-reloc;
+	clock-frequency = <24000000>;
+	status = "okay";
+};
diff --git a/arch/arm/dts/rk3308-roc-cc.dts b/arch/arm/dts/rk3308-roc-cc.dts
new file mode 100644
index 0000000..e10aa63
--- /dev/null
+++ b/arch/arm/dts/rk3308-roc-cc.dts
@@ -0,0 +1,190 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
+ */
+
+/dts-v1/;
+#include "rk3308.dtsi"
+
+/ {
+	model = "Firefly ROC-RK3308-CC board";
+	compatible = "firefly,roc-rk3308-cc", "rockchip,rk3308";
+	chosen {
+		stdout-path = "serial2:1500000n8";
+	};
+
+	ir_rx {
+		compatible = "gpio-ir-receiver";
+		gpios = <&gpio0 RK_PC0 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&ir_recv_pin>;
+	};
+
+	ir_tx {
+		compatible = "pwm-ir-tx";
+		pwms = <&pwm5 0 25000 0>;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		power {
+			label = "firefly:red:power";
+			linux,default-trigger = "ir-power-click";
+			default-state = "on";
+			gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
+		};
+
+		user {
+			label = "firefly:blue:user";
+			linux,default-trigger = "ir-user-click";
+			default-state = "off";
+			gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	typec_vcc5v: typec-vcc5v {
+		compatible = "regulator-fixed";
+		regulator-name = "typec_vcc5v";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+	};
+
+	vcc5v0_sys: vcc5v0-sys {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc5v0_sys";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-always-on;
+		regulator-boot-on;
+		vin-supply = <&typec_vcc5v>;
+	};
+
+	vdd_core: vdd-core {
+		compatible = "pwm-regulator";
+		pwms = <&pwm0 0 5000 1>;
+		regulator-name = "vdd_core";
+		regulator-min-microvolt = <827000>;
+		regulator-max-microvolt = <1340000>;
+		regulator-init-microvolt = <1015000>;
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-settling-time-up-us = <250>;
+		pwm-supply = <&vcc5v0_sys>;
+	};
+
+	vdd_log: vdd-log {
+		compatible = "regulator-fixed";
+		regulator-name = "vdd_log";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <1050000>;
+		regulator-max-microvolt = <1050000>;
+		vin-supply = <&vcc5v0_sys>;
+	};
+
+	vcc_io: vcc-io {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_io";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-always-on;
+		regulator-boot-on;
+		vin-supply = <&vcc5v0_sys>;
+	};
+
+	vcc_sdmmc: vcc-sdmmc {
+		compatible = "regulator-gpio";
+		regulator-name = "vcc_sdmmc";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <3300000>;
+		gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_HIGH>;
+		states = <1800000 0x0
+			  3300000 0x1>;
+		vin-supply = <&vcc5v0_sys>;
+	};
+
+	vcc_sd: vcc-sd {
+		compatible = "regulator-fixed";
+		gpio = <&gpio4 RK_PD6 GPIO_ACTIVE_LOW>;
+		regulator-name = "vcc_sd";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-always-on;
+		regulator-boot-on;
+		vim-supply = <&vcc_io>;
+	};
+
+};
+
+&cpu0 {
+	cpu-supply = <&vdd_core>;
+};
+
+&emmc {
+	bus-width = <8>;
+	cap-mmc-highspeed;
+	supports-emmc;
+	disable-wp;
+	non-removable;
+	num-slots = <1>;
+	status = "okay";
+};
+
+&i2c1 {
+	clock-frequency = <400000>;
+	status = "okay";
+
+	rtc: rtc@51 {
+		compatible = "nxp,pcf8563";
+		reg = <0x51>;
+		#clock-cells = <0>;
+	};
+};
+
+&pwm5 {
+	status = "okay";
+	pinctrl-names = "active";
+	pinctrl-0 = <&pwm5_pin_pull_down>;
+};
+
+&pinctrl {
+	pinctrl-names = "default";
+	pinctrl-0 = <&rtc_32k>;
+
+	ir-receiver {
+		ir_recv_pin: ir-recv-pin  {
+			rockchip,pins = <0 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	buttons {
+		pwr_key: pwr-key {
+			rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+};
+
+&pwm0 {
+	status = "okay";
+	pinctrl-0 = <&pwm0_pin_pull_down>;
+};
+
+&sdmmc {
+	bus-width = <4>;
+	cap-mmc-highspeed;
+	cap-sd-highspeed;
+	supports-sd;
+	card-detect-delay = <300>;
+	sd-uhs-sdr25;
+	sd-uhs-sdr50;
+	sd-uhs-sdr104;
+	vmmc-supply = <&vcc_sd>;
+	vqmmc-supply = <&vcc_sdmmc>;
+	status = "okay";
+};
+
+&uart2 {
+	status = "okay";
+};
diff --git a/arch/arm/dts/rk3308-u-boot.dtsi b/arch/arm/dts/rk3308-u-boot.dtsi
new file mode 100644
index 0000000..1a68dec
--- /dev/null
+++ b/arch/arm/dts/rk3308-u-boot.dtsi
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ *(C) Copyright 2019 Rockchip Electronics Co., Ltd
+ */
+
+&cru {
+	u-boot,dm-pre-reloc;
+};
+
+&dmc {
+	u-boot,dm-pre-reloc;
+};
+
+&emmc {
+	u-boot,dm-pre-reloc;
+};
+
+&grf {
+	u-boot,dm-pre-reloc;
+};
+
+&saradc {
+	u-boot,dm-pre-reloc;
+	status = "okay";
+};
diff --git a/arch/arm/dts/rk3308.dtsi b/arch/arm/dts/rk3308.dtsi
new file mode 100644
index 0000000..0eeec16
--- /dev/null
+++ b/arch/arm/dts/rk3308.dtsi
@@ -0,0 +1,1829 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
+ *
+ */
+
+#include <dt-bindings/clock/rk3308-cru.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/thermal/thermal.h>
+
+/ {
+	compatible = "rockchip,rk3308";
+
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	aliases {
+		i2c0 = &i2c0;
+		i2c1 = &i2c1;
+		i2c2 = &i2c2;
+		i2c3 = &i2c3;
+		serial0 = &uart0;
+		serial1 = &uart1;
+		serial2 = &uart2;
+		serial3 = &uart3;
+		serial4 = &uart4;
+		spi0 = &spi0;
+		spi1 = &spi1;
+		spi2 = &spi2;
+	};
+
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		cpu0: cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a35", "arm,armv8";
+			reg = <0x0 0x0>;
+			enable-method = "psci";
+			clocks = <&cru ARMCLK>;
+			#cooling-cells = <2>;
+			dynamic-power-coefficient = <90>;
+			operating-points-v2 = <&cpu0_opp_table>;
+			cpu-idle-states = <&CPU_SLEEP>;
+			next-level-cache = <&l2>;
+		};
+
+		cpu1: cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a35", "arm,armv8";
+			reg = <0x0 0x1>;
+			enable-method = "psci";
+			operating-points-v2 = <&cpu0_opp_table>;
+			cpu-idle-states = <&CPU_SLEEP>;
+			next-level-cache = <&l2>;
+		};
+
+		cpu2: cpu@2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a35", "arm,armv8";
+			reg = <0x0 0x2>;
+			enable-method = "psci";
+			operating-points-v2 = <&cpu0_opp_table>;
+			cpu-idle-states = <&CPU_SLEEP>;
+			next-level-cache = <&l2>;
+		};
+
+		cpu3: cpu@3 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a35", "arm,armv8";
+			reg = <0x0 0x3>;
+			enable-method = "psci";
+			operating-points-v2 = <&cpu0_opp_table>;
+			cpu-idle-states = <&CPU_SLEEP>;
+			next-level-cache = <&l2>;
+		};
+
+		idle-states {
+			entry-method = "psci";
+
+			CPU_SLEEP: cpu-sleep {
+				compatible = "arm,idle-state";
+				local-timer-stop;
+				arm,psci-suspend-param = <0x0010000>;
+				entry-latency-us = <120>;
+				exit-latency-us = <250>;
+				min-residency-us = <900>;
+			};
+		};
+
+		l2: l2-cache {
+			compatible = "cache";
+		};
+	};
+
+	cpu0_opp_table: cpu0-opp-table {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		opp-408000000 {
+			opp-hz = /bits/ 64 <408000000>;
+			opp-microvolt = <950000 950000 1340000>;
+			clock-latency-ns = <40000>;
+			opp-suspend;
+		};
+		opp-600000000 {
+			opp-hz = /bits/ 64 <600000000>;
+			opp-microvolt = <950000 950000 1340000>;
+			clock-latency-ns = <40000>;
+		};
+		opp-816000000 {
+			opp-hz = /bits/ 64 <816000000>;
+			opp-microvolt = <1025000 1025000 1340000>;
+			clock-latency-ns = <40000>;
+		};
+		opp-1008000000 {
+			opp-hz = /bits/ 64 <1008000000>;
+			opp-microvolt = <1125000 1125000 1340000>;
+			clock-latency-ns = <40000>;
+		};
+	};
+
+	arm-pmu {
+		compatible = "arm,cortex-a53-pmu";
+		interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;
+	};
+
+	mac_clkin: external-mac-clock {
+		compatible = "fixed-clock";
+		clock-frequency = <50000000>;
+		clock-output-names = "mac_clkin";
+		#clock-cells = <0>;
+	};
+
+	psci {
+		compatible = "arm,psci-1.0";
+		method = "smc";
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+	};
+
+	xin24m: xin24m {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <24000000>;
+		clock-output-names = "xin24m";
+	};
+
+	grf: grf@ff000000 {
+		compatible = "rockchip,rk3308-grf", "syscon", "simple-mfd";
+		reg = <0x0 0xff000000 0x0 0x10000>;
+	};
+
+	dmc: dmc@0xff010000 {
+		compatible = "rockchip,rk3308-dmc";
+		reg = <0x0 0xff010000 0x0 0x10000>;
+	};
+
+	detect_grf: syscon@ff00b000 {
+		compatible = "rockchip,rk3308-detect-grf", "syscon", "simple-mfd";
+		reg = <0x0 0xff00b000 0x0 0x1000>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+	};
+
+	core_grf: syscon@ff00c000 {
+		compatible = "rockchip,rk3308-core-grf", "syscon", "simple-mfd";
+		reg = <0x0 0xff00c000 0x0 0x1000>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+	};
+
+	i2c0: i2c@ff040000 {
+		compatible = "rockchip,rk3308-i2c", "rockchip,rk3399-i2c";
+		reg = <0x0 0xff040000 0x0 0x1000>;
+		clocks = <&cru SCLK_I2C0>, <&cru PCLK_I2C0>;
+		clock-names = "i2c", "pclk";
+		interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&i2c0_xfer>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	i2c1: i2c@ff050000 {
+		compatible = "rockchip,rk3308-i2c", "rockchip,rk3399-i2c";
+		reg = <0x0 0xff050000 0x0 0x1000>;
+		clocks = <&cru SCLK_I2C1>, <&cru PCLK_I2C1>;
+		clock-names = "i2c", "pclk";
+		interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&i2c1_xfer>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	i2c2: i2c@ff060000 {
+		compatible = "rockchip,rk3308-i2c", "rockchip,rk3399-i2c";
+		reg = <0x0 0xff060000 0x0 0x1000>;
+		clocks = <&cru SCLK_I2C2>, <&cru PCLK_I2C2>;
+		clock-names = "i2c", "pclk";
+		interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&i2c2_xfer>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	i2c3: i2c@ff070000 {
+		compatible = "rockchip,rk3308-i2c", "rockchip,rk3399-i2c";
+		reg = <0x0 0xff070000 0x0 0x1000>;
+		clocks = <&cru SCLK_I2C3>, <&cru PCLK_I2C3>;
+		clock-names = "i2c", "pclk";
+		interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&i2c3m0_xfer>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	wdt: watchdog@ff080000 {
+		compatible = "snps,dw-wdt";
+		reg = <0x0 0xff080000 0x0 0x100>;
+		clocks = <&cru PCLK_WDT>;
+		interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+		status = "disabled";
+	};
+
+	uart0: serial@ff0a0000 {
+		compatible = "rockchip,rk3308-uart", "snps,dw-apb-uart";
+		reg = <0x0 0xff0a0000 0x0 0x100>;
+		interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>;
+		clock-names = "baudclk", "apb_pclk";
+		reg-shift = <2>;
+		reg-io-width = <4>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>;
+		status = "disabled";
+	};
+
+	uart1: serial@ff0b0000 {
+		compatible = "rockchip,rk3308-uart", "snps,dw-apb-uart";
+		reg = <0x0 0xff0b0000 0x0 0x100>;
+		interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>;
+		clock-names = "baudclk", "apb_pclk";
+		reg-shift = <2>;
+		reg-io-width = <4>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&uart1_xfer &uart1_cts &uart1_rts>;
+		status = "disabled";
+	};
+
+	uart2: serial@ff0c0000 {
+		compatible = "rockchip,rk3308-uart", "snps,dw-apb-uart";
+		reg = <0x0 0xff0c0000 0x0 0x100>;
+		interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>;
+		clock-names = "baudclk", "apb_pclk";
+		reg-shift = <2>;
+		reg-io-width = <4>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&uart2m0_xfer>;
+		status = "disabled";
+	};
+
+	uart3: serial@ff0d0000 {
+		compatible = "rockchip,rk3308-uart", "snps,dw-apb-uart";
+		reg = <0x0 0xff0d0000 0x0 0x100>;
+		interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru SCLK_UART3>, <&cru PCLK_UART3>;
+		clock-names = "baudclk", "apb_pclk";
+		reg-shift = <2>;
+		reg-io-width = <4>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&uart3_xfer>;
+		status = "disabled";
+	};
+
+	uart4: serial@ff0e0000 {
+		compatible = "rockchip,rk3308-uart", "snps,dw-apb-uart";
+		reg = <0x0 0xff0e0000 0x0 0x100>;
+		interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru SCLK_UART4>, <&cru PCLK_UART4>;
+		clock-names = "baudclk", "apb_pclk";
+		reg-shift = <2>;
+		reg-io-width = <4>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&uart4_xfer &uart4_cts &uart4_rts>;
+		status = "disabled";
+	};
+
+	spi0: spi@ff120000 {
+		compatible = "rockchip,rk3308-spi", "rockchip,rk3066-spi";
+		reg = <0x0 0xff120000 0x0 0x1000>;
+		interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		clocks = <&cru SCLK_SPI0>, <&cru PCLK_SPI0>;
+		clock-names = "spiclk", "apb_pclk";
+		dmas = <&dmac0 0>, <&dmac0 1>;
+		dma-names = "tx", "rx";
+		pinctrl-names = "default", "high_speed";
+		pinctrl-0 = <&spi0_clk &spi0_csn0 &spi0_miso &spi0_mosi>;
+		pinctrl-1 = <&spi0_clk_hs &spi0_csn0 &spi0_miso_hs &spi0_mosi_hs>;
+		status = "disabled";
+	};
+
+	spi1: spi@ff130000 {
+		compatible = "rockchip,rk3308-spi", "rockchip,rk3066-spi";
+		reg = <0x0 0xff130000 0x0 0x1000>;
+		interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		clocks = <&cru SCLK_SPI1>, <&cru PCLK_SPI1>;
+		clock-names = "spiclk", "apb_pclk";
+		dmas = <&dmac0 2>, <&dmac0 3>;
+		dma-names = "tx", "rx";
+		pinctrl-names = "default", "high_speed";
+		pinctrl-0 = <&spi1_clk &spi1_csn0 &spi1_miso &spi1_mosi>;
+		pinctrl-1 = <&spi1_clk_hs &spi1_csn0 &spi1_miso_hs &spi1_mosi_hs>;
+		status = "disabled";
+	};
+
+	spi2: spi@ff140000 {
+		compatible = "rockchip,rk3308-spi", "rockchip,rk3066-spi";
+		reg = <0x0 0xff140000 0x0 0x1000>;
+		interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		clocks = <&cru SCLK_SPI2>, <&cru PCLK_SPI2>;
+		clock-names = "spiclk", "apb_pclk";
+		dmas = <&dmac1 16>, <&dmac1 17>;
+		dma-names = "tx", "rx";
+		pinctrl-names = "default", "high_speed";
+		pinctrl-0 = <&spi2_clk &spi2_csn0 &spi2_miso &spi2_mosi>;
+		pinctrl-1 = <&spi2_clk_hs &spi2_csn0 &spi2_miso_hs &spi2_mosi_hs>;
+		status = "disabled";
+	};
+
+	pwm8: pwm@ff160000 {
+		compatible = "rockchip,rk3308-pwm", "rockchip,rk3328-pwm";
+		reg = <0x0 0xff160000 0x0 0x10>;
+		#pwm-cells = <3>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pwm8_pin>;
+		clocks = <&cru SCLK_PWM2>, <&cru PCLK_PWM2>;
+		clock-names = "pwm", "pclk";
+		status = "disabled";
+	};
+
+	pwm9: pwm@ff160010 {
+		compatible = "rockchip,rk3308-pwm", "rockchip,rk3328-pwm";
+		reg = <0x0 0xff160010 0x0 0x10>;
+		#pwm-cells = <3>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pwm9_pin>;
+		clocks = <&cru SCLK_PWM2>, <&cru PCLK_PWM2>;
+		clock-names = "pwm", "pclk";
+		status = "disabled";
+	};
+
+	pwm10: pwm@ff160020 {
+		compatible = "rockchip,rk3308-pwm", "rockchip,rk3328-pwm";
+		reg = <0x0 0xff160020 0x0 0x10>;
+		#pwm-cells = <3>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pwm10_pin>;
+		clocks = <&cru SCLK_PWM2>, <&cru PCLK_PWM2>;
+		clock-names = "pwm", "pclk";
+		status = "disabled";
+	};
+
+	pwm11: pwm@ff160030 {
+		compatible = "rockchip,rk3308-pwm", "rockchip,rk3328-pwm";
+		reg = <0x0 0xff160030 0x0 0x10>;
+		#pwm-cells = <3>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pwm11_pin>;
+		clocks = <&cru SCLK_PWM2>, <&cru PCLK_PWM2>;
+		clock-names = "pwm", "pclk";
+		status = "disabled";
+	};
+
+	pwm4: pwm@ff170000 {
+		compatible = "rockchip,rk3308-pwm", "rockchip,rk3328-pwm";
+		reg = <0x0 0xff170000 0x0 0x10>;
+		#pwm-cells = <3>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pwm4_pin>;
+		clocks = <&cru SCLK_PWM1>, <&cru PCLK_PWM1>;
+		clock-names = "pwm", "pclk";
+		status = "disabled";
+	};
+
+	pwm5: pwm@ff170010 {
+		compatible = "rockchip,rk3308-pwm", "rockchip,rk3328-pwm";
+		reg = <0x0 0xff170010 0x0 0x10>;
+		#pwm-cells = <3>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pwm5_pin>;
+		clocks = <&cru SCLK_PWM1>, <&cru PCLK_PWM1>;
+		clock-names = "pwm", "pclk";
+		status = "disabled";
+	};
+
+	pwm6: pwm@ff170020 {
+		compatible = "rockchip,rk3308-pwm", "rockchip,rk3328-pwm";
+		reg = <0x0 0xff170020 0x0 0x10>;
+		#pwm-cells = <3>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pwm6_pin>;
+		clocks = <&cru SCLK_PWM1>, <&cru PCLK_PWM1>;
+		clock-names = "pwm", "pclk";
+		status = "disabled";
+	};
+
+	pwm7: pwm@ff170030 {
+		compatible = "rockchip,rk3308-pwm", "rockchip,rk3328-pwm";
+		reg = <0x0 0xff170030 0x0 0x10>;
+		#pwm-cells = <3>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pwm7_pin>;
+		clocks = <&cru SCLK_PWM1>, <&cru PCLK_PWM1>;
+		clock-names = "pwm", "pclk";
+		status = "disabled";
+	};
+
+	pwm0: pwm@ff180000 {
+		compatible = "rockchip,rk3308-pwm", "rockchip,rk3328-pwm";
+		reg = <0x0 0xff180000 0x0 0x10>;
+		#pwm-cells = <3>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pwm0_pin>;
+		clocks = <&cru SCLK_PWM0>, <&cru PCLK_PWM0>;
+		clock-names = "pwm", "pclk";
+		status = "disabled";
+	};
+
+	pwm1: pwm@ff180010 {
+		compatible = "rockchip,rk3308-pwm", "rockchip,rk3328-pwm";
+		reg = <0x0 0xff180010 0x0 0x10>;
+		#pwm-cells = <3>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pwm1_pin>;
+		clocks = <&cru SCLK_PWM0>, <&cru PCLK_PWM0>;
+		clock-names = "pwm", "pclk";
+		status = "disabled";
+	};
+
+	pwm2: pwm@ff180020 {
+		compatible = "rockchip,rk3308-pwm", "rockchip,rk3328-pwm";
+		reg = <0x0 0xff180020 0x0 0x10>;
+		#pwm-cells = <3>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pwm2_pin>;
+		clocks = <&cru SCLK_PWM0>, <&cru PCLK_PWM0>;
+		clock-names = "pwm", "pclk";
+		status = "disabled";
+	};
+
+	pwm3: pwm@ff180030 {
+		compatible = "rockchip,rk3308-pwm", "rockchip,rk3328-pwm";
+		reg = <0x0 0xff180030 0x0 0x10>;
+		#pwm-cells = <3>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pwm3_pin>;
+		clocks = <&cru SCLK_PWM0>, <&cru PCLK_PWM0>;
+		clock-names = "pwm", "pclk";
+		status = "disabled";
+	};
+
+	rktimer: rktimer@ff1a0000 {
+		compatible = "rockchip,rk3288-timer";
+		reg = <0x0 0xff1a0000 0x0 0x20>;
+		interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru PCLK_TIMER>, <&cru SCLK_TIMER0>;
+		clock-names = "pclk", "timer";
+	};
+
+	saradc: saradc@ff1e0000 {
+		compatible = "rockchip,rk3308-saradc", "rockchip,rk3399-saradc";
+		reg = <0x0 0xff1e0000 0x0 0x100>;
+		interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+		#io-channel-cells = <1>;
+		clocks = <&cru SCLK_SARADC>, <&cru PCLK_SARADC>;
+		clock-names = "saradc", "apb_pclk";
+		resets = <&cru SRST_SARADC_P>;
+		reset-names = "saradc-apb";
+		status = "disabled";
+	};
+
+	amba {
+		compatible = "arm,amba-bus";
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		dmac0: dma-controller@ff2c0000 {
+			compatible = "arm,pl330", "arm,primecell";
+			reg = <0x0 0xff2c0000 0x0 0x4000>;
+			interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
+			#dma-cells = <1>;
+			clocks = <&cru ACLK_DMAC0>;
+			clock-names = "apb_pclk";
+			peripherals-req-type-burst;
+		};
+
+		dmac1: dma-controller@ff2d0000 {
+			compatible = "arm,pl330", "arm,primecell";
+			reg = <0x0 0xff2d0000 0x0 0x4000>;
+			interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
+			#dma-cells = <1>;
+			clocks = <&cru ACLK_DMAC1>;
+			clock-names = "apb_pclk";
+			peripherals-req-type-burst;
+		};
+	};
+
+	i2s_2ch_0: i2s@ff350000 {
+		compatible = "rockchip,rk3308-i2s", "rockchip,rk3066-i2s";
+		reg = <0x0 0xff350000 0x0 0x1000>;
+		interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru SCLK_I2S0_2CH>, <&cru HCLK_I2S0_2CH>;
+		clock-names = "i2s_clk", "i2s_hclk";
+		dmas = <&dmac1 8>, <&dmac1 9>;
+		dma-names = "tx", "rx";
+		resets = <&cru SRST_I2S0_2CH_M>, <&cru SRST_I2S0_2CH_H>;
+		reset-names = "reset-m", "reset-h";
+		pinctrl-names = "default";
+		pinctrl-0 = <&i2s_2ch_0_sclk
+			     &i2s_2ch_0_lrck
+			     &i2s_2ch_0_sdi
+			     &i2s_2ch_0_sdo>;
+		status = "disabled";
+	};
+
+	i2s_2ch_1: i2s@ff360000 {
+		compatible = "rockchip,rk3308-i2s", "rockchip,rk3066-i2s";
+		reg = <0x0 0xff360000 0x0 0x1000>;
+		interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru SCLK_I2S1_2CH>, <&cru HCLK_I2S1_2CH>;
+		clock-names = "i2s_clk", "i2s_hclk";
+		dmas = <&dmac1 11>;
+		dma-names = "rx";
+		resets = <&cru SRST_I2S1_2CH_M>, <&cru SRST_I2S1_2CH_H>;
+		reset-names = "reset-m", "reset-h";
+		status = "disabled";
+	};
+
+	spdif_tx: spdif-tx@ff3a0000 {
+		compatible = "rockchip,rk3308-spdif", "rockchip,rk3328-spdif";
+		reg = <0x0 0xff3a0000 0x0 0x1000>;
+		interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru SCLK_SPDIF_TX>, <&cru HCLK_SPDIFTX>;
+		clock-names = "mclk", "hclk";
+		dmas = <&dmac1 13>;
+		dma-names = "tx";
+		pinctrl-names = "default";
+		pinctrl-0 = <&spdif_out>;
+		status = "disabled";
+	};
+
+	sdmmc: dwmmc@ff480000 {
+		compatible = "rockchip,rk3308-dw-mshc", "rockchip,rk3288-dw-mshc";
+		reg = <0x0 0xff480000 0x0 0x4000>;
+		max-frequency = <150000000>;
+		bus-width = <4>;
+		clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>,
+			 <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>;
+		clock-names = "biu", "ciu", "ciu-drv", "ciu-sample";
+		fifo-depth = <0x100>;
+		interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_det &sdmmc_bus4>;
+		status = "disabled";
+	};
+
+	emmc: dwmmc@ff490000 {
+		compatible = "rockchip,rk3308-dw-mshc", "rockchip,rk3288-dw-mshc";
+		reg = <0x0 0xff490000 0x0 0x4000>;
+		max-frequency = <150000000>;
+		bus-width = <8>;
+		clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>,
+			 <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>;
+		clock-names = "biu", "ciu", "ciu-drv", "ciu-sample";
+		fifo-depth = <0x100>;
+		interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
+		status = "disabled";
+	};
+
+	sdio: dwmmc@ff4a0000 {
+		compatible = "rockchip,rk3308-dw-mshc", "rockchip,rk3288-dw-mshc";
+		reg = <0x0 0xff4a0000 0x0 0x4000>;
+		max-frequency = <150000000>;
+		bus-width = <4>;
+		clocks = <&cru HCLK_SDIO>, <&cru SCLK_SDIO>,
+			 <&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>;
+		clock-names = "biu", "ciu", "ciu-drv", "ciu-sample";
+		fifo-depth = <0x100>;
+		interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&sdio_bus4 &sdio_cmd &sdio_clk>;
+		status = "disabled";
+	};
+
+	cru: clock-controller@ff500000 {
+		compatible = "rockchip,rk3308-cru";
+		reg = <0x0 0xff500000 0x0 0x1000>;
+		rockchip,grf = <&grf>;
+		#clock-cells = <1>;
+		#reset-cells = <1>;
+	};
+
+	gic: interrupt-controller@ff580000 {
+		compatible = "arm,gic-400";
+		#interrupt-cells = <3>;
+		#address-cells = <0>;
+		interrupt-controller;
+
+		reg = <0x0 0xff581000 0x0 0x1000>,
+		      <0x0 0xff582000 0x0 0x2000>,
+		      <0x0 0xff584000 0x0 0x2000>,
+		      <0x0 0xff586000 0x0 0x2000>;
+		interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	sram: sram@fff80000 {
+		compatible = "mmio-sram";
+		reg = <0x0 0xfff80000 0x0 0x40000>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0 0x0 0xfff80000 0x40000>;
+		/* reserved for ddr dvfs and system suspend/resume */
+		ddr-sram@0 {
+			reg = <0x0 0x8000>;
+		};
+		/* reserved for vad audio buffer */
+		vad_sram: vad-sram@8000 {
+			reg = <0x8000 0x38000>;
+		};
+	};
+
+	pinctrl: pinctrl {
+		compatible = "rockchip,rk3308-pinctrl";
+		rockchip,grf = <&grf>;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+		gpio0: gpio0@ff220000 {
+			compatible = "rockchip,gpio-bank";
+			reg = <0x0 0xff220000 0x0 0x100>;
+			interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cru PCLK_GPIO0>;
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpio1: gpio1@ff230000 {
+			compatible = "rockchip,gpio-bank";
+			reg = <0x0 0xff230000 0x0 0x100>;
+			interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cru PCLK_GPIO1>;
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpio2: gpio2@ff240000 {
+			compatible = "rockchip,gpio-bank";
+			reg = <0x0 0xff240000 0x0 0x100>;
+			interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cru PCLK_GPIO2>;
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpio3: gpio3@ff250000 {
+			compatible = "rockchip,gpio-bank";
+			reg = <0x0 0xff250000 0x0 0x100>;
+			interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cru PCLK_GPIO3>;
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpio4: gpio4@ff260000 {
+			compatible = "rockchip,gpio-bank";
+			reg = <0x0 0xff260000 0x0 0x100>;
+			interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cru PCLK_GPIO4>;
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		pcfg_pull_up: pcfg-pull-up {
+			bias-pull-up;
+		};
+
+		pcfg_pull_down: pcfg-pull-down {
+			bias-pull-down;
+		};
+
+		pcfg_pull_none: pcfg-pull-none {
+			bias-disable;
+		};
+
+		pcfg_pull_none_2ma: pcfg-pull-none-2ma {
+			bias-disable;
+			drive-strength = <2>;
+		};
+
+		pcfg_pull_up_2ma: pcfg-pull-up-2ma {
+			bias-pull-up;
+			drive-strength = <2>;
+		};
+
+		pcfg_pull_up_4ma: pcfg-pull-up-4ma {
+			bias-pull-up;
+			drive-strength = <4>;
+		};
+
+		pcfg_pull_none_4ma: pcfg-pull-none-4ma {
+			bias-disable;
+			drive-strength = <4>;
+		};
+
+		pcfg_pull_down_4ma: pcfg-pull-down-4ma {
+			bias-pull-down;
+			drive-strength = <4>;
+		};
+
+		pcfg_pull_none_8ma: pcfg-pull-none-8ma {
+			bias-disable;
+			drive-strength = <8>;
+		};
+
+		pcfg_pull_up_8ma: pcfg-pull-up-8ma {
+			bias-pull-up;
+			drive-strength = <8>;
+		};
+
+		pcfg_pull_none_12ma: pcfg-pull-none-12ma {
+			bias-disable;
+			drive-strength = <12>;
+		};
+
+		pcfg_pull_up_12ma: pcfg-pull-up-12ma {
+			bias-pull-up;
+			drive-strength = <12>;
+		};
+
+		pcfg_pull_none_smt: pcfg-pull-none-smt {
+			bias-disable;
+			input-schmitt-enable;
+		};
+
+		pcfg_output_high: pcfg-output-high {
+			output-high;
+		};
+
+		pcfg_output_low: pcfg-output-low {
+			output-low;
+		};
+
+		pcfg_input_high: pcfg-input-high {
+			bias-pull-up;
+			input-enable;
+		};
+
+		pcfg_input: pcfg-input {
+			input-enable;
+		};
+
+		i2c0 {
+			i2c0_xfer: i2c0-xfer {
+				rockchip,pins =
+					<1 RK_PD0 2 &pcfg_pull_none_smt>,
+					<1 RK_PD1 2 &pcfg_pull_none_smt>;
+			};
+		};
+
+		i2c1 {
+			i2c1_xfer: i2c1-xfer {
+				rockchip,pins =
+					<0 RK_PB3 1 &pcfg_pull_none_smt>,
+					<0 RK_PB4 1 &pcfg_pull_none_smt>;
+			};
+		};
+
+		i2c2 {
+			i2c2_xfer: i2c2-xfer {
+				rockchip,pins =
+					<2 RK_PA2 3 &pcfg_pull_none_smt>,
+					<2 RK_PA3 3 &pcfg_pull_none_smt>;
+			};
+		};
+
+		i2c3-m0 {
+			i2c3m0_xfer: i2c3m0-xfer {
+				rockchip,pins =
+					<0 RK_PB7 2 &pcfg_pull_none_smt>,
+					<0 RK_PC0 2 &pcfg_pull_none_smt>;
+			};
+		};
+
+		i2c3-m1 {
+			i2c3m1_xfer: i2c3m1-xfer {
+				rockchip,pins =
+					<3 RK_PB4 2 &pcfg_pull_none_smt>,
+					<3 RK_PB5 2 &pcfg_pull_none_smt>;
+			};
+		};
+
+		i2c3-m2 {
+			i2c3m2_xfer: i2c3m2-xfer {
+				rockchip,pins =
+					<2 RK_PA1 3 &pcfg_pull_none_smt>,
+					<2 RK_PA0 3 &pcfg_pull_none_smt>;
+			};
+		};
+
+		i2s_2ch_0 {
+			i2s_2ch_0_mclk: i2s-2ch-0-mclk {
+				rockchip,pins =
+					<4 RK_PB4 1 &pcfg_pull_none>;
+			};
+
+			i2s_2ch_0_sclk: i2s-2ch-0-sclk {
+				rockchip,pins =
+					<4 RK_PB5 1 &pcfg_pull_none>;
+			};
+
+			i2s_2ch_0_lrck: i2s-2ch-0-lrck {
+				rockchip,pins =
+					<4 RK_PB6 1 &pcfg_pull_none>;
+			};
+
+			i2s_2ch_0_sdo: i2s-2ch-0-sdo {
+				rockchip,pins =
+					<4 RK_PB7 1 &pcfg_pull_none>;
+			};
+
+			i2s_2ch_0_sdi: i2s-2ch-0-sdi {
+				rockchip,pins =
+					<4 RK_PC0 1 &pcfg_pull_none>;
+			};
+		};
+
+		i2s_8ch_0 {
+			i2s_8ch_0_mclk: i2s-8ch-0-mclk {
+				rockchip,pins =
+					<2 RK_PA4 1 &pcfg_pull_none>;
+			};
+
+			i2s_8ch_0_sclktx: i2s-8ch-0-sclktx {
+				rockchip,pins =
+					<2 RK_PA5 1 &pcfg_pull_none>;
+			};
+
+			i2s_8ch_0_sclkrx: i2s-8ch-0-sclkrx {
+				rockchip,pins =
+					<2 RK_PA6 1 &pcfg_pull_none>;
+			};
+
+			i2s_8ch_0_lrcktx: i2s-8ch-0-lrcktx {
+				rockchip,pins =
+					<2 RK_PA7 1 &pcfg_pull_none>;
+			};
+
+			i2s_8ch_0_lrckrx: i2s-8ch-0-lrckrx {
+				rockchip,pins =
+					<2 RK_PB0 1 &pcfg_pull_none>;
+			};
+
+			i2s_8ch_0_sdo0: i2s-8ch-0-sdo0 {
+				rockchip,pins =
+					<2 RK_PB1 1 &pcfg_pull_none>;
+			};
+
+			i2s_8ch_0_sdo1: i2s-8ch-0-sdo1 {
+				rockchip,pins =
+					<2 RK_PB2 1 &pcfg_pull_none>;
+			};
+
+			i2s_8ch_0_sdo2: i2s-8ch-0-sdo2 {
+				rockchip,pins =
+					<2 RK_PB3 1 &pcfg_pull_none>;
+			};
+
+			i2s_8ch_0_sdo3: i2s-8ch-0-sdo3 {
+				rockchip,pins =
+					<2 RK_PB4 1 &pcfg_pull_none>;
+			};
+
+			i2s_8ch_0_sdi0: i2s-8ch-0-sdi0 {
+				rockchip,pins =
+					<2 RK_PB5 1 &pcfg_pull_none>;
+			};
+
+			i2s_8ch_0_sdi1: i2s-8ch-0-sdi1 {
+				rockchip,pins =
+					<2 RK_PB6 1 &pcfg_pull_none>;
+			};
+
+			i2s_8ch_0_sdi2: i2s-8ch-0-sdi2 {
+				rockchip,pins =
+					<2 RK_PB7 1 &pcfg_pull_none>;
+			};
+
+			i2s_8ch_0_sdi3: i2s-8ch-0-sdi3 {
+				rockchip,pins =
+					<2 RK_PC0 1 &pcfg_pull_none>;
+			};
+		};
+
+		i2s_8ch_1_m0 {
+			i2s_8ch_1_m0_mclk: i2s-8ch-1-m0-mclk {
+				rockchip,pins =
+					<1 RK_PA2 2 &pcfg_pull_none>;
+			};
+
+			i2s_8ch_1_m0_sclktx: i2s-8ch-1-m0-sclktx {
+				rockchip,pins =
+					<1 RK_PA3 2 &pcfg_pull_none>;
+			};
+
+			i2s_8ch_1_m0_sclkrx: i2s-8ch-1-m0-sclkrx {
+				rockchip,pins =
+					<1 RK_PA4 2 &pcfg_pull_none>;
+			};
+
+			i2s_8ch_1_m0_lrcktx: i2s-8ch-1-m0-lrcktx {
+				rockchip,pins =
+					<1 RK_PA5 2 &pcfg_pull_none>;
+			};
+
+			i2s_8ch_1_m0_lrckrx: i2s-8ch-1-m0-lrckrx {
+				rockchip,pins =
+					<1 RK_PA6 2 &pcfg_pull_none>;
+			};
+
+			i2s_8ch_1_m0_sdo0: i2s-8ch-1-m0-sdo0 {
+				rockchip,pins =
+					<1 RK_PA7 2 &pcfg_pull_none>;
+			};
+
+			i2s_8ch_1_m0_sdo1_sdi3: i2s-8ch-1-m0-sdo1-sdi3 {
+				rockchip,pins =
+					<1 RK_PB0 2 &pcfg_pull_none>;
+			};
+
+			i2s_8ch_1_m0_sdo2_sdi2: i2s-8ch-1-m0-sdo2-sdi2 {
+				rockchip,pins =
+					<1 RK_PB1 2 &pcfg_pull_none>;
+			};
+
+			i2s_8ch_1_m0_sdo3_sdi1: i2s-8ch-1-m0-sdo3_sdi1 {
+				rockchip,pins =
+					<1 RK_PB2 2 &pcfg_pull_none>;
+			};
+
+			i2s_8ch_1_m0_sdi0: i2s-8ch-1-m0-sdi0 {
+				rockchip,pins =
+					<1 RK_PB3 2 &pcfg_pull_none>;
+			};
+		};
+
+		i2s_8ch_1_m1 {
+			i2s_8ch_1_m1_mclk: i2s-8ch-1-m1-mclk {
+				rockchip,pins =
+					<1 RK_PB4 2 &pcfg_pull_none>;
+			};
+
+			i2s_8ch_1_m1_sclktx: i2s-8ch-1-m1-sclktx {
+				rockchip,pins =
+					<1 RK_PB5 2 &pcfg_pull_none>;
+			};
+
+			i2s_8ch_1_m1_sclkrx: i2s-8ch-1-m1-sclkrx {
+				rockchip,pins =
+					<1 RK_PB6 2 &pcfg_pull_none>;
+			};
+
+			i2s_8ch_1_m1_lrcktx: i2s-8ch-1-m1-lrcktx {
+				rockchip,pins =
+					<1 RK_PB7 2 &pcfg_pull_none>;
+			};
+
+			i2s_8ch_1_m1_lrckrx: i2s-8ch-1-m1-lrckrx {
+				rockchip,pins =
+					<1 RK_PC0 2 &pcfg_pull_none>;
+			};
+
+			i2s_8ch_1_m1_sdo0: i2s-8ch-1-m1-sdo0 {
+				rockchip,pins =
+					<1 RK_PC1 2 &pcfg_pull_none>;
+			};
+
+			i2s_8ch_1_m1_sdo1_sdi3: i2s-8ch-1-m1-sdo1-sdi3 {
+				rockchip,pins =
+					<1 RK_PC2 2 &pcfg_pull_none>;
+			};
+
+			i2s_8ch_1_m1_sdo2_sdi2: i2s-8ch-1-m1-sdo2-sdi2 {
+				rockchip,pins =
+					<1 RK_PC3 2 &pcfg_pull_none>;
+			};
+
+			i2s_8ch_1_m1_sdo3_sdi1: i2s-8ch-1-m1-sdo3_sdi1 {
+				rockchip,pins =
+					<1 RK_PC4 2 &pcfg_pull_none>;
+			};
+
+			i2s_8ch_1_m1_sdi0: i2s-8ch-1-m1-sdi0 {
+				rockchip,pins =
+					<1 RK_PC5 2 &pcfg_pull_none>;
+			};
+		};
+
+		pdm_m0 {
+			pdm_m0_clk: pdm-m0-clk {
+				rockchip,pins =
+					<1 RK_PA4 3 &pcfg_pull_none>;
+			};
+
+			pdm_m0_sdi0: pdm-m0-sdi0 {
+				rockchip,pins =
+					<1 RK_PB3 3 &pcfg_pull_none>;
+			};
+
+			pdm_m0_sdi1: pdm-m0-sdi1 {
+				rockchip,pins =
+					<1 RK_PB2 3 &pcfg_pull_none>;
+			};
+
+			pdm_m0_sdi2: pdm-m0-sdi2 {
+				rockchip,pins =
+					<1 RK_PB1 3 &pcfg_pull_none>;
+			};
+
+			pdm_m0_sdi3: pdm-m0-sdi3 {
+				rockchip,pins =
+					<1 RK_PB0 3 &pcfg_pull_none>;
+			};
+		};
+
+		pdm_m1 {
+			pdm_m1_clk: pdm-m1-clk {
+				rockchip,pins =
+					<1 RK_PB6 4 &pcfg_pull_none>;
+			};
+
+			pdm_m1_sdi0: pdm-m1-sdi0 {
+				rockchip,pins =
+					<1 RK_PC5 4 &pcfg_pull_none>;
+			};
+
+			pdm_m1_sdi1: pdm-m1-sdi1 {
+				rockchip,pins =
+					<1 RK_PC4 4 &pcfg_pull_none>;
+			};
+
+			pdm_m1_sdi2: pdm-m1-sdi2 {
+				rockchip,pins =
+					<1 RK_PC3 4 &pcfg_pull_none>;
+			};
+
+			pdm_m1_sdi3: pdm-m1-sdi3 {
+				rockchip,pins =
+					<1 RK_PC2 4 &pcfg_pull_none>;
+			};
+		};
+
+		pdm_m2 {
+			pdm_m2_clkm: pdm-m2-clkm {
+				rockchip,pins =
+					<2 RK_PA4 3 &pcfg_pull_none>;
+			};
+
+			pdm_m2_clk: pdm-m2-clk {
+				rockchip,pins =
+					<2 RK_PA6 2 &pcfg_pull_none>;
+			};
+
+			pdm_m2_sdi0: pdm-m2-sdi0 {
+				rockchip,pins =
+					<2 RK_PB5 2 &pcfg_pull_none>;
+			};
+
+			pdm_m2_sdi1: pdm-m2-sdi1 {
+				rockchip,pins =
+					<2 RK_PB6 2 &pcfg_pull_none>;
+			};
+
+			pdm_m2_sdi2: pdm-m2-sdi2 {
+				rockchip,pins =
+					<2 RK_PB7 2 &pcfg_pull_none>;
+			};
+
+			pdm_m2_sdi3: pdm-m2-sdi3 {
+				rockchip,pins =
+					<2 RK_PC0 2 &pcfg_pull_none>;
+			};
+		};
+
+		spdif_in {
+			spdif_in: spdif-in {
+				rockchip,pins =
+					<0 RK_PC2 1 &pcfg_pull_none>;
+			};
+		};
+
+		spdif_out {
+			spdif_out: spdif-out {
+				rockchip,pins =
+					<0 RK_PC1 1 &pcfg_pull_none>;
+			};
+		};
+
+		tsadc {
+			tsadc_otp_gpio: tsadc-otp-gpio {
+				rockchip,pins =
+					<0 RK_PB2 0 &pcfg_pull_none>;
+			};
+
+			tsadc_otp_out: tsadc-otp-out {
+				rockchip,pins =
+					<0 RK_PB2 1 &pcfg_pull_none>;
+			};
+		};
+
+		uart0 {
+			uart0_xfer: uart0-xfer {
+				rockchip,pins =
+					<2 RK_PA1 1 &pcfg_pull_up>,
+					<2 RK_PA0 1 &pcfg_pull_up>;
+			};
+
+			uart0_cts: uart0-cts {
+				rockchip,pins =
+					<2 RK_PA2 1 &pcfg_pull_none>;
+			};
+
+			uart0_rts: uart0-rts {
+				rockchip,pins =
+					<2 RK_PA3 1 &pcfg_pull_none>;
+			};
+
+			uart0_rts_gpio: uart0-rts-gpio {
+				rockchip,pins =
+					<2 RK_PA3 0 &pcfg_pull_none>;
+			};
+		};
+
+		uart1 {
+			uart1_xfer: uart1-xfer {
+				rockchip,pins =
+					<1 RK_PD1 1 &pcfg_pull_up>,
+					<1 RK_PD0 1 &pcfg_pull_up>;
+			};
+
+			uart1_cts: uart1-cts {
+				rockchip,pins =
+					<1 RK_PC6 1 &pcfg_pull_none>;
+			};
+
+			uart1_rts: uart1-rts {
+				rockchip,pins =
+					<1 RK_PC7 1 &pcfg_pull_none>;
+			};
+		};
+
+		uart2-m0 {
+			uart2m0_xfer: uart2m0-xfer {
+				rockchip,pins =
+					<1 RK_PC7 2 &pcfg_pull_up>,
+					<1 RK_PC6 2 &pcfg_pull_up>;
+			};
+		};
+
+		uart2-m1 {
+			uart2m1_xfer: uart2m1-xfer {
+				rockchip,pins =
+					<4 RK_PD3 2 &pcfg_pull_up>,
+					<4 RK_PD2 2 &pcfg_pull_up>;
+			};
+		};
+
+		uart3 {
+			uart3_xfer: uart3-xfer {
+				rockchip,pins =
+					<3 RK_PB5 4 &pcfg_pull_up>,
+					<3 RK_PB4 4 &pcfg_pull_up>;
+			};
+		};
+
+		uart3-m1 {
+			uart3m1_xfer: uart3m1-xfer {
+				rockchip,pins =
+					<0 RK_PC2 3 &pcfg_pull_up>,
+					<0 RK_PC1 3 &pcfg_pull_up>;
+			};
+		};
+
+		uart4 {
+
+			uart4_xfer: uart4-xfer {
+				rockchip,pins =
+					<4 RK_PB1 1 &pcfg_pull_up>,
+					<4 RK_PB0 1 &pcfg_pull_up>;
+			};
+
+			uart4_cts: uart4-cts {
+				rockchip,pins =
+					<4 RK_PA6 1 &pcfg_pull_none>;
+
+			};
+
+			uart4_rts: uart4-rts {
+				rockchip,pins =
+					<4 RK_PA7 1 &pcfg_pull_none>;
+			};
+
+			uart4_rts_gpio: uart4-rts-gpio {
+				rockchip,pins =
+					<4 RK_PA7 0 &pcfg_pull_none>;
+			};
+		};
+
+		spi0 {
+			spi0_clk: spi0-clk {
+				rockchip,pins =
+					<2 RK_PA2 2 &pcfg_pull_up_4ma>;
+			};
+
+			spi0_csn0: spi0-csn0 {
+				rockchip,pins =
+					<2 RK_PA3 2 &pcfg_pull_up_4ma>;
+			};
+
+			spi0_miso: spi0-miso {
+				rockchip,pins =
+					<2 RK_PA0 2 &pcfg_pull_up_4ma>;
+			};
+
+			spi0_mosi: spi0-mosi {
+				rockchip,pins =
+					<2 RK_PA1 2 &pcfg_pull_up_4ma>;
+			};
+
+			spi0_clk_hs: spi0-clk-hs {
+				rockchip,pins =
+					<2 RK_PA2 2 &pcfg_pull_up_8ma>;
+			};
+
+			spi0_miso_hs: spi0-miso-hs {
+				rockchip,pins =
+					<2 RK_PA0 2 &pcfg_pull_up_8ma>;
+			};
+
+			spi0_mosi_hs: spi0-mosi-hs {
+				rockchip,pins =
+					<2 RK_PA1 2 &pcfg_pull_up_8ma>;
+			};
+
+		};
+
+		spi1 {
+			spi1_clk: spi1-clk {
+				rockchip,pins =
+					<3 RK_PB3 3 &pcfg_pull_up_4ma>;
+			};
+
+			spi1_csn0: spi1-csn0 {
+				rockchip,pins =
+					<3 RK_PB5 3 &pcfg_pull_up_4ma>;
+			};
+
+			spi1_miso: spi1-miso {
+				rockchip,pins =
+					<3 RK_PB2 3 &pcfg_pull_up_4ma>;
+			};
+
+			spi1_mosi: spi1-mosi {
+				rockchip,pins =
+					<3 RK_PB4 3 &pcfg_pull_up_4ma>;
+			};
+
+			spi1_clk_hs: spi1-clk-hs {
+				rockchip,pins =
+					<3 RK_PB3 3 &pcfg_pull_up_8ma>;
+			};
+
+			spi1_miso_hs: spi1-miso-hs {
+				rockchip,pins =
+					<3 RK_PB2 3 &pcfg_pull_up_8ma>;
+			};
+
+			spi1_mosi_hs: spi1-mosi-hs {
+				rockchip,pins =
+					<3 RK_PB4 3 &pcfg_pull_up_8ma>;
+			};
+		};
+
+		spi1-m1 {
+			spi1m1_miso: spi1m1-miso {
+				rockchip,pins =
+					<2 RK_PA4 2 &pcfg_pull_up_4ma>;
+			};
+
+			spi1m1_mosi: spi1m1-mosi {
+				rockchip,pins =
+					<2 RK_PA5 2 &pcfg_pull_up_4ma>;
+			};
+
+			spi1m1_clk: spi1m1-clk {
+				rockchip,pins =
+					<2 RK_PA7 2 &pcfg_pull_up_4ma>;
+			};
+
+			spi1m1_csn0: spi1m1-csn0 {
+				rockchip,pins =
+					<2 RK_PB1 2 &pcfg_pull_up_4ma>;
+			};
+
+			spi1m1_miso_hs: spi1m1-miso-hs {
+				rockchip,pins =
+					<2 RK_PA4 2 &pcfg_pull_up_8ma>;
+			};
+
+			spi1m1_mosi_hs: spi1m1-mosi-hs {
+				rockchip,pins =
+					<2 RK_PA5 2 &pcfg_pull_up_8ma>;
+			};
+
+			spi1m1_clk_hs: spi1m1-clk-hs {
+				rockchip,pins =
+					<2 RK_PA7 2 &pcfg_pull_up_8ma>;
+			};
+
+			spi1m1_csn0_hs: spi1m1-csn0-hs {
+				rockchip,pins =
+					<2 RK_PB1 2 &pcfg_pull_up_8ma>;
+			};
+		};
+
+		spi2 {
+			spi2_clk: spi2-clk {
+				rockchip,pins =
+					<1 RK_PD0 3 &pcfg_pull_up_4ma>;
+			};
+
+			spi2_csn0: spi2-csn0 {
+				rockchip,pins =
+					<1 RK_PD1 3 &pcfg_pull_up_4ma>;
+			};
+
+			spi2_miso: spi2-miso {
+				rockchip,pins =
+					<1 RK_PC6 3 &pcfg_pull_up_4ma>;
+			};
+
+			spi2_mosi: spi2-mosi {
+				rockchip,pins =
+					<1 RK_PC7 3 &pcfg_pull_up_4ma>;
+			};
+
+			spi2_clk_hs: spi2-clk-hs {
+				rockchip,pins =
+					<1 RK_PD0 3 &pcfg_pull_up_8ma>;
+			};
+
+			spi2_miso_hs: spi2-miso-hs {
+				rockchip,pins =
+					<1 RK_PC6 3 &pcfg_pull_up_8ma>;
+			};
+
+			spi2_mosi_hs: spi2-mosi-hs {
+				rockchip,pins =
+					<1 RK_PC7 3 &pcfg_pull_up_8ma>;
+			};
+		};
+
+		sdmmc {
+			sdmmc_clk: sdmmc-clk {
+				rockchip,pins =
+					<4 RK_PD5 1 &pcfg_pull_none_4ma>;
+			};
+
+			sdmmc_cmd: sdmmc-cmd {
+				rockchip,pins =
+					<4 RK_PD4 1 &pcfg_pull_up_4ma>;
+			};
+
+			sdmmc_det: sdmmc-det {
+				rockchip,pins =
+					<0 RK_PA3 1 &pcfg_pull_up_4ma>;
+			};
+
+			sdmmc_pwren: sdmmc-pwren {
+				rockchip,pins =
+					<4 RK_PD6 1 &pcfg_pull_none_4ma>;
+			};
+
+			sdmmc_bus1: sdmmc-bus1 {
+				rockchip,pins =
+					<4 RK_PD0 1 &pcfg_pull_up_4ma>;
+			};
+
+			sdmmc_bus4: sdmmc-bus4 {
+				rockchip,pins =
+					<4 RK_PD0 1 &pcfg_pull_up_4ma>,
+					<4 RK_PD1 1 &pcfg_pull_up_4ma>,
+					<4 RK_PD2 1 &pcfg_pull_up_4ma>,
+					<4 RK_PD3 1 &pcfg_pull_up_4ma>;
+			};
+
+			sdmmc_gpio: sdmmc-gpio {
+				rockchip,pins =
+					<4 RK_PD0 0 &pcfg_pull_up_4ma>,
+					<4 RK_PD1 0 &pcfg_pull_up_4ma>,
+					<4 RK_PD2 0 &pcfg_pull_up_4ma>,
+					<4 RK_PD3 0 &pcfg_pull_up_4ma>,
+					<4 RK_PD4 0 &pcfg_pull_up_4ma>,
+					<4 RK_PD5 0 &pcfg_pull_up_4ma>,
+					<4 RK_PD6 0 &pcfg_pull_up_4ma>;
+			};
+		};
+
+		sdio {
+			sdio_clk: sdio-clk {
+				rockchip,pins =
+					<4 RK_PA5 1 &pcfg_pull_none_8ma>;
+			};
+
+			sdio_cmd: sdio-cmd {
+				rockchip,pins =
+					<4 RK_PA4 1 &pcfg_pull_up_8ma>;
+			};
+
+			sdio_pwren: sdio-pwren {
+				rockchip,pins =
+					<0 RK_PA2 1 &pcfg_pull_none_8ma>;
+			};
+
+			sdio_wrpt: sdio-wrpt {
+				rockchip,pins =
+					<0 RK_PA1 1 &pcfg_pull_none_8ma>;
+			};
+
+			sdio_intn: sdio-intn {
+				rockchip,pins =
+					<0 RK_PA0 1 &pcfg_pull_none_8ma>;
+			};
+
+			sdio_bus1: sdio-bus1 {
+				rockchip,pins =
+					<4 RK_PA0 1 &pcfg_pull_up_8ma>;
+			};
+
+			sdio_bus4: sdio-bus4 {
+				rockchip,pins =
+					<4 RK_PA0 1 &pcfg_pull_up_8ma>,
+					<4 RK_PA1 1 &pcfg_pull_up_8ma>,
+					<4 RK_PA2 1 &pcfg_pull_up_8ma>,
+					<4 RK_PA3 1 &pcfg_pull_up_8ma>;
+			};
+
+			sdio_gpio: sdio-gpio {
+				rockchip,pins =
+					<4 RK_PA0 0 &pcfg_pull_up_4ma>,
+					<4 RK_PA1 0 &pcfg_pull_up_4ma>,
+					<4 RK_PA2 0 &pcfg_pull_up_4ma>,
+					<4 RK_PA3 0 &pcfg_pull_up_4ma>,
+					<4 RK_PA4 0 &pcfg_pull_up_4ma>,
+					<4 RK_PA5 0 &pcfg_pull_up_4ma>;
+			};
+		};
+
+		emmc {
+			emmc_clk: emmc-clk {
+				rockchip,pins =
+					<3 RK_PB1 2 &pcfg_pull_none_8ma>;
+			};
+
+			emmc_cmd: emmc-cmd {
+				rockchip,pins =
+					<3 RK_PB0 2 &pcfg_pull_up_8ma>;
+			};
+
+			emmc_pwren: emmc-pwren {
+				rockchip,pins =
+					<3 RK_PB3 2 &pcfg_pull_none>;
+			};
+
+			emmc_rstn: emmc-rstn {
+				rockchip,pins =
+					<3 RK_PB2 2 &pcfg_pull_none>;
+			};
+
+			emmc_bus1: emmc-bus1 {
+				rockchip,pins =
+					<3 RK_PA0 2 &pcfg_pull_up_8ma>;
+			};
+
+			emmc_bus4: emmc-bus4 {
+				rockchip,pins =
+					<3 RK_PA0 2 &pcfg_pull_up_8ma>,
+					<3 RK_PA1 2 &pcfg_pull_up_8ma>,
+					<3 RK_PA2 2 &pcfg_pull_up_8ma>,
+					<3 RK_PA3 2 &pcfg_pull_up_8ma>;
+			};
+
+			emmc_bus8: emmc-bus8 {
+				rockchip,pins =
+					<3 RK_PA0 2 &pcfg_pull_up_8ma>,
+					<3 RK_PA1 2 &pcfg_pull_up_8ma>,
+					<3 RK_PA2 2 &pcfg_pull_up_8ma>,
+					<3 RK_PA3 2 &pcfg_pull_up_8ma>,
+					<3 RK_PA4 2 &pcfg_pull_up_8ma>,
+					<3 RK_PA5 2 &pcfg_pull_up_8ma>,
+					<3 RK_PA6 2 &pcfg_pull_up_8ma>,
+					<3 RK_PA7 2 &pcfg_pull_up_8ma>;
+			};
+		};
+
+		flash {
+			flash_csn0: flash-csn0 {
+				rockchip,pins =
+					<3 RK_PB5 1 &pcfg_pull_none>;
+			};
+
+			flash_rdy: flash-rdy {
+				rockchip,pins =
+					<3 RK_PB4 1 &pcfg_pull_none>;
+			};
+
+			flash_ale: flash-ale {
+				rockchip,pins =
+					<3 RK_PB3 1 &pcfg_pull_none>;
+			};
+
+			flash_cle: flash-cle {
+				rockchip,pins =
+					<3 RK_PB1 1 &pcfg_pull_none>;
+			};
+
+			flash_wrn: flash-wrn {
+				rockchip,pins =
+					<3 RK_PB0 1 &pcfg_pull_none>;
+			};
+
+			flash_rdn: flash-rdn {
+				rockchip,pins =
+					<3 RK_PB2 1 &pcfg_pull_none>;
+			};
+
+			flash_bus8: flash-bus8 {
+				rockchip,pins =
+					<3 RK_PA0 1 &pcfg_pull_up_12ma>,
+					<3 RK_PA1 1 &pcfg_pull_up_12ma>,
+					<3 RK_PA2 1 &pcfg_pull_up_12ma>,
+					<3 RK_PA3 1 &pcfg_pull_up_12ma>,
+					<3 RK_PA4 1 &pcfg_pull_up_12ma>,
+					<3 RK_PA5 1 &pcfg_pull_up_12ma>,
+					<3 RK_PA6 1 &pcfg_pull_up_12ma>,
+					<3 RK_PA7 1 &pcfg_pull_up_12ma>;
+			};
+		};
+
+		pwm0 {
+			pwm0_pin: pwm0-pin {
+				rockchip,pins =
+					<0 RK_PB5 1 &pcfg_pull_none>;
+			};
+
+			pwm0_pin_pull_down: pwm0-pin-pull-down {
+				rockchip,pins =
+					<0 RK_PB5 1 &pcfg_pull_down>;
+			};
+		};
+
+		pwm1 {
+			pwm1_pin: pwm1-pin {
+				rockchip,pins =
+					<0 RK_PB6 1 &pcfg_pull_none>;
+			};
+
+			pwm1_pin_pull_down: pwm1-pin-pull-down {
+				rockchip,pins =
+					<0 RK_PB6 1 &pcfg_pull_down>;
+			};
+		};
+
+		pwm2 {
+			pwm2_pin: pwm2-pin {
+				rockchip,pins =
+					<0 RK_PB7 1 &pcfg_pull_none>;
+			};
+
+			pwm2_pin_pull_down: pwm2-pin-pull-down {
+				rockchip,pins =
+					<0 RK_PB7 1 &pcfg_pull_down>;
+			};
+		};
+
+		pwm3 {
+			pwm3_pin: pwm3-pin {
+				rockchip,pins =
+					<0 RK_PC0 1 &pcfg_pull_none>;
+			};
+
+			pwm3_pin_pull_down: pwm3-pin-pull-down {
+				rockchip,pins =
+					<0 RK_PC0 1 &pcfg_pull_down>;
+			};
+		};
+
+		pwm4 {
+			pwm4_pin: pwm4-pin {
+				rockchip,pins =
+					<0 RK_PA1 2 &pcfg_pull_none>;
+			};
+
+			pwm4_pin_pull_down: pwm4-pin-pull-down {
+				rockchip,pins =
+					<0 RK_PA1 2 &pcfg_pull_down>;
+			};
+		};
+
+		pwm5 {
+			pwm5_pin: pwm5-pin {
+				rockchip,pins =
+					<0 RK_PC1 2 &pcfg_pull_none>;
+			};
+
+			pwm5_pin_pull_down: pwm5-pin-pull-down {
+				rockchip,pins =
+					<0 RK_PC1 2 &pcfg_pull_down>;
+			};
+		};
+
+		pwm6 {
+			pwm6_pin: pwm6-pin {
+				rockchip,pins =
+					<0 RK_PC2 2 &pcfg_pull_none>;
+			};
+
+			pwm6_pin_pull_down: pwm6-pin-pull-down {
+				rockchip,pins =
+					<0 RK_PC2 2 &pcfg_pull_down>;
+			};
+		};
+
+		pwm7 {
+			pwm7_pin: pwm7-pin {
+				rockchip,pins =
+					<2 RK_PB0 2 &pcfg_pull_none>;
+			};
+
+			pwm7_pin_pull_down: pwm7-pin-pull-down {
+				rockchip,pins =
+					<2 RK_PB0 2 &pcfg_pull_down>;
+			};
+		};
+
+		pwm8 {
+			pwm8_pin: pwm8-pin {
+				rockchip,pins =
+					<2 RK_PB2 2 &pcfg_pull_none>;
+			};
+
+			pwm8_pin_pull_down: pwm8-pin-pull-down {
+				rockchip,pins =
+					<2 RK_PB2 2 &pcfg_pull_down>;
+			};
+		};
+
+		pwm9 {
+			pwm9_pin: pwm9-pin {
+				rockchip,pins =
+					<2 RK_PB3 2 &pcfg_pull_none>;
+			};
+
+			pwm9_pin_pull_down: pwm9-pin-pull-down {
+				rockchip,pins =
+					<2 RK_PB3 2 &pcfg_pull_down>;
+			};
+		};
+
+		pwm10 {
+			pwm10_pin: pwm10-pin {
+				rockchip,pins =
+					<2 RK_PB4 2 &pcfg_pull_none>;
+			};
+
+			pwm10_pin_pull_down: pwm10-pin-pull-down {
+				rockchip,pins =
+					<2 RK_PB4 2 &pcfg_pull_down>;
+			};
+		};
+
+		pwm11 {
+			pwm11_pin: pwm11-pin {
+				rockchip,pins =
+					<2 RK_PC0 4 &pcfg_pull_none>;
+			};
+
+			pwm11_pin_pull_down: pwm11-pin-pull-down {
+				rockchip,pins =
+					<2 RK_PC0 4 &pcfg_pull_down>;
+			};
+		};
+
+		gmac {
+			rmii_pins: rmii-pins {
+				rockchip,pins =
+					/* mac_txen */
+					<1 RK_PC1 3 &pcfg_pull_none_12ma>,
+					/* mac_txd1 */
+					<1 RK_PC3 3 &pcfg_pull_none_12ma>,
+					/* mac_txd0 */
+					<1 RK_PC2 3 &pcfg_pull_none_12ma>,
+					/* mac_rxd0 */
+					<1 RK_PC4 3 &pcfg_pull_none>,
+					/* mac_rxd1 */
+					<1 RK_PC5 3 &pcfg_pull_none>,
+					/* mac_rxer */
+					<1 RK_PB7 3 &pcfg_pull_none>,
+					/* mac_rxdv */
+					<1 RK_PC0 3 &pcfg_pull_none>,
+					/* mac_mdio */
+					<1 RK_PB6 3 &pcfg_pull_none>,
+					/* mac_mdc */
+					<1 RK_PB5 3 &pcfg_pull_none>;
+			};
+
+			mac_refclk_12ma: mac-refclk-12ma {
+				rockchip,pins =
+					<1 RK_PB4 3 &pcfg_pull_none_12ma>;
+			};
+
+			mac_refclk: mac-refclk {
+				rockchip,pins =
+					<1 RK_PB4 3 &pcfg_pull_none>;
+			};
+		};
+
+		gmac-m1 {
+			rmiim1_pins: rmiim1-pins {
+				rockchip,pins =
+					/* mac_txen */
+					<4 RK_PB7 2 &pcfg_pull_none_12ma>,
+					/* mac_txd1 */
+					<4 RK_PA5 2 &pcfg_pull_none_12ma>,
+					/* mac_txd0 */
+					<4 RK_PA4 2 &pcfg_pull_none_12ma>,
+					/* mac_rxd0 */
+					<4 RK_PA2 2 &pcfg_pull_none>,
+					/* mac_rxd1 */
+					<4 RK_PA3 2 &pcfg_pull_none>,
+					/* mac_rxer */
+					<4 RK_PA0 2 &pcfg_pull_none>,
+					/* mac_rxdv */
+					<4 RK_PA1 2 &pcfg_pull_none>,
+					/* mac_mdio */
+					<4 RK_PB6 2 &pcfg_pull_none>,
+					/* mac_mdc */
+					<4 RK_PB5 2 &pcfg_pull_none>;
+			};
+
+			macm1_refclk_12ma: macm1-refclk-12ma {
+				rockchip,pins =
+					<4 RK_PB4 2 &pcfg_pull_none_12ma>;
+			};
+
+			macm1_refclk: macm1-refclk {
+				rockchip,pins =
+					<4 RK_PB4 2 &pcfg_pull_none>;
+			};
+		};
+
+		rtc {
+			rtc_32k: rtc-32k {
+				rockchip,pins =
+					<0 RK_PC3 1 &pcfg_pull_none>;
+			};
+		};
+
+	};
+};
diff --git a/arch/arm/dts/rk3328-sdram-ddr3-666.dtsi b/arch/arm/dts/rk3328-sdram-ddr3-666.dtsi
index d99e7e0..3e88ed4 100644
--- a/arch/arm/dts/rk3328-sdram-ddr3-666.dtsi
+++ b/arch/arm/dts/rk3328-sdram-ddr3-666.dtsi
@@ -14,6 +14,8 @@
 		0x0
 		0x10
 		0x10
+		0x10
+		0x10
 		0
 
 		0x9028b189
@@ -26,6 +28,8 @@
 
 		333
 		3
+		1
+		0
 		0
 
 		0x00000000
diff --git a/arch/arm/dts/rk3328-sdram-lpddr3-1600.dtsi b/arch/arm/dts/rk3328-sdram-lpddr3-1600.dtsi
index cc0011c..d63c761 100644
--- a/arch/arm/dts/rk3328-sdram-lpddr3-1600.dtsi
+++ b/arch/arm/dts/rk3328-sdram-lpddr3-1600.dtsi
@@ -14,6 +14,8 @@
 		0x0
 		0x10
 		0x10
+		0x10
+		0x10
 		0
 
 		0x98899459
@@ -27,6 +29,8 @@
 		800
 		6
 		1
+		0
+		1
 
 		0x00000000
 		0x43041008
diff --git a/arch/arm/dts/rk3328-sdram-lpddr3-666.dtsi b/arch/arm/dts/rk3328-sdram-lpddr3-666.dtsi
index 62d809e..b9d3b3b 100644
--- a/arch/arm/dts/rk3328-sdram-lpddr3-666.dtsi
+++ b/arch/arm/dts/rk3328-sdram-lpddr3-666.dtsi
@@ -14,6 +14,8 @@
 		0x0
 		0x10
 		0x10
+		0x10
+		0x10
 		0
 
 		0x0c48a18a
@@ -26,6 +28,8 @@
 
 		333
 		6
+		1
+		0
 		0
 
 		0x00000000
diff --git a/arch/arm/dts/rk3399-evb-u-boot.dtsi b/arch/arm/dts/rk3399-evb-u-boot.dtsi
index 20910e7..ccb33d3 100644
--- a/arch/arm/dts/rk3399-evb-u-boot.dtsi
+++ b/arch/arm/dts/rk3399-evb-u-boot.dtsi
@@ -5,3 +5,9 @@
 
 #include "rk3399-u-boot.dtsi"
 #include "rk3399-sdram-lpddr3-4GB-1600.dtsi"
+
+/ {
+	chosen {
+		u-boot,spl-boot-order = &sdhci, &sdmmc;
+	};
+};
diff --git a/arch/arm/dts/rk3399-evb.dts b/arch/arm/dts/rk3399-evb.dts
index a506e8d..8e887f3 100644
--- a/arch/arm/dts/rk3399-evb.dts
+++ b/arch/arm/dts/rk3399-evb.dts
@@ -15,8 +15,6 @@
 
 	chosen {
 		stdout-path = &uart2;
-		u-boot,spl-boot-order = \
-			&sdhci, &sdmmc;
 	};
 
 	vdd_center: vdd-center {
diff --git a/arch/arm/dts/rk3399-firefly-u-boot.dtsi b/arch/arm/dts/rk3399-firefly-u-boot.dtsi
index 67b63a8..38e0897 100644
--- a/arch/arm/dts/rk3399-firefly-u-boot.dtsi
+++ b/arch/arm/dts/rk3399-firefly-u-boot.dtsi
@@ -5,3 +5,9 @@
 
 #include "rk3399-u-boot.dtsi"
 #include "rk3399-sdram-ddr3-1600.dtsi"
+
+/ {
+	chosen {
+		u-boot,spl-boot-order = "same-as-spl", &sdhci, &sdmmc;
+	};
+};
diff --git a/arch/arm/dts/rk3399-firefly.dts b/arch/arm/dts/rk3399-firefly.dts
index a4cb64f..89c67fd 100644
--- a/arch/arm/dts/rk3399-firefly.dts
+++ b/arch/arm/dts/rk3399-firefly.dts
@@ -14,7 +14,6 @@
 
 	chosen {
 		stdout-path = &uart2;
-		u-boot,spl-boot-order = "same-as-spl", &sdhci, &sdmmc;
 	};
 
 	backlight: backlight {
diff --git a/arch/arm/dts/rk3399-khadas-edge-u-boot.dtsi b/arch/arm/dts/rk3399-khadas-edge-u-boot.dtsi
index 35b9fdd..a7039d7 100644
--- a/arch/arm/dts/rk3399-khadas-edge-u-boot.dtsi
+++ b/arch/arm/dts/rk3399-khadas-edge-u-boot.dtsi
@@ -11,3 +11,7 @@
 		u-boot,spl-boot-order = "same-as-spl", &sdhci, &sdmmc;
 	};
 };
+
+&vdd_log {
+	regulator-init-microvolt = <950000>;
+};
diff --git a/arch/arm/dts/rk3399-orangepi-u-boot.dtsi b/arch/arm/dts/rk3399-orangepi-u-boot.dtsi
index 236b61d..d4327ea 100644
--- a/arch/arm/dts/rk3399-orangepi-u-boot.dtsi
+++ b/arch/arm/dts/rk3399-orangepi-u-boot.dtsi
@@ -5,3 +5,7 @@
 
 #include "rk3399-u-boot.dtsi"
 #include "rk3399-sdram-ddr3-1333.dtsi"
+
+&vdd_log {
+	regulator-init-microvolt = <950000>;
+};
diff --git a/arch/arm/dts/rk3399-roc-pc.dts b/arch/arm/dts/rk3399-roc-pc.dts
index 19f7732..257543d 100644
--- a/arch/arm/dts/rk3399-roc-pc.dts
+++ b/arch/arm/dts/rk3399-roc-pc.dts
@@ -57,9 +57,9 @@
 	 * should be placed inside mp8859, but not until mp8859 has
 	 * its own dt-binding.
 	 */
-	vcc12v_sys: mp8859-dcdc1 {
+	dc_12v: mp8859-dcdc1 {
 		compatible = "regulator-fixed";
-		regulator-name = "vcc12v_sys";
+		regulator-name = "dc_12v";
 		regulator-always-on;
 		regulator-boot-on;
 		regulator-min-microvolt = <12000000>;
@@ -85,7 +85,7 @@
 		regulator-boot-on;
 		regulator-min-microvolt = <3300000>;
 		regulator-max-microvolt = <3300000>;
-		vin-supply = <&vcc12v_sys>;
+		vin-supply = <&vcc_sys>;
 	};
 
 	/* Actually 3 regulators (host0, 1, 2) controlled by the same gpio */
@@ -118,7 +118,7 @@
 		regulator-boot-on;
 		regulator-min-microvolt = <5000000>;
 		regulator-max-microvolt = <5000000>;
-		vin-supply = <&vcc12v_sys>;
+		vin-supply = <&dc_12v>;
 	};
 
 	vdd_log: vdd-log {
@@ -129,7 +129,7 @@
 		regulator-boot-on;
 		regulator-min-microvolt = <800000>;
 		regulator-max-microvolt = <1400000>;
-		vin-supply = <&vcc3v3_sys>;
+		vin-supply = <&vcc_sys>;
 	};
 };
 
@@ -202,16 +202,16 @@
 		rockchip,system-power-controller;
 		wakeup-source;
 
-		vcc1-supply = <&vcc3v3_sys>;
-		vcc2-supply = <&vcc3v3_sys>;
-		vcc3-supply = <&vcc3v3_sys>;
-		vcc4-supply = <&vcc3v3_sys>;
-		vcc6-supply = <&vcc3v3_sys>;
-		vcc7-supply = <&vcc3v3_sys>;
+		vcc1-supply = <&vcc_sys>;
+		vcc2-supply = <&vcc_sys>;
+		vcc3-supply = <&vcc_sys>;
+		vcc4-supply = <&vcc_sys>;
+		vcc6-supply = <&vcc_sys>;
+		vcc7-supply = <&vcc_sys>;
 		vcc8-supply = <&vcc3v3_sys>;
-		vcc9-supply = <&vcc3v3_sys>;
-		vcc10-supply = <&vcc3v3_sys>;
-		vcc11-supply = <&vcc3v3_sys>;
+		vcc9-supply = <&vcc_sys>;
+		vcc10-supply = <&vcc_sys>;
+		vcc11-supply = <&vcc_sys>;
 		vcc12-supply = <&vcc3v3_sys>;
 		vddio-supply = <&vcc1v8_pmu>;
 
@@ -385,7 +385,7 @@
 		regulator-ramp-delay = <1000>;
 		regulator-always-on;
 		regulator-boot-on;
-		vin-supply = <&vcc3v3_sys>;
+		vin-supply = <&vcc_sys>;
 
 		regulator-state-mem {
 			regulator-off-in-suspend;
@@ -404,7 +404,7 @@
 		regulator-ramp-delay = <1000>;
 		regulator-always-on;
 		regulator-boot-on;
-		vin-supply = <&vcc3v3_sys>;
+		vin-supply = <&vcc_sys>;
 
 		regulator-state-mem {
 			regulator-off-in-suspend;
diff --git a/arch/arm/dts/rk3399-rock-pi-4-u-boot.dtsi b/arch/arm/dts/rk3399-rock-pi-4-u-boot.dtsi
index 5bd8696..c17e769 100644
--- a/arch/arm/dts/rk3399-rock-pi-4-u-boot.dtsi
+++ b/arch/arm/dts/rk3399-rock-pi-4-u-boot.dtsi
@@ -11,3 +11,7 @@
 		u-boot,spl-boot-order = "same-as-spl", &sdhci, &sdmmc;
 	};
 };
+
+&vdd_log {
+	regulator-init-microvolt = <950000>;
+};
diff --git a/arch/arm/dts/rk3399-rock960-u-boot.dtsi b/arch/arm/dts/rk3399-rock960-u-boot.dtsi
index 4850deb..82f2c31 100644
--- a/arch/arm/dts/rk3399-rock960-u-boot.dtsi
+++ b/arch/arm/dts/rk3399-rock960-u-boot.dtsi
@@ -10,4 +10,17 @@
 	chosen {
 		u-boot,spl-boot-order = &sdhci, &sdmmc;
 	};
+
+	vdd_log: vdd-log {
+		compatible = "pwm-regulator";
+		pwms = <&pwm2 0 25000 1>;
+		regulator-name = "vdd_log";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <800000>;
+		regulator-max-microvolt = <1400000>;
+		regulator-init-microvolt = <950000>;
+		vin-supply = <&vcc5v0_sys>;
+	};
+
 };
diff --git a/arch/arm/dts/rk3399-rockpro64-u-boot.dtsi b/arch/arm/dts/rk3399-rockpro64-u-boot.dtsi
index a073ea2..4648513 100644
--- a/arch/arm/dts/rk3399-rockpro64-u-boot.dtsi
+++ b/arch/arm/dts/rk3399-rockpro64-u-boot.dtsi
@@ -11,6 +11,11 @@
 	};
 };
 
+&vdd_center {
+	regulator-min-microvolt = <950000>;
+	regulator-max-microvolt = <950000>;
+};
+
 &vdd_log {
 	regulator-init-microvolt = <950000>;
 };
diff --git a/arch/arm/dts/rk3399-rockpro64.dts b/arch/arm/dts/rk3399-rockpro64.dts
index 1f2394e..e544deb 100644
--- a/arch/arm/dts/rk3399-rockpro64.dts
+++ b/arch/arm/dts/rk3399-rockpro64.dts
@@ -58,6 +58,13 @@
 		};
 	};
 
+	fan: pwm-fan {
+		compatible = "pwm-fan";
+		#cooling-cells = <2>;
+		fan-supply = <&vcc12v_dcin>;
+		pwms = <&pwm1 0 50000 0>;
+	};
+
 	sdio_pwrseq: sdio-pwrseq {
 		compatible = "mmc-pwrseq-simple";
 		clocks = <&rk808 1>;
@@ -166,7 +173,7 @@
 		regulator-always-on;
 		regulator-boot-on;
 		regulator-min-microvolt = <800000>;
-		regulator-max-microvolt = <1400000>;
+		regulator-max-microvolt = <1700000>;
 		vin-supply = <&vcc5v0_sys>;
 	};
 };
@@ -222,6 +229,10 @@
 	status = "okay";
 };
 
+&hdmi_sound {
+	status = "okay";
+};
+
 &gpu {
 	mali-supply = <&vdd_gpu>;
 	status = "okay";
@@ -236,8 +247,8 @@
 	rk808: pmic@1b {
 		compatible = "rockchip,rk808";
 		reg = <0x1b>;
-		interrupt-parent = <&gpio1>;
-		interrupts = <21 IRQ_TYPE_LEVEL_LOW>;
+		interrupt-parent = <&gpio3>;
+		interrupts = <10 IRQ_TYPE_LEVEL_LOW>;
 		#clock-cells = <1>;
 		clock-output-names = "xin32k", "rk808-clkout2";
 		pinctrl-names = "default";
@@ -504,11 +515,25 @@
 	status = "okay";
 
 	bt656-supply = <&vcc1v8_dvp>;
-	audio-supply = <&vcca1v8_codec>;
+	audio-supply = <&vcc_3v0>;
 	sdmmc-supply = <&vcc_sdio>;
 	gpio1830-supply = <&vcc_3v0>;
 };
 
+&pcie0 {
+	ep-gpios = <&gpio2 RK_PD4 GPIO_ACTIVE_HIGH>;
+	num-lanes = <4>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie_perst>;
+	vpcie12v-supply = <&vcc12v_dcin>;
+	vpcie3v3-supply = <&vcc3v3_pcie>;
+	status = "okay";
+};
+
+&pcie_phy {
+	status = "okay";
+};
+
 &pmu_io_domains {
 	pmu1830-supply = <&vcc_3v0>;
 	status = "okay";
@@ -538,6 +563,10 @@
 	};
 
 	pcie {
+		pcie_perst: pcie-perst {
+			rockchip,pins = <2 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
 		pcie_pwr_en: pcie-pwr-en {
 			rockchip,pins = <1 RK_PD0 RK_FUNC_GPIO &pcfg_pull_none>;
 		};
@@ -545,7 +574,7 @@
 
 	pmic {
 		pmic_int_l: pmic-int-l {
-			rockchip,pins = <1 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>;
+			rockchip,pins = <3 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>;
 		};
 
 		vsel1_gpio: vsel1-gpio {
@@ -580,6 +609,10 @@
 	status = "okay";
 };
 
+&pwm1 {
+	status = "okay";
+};
+
 &pwm2 {
 	status = "okay";
 };
@@ -591,7 +624,6 @@
 
 &sdmmc {
 	bus-width = <4>;
-	cap-mmc-highspeed;
 	cap-sd-highspeed;
 	cd-gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
 	disable-wp;
@@ -603,12 +635,21 @@
 
 &sdhci {
 	bus-width = <8>;
-	mmc-hs400-1_8v;
-	mmc-hs400-enhanced-strobe;
+	mmc-hs200-1_8v;
 	non-removable;
 	status = "okay";
 };
 
+&spi1 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+	};
+};
+
 &tcphy0 {
 	status = "okay";
 };
diff --git a/arch/arm/dts/rk3399-sdram-ddr3-1333.dtsi b/arch/arm/dts/rk3399-sdram-ddr3-1333.dtsi
index 3708bd6..7fae249 100644
--- a/arch/arm/dts/rk3399-sdram-ddr3-1333.dtsi
+++ b/arch/arm/dts/rk3399-sdram-ddr3-1333.dtsi
@@ -13,6 +13,8 @@
 		0x0
 		0xf
 		0xf
+		0xf
+		0xf
 		1
 		0x80120e12
 		0x11030802
@@ -28,6 +30,8 @@
 		0x0
 		0xf
 		0xf
+		0xf
+		0xf
 		1
 		0x80120e12
 		0x11030802
diff --git a/arch/arm/dts/rk3399-sdram-ddr3-1600.dtsi b/arch/arm/dts/rk3399-sdram-ddr3-1600.dtsi
index fcd01f8..23c7c34 100644
--- a/arch/arm/dts/rk3399-sdram-ddr3-1600.dtsi
+++ b/arch/arm/dts/rk3399-sdram-ddr3-1600.dtsi
@@ -13,6 +13,8 @@
 		0x0
 		0xf
 		0xf
+		0xf
+		0xf
 		1
 		0x80151015
 		0x14040902
@@ -28,6 +30,8 @@
 		0x0
 		0xf
 		0xf
+		0xf
+		0xf
 		1
 		0x80151015
 		0x14040902
diff --git a/arch/arm/dts/rk3399-sdram-ddr3-1866.dtsi b/arch/arm/dts/rk3399-sdram-ddr3-1866.dtsi
index c46c199..ea029ca 100644
--- a/arch/arm/dts/rk3399-sdram-ddr3-1866.dtsi
+++ b/arch/arm/dts/rk3399-sdram-ddr3-1866.dtsi
@@ -13,6 +13,8 @@
 		0x0
 		0xf
 		0xf
+		0xf
+		0xf
 		1
 		0x80181219
 		0x17050a03
@@ -28,6 +30,8 @@
 		0x0
 		0xf
 		0xf
+		0xf
+		0xf
 		1
 		0x80181219
 		0x17050a03
diff --git a/arch/arm/dts/rk3399-sdram-lpddr3-2GB-1600.dtsi b/arch/arm/dts/rk3399-sdram-lpddr3-2GB-1600.dtsi
index d14e833..7296dbb 100644
--- a/arch/arm/dts/rk3399-sdram-lpddr3-2GB-1600.dtsi
+++ b/arch/arm/dts/rk3399-sdram-lpddr3-2GB-1600.dtsi
@@ -14,6 +14,8 @@
 		0x0
 		0xf
 		0xf
+		0xf
+		0xf
 		1
 		0x1d191519
 		0x14040808
@@ -29,6 +31,8 @@
 		0x0
 		0xf
 		0xf
+		0xf
+		0xf
 		1
 		0x1d191519
 		0x14040808
diff --git a/arch/arm/dts/rk3399-sdram-lpddr3-4GB-1600.dtsi b/arch/arm/dts/rk3399-sdram-lpddr3-4GB-1600.dtsi
index fc4cccb..bf429c2 100644
--- a/arch/arm/dts/rk3399-sdram-lpddr3-4GB-1600.dtsi
+++ b/arch/arm/dts/rk3399-sdram-lpddr3-4GB-1600.dtsi
@@ -13,6 +13,8 @@
 		0x0
 		0xf
 		0xf
+		0xf
+		0xf
 		1
 		0x1d191519
 		0x14040808
@@ -28,6 +30,8 @@
 		0x0
 		0xf
 		0xf
+		0xf
+		0xf
 		1
 		0x1d191519
 		0x14040808
diff --git a/arch/arm/dts/rk3399-sdram-lpddr3-samsung-4GB-1866.dtsi b/arch/arm/dts/rk3399-sdram-lpddr3-samsung-4GB-1866.dtsi
index 2a627e1..96f459f 100644
--- a/arch/arm/dts/rk3399-sdram-lpddr3-samsung-4GB-1866.dtsi
+++ b/arch/arm/dts/rk3399-sdram-lpddr3-samsung-4GB-1866.dtsi
@@ -13,6 +13,8 @@
 		0x0
 		0xf
 		0xf
+		0xf
+		0xf
 		1
 
 		0x801d181e
@@ -30,6 +32,8 @@
 		0x0
 		0xf
 		0xf
+		0xf
+		0xf
 		1
 
 		0x801d181e
diff --git a/arch/arm/dts/rk3399-sdram-lpddr4-100.dtsi b/arch/arm/dts/rk3399-sdram-lpddr4-100.dtsi
index 4a4414a..f0c478d 100644
--- a/arch/arm/dts/rk3399-sdram-lpddr4-100.dtsi
+++ b/arch/arm/dts/rk3399-sdram-lpddr4-100.dtsi
@@ -15,6 +15,8 @@
 		0x0
 		0xf
 		0xf
+		0xf
+		0xf
 		1
 		0x80241d22
 		0x15050f08
@@ -30,6 +32,8 @@
 		0x0
 		0xf
 		0xf
+		0xf
+		0xf
 		1
 		0x80241d22
 		0x15050f08
diff --git a/arch/arm/dts/rk3399-u-boot.dtsi b/arch/arm/dts/rk3399-u-boot.dtsi
index 2738a38..40240bb 100644
--- a/arch/arm/dts/rk3399-u-boot.dtsi
+++ b/arch/arm/dts/rk3399-u-boot.dtsi
@@ -3,10 +3,50 @@
  * Copyright (C) 2019 Jagan Teki <jagan@amarulasolutions.com>
  */
 
+&cic {
+	u-boot,dm-pre-reloc;
+};
+
+&cru {
+	u-boot,dm-pre-reloc;
+};
+
+&dmc {
+	u-boot,dm-pre-reloc;
+};
+
+&grf {
+	u-boot,dm-pre-reloc;
+};
+
+&pinctrl {
+	u-boot,dm-pre-reloc;
+};
+
 &pmu {
 	u-boot,dm-pre-reloc;
 };
 
+&pmugrf {
+	u-boot,dm-pre-reloc;
+};
+
+&pmu {
+	u-boot,dm-pre-reloc;
+};
+
+&pmucru {
+	u-boot,dm-pre-reloc;
+};
+
+&pmusgrf {
+	u-boot,dm-pre-reloc;
+};
+
+&sdhci {
+	u-boot,dm-pre-reloc;
+};
+
 &sdmmc {
 	u-boot,dm-pre-reloc;
 };
@@ -22,3 +62,11 @@
 &uart2 {
 	u-boot,dm-pre-reloc;
 };
+
+&vopb {
+	u-boot,dm-pre-reloc;
+};
+
+&vopl {
+	u-boot,dm-pre-reloc;
+};
diff --git a/arch/arm/dts/rk3399.dtsi b/arch/arm/dts/rk3399.dtsi
index b73442e..3f773b1 100644
--- a/arch/arm/dts/rk3399.dtsi
+++ b/arch/arm/dts/rk3399.dtsi
@@ -275,7 +275,6 @@
 	};
 
 	sdhci: sdhci@fe330000 {
-		u-boot,dm-pre-reloc;
 		compatible = "rockchip,rk3399-sdhci-5.1", "arasan,sdhci-5.1";
 		reg = <0x0 0xfe330000 0x0 0x10000>;
 		interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH 0>;
@@ -1072,7 +1071,6 @@
 	};
 
 	pmugrf: syscon@ff320000 {
-		u-boot,dm-pre-reloc;
 		compatible = "rockchip,rk3399-pmugrf", "syscon", "simple-mfd";
 		reg = <0x0 0xff320000 0x0 0x1000>;
 
@@ -1083,7 +1081,6 @@
 	};
 
 	pmusgrf: syscon@ff330000 {
-		u-boot,dm-pre-reloc;
 		compatible = "rockchip,rk3399-pmusgrf", "syscon";
 		reg = <0x0 0xff330000 0x0 0xe3d4>;
 	};
@@ -1204,7 +1201,6 @@
 	};
 
 	cic: syscon@ff620000 {
-		u-boot,dm-pre-reloc;
 		compatible = "rockchip,rk3399-cic", "syscon";
 		reg = <0x0 0xff620000 0x0 0x100>;
 	};
@@ -1219,7 +1215,6 @@
 	};
 
 	dmc: dmc {
-		u-boot,dm-pre-reloc;
 		compatible = "rockchip,rk3399-dmc";
 		devfreq-events = <&dfi>;
 		interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH 0>;
@@ -1268,7 +1263,6 @@
 	};
 
 	pmucru: pmu-clock-controller@ff750000 {
-		u-boot,dm-pre-reloc;
 		compatible = "rockchip,rk3399-pmucru";
 		reg = <0x0 0xff750000 0x0 0x1000>;
 		rockchip,grf = <&pmugrf>;
@@ -1279,7 +1273,6 @@
 	};
 
 	cru: clock-controller@ff760000 {
-		u-boot,dm-pre-reloc;
 		compatible = "rockchip,rk3399-cru";
 		reg = <0x0 0xff760000 0x0 0x1000>;
 		rockchip,grf = <&grf>;
@@ -1310,7 +1303,6 @@
 	};
 
 	grf: syscon@ff770000 {
-		u-boot,dm-pre-reloc;
 		compatible = "rockchip,rk3399-grf", "syscon", "simple-mfd";
 		reg = <0x0 0xff770000 0x0 0x10000>;
 		#address-cells = <1>;
@@ -1520,7 +1512,6 @@
 	};
 
 	vopl: vop@ff8f0000 {
-		u-boot,dm-pre-reloc;
 		compatible = "rockchip,rk3399-vop-lit";
 		reg = <0x0 0xff8f0000 0x0 0x3efc>;
 		interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH 0>;
@@ -1578,7 +1569,6 @@
 	};
 
 	vopb: vop@ff900000 {
-		u-boot,dm-pre-reloc;
 		compatible = "rockchip,rk3399-vop-big";
 		reg = <0x0 0xff900000 0x0 0x3efc>;
 		interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH 0>;
@@ -1818,7 +1808,6 @@
 	};
 
 	pinctrl: pinctrl {
-		u-boot,dm-pre-reloc;
 		compatible = "rockchip,rk3399-pinctrl";
 		rockchip,grf = <&grf>;
 		rockchip,pmu = <&pmugrf>;
diff --git a/arch/arm/include/asm/arch-imx/cpu.h b/arch/arm/include/asm/arch-imx/cpu.h
index 3a85492..b0f4dd0 100644
--- a/arch/arm/include/asm/arch-imx/cpu.h
+++ b/arch/arm/include/asm/arch-imx/cpu.h
@@ -32,6 +32,7 @@
 #define MXC_CPU_IMX8MMDL	0x88 /* dummy ID */
 #define MXC_CPU_IMX8MMS		0x89 /* dummy ID */
 #define MXC_CPU_IMX8MMSL	0x8a /* dummy ID */
+#define MXC_CPU_IMX8MN		0x8b /* dummy ID */
 #define MXC_CPU_IMX8QXP_A0	0x90 /* dummy ID */
 #define MXC_CPU_IMX8QM		0x91 /* dummy ID */
 #define MXC_CPU_IMX8QXP		0x92 /* dummy ID */
diff --git a/arch/arm/include/asm/arch-imx8m/clock.h b/arch/arm/include/asm/arch-imx8m/clock.h
index dded6e0..c910b61 100644
--- a/arch/arm/include/asm/arch-imx8m/clock.h
+++ b/arch/arm/include/asm/arch-imx8m/clock.h
@@ -9,7 +9,7 @@
 
 #ifdef CONFIG_IMX8MQ
 #include <asm/arch/clock_imx8mq.h>
-#elif defined(CONFIG_IMX8MM)
+#elif defined(CONFIG_IMX8MM) || defined(CONFIG_IMX8MN)
 #include <asm/arch/clock_imx8mm.h>
 #else
 #error "Error no clock.h"
diff --git a/arch/arm/include/asm/arch-imx8m/clock_imx8mm.h b/arch/arm/include/asm/arch-imx8m/clock_imx8mm.h
index 305514a..76c73ed 100644
--- a/arch/arm/include/asm/arch-imx8m/clock_imx8mm.h
+++ b/arch/arm/include/asm/arch-imx8m/clock_imx8mm.h
@@ -52,8 +52,85 @@
 	ANATOP_DRAM_PLL,
 };
 
+#ifdef CONFIG_IMX8MN
 enum clk_root_index {
 	ARM_A53_CLK_ROOT		= 0,
+	ARM_M7_CLK_ROOT			= 1,
+	GPU_CORE_CLK_ROOT		= 3,
+	GPU_SHADER_CLK_ROOT		= 4,
+	MAIN_AXI_CLK_ROOT		= 16,
+	ENET_AXI_CLK_ROOT		= 17,
+	NAND_USDHC_BUS_CLK_ROOT		= 18,
+	DISPLAY_AXI_CLK_ROOT		= 20,
+	DISPLAY_APB_CLK_ROOT		= 21,
+	USB_BUS_CLK_ROOT		= 23,
+	GPU_AXI_CLK_ROOT		= 24,
+	GPU_AHB_CLK_ROOT		= 25,
+	NOC_CLK_ROOT			= 26,
+	AHB_CLK_ROOT			= 32,
+	IPG_CLK_ROOT			= 33,
+	AUDIO_AHB_CLK_ROOT		= 34,
+	DRAM_SEL_CFG			= 48,
+	CORE_SEL_CFG			= 49,
+	DRAM_ALT_CLK_ROOT		= 64,
+	DRAM_APB_CLK_ROOT		= 65,
+	DISPLAY_PIXEL_CLK_ROOT		= 74,
+	SAI2_CLK_ROOT			= 76,
+	SAI3_CLK_ROOT			= 77,
+	SAI5_CLK_ROOT			= 79,
+	SAI6_CLK_ROOT			= 80,
+	SPDIF1_CLK_ROOT			= 81,
+	ENET_REF_CLK_ROOT		= 83,
+	ENET_TIMER_CLK_ROOT		= 84,
+	ENET_PHY_REF_CLK_ROOT		= 85,
+	NAND_CLK_ROOT			= 86,
+	QSPI_CLK_ROOT			= 87,
+	USDHC1_CLK_ROOT			= 88,
+	USDHC2_CLK_ROOT			= 89,
+	I2C1_CLK_ROOT			= 90,
+	I2C2_CLK_ROOT			= 91,
+	I2C3_CLK_ROOT			= 92,
+	I2C4_CLK_ROOT			= 93,
+	UART1_CLK_ROOT			= 94,
+	UART2_CLK_ROOT			= 95,
+	UART3_CLK_ROOT			= 96,
+	UART4_CLK_ROOT			= 97,
+	USB_CORE_REF_CLK_ROOT		= 98,
+	USB_PHY_REF_CLK_ROOT		= 99,
+	GIC_CLK_ROOT			= 100,
+	ECSPI1_CLK_ROOT			= 101,
+	ECSPI2_CLK_ROOT			= 102,
+	PWM1_CLK_ROOT			= 103,
+	PWM2_CLK_ROOT			= 104,
+	PWM3_CLK_ROOT			= 105,
+	PWM4_CLK_ROOT			= 106,
+	GPT1_CLK_ROOT			= 107,
+	GPT2_CLK_ROOT			= 108,
+	GPT3_CLK_ROOT			= 109,
+	GPT4_CLK_ROOT			= 110,
+	GPT5_CLK_ROOT			= 111,
+	GPT6_CLK_ROOT			= 112,
+	TRACE_CLK_ROOT			= 113,
+	WDOG_CLK_ROOT			= 114,
+	WRCLK_CLK_ROOT			= 115,
+	IPP_DO_CLKO1			= 116,
+	IPP_DO_CLKO2			= 117,
+	MIPI_DSI_CORE_CLK_ROOT		= 118,
+	DISPLAY_DSI_PHY_REF_CLK_ROOT	= 119,
+	MIPI_DSI_DBI_CLK_ROOT		= 120,
+	USDHC3_CLK_ROOT			= 121,
+	DISPLAY_CAMERA_PIXEL_CLK_ROOT	= 122,
+	MIPI_CSI1_PHY_REF_CLK_ROOT	= 123,
+	MIPI_CSI2_PHY_REF_CLK_ROOT	= 126,
+	MIPI_CSI2_ESC_CLK_ROOT		= 127,
+	ECSPI3_CLK_ROOT			= 131,
+	PDM_CLK_ROOT			= 132,
+	SAI7_CLK_ROOT			= 134,
+	CLK_ROOT_MAX,
+};
+#else
+enum clk_root_index {
+	ARM_A53_CLK_ROOT		= 0,
 	ARM_M4_CLK_ROOT			= 1,
 	VPU_A53_CLK_ROOT		= 2,
 	GPU3D_CLK_ROOT			= 3,
@@ -148,6 +225,7 @@
 	VPU_H1_CLK_ROOT			= 133,
 	CLK_ROOT_MAX,
 };
+#endif
 
 enum clk_root_src {
 	OSC_24M_CLK,
diff --git a/arch/arm/include/asm/arch-imx8m/imx8mn_pins.h b/arch/arm/include/asm/arch-imx8m/imx8mn_pins.h
new file mode 100644
index 0000000..b4298f2
--- /dev/null
+++ b/arch/arm/include/asm/arch-imx8m/imx8mn_pins.h
@@ -0,0 +1,763 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2018 NXP
+ */
+
+#ifndef __ASM_ARCH_IMX8MN_PINS_H__
+#define __ASM_ARCH_IMX8MN_PINS_H__
+
+#include <asm/mach-imx/iomux-v3.h>
+
+enum {
+	IMX8MN_PAD_BOOT_MODE2__CCMSRCGPCMIX_BOOT_MODE2                          = IOMUX_PAD(0x025C, 0x0020, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_BOOT_MODE2__I2C1_SCL                                         = IOMUX_PAD(0x025C, 0x0020, 1, 0x055C, 3, 0),
+
+	IMX8MN_PAD_BOOT_MODE3__CCMSRCGPCMIX_BOOT_MODE3                          = IOMUX_PAD(0x0260, 0x0024, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_BOOT_MODE3__I2C1_SDA                                         = IOMUX_PAD(0x0260, 0x0024, 1, 0x056C, 3, 0),
+
+	IMX8MN_PAD_GPIO1_IO00__GPIO1_IO0                                        = IOMUX_PAD(0x0290, 0x0028, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_GPIO1_IO00__CCMSRCGPCMIX_ENET_PHY_REF_CLK_ROOT               = IOMUX_PAD(0x0290, 0x0028, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_GPIO1_IO00__ANAMIX_REF_CLK_32K                               = IOMUX_PAD(0x0290, 0x0028, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_GPIO1_IO00__CCMSRCGPCMIX_EXT_CLK1                            = IOMUX_PAD(0x0290, 0x0028, 6, 0x0000, 0, 0),
+
+	IMX8MN_PAD_GPIO1_IO01__GPIO1_IO1                                        = IOMUX_PAD(0x0294, 0x002C, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_GPIO1_IO01__PWM1_OUT                                         = IOMUX_PAD(0x0294, 0x002C, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_GPIO1_IO01__ANAMIX_REF_CLK_24M                               = IOMUX_PAD(0x0294, 0x002C, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_GPIO1_IO01__CCMSRCGPCMIX_EXT_CLK2                            = IOMUX_PAD(0x0294, 0x002C, 6, 0x0000, 0, 0),
+
+	IMX8MN_PAD_GPIO1_IO02__GPIO1_IO2                                        = IOMUX_PAD(0x0298, 0x0030, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_GPIO1_IO02__WDOG1_WDOG_B                                     = IOMUX_PAD(0x0298, 0x0030, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_GPIO1_IO02__WDOG1_WDOG_ANY                                   = IOMUX_PAD(0x0298, 0x0030, 5, 0x0000, 0, 0),
+
+	IMX8MN_PAD_GPIO1_IO03__GPIO1_IO3                                        = IOMUX_PAD(0x029C, 0x0034, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_GPIO1_IO03__USDHC1_VSELECT                                   = IOMUX_PAD(0x029C, 0x0034, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_GPIO1_IO03__SDMA1_EXT_EVENT0                                 = IOMUX_PAD(0x029C, 0x0034, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_GPIO1_IO03__ANAMIX_XTAL_OK                                   = IOMUX_PAD(0x029C, 0x0034, 6, 0x0000, 0, 0),
+
+	IMX8MN_PAD_GPIO1_IO04__GPIO1_IO4                                        = IOMUX_PAD(0x02A0, 0x0038, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_GPIO1_IO04__USDHC2_VSELECT                                   = IOMUX_PAD(0x02A0, 0x0038, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_GPIO1_IO04__SDMA1_EXT_EVENT1                                 = IOMUX_PAD(0x02A0, 0x0038, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_GPIO1_IO04__ANAMIX_XTAL_OK_LV                                = IOMUX_PAD(0x02A0, 0x0038, 6, 0x0000, 0, 0),
+
+	IMX8MN_PAD_GPIO1_IO05__GPIO1_IO5                                        = IOMUX_PAD(0x02A4, 0x003C, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_GPIO1_IO05__M4_NMI                                           = IOMUX_PAD(0x02A4, 0x003C, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_GPIO1_IO05__CCMSRCGPCMIX_PMIC_READY                          = IOMUX_PAD(0x02A4, 0x003C, 5, 0x04BC, 0, 0),
+	IMX8MN_PAD_GPIO1_IO05__CCMSRCGPCMIX_INT_BOOT                            = IOMUX_PAD(0x02A4, 0x003C, 6, 0x0000, 0, 0),
+
+	IMX8MN_PAD_GPIO1_IO06__GPIO1_IO6                                        = IOMUX_PAD(0x02A8, 0x0040, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_GPIO1_IO06__ENET1_MDC                                        = IOMUX_PAD(0x02A8, 0x0040, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_GPIO1_IO06__USDHC1_CD_B                                      = IOMUX_PAD(0x02A8, 0x0040, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_GPIO1_IO06__CCMSRCGPCMIX_EXT_CLK3                            = IOMUX_PAD(0x02A8, 0x0040, 6, 0x0000, 0, 0),
+
+	IMX8MN_PAD_GPIO1_IO07__GPIO1_IO7                                        = IOMUX_PAD(0x02AC, 0x0044, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_GPIO1_IO07__ENET1_MDIO                                       = IOMUX_PAD(0x02AC, 0x0044, 1, 0x04C0, 0, 0),
+	IMX8MN_PAD_GPIO1_IO07__USDHC1_WP                                        = IOMUX_PAD(0x02AC, 0x0044, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_GPIO1_IO07__CCMSRCGPCMIX_EXT_CLK4                            = IOMUX_PAD(0x02AC, 0x0044, 6, 0x0000, 0, 0),
+
+	IMX8MN_PAD_GPIO1_IO08__GPIO1_IO8                                        = IOMUX_PAD(0x02B0, 0x0048, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_GPIO1_IO08__ENET1_1588_EVENT0_IN                             = IOMUX_PAD(0x02B0, 0x0048, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_GPIO1_IO08__PWM1_OUT                                         = IOMUX_PAD(0x02B0, 0x0048, 2, 0x0000, 0, 0),
+	IMX8MN_PAD_GPIO1_IO08__USDHC2_RESET_B                                   = IOMUX_PAD(0x02B0, 0x0048, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_GPIO1_IO08__CCMSRCGPCMIX_WAIT                                = IOMUX_PAD(0x02B0, 0x0048, 6, 0x0000, 0, 0),
+
+	IMX8MN_PAD_GPIO1_IO09__GPIO1_IO9                                        = IOMUX_PAD(0x02B4, 0x004C, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_GPIO1_IO09__ENET1_1588_EVENT0_OUT                            = IOMUX_PAD(0x02B4, 0x004C, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_GPIO1_IO09__PWM2_OUT                                         = IOMUX_PAD(0x02B4, 0x004C, 2, 0x0000, 0, 0),
+	IMX8MN_PAD_GPIO1_IO09__USDHC3_RESET_B                                   = IOMUX_PAD(0x02B4, 0x004C, 4, 0x0000, 0, 0),
+	IMX8MN_PAD_GPIO1_IO09__SDMA2_EXT_EVENT0                                 = IOMUX_PAD(0x02B4, 0x004C, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_GPIO1_IO09__CCMSRCGPCMIX_STOP                                = IOMUX_PAD(0x02B4, 0x004C, 6, 0x0000, 0, 0),
+
+	IMX8MN_PAD_GPIO1_IO10__GPIO1_IO10                                       = IOMUX_PAD(0x02B8, 0x0050, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_GPIO1_IO10__USB1_OTG_ID                                      = IOMUX_PAD(0x02B8, 0x0050, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_GPIO1_IO10__PWM3_OUT                                         = IOMUX_PAD(0x02B8, 0x0050, 2, 0x0000, 0, 0),
+
+	IMX8MN_PAD_GPIO1_IO11__GPIO1_IO11                                       = IOMUX_PAD(0x02BC, 0x0054, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_GPIO1_IO11__PWM2_OUT                                         = IOMUX_PAD(0x02BC, 0x0054, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_GPIO1_IO11__USDHC3_VSELECT                                   = IOMUX_PAD(0x02BC, 0x0054, 4, 0x0000, 0, 0),
+	IMX8MN_PAD_GPIO1_IO11__CCMSRCGPCMIX_PMIC_READY                          = IOMUX_PAD(0x02BC, 0x0054, 5, 0x04BC, 1, 0),
+	IMX8MN_PAD_GPIO1_IO11__CCMSRCGPCMIX_OUT0                                = IOMUX_PAD(0x02BC, 0x0054, 6, 0x0000, 0, 0),
+
+	IMX8MN_PAD_GPIO1_IO12__GPIO1_IO12                                       = IOMUX_PAD(0x02C0, 0x0058, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_GPIO1_IO12__USB1_OTG_PWR                                     = IOMUX_PAD(0x02C0, 0x0058, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_GPIO1_IO12__SDMA2_EXT_EVENT1                                 = IOMUX_PAD(0x02C0, 0x0058, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_GPIO1_IO12__CCMSRCGPCMIX_OUT1                                = IOMUX_PAD(0x02C0, 0x0058, 6, 0x0000, 0, 0),
+
+	IMX8MN_PAD_GPIO1_IO13__GPIO1_IO13                                       = IOMUX_PAD(0x02C4, 0x005C, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_GPIO1_IO13__USB1_OTG_OC                                      = IOMUX_PAD(0x02C4, 0x005C, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_GPIO1_IO13__PWM2_OUT                                         = IOMUX_PAD(0x02C4, 0x005C, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_GPIO1_IO13__CCMSRCGPCMIX_OUT2                                = IOMUX_PAD(0x02C4, 0x005C, 6, 0x0000, 0, 0),
+
+	IMX8MN_PAD_GPIO1_IO14__GPIO1_IO14                                       = IOMUX_PAD(0x02C8, 0x0060, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_GPIO1_IO14__USDHC3_CD_B                                      = IOMUX_PAD(0x02C8, 0x0060, 4, 0x0598, 2, 0),
+	IMX8MN_PAD_GPIO1_IO14__PWM3_OUT                                         = IOMUX_PAD(0x02C8, 0x0060, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_GPIO1_IO14__CCMSRCGPCMIX_CLKO1                               = IOMUX_PAD(0x02C8, 0x0060, 6, 0x0000, 0, 0),
+
+	IMX8MN_PAD_GPIO1_IO15__GPIO1_IO15                                       = IOMUX_PAD(0x02CC, 0x0064, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_GPIO1_IO15__USDHC3_WP                                        = IOMUX_PAD(0x02CC, 0x0064, 4, 0x05B8, 2, 0),
+	IMX8MN_PAD_GPIO1_IO15__PWM4_OUT                                         = IOMUX_PAD(0x02CC, 0x0064, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_GPIO1_IO15__CCMSRCGPCMIX_CLKO2                               = IOMUX_PAD(0x02CC, 0x0064, 6, 0x0000, 0, 0),
+
+	IMX8MN_PAD_ENET_MDC__ENET1_MDC                                          = IOMUX_PAD(0x02D0, 0x0068, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_ENET_MDC__SAI6_TX_DATA0                                      = IOMUX_PAD(0x02D0, 0x0068, 2, 0x0000, 0, 0),
+	IMX8MN_PAD_ENET_MDC__PDM_BIT_STREAM3                                    = IOMUX_PAD(0x02D0, 0x0068, 3, 0x0540, 1, 0),
+	IMX8MN_PAD_ENET_MDC__SPDIF1_OUT                                         = IOMUX_PAD(0x02D0, 0x0068, 4, 0x0000, 0, 0),
+	IMX8MN_PAD_ENET_MDC__GPIO1_IO16                                         = IOMUX_PAD(0x02D0, 0x0068, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_ENET_MDC__USDHC3_STROBE                                      = IOMUX_PAD(0x02D0, 0x0068, 6, 0x059C, 1, 0),
+
+	IMX8MN_PAD_ENET_MDIO__ENET1_MDIO                                        = IOMUX_PAD(0x02D4, 0x006C, 0, 0x04C0, 1, 0),
+	IMX8MN_PAD_ENET_MDIO__SAI6_TX_SYNC                                      = IOMUX_PAD(0x02D4, 0x006C, 2, 0x0000, 0, 0),
+	IMX8MN_PAD_ENET_MDIO__PDM_BIT_STREAM2                                   = IOMUX_PAD(0x02D4, 0x006C, 3, 0x053C, 1, 0),
+	IMX8MN_PAD_ENET_MDIO__SPDIF1_IN                                         = IOMUX_PAD(0x02D4, 0x006C, 4, 0x05CC, 1, 0),
+	IMX8MN_PAD_ENET_MDIO__GPIO1_IO17                                        = IOMUX_PAD(0x02D4, 0x006C, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_ENET_MDIO__USDHC3_DATA5                                      = IOMUX_PAD(0x02D4, 0x006C, 6, 0x0550, 1, 0),
+
+	IMX8MN_PAD_ENET_TD3__ENET1_RGMII_TD3                                    = IOMUX_PAD(0x02D8, 0x0070, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_ENET_TD3__SAI6_TX_BCLK                                       = IOMUX_PAD(0x02D8, 0x0070, 2, 0x0000, 0, 0),
+	IMX8MN_PAD_ENET_TD3__PDM_BIT_STREAM1                                    = IOMUX_PAD(0x02D8, 0x0070, 3, 0x0538, 1, 0),
+	IMX8MN_PAD_ENET_TD3__SPDIF1_EXT_CLK                                     = IOMUX_PAD(0x02D8, 0x0070, 4, 0x0568, 1, 0),
+	IMX8MN_PAD_ENET_TD3__GPIO1_IO18                                         = IOMUX_PAD(0x02D8, 0x0070, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_ENET_TD3__USDHC3_DATA6                                       = IOMUX_PAD(0x02D8, 0x0070, 6, 0x0584, 1, 0),
+
+	IMX8MN_PAD_ENET_TD2__ENET1_RGMII_TD2                                    = IOMUX_PAD(0x02DC, 0x0074, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_ENET_TD2__ENET1_TX_CLK                                       = IOMUX_PAD(0x02DC, 0x0074, 1, 0x05A4, 0, 0),
+	IMX8MN_PAD_ENET_TD2__CCMSRCGPCMIX_ENET_REF_CLK_ROOT                     = IOMUX_PAD(0x02DC, 0x0074, 1, 0x05A4, 0, 0),
+	IMX8MN_PAD_ENET_TD2__SAI6_RX_DATA0                                      = IOMUX_PAD(0x02DC, 0x0074, 2, 0x0000, 0, 0),
+	IMX8MN_PAD_ENET_TD2__PDM_BIT_STREAM3                                    = IOMUX_PAD(0x02DC, 0x0074, 3, 0x0540, 2, 0),
+	IMX8MN_PAD_ENET_TD2__GPIO1_IO19                                         = IOMUX_PAD(0x02DC, 0x0074, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_ENET_TD2__USDHC3_DATA7                                       = IOMUX_PAD(0x02DC, 0x0074, 6, 0x054C, 1, 0),
+
+	IMX8MN_PAD_ENET_TD1__ENET1_RGMII_TD1                                    = IOMUX_PAD(0x02E0, 0x0078, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_ENET_TD1__SAI6_RX_SYNC                                       = IOMUX_PAD(0x02E0, 0x0078, 2, 0x0000, 0, 0),
+	IMX8MN_PAD_ENET_TD1__PDM_BIT_STREAM2                                    = IOMUX_PAD(0x02E0, 0x0078, 3, 0x053C, 2, 0),
+	IMX8MN_PAD_ENET_TD1__GPIO1_IO20                                         = IOMUX_PAD(0x02E0, 0x0078, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_ENET_TD1__USDHC3_CD_B                                        = IOMUX_PAD(0x02E0, 0x0078, 6, 0x0598, 3, 0),
+
+	IMX8MN_PAD_ENET_TD0__ENET1_RGMII_TD0                                    = IOMUX_PAD(0x02E4, 0x007C, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_ENET_TD0__SAI6_RX_BCLK                                       = IOMUX_PAD(0x02E4, 0x007C, 2, 0x0000, 0, 0),
+	IMX8MN_PAD_ENET_TD0__PDM_BIT_STREAM1                                    = IOMUX_PAD(0x02E4, 0x007C, 3, 0x0538, 2, 0),
+	IMX8MN_PAD_ENET_TD0__GPIO1_IO21                                         = IOMUX_PAD(0x02E4, 0x007C, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_ENET_TD0__USDHC3_WP                                          = IOMUX_PAD(0x02E4, 0x007C, 6, 0x05B8, 3, 0),
+
+	IMX8MN_PAD_ENET_TX_CTL__ENET1_RGMII_TX_CTL                              = IOMUX_PAD(0x02E8, 0x0080, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_ENET_TX_CTL__SAI6_MCLK                                       = IOMUX_PAD(0x02E8, 0x0080, 2, 0x0000, 0, 0),
+	IMX8MN_PAD_ENET_TX_CTL__GPIO1_IO22                                      = IOMUX_PAD(0x02E8, 0x0080, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_ENET_TX_CTL__USDHC3_DATA0                                    = IOMUX_PAD(0x02E8, 0x0080, 6, 0x05B4, 1, 0),
+
+	IMX8MN_PAD_ENET_TXC__ENET1_RGMII_TXC                                    = IOMUX_PAD(0x02EC, 0x0084, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_ENET_TXC__ENET1_TX_ER                                        = IOMUX_PAD(0x02EC, 0x0084, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_ENET_TXC__SAI7_TX_DATA0                                      = IOMUX_PAD(0x02EC, 0x0084, 2, 0x0000, 0, 0),
+	IMX8MN_PAD_ENET_TXC__GPIO1_IO23                                         = IOMUX_PAD(0x02EC, 0x0084, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_ENET_TXC__USDHC3_DATA1                                       = IOMUX_PAD(0x02EC, 0x0084, 6, 0x05B0, 1, 0),
+
+	IMX8MN_PAD_ENET_RX_CTL__ENET1_RGMII_RX_CTL                              = IOMUX_PAD(0x02F0, 0x0088, 0, 0x0574, 0, 0),
+	IMX8MN_PAD_ENET_RX_CTL__SAI7_TX_SYNC                                    = IOMUX_PAD(0x02F0, 0x0088, 2, 0x0000, 0, 0),
+	IMX8MN_PAD_ENET_RX_CTL__PDM_BIT_STREAM3                                 = IOMUX_PAD(0x02F0, 0x0088, 3, 0x0540, 3, 0),
+	IMX8MN_PAD_ENET_RX_CTL__GPIO1_IO24                                      = IOMUX_PAD(0x02F0, 0x0088, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_ENET_RX_CTL__USDHC3_DATA2                                    = IOMUX_PAD(0x02F0, 0x0088, 6, 0x05E4, 1, 0),
+
+	IMX8MN_PAD_ENET_RXC__ENET1_RGMII_RXC                                    = IOMUX_PAD(0x02F4, 0x008C, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_ENET_RXC__ENET1_RX_ER                                        = IOMUX_PAD(0x02F4, 0x008C, 1, 0x05C8, 0, 0),
+	IMX8MN_PAD_ENET_RXC__SAI7_TX_BCLK                                       = IOMUX_PAD(0x02F4, 0x008C, 2, 0x0000, 0, 0),
+	IMX8MN_PAD_ENET_RXC__PDM_BIT_STREAM2                                    = IOMUX_PAD(0x02F4, 0x008C, 3, 0x053C, 3, 0),
+	IMX8MN_PAD_ENET_RXC__GPIO1_IO25                                         = IOMUX_PAD(0x02F4, 0x008C, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_ENET_RXC__USDHC3_DATA3                                       = IOMUX_PAD(0x02F4, 0x008C, 6, 0x05E0, 1, 0),
+
+	IMX8MN_PAD_ENET_RD0__ENET1_RGMII_RD0                                    = IOMUX_PAD(0x02F8, 0x0090, 0, 0x057C, 0, 0),
+	IMX8MN_PAD_ENET_RD0__SAI7_RX_DATA0                                      = IOMUX_PAD(0x02F8, 0x0090, 2, 0x0000, 0, 0),
+	IMX8MN_PAD_ENET_RD0__PDM_BIT_STREAM1                                    = IOMUX_PAD(0x02F8, 0x0090, 3, 0x0538, 3, 0),
+	IMX8MN_PAD_ENET_RD0__GPIO1_IO26                                         = IOMUX_PAD(0x02F8, 0x0090, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_ENET_RD0__USDHC3_DATA4                                       = IOMUX_PAD(0x02F8, 0x0090, 6, 0x0558, 1, 0),
+
+	IMX8MN_PAD_ENET_RD1__ENET1_RGMII_RD1                                    = IOMUX_PAD(0x02FC, 0x0094, 0, 0x0554, 0, 0),
+	IMX8MN_PAD_ENET_RD1__SAI7_RX_SYNC                                       = IOMUX_PAD(0x02FC, 0x0094, 2, 0x0000, 0, 0),
+	IMX8MN_PAD_ENET_RD1__PDM_BIT_STREAM0                                    = IOMUX_PAD(0x02FC, 0x0094, 3, 0x0534, 1, 0),
+	IMX8MN_PAD_ENET_RD1__GPIO1_IO27                                         = IOMUX_PAD(0x02FC, 0x0094, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_ENET_RD1__USDHC3_RESET_B                                     = IOMUX_PAD(0x02FC, 0x0094, 6, 0x0000, 0, 0),
+
+	IMX8MN_PAD_ENET_RD2__ENET1_RGMII_RD2                                    = IOMUX_PAD(0x0300, 0x0098, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_ENET_RD2__SAI7_RX_BCLK                                       = IOMUX_PAD(0x0300, 0x0098, 2, 0x0000, 0, 0),
+	IMX8MN_PAD_ENET_RD2__PDM_CLK                                            = IOMUX_PAD(0x0300, 0x0098, 3, 0x0000, 0, 0),
+	IMX8MN_PAD_ENET_RD2__GPIO1_IO28                                         = IOMUX_PAD(0x0300, 0x0098, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_ENET_RD2__USDHC3_CLK                                         = IOMUX_PAD(0x0300, 0x0098, 6, 0x05A0, 1, 0),
+
+	IMX8MN_PAD_ENET_RD3__ENET1_RGMII_RD3                                    = IOMUX_PAD(0x0304, 0x009C, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_ENET_RD3__SAI7_MCLK                                          = IOMUX_PAD(0x0304, 0x009C, 2, 0x0000, 0, 0),
+	IMX8MN_PAD_ENET_RD3__SPDIF1_IN                                          = IOMUX_PAD(0x0304, 0x009C, 3, 0x05CC, 5, 0),
+	IMX8MN_PAD_ENET_RD3__GPIO1_IO29                                         = IOMUX_PAD(0x0304, 0x009C, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_ENET_RD3__USDHC3_CMD                                         = IOMUX_PAD(0x0304, 0x009C, 6, 0x05DC, 1, 0),
+
+	IMX8MN_PAD_SD1_CLK__USDHC1_CLK                                          = IOMUX_PAD(0x0308, 0x00A0, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_SD1_CLK__ENET1_MDC                                           = IOMUX_PAD(0x0308, 0x00A0, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_SD1_CLK__UART1_DCE_TX                                        = IOMUX_PAD(0x0308, 0x00A0, 4, 0x0000, 0, 0),
+	IMX8MN_PAD_SD1_CLK__UART1_DTE_RX                                        = IOMUX_PAD(0x0308, 0x00A0, 4, 0x04F4, 4, 0),
+	IMX8MN_PAD_SD1_CLK__GPIO2_IO0                                           = IOMUX_PAD(0x0308, 0x00A0, 5, 0x0000, 0, 0),
+
+	IMX8MN_PAD_SD1_CMD__USDHC1_CMD                                          = IOMUX_PAD(0x030C, 0x00A4, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_SD1_CMD__ENET1_MDIO                                          = IOMUX_PAD(0x030C, 0x00A4, 1, 0x04C0, 3, 0),
+	IMX8MN_PAD_SD1_CMD__UART1_DCE_RX                                        = IOMUX_PAD(0x030C, 0x00A4, 4, 0x04F4, 5, 0),
+	IMX8MN_PAD_SD1_CMD__UART1_DTE_TX                                        = IOMUX_PAD(0x030C, 0x00A4, 4, 0x0000, 0, 0),
+	IMX8MN_PAD_SD1_CMD__GPIO2_IO1                                           = IOMUX_PAD(0x030C, 0x00A4, 5, 0x0000, 0, 0),
+
+	IMX8MN_PAD_SD1_DATA0__USDHC1_DATA0                                      = IOMUX_PAD(0x0310, 0x00A8, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_SD1_DATA0__ENET1_RGMII_TD1                                   = IOMUX_PAD(0x0310, 0x00A8, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_SD1_DATA0__UART1_DCE_RTS_B                                   = IOMUX_PAD(0x0310, 0x00A8, 4, 0x04F0, 4, 0),
+	IMX8MN_PAD_SD1_DATA0__UART1_DTE_CTS_B                                   = IOMUX_PAD(0x0310, 0x00A8, 4, 0x0000, 0, 0),
+	IMX8MN_PAD_SD1_DATA0__GPIO2_IO2                                         = IOMUX_PAD(0x0310, 0x00A8, 5, 0x0000, 0, 0),
+
+	IMX8MN_PAD_SD1_DATA1__USDHC1_DATA1                                      = IOMUX_PAD(0x0314, 0x00AC, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_SD1_DATA1__ENET1_RGMII_TD0                                   = IOMUX_PAD(0x0314, 0x00AC, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_SD1_DATA1__UART1_DCE_CTS_B                                   = IOMUX_PAD(0x0314, 0x00AC, 4, 0x0000, 0, 0),
+	IMX8MN_PAD_SD1_DATA1__UART1_DTE_RTS_B                                   = IOMUX_PAD(0x0314, 0x00AC, 4, 0x04F0, 5, 0),
+	IMX8MN_PAD_SD1_DATA1__GPIO2_IO3                                         = IOMUX_PAD(0x0314, 0x00AC, 5, 0x0000, 0, 0),
+
+	IMX8MN_PAD_SD1_DATA2__USDHC1_DATA2                                      = IOMUX_PAD(0x0318, 0x00B0, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_SD1_DATA2__ENET1_RGMII_RD0                                   = IOMUX_PAD(0x0318, 0x00B0, 1, 0x057C, 1, 0),
+	IMX8MN_PAD_SD1_DATA2__UART2_DCE_TX                                      = IOMUX_PAD(0x0318, 0x00B0, 4, 0x0000, 0, 0),
+	IMX8MN_PAD_SD1_DATA2__UART2_DTE_RX                                      = IOMUX_PAD(0x0318, 0x00B0, 4, 0x04FC, 4, 0),
+	IMX8MN_PAD_SD1_DATA2__GPIO2_IO4                                         = IOMUX_PAD(0x0318, 0x00B0, 5, 0x0000, 0, 0),
+
+	IMX8MN_PAD_SD1_DATA3__USDHC1_DATA3                                      = IOMUX_PAD(0x031C, 0x00B4, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_SD1_DATA3__ENET1_RGMII_RD1                                   = IOMUX_PAD(0x031C, 0x00B4, 1, 0x0554, 1, 0),
+	IMX8MN_PAD_SD1_DATA3__UART2_DCE_RX                                      = IOMUX_PAD(0x031C, 0x00B4, 4, 0x04FC, 5, 0),
+	IMX8MN_PAD_SD1_DATA3__UART2_DTE_TX                                      = IOMUX_PAD(0x031C, 0x00B4, 4, 0x0000, 0, 0),
+	IMX8MN_PAD_SD1_DATA3__GPIO2_IO5                                         = IOMUX_PAD(0x031C, 0x00B4, 5, 0x0000, 0, 0),
+
+	IMX8MN_PAD_SD1_DATA4__USDHC1_DATA4                                      = IOMUX_PAD(0x0320, 0x00B8, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_SD1_DATA4__ENET1_RGMII_TX_CTL                                = IOMUX_PAD(0x0320, 0x00B8, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_SD1_DATA4__I2C1_SCL                                          = IOMUX_PAD(0x0320, 0x00B8, 3, 0x055C, 1, 0),
+	IMX8MN_PAD_SD1_DATA4__UART2_DCE_RTS_B                                   = IOMUX_PAD(0x0320, 0x00B8, 4, 0x04F8, 4, 0),
+	IMX8MN_PAD_SD1_DATA4__UART2_DTE_CTS_B                                   = IOMUX_PAD(0x0320, 0x00B8, 4, 0x0000, 0, 0),
+	IMX8MN_PAD_SD1_DATA4__GPIO2_IO6                                         = IOMUX_PAD(0x0320, 0x00B8, 5, 0x0000, 0, 0),
+
+	IMX8MN_PAD_SD1_DATA5__USDHC1_DATA5                                      = IOMUX_PAD(0x0324, 0x00BC, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_SD1_DATA5__ENET1_TX_ER                                       = IOMUX_PAD(0x0324, 0x00BC, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_SD1_DATA5__I2C1_SDA                                          = IOMUX_PAD(0x0324, 0x00BC, 3, 0x056C, 1, 0),
+	IMX8MN_PAD_SD1_DATA5__UART2_DCE_CTS_B                                   = IOMUX_PAD(0x0324, 0x00BC, 4, 0x0000, 0, 0),
+	IMX8MN_PAD_SD1_DATA5__UART2_DTE_RTS_B                                   = IOMUX_PAD(0x0324, 0x00BC, 4, 0x04F8, 5, 0),
+	IMX8MN_PAD_SD1_DATA5__GPIO2_IO7                                         = IOMUX_PAD(0x0324, 0x00BC, 5, 0x0000, 0, 0),
+
+	IMX8MN_PAD_SD1_DATA6__USDHC1_DATA6                                      = IOMUX_PAD(0x0328, 0x00C0, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_SD1_DATA6__ENET1_RGMII_RX_CTL                                = IOMUX_PAD(0x0328, 0x00C0, 1, 0x0574, 1, 0),
+	IMX8MN_PAD_SD1_DATA6__I2C2_SCL                                          = IOMUX_PAD(0x0328, 0x00C0, 3, 0x05D0, 1, 0),
+	IMX8MN_PAD_SD1_DATA6__UART3_DCE_TX                                      = IOMUX_PAD(0x0328, 0x00C0, 4, 0x0000, 0, 0),
+	IMX8MN_PAD_SD1_DATA6__UART3_DTE_RX                                      = IOMUX_PAD(0x0328, 0x00C0, 4, 0x0504, 4, 0),
+	IMX8MN_PAD_SD1_DATA6__GPIO2_IO8                                         = IOMUX_PAD(0x0328, 0x00C0, 5, 0x0000, 0, 0),
+
+	IMX8MN_PAD_SD1_DATA7__USDHC1_DATA7                                      = IOMUX_PAD(0x032C, 0x00C4, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_SD1_DATA7__ENET1_RX_ER                                       = IOMUX_PAD(0x032C, 0x00C4, 1, 0x05C8, 1, 0),
+	IMX8MN_PAD_SD1_DATA7__I2C2_SDA                                          = IOMUX_PAD(0x032C, 0x00C4, 3, 0x0560, 1, 0),
+	IMX8MN_PAD_SD1_DATA7__UART3_DCE_RX                                      = IOMUX_PAD(0x032C, 0x00C4, 4, 0x0504, 5, 0),
+	IMX8MN_PAD_SD1_DATA7__UART3_DTE_TX                                      = IOMUX_PAD(0x032C, 0x00C4, 4, 0x0000, 0, 0),
+	IMX8MN_PAD_SD1_DATA7__GPIO2_IO9                                         = IOMUX_PAD(0x032C, 0x00C4, 5, 0x0000, 0, 0),
+
+	IMX8MN_PAD_SD1_RESET_B__USDHC1_RESET_B                                  = IOMUX_PAD(0x0330, 0x00C8, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_SD1_RESET_B__ENET1_TX_CLK                              = IOMUX_PAD(0x0330, 0x00C8, 1, 0x05A4, 1, 0),
+	IMX8MN_PAD_SD1_RESET_B__CCMSRCGPCMIX_ENET_REF_CLK_ROOT                  = IOMUX_PAD(0x0330, 0x00C8, 1, 0x05A4, 0, 0),
+	IMX8MN_PAD_SD1_RESET_B__I2C3_SCL                                        = IOMUX_PAD(0x0330, 0x00C8, 3, 0x0588, 1, 0),
+	IMX8MN_PAD_SD1_RESET_B__UART3_DCE_RTS_B                                 = IOMUX_PAD(0x0330, 0x00C8, 4, 0x0500, 2, 0),
+	IMX8MN_PAD_SD1_RESET_B__UART3_DTE_CTS_B                                 = IOMUX_PAD(0x0330, 0x00C8, 4, 0x0000, 0, 0),
+	IMX8MN_PAD_SD1_RESET_B__GPIO2_IO10                                      = IOMUX_PAD(0x0330, 0x00C8, 5, 0x0000, 0, 0),
+
+	IMX8MN_PAD_SD1_STROBE__USDHC1_STROBE                                    = IOMUX_PAD(0x0334, 0x00CC, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_SD1_STROBE__I2C3_SDA                                         = IOMUX_PAD(0x0334, 0x00CC, 3, 0x05BC, 1, 0),
+	IMX8MN_PAD_SD1_STROBE__UART3_DCE_CTS_B                                  = IOMUX_PAD(0x0334, 0x00CC, 4, 0x0000, 0, 0),
+	IMX8MN_PAD_SD1_STROBE__UART3_DTE_RTS_B                                  = IOMUX_PAD(0x0334, 0x00CC, 4, 0x0500, 3, 0),
+	IMX8MN_PAD_SD1_STROBE__GPIO2_IO11                                       = IOMUX_PAD(0x0334, 0x00CC, 5, 0x0000, 0, 0),
+
+	IMX8MN_PAD_SD2_CD_B__USDHC2_CD_B                                        = IOMUX_PAD(0x0338, 0x00D0, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_SD2_CD_B__GPIO2_IO12                                         = IOMUX_PAD(0x0338, 0x00D0, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_SD2_CD_B__CCMSRCGPCMIX_TESTER_ACK                            = IOMUX_PAD(0x0338, 0x00D0, 6, 0x0000, 0, 0),
+
+	IMX8MN_PAD_SD2_CLK__USDHC2_CLK                                          = IOMUX_PAD(0x033C, 0x00D4, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_SD2_CLK__SAI5_RX_SYNC                                        = IOMUX_PAD(0x033C, 0x00D4, 1, 0x04E4, 1, 0),
+	IMX8MN_PAD_SD2_CLK__ECSPI2_SCLK                                         = IOMUX_PAD(0x033C, 0x00D4, 2, 0x0580, 1, 0),
+	IMX8MN_PAD_SD2_CLK__UART4_DCE_RX                                        = IOMUX_PAD(0x033C, 0x00D4, 3, 0x050C, 4, 0),
+	IMX8MN_PAD_SD2_CLK__UART4_DTE_TX                                        = IOMUX_PAD(0x033C, 0x00D4, 3, 0x0000, 0, 0),
+	IMX8MN_PAD_SD2_CLK__SAI5_MCLK                                           = IOMUX_PAD(0x033C, 0x00D4, 4, 0x0594, 1, 0),
+	IMX8MN_PAD_SD2_CLK__GPIO2_IO13                                          = IOMUX_PAD(0x033C, 0x00D4, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_SD2_CLK__CCMSRCGPCMIX_OBSERVE0                               = IOMUX_PAD(0x033C, 0x00D4, 6, 0x0000, 0, 0),
+
+	IMX8MN_PAD_SD2_CMD__USDHC2_CMD                                          = IOMUX_PAD(0x0340, 0x00D8, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_SD2_CMD__SAI5_RX_BCLK                                        = IOMUX_PAD(0x0340, 0x00D8, 1, 0x04D0, 1, 0),
+	IMX8MN_PAD_SD2_CMD__ECSPI2_MOSI                                         = IOMUX_PAD(0x0340, 0x00D8, 2, 0x0590, 1, 0),
+	IMX8MN_PAD_SD2_CMD__UART4_DCE_TX                                        = IOMUX_PAD(0x0340, 0x00D8, 3, 0x0000, 0, 0),
+	IMX8MN_PAD_SD2_CMD__UART4_DTE_RX                                        = IOMUX_PAD(0x0340, 0x00D8, 3, 0x050C, 5, 0),
+	IMX8MN_PAD_SD2_CMD__PDM_CLK                                             = IOMUX_PAD(0x0340, 0x00D8, 4, 0x0000, 0, 0),
+	IMX8MN_PAD_SD2_CMD__GPIO2_IO14                                          = IOMUX_PAD(0x0340, 0x00D8, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_SD2_CMD__CCMSRCGPCMIX_OBSERVE1                               = IOMUX_PAD(0x0340, 0x00D8, 6, 0x0000, 0, 0),
+
+	IMX8MN_PAD_SD2_DATA0__USDHC2_DATA0                                      = IOMUX_PAD(0x0344, 0x00DC, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_SD2_DATA0__SAI5_RX_DATA0                                     = IOMUX_PAD(0x0344, 0x00DC, 1, 0x04D4, 1, 0),
+	IMX8MN_PAD_SD2_DATA0__I2C4_SDA                                          = IOMUX_PAD(0x0344, 0x00DC, 2, 0x058C, 1, 0),
+	IMX8MN_PAD_SD2_DATA0__UART2_DCE_RX                                      = IOMUX_PAD(0x0344, 0x00DC, 3, 0x04FC, 6, 0),
+	IMX8MN_PAD_SD2_DATA0__UART2_DTE_TX                                      = IOMUX_PAD(0x0344, 0x00DC, 3, 0x0000, 0, 0),
+	IMX8MN_PAD_SD2_DATA0__PDM_BIT_STREAM0                                   = IOMUX_PAD(0x0344, 0x00DC, 4, 0x0534, 2, 0),
+	IMX8MN_PAD_SD2_DATA0__GPIO2_IO15                                        = IOMUX_PAD(0x0344, 0x00DC, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_SD2_DATA0__CCMSRCGPCMIX_OBSERVE2                             = IOMUX_PAD(0x0344, 0x00DC, 6, 0x0000, 0, 0),
+
+	IMX8MN_PAD_SD2_DATA1__USDHC2_DATA1                                      = IOMUX_PAD(0x0348, 0x00E0, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_SD2_DATA1__SAI5_TX_SYNC                                      = IOMUX_PAD(0x0348, 0x00E0, 1, 0x04EC, 1, 0),
+	IMX8MN_PAD_SD2_DATA1__I2C4_SCL                                          = IOMUX_PAD(0x0348, 0x00E0, 2, 0x05D4, 1, 0),
+	IMX8MN_PAD_SD2_DATA1__UART2_DCE_TX                                      = IOMUX_PAD(0x0348, 0x00E0, 3, 0x0000, 0, 0),
+	IMX8MN_PAD_SD2_DATA1__UART2_DTE_RX                                      = IOMUX_PAD(0x0348, 0x00E0, 3, 0x04FC, 7, 0),
+	IMX8MN_PAD_SD2_DATA1__PDM_BIT_STREAM1                                   = IOMUX_PAD(0x0348, 0x00E0, 4, 0x0538, 4, 0),
+	IMX8MN_PAD_SD2_DATA1__GPIO2_IO16                                        = IOMUX_PAD(0x0348, 0x00E0, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_SD2_DATA1__CCMSRCGPCMIX_WAIT                                 = IOMUX_PAD(0x0348, 0x00E0, 6, 0x0000, 0, 0),
+
+	IMX8MN_PAD_SD2_DATA2__USDHC2_DATA2                                      = IOMUX_PAD(0x034C, 0x00E4, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_SD2_DATA2__SAI5_TX_BCLK                                      = IOMUX_PAD(0x034C, 0x00E4, 1, 0x04E8, 1, 0),
+	IMX8MN_PAD_SD2_DATA2__ECSPI2_SS0                                        = IOMUX_PAD(0x034C, 0x00E4, 2, 0x0570, 2, 0),
+	IMX8MN_PAD_SD2_DATA2__SPDIF1_OUT                                        = IOMUX_PAD(0x034C, 0x00E4, 3, 0x0000, 0, 0),
+	IMX8MN_PAD_SD2_DATA2__PDM_BIT_STREAM2                                   = IOMUX_PAD(0x034C, 0x00E4, 4, 0x053C, 4, 0),
+	IMX8MN_PAD_SD2_DATA2__GPIO2_IO17                                        = IOMUX_PAD(0x034C, 0x00E4, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_SD2_DATA2__CCMSRCGPCMIX_STOP                                 = IOMUX_PAD(0x034C, 0x00E4, 6, 0x0000, 0, 0),
+
+	IMX8MN_PAD_SD2_DATA3__USDHC2_DATA3                                      = IOMUX_PAD(0x0350, 0x00E8, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_SD2_DATA3__SAI5_TX_DATA0                                     = IOMUX_PAD(0x0350, 0x00E8, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_SD2_DATA3__ECSPI2_MISO                                       = IOMUX_PAD(0x0350, 0x00E8, 2, 0x0578, 1, 0),
+	IMX8MN_PAD_SD2_DATA3__SPDIF1_IN                                         = IOMUX_PAD(0x0350, 0x00E8, 3, 0x05CC, 2, 0),
+	IMX8MN_PAD_SD2_DATA3__PDM_BIT_STREAM3                                   = IOMUX_PAD(0x0350, 0x00E8, 4, 0x0540, 4, 0),
+	IMX8MN_PAD_SD2_DATA3__GPIO2_IO18                                        = IOMUX_PAD(0x0350, 0x00E8, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_SD2_DATA3__CCMSRCGPCMIX_EARLY_RESET                          = IOMUX_PAD(0x0350, 0x00E8, 6, 0x0000, 0, 0),
+
+	IMX8MN_PAD_SD2_RESET_B__USDHC2_RESET_B                                  = IOMUX_PAD(0x0354, 0x00EC, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_SD2_RESET_B__GPIO2_IO19                                      = IOMUX_PAD(0x0354, 0x00EC, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_SD2_RESET_B__CCMSRCGPCMIX_SYSTEM_RESET                       = IOMUX_PAD(0x0354, 0x00EC, 6, 0x0000, 0, 0),
+
+	IMX8MN_PAD_SD2_WP__USDHC2_WP                                            = IOMUX_PAD(0x0358, 0x00F0, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_SD2_WP__GPIO2_IO20                                           = IOMUX_PAD(0x0358, 0x00F0, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_SD2_WP__CORESIGHT_EVENTI                                     = IOMUX_PAD(0x0358, 0x00F0, 6, 0x0000, 0, 0),
+
+	IMX8MN_PAD_NAND_ALE__RAWNAND_ALE                                        = IOMUX_PAD(0x035C, 0x00F4, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_ALE__QSPI_A_SCLK                                        = IOMUX_PAD(0x035C, 0x00F4, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_ALE__PDM_BIT_STREAM0                                    = IOMUX_PAD(0x035C, 0x00F4, 3, 0x0534, 3, 0),
+	IMX8MN_PAD_NAND_ALE__UART3_DCE_RX                                       = IOMUX_PAD(0x035C, 0x00F4, 4, 0x0504, 6, 0),
+	IMX8MN_PAD_NAND_ALE__UART3_DTE_TX                                       = IOMUX_PAD(0x035C, 0x00F4, 4, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_ALE__GPIO3_IO0                                          = IOMUX_PAD(0x035C, 0x00F4, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_ALE__CORESIGHT_TRACE_CLK                                = IOMUX_PAD(0x035C, 0x00F4, 6, 0x0000, 0, 0),
+
+	IMX8MN_PAD_NAND_CE0_B__RAWNAND_CE0_B                                    = IOMUX_PAD(0x0360, 0x00F8, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_CE0_B__QSPI_A_SS0_B                                     = IOMUX_PAD(0x0360, 0x00F8, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_CE0_B__PDM_BIT_STREAM1                                  = IOMUX_PAD(0x0360, 0x00F8, 3, 0x0538, 5, 0),
+	IMX8MN_PAD_NAND_CE0_B__UART3_DCE_TX                                     = IOMUX_PAD(0x0360, 0x00F8, 4, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_CE0_B__UART3_DTE_RX                                     = IOMUX_PAD(0x0360, 0x00F8, 4, 0x0504, 7, 0),
+	IMX8MN_PAD_NAND_CE0_B__GPIO3_IO1                                        = IOMUX_PAD(0x0360, 0x00F8, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_CE0_B__CORESIGHT_TRACE_CTL                              = IOMUX_PAD(0x0360, 0x00F8, 6, 0x0000, 0, 0),
+
+	IMX8MN_PAD_NAND_CE1_B__RAWNAND_CE1_B                                    = IOMUX_PAD(0x0364, 0x00FC, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_CE1_B__QSPI_A_SS1_B                                     = IOMUX_PAD(0x0364, 0x00FC, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_CE1_B__USDHC3_STROBE                                    = IOMUX_PAD(0x0364, 0x00FC, 2, 0x059C, 0, 0),
+	IMX8MN_PAD_NAND_CE1_B__PDM_BIT_STREAM0                                  = IOMUX_PAD(0x0364, 0x00FC, 3, 0x0534, 4, 0),
+	IMX8MN_PAD_NAND_CE1_B__I2C4_SCL                                         = IOMUX_PAD(0x0364, 0x00FC, 4, 0x05D4, 2, 0),
+	IMX8MN_PAD_NAND_CE1_B__GPIO3_IO2                                        = IOMUX_PAD(0x0364, 0x00FC, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_CE1_B__CORESIGHT_TRACE0                                 = IOMUX_PAD(0x0364, 0x00FC, 6, 0x0000, 0, 0),
+
+	IMX8MN_PAD_NAND_CE2_B__RAWNAND_CE2_B                                    = IOMUX_PAD(0x0368, 0x0100, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_CE2_B__QSPI_B_SS0_B                                     = IOMUX_PAD(0x0368, 0x0100, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_CE2_B__USDHC3_DATA5                                     = IOMUX_PAD(0x0368, 0x0100, 2, 0x0550, 0, 0),
+	IMX8MN_PAD_NAND_CE2_B__PDM_BIT_STREAM1                                  = IOMUX_PAD(0x0368, 0x0100, 3, 0x0538, 6, 0),
+	IMX8MN_PAD_NAND_CE2_B__I2C4_SDA                                         = IOMUX_PAD(0x0368, 0x0100, 4, 0x058C, 2, 0),
+	IMX8MN_PAD_NAND_CE2_B__GPIO3_IO3                                        = IOMUX_PAD(0x0368, 0x0100, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_CE2_B__CORESIGHT_TRACE1                                 = IOMUX_PAD(0x0368, 0x0100, 6, 0x0000, 0, 0),
+
+	IMX8MN_PAD_NAND_CE3_B__RAWNAND_CE3_B                                    = IOMUX_PAD(0x036C, 0x0104, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_CE3_B__QSPI_B_SS1_B                                     = IOMUX_PAD(0x036C, 0x0104, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_CE3_B__USDHC3_DATA6                                     = IOMUX_PAD(0x036C, 0x0104, 2, 0x0584, 0, 0),
+	IMX8MN_PAD_NAND_CE3_B__PDM_BIT_STREAM2                                  = IOMUX_PAD(0x036C, 0x0104, 3, 0x053C, 5, 0),
+	IMX8MN_PAD_NAND_CE3_B__I2C3_SDA                                         = IOMUX_PAD(0x036C, 0x0104, 4, 0x05BC, 2, 0),
+	IMX8MN_PAD_NAND_CE3_B__GPIO3_IO4                                        = IOMUX_PAD(0x036C, 0x0104, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_CE3_B__CORESIGHT_TRACE2                                 = IOMUX_PAD(0x036C, 0x0104, 6, 0x0000, 0, 0),
+
+	IMX8MN_PAD_NAND_CLE__RAWNAND_CLE                                        = IOMUX_PAD(0x0370, 0x0108, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_CLE__QSPI_B_SCLK                                        = IOMUX_PAD(0x0370, 0x0108, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_CLE__USDHC3_DATA7                                       = IOMUX_PAD(0x0370, 0x0108, 2, 0x054C, 0, 0),
+	IMX8MN_PAD_NAND_CLE__GPIO3_IO5                                          = IOMUX_PAD(0x0370, 0x0108, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_CLE__CORESIGHT_TRACE3                                   = IOMUX_PAD(0x0370, 0x0108, 6, 0x0000, 0, 0),
+
+	IMX8MN_PAD_NAND_DATA00__RAWNAND_DATA00                                  = IOMUX_PAD(0x0374, 0x010C, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_DATA00__QSPI_A_DATA0                                    = IOMUX_PAD(0x0374, 0x010C, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_DATA00__PDM_BIT_STREAM2                                 = IOMUX_PAD(0x0374, 0x010C, 3, 0x053C, 6, 0),
+	IMX8MN_PAD_NAND_DATA00__UART4_DCE_RX                                    = IOMUX_PAD(0x0374, 0x010C, 4, 0x050C, 6, 0),
+	IMX8MN_PAD_NAND_DATA00__UART4_DTE_TX                                    = IOMUX_PAD(0x0374, 0x010C, 4, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_DATA00__GPIO3_IO6                                       = IOMUX_PAD(0x0374, 0x010C, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_DATA00__CORESIGHT_TRACE4                                = IOMUX_PAD(0x0374, 0x010C, 6, 0x0000, 0, 0),
+
+	IMX8MN_PAD_NAND_DATA01__RAWNAND_DATA01                                  = IOMUX_PAD(0x0378, 0x0110, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_DATA01__QSPI_A_DATA1                                    = IOMUX_PAD(0x0378, 0x0110, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_DATA01__PDM_BIT_STREAM3                                 = IOMUX_PAD(0x0378, 0x0110, 3, 0x0540, 5, 0),
+	IMX8MN_PAD_NAND_DATA01__UART4_DCE_TX                                    = IOMUX_PAD(0x0378, 0x0110, 4, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_DATA01__UART4_DTE_RX                                    = IOMUX_PAD(0x0378, 0x0110, 4, 0x050C, 7, 0),
+	IMX8MN_PAD_NAND_DATA01__GPIO3_IO7                                       = IOMUX_PAD(0x0378, 0x0110, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_DATA01__CORESIGHT_TRACE5                                = IOMUX_PAD(0x0378, 0x0110, 6, 0x0000, 0, 0),
+
+	IMX8MN_PAD_NAND_DATA02__RAWNAND_DATA02                                  = IOMUX_PAD(0x037C, 0x0114, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_DATA02__QSPI_A_DATA2                                    = IOMUX_PAD(0x037C, 0x0114, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_DATA02__USDHC3_CD_B                                     = IOMUX_PAD(0x037C, 0x0114, 2, 0x0598, 0, 0),
+	IMX8MN_PAD_NAND_DATA02__I2C4_SDA                                        = IOMUX_PAD(0x037C, 0x0114, 4, 0x058C, 3, 0),
+	IMX8MN_PAD_NAND_DATA02__GPIO3_IO8                                       = IOMUX_PAD(0x037C, 0x0114, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_DATA02__CORESIGHT_TRACE6                                = IOMUX_PAD(0x037C, 0x0114, 6, 0x0000, 0, 0),
+
+	IMX8MN_PAD_NAND_DATA03__RAWNAND_DATA03                                  = IOMUX_PAD(0x0380, 0x0118, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_DATA03__QSPI_A_DATA3                                    = IOMUX_PAD(0x0380, 0x0118, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_DATA03__USDHC3_WP                                       = IOMUX_PAD(0x0380, 0x0118, 2, 0x05B8, 0, 0),
+	IMX8MN_PAD_NAND_DATA03__GPIO3_IO9                                       = IOMUX_PAD(0x0380, 0x0118, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_DATA03__CORESIGHT_TRACE7                                = IOMUX_PAD(0x0380, 0x0118, 6, 0x0000, 0, 0),
+
+	IMX8MN_PAD_NAND_DATA04__RAWNAND_DATA04                                  = IOMUX_PAD(0x0384, 0x011C, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_DATA04__QSPI_B_DATA0                                    = IOMUX_PAD(0x0384, 0x011C, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_DATA04__USDHC3_DATA0                                    = IOMUX_PAD(0x0384, 0x011C, 2, 0x05B4, 0, 0),
+	IMX8MN_PAD_NAND_DATA04__GPIO3_IO10                                      = IOMUX_PAD(0x0384, 0x011C, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_DATA04__CORESIGHT_TRACE8                                = IOMUX_PAD(0x0384, 0x011C, 6, 0x0000, 0, 0),
+
+	IMX8MN_PAD_NAND_DATA05__RAWNAND_DATA05                                  = IOMUX_PAD(0x0388, 0x0120, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_DATA05__QSPI_B_DATA1                                    = IOMUX_PAD(0x0388, 0x0120, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_DATA05__USDHC3_DATA1                                    = IOMUX_PAD(0x0388, 0x0120, 2, 0x05B0, 0, 0),
+	IMX8MN_PAD_NAND_DATA05__GPIO3_IO11                                      = IOMUX_PAD(0x0388, 0x0120, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_DATA05__CORESIGHT_TRACE9                                = IOMUX_PAD(0x0388, 0x0120, 6, 0x0000, 0, 0),
+
+	IMX8MN_PAD_NAND_DATA06__RAWNAND_DATA06                                  = IOMUX_PAD(0x038C, 0x0124, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_DATA06__QSPI_B_DATA2                                    = IOMUX_PAD(0x038C, 0x0124, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_DATA06__USDHC3_DATA2                                    = IOMUX_PAD(0x038C, 0x0124, 2, 0x05E4, 0, 0),
+	IMX8MN_PAD_NAND_DATA06__GPIO3_IO12                                      = IOMUX_PAD(0x038C, 0x0124, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_DATA06__CORESIGHT_TRACE10                               = IOMUX_PAD(0x038C, 0x0124, 6, 0x0000, 0, 0),
+
+	IMX8MN_PAD_NAND_DATA07__RAWNAND_DATA07                                  = IOMUX_PAD(0x0390, 0x0128, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_DATA07__QSPI_B_DATA3                                    = IOMUX_PAD(0x0390, 0x0128, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_DATA07__USDHC3_DATA3                                    = IOMUX_PAD(0x0390, 0x0128, 2, 0x05E0, 0, 0),
+	IMX8MN_PAD_NAND_DATA07__GPIO3_IO13                                      = IOMUX_PAD(0x0390, 0x0128, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_DATA07__CORESIGHT_TRACE11                               = IOMUX_PAD(0x0390, 0x0128, 6, 0x0000, 0, 0),
+
+	IMX8MN_PAD_NAND_DQS__RAWNAND_DQS                                        = IOMUX_PAD(0x0394, 0x012C, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_DQS__QSPI_A_DQS                                         = IOMUX_PAD(0x0394, 0x012C, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_DQS__PDM_CLK                                            = IOMUX_PAD(0x0394, 0x012C, 3, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_DQS__I2C3_SCL                                           = IOMUX_PAD(0x0394, 0x012C, 4, 0x0588, 2, 0),
+	IMX8MN_PAD_NAND_DQS__GPIO3_IO14                                         = IOMUX_PAD(0x0394, 0x012C, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_DQS__CORESIGHT_TRACE12                                  = IOMUX_PAD(0x0394, 0x012C, 6, 0x0000, 0, 0),
+
+	IMX8MN_PAD_NAND_RE_B__RAWNAND_RE_B                                      = IOMUX_PAD(0x0398, 0x0130, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_RE_B__QSPI_B_DQS                                        = IOMUX_PAD(0x0398, 0x0130, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_RE_B__USDHC3_DATA4                                      = IOMUX_PAD(0x0398, 0x0130, 2, 0x0558, 0, 0),
+	IMX8MN_PAD_NAND_RE_B__PDM_BIT_STREAM1                                   = IOMUX_PAD(0x0398, 0x0130, 3, 0x0538, 7, 0),
+	IMX8MN_PAD_NAND_RE_B__GPIO3_IO15                                        = IOMUX_PAD(0x0398, 0x0130, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_RE_B__CORESIGHT_TRACE13                                 = IOMUX_PAD(0x0398, 0x0130, 6, 0x0000, 0, 0),
+
+	IMX8MN_PAD_NAND_READY_B__RAWNAND_READY_B                                = IOMUX_PAD(0x039C, 0x0134, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_READY_B__USDHC3_RESET_B                                 = IOMUX_PAD(0x039C, 0x0134, 2, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_READY_B__PDM_BIT_STREAM3                                = IOMUX_PAD(0x039C, 0x0134, 3, 0x0540, 6, 0),
+	IMX8MN_PAD_NAND_READY_B__I2C3_SCL                                       = IOMUX_PAD(0x039C, 0x0134, 4, 0x0588, 3, 0),
+	IMX8MN_PAD_NAND_READY_B__GPIO3_IO16                                     = IOMUX_PAD(0x039C, 0x0134, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_READY_B__CORESIGHT_TRACE14                              = IOMUX_PAD(0x039C, 0x0134, 6, 0x0000, 0, 0),
+
+	IMX8MN_PAD_NAND_WE_B__RAWNAND_WE_B                                      = IOMUX_PAD(0x03A0, 0x0138, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_WE_B__USDHC3_CLK                                        = IOMUX_PAD(0x03A0, 0x0138, 2  | IOMUX_CONFIG_SION, 0x05A0, 0, 0),
+	IMX8MN_PAD_NAND_WE_B__I2C3_SDA                                          = IOMUX_PAD(0x03A0, 0x0138, 4, 0x05BC, 3, 0),
+	IMX8MN_PAD_NAND_WE_B__GPIO3_IO17                                        = IOMUX_PAD(0x03A0, 0x0138, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_WE_B__CORESIGHT_TRACE15                                 = IOMUX_PAD(0x03A0, 0x0138, 6, 0x0000, 0, 0),
+
+	IMX8MN_PAD_NAND_WP_B__RAWNAND_WP_B                                      = IOMUX_PAD(0x03A4, 0x013C, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_WP_B__USDHC3_CMD                                        = IOMUX_PAD(0x03A4, 0x013C, 2, 0x05DC, 0, 0),
+	IMX8MN_PAD_NAND_WP_B__I2C4_SDA                                          = IOMUX_PAD(0x03A4, 0x013C, 4, 0x058C, 4, 0),
+	IMX8MN_PAD_NAND_WP_B__GPIO3_IO18                                        = IOMUX_PAD(0x03A4, 0x013C, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_NAND_WP_B__CORESIGHT_EVENTO                                  = IOMUX_PAD(0x03A4, 0x013C, 6, 0x0000, 0, 0),
+
+	IMX8MN_PAD_SAI5_RXFS__SAI5_RX_SYNC                                      = IOMUX_PAD(0x03A8, 0x0140, 0, 0x04E4, 0, 0),
+	IMX8MN_PAD_SAI5_RXFS__GPIO3_IO19                                        = IOMUX_PAD(0x03A8, 0x0140, 5, 0x0000, 0, 0),
+
+	IMX8MN_PAD_SAI5_RXC__SAI5_RX_BCLK                                       = IOMUX_PAD(0x03AC, 0x0144, 0, 0x04D0, 0, 0),
+	IMX8MN_PAD_SAI5_RXC__PDM_CLK                                            = IOMUX_PAD(0x03AC, 0x0144, 4, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI5_RXC__GPIO3_IO20                                         = IOMUX_PAD(0x03AC, 0x0144, 5, 0x0000, 0, 0),
+
+	IMX8MN_PAD_SAI5_RXD0__SAI5_RX_DATA0                                     = IOMUX_PAD(0x03B0, 0x0148, 0, 0x04D4, 0, 0),
+	IMX8MN_PAD_SAI5_RXD0__PDM_BIT_STREAM0                                   = IOMUX_PAD(0x03B0, 0x0148, 4, 0x0534, 0, 0),
+	IMX8MN_PAD_SAI5_RXD0__GPIO3_IO21                                        = IOMUX_PAD(0x03B0, 0x0148, 5, 0x0000, 0, 0),
+
+	IMX8MN_PAD_SAI5_RXD1__SAI5_RX_DATA1                                     = IOMUX_PAD(0x03B4, 0x014C, 0, 0x04D8, 0, 0),
+	IMX8MN_PAD_SAI5_RXD1__SAI5_TX_SYNC                                      = IOMUX_PAD(0x03B4, 0x014C, 3, 0x04EC, 0, 0),
+	IMX8MN_PAD_SAI5_RXD1__PDM_BIT_STREAM1                                   = IOMUX_PAD(0x03B4, 0x014C, 4, 0x0538, 0, 0),
+	IMX8MN_PAD_SAI5_RXD1__GPIO3_IO22                                        = IOMUX_PAD(0x03B4, 0x014C, 5, 0x0000, 0, 0),
+
+	IMX8MN_PAD_SAI5_RXD2__SAI5_RX_DATA2                                     = IOMUX_PAD(0x03B8, 0x0150, 0, 0x04DC, 0, 0),
+	IMX8MN_PAD_SAI5_RXD2__SAI5_TX_BCLK                                      = IOMUX_PAD(0x03B8, 0x0150, 3, 0x04E8, 0, 0),
+	IMX8MN_PAD_SAI5_RXD2__PDM_BIT_STREAM2                                   = IOMUX_PAD(0x03B8, 0x0150, 4, 0x053C, 0, 0),
+	IMX8MN_PAD_SAI5_RXD2__GPIO3_IO23                                        = IOMUX_PAD(0x03B8, 0x0150, 5, 0x0000, 0, 0),
+
+	IMX8MN_PAD_SAI5_RXD3__SAI5_RX_DATA3                                     = IOMUX_PAD(0x03BC, 0x0154, 0, 0x04E0, 0, 0),
+	IMX8MN_PAD_SAI5_RXD3__SAI5_TX_DATA0                                     = IOMUX_PAD(0x03BC, 0x0154, 3, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI5_RXD3__PDM_BIT_STREAM3                                   = IOMUX_PAD(0x03BC, 0x0154, 4, 0x0540, 0, 0),
+	IMX8MN_PAD_SAI5_RXD3__GPIO3_IO24                                        = IOMUX_PAD(0x03BC, 0x0154, 5, 0x0000, 0, 0),
+
+	IMX8MN_PAD_SAI5_MCLK__SAI5_MCLK                                         = IOMUX_PAD(0x03C0, 0x0158, 0, 0x0594, 0, 0),
+	IMX8MN_PAD_SAI5_MCLK__GPIO3_IO25                                        = IOMUX_PAD(0x03C0, 0x0158, 5, 0x0000, 0, 0),
+
+	IMX8MN_PAD_SAI2_RXFS__SAI2_RX_SYNC                                      = IOMUX_PAD(0x0418, 0x01B0, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI2_RXFS__SAI5_TX_SYNC                                      = IOMUX_PAD(0x0418, 0x01B0, 1, 0x04EC, 2, 0),
+	IMX8MN_PAD_SAI2_RXFS__SAI5_TX_DATA1                                     = IOMUX_PAD(0x0418, 0x01B0, 2, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI2_RXFS__SAI2_RX_DATA1                                     = IOMUX_PAD(0x0418, 0x01B0, 3, 0x05AC, 0, 0),
+	IMX8MN_PAD_SAI2_RXFS__UART1_DCE_TX                                      = IOMUX_PAD(0x0418, 0x01B0, 4, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI2_RXFS__UART1_DTE_RX                                      = IOMUX_PAD(0x0418, 0x01B0, 4, 0x04F4, 2, 0),
+	IMX8MN_PAD_SAI2_RXFS__GPIO4_IO21                                        = IOMUX_PAD(0x0418, 0x01B0, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI2_RXFS__PDM_BIT_STREAM2                                   = IOMUX_PAD(0x0418, 0x01B0, 6, 0x053C, 7, 0),
+
+	IMX8MN_PAD_SAI2_RXC__SAI2_RX_BCLK                                       = IOMUX_PAD(0x041C, 0x01B4, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI2_RXC__SAI5_TX_BCLK                                       = IOMUX_PAD(0x041C, 0x01B4, 1, 0x04E8, 2, 0),
+	IMX8MN_PAD_SAI2_RXC__UART1_DCE_RX                                       = IOMUX_PAD(0x041C, 0x01B4, 4, 0x04F4, 3, 0),
+	IMX8MN_PAD_SAI2_RXC__UART1_DTE_TX                                       = IOMUX_PAD(0x041C, 0x01B4, 4, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI2_RXC__GPIO4_IO22                                         = IOMUX_PAD(0x041C, 0x01B4, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI2_RXC__PDM_BIT_STREAM1                                    = IOMUX_PAD(0x041C, 0x01B4, 6, 0x0538, 8, 0),
+
+	IMX8MN_PAD_SAI2_RXD0__SAI2_RX_DATA0                                     = IOMUX_PAD(0x0420, 0x01B8, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI2_RXD0__SAI5_TX_DATA0                                     = IOMUX_PAD(0x0420, 0x01B8, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI2_RXD0__SAI2_TX_DATA1                                     = IOMUX_PAD(0x0420, 0x01B8, 3, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI2_RXD0__UART1_DCE_RTS_B                                   = IOMUX_PAD(0x0420, 0x01B8, 4, 0x04F0, 2, 0),
+	IMX8MN_PAD_SAI2_RXD0__UART1_DTE_CTS_B                                   = IOMUX_PAD(0x0420, 0x01B8, 4, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI2_RXD0__GPIO4_IO23                                        = IOMUX_PAD(0x0420, 0x01B8, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI2_RXD0__PDM_BIT_STREAM3                                   = IOMUX_PAD(0x0420, 0x01B8, 6, 0x0540, 7, 0),
+
+	IMX8MN_PAD_SAI2_TXFS__SAI2_TX_SYNC                                      = IOMUX_PAD(0x0424, 0x01BC, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI2_TXFS__SAI5_TX_DATA1                                     = IOMUX_PAD(0x0424, 0x01BC, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI2_TXFS__SAI2_TX_DATA1                                     = IOMUX_PAD(0x0424, 0x01BC, 3, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI2_TXFS__UART1_DCE_CTS_B                                   = IOMUX_PAD(0x0424, 0x01BC, 4, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI2_TXFS__UART1_DTE_RTS_B                                   = IOMUX_PAD(0x0424, 0x01BC, 4, 0x04F0, 3, 0),
+	IMX8MN_PAD_SAI2_TXFS__GPIO4_IO24                                        = IOMUX_PAD(0x0424, 0x01BC, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI2_TXFS__PDM_BIT_STREAM2                                   = IOMUX_PAD(0x0424, 0x01BC, 6, 0x053C, 8, 0),
+
+	IMX8MN_PAD_SAI2_TXC__SAI2_TX_BCLK                                       = IOMUX_PAD(0x0428, 0x01C0, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI2_TXC__SAI5_TX_DATA2                                      = IOMUX_PAD(0x0428, 0x01C0, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI2_TXC__GPIO4_IO25                                         = IOMUX_PAD(0x0428, 0x01C0, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI2_TXC__PDM_BIT_STREAM1                                    = IOMUX_PAD(0x0428, 0x01C0, 6, 0x0538, 9, 0),
+
+	IMX8MN_PAD_SAI2_TXD0__SAI2_TX_DATA0                                     = IOMUX_PAD(0x042C, 0x01C4, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI2_TXD0__SAI5_TX_DATA3                                     = IOMUX_PAD(0x042C, 0x01C4, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI2_TXD0__GPIO4_IO26                                        = IOMUX_PAD(0x042C, 0x01C4, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI2_TXD0__CCMSRCGPCMIX_BOOT_MODE4                           = IOMUX_PAD(0x042C, 0x01C4, 6, 0x0540, 8, 0),
+
+	IMX8MN_PAD_SAI2_MCLK__SAI2_MCLK                                         = IOMUX_PAD(0x0430, 0x01C8, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI2_MCLK__SAI5_MCLK                                         = IOMUX_PAD(0x0430, 0x01C8, 1, 0x0594, 2, 0),
+	IMX8MN_PAD_SAI2_MCLK__GPIO4_IO27                                        = IOMUX_PAD(0x0430, 0x01C8, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI2_MCLK__SAI3_MCLK                                         = IOMUX_PAD(0x0430, 0x01C8, 6, 0x05C0, 1, 0),
+
+	IMX8MN_PAD_SAI3_RXFS__SAI3_RX_SYNC                                      = IOMUX_PAD(0x0434, 0x01CC, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI3_RXFS__GPT1_CAPTURE1                                     = IOMUX_PAD(0x0434, 0x01CC, 1, 0x05F0, 0, 0),
+	IMX8MN_PAD_SAI3_RXFS__SAI5_RX_SYNC                                      = IOMUX_PAD(0x0434, 0x01CC, 2, 0x04E4, 2, 0),
+	IMX8MN_PAD_SAI3_RXFS__SAI3_RX_DATA1                                     = IOMUX_PAD(0x0434, 0x01CC, 3, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI3_RXFS__SPDIF1_IN                                         = IOMUX_PAD(0x0434, 0x01CC, 4, 0x05CC, 3, 0),
+	IMX8MN_PAD_SAI3_RXFS__GPIO4_IO28                                        = IOMUX_PAD(0x0434, 0x01CC, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI3_RXFS__PDM_BIT_STREAM0                                   = IOMUX_PAD(0x0434, 0x01CC, 6, 0x0534, 5, 0),
+
+	IMX8MN_PAD_SAI3_RXC__SAI3_RX_BCLK                                       = IOMUX_PAD(0x0438, 0x01D0, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI3_RXC__GPT1_CLK                                           = IOMUX_PAD(0x0438, 0x01D0, 1, 0x05E8, 0, 0),
+	IMX8MN_PAD_SAI3_RXC__SAI5_RX_BCLK                                       = IOMUX_PAD(0x0438, 0x01D0, 2, 0x04D0, 2, 0),
+	IMX8MN_PAD_SAI3_RXC__SAI2_RX_DATA1                                      = IOMUX_PAD(0x0438, 0x01D0, 3, 0x05AC, 2, 0),
+	IMX8MN_PAD_SAI3_RXC__UART2_DCE_CTS_B                                    = IOMUX_PAD(0x0438, 0x01D0, 4, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI3_RXC__UART2_DTE_RTS_B                                    = IOMUX_PAD(0x0438, 0x01D0, 4, 0x04F8, 2, 0),
+	IMX8MN_PAD_SAI3_RXC__GPIO4_IO29                                         = IOMUX_PAD(0x0438, 0x01D0, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI3_RXC__PDM_CLK                                            = IOMUX_PAD(0x0438, 0x01D0, 6, 0x0000, 0, 0),
+
+	IMX8MN_PAD_SAI3_RXD__SAI3_RX_DATA0                                      = IOMUX_PAD(0x043C, 0x01D4, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI3_RXD__GPT1_COMPARE1                                      = IOMUX_PAD(0x043C, 0x01D4, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI3_RXD__SAI5_RX_DATA0                                      = IOMUX_PAD(0x043C, 0x01D4, 2, 0x04D4, 2, 0),
+	IMX8MN_PAD_SAI3_RXD__SAI3_TX_DATA1                                      = IOMUX_PAD(0x043C, 0x01D4, 3, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI3_RXD__UART2_DCE_RTS_B                                    = IOMUX_PAD(0x043C, 0x01D4, 4, 0x04F8, 3, 0),
+	IMX8MN_PAD_SAI3_RXD__UART2_DTE_CTS_B                                    = IOMUX_PAD(0x043C, 0x01D4, 4, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI3_RXD__GPIO4_IO30                                         = IOMUX_PAD(0x043C, 0x01D4, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI3_RXD__PDM_BIT_STREAM1                                    = IOMUX_PAD(0x043C, 0x01D4, 6, 0x0538, 10, 0),
+
+	IMX8MN_PAD_SAI3_TXFS__SAI3_TX_SYNC                                      = IOMUX_PAD(0x0440, 0x01D8, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI3_TXFS__GPT1_CAPTURE2                                     = IOMUX_PAD(0x0440, 0x01D8, 1, 0x05EC, 0, 0),
+	IMX8MN_PAD_SAI3_TXFS__SAI5_RX_DATA1                                     = IOMUX_PAD(0x0440, 0x01D8, 2, 0x04D8, 1, 0),
+	IMX8MN_PAD_SAI3_TXFS__SAI3_TX_DATA1                                     = IOMUX_PAD(0x0440, 0x01D8, 3, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI3_TXFS__UART2_DCE_RX                                      = IOMUX_PAD(0x0440, 0x01D8, 4, 0x04FC, 2, 0),
+	IMX8MN_PAD_SAI3_TXFS__UART2_DTE_TX                                      = IOMUX_PAD(0x0440, 0x01D8, 4, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI3_TXFS__GPIO4_IO31                                        = IOMUX_PAD(0x0440, 0x01D8, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI3_TXFS__PDM_BIT_STREAM3                                   = IOMUX_PAD(0x0440, 0x01D8, 6, 0x0540, 9, 0),
+
+	IMX8MN_PAD_SAI3_TXC__SAI3_TX_BCLK                                       = IOMUX_PAD(0x0444, 0x01DC, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI3_TXC__GPT1_COMPARE2                                      = IOMUX_PAD(0x0444, 0x01DC, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI3_TXC__SAI5_RX_DATA2                                      = IOMUX_PAD(0x0444, 0x01DC, 2, 0x04DC, 1, 0),
+	IMX8MN_PAD_SAI3_TXC__SAI2_TX_DATA1                                      = IOMUX_PAD(0x0444, 0x01DC, 3, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI3_TXC__UART2_DCE_TX                                       = IOMUX_PAD(0x0444, 0x01DC, 4, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI3_TXC__UART2_DTE_RX                                       = IOMUX_PAD(0x0444, 0x01DC, 4, 0x04FC, 3, 0),
+	IMX8MN_PAD_SAI3_TXC__GPIO5_IO0                                          = IOMUX_PAD(0x0444, 0x01DC, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI3_TXC__PDM_BIT_STREAM2                                    = IOMUX_PAD(0x0444, 0x01DC, 6, 0x053C, 9, 0),
+
+	IMX8MN_PAD_SAI3_TXD__SAI3_TX_DATA0                                      = IOMUX_PAD(0x0448, 0x01E0, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI3_TXD__GPT1_COMPARE3                                      = IOMUX_PAD(0x0448, 0x01E0, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI3_TXD__SAI5_RX_DATA3                                      = IOMUX_PAD(0x0448, 0x01E0, 2, 0x04E0, 1, 0),
+	IMX8MN_PAD_SAI3_TXD__SPDIF1_EXT_CLK                                     = IOMUX_PAD(0x0448, 0x01E0, 4, 0x0568, 2, 0),
+	IMX8MN_PAD_SAI3_TXD__GPIO5_IO1                                          = IOMUX_PAD(0x0448, 0x01E0, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI3_TXD__CCMSRCGPCMIX_BOOT_MODE5                            = IOMUX_PAD(0x0448, 0x01E0, 6, 0x0000, 0, 0),
+
+	IMX8MN_PAD_SAI3_MCLK__SAI3_MCLK                                         = IOMUX_PAD(0x044C, 0x01E4, 0, 0x05C0, 0, 0),
+	IMX8MN_PAD_SAI3_MCLK__PWM4_OUT                                          = IOMUX_PAD(0x044C, 0x01E4, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI3_MCLK__SAI5_MCLK                                         = IOMUX_PAD(0x044C, 0x01E4, 2, 0x0594, 3, 0),
+	IMX8MN_PAD_SAI3_MCLK__SPDIF1_OUT                                        = IOMUX_PAD(0x044C, 0x01E4, 4, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI3_MCLK__GPIO5_IO2                                         = IOMUX_PAD(0x044C, 0x01E4, 5, 0x0000, 0, 0),
+	IMX8MN_PAD_SAI3_MCLK__SPDIF1_IN                                         = IOMUX_PAD(0x044C, 0x01E4, 6, 0x05CC, 4, 0),
+
+	IMX8MN_PAD_SPDIF_TX__SPDIF1_OUT                                         = IOMUX_PAD(0x0450, 0x01E8, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_SPDIF_TX__PWM3_OUT                                           = IOMUX_PAD(0x0450, 0x01E8, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_SPDIF_TX__GPIO5_IO3                                          = IOMUX_PAD(0x0450, 0x01E8, 5, 0x0000, 0, 0),
+
+	IMX8MN_PAD_SPDIF_RX__SPDIF1_IN                                          = IOMUX_PAD(0x0454, 0x01EC, 0, 0x05CC, 0, 0),
+	IMX8MN_PAD_SPDIF_RX__PWM2_OUT                                           = IOMUX_PAD(0x0454, 0x01EC, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_SPDIF_RX__GPIO5_IO4                                          = IOMUX_PAD(0x0454, 0x01EC, 5, 0x0000, 0, 0),
+
+	IMX8MN_PAD_SPDIF_EXT_CLK__SPDIF1_EXT_CLK                                = IOMUX_PAD(0x0458, 0x01F0, 0, 0x0568, 0, 0),
+	IMX8MN_PAD_SPDIF_EXT_CLK__PWM1_OUT                                      = IOMUX_PAD(0x0458, 0x01F0, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_SPDIF_EXT_CLK__GPIO5_IO5                                     = IOMUX_PAD(0x0458, 0x01F0, 5, 0x0000, 0, 0),
+
+	IMX8MN_PAD_ECSPI1_SCLK__ECSPI1_SCLK                                     = IOMUX_PAD(0x045C, 0x01F4, 0, 0x05D8, 0, 0),
+	IMX8MN_PAD_ECSPI1_SCLK__UART3_DCE_RX                                    = IOMUX_PAD(0x045C, 0x01F4, 1, 0x0504, 0, 0),
+	IMX8MN_PAD_ECSPI1_SCLK__UART3_DTE_TX                                    = IOMUX_PAD(0x045C, 0x01F4, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_ECSPI1_SCLK__I2C1_SCL                                        = IOMUX_PAD(0x045C, 0x01F4, 2, 0x055C, 2, 0),
+	IMX8MN_PAD_ECSPI1_SCLK__SAI5_RX_SYNC                                    = IOMUX_PAD(0x045C, 0x01F4, 3, 0x04DC, 2, 0),
+	IMX8MN_PAD_ECSPI1_SCLK__GPIO5_IO6                                       = IOMUX_PAD(0x045C, 0x01F4, 5, 0x0000, 0, 0),
+
+	IMX8MN_PAD_ECSPI1_MOSI__ECSPI1_MOSI                                     = IOMUX_PAD(0x0460, 0x01F8, 0, 0x05A8, 0, 0),
+	IMX8MN_PAD_ECSPI1_MOSI__UART3_DCE_TX                                    = IOMUX_PAD(0x0460, 0x01F8, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_ECSPI1_MOSI__UART3_DTE_RX                                    = IOMUX_PAD(0x0460, 0x01F8, 1, 0x0504, 1, 0),
+	IMX8MN_PAD_ECSPI1_MOSI__I2C1_SDA                                        = IOMUX_PAD(0x0460, 0x01F8, 2, 0x056C, 2, 0),
+	IMX8MN_PAD_ECSPI1_MOSI__SAI5_RX_BCLK                                    = IOMUX_PAD(0x0460, 0x01F8, 3, 0x04D0, 3, 0),
+	IMX8MN_PAD_ECSPI1_MOSI__GPIO5_IO7                                       = IOMUX_PAD(0x0460, 0x01F8, 5, 0x0000, 0, 0),
+
+	IMX8MN_PAD_ECSPI1_MISO__ECSPI1_MISO                                     = IOMUX_PAD(0x0464, 0x01FC, 0, 0x05C4, 0, 0),
+	IMX8MN_PAD_ECSPI1_MISO__UART3_DCE_CTS_B                                 = IOMUX_PAD(0x0464, 0x01FC, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_ECSPI1_MISO__UART3_DTE_RTS_B                                 = IOMUX_PAD(0x0464, 0x01FC, 1, 0x0500, 0, 0),
+	IMX8MN_PAD_ECSPI1_MISO__I2C2_SCL                                        = IOMUX_PAD(0x0464, 0x01FC, 2, 0x05D0, 2, 0),
+	IMX8MN_PAD_ECSPI1_MISO__SAI5_RX_DATA0                                   = IOMUX_PAD(0x0464, 0x01FC, 3, 0x04D4, 3, 0),
+	IMX8MN_PAD_ECSPI1_MISO__GPIO5_IO8                                       = IOMUX_PAD(0x0464, 0x01FC, 5, 0x0000, 0, 0),
+
+	IMX8MN_PAD_ECSPI1_SS0__ECSPI1_SS0                                       = IOMUX_PAD(0x0468, 0x0200, 0, 0x0564, 0, 0),
+	IMX8MN_PAD_ECSPI1_SS0__UART3_DCE_RTS_B                                  = IOMUX_PAD(0x0468, 0x0200, 1, 0x0500, 1, 0),
+	IMX8MN_PAD_ECSPI1_SS0__UART3_DTE_CTS_B                                  = IOMUX_PAD(0x0468, 0x0200, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_ECSPI1_SS0__I2C2_SDA                                         = IOMUX_PAD(0x0468, 0x0200, 2, 0x0560, 2, 0),
+	IMX8MN_PAD_ECSPI1_SS0__SAI5_RX_DATA1                                    = IOMUX_PAD(0x0468, 0x0200, 3, 0x04D8, 2, 0),
+	IMX8MN_PAD_ECSPI1_SS0__SAI5_TX_SYNC                                     = IOMUX_PAD(0x0468, 0x0200, 4, 0x04EC, 3, 0),
+	IMX8MN_PAD_ECSPI1_SS0__GPIO5_IO9                                        = IOMUX_PAD(0x0468, 0x0200, 5, 0x0000, 0, 0),
+
+	IMX8MN_PAD_ECSPI2_SCLK__ECSPI2_SCLK                                     = IOMUX_PAD(0x046C, 0x0204, 0, 0x0580, 0, 0),
+	IMX8MN_PAD_ECSPI2_SCLK__UART4_DCE_RX                                    = IOMUX_PAD(0x046C, 0x0204, 1, 0x050C, 0, 0),
+	IMX8MN_PAD_ECSPI2_SCLK__UART4_DTE_TX                                    = IOMUX_PAD(0x046C, 0x0204, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_ECSPI2_SCLK__I2C3_SCL                                        = IOMUX_PAD(0x046C, 0x0204, 2, 0x0588, 4, 0),
+	IMX8MN_PAD_ECSPI2_SCLK__SAI5_RX_DATA2                                   = IOMUX_PAD(0x046C, 0x0204, 3, 0x0000, 0, 0),
+	IMX8MN_PAD_ECSPI2_SCLK__SAI5_TX_BCLK                                    = IOMUX_PAD(0x046C, 0x0204, 4, 0x04E8, 3, 0),
+	IMX8MN_PAD_ECSPI2_SCLK__GPIO5_IO10                                      = IOMUX_PAD(0x046C, 0x0204, 5, 0x0000, 0, 0),
+
+	IMX8MN_PAD_ECSPI2_MOSI__ECSPI2_MOSI                                     = IOMUX_PAD(0x0470, 0x0208, 0, 0x0590, 0, 0),
+	IMX8MN_PAD_ECSPI2_MOSI__UART4_DCE_TX                                    = IOMUX_PAD(0x0470, 0x0208, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_ECSPI2_MOSI__UART4_DTE_RX                                    = IOMUX_PAD(0x0470, 0x0208, 1, 0x050C, 1, 0),
+	IMX8MN_PAD_ECSPI2_MOSI__I2C3_SDA                                        = IOMUX_PAD(0x0470, 0x0208, 2, 0x05BC, 4, 0),
+	IMX8MN_PAD_ECSPI2_MOSI__SAI5_RX_DATA3                                   = IOMUX_PAD(0x0470, 0x0208, 3, 0x04E0, 2, 0),
+	IMX8MN_PAD_ECSPI2_MOSI__SAI5_TX_DATA0                                   = IOMUX_PAD(0x0470, 0x0208, 4, 0x0000, 0, 0),
+	IMX8MN_PAD_ECSPI2_MOSI__GPIO5_IO11                                      = IOMUX_PAD(0x0470, 0x0208, 5, 0x0000, 0, 0),
+
+	IMX8MN_PAD_ECSPI2_MISO__ECSPI2_MISO                                     = IOMUX_PAD(0x0474, 0x020C, 0, 0x0578, 0, 0),
+	IMX8MN_PAD_ECSPI2_MISO__UART4_DCE_CTS_B                                 = IOMUX_PAD(0x0474, 0x020C, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_ECSPI2_MISO__UART4_DTE_RTS_B                                 = IOMUX_PAD(0x0474, 0x020C, 1, 0x0508, 0, 0),
+	IMX8MN_PAD_ECSPI2_MISO__I2C4_SCL                                        = IOMUX_PAD(0x0474, 0x020C, 2, 0x05D4, 3, 0),
+	IMX8MN_PAD_ECSPI2_MISO__SAI5_MCLK                                       = IOMUX_PAD(0x0474, 0x020C, 3, 0x0594, 4, 0),
+	IMX8MN_PAD_ECSPI2_MISO__GPIO5_IO12                                      = IOMUX_PAD(0x0474, 0x020C, 5, 0x0000, 0, 0),
+
+	IMX8MN_PAD_ECSPI2_SS0__ECSPI2_SS0                                       = IOMUX_PAD(0x0478, 0x0210, 0, 0x0570, 0, 0),
+	IMX8MN_PAD_ECSPI2_SS0__UART4_DCE_RTS_B                                  = IOMUX_PAD(0x0478, 0x0210, 1, 0x0508, 1, 0),
+	IMX8MN_PAD_ECSPI2_SS0__UART4_DTE_CTS_B                                  = IOMUX_PAD(0x0478, 0x0210, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_ECSPI2_SS0__I2C4_SDA                                         = IOMUX_PAD(0x0478, 0x0210, 2, 0x058C, 5, 0),
+	IMX8MN_PAD_ECSPI2_SS0__GPIO5_IO13                                       = IOMUX_PAD(0x0478, 0x0210, 5, 0x0000, 0, 0),
+
+	IMX8MN_PAD_I2C1_SCL__I2C1_SCL                                           = IOMUX_PAD(0x047C, 0x0214, 0 | IOMUX_CONFIG_SION, 0x055C, 0, 0),
+	IMX8MN_PAD_I2C1_SCL__ENET1_MDC                                          = IOMUX_PAD(0x047C, 0x0214, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_I2C1_SCL__ECSPI1_SCLK                                        = IOMUX_PAD(0x047C, 0x0214, 3, 0x05D8, 1, 0),
+	IMX8MN_PAD_I2C1_SCL__GPIO5_IO14                                         = IOMUX_PAD(0x047C, 0x0214, 5, 0x0000, 0, 0),
+
+	IMX8MN_PAD_I2C1_SDA__I2C1_SDA                                           = IOMUX_PAD(0x0480, 0x0218, 0 | IOMUX_CONFIG_SION, 0x056C, 0, 0),
+	IMX8MN_PAD_I2C1_SDA__ENET1_MDIO                                         = IOMUX_PAD(0x0480, 0x0218, 1, 0x04C0, 2, 0),
+	IMX8MN_PAD_I2C1_SDA__ECSPI1_MOSI                                        = IOMUX_PAD(0x0480, 0x0218, 3, 0x05A8, 1, 0),
+	IMX8MN_PAD_I2C1_SDA__GPIO5_IO15                                         = IOMUX_PAD(0x0480, 0x0218, 5, 0x0000, 0, 0),
+
+	IMX8MN_PAD_I2C2_SCL__I2C2_SCL                                           = IOMUX_PAD(0x0484, 0x021C, 0, 0x05D0, 0, 0),
+	IMX8MN_PAD_I2C2_SCL__ENET1_1588_EVENT1_IN                               = IOMUX_PAD(0x0484, 0x021C, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_I2C2_SCL__USDHC3_CD_B                                        = IOMUX_PAD(0x0484, 0x021C, 2, 0x0598, 1, 0),
+	IMX8MN_PAD_I2C2_SCL__ECSPI1_MISO                                        = IOMUX_PAD(0x0484, 0x021C, 3, 0x05C4, 1, 0),
+	IMX8MN_PAD_I2C2_SCL__GPIO5_IO16                                         = IOMUX_PAD(0x0484, 0x021C, 5, 0x0000, 0, 0),
+
+	IMX8MN_PAD_I2C2_SDA__I2C2_SDA                                           = IOMUX_PAD(0x0488, 0x0220, 0, 0x0560, 0, 0),
+	IMX8MN_PAD_I2C2_SDA__ENET1_1588_EVENT1_OUT                              = IOMUX_PAD(0x0488, 0x0220, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_I2C2_SDA__USDHC3_WP                                          = IOMUX_PAD(0x0488, 0x0220, 2, 0x05B8, 1, 0),
+	IMX8MN_PAD_I2C2_SDA__ECSPI1_SS0                                         = IOMUX_PAD(0x0488, 0x0220, 3, 0x0564, 1, 0),
+	IMX8MN_PAD_I2C2_SDA__GPIO5_IO17                                         = IOMUX_PAD(0x0488, 0x0220, 5, 0x0000, 0, 0),
+
+	IMX8MN_PAD_I2C3_SCL__I2C3_SCL                                           = IOMUX_PAD(0x048C, 0x0224, 0, 0x0588, 0, 0),
+	IMX8MN_PAD_I2C3_SCL__PWM4_OUT                                           = IOMUX_PAD(0x048C, 0x0224, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_I2C3_SCL__GPT2_CLK                                           = IOMUX_PAD(0x048C, 0x0224, 2, 0x0000, 0, 0),
+	IMX8MN_PAD_I2C3_SCL__ECSPI2_SCLK                                        = IOMUX_PAD(0x048C, 0x0224, 3, 0x0580, 2, 0),
+	IMX8MN_PAD_I2C3_SCL__GPIO5_IO18                                         = IOMUX_PAD(0x048C, 0x0224, 5, 0x0000, 0, 0),
+
+	IMX8MN_PAD_I2C3_SDA__I2C3_SDA                                           = IOMUX_PAD(0x0490, 0x0228, 0, 0x05BC, 0, 0),
+	IMX8MN_PAD_I2C3_SDA__PWM3_OUT                                           = IOMUX_PAD(0x0490, 0x0228, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_I2C3_SDA__GPT3_CLK                                           = IOMUX_PAD(0x0490, 0x0228, 2, 0x0000, 0, 0),
+	IMX8MN_PAD_I2C3_SDA__ECSPI2_MOSI                                        = IOMUX_PAD(0x0490, 0x0228, 3, 0x0590, 2, 0),
+	IMX8MN_PAD_I2C3_SDA__GPIO5_IO19                                         = IOMUX_PAD(0x0490, 0x0228, 5, 0x0000, 0, 0),
+
+	IMX8MN_PAD_I2C4_SCL__I2C4_SCL                                           = IOMUX_PAD(0x0494, 0x022C, 0, 0x05D4, 0, 0),
+	IMX8MN_PAD_I2C4_SCL__PWM2_OUT                                           = IOMUX_PAD(0x0494, 0x022C, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_I2C4_SCL__ECSPI2_MISO                                        = IOMUX_PAD(0x0494, 0x022C, 3, 0x0578, 2, 0),
+	IMX8MN_PAD_I2C4_SCL__GPIO5_IO20                                         = IOMUX_PAD(0x0494, 0x022C, 5, 0x0000, 0, 0),
+
+	IMX8MN_PAD_I2C4_SDA__I2C4_SDA                                           = IOMUX_PAD(0x0498, 0x0230, 0, 0x058C, 0, 0),
+	IMX8MN_PAD_I2C4_SDA__PWM1_OUT                                           = IOMUX_PAD(0x0498, 0x0230, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_I2C4_SDA__ECSPI2_SS0                                         = IOMUX_PAD(0x0498, 0x0230, 3, 0x0570, 1, 0),
+	IMX8MN_PAD_I2C4_SDA__GPIO5_IO21                                         = IOMUX_PAD(0x0498, 0x0230, 5, 0x0000, 0, 0),
+
+	IMX8MN_PAD_UART1_RXD__UART1_DCE_RX                                      = IOMUX_PAD(0x049C, 0x0234, 0, 0x04F4, 0, 0),
+	IMX8MN_PAD_UART1_RXD__UART1_DTE_TX                                      = IOMUX_PAD(0x049C, 0x0234, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_UART1_RXD__ECSPI3_SCLK                                       = IOMUX_PAD(0x049C, 0x0234, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_UART1_RXD__GPIO5_IO22                                        = IOMUX_PAD(0x049C, 0x0234, 5, 0x0000, 0, 0),
+
+	IMX8MN_PAD_UART1_TXD__UART1_DCE_TX                                      = IOMUX_PAD(0x04A0, 0x0238, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_UART1_TXD__UART1_DTE_RX                                      = IOMUX_PAD(0x04A0, 0x0238, 0, 0x04F4, 1, 0),
+	IMX8MN_PAD_UART1_TXD__ECSPI3_MOSI                                       = IOMUX_PAD(0x04A0, 0x0238, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_UART1_TXD__GPIO5_IO23                                        = IOMUX_PAD(0x04A0, 0x0238, 5, 0x0000, 0, 0),
+
+	IMX8MN_PAD_UART2_RXD__UART2_DCE_RX                                      = IOMUX_PAD(0x04A4, 0x023C, 0, 0x04FC, 0, 0),
+	IMX8MN_PAD_UART2_RXD__UART2_DTE_TX                                      = IOMUX_PAD(0x04A4, 0x023C, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_UART2_RXD__ECSPI3_MISO                                       = IOMUX_PAD(0x04A4, 0x023C, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_UART2_RXD__GPT1_COMPARE3                                     = IOMUX_PAD(0x04A4, 0x023C, 3, 0x0000, 0, 0),
+	IMX8MN_PAD_UART2_RXD__GPIO5_IO24                                        = IOMUX_PAD(0x04A4, 0x023C, 5, 0x0000, 0, 0),
+
+	IMX8MN_PAD_UART2_TXD__UART2_DCE_TX                                      = IOMUX_PAD(0x04A8, 0x0240, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_UART2_TXD__UART2_DTE_RX                                      = IOMUX_PAD(0x04A8, 0x0240, 0, 0x04FC, 1, 0),
+	IMX8MN_PAD_UART2_TXD__ECSPI3_SS0                                        = IOMUX_PAD(0x04A8, 0x0240, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_UART2_TXD__GPT1_COMPARE2                                     = IOMUX_PAD(0x04A8, 0x0240, 3, 0x0000, 0, 0),
+	IMX8MN_PAD_UART2_TXD__GPIO5_IO25                                        = IOMUX_PAD(0x04A8, 0x0240, 5, 0x0000, 0, 0),
+
+	IMX8MN_PAD_UART3_RXD__UART3_DCE_RX                                      = IOMUX_PAD(0x04AC, 0x0244, 0, 0x0504, 2, 0),
+	IMX8MN_PAD_UART3_RXD__UART3_DTE_TX                                      = IOMUX_PAD(0x04AC, 0x0244, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_UART3_RXD__UART1_DCE_CTS_B                                   = IOMUX_PAD(0x04AC, 0x0244, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_UART3_RXD__UART1_DTE_RTS_B                                   = IOMUX_PAD(0x04AC, 0x0244, 1, 0x04F0, 0, 0),
+	IMX8MN_PAD_UART3_RXD__USDHC3_RESET_B                                    = IOMUX_PAD(0x04AC, 0x0244, 2, 0x0000, 0, 0),
+	IMX8MN_PAD_UART3_RXD__GPT1_CAPTURE2                                     = IOMUX_PAD(0x04AC, 0x0244, 3, 0x05EC, 1, 0),
+	IMX8MN_PAD_UART3_RXD__GPIO5_IO26                                        = IOMUX_PAD(0x04AC, 0x0244, 5, 0x0000, 0, 0),
+
+	IMX8MN_PAD_UART3_TXD__UART3_DCE_TX                                      = IOMUX_PAD(0x04B0, 0x0248, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_UART3_TXD__UART3_DTE_RX                                      = IOMUX_PAD(0x04B0, 0x0248, 0, 0x0504, 3, 0),
+	IMX8MN_PAD_UART3_TXD__UART1_DCE_RTS_B                                   = IOMUX_PAD(0x04B0, 0x0248, 1, 0x04F0, 1, 0),
+	IMX8MN_PAD_UART3_TXD__UART1_DTE_CTS_B                                   = IOMUX_PAD(0x04B0, 0x0248, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_UART3_TXD__USDHC3_VSELECT                                    = IOMUX_PAD(0x04B0, 0x0248, 2, 0x0000, 0, 0),
+	IMX8MN_PAD_UART3_TXD__GPT1_CLK                                          = IOMUX_PAD(0x04B0, 0x0248, 3, 0x05E8, 1, 0),
+	IMX8MN_PAD_UART3_TXD__GPIO5_IO27                                        = IOMUX_PAD(0x04B0, 0x0248, 5, 0x0000, 0, 0),
+
+	IMX8MN_PAD_UART4_RXD__UART4_DCE_RX                                      = IOMUX_PAD(0x04B4, 0x024C, 0, 0x050C, 2, 0),
+	IMX8MN_PAD_UART4_RXD__UART4_DTE_TX                                      = IOMUX_PAD(0x04B4, 0x024C, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_UART4_RXD__UART2_DCE_CTS_B                                   = IOMUX_PAD(0x04B4, 0x024C, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_UART4_RXD__UART2_DTE_RTS_B                                   = IOMUX_PAD(0x04B4, 0x024C, 1, 0x04F8, 0, 0),
+	IMX8MN_PAD_UART4_RXD__GPT1_COMPARE1                                     = IOMUX_PAD(0x04B4, 0x024C, 3, 0x0000, 0, 0),
+	IMX8MN_PAD_UART4_RXD__GPIO5_IO28                                        = IOMUX_PAD(0x04B4, 0x024C, 5, 0x0000, 0, 0),
+
+	IMX8MN_PAD_UART4_TXD__UART4_DCE_TX                                      = IOMUX_PAD(0x04B8, 0x0250, 0, 0x0000, 0, 0),
+	IMX8MN_PAD_UART4_TXD__UART4_DTE_RX                                      = IOMUX_PAD(0x04B8, 0x0250, 0, 0x050C, 3, 0),
+	IMX8MN_PAD_UART4_TXD__UART2_DCE_RTS_B                                   = IOMUX_PAD(0x04B8, 0x0250, 1, 0x04F8, 1, 0),
+	IMX8MN_PAD_UART4_TXD__UART2_DTE_CTS_B                                   = IOMUX_PAD(0x04B8, 0x0250, 1, 0x0000, 0, 0),
+	IMX8MN_PAD_UART4_TXD__GPT1_CAPTURE1                                     = IOMUX_PAD(0x04B8, 0x0250, 3, 0x05F0, 1, 0),
+	IMX8MN_PAD_UART4_TXD__GPIO5_IO29                                        = IOMUX_PAD(0x04B8, 0x0250, 5, 0x0000, 0, 0),
+};
+#endif  /* __ASM_ARCH_IMX8MN_PINS_H__ */
diff --git a/arch/arm/include/asm/arch-px30/boot0.h b/arch/arm/include/asm/arch-px30/boot0.h
new file mode 100644
index 0000000..2e78b07
--- /dev/null
+++ b/arch/arm/include/asm/arch-px30/boot0.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2019 Rockchip Electronics Co., Ltd
+ */
+
+#ifndef __ASM_ARCH_BOOT0_H__
+#define __ASM_ARCH_BOOT0_H__
+
+#include <asm/arch-rockchip/boot0.h>
+
+#endif
diff --git a/arch/arm/include/asm/arch-px30/gpio.h b/arch/arm/include/asm/arch-px30/gpio.h
new file mode 100644
index 0000000..eca79d5
--- /dev/null
+++ b/arch/arm/include/asm/arch-px30/gpio.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2019 Rockchip Electronics Co., Ltd
+ */
+
+#ifndef __ASM_ARCH_GPIO_H__
+#define __ASM_ARCH_GPIO_H__
+
+#include <asm/arch-rockchip/gpio.h>
+
+#endif
diff --git a/arch/arm/include/asm/arch-rk3308/boot0.h b/arch/arm/include/asm/arch-rk3308/boot0.h
new file mode 100644
index 0000000..2e78b07
--- /dev/null
+++ b/arch/arm/include/asm/arch-rk3308/boot0.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2019 Rockchip Electronics Co., Ltd
+ */
+
+#ifndef __ASM_ARCH_BOOT0_H__
+#define __ASM_ARCH_BOOT0_H__
+
+#include <asm/arch-rockchip/boot0.h>
+
+#endif
diff --git a/arch/arm/include/asm/arch-rk3308/cru_rk3308.h b/arch/arm/include/asm/arch-rk3308/cru_rk3308.h
new file mode 100644
index 0000000..a14b64c
--- /dev/null
+++ b/arch/arm/include/asm/arch-rk3308/cru_rk3308.h
@@ -0,0 +1,290 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2018 Rockchip Electronics Co., Ltd.
+ */
+#ifndef _ASM_ARCH_CRU_RK3308_H
+#define _ASM_ARCH_CRU_RK3308_H
+
+#include <common.h>
+
+#define MHz		1000000
+#define OSC_HZ		(24 * MHz)
+
+#define APLL_HZ		(816 * MHz)
+
+#define CORE_ACLK_HZ	408000000
+#define CORE_DBG_HZ	204000000
+
+#define BUS_ACLK_HZ	200000000
+#define BUS_HCLK_HZ	100000000
+#define BUS_PCLK_HZ	100000000
+
+#define PERI_ACLK_HZ	200000000
+#define PERI_HCLK_HZ	100000000
+#define PERI_PCLK_HZ	100000000
+
+#define AUDIO_HCLK_HZ	100000000
+#define AUDIO_PCLK_HZ	100000000
+
+#define RK3308_PLL_CON(x)	((x) * 0x4)
+#define RK3308_MODE_CON		0xa0
+
+/* RK3308 pll id */
+enum rk3308_pll_id {
+	APLL,
+	DPLL,
+	VPLL0,
+	VPLL1,
+	PLL_COUNT,
+};
+
+struct rk3308_clk_info {
+	unsigned long id;
+	char *name;
+};
+
+/* Private data for the clock driver - used by rockchip_get_cru() */
+struct rk3308_clk_priv {
+	struct rk3308_cru *cru;
+	ulong armclk_hz;
+	ulong dpll_hz;
+	ulong vpll0_hz;
+	ulong vpll1_hz;
+};
+
+struct rk3308_cru {
+	struct rk3308_pll {
+		unsigned int con0;
+		unsigned int con1;
+		unsigned int con2;
+		unsigned int con3;
+		unsigned int con4;
+		unsigned int reserved0[3];
+	} pll[4];
+	unsigned int reserved1[8];
+	unsigned int mode;
+	unsigned int misc;
+	unsigned int reserved2[2];
+	unsigned int glb_cnt_th;
+	unsigned int glb_rst_st;
+	unsigned int glb_srst_fst;
+	unsigned int glb_srst_snd;
+	unsigned int glb_rst_con;
+	unsigned int pll_lock;
+	unsigned int reserved3[6];
+	unsigned int hwffc_con0;
+	unsigned int reserved4;
+	unsigned int hwffc_th;
+	unsigned int hwffc_intst;
+	unsigned int apll_con0_s;
+	unsigned int apll_con1_s;
+	unsigned int clksel_con0_s;
+	unsigned int reserved5;
+	unsigned int clksel_con[74];
+	unsigned int reserved6[54];
+	unsigned int clkgate_con[15];
+	unsigned int reserved7[(0x380 - 0x338) / 4 - 1];
+	unsigned int ssgtbl[32];
+	unsigned int softrst_con[10];
+	unsigned int reserved8[(0x480 - 0x424) / 4 - 1];
+	unsigned int sdmmc_con[2];
+	unsigned int sdio_con[2];
+	unsigned int emmc_con[2];
+};
+
+enum {
+	/* PLLCON0*/
+	PLL_BP_SHIFT		= 15,
+	PLL_POSTDIV1_SHIFT	= 12,
+	PLL_POSTDIV1_MASK	= 7 << PLL_POSTDIV1_SHIFT,
+	PLL_FBDIV_SHIFT		= 0,
+	PLL_FBDIV_MASK		= 0xfff,
+
+	/* PLLCON1 */
+	PLL_PDSEL_SHIFT		= 15,
+	PLL_PD1_SHIFT		= 14,
+	PLL_PD_SHIFT		= 13,
+	PLL_PD_MASK		= 1 << PLL_PD_SHIFT,
+	PLL_DSMPD_SHIFT		= 12,
+	PLL_DSMPD_MASK		= 1 << PLL_DSMPD_SHIFT,
+	PLL_LOCK_STATUS_SHIFT	= 10,
+	PLL_LOCK_STATUS_MASK	= 1 << PLL_LOCK_STATUS_SHIFT,
+	PLL_POSTDIV2_SHIFT	= 6,
+	PLL_POSTDIV2_MASK	= 7 << PLL_POSTDIV2_SHIFT,
+	PLL_REFDIV_SHIFT	= 0,
+	PLL_REFDIV_MASK		= 0x3f,
+
+	/* PLLCON2 */
+	PLL_FOUT4PHASEPD_SHIFT	= 27,
+	PLL_FOUTVCOPD_SHIFT	= 26,
+	PLL_FOUTPOSTDIVPD_SHIFT	= 25,
+	PLL_DACPD_SHIFT		= 24,
+	PLL_FRAC_DIV	= 0xffffff,
+
+	/* CRU_MODE */
+	PLLMUX_FROM_XIN24M	= 0,
+	PLLMUX_FROM_PLL,
+	PLLMUX_FROM_RTC32K,
+	USBPHY480M_MODE_SHIFT	= 8,
+	USBPHY480M_MODE_MASK	= 3 << USBPHY480M_MODE_SHIFT,
+	VPLL1_MODE_SHIFT		= 6,
+	VPLL1_MODE_MASK		= 3 << VPLL1_MODE_SHIFT,
+	VPLL0_MODE_SHIFT		= 4,
+	VPLL0_MODE_MASK		= 3 << VPLL0_MODE_SHIFT,
+	DPLL_MODE_SHIFT		= 2,
+	DPLL_MODE_MASK		= 3 << DPLL_MODE_SHIFT,
+	APLL_MODE_SHIFT		= 0,
+	APLL_MODE_MASK		= 3 << APLL_MODE_SHIFT,
+
+	/* CRU_CLK_SEL0_CON */
+	CORE_ACLK_DIV_SHIFT	= 12,
+	CORE_ACLK_DIV_MASK	= 0x7 << CORE_ACLK_DIV_SHIFT,
+	CORE_DBG_DIV_SHIFT	= 8,
+	CORE_DBG_DIV_MASK	= 0xf << CORE_DBG_DIV_SHIFT,
+	CORE_CLK_PLL_SEL_SHIFT	= 6,
+	CORE_CLK_PLL_SEL_MASK	= 0x3 << CORE_CLK_PLL_SEL_SHIFT,
+	CORE_CLK_PLL_SEL_APLL	= 0,
+	CORE_CLK_PLL_SEL_VPLL0,
+	CORE_CLK_PLL_SEL_VPLL1,
+	CORE_DIV_CON_SHIFT	= 0,
+	CORE_DIV_CON_MASK	= 0x0f << CORE_DIV_CON_SHIFT,
+
+	/* CRU_CLK_SEL5_CON */
+	BUS_PLL_SEL_SHIFT	= 6,
+	BUS_PLL_SEL_MASK	= 0x3 << BUS_PLL_SEL_SHIFT,
+	BUS_PLL_SEL_DPLL	= 0,
+	BUS_PLL_SEL_VPLL0,
+	BUS_PLL_SEL_VPLL1,
+	BUS_ACLK_DIV_SHIFT	= 0,
+	BUS_ACLK_DIV_MASK	= 0x1f << BUS_ACLK_DIV_SHIFT,
+
+	/* CRU_CLK_SEL6_CON */
+	BUS_PCLK_DIV_SHIFT	= 8,
+	BUS_PCLK_DIV_MASK	= 0x1f << BUS_PCLK_DIV_SHIFT,
+	BUS_HCLK_DIV_SHIFT	= 0,
+	BUS_HCLK_DIV_MASK	= 0x1f << BUS_HCLK_DIV_SHIFT,
+
+	/* CRU_CLK_SEL7_CON */
+	CRYPTO_APK_SEL_SHIFT	= 14,
+	CRYPTO_APK_PLL_SEL_MASK	= 3 << CRYPTO_APK_SEL_SHIFT,
+	CRYPTO_PLL_SEL_DPLL	= 0,
+	CRYPTO_PLL_SEL_VPLL0,
+	CRYPTO_PLL_SEL_VPLL1	= 0,
+	CRYPTO_APK_DIV_SHIFT	= 8,
+	CRYPTO_APK_DIV_MASK	= 0x1f << CRYPTO_APK_DIV_SHIFT,
+	CRYPTO_PLL_SEL_SHIFT	= 6,
+	CRYPTO_PLL_SEL_MASK	= 3 << CRYPTO_PLL_SEL_SHIFT,
+	CRYPTO_DIV_SHIFT	= 0,
+	CRYPTO_DIV_MASK		= 0x1f << CRYPTO_DIV_SHIFT,
+
+	/* CRU_CLK_SEL8_CON */
+	DCLK_VOP_SEL_SHIFT	= 14,
+	DCLK_VOP_SEL_MASK	= 0x3 << DCLK_VOP_SEL_SHIFT,
+	DCLK_VOP_SEL_DIVOUT	= 0,
+	DCLK_VOP_SEL_FRACOUT,
+	DCLK_VOP_SEL_24M,
+	DCLK_VOP_PLL_SEL_SHIFT	= 10,
+	DCLK_VOP_PLL_SEL_MASK	= 0x3 << DCLK_VOP_PLL_SEL_SHIFT,
+	DCLK_VOP_PLL_SEL_DPLL	= 0,
+	DCLK_VOP_PLL_SEL_VPLL0,
+	DCLK_VOP_PLL_SEL_VPLL1,
+	DCLK_VOP_DIV_SHIFT	= 0,
+	DCLK_VOP_DIV_MASK	= 0xff,
+
+	/* CRU_CLK_SEL25_CON */
+	/* CRU_CLK_SEL26_CON */
+	/* CRU_CLK_SEL27_CON */
+	/* CRU_CLK_SEL28_CON */
+	CLK_I2C_PLL_SEL_SHIFT		= 14,
+	CLK_I2C_PLL_SEL_MASK		= 0x3 << CLK_I2C_PLL_SEL_SHIFT,
+	CLK_I2C_PLL_SEL_DPLL		= 0,
+	CLK_I2C_PLL_SEL_VPLL0,
+	CLK_I2C_PLL_SEL_24M,
+	CLK_I2C_DIV_CON_SHIFT		= 0,
+	CLK_I2C_DIV_CON_MASK		= 0x7f << CLK_I2C_DIV_CON_SHIFT,
+
+	/* CRU_CLK_SEL29_CON */
+	CLK_PWM_PLL_SEL_SHIFT		= 14,
+	CLK_PWM_PLL_SEL_MASK		= 0x3 << CLK_PWM_PLL_SEL_SHIFT,
+	CLK_PWM_PLL_SEL_DPLL		= 0,
+	CLK_PWM_PLL_SEL_VPLL0,
+	CLK_PWM_PLL_SEL_24M,
+	CLK_PWM_DIV_CON_SHIFT		= 0,
+	CLK_PWM_DIV_CON_MASK		= 0x7f << CLK_PWM_DIV_CON_SHIFT,
+
+	/* CRU_CLK_SEL30_CON */
+	/* CRU_CLK_SEL31_CON */
+	/* CRU_CLK_SEL32_CON */
+	CLK_SPI_PLL_SEL_SHIFT		= 14,
+	CLK_SPI_PLL_SEL_MASK		= 0x3 << CLK_SPI_PLL_SEL_SHIFT,
+	CLK_SPI_PLL_SEL_DPLL		= 0,
+	CLK_SPI_PLL_SEL_VPLL0,
+	CLK_SPI_PLL_SEL_24M,
+	CLK_SPI_DIV_CON_SHIFT		= 0,
+	CLK_SPI_DIV_CON_MASK		= 0x7f << CLK_SPI_DIV_CON_SHIFT,
+
+	/* CRU_CLK_SEL34_CON */
+	CLK_SARADC_DIV_CON_SHIFT	= 0,
+	CLK_SARADC_DIV_CON_MASK		= 0x7ff << CLK_SARADC_DIV_CON_SHIFT,
+
+	/* CRU_CLK_SEL36_CON */
+	PERI_PLL_SEL_SHIFT	= 6,
+	PERI_PLL_SEL_MASK	= 0x3 << PERI_PLL_SEL_SHIFT,
+	PERI_PLL_DPLL		= 0,
+	PERI_PLL_VPLL0,
+	PERI_PLL_VPLL1,
+	PERI_ACLK_DIV_SHIFT	= 0,
+	PERI_ACLK_DIV_MASK	= 0x1f << PERI_ACLK_DIV_SHIFT,
+
+	/* CRU_CLK_SEL37_CON */
+	PERI_PCLK_DIV_SHIFT	= 8,
+	PERI_PCLK_DIV_MASK	= 0x1f << PERI_PCLK_DIV_SHIFT,
+	PERI_HCLK_DIV_SHIFT	= 0,
+	PERI_HCLK_DIV_MASK	= 0x1f << PERI_HCLK_DIV_SHIFT,
+
+	/* CRU_CLKSEL41_CON */
+	EMMC_CLK_SEL_SHIFT	= 15,
+	EMMC_CLK_SEL_MASK	= 1 << EMMC_CLK_SEL_SHIFT,
+	EMMC_CLK_SEL_EMMC	= 0,
+	EMMC_CLK_SEL_EMMC_DIV50,
+	EMMC_PLL_SHIFT		= 8,
+	EMMC_PLL_MASK		= 0x3 << EMMC_PLL_SHIFT,
+	EMMC_SEL_DPLL		= 0,
+	EMMC_SEL_VPLL0,
+	EMMC_SEL_VPLL1,
+	EMMC_SEL_24M,
+	EMMC_DIV_SHIFT		= 0,
+	EMMC_DIV_MASK		= 0xff << EMMC_DIV_SHIFT,
+
+	/* CRU_CLKSEL43_CON */
+	MAC_CLK_SPEED_SEL_SHIFT = 15,
+	MAC_CLK_SPEED_SEL_MASK = 1 << MAC_CLK_SPEED_SEL_SHIFT,
+	MAC_CLK_SPEED_SEL_10M = 0,
+	MAC_CLK_SPEED_SEL_100M,
+	MAC_CLK_SOURCE_SEL_SHIFT = 14,
+	MAC_CLK_SOURCE_SEL_MASK = 1 << MAC_CLK_SOURCE_SEL_SHIFT,
+	MAC_CLK_SOURCE_SEL_INTERNAL	= 0,
+	MAC_CLK_SOURCE_SEL_EXTERNAL,
+	MAC_PLL_SHIFT		= 6,
+	MAC_PLL_MASK		= 0x3 << MAC_PLL_SHIFT,
+	MAC_SEL_DPLL		= 0,
+	MAC_SEL_VPLL0,
+	MAC_SEL_VPLL1,
+	MAC_DIV_SHIFT		= 0,
+	MAC_DIV_MASK		= 0x1f << MAC_DIV_SHIFT,
+
+	/* CRU_CLK_SEL45_CON */
+	AUDIO_PCLK_DIV_SHIFT	= 8,
+	AUDIO_PCLK_DIV_MASK	= 0x1f << AUDIO_PCLK_DIV_SHIFT,
+	AUDIO_PLL_SEL_SHIFT	= 6,
+	AUDIO_PLL_SEL_MASK	= 0x3 << AUDIO_PLL_SEL_SHIFT,
+	AUDIO_PLL_VPLL0		= 0,
+	AUDIO_PLL_VPLL1,
+	AUDIO_PLL_24M,
+	AUDIO_HCLK_DIV_SHIFT	= 0,
+	AUDIO_HCLK_DIV_MASK	= 0x1f << AUDIO_HCLK_DIV_SHIFT,
+};
+
+check_member(rk3308_cru, emmc_con[1], 0x494);
+
+#endif
diff --git a/arch/arm/include/asm/arch-rk3308/gpio.h b/arch/arm/include/asm/arch-rk3308/gpio.h
new file mode 100644
index 0000000..eca79d5
--- /dev/null
+++ b/arch/arm/include/asm/arch-rk3308/gpio.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2019 Rockchip Electronics Co., Ltd
+ */
+
+#ifndef __ASM_ARCH_GPIO_H__
+#define __ASM_ARCH_GPIO_H__
+
+#include <asm/arch-rockchip/gpio.h>
+
+#endif
diff --git a/arch/arm/include/asm/arch-rk3308/grf_rk3308.h b/arch/arm/include/asm/arch-rk3308/grf_rk3308.h
new file mode 100644
index 0000000..3e68626
--- /dev/null
+++ b/arch/arm/include/asm/arch-rk3308/grf_rk3308.h
@@ -0,0 +1,197 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ *Copyright 2019 Rockchip Electronics Co., Ltd.
+ */
+#ifndef _ASM_ARCH_GRF_rk3308_H
+#define _ASM_ARCH_GRF_rk3308_H
+
+#include <common.h>
+
+struct rk3308_grf {
+	unsigned int gpio0a_iomux;
+	unsigned int reserved0;
+	unsigned int gpio0b_iomux;
+	unsigned int reserved1;
+	unsigned int gpio0c_iomux;
+	unsigned int reserved2[3];
+	unsigned int gpio1a_iomux;
+	unsigned int reserved3;
+	unsigned int gpio1bl_iomux;
+	unsigned int gpio1bh_iomux;
+	unsigned int gpio1cl_iomux;
+	unsigned int gpio1ch_iomux;
+	unsigned int gpio1d_iomux;
+	unsigned int reserved4;
+	unsigned int gpio2a_iomux;
+	unsigned int reserved5;
+	unsigned int gpio2b_iomux;
+	unsigned int reserved6;
+	unsigned int gpio2c_iomux;
+	unsigned int reserved7[3];
+	unsigned int gpio3a_iomux;
+	unsigned int reserved8;
+	unsigned int gpio3b_iomux;
+	unsigned int reserved9[5];
+	unsigned int gpio4a_iomux;
+	unsigned int reserved33;
+	unsigned int gpio4b_iomux;
+	unsigned int reserved10;
+	unsigned int gpio4c_iomux;
+	unsigned int reserved11;
+	unsigned int gpio4d_iomux;
+	unsigned int reserved34;
+	unsigned int gpio0a_p;
+	unsigned int gpio0b_p;
+	unsigned int gpio0c_p;
+	unsigned int reserved12;
+	unsigned int gpio1a_p;
+	unsigned int gpio1b_p;
+	unsigned int gpio1c_p;
+	unsigned int gpio1d_p;
+	unsigned int gpio2a_p;
+	unsigned int gpio2b_p;
+	unsigned int gpio2c_p;
+	unsigned int reserved13;
+	unsigned int gpio3a_p;
+	unsigned int gpio3b_p;
+	unsigned int reserved14[2];
+	unsigned int gpio4a_p;
+	unsigned int gpio4b_p;
+	unsigned int gpio4c_p;
+	unsigned int gpio4d_p;
+	unsigned int reserved15[(0x100 - 0xec) / 4 - 1];
+	unsigned int gpio0a_e;
+	unsigned int gpio0b_e;
+	unsigned int gpio0c_e;
+	unsigned int reserved16;
+	unsigned int gpio1a_e;
+	unsigned int gpio1b_e;
+	unsigned int gpio1c_e;
+	unsigned int gpio1d_e;
+	unsigned int gpio2a_e;
+	unsigned int gpio2b_e;
+	unsigned int gpio2c_e;
+	unsigned int reserved17;
+	unsigned int gpio3a_e;
+	unsigned int gpio3b_e;
+	unsigned int reserved18[2];
+	unsigned int gpio4a_e;
+	unsigned int gpio4b_e;
+	unsigned int gpio4c_e;
+	unsigned int gpio4d_e;
+	unsigned int gpio0a_sr;
+	unsigned int gpio0b_sr;
+	unsigned int gpio0c_sr;
+	unsigned int reserved19;
+	unsigned int gpio1a_sr;
+	unsigned int gpio1b_sr;
+	unsigned int gpio1c_sr;
+	unsigned int gpio1d_sr;
+	unsigned int gpio2a_sr;
+	unsigned int gpio2b_sr;
+	unsigned int gpio2c_sr;
+	unsigned int reserved20;
+	unsigned int gpio3a_sr;
+	unsigned int gpio3b_sr;
+	unsigned int reserved21[2];
+	unsigned int gpio4a_sr;
+	unsigned int gpio4b_sr;
+	unsigned int gpio4c_sr;
+	unsigned int gpio4d_sr;
+	unsigned int gpio0a_smt;
+	unsigned int gpio0b_smt;
+	unsigned int gpio0c_smt;
+	unsigned int reserved22;
+	unsigned int gpio1a_smt;
+	unsigned int gpio1b_smt;
+	unsigned int gpio1c_smt;
+	unsigned int gpio1d_smt;
+	unsigned int gpio2a_smt;
+	unsigned int gpio2b_smt;
+	unsigned int gpio2c_smt;
+	unsigned int reserved23;
+	unsigned int gpio3a_smt;
+	unsigned int gpio3b_smt;
+	unsigned int reserved35[2];
+	unsigned int gpio4a_smt;
+	unsigned int gpio4b_smt;
+	unsigned int gpio4c_smt;
+	unsigned int gpio4d_smt;
+	unsigned int reserved24[(0x300 - 0x1EC) / 4 - 1];
+	unsigned int soc_con0;
+	unsigned int soc_con1;
+	unsigned int soc_con2;
+	unsigned int soc_con3;
+	unsigned int soc_con4;
+	unsigned int soc_con5;
+	unsigned int soc_con6;
+	unsigned int soc_con7;
+	unsigned int soc_con8;
+	unsigned int soc_con9;
+	unsigned int soc_con10;
+	unsigned int reserved25[(0x380 - 0x328) / 4 - 1];
+	unsigned int soc_status0;
+	unsigned int reserved26[(0x400 - 0x380) / 4 - 1];
+	unsigned int cpu_con0;
+	unsigned int cpu_con1;
+	unsigned int cpu_con2;
+	unsigned int reserved27[(0x420 - 0x408) / 4 - 1];
+	unsigned int cpu_status0;
+	unsigned int cpu_status1;
+	unsigned int reserved28[(0x440 - 0x424) / 4 - 1];
+	unsigned int pvtm_con0;
+	unsigned int pvtm_con1;
+	unsigned int pvtm_status0;
+	unsigned int pvtm_status1;
+	unsigned int reserved29[(0x460 - 0x44C) / 4 - 1];
+	unsigned int tsadc_tbl;
+	unsigned int tsadc_tbh;
+	unsigned int reserved30[(0x480 - 0x464) / 4 - 1];
+	unsigned int host0_con0;
+	unsigned int host0_con1;
+	unsigned int otg_con0;
+	unsigned int host0_status0;
+	unsigned int reserved31[(0x4a0 - 0x48C) / 4 - 1];
+	unsigned int mac_con0;
+	unsigned int upctrl_con0;
+	unsigned int upctrl_status0;
+	unsigned int reserved32[(0x500 - 0x4A8) / 4 - 1];
+	unsigned int os_reg0;
+	unsigned int os_reg1;
+	unsigned int os_reg2;
+	unsigned int os_reg3;
+	unsigned int os_reg4;
+	unsigned int os_reg5;
+	unsigned int os_reg6;
+	unsigned int os_reg7;
+	unsigned int os_reg8;
+	unsigned int os_reg9;
+	unsigned int os_reg10;
+	unsigned int os_reg11;
+	unsigned int reserved38[(0x600 - 0x52c) / 4 - 1];
+	unsigned int soc_con12;
+	unsigned int reserved39;
+	unsigned int soc_con13;
+	unsigned int soc_con14;
+	unsigned int soc_con15;
+	unsigned int reserved40[(0x800 - 0x610) / 4 - 1];
+	unsigned int chip_id;
+};
+check_member(rk3308_grf, gpio0a_p, 0xa0);
+
+struct rk3308_sgrf {
+	unsigned int soc_con0;
+	unsigned int soc_con1;
+	unsigned int con_tzma_r0size;
+	unsigned int con_secure0;
+	unsigned int reserved0;
+	unsigned int clk_timer_en;
+	unsigned int clkgat_con;
+	unsigned int fastboot_addr;
+	unsigned int fastboot_en;
+	unsigned int reserved1[(0x30 - 0x24) / 4];
+	unsigned int srst_con;
+};
+check_member(rk3308_sgrf, fastboot_en, 0x20);
+
+#endif
diff --git a/arch/arm/include/asm/arch-rockchip/clock.h b/arch/arm/include/asm/arch-rockchip/clock.h
index 0eb19ca..8f7fc86 100644
--- a/arch/arm/include/asm/arch-rockchip/clock.h
+++ b/arch/arm/include/asm/arch-rockchip/clock.h
@@ -9,6 +9,7 @@
 /* define pll mode */
 #define RKCLK_PLL_MODE_SLOW		0
 #define RKCLK_PLL_MODE_NORMAL		1
+#define RKCLK_PLL_MODE_DEEP		2
 
 enum {
 	ROCKCHIP_SYSCON_NOC,
@@ -33,6 +34,81 @@
 	CLK_COUNT,
 };
 
+#define PLL(_type, _id, _con, _mode, _mshift,			\
+		 _lshift, _pflags, _rtable)			\
+	{							\
+		.id		= _id,				\
+		.type		= _type,			\
+		.con_offset	= _con,				\
+		.mode_offset	= _mode,			\
+		.mode_shift	= _mshift,			\
+		.lock_shift	= _lshift,			\
+		.pll_flags	= _pflags,			\
+		.rate_table	= _rtable,			\
+	}
+
+#define RK3036_PLL_RATE(_rate, _refdiv, _fbdiv, _postdiv1,	\
+			_postdiv2, _dsmpd, _frac)		\
+{								\
+	.rate	= _rate##U,					\
+	.fbdiv = _fbdiv,					\
+	.postdiv1 = _postdiv1,					\
+	.refdiv = _refdiv,					\
+	.postdiv2 = _postdiv2,					\
+	.dsmpd = _dsmpd,					\
+	.frac = _frac,						\
+}
+
+struct rockchip_pll_rate_table {
+	unsigned long rate;
+	unsigned int nr;
+	unsigned int nf;
+	unsigned int no;
+	unsigned int nb;
+	/* for RK3036/RK3399 */
+	unsigned int fbdiv;
+	unsigned int postdiv1;
+	unsigned int refdiv;
+	unsigned int postdiv2;
+	unsigned int dsmpd;
+	unsigned int frac;
+};
+
+enum rockchip_pll_type {
+	pll_rk3036,
+	pll_rk3066,
+	pll_rk3328,
+	pll_rk3366,
+	pll_rk3399,
+};
+
+struct rockchip_pll_clock {
+	unsigned int			id;
+	unsigned int			con_offset;
+	unsigned int			mode_offset;
+	unsigned int			mode_shift;
+	unsigned int			lock_shift;
+	enum rockchip_pll_type		type;
+	unsigned int			pll_flags;
+	struct rockchip_pll_rate_table *rate_table;
+	unsigned int			mode_mask;
+};
+
+struct rockchip_cpu_rate_table {
+	unsigned long rate;
+	unsigned int aclk_div;
+	unsigned int pclk_div;
+};
+
+int rockchip_pll_set_rate(struct rockchip_pll_clock *pll,
+			  void __iomem *base, ulong clk_id,
+			  ulong drate);
+ulong rockchip_pll_get_rate(struct rockchip_pll_clock *pll,
+			    void __iomem *base, ulong clk_id);
+const struct rockchip_cpu_rate_table *
+rockchip_get_cpu_settings(struct rockchip_cpu_rate_table *cpu_table,
+			  ulong rate);
+
 static inline int rk_pll_id(enum rk_clk_id clk_id)
 {
 	return clk_id - 1;
@@ -43,12 +119,6 @@
 	unsigned int glb_srst_snd_value;
 };
 
-struct softreset_reg {
-        void __iomem *base;
-        unsigned int sf_reset_offset;
-        unsigned int sf_reset_num;
-};
-
 /**
  * clk_get_divisor() - Calculate the required clock divisior
  *
diff --git a/arch/arm/include/asm/arch-rockchip/cru_px30.h b/arch/arm/include/asm/arch-rockchip/cru_px30.h
new file mode 100644
index 0000000..7d9fd18
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/cru_px30.h
@@ -0,0 +1,432 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2017 Rockchip Electronics Co., Ltd.
+ */
+#ifndef _ASM_ARCH_CRU_PX30_H
+#define _ASM_ARCH_CRU_PX30_H
+
+#include <common.h>
+
+#define MHz		1000000
+#define KHz		1000
+#define OSC_HZ		(24 * MHz)
+
+#define APLL_HZ		(600 * MHz)
+#define GPLL_HZ		(1200 * MHz)
+#define NPLL_HZ		(1188 * MHz)
+#define ACLK_BUS_HZ	(200 * MHz)
+#define HCLK_BUS_HZ	(150 * MHz)
+#define PCLK_BUS_HZ	(100 * MHz)
+#define ACLK_PERI_HZ	(200 * MHz)
+#define HCLK_PERI_HZ	(150 * MHz)
+#define PCLK_PMU_HZ	(100 * MHz)
+
+/* PX30 pll id */
+enum px30_pll_id {
+	APLL,
+	DPLL,
+	CPLL,
+	NPLL,
+	GPLL,
+	PLL_COUNT,
+};
+
+struct px30_clk_priv {
+	struct px30_cru *cru;
+	ulong gpll_hz;
+};
+
+struct px30_pmuclk_priv {
+	struct px30_pmucru *pmucru;
+	ulong gpll_hz;
+};
+
+struct px30_pll {
+	unsigned int con0;
+	unsigned int con1;
+	unsigned int con2;
+	unsigned int con3;
+	unsigned int con4;
+	unsigned int reserved0[3];
+};
+
+struct px30_cru {
+	struct px30_pll pll[4];
+	unsigned int reserved1[8];
+	unsigned int mode;
+	unsigned int misc;
+	unsigned int reserved2[2];
+	unsigned int glb_cnt_th;
+	unsigned int glb_rst_st;
+	unsigned int glb_srst_fst;
+	unsigned int glb_srst_snd;
+	unsigned int glb_rst_con;
+	unsigned int reserved3[7];
+	unsigned int hwffc_con0;
+	unsigned int reserved4;
+	unsigned int hwffc_th;
+	unsigned int hwffc_intst;
+	unsigned int apll_con0_s;
+	unsigned int apll_con1_s;
+	unsigned int clksel_con0_s;
+	unsigned int reserved5;
+	unsigned int clksel_con[60];
+	unsigned int reserved6[4];
+	unsigned int clkgate_con[18];
+	unsigned int reserved7[(0x280 - 0x244) / 4 - 1];
+	unsigned int ssgtbl[32];
+	unsigned int softrst_con[12];
+	unsigned int reserved8[(0x380 - 0x32c) / 4 - 1];
+	unsigned int sdmmc_con[2];
+	unsigned int sdio_con[2];
+	unsigned int emmc_con[2];
+	unsigned int reserved9[(0x400 - 0x394) / 4 - 1];
+	unsigned int autocs_con[8];
+};
+
+check_member(px30_cru, autocs_con[7], 0x41c);
+
+struct px30_pmucru {
+	struct px30_pll pll;
+	unsigned int pmu_mode;
+	unsigned int reserved1[7];
+	unsigned int pmu_clksel_con[6];
+	unsigned int reserved2[10];
+	unsigned int pmu_clkgate_con[2];
+	unsigned int reserved3[14];
+	unsigned int pmu_autocs_con[2];
+};
+
+check_member(px30_pmucru, pmu_autocs_con[1], 0xc4);
+
+struct pll_rate_table {
+	unsigned long rate;
+	unsigned int fbdiv;
+	unsigned int postdiv1;
+	unsigned int refdiv;
+	unsigned int postdiv2;
+	unsigned int dsmpd;
+	unsigned int frac;
+};
+
+struct cpu_rate_table {
+	unsigned long rate;
+	unsigned int aclk_div;
+	unsigned int pclk_div;
+};
+
+enum {
+	/* PLLCON0*/
+	PLL_BP_SHIFT		= 15,
+	PLL_POSTDIV1_SHIFT	= 12,
+	PLL_POSTDIV1_MASK	= 7 << PLL_POSTDIV1_SHIFT,
+	PLL_FBDIV_SHIFT		= 0,
+	PLL_FBDIV_MASK		= 0xfff,
+
+	/* PLLCON1 */
+	PLL_PDSEL_SHIFT		= 15,
+	PLL_PD1_SHIFT		= 14,
+	PLL_PD_SHIFT		= 13,
+	PLL_PD_MASK		= 1 << PLL_PD_SHIFT,
+	PLL_DSMPD_SHIFT		= 12,
+	PLL_DSMPD_MASK		= 1 << PLL_DSMPD_SHIFT,
+	PLL_LOCK_STATUS_SHIFT	= 10,
+	PLL_LOCK_STATUS_MASK	= 1 << PLL_LOCK_STATUS_SHIFT,
+	PLL_POSTDIV2_SHIFT	= 6,
+	PLL_POSTDIV2_MASK	= 7 << PLL_POSTDIV2_SHIFT,
+	PLL_REFDIV_SHIFT	= 0,
+	PLL_REFDIV_MASK		= 0x3f,
+
+	/* PLLCON2 */
+	PLL_FOUT4PHASEPD_SHIFT	= 27,
+	PLL_FOUTVCOPD_SHIFT	= 26,
+	PLL_FOUTPOSTDIVPD_SHIFT	= 25,
+	PLL_DACPD_SHIFT		= 24,
+	PLL_FRAC_DIV	= 0xffffff,
+
+	/* CRU_MODE */
+	PLLMUX_FROM_XIN24M	= 0,
+	PLLMUX_FROM_PLL,
+	PLLMUX_FROM_RTC32K,
+	USBPHY480M_MODE_SHIFT	= 8,
+	USBPHY480M_MODE_MASK	= 3 << USBPHY480M_MODE_SHIFT,
+	NPLL_MODE_SHIFT		= 6,
+	NPLL_MODE_MASK		= 3 << NPLL_MODE_SHIFT,
+	DPLL_MODE_SHIFT		= 4,
+	DPLL_MODE_MASK		= 3 << DPLL_MODE_SHIFT,
+	CPLL_MODE_SHIFT		= 2,
+	CPLL_MODE_MASK		= 3 << CPLL_MODE_SHIFT,
+	APLL_MODE_SHIFT		= 0,
+	APLL_MODE_MASK		= 3 << APLL_MODE_SHIFT,
+
+	/* CRU_CLK_SEL0_CON */
+	CORE_ACLK_DIV_SHIFT	= 12,
+	CORE_ACLK_DIV_MASK	= 0x07 << CORE_ACLK_DIV_SHIFT,
+	CORE_DBG_DIV_SHIFT	= 8,
+	CORE_DBG_DIV_MASK	= 0x03 << CORE_DBG_DIV_SHIFT,
+	CORE_CLK_PLL_SEL_SHIFT	= 7,
+	CORE_CLK_PLL_SEL_MASK	= 1 << CORE_CLK_PLL_SEL_SHIFT,
+	CORE_CLK_PLL_SEL_APLL	= 0,
+	CORE_CLK_PLL_SEL_GPLL,
+	CORE_DIV_CON_SHIFT	= 0,
+	CORE_DIV_CON_MASK	= 0x0f << CORE_DIV_CON_SHIFT,
+
+	/* CRU_CLK_SEL3_CON */
+	ACLK_VO_PLL_SHIFT	= 6,
+	ACLK_VO_PLL_MASK	= 0x3 << ACLK_VO_PLL_SHIFT,
+	ACLK_VO_SEL_GPLL	= 0,
+	ACLK_VO_SEL_CPLL,
+	ACLK_VO_SEL_NPLL,
+	ACLK_VO_DIV_SHIFT	= 0,
+	ACLK_VO_DIV_MASK	= 0x1f << ACLK_VO_DIV_SHIFT,
+
+	/* CRU_CLK_SEL5_CON */
+	DCLK_VOPB_SEL_SHIFT	= 14,
+	DCLK_VOPB_SEL_MASK	= 0x3 << DCLK_VOPB_SEL_SHIFT,
+	DCLK_VOPB_SEL_DIVOUT	= 0,
+	DCLK_VOPB_SEL_FRACOUT,
+	DCLK_VOPB_SEL_24M,
+	DCLK_VOPB_PLL_SEL_SHIFT	= 11,
+	DCLK_VOPB_PLL_SEL_MASK	= 0x1 << DCLK_VOPB_PLL_SEL_SHIFT,
+	DCLK_VOPB_PLL_SEL_CPLL	= 0,
+	DCLK_VOPB_PLL_SEL_NPLL,
+	DCLK_VOPB_DIV_SHIFT	= 0,
+	DCLK_VOPB_DIV_MASK	= 0xff,
+
+	/* CRU_CLK_SEL8_CON */
+	DCLK_VOPL_SEL_SHIFT	= 14,
+	DCLK_VOPL_SEL_MASK	= 0x3 << DCLK_VOPL_SEL_SHIFT,
+	DCLK_VOPL_SEL_DIVOUT	= 0,
+	DCLK_VOPL_SEL_FRACOUT,
+	DCLK_VOPL_SEL_24M,
+	DCLK_VOPL_PLL_SEL_SHIFT	= 11,
+	DCLK_VOPL_PLL_SEL_MASK	= 0x1 << DCLK_VOPL_PLL_SEL_SHIFT,
+	DCLK_VOPL_PLL_SEL_NPLL	= 0,
+	DCLK_VOPL_PLL_SEL_CPLL,
+	DCLK_VOPL_DIV_SHIFT	= 0,
+	DCLK_VOPL_DIV_MASK	= 0xff,
+
+	/* CRU_CLK_SEL14_CON */
+	PERI_PLL_SEL_SHIFT	= 15,
+	PERI_PLL_SEL_MASK	= 3 << PERI_PLL_SEL_SHIFT,
+	PERI_PLL_GPLL		= 0,
+	PERI_PLL_CPLL,
+	PERI_HCLK_DIV_SHIFT	= 8,
+	PERI_HCLK_DIV_MASK	= 0x1f << PERI_HCLK_DIV_SHIFT,
+	PERI_ACLK_DIV_SHIFT	= 0,
+	PERI_ACLK_DIV_MASK	= 0x1f << PERI_ACLK_DIV_SHIFT,
+
+	/* CRU_CLKSEL15_CON */
+	NANDC_CLK_SEL_SHIFT	= 15,
+	NANDC_CLK_SEL_MASK	= 0x1 << NANDC_CLK_SEL_SHIFT,
+	NANDC_CLK_SEL_NANDC	= 0,
+	NANDC_CLK_SEL_NANDC_DIV50,
+	NANDC_DIV50_SHIFT	= 8,
+	NANDC_DIV50_MASK	= 0x1f << NANDC_DIV50_SHIFT,
+	NANDC_PLL_SHIFT		= 6,
+	NANDC_PLL_MASK		= 0x3 << NANDC_PLL_SHIFT,
+	NANDC_SEL_GPLL		= 0,
+	NANDC_SEL_CPLL,
+	NANDC_SEL_NPLL,
+	NANDC_DIV_SHIFT		= 0,
+	NANDC_DIV_MASK		= 0x1f << NANDC_DIV_SHIFT,
+
+	/* CRU_CLKSEL20_CON */
+	EMMC_PLL_SHIFT		= 14,
+	EMMC_PLL_MASK		= 3 << EMMC_PLL_SHIFT,
+	EMMC_SEL_GPLL		= 0,
+	EMMC_SEL_CPLL,
+	EMMC_SEL_NPLL,
+	EMMC_SEL_24M,
+	EMMC_DIV_SHIFT		= 0,
+	EMMC_DIV_MASK		= 0xff << EMMC_DIV_SHIFT,
+
+	/* CRU_CLKSEL21_CON */
+	EMMC_CLK_SEL_SHIFT	= 15,
+	EMMC_CLK_SEL_MASK	= 1 << EMMC_CLK_SEL_SHIFT,
+	EMMC_CLK_SEL_EMMC	= 0,
+	EMMC_CLK_SEL_EMMC_DIV50,
+	EMMC_DIV50_SHIFT	= 0,
+	EMMC_DIV50_MASK		= 0xff << EMMC_DIV_SHIFT,
+
+	/* CRU_CLKSEL22_CON */
+	GMAC_PLL_SEL_SHIFT	= 14,
+	GMAC_PLL_SEL_MASK	= 3 << GMAC_PLL_SEL_SHIFT,
+	GMAC_PLL_SEL_GPLL	= 0,
+	GMAC_PLL_SEL_CPLL,
+	GMAC_PLL_SEL_NPLL,
+	CLK_GMAC_DIV_SHIFT	= 8,
+	CLK_GMAC_DIV_MASK	= 0x1f << CLK_GMAC_DIV_SHIFT,
+	SFC_PLL_SEL_SHIFT	= 7,
+	SFC_PLL_SEL_MASK	= 1 << SFC_PLL_SEL_SHIFT,
+	SFC_DIV_CON_SHIFT	= 0,
+	SFC_DIV_CON_MASK	= 0x7f,
+
+	/* CRU_CLK_SEL23_CON */
+	BUS_PLL_SEL_SHIFT	= 15,
+	BUS_PLL_SEL_MASK	= 1 << BUS_PLL_SEL_SHIFT,
+	BUS_PLL_SEL_GPLL	= 0,
+	BUS_PLL_SEL_CPLL,
+	BUS_ACLK_DIV_SHIFT	= 8,
+	BUS_ACLK_DIV_MASK	= 0x1f << BUS_ACLK_DIV_SHIFT,
+	RMII_CLK_SEL_SHIFT	= 7,
+	RMII_CLK_SEL_MASK	= 1 << RMII_CLK_SEL_SHIFT,
+	RMII_CLK_SEL_10M	= 0,
+	RMII_CLK_SEL_100M,
+	RMII_EXTCLK_SEL_SHIFT	= 6,
+	RMII_EXTCLK_SEL_MASK	= 1 << RMII_EXTCLK_SEL_SHIFT,
+	RMII_EXTCLK_SEL_INT	= 0,
+	RMII_EXTCLK_SEL_EXT,
+	PCLK_GMAC_DIV_SHIFT	= 0,
+	PCLK_GMAC_DIV_MASK	= 0x0f << PCLK_GMAC_DIV_SHIFT,
+
+	/* CRU_CLK_SEL24_CON */
+	BUS_PCLK_DIV_SHIFT	= 8,
+	BUS_PCLK_DIV_MASK	= 3 << BUS_PCLK_DIV_SHIFT,
+	BUS_HCLK_DIV_SHIFT	= 0,
+	BUS_HCLK_DIV_MASK	= 0x1f << BUS_HCLK_DIV_SHIFT,
+
+	/* CRU_CLK_SEL25_CON */
+	CRYPTO_APK_SEL_SHIFT	= 14,
+	CRYPTO_APK_PLL_SEL_MASK	= 3 << CRYPTO_APK_SEL_SHIFT,
+	CRYPTO_PLL_SEL_GPLL	= 0,
+	CRYPTO_PLL_SEL_CPLL,
+	CRYPTO_PLL_SEL_NPLL	= 0,
+	CRYPTO_APK_DIV_SHIFT	= 8,
+	CRYPTO_APK_DIV_MASK	= 0x1f << CRYPTO_APK_DIV_SHIFT,
+	CRYPTO_PLL_SEL_SHIFT	= 6,
+	CRYPTO_PLL_SEL_MASK	= 3 << CRYPTO_PLL_SEL_SHIFT,
+	CRYPTO_DIV_SHIFT	= 0,
+	CRYPTO_DIV_MASK		= 0x1f << CRYPTO_DIV_SHIFT,
+
+	/* CRU_CLK_SEL30_CON */
+	CLK_I2S1_DIV_CON_MASK	= 0x7f,
+	CLK_I2S1_PLL_SEL_MASK	= 0X1 << 8,
+	CLK_I2S1_PLL_SEL_GPLL	= 0X0 << 8,
+	CLK_I2S1_PLL_SEL_NPLL	= 0X1 << 8,
+	CLK_I2S1_SEL_MASK	= 0x3 << 10,
+	CLK_I2S1_SEL_I2S1	= 0x0 << 10,
+	CLK_I2S1_SEL_FRAC	= 0x1 << 10,
+	CLK_I2S1_SEL_MCLK_IN	= 0x2 << 10,
+	CLK_I2S1_SEL_OSC	= 0x3 << 10,
+	CLK_I2S1_OUT_SEL_MASK	= 0x1 << 15,
+	CLK_I2S1_OUT_SEL_I2S1	= 0x0 << 15,
+	CLK_I2S1_OUT_SEL_OSC	= 0x1 << 15,
+
+	/* CRU_CLK_SEL31_CON */
+	CLK_I2S1_FRAC_NUMERATOR_SHIFT	= 16,
+	CLK_I2S1_FRAC_NUMERATOR_MASK	= 0xffff << 16,
+	CLK_I2S1_FRAC_DENOMINATOR_SHIFT	= 0,
+	CLK_I2S1_FRAC_DENOMINATOR_MASK	= 0xffff,
+
+	/* CRU_CLK_SEL34_CON */
+	UART1_PLL_SEL_SHIFT	= 14,
+	UART1_PLL_SEL_MASK	= 3 << UART1_PLL_SEL_SHIFT,
+	UART1_PLL_SEL_GPLL	= 0,
+	UART1_PLL_SEL_24M,
+	UART1_PLL_SEL_480M,
+	UART1_PLL_SEL_NPLL,
+	UART1_DIV_CON_SHIFT	= 0,
+	UART1_DIV_CON_MASK	= 0x1f << UART1_DIV_CON_SHIFT,
+
+	/* CRU_CLK_SEL35_CON */
+	UART1_CLK_SEL_SHIFT	= 14,
+	UART1_CLK_SEL_MASK	= 3 << UART1_PLL_SEL_SHIFT,
+	UART1_CLK_SEL_UART1	= 0,
+	UART1_CLK_SEL_UART1_NP5,
+	UART1_CLK_SEL_UART1_FRAC,
+	UART1_DIVNP5_SHIFT	= 0,
+	UART1_DIVNP5_MASK	= 0x1f << UART1_DIVNP5_SHIFT,
+
+	/* CRU_CLK_SEL37_CON */
+	UART2_PLL_SEL_SHIFT	= 14,
+	UART2_PLL_SEL_MASK	= 3 << UART2_PLL_SEL_SHIFT,
+	UART2_PLL_SEL_GPLL	= 0,
+	UART2_PLL_SEL_24M,
+	UART2_PLL_SEL_480M,
+	UART2_PLL_SEL_NPLL,
+	UART2_DIV_CON_SHIFT	= 0,
+	UART2_DIV_CON_MASK	= 0x1f << UART2_DIV_CON_SHIFT,
+
+	/* CRU_CLK_SEL38_CON */
+	UART2_CLK_SEL_SHIFT	= 14,
+	UART2_CLK_SEL_MASK	= 3 << UART2_PLL_SEL_SHIFT,
+	UART2_CLK_SEL_UART2	= 0,
+	UART2_CLK_SEL_UART2_NP5,
+	UART2_CLK_SEL_UART2_FRAC,
+	UART2_DIVNP5_SHIFT	= 0,
+	UART2_DIVNP5_MASK	= 0x1f << UART2_DIVNP5_SHIFT,
+
+	/* CRU_CLK_SEL46_CON */
+	UART5_PLL_SEL_SHIFT	= 14,
+	UART5_PLL_SEL_MASK	= 3 << UART5_PLL_SEL_SHIFT,
+	UART5_PLL_SEL_GPLL	= 0,
+	UART5_PLL_SEL_24M,
+	UART5_PLL_SEL_480M,
+	UART5_PLL_SEL_NPLL,
+	UART5_DIV_CON_SHIFT	= 0,
+	UART5_DIV_CON_MASK	= 0x1f << UART5_DIV_CON_SHIFT,
+
+	/* CRU_CLK_SEL47_CON */
+	UART5_CLK_SEL_SHIFT	= 14,
+	UART5_CLK_SEL_MASK	= 3 << UART5_PLL_SEL_SHIFT,
+	UART5_CLK_SEL_UART5	= 0,
+	UART5_CLK_SEL_UART5_NP5,
+	UART5_CLK_SEL_UART5_FRAC,
+	UART5_DIVNP5_SHIFT	= 0,
+	UART5_DIVNP5_MASK	= 0x1f << UART5_DIVNP5_SHIFT,
+
+	/* CRU_CLK_SEL49_CON */
+	CLK_I2C_PLL_SEL_GPLL		= 0,
+	CLK_I2C_PLL_SEL_24M,
+	CLK_I2C_DIV_CON_MASK		= 0x7f,
+	CLK_I2C_PLL_SEL_MASK		= 1,
+	CLK_I2C1_PLL_SEL_SHIFT		= 15,
+	CLK_I2C1_DIV_CON_SHIFT		= 8,
+	CLK_I2C0_PLL_SEL_SHIFT		= 7,
+	CLK_I2C0_DIV_CON_SHIFT		= 0,
+
+	/* CRU_CLK_SEL50_CON */
+	CLK_I2C3_PLL_SEL_SHIFT		= 15,
+	CLK_I2C3_DIV_CON_SHIFT		= 8,
+	CLK_I2C2_PLL_SEL_SHIFT		= 7,
+	CLK_I2C2_DIV_CON_SHIFT		= 0,
+
+	/* CRU_CLK_SEL52_CON */
+	CLK_PWM_PLL_SEL_GPLL		= 0,
+	CLK_PWM_PLL_SEL_24M,
+	CLK_PWM_DIV_CON_MASK		= 0x7f,
+	CLK_PWM_PLL_SEL_MASK		= 1,
+	CLK_PWM1_PLL_SEL_SHIFT		= 15,
+	CLK_PWM1_DIV_CON_SHIFT		= 8,
+	CLK_PWM0_PLL_SEL_SHIFT		= 7,
+	CLK_PWM0_DIV_CON_SHIFT		= 0,
+
+	/* CRU_CLK_SEL53_CON */
+	CLK_SPI_PLL_SEL_GPLL		= 0,
+	CLK_SPI_PLL_SEL_24M,
+	CLK_SPI_DIV_CON_MASK		= 0x7f,
+	CLK_SPI_PLL_SEL_MASK		= 1,
+	CLK_SPI1_PLL_SEL_SHIFT		= 15,
+	CLK_SPI1_DIV_CON_SHIFT		= 8,
+	CLK_SPI0_PLL_SEL_SHIFT		= 7,
+	CLK_SPI0_DIV_CON_SHIFT		= 0,
+
+	/* CRU_CLK_SEL55_CON */
+	CLK_SARADC_DIV_CON_SHIFT	= 0,
+	CLK_SARADC_DIV_CON_MASK		= 0x7ff,
+
+	/* CRU_CLK_GATE10_CON */
+	CLK_I2S1_OUT_MCLK_PAD_MASK	= 0x1 << 9,
+	CLK_I2S1_OUT_MCLK_PAD_ENABLE	= 0x1 << 9,
+	CLK_I2S1_OUT_MCLK_PAD_DISABLE	= 0x0 << 9,
+
+	/* CRU_PMU_MODE */
+	GPLL_MODE_SHIFT			= 0,
+	GPLL_MODE_MASK			= 3 << GPLL_MODE_SHIFT,
+
+	/* CRU_PMU_CLK_SEL0_CON */
+	CLK_PMU_PCLK_DIV_SHIFT		= 0,
+	CLK_PMU_PCLK_DIV_MASK		= 0x1f << CLK_PMU_PCLK_DIV_SHIFT,
+};
+#endif
diff --git a/arch/arm/include/asm/arch-rockchip/grf_px30.h b/arch/arm/include/asm/arch-rockchip/grf_px30.h
new file mode 100644
index 0000000..c167bb4
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/grf_px30.h
@@ -0,0 +1,144 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2017 Rockchip Electronics Co., Ltd.
+ */
+#ifndef _ASM_ARCH_GRF_px30_H
+#define _ASM_ARCH_GRF_px30_H
+
+#include <common.h>
+
+struct px30_grf {
+	unsigned int gpio1al_iomux;
+	unsigned int gpio1ah_iomux;
+	unsigned int gpio1bl_iomux;
+	unsigned int gpio1bh_iomux;
+	unsigned int gpio1cl_iomux;
+	unsigned int gpio1ch_iomux;
+	unsigned int gpio1dl_iomux;
+	unsigned int gpio1dh_iomux;
+
+	unsigned int gpio2al_iomux;
+	unsigned int gpio2ah_iomux;
+	unsigned int gpio2bl_iomux;
+	unsigned int gpio2bh_iomux;
+	unsigned int gpio2cl_iomux;
+	unsigned int gpio2ch_iomux;
+	unsigned int gpio2dl_iomux;
+	unsigned int gpio2dh_iomux;
+
+	unsigned int gpio3al_iomux;
+	unsigned int gpio3ah_iomux;
+	unsigned int gpio3bl_iomux;
+	unsigned int gpio3bh_iomux;
+	unsigned int gpio3cl_iomux;
+	unsigned int gpio3ch_iomux;
+	unsigned int gpio3dl_iomux;
+	unsigned int gpio3dh_iomux;
+
+	unsigned int gpio1a_p;
+	unsigned int gpio1b_p;
+	unsigned int gpio1c_p;
+	unsigned int gpio1d_p;
+	unsigned int gpio2a_p;
+	unsigned int gpio2b_p;
+	unsigned int gpio2c_p;
+	unsigned int gpio2d_p;
+	unsigned int gpio3a_p;
+	unsigned int gpio3b_p;
+	unsigned int gpio3c_p;
+	unsigned int gpio3d_p;
+	unsigned int gpio1a_sr;
+	unsigned int gpio1b_sr;
+	unsigned int gpio1c_sr;
+	unsigned int gpio1d_sr;
+	unsigned int gpio2a_sr;
+	unsigned int gpio2b_sr;
+	unsigned int gpio2c_sr;
+	unsigned int gpio2d_sr;
+	unsigned int gpio3a_sr;
+	unsigned int gpio3b_sr;
+	unsigned int gpio3c_sr;
+	unsigned int gpio3d_sr;
+	unsigned int gpio1a_smt;
+	unsigned int gpio1b_smt;
+	unsigned int gpio1c_smt;
+	unsigned int gpio1d_smt;
+	unsigned int gpio2a_smt;
+	unsigned int gpio2b_smt;
+	unsigned int gpio2c_smt;
+	unsigned int gpio2d_smt;
+	unsigned int gpio3a_smt;
+	unsigned int gpio3b_smt;
+	unsigned int gpio3c_smt;
+	unsigned int gpio3d_smt;
+	unsigned int gpio1a_e;
+	unsigned int gpio1b_e;
+	unsigned int gpio1c_e;
+	unsigned int gpio1d_e;
+	unsigned int gpio2a_e;
+	unsigned int gpio2b_e;
+	unsigned int gpio2c_e;
+	unsigned int gpio2d_e;
+	unsigned int gpio3a_e;
+	unsigned int gpio3b_e;
+	unsigned int gpio3c_e;
+	unsigned int gpio3d_e;
+
+	unsigned int reserved0[(0x180 - 0x11C) / 4 - 1];
+	unsigned int io_vsel;
+	unsigned int iofunc_con0;
+	unsigned int reserved1[(0x400 - 0x184) / 4 - 1];
+	unsigned int soc_con[6];
+	unsigned int reserved2[(0x480 - 0x414) / 4 - 1];
+	unsigned int soc_status0;
+	unsigned int reserved3[(0x500 - 0x480) / 4 - 1];
+	unsigned int cpu_con[3];
+	unsigned int reserved4[5];
+	unsigned int cpu_status[2];
+	unsigned int reserved5[2];
+	unsigned int soc_noc_con[2];
+	unsigned int reserved6[6];
+	unsigned int ddr_bankhash[4];
+	unsigned int reserved7[(0x700 - 0x55c) / 4 - 1];
+	unsigned int host0_con[2];
+	unsigned int reserved8[(0x880 - 0x704) / 4 - 1];
+	unsigned int otg_con3;
+	unsigned int reserved9[3];
+	unsigned int host0_status4;
+	unsigned int reserved10[(0x904 - 0x890) / 4 - 1];
+	unsigned int mac_con1;
+};
+
+check_member(px30_grf, mac_con1, 0x904);
+
+struct px30_pmugrf {
+	unsigned int gpio0a_e;
+	unsigned int gpio0b_e;
+	unsigned int gpio0c_e;
+	unsigned int gpio0d_e;
+	unsigned int gpio0a_p;
+	unsigned int gpio0b_p;
+	unsigned int gpio0c_p;
+	unsigned int gpio0d_p;
+	unsigned int gpio0al_iomux;
+	unsigned int gpio0bl_iomux;
+	unsigned int gpio0cl_iomux;
+	unsigned int gpio0dl_iomux;
+	unsigned int gpio0l_sr;
+	unsigned int gpio0h_sr;
+	unsigned int gpio0l_smt;
+	unsigned int gpio0h_smt;
+	unsigned int reserved1[(0x100 - 0x3c) / 4 - 1];
+	unsigned int soc_con[4];
+	unsigned int reserved2[(0x180 - 0x10c) / 4 - 1];
+	unsigned int pvtm_con[2];
+	unsigned int reserved3[2];
+	unsigned int pvtm_status[2];
+	unsigned int reserved4[(0x200 - 0x194) / 4 - 1];
+	unsigned int os_reg[12];
+	unsigned int reset_function_status;
+};
+
+check_member(px30_pmugrf, reset_function_status, 0x230);
+
+#endif
diff --git a/arch/arm/include/asm/arch-rockchip/sdram.h b/arch/arm/include/asm/arch-rockchip/sdram.h
index 9220763..cf2a7b7 100644
--- a/arch/arm/include/asm/arch-rockchip/sdram.h
+++ b/arch/arm/include/asm/arch-rockchip/sdram.h
@@ -1,102 +1,86 @@
-/* SPDX-License-Identifier: GPL-2.0 */
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
- * Copyright (c) 2015 Google, Inc
- *
- * Copyright 2014 Rockchip Inc.
+ * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
  */
 
-#ifndef _ASM_ARCH_RK3288_SDRAM_H__
-#define _ASM_ARCH_RK3288_SDRAM_H__
+#ifndef _ASM_ARCH_SDRAM_H
+#define _ASM_ARCH_SDRAM_H
 
-struct rk3288_sdram_channel {
-	/*
-	 * bit width in address, eg:
-	 * 8 banks using 3 bit to address,
-	 * 2 cs using 1 bit to address.
-	 */
-	u8 rank;
-	u8 col;
-	u8 bk;
-	u8 bw;
-	u8 dbw;
-	u8 row_3_4;
-	u8 cs0_row;
-	u8 cs1_row;
-#if CONFIG_IS_ENABLED(OF_PLATDATA)
-	/*
-	 * For of-platdata, which would otherwise convert this into two
-	 * byte-swapped integers. With a size of 9 bytes, this struct will
-	 * appear in of-platdata as a byte array.
-	 *
-	 * If OF_PLATDATA enabled, need to add a dummy byte in dts.(i.e 0xff)
-	 */
-	u8 dummy;
-#endif
+enum {
+	DDR4 = 0,
+	DDR3 = 0x3,
+	LPDDR2 = 0x5,
+	LPDDR3 = 0x6,
+	LPDDR4 = 0x7,
+	UNUSED = 0xFF
 };
 
-struct rk3288_sdram_pctl_timing {
-	u32 togcnt1u;
-	u32 tinit;
-	u32 trsth;
-	u32 togcnt100n;
-	u32 trefi;
-	u32 tmrd;
-	u32 trfc;
-	u32 trp;
-	u32 trtw;
-	u32 tal;
-	u32 tcl;
-	u32 tcwl;
-	u32 tras;
-	u32 trc;
-	u32 trcd;
-	u32 trrd;
-	u32 trtp;
-	u32 twr;
-	u32 twtr;
-	u32 texsr;
-	u32 txp;
-	u32 txpdll;
-	u32 tzqcs;
-	u32 tzqcsi;
-	u32 tdqs;
-	u32 tcksre;
-	u32 tcksrx;
-	u32 tcke;
-	u32 tmod;
-	u32 trstl;
-	u32 tzqcl;
-	u32 tmrr;
-	u32 tckesr;
-	u32 tdpd;
-};
-check_member(rk3288_sdram_pctl_timing, tdpd, 0x144 - 0xc0);
+/*
+ * sys_reg2 bitfield struct
+ * [31]		row_3_4_ch1
+ * [30]		row_3_4_ch0
+ * [29:28]	chinfo
+ * [27]		rank_ch1
+ * [26:25]	col_ch1
+ * [24]		bk_ch1
+ * [23:22]	low bits of cs0_row_ch1
+ * [21:20]	low bits of cs1_row_ch1
+ * [19:18]	bw_ch1
+ * [17:16]	dbw_ch1;
+ * [15:13]	ddrtype
+ * [12]		channelnum
+ * [11]		rank_ch0
+ * [10:9]	col_ch0,
+ * [8]		bk_ch0
+ * [7:6]	low bits of cs0_row_ch0
+ * [5:4]	low bits of cs1_row_ch0
+ * [3:2]	bw_ch0
+ * [1:0]	dbw_ch0
+ */
+#define SYS_REG_DDRTYPE_SHIFT		13
+#define SYS_REG_DDRTYPE_MASK		7
+#define SYS_REG_NUM_CH_SHIFT		12
+#define SYS_REG_NUM_CH_MASK		1
+#define SYS_REG_ROW_3_4_SHIFT(ch)	(30 + (ch))
+#define SYS_REG_ROW_3_4_MASK		1
+#define SYS_REG_CHINFO_SHIFT(ch)	(28 + (ch))
+#define SYS_REG_RANK_SHIFT(ch)		(11 + (ch) * 16)
+#define SYS_REG_RANK_MASK		1
+#define SYS_REG_COL_SHIFT(ch)		(9 + (ch) * 16)
+#define SYS_REG_COL_MASK		3
+#define SYS_REG_BK_SHIFT(ch)		(8 + (ch) * 16)
+#define SYS_REG_BK_MASK			1
+#define SYS_REG_CS0_ROW_SHIFT(ch)	(6 + (ch) * 16)
+#define SYS_REG_CS0_ROW_MASK		3
+#define SYS_REG_CS1_ROW_SHIFT(ch)	(4 + (ch) * 16)
+#define SYS_REG_CS1_ROW_MASK		3
+#define SYS_REG_BW_SHIFT(ch)		(2 + (ch) * 16)
+#define SYS_REG_BW_MASK			3
+#define SYS_REG_DBW_SHIFT(ch)		((ch) * 16)
+#define SYS_REG_DBW_MASK		3
 
-struct rk3288_sdram_phy_timing {
-	u32 dtpr0;
-	u32 dtpr1;
-	u32 dtpr2;
-	u32 mr[4];
-};
+/*
+ * sys_reg3 bitfield struct
+ * [7]		high bit of cs0_row_ch1
+ * [6]		high bit of cs1_row_ch1
+ * [5]		high bit of cs0_row_ch0
+ * [4]		high bit of cs1_row_ch0
+ * [3:2]	cs1_col_ch1
+ * [1:0]	cs1_col_ch0
+ */
+#define SYS_REG_VERSION_SHIFT			28
+#define SYS_REG_VERSION_MASK			0xf
+#define SYS_REG_EXTEND_CS0_ROW_SHIFT(ch)	(5 + (ch) * 2)
+#define SYS_REG_EXTEND_CS0_ROW_MASK		1
+#define SYS_REG_EXTEND_CS1_ROW_SHIFT(ch)	(4 + (ch) * 2)
+#define SYS_REG_EXTEND_CS1_ROW_MASK		1
+#define SYS_REG_CS1_COL_SHIFT(ch)		(0 + (ch) * 2)
+#define SYS_REG_CS1_COL_MASK			3
 
-struct rk3288_base_params {
-	u32 noc_timing;
-	u32 noc_activate;
-	u32 ddrconfig;
-	u32 ddr_freq;
-	u32 dramtype;
-	/*
-	 * DDR Stride is address mapping for DRAM space
-	 * Stride	Ch 0 range	Ch1 range	Total
-	 * 0x00		0-256MB		256MB-512MB	512MB
-	 * 0x05		0-1GB		0-1GB		1GB
-	 * 0x09		0-2GB		0-2GB		2GB
-	 * 0x0d		0-4GB		0-4GB		4GB
-	 * 0x17		N/A		0-4GB		4GB
-	 * 0x1a		0-4GB		4GB-8GB		8GB
-	 */
-	u32 stride;
-	u32 odt;
-};
+/* Get sdram size decode from reg */
+size_t rockchip_sdram_size(phys_addr_t reg);
+
+/* Called by U-Boot board_init_r for Rockchip SoCs */
+int dram_init(void);
 
 #endif
diff --git a/arch/arm/include/asm/arch-rockchip/sdram_common.h b/arch/arm/include/asm/arch-rockchip/sdram_common.h
index 8027b53..36d3115 100644
--- a/arch/arm/include/asm/arch-rockchip/sdram_common.h
+++ b/arch/arm/include/asm/arch-rockchip/sdram_common.h
@@ -1,19 +1,19 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
+/* SPDX-License-Identifier:     GPL-2.0+ */
 /*
- * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
+ * Copyright (C) 2018 Rockchip Electronics Co., Ltd
  */
 
 #ifndef _ASM_ARCH_SDRAM_COMMON_H
 #define _ASM_ARCH_SDRAM_COMMON_H
 
-enum {
-	DDR4 = 0,
-	DDR3 = 0x3,
-	LPDDR2 = 0x5,
-	LPDDR3 = 0x6,
-	LPDDR4 = 0x7,
-	UNUSED = 0xFF
-};
+#ifndef MHZ
+#define MHZ		(1000 * 1000)
+#endif
+
+#define PATTERN		(0x5aa5f00f)
+
+#define MIN(a, b)	(((a) > (b)) ? (b) : (a))
+#define MAX(a, b)	(((a) > (b)) ? (a) : (b))
 
 struct sdram_cap_info {
 	unsigned int rank;
@@ -32,6 +32,8 @@
 	unsigned int row_3_4;
 	unsigned int cs0_row;
 	unsigned int cs1_row;
+	unsigned int cs0_high16bit_row;
+	unsigned int cs1_high16bit_row;
 	unsigned int ddrconfig;
 };
 
@@ -43,8 +45,9 @@
 	unsigned int odt;
 };
 
+#define DDR_SYS_REG_VERSION		(0x2)
 /*
- * sys_reg bitfield struct
+ * sys_reg2 bitfield struct
  * [31]		row_3_4_ch1
  * [30]		row_3_4_ch0
  * [29:28]	chinfo
@@ -64,49 +67,38 @@
  * [5:4]	cs1_row_ch0
  * [3:2]	bw_ch0
  * [1:0]	dbw_ch0
-*/
-#define SYS_REG_DDRTYPE_SHIFT		13
-#define DDR_SYS_REG_VERSION		2
-#define SYS_REG_DDRTYPE_MASK		7
-#define SYS_REG_NUM_CH_SHIFT		12
-#define SYS_REG_NUM_CH_MASK		1
-#define SYS_REG_ROW_3_4_SHIFT(ch)	(30 + (ch))
-#define SYS_REG_ROW_3_4_MASK		1
+ */
 #define SYS_REG_ENC_ROW_3_4(n, ch)	((n) << (30 + (ch)))
-#define SYS_REG_CHINFO_SHIFT(ch)	(28 + (ch))
-#define SYS_REG_ENC_CHINFO(ch)		(1 << SYS_REG_CHINFO_SHIFT(ch))
-#define SYS_REG_ENC_DDRTYPE(n)		((n) << SYS_REG_DDRTYPE_SHIFT)
-#define SYS_REG_ENC_NUM_CH(n)		(((n) - SYS_REG_NUM_CH_MASK) << \
-					SYS_REG_NUM_CH_SHIFT)
-#define SYS_REG_RANK_SHIFT(ch)		(11 + (ch) * 16)
-#define SYS_REG_RANK_MASK		1
-#define SYS_REG_ENC_RANK(n, ch)		(((n) - SYS_REG_RANK_MASK) << \
-					 SYS_REG_RANK_SHIFT(ch))
-#define SYS_REG_COL_SHIFT(ch)		(9 + (ch) * 16)
-#define SYS_REG_COL_MASK		3
-#define SYS_REG_ENC_COL(n, ch)		(((n) - 9) << SYS_REG_COL_SHIFT(ch))
-#define SYS_REG_BK_SHIFT(ch)		(8 + (ch) * 16)
-#define SYS_REG_BK_MASK			1
+#define SYS_REG_DEC_ROW_3_4(n, ch)	(((n) >> (30 + (ch))) & 0x1)
+#define SYS_REG_ENC_CHINFO(ch)		(1 << (28 + (ch)))
+#define SYS_REG_ENC_DDRTYPE(n)		((n) << 13)
+#define SYS_REG_DEC_DDRTYPE(n)		(((n) >> 13) & 0x7)
+#define SYS_REG_ENC_NUM_CH(n)		(((n) - 1) << 12)
+#define SYS_REG_DEC_NUM_CH(n)		(1 + (((n) >> 12) & 0x1))
+#define SYS_REG_ENC_RANK(n, ch)		(((n) - 1) << (11 + ((ch) * 16)))
+#define SYS_REG_DEC_RANK(n, ch)		(1 + (((n) >> (11 + 16 * (ch))) & 0x1))
+#define SYS_REG_ENC_COL(n, ch)		(((n) - 9) << (9 + ((ch) * 16)))
+#define SYS_REG_DEC_COL(n, ch)		(9 + (((n) >> (9 + 16 * (ch))) & 0x3))
 #define SYS_REG_ENC_BK(n, ch)		(((n) == 3 ? 0 : 1) << \
-					SYS_REG_BK_SHIFT(ch))
-#define SYS_REG_CS0_ROW_SHIFT(ch)	(6 + (ch) * 16)
-#define SYS_REG_CS0_ROW_MASK		3
-#define SYS_REG_CS1_ROW_SHIFT(ch)	(4 + (ch) * 16)
-#define SYS_REG_CS1_ROW_MASK		3
-#define SYS_REG_BW_SHIFT(ch)		(2 + (ch) * 16)
-#define SYS_REG_BW_MASK			3
-#define SYS_REG_ENC_BW(n, ch)		((2 >> (n)) << SYS_REG_BW_SHIFT(ch))
-#define SYS_REG_DBW_SHIFT(ch)		((ch) * 16)
-#define SYS_REG_DBW_MASK		3
-#define SYS_REG_ENC_DBW(n, ch)		((2 >> (n)) << SYS_REG_DBW_SHIFT(ch))
-
+						(8 + ((ch) * 16)))
+#define SYS_REG_DEC_BK(n, ch)		(3 - (((n) >> (8 + 16 * (ch))) & 0x1))
+#define SYS_REG_ENC_BW(n, ch)		((2 >> (n)) << (2 + ((ch) * 16)))
+#define SYS_REG_DEC_BW(n, ch)		(2 >> (((n) >> (2 + 16 * (ch))) & 0x3))
+#define SYS_REG_ENC_DBW(n, ch)		((2 >> (n)) << (0 + ((ch) * 16)))
+#define SYS_REG_DEC_DBW(n, ch)		(2 >> (((n) >> (0 + 16 * (ch))) & 0x3))
+/* sys reg 3 */
 #define SYS_REG_ENC_VERSION(n)		((n) << 28)
+#define SYS_REG_DEC_VERSION(n)		(((n) >> 28) & 0xf)
 #define SYS_REG_ENC_CS0_ROW(n, os_reg2, os_reg3, ch) do { \
 			(os_reg2) |= (((n) - 13) & 0x3) << (6 + 16 * (ch)); \
 			(os_reg3) |= ((((n) - 13) & 0x4) >> 2) << \
 				     (5 + 2 * (ch)); \
 		} while (0)
 
+#define SYS_REG_DEC_CS0_ROW(os_reg2, os_reg3, ch)	\
+		((((((os_reg2) >> (6 + 16 * (ch)) & 0x3) | \
+		 ((((os_reg3) >> (5 + 2 * (ch))) & 0x1) << 2)) + 1) & 0x7) + 12)
+
 #define SYS_REG_ENC_CS1_ROW(n, os_reg2, os_reg3, ch) do { \
 			(os_reg2) &= (~(0x3 << (4 + 16 * (ch)))); \
 			(os_reg3) &= (~(0x1 << (4 + 2 * (ch)))); \
@@ -115,14 +107,12 @@
 				     (4 + 2 * (ch)); \
 		} while (0)
 
-#define SYS_REG_CS1_COL_SHIFT(ch)	(0 + 2 * (ch))
-#define SYS_REG_ENC_CS1_COL(n, ch)      (((n) - 9) << SYS_REG_CS1_COL_SHIFT(ch))
-
-/* Get sdram size decode from reg */
-size_t rockchip_sdram_size(phys_addr_t reg);
+#define SYS_REG_DEC_CS1_ROW(os_reg2, os_reg3, ch) \
+		((((((os_reg2) >> (4 + 16 * (ch)) & 0x3) | \
+		 ((((os_reg3) >> (4 + 2 * (ch))) & 0x1) << 2)) + 1) & 0x7) + 12)
 
-/* Called by U-Boot board_init_r for Rockchip SoCs */
-int dram_init(void);
+#define SYS_REG_ENC_CS1_COL(n, ch)	(((n) - 9) << (0 + 2 * (ch)))
+#define SYS_REG_DEC_CS1_COL(n, ch)	(9 + (((n) >> (0 + 2 * (ch))) & 0x3))
 
 #if !defined(CONFIG_RAM_ROCKCHIP_DEBUG)
 inline void sdram_print_dram_type(unsigned char dramtype)
@@ -144,4 +134,26 @@
 void sdram_print_stride(unsigned int stride);
 #endif /* CONFIG_RAM_ROCKCHIP_DEBUG */
 
+void sdram_org_config(struct sdram_cap_info *cap_info,
+		      struct sdram_base_params *base,
+		      u32 *p_os_reg2, u32 *p_os_reg3, u32 channel);
+
+int sdram_detect_bw(struct sdram_cap_info *cap_info);
+int sdram_detect_cs(struct sdram_cap_info *cap_info);
+int sdram_detect_col(struct sdram_cap_info *cap_info,
+		     u32 coltmp);
+int sdram_detect_bank(struct sdram_cap_info *cap_info,
+		      u32 coltmp, u32 bktmp);
+int sdram_detect_bg(struct sdram_cap_info *cap_info,
+		    u32 coltmp);
+int sdram_detect_dbw(struct sdram_cap_info *cap_info, u32 dram_type);
+int sdram_detect_row(struct sdram_cap_info *cap_info,
+		     u32 coltmp, u32 bktmp, u32 rowtmp);
+int sdram_detect_row_3_4(struct sdram_cap_info *cap_info,
+			 u32 coltmp, u32 bktmp);
+int sdram_detect_high_row(struct sdram_cap_info *cap_info);
+int sdram_detect_cs1_row(struct sdram_cap_info *cap_info, u32 dram_type);
+u64 sdram_get_cs_cap(struct sdram_cap_info *cap_info, u32 cs, u32 dram_type);
+void sdram_copy_to_reg(u32 *dest, const u32 *src, u32 n);
+
 #endif
diff --git a/arch/arm/include/asm/arch-rockchip/sdram_msch.h b/arch/arm/include/asm/arch-rockchip/sdram_msch.h
new file mode 100644
index 0000000..cfb3d9c
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/sdram_msch.h
@@ -0,0 +1,85 @@
+/* SPDX-License-Identifier:     GPL-2.0+ */
+/*
+ * Copyright (C) 2019 Rockchip Electronics Co., Ltd
+ */
+
+#ifndef _ASM_ARCH_SDRAM_MSCH_H
+#define _ASM_ARCH_SDRAM_MSCH_H
+
+union noc_ddrtiminga0 {
+	u32 d32;
+	struct {
+		unsigned acttoact : 6;
+		unsigned reserved0 : 2;
+		unsigned rdtomiss : 6;
+		unsigned reserved1 : 2;
+		unsigned wrtomiss : 6;
+		unsigned reserved2 : 2;
+		unsigned readlatency : 8;
+	} b;
+};
+
+union noc_ddrtimingb0 {
+	u32 d32;
+	struct {
+		unsigned rdtowr : 5;
+		unsigned reserved0 : 3;
+		unsigned wrtord : 5;
+		unsigned reserved1 : 3;
+		unsigned rrd : 4;
+		unsigned reserved2 : 4;
+		unsigned faw : 6;
+		unsigned reserved3 : 2;
+	} b;
+};
+
+union noc_ddrtimingc0 {
+	u32 d32;
+	struct {
+		unsigned burstpenalty : 4;
+		unsigned reserved0 : 4;
+		unsigned wrtomwr : 6;
+		unsigned reserved1 : 18;
+	} b;
+};
+
+union noc_devtodev0 {
+	u32 d32;
+	struct {
+		unsigned busrdtord : 3;
+		unsigned reserved0 : 1;
+		unsigned busrdtowr : 3;
+		unsigned reserved1 : 1;
+		unsigned buswrtord : 3;
+		unsigned reserved2 : 1;
+		unsigned buswrtowr : 3;
+		unsigned reserved3 : 17;
+	} b;
+};
+
+union noc_ddrmode {
+	u32 d32;
+	struct {
+		unsigned autoprecharge : 1;
+		unsigned bypassfiltering : 1;
+		unsigned fawbank : 1;
+		unsigned burstsize : 2;
+		unsigned mwrsize : 2;
+		unsigned reserved2 : 1;
+		unsigned forceorder : 8;
+		unsigned forceorderstate : 8;
+		unsigned reserved3 : 8;
+	} b;
+};
+
+union noc_ddr4timing {
+	u32 d32;
+	struct {
+		unsigned ccdl : 3;
+		unsigned wrtordl : 5;
+		unsigned rrdl : 4;
+		unsigned reserved1 : 20;
+	} b;
+};
+
+#endif
diff --git a/arch/arm/include/asm/arch-rockchip/sdram_pctl_px30.h b/arch/arm/include/asm/arch-rockchip/sdram_pctl_px30.h
new file mode 100644
index 0000000..9781881
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/sdram_pctl_px30.h
@@ -0,0 +1,139 @@
+/* SPDX-License-Identifier:     GPL-2.0+ */
+/*
+ * Copyright (C) 2018 Rockchip Electronics Co., Ltd
+ */
+
+#ifndef _ASM_ARCH_SDRAM_PCTL_PX30_H
+#define _ASM_ARCH_SDRAM_PCTL_PX30_H
+#include <asm/arch-rockchip/sdram_common.h>
+
+struct ddr_pctl_regs {
+	u32 pctl[30][2];
+};
+
+/* ddr pctl registers define */
+#define DDR_PCTL2_MSTR			0x0
+#define DDR_PCTL2_STAT			0x4
+#define DDR_PCTL2_MSTR1			0x8
+#define DDR_PCTL2_MRCTRL0		0x10
+#define DDR_PCTL2_MRCTRL1		0x14
+#define DDR_PCTL2_MRSTAT		0x18
+#define DDR_PCTL2_MRCTRL2		0x1c
+#define DDR_PCTL2_DERATEEN		0x20
+#define DDR_PCTL2_DERATEINT		0x24
+#define DDR_PCTL2_PWRCTL		0x30
+#define DDR_PCTL2_PWRTMG		0x34
+#define DDR_PCTL2_HWLPCTL		0x38
+#define DDR_PCTL2_RFSHCTL0		0x50
+#define DDR_PCTL2_RFSHCTL1		0x54
+#define DDR_PCTL2_RFSHCTL2		0x58
+#define DDR_PCTL2_RFSHCTL4		0x5c
+#define DDR_PCTL2_RFSHCTL3		0x60
+#define DDR_PCTL2_RFSHTMG		0x64
+#define DDR_PCTL2_RFSHTMG1		0x68
+#define DDR_PCTL2_RFSHCTL5		0x6c
+#define DDR_PCTL2_INIT0			0xd0
+#define DDR_PCTL2_INIT1			0xd4
+#define DDR_PCTL2_INIT2			0xd8
+#define DDR_PCTL2_INIT3			0xdc
+#define DDR_PCTL2_INIT4			0xe0
+#define DDR_PCTL2_INIT5			0xe4
+#define DDR_PCTL2_INIT6			0xe8
+#define DDR_PCTL2_INIT7			0xec
+#define DDR_PCTL2_DIMMCTL		0xf0
+#define DDR_PCTL2_RANKCTL		0xf4
+#define DDR_PCTL2_CHCTL			0xfc
+#define DDR_PCTL2_DRAMTMG0		0x100
+#define DDR_PCTL2_DRAMTMG1		0x104
+#define DDR_PCTL2_DRAMTMG2		0x108
+#define DDR_PCTL2_DRAMTMG3		0x10c
+#define DDR_PCTL2_DRAMTMG4		0x110
+#define DDR_PCTL2_DRAMTMG5		0x114
+#define DDR_PCTL2_DRAMTMG6		0x118
+#define DDR_PCTL2_DRAMTMG7		0x11c
+#define DDR_PCTL2_DRAMTMG8		0x120
+#define DDR_PCTL2_DRAMTMG9		0x124
+#define DDR_PCTL2_DRAMTMG10		0x128
+#define DDR_PCTL2_DRAMTMG11		0x12c
+#define DDR_PCTL2_DRAMTMG12		0x130
+#define DDR_PCTL2_DRAMTMG13		0x134
+#define DDR_PCTL2_DRAMTMG14		0x138
+#define DDR_PCTL2_DRAMTMG15		0x13c
+#define DDR_PCTL2_DRAMTMG16		0x140
+#define DDR_PCTL2_ZQCTL0		0x180
+#define DDR_PCTL2_ZQCTL1		0x184
+#define DDR_PCTL2_ZQCTL2		0x188
+#define DDR_PCTL2_ZQSTAT		0x18c
+#define DDR_PCTL2_DFITMG0		0x190
+#define DDR_PCTL2_DFITMG1		0x194
+#define DDR_PCTL2_DFILPCFG0		0x198
+#define DDR_PCTL2_DFILPCFG1		0x19c
+#define DDR_PCTL2_DFIUPD0		0x1a0
+#define DDR_PCTL2_DFIUPD1		0x1a4
+#define DDR_PCTL2_DFIUPD2		0x1a8
+#define DDR_PCTL2_DFIMISC		0x1b0
+#define DDR_PCTL2_DFITMG2		0x1b4
+#define DDR_PCTL2_DFITMG3		0x1b8
+#define DDR_PCTL2_DFISTAT		0x1bc
+#define DDR_PCTL2_DBICTL		0x1c0
+#define DDR_PCTL2_ADDRMAP0		0x200
+#define DDR_PCTL2_ADDRMAP1		0x204
+#define DDR_PCTL2_ADDRMAP2		0x208
+#define DDR_PCTL2_ADDRMAP3		0x20c
+#define DDR_PCTL2_ADDRMAP4		0x210
+#define DDR_PCTL2_ADDRMAP5		0x214
+#define DDR_PCTL2_ADDRMAP6		0x218
+#define DDR_PCTL2_ADDRMAP7		0x21c
+#define DDR_PCTL2_ADDRMAP8		0x220
+#define DDR_PCTL2_ADDRMAP9		0x224
+#define DDR_PCTL2_ADDRMAP10		0x228
+#define DDR_PCTL2_ADDRMAP11		0x22c
+#define DDR_PCTL2_ODTCFG		0x240
+#define DDR_PCTL2_ODTMAP		0x244
+#define DDR_PCTL2_SCHED			0x250
+#define DDR_PCTL2_SCHED1		0x254
+#define DDR_PCTL2_PERFHPR1		0x25c
+#define DDR_PCTL2_PERFLPR1		0x264
+#define DDR_PCTL2_PERFWR1		0x26c
+#define DDR_PCTL2_DQMAP0		0x280
+#define DDR_PCTL2_DQMAP1		0x284
+#define DDR_PCTL2_DQMAP2		0x288
+#define DDR_PCTL2_DQMAP3		0x28c
+#define DDR_PCTL2_DQMAP4		0x290
+#define DDR_PCTL2_DQMAP5		0x294
+#define DDR_PCTL2_DBG0			0x300
+#define DDR_PCTL2_DBG1			0x304
+#define DDR_PCTL2_DBGCAM		0x308
+#define DDR_PCTL2_DBGCMD		0x30c
+#define DDR_PCTL2_DBGSTAT		0x310
+#define DDR_PCTL2_SWCTL			0x320
+#define DDR_PCTL2_SWSTAT		0x324
+#define DDR_PCTL2_POISONCFG		0x36c
+#define DDR_PCTL2_POISONSTAT		0x370
+#define DDR_PCTL2_ADVECCINDEX		0x374
+#define DDR_PCTL2_ADVECCSTAT		0x378
+#define DDR_PCTL2_PSTAT			0x3fc
+#define DDR_PCTL2_PCCFG			0x400
+#define DDR_PCTL2_PCFGR_n		0x404
+#define DDR_PCTL2_PCFGW_n		0x408
+#define DDR_PCTL2_PCTRL_n		0x490
+
+/* PCTL2_MRSTAT */
+#define MR_WR_BUSY			BIT(0)
+
+void pctl_read_mr(void __iomem *pctl_base, u32 rank, u32 mr_num);
+int pctl_write_mr(void __iomem *pctl_base, u32 rank, u32 mr_num, u32 arg,
+		  u32 dramtype);
+int pctl_write_vrefdq(void __iomem *pctl_base, u32 rank, u32 vrefrate,
+		      u32 dramtype);
+
+u32 pctl_dis_zqcs_aref(void __iomem *pctl_base);
+void pctl_rest_zqcs_aref(void __iomem *pctl_base, u32 dis_auto_zq);
+
+u32 pctl_remodify_sdram_params(struct ddr_pctl_regs *pctl_regs,
+			       struct sdram_cap_info *cap_info,
+			       u32 dram_type);
+int pctl_cfg(void __iomem *pctl_base, struct ddr_pctl_regs *pctl_regs,
+	     u32 sr_idle, u32 pd_idle);
+
+#endif
diff --git a/arch/arm/include/asm/arch-rockchip/sdram_phy_px30.h b/arch/arm/include/asm/arch-rockchip/sdram_phy_px30.h
new file mode 100644
index 0000000..c75a633
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/sdram_phy_px30.h
@@ -0,0 +1,62 @@
+/* SPDX-License-Identifier:     GPL-2.0+ */
+/*
+ * Copyright (C) 2018 Rockchip Electronics Co., Ltd
+ */
+
+#ifndef _ASM_ARCH_SDRAM_PHY_PX30_H
+#define _ASM_ARCH_SDRAM_PHY_PX30_H
+#include <asm/arch-rockchip/sdram_common.h>
+#include <asm/arch-rockchip/sdram_phy_ron_rtt_px30.h>
+
+struct ddr_phy_regs {
+	u32 phy[5][2];
+};
+
+#define PHY_REG(base, n)		((base) + 4 * (n))
+
+/* PHY_REG0 */
+#define DIGITAL_DERESET			BIT(3)
+#define ANALOG_DERESET			BIT(2)
+#define DIGITAL_RESET			(0 << 3)
+#define ANALOG_RESET			(0 << 2)
+
+/* PHY_REG1 */
+#define PHY_DDR2			(0)
+#define PHY_LPDDR2			(1)
+#define PHY_DDR3			(2)
+#define PHY_LPDDR3			(3)
+#define PHY_DDR4			(4)
+#define PHY_BL_4			(0 << 2)
+#define PHY_BL_8			BIT(2)
+
+/* PHY_REG2 */
+#define PHY_DTT_EN			BIT(0)
+#define PHY_DTT_DISB			(0 << 0)
+#define PHY_WRITE_LEVELING_EN		BIT(2)
+#define PHY_WRITE_LEVELING_DISB		(0 << 2)
+#define PHY_SELECT_CS0			(2)
+#define PHY_SELECT_CS1			(1)
+#define PHY_SELECT_CS0_1		(0)
+#define PHY_WRITE_LEVELING_SELECTCS(n)	((n) << 6)
+#define PHY_DATA_TRAINING_SELECTCS(n)	((n) << 4)
+
+struct ddr_phy_skew {
+	u32 a0_a1_skew[15];
+	u32 cs0_dm0_skew[11];
+	u32 cs0_dm1_skew[11];
+	u32 cs0_dm2_skew[11];
+	u32 cs0_dm3_skew[11];
+	u32 cs1_dm0_skew[11];
+	u32 cs1_dm1_skew[11];
+	u32 cs1_dm2_skew[11];
+	u32 cs1_dm3_skew[11];
+};
+
+void phy_soft_reset(void __iomem *phy_base);
+void phy_dram_set_bw(void __iomem *phy_base, u32 bw);
+void phy_cfg(void __iomem *phy_base,
+	     struct ddr_phy_regs *phy_regs, struct ddr_phy_skew *skew,
+	     struct sdram_base_params *base, u32 bw);
+int phy_data_training(void __iomem *phy_base, u32 cs, u32 dramtype);
+
+#endif
diff --git a/arch/arm/include/asm/arch-rockchip/sdram_phy_ron_rtt_px30.h b/arch/arm/include/asm/arch-rockchip/sdram_phy_ron_rtt_px30.h
new file mode 100644
index 0000000..9c15232
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/sdram_phy_ron_rtt_px30.h
@@ -0,0 +1,59 @@
+/* SPDX-License-Identifier:     GPL-2.0+ */
+/*
+ * Copyright (C) 2018 Rockchip Electronics Co., Ltd
+ */
+
+#ifndef _ASM_ARCH_SDRAM_PHY_RON_RTT_PX30_H
+#define _ASM_ARCH_SDRAM_PHY_RON_RTT_PX30_H
+
+#define PHY_DDR3_RON_RTT_DISABLE	(0)
+#define PHY_DDR3_RON_RTT_451ohm		(1)
+#define PHY_DDR3_RON_RTT_225ohm		(2)
+#define PHY_DDR3_RON_RTT_150ohm		(3)
+#define PHY_DDR3_RON_RTT_112ohm		(4)
+#define PHY_DDR3_RON_RTT_90ohm		(5)
+#define PHY_DDR3_RON_RTT_75ohm		(6)
+#define PHY_DDR3_RON_RTT_64ohm		(7)
+#define PHY_DDR3_RON_RTT_56ohm		(16)
+#define PHY_DDR3_RON_RTT_50ohm		(17)
+#define PHY_DDR3_RON_RTT_45ohm		(18)
+#define PHY_DDR3_RON_RTT_41ohm		(19)
+#define PHY_DDR3_RON_RTT_37ohm		(20)
+#define PHY_DDR3_RON_RTT_34ohm		(21)
+#define PHY_DDR3_RON_RTT_33ohm		(22)
+#define PHY_DDR3_RON_RTT_30ohm		(23)
+#define PHY_DDR3_RON_RTT_28ohm		(24)
+#define PHY_DDR3_RON_RTT_26ohm		(25)
+#define PHY_DDR3_RON_RTT_25ohm		(26)
+#define PHY_DDR3_RON_RTT_23ohm		(27)
+#define PHY_DDR3_RON_RTT_22ohm		(28)
+#define PHY_DDR3_RON_RTT_21ohm		(29)
+#define PHY_DDR3_RON_RTT_20ohm		(30)
+#define PHY_DDR3_RON_RTT_19ohm		(31)
+
+#define PHY_DDR4_LPDDR3_RON_RTT_DISABLE	(0)
+#define PHY_DDR4_LPDDR3_RON_RTT_480ohm	(1)
+#define PHY_DDR4_LPDDR3_RON_RTT_240ohm	(2)
+#define PHY_DDR4_LPDDR3_RON_RTT_160ohm	(3)
+#define PHY_DDR4_LPDDR3_RON_RTT_120ohm	(4)
+#define PHY_DDR4_LPDDR3_RON_RTT_96ohm	(5)
+#define PHY_DDR4_LPDDR3_RON_RTT_80ohm	(6)
+#define PHY_DDR4_LPDDR3_RON_RTT_68ohm	(7)
+#define PHY_DDR4_LPDDR3_RON_RTT_60ohm	(16)
+#define PHY_DDR4_LPDDR3_RON_RTT_53ohm	(17)
+#define PHY_DDR4_LPDDR3_RON_RTT_48ohm	(18)
+#define PHY_DDR4_LPDDR3_RON_RTT_43ohm	(19)
+#define PHY_DDR4_LPDDR3_RON_RTT_40ohm	(20)
+#define PHY_DDR4_LPDDR3_RON_RTT_37ohm	(21)
+#define PHY_DDR4_LPDDR3_RON_RTT_34ohm	(22)
+#define PHY_DDR4_LPDDR3_RON_RTT_32ohm	(23)
+#define PHY_DDR4_LPDDR3_RON_RTT_30ohm	(24)
+#define PHY_DDR4_LPDDR3_RON_RTT_28ohm	(25)
+#define PHY_DDR4_LPDDR3_RON_RTT_26ohm	(26)
+#define PHY_DDR4_LPDDR3_RON_RTT_25ohm	(27)
+#define PHY_DDR4_LPDDR3_RON_RTT_24ohm	(28)
+#define PHY_DDR4_LPDDR3_RON_RTT_22ohm	(29)
+#define PHY_DDR4_LPDDR3_RON_RTT_21ohm	(30)
+#define PHY_DDR4_LPDDR3_RON_RTT_20ohm	(31)
+
+#endif
diff --git a/arch/arm/include/asm/arch-rockchip/sdram_px30.h b/arch/arm/include/asm/arch-rockchip/sdram_px30.h
new file mode 100644
index 0000000..2ab8e97
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/sdram_px30.h
@@ -0,0 +1,134 @@
+/* SPDX-License-Identifier:     GPL-2.0+ */
+/*
+ * Copyright (C) 2018 Rockchip Electronics Co., Ltd
+ */
+
+#ifndef _ASM_ARCH_SDRAM_PX30_H
+#define _ASM_ARCH_SDRAM_PX30_H
+#include <asm/arch-rockchip/sdram_common.h>
+#include <asm/arch-rockchip/sdram_msch.h>
+#include <asm/arch-rockchip/sdram_pctl_px30.h>
+#include <asm/arch-rockchip/sdram_phy_px30.h>
+#include <asm/arch-rockchip/sdram_phy_ron_rtt_px30.h>
+
+#define SR_IDLE				93
+#define PD_IDLE				13
+
+/* PMUGRF */
+#define PMUGRF_OS_REG0			(0x200)
+#define PMUGRF_OS_REG(n)		(PMUGRF_OS_REG0 + (n) * 4)
+
+/* DDR GRF */
+#define DDR_GRF_CON(n)			(0 + (n) * 4)
+#define DDR_GRF_STATUS_BASE		(0X100)
+#define DDR_GRF_STATUS(n)		(DDR_GRF_STATUS_BASE + (n) * 4)
+#define DDR_GRF_LP_CON			(0x20)
+
+#define SPLIT_MODE_32_L16_VALID		(0)
+#define SPLIT_MODE_32_H16_VALID		(1)
+#define SPLIT_MODE_16_L8_VALID		(2)
+#define SPLIT_MODE_16_H8_VALID		(3)
+
+#define DDR_GRF_SPLIT_CON		(0x8)
+#define SPLIT_MODE_MASK			(0x3)
+#define SPLIT_MODE_OFFSET		(9)
+#define SPLIT_BYPASS_MASK		(1)
+#define SPLIT_BYPASS_OFFSET		(8)
+#define SPLIT_SIZE_MASK			(0xff)
+#define SPLIT_SIZE_OFFSET		(0)
+
+/* CRU define */
+/* CRU_PLL_CON0 */
+#define PB(n)				((0x1 << (15 + 16)) | ((n) << 15))
+#define POSTDIV1(n)			((0x7 << (12 + 16)) | ((n) << 12))
+#define FBDIV(n)			((0xFFF << 16) | (n))
+
+/* CRU_PLL_CON1 */
+#define RSTMODE(n)			((0x1 << (15 + 16)) | ((n) << 15))
+#define RST(n)				((0x1 << (14 + 16)) | ((n) << 14))
+#define PD(n)				((0x1 << (13 + 16)) | ((n) << 13))
+#define DSMPD(n)			((0x1 << (12 + 16)) | ((n) << 12))
+#define LOCK(n)				(((n) >> 10) & 0x1)
+#define POSTDIV2(n)			((0x7 << (6 + 16)) | ((n) << 6))
+#define REFDIV(n)			((0x3F << 16) | (n))
+
+/* CRU_MODE */
+#define CLOCK_FROM_XIN_OSC		(0)
+#define CLOCK_FROM_PLL			(1)
+#define CLOCK_FROM_RTC_32K		(2)
+#define DPLL_MODE(n)			((0x3 << (4 + 16)) | ((n) << 4))
+
+/* CRU_SOFTRESET_CON1 */
+#define upctl2_psrstn_req(n)		(((0x1 << 6) << 16) | ((n) << 6))
+#define upctl2_asrstn_req(n)		(((0x1 << 5) << 16) | ((n) << 5))
+#define upctl2_srstn_req(n)		(((0x1 << 4) << 16) | ((n) << 4))
+
+/* CRU_SOFTRESET_CON2 */
+#define ddrphy_psrstn_req(n)		(((0x1 << 2) << 16) | ((n) << 2))
+#define ddrphy_srstn_req(n)		(((0x1 << 0) << 16) | ((n) << 0))
+
+/* CRU register */
+#define CRU_PLL_CON(pll_id, n)		((pll_id)  * 0x20 + (n) * 4)
+#define CRU_MODE			(0xa0)
+#define CRU_GLB_CNT_TH			(0xb0)
+#define CRU_CLKSEL_CON_BASE		0x100
+#define CRU_CLKSELS_CON(i)		(CRU_CLKSEL_CON_BASE + ((i) * 4))
+#define CRU_CLKGATE_CON_BASE		0x200
+#define CRU_CLKGATE_CON(i)		(CRU_CLKGATE_CON_BASE + ((i) * 4))
+#define CRU_CLKSFTRST_CON_BASE		0x300
+#define CRU_CLKSFTRST_CON(i)		(CRU_CLKSFTRST_CON_BASE + ((i) * 4))
+
+struct px30_ddr_grf_regs {
+	u32 ddr_grf_con[4];
+	u32 reserved1[(0x20 - 0x10) / 4];
+	u32 ddr_grf_lp_con;
+	u32 reserved2[(0x100 - 0x24) / 4];
+	u32 ddr_grf_status[11];
+};
+
+struct msch_regs {
+	u32 coreid;
+	u32 revisionid;
+	u32 deviceconf;
+	u32 devicesize;
+	u32 ddrtiminga0;
+	u32 ddrtimingb0;
+	u32 ddrtimingc0;
+	u32 devtodev0;
+	u32 reserved1[(0x110 - 0x20) / 4];
+	u32 ddrmode;
+	u32 ddr4timing;
+	u32 reserved2[(0x1000 - 0x118) / 4];
+	u32 agingx0;
+	u32 reserved3[(0x1040 - 0x1004) / 4];
+	u32 aging0;
+	u32 aging1;
+	u32 aging2;
+	u32 aging3;
+};
+
+struct sdram_msch_timings {
+	union noc_ddrtiminga0 ddrtiminga0;
+	union noc_ddrtimingb0 ddrtimingb0;
+	union noc_ddrtimingc0 ddrtimingc0;
+	union noc_devtodev0 devtodev0;
+	union noc_ddrmode ddrmode;
+	union noc_ddr4timing ddr4timing;
+	u32 agingx0;
+};
+
+struct px30_sdram_channel {
+	struct sdram_cap_info cap_info;
+	struct sdram_msch_timings noc_timings;
+};
+
+struct px30_sdram_params {
+	struct px30_sdram_channel ch;
+	struct sdram_base_params base;
+	struct ddr_pctl_regs pctl_regs;
+	struct ddr_phy_regs phy_regs;
+	struct ddr_phy_skew *skew;
+};
+
+int sdram_init(void);
+#endif
diff --git a/arch/arm/include/asm/arch-rockchip/sdram_rk3288.h b/arch/arm/include/asm/arch-rockchip/sdram_rk3288.h
new file mode 100644
index 0000000..9220763
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/sdram_rk3288.h
@@ -0,0 +1,102 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2015 Google, Inc
+ *
+ * Copyright 2014 Rockchip Inc.
+ */
+
+#ifndef _ASM_ARCH_RK3288_SDRAM_H__
+#define _ASM_ARCH_RK3288_SDRAM_H__
+
+struct rk3288_sdram_channel {
+	/*
+	 * bit width in address, eg:
+	 * 8 banks using 3 bit to address,
+	 * 2 cs using 1 bit to address.
+	 */
+	u8 rank;
+	u8 col;
+	u8 bk;
+	u8 bw;
+	u8 dbw;
+	u8 row_3_4;
+	u8 cs0_row;
+	u8 cs1_row;
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+	/*
+	 * For of-platdata, which would otherwise convert this into two
+	 * byte-swapped integers. With a size of 9 bytes, this struct will
+	 * appear in of-platdata as a byte array.
+	 *
+	 * If OF_PLATDATA enabled, need to add a dummy byte in dts.(i.e 0xff)
+	 */
+	u8 dummy;
+#endif
+};
+
+struct rk3288_sdram_pctl_timing {
+	u32 togcnt1u;
+	u32 tinit;
+	u32 trsth;
+	u32 togcnt100n;
+	u32 trefi;
+	u32 tmrd;
+	u32 trfc;
+	u32 trp;
+	u32 trtw;
+	u32 tal;
+	u32 tcl;
+	u32 tcwl;
+	u32 tras;
+	u32 trc;
+	u32 trcd;
+	u32 trrd;
+	u32 trtp;
+	u32 twr;
+	u32 twtr;
+	u32 texsr;
+	u32 txp;
+	u32 txpdll;
+	u32 tzqcs;
+	u32 tzqcsi;
+	u32 tdqs;
+	u32 tcksre;
+	u32 tcksrx;
+	u32 tcke;
+	u32 tmod;
+	u32 trstl;
+	u32 tzqcl;
+	u32 tmrr;
+	u32 tckesr;
+	u32 tdpd;
+};
+check_member(rk3288_sdram_pctl_timing, tdpd, 0x144 - 0xc0);
+
+struct rk3288_sdram_phy_timing {
+	u32 dtpr0;
+	u32 dtpr1;
+	u32 dtpr2;
+	u32 mr[4];
+};
+
+struct rk3288_base_params {
+	u32 noc_timing;
+	u32 noc_activate;
+	u32 ddrconfig;
+	u32 ddr_freq;
+	u32 dramtype;
+	/*
+	 * DDR Stride is address mapping for DRAM space
+	 * Stride	Ch 0 range	Ch1 range	Total
+	 * 0x00		0-256MB		256MB-512MB	512MB
+	 * 0x05		0-1GB		0-1GB		1GB
+	 * 0x09		0-2GB		0-2GB		2GB
+	 * 0x0d		0-4GB		0-4GB		4GB
+	 * 0x17		N/A		0-4GB		4GB
+	 * 0x1a		0-4GB		4GB-8GB		8GB
+	 */
+	u32 stride;
+	u32 odt;
+};
+
+#endif
diff --git a/arch/arm/include/asm/arch-rockchip/sdram_rk3328.h b/arch/arm/include/asm/arch-rockchip/sdram_rk3328.h
index 11411ea..1092350 100644
--- a/arch/arm/include/asm/arch-rockchip/sdram_rk3328.h
+++ b/arch/arm/include/asm/arch-rockchip/sdram_rk3328.h
@@ -6,197 +6,14 @@
 
 #ifndef _ASM_ARCH_SDRAM_RK3328_H
 #define _ASM_ARCH_SDRAM_RK3328_H
+#include <asm/arch-rockchip/sdram_common.h>
+#include <asm/arch-rockchip/sdram_pctl_px30.h>
+#include <asm/arch-rockchip/sdram_phy_px30.h>
+#include <asm/arch-rockchip/sdram_phy_ron_rtt_px30.h>
 
 #define SR_IDLE		93
 #define PD_IDLE		13
 #define SDRAM_ADDR	0x00000000
-#define PATTERN		(0x5aa5f00f)
-
-/* ddr pctl registers define */
-#define DDR_PCTL2_MSTR			0x0
-#define DDR_PCTL2_STAT			0x4
-#define DDR_PCTL2_MSTR1			0x8
-#define DDR_PCTL2_MRCTRL0		0x10
-#define DDR_PCTL2_MRCTRL1		0x14
-#define DDR_PCTL2_MRSTAT		0x18
-#define DDR_PCTL2_MRCTRL2		0x1c
-#define DDR_PCTL2_DERATEEN		0x20
-#define DDR_PCTL2_DERATEINT		0x24
-#define DDR_PCTL2_PWRCTL		0x30
-#define DDR_PCTL2_PWRTMG		0x34
-#define DDR_PCTL2_HWLPCTL		0x38
-#define DDR_PCTL2_RFSHCTL0		0x50
-#define DDR_PCTL2_RFSHCTL1		0x54
-#define DDR_PCTL2_RFSHCTL2		0x58
-#define DDR_PCTL2_RFSHCTL4		0x5c
-#define DDR_PCTL2_RFSHCTL3		0x60
-#define DDR_PCTL2_RFSHTMG		0x64
-#define DDR_PCTL2_RFSHTMG1		0x68
-#define DDR_PCTL2_RFSHCTL5		0x6c
-#define DDR_PCTL2_INIT0			0xd0
-#define DDR_PCTL2_INIT1			0xd4
-#define DDR_PCTL2_INIT2			0xd8
-#define DDR_PCTL2_INIT3			0xdc
-#define DDR_PCTL2_INIT4			0xe0
-#define DDR_PCTL2_INIT5			0xe4
-#define DDR_PCTL2_INIT6			0xe8
-#define DDR_PCTL2_INIT7			0xec
-#define DDR_PCTL2_DIMMCTL		0xf0
-#define DDR_PCTL2_RANKCTL		0xf4
-#define DDR_PCTL2_CHCTL			0xfc
-#define DDR_PCTL2_DRAMTMG0		0x100
-#define DDR_PCTL2_DRAMTMG1		0x104
-#define DDR_PCTL2_DRAMTMG2		0x108
-#define DDR_PCTL2_DRAMTMG3		0x10c
-#define DDR_PCTL2_DRAMTMG4		0x110
-#define DDR_PCTL2_DRAMTMG5		0x114
-#define DDR_PCTL2_DRAMTMG6		0x118
-#define DDR_PCTL2_DRAMTMG7		0x11c
-#define DDR_PCTL2_DRAMTMG8		0x120
-#define DDR_PCTL2_DRAMTMG9		0x124
-#define DDR_PCTL2_DRAMTMG10		0x128
-#define DDR_PCTL2_DRAMTMG11		0x12c
-#define DDR_PCTL2_DRAMTMG12		0x130
-#define DDR_PCTL2_DRAMTMG13		0x134
-#define DDR_PCTL2_DRAMTMG14		0x138
-#define DDR_PCTL2_DRAMTMG15		0x13c
-#define DDR_PCTL2_DRAMTMG16		0x140
-#define DDR_PCTL2_ZQCTL0		0x180
-#define DDR_PCTL2_ZQCTL1		0x184
-#define DDR_PCTL2_ZQCTL2		0x188
-#define DDR_PCTL2_ZQSTAT		0x18c
-#define DDR_PCTL2_DFITMG0		0x190
-#define DDR_PCTL2_DFITMG1		0x194
-#define DDR_PCTL2_DFILPCFG0		0x198
-#define DDR_PCTL2_DFILPCFG1		0x19c
-#define DDR_PCTL2_DFIUPD0		0x1a0
-#define DDR_PCTL2_DFIUPD1		0x1a4
-#define DDR_PCTL2_DFIUPD2		0x1a8
-#define DDR_PCTL2_DFIMISC		0x1b0
-#define DDR_PCTL2_DFITMG2		0x1b4
-#define DDR_PCTL2_DFITMG3		0x1b8
-#define DDR_PCTL2_DFISTAT		0x1bc
-#define DDR_PCTL2_DBICTL		0x1c0
-#define DDR_PCTL2_ADDRMAP0		0x200
-#define DDR_PCTL2_ADDRMAP1		0x204
-#define DDR_PCTL2_ADDRMAP2		0x208
-#define DDR_PCTL2_ADDRMAP3		0x20c
-#define DDR_PCTL2_ADDRMAP4		0x210
-#define DDR_PCTL2_ADDRMAP5		0x214
-#define DDR_PCTL2_ADDRMAP6		0x218
-#define DDR_PCTL2_ADDRMAP7		0x21c
-#define DDR_PCTL2_ADDRMAP8		0x220
-#define DDR_PCTL2_ADDRMAP9		0x224
-#define DDR_PCTL2_ADDRMAP10		0x228
-#define DDR_PCTL2_ADDRMAP11		0x22c
-#define DDR_PCTL2_ODTCFG		0x240
-#define DDR_PCTL2_ODTMAP		0x244
-#define DDR_PCTL2_SCHED			0x250
-#define DDR_PCTL2_SCHED1		0x254
-#define DDR_PCTL2_PERFHPR1		0x25c
-#define DDR_PCTL2_PERFLPR1		0x264
-#define DDR_PCTL2_PERFWR1		0x26c
-#define DDR_PCTL2_DQMAP0		0x280
-#define DDR_PCTL2_DQMAP1		0x284
-#define DDR_PCTL2_DQMAP2		0x288
-#define DDR_PCTL2_DQMAP3		0x28c
-#define DDR_PCTL2_DQMAP4		0x290
-#define DDR_PCTL2_DQMAP5		0x294
-#define DDR_PCTL2_DBG0			0x300
-#define DDR_PCTL2_DBG1			0x304
-#define DDR_PCTL2_DBGCAM		0x308
-#define DDR_PCTL2_DBGCMD		0x30c
-#define DDR_PCTL2_DBGSTAT		0x310
-#define DDR_PCTL2_SWCTL			0x320
-#define DDR_PCTL2_SWSTAT		0x324
-#define DDR_PCTL2_POISONCFG		0x36c
-#define DDR_PCTL2_POISONSTAT		0x370
-#define DDR_PCTL2_ADVECCINDEX		0x374
-#define DDR_PCTL2_ADVECCSTAT		0x378
-#define DDR_PCTL2_PSTAT			0x3fc
-#define DDR_PCTL2_PCCFG			0x400
-#define DDR_PCTL2_PCFGR_n		0x404
-#define DDR_PCTL2_PCFGW_n		0x408
-#define DDR_PCTL2_PCTRL_n		0x490
-
-/* PCTL2_MRSTAT */
-#define MR_WR_BUSY			BIT(0)
-
-/* PHY_REG0 */
-#define DIGITAL_DERESET			BIT(3)
-#define ANALOG_DERESET			BIT(2)
-#define DIGITAL_RESET			(0 << 3)
-#define ANALOG_RESET			(0 << 2)
-
-/* PHY_REG1 */
-#define PHY_DDR2			(0)
-#define PHY_LPDDR2			(1)
-#define PHY_DDR3			(2)
-#define PHY_LPDDR3			(3)
-#define PHY_DDR4			(4)
-#define PHY_BL_4			(0 << 2)
-#define PHY_BL_8			BIT(2)
-
-/* PHY_REG2 */
-#define PHY_DTT_EN			BIT(0)
-#define PHY_DTT_DISB			(0 << 0)
-#define PHY_WRITE_LEVELING_EN		BIT(2)
-#define PHY_WRITE_LEVELING_DISB		(0 << 2)
-#define PHY_SELECT_CS0			(2)
-#define PHY_SELECT_CS1			(1)
-#define PHY_SELECT_CS0_1		(0)
-#define PHY_WRITE_LEVELING_SELECTCS(n)	(n << 6)
-#define PHY_DATA_TRAINING_SELECTCS(n)	(n << 4)
-
-#define PHY_DDR3_RON_RTT_DISABLE	(0)
-#define PHY_DDR3_RON_RTT_451ohm		(1)
-#define PHY_DDR3_RON_RTT_225ohm		(2)
-#define PHY_DDR3_RON_RTT_150ohm		(3)
-#define PHY_DDR3_RON_RTT_112ohm		(4)
-#define PHY_DDR3_RON_RTT_90ohm		(5)
-#define PHY_DDR3_RON_RTT_75ohm		(6)
-#define PHY_DDR3_RON_RTT_64ohm		(7)
-#define PHY_DDR3_RON_RTT_56ohm		(16)
-#define PHY_DDR3_RON_RTT_50ohm		(17)
-#define PHY_DDR3_RON_RTT_45ohm		(18)
-#define PHY_DDR3_RON_RTT_41ohm		(19)
-#define PHY_DDR3_RON_RTT_37ohm		(20)
-#define PHY_DDR3_RON_RTT_34ohm		(21)
-#define PHY_DDR3_RON_RTT_33ohm		(22)
-#define PHY_DDR3_RON_RTT_30ohm		(23)
-#define PHY_DDR3_RON_RTT_28ohm		(24)
-#define PHY_DDR3_RON_RTT_26ohm		(25)
-#define PHY_DDR3_RON_RTT_25ohm		(26)
-#define PHY_DDR3_RON_RTT_23ohm		(27)
-#define PHY_DDR3_RON_RTT_22ohm		(28)
-#define PHY_DDR3_RON_RTT_21ohm		(29)
-#define PHY_DDR3_RON_RTT_20ohm		(30)
-#define PHY_DDR3_RON_RTT_19ohm		(31)
-
-#define PHY_DDR4_LPDDR3_RON_RTT_DISABLE	(0)
-#define PHY_DDR4_LPDDR3_RON_RTT_480ohm	(1)
-#define PHY_DDR4_LPDDR3_RON_RTT_240ohm	(2)
-#define PHY_DDR4_LPDDR3_RON_RTT_160ohm	(3)
-#define PHY_DDR4_LPDDR3_RON_RTT_120ohm	(4)
-#define PHY_DDR4_LPDDR3_RON_RTT_96ohm	(5)
-#define PHY_DDR4_LPDDR3_RON_RTT_80ohm	(6)
-#define PHY_DDR4_LPDDR3_RON_RTT_68ohm	(7)
-#define PHY_DDR4_LPDDR3_RON_RTT_60ohm	(16)
-#define PHY_DDR4_LPDDR3_RON_RTT_53ohm	(17)
-#define PHY_DDR4_LPDDR3_RON_RTT_48ohm	(18)
-#define PHY_DDR4_LPDDR3_RON_RTT_43ohm	(19)
-#define PHY_DDR4_LPDDR3_RON_RTT_40ohm	(20)
-#define PHY_DDR4_LPDDR3_RON_RTT_37ohm	(21)
-#define PHY_DDR4_LPDDR3_RON_RTT_34ohm	(22)
-#define PHY_DDR4_LPDDR3_RON_RTT_32ohm	(23)
-#define PHY_DDR4_LPDDR3_RON_RTT_30ohm	(24)
-#define PHY_DDR4_LPDDR3_RON_RTT_28ohm	(25)
-#define PHY_DDR4_LPDDR3_RON_RTT_26ohm	(26)
-#define PHY_DDR4_LPDDR3_RON_RTT_25ohm	(27)
-#define PHY_DDR4_LPDDR3_RON_RTT_24ohm	(28)
-#define PHY_DDR4_LPDDR3_RON_RTT_22ohm	(29)
-#define PHY_DDR4_LPDDR3_RON_RTT_21ohm	(30)
-#define PHY_DDR4_LPDDR3_RON_RTT_20ohm	(31)
 
 /* noc registers define */
 #define DDRCONF				0x8
@@ -219,16 +36,16 @@
 #define DDR_GRF_STATUS(n)	(DDR_GRF_STATUS_BASE + (n) * 4)
 
 /* CRU_SOFTRESET_CON5 */
-#define ddrphy_psrstn_req(n)    (((0x1 << 15) << 16) | (n << 15))
-#define ddrphy_srstn_req(n)     (((0x1 << 14) << 16) | (n << 14))
-#define ddrctrl_psrstn_req(n)	(((0x1 << 13) << 16) | (n << 13))
-#define ddrctrl_srstn_req(n)	(((0x1 << 12) << 16) | (n << 12))
-#define ddrmsch_srstn_req(n)	(((0x1 << 11) << 16) | (n << 11))
-#define msch_srstn_req(n)		(((0x1 << 9) << 16) | (n << 9))
-#define dfimon_srstn_req(n)		(((0x1 << 8) << 16) | (n << 8))
-#define grf_ddr_srstn_req(n)	(((0x1 << 7) << 16) | (n << 7))
+#define ddrphy_psrstn_req(n)    (((0x1 << 15) << 16) | ((n) << 15))
+#define ddrphy_srstn_req(n)     (((0x1 << 14) << 16) | ((n) << 14))
+#define ddrctrl_psrstn_req(n)	(((0x1 << 13) << 16) | ((n) << 13))
+#define ddrctrl_srstn_req(n)	(((0x1 << 12) << 16) | ((n) << 12))
+#define ddrmsch_srstn_req(n)	(((0x1 << 11) << 16) | ((n) << 11))
+#define msch_srstn_req(n)		(((0x1 << 9) << 16) | ((n) << 9))
+#define dfimon_srstn_req(n)		(((0x1 << 8) << 16) | ((n) << 8))
+#define grf_ddr_srstn_req(n)	(((0x1 << 7) << 16) | ((n) << 7))
 /* CRU_SOFTRESET_CON9 */
-#define ddrctrl_asrstn_req(n)		(((0x1 << 9) << 16) | (n << 9))
+#define ddrctrl_asrstn_req(n)		(((0x1 << 9) << 16) | ((n) << 9))
 
 /* CRU register */
 #define CRU_PLL_CON(pll_id, n)	((pll_id)  * 0x20 + (n) * 4)
@@ -255,56 +72,46 @@
 #define POSTDIV2(n)   ((0x7 << (6 + 16)) | ((n) << 6))
 #define REFDIV(n)     ((0x3F << 16) | (n))
 
-union noc_ddrtiming {
-	u32 d32;
-	struct {
-		unsigned acttoact:6;
-		unsigned rdtomiss:6;
-		unsigned wrtomiss:6;
-		unsigned burstlen:3;
-		unsigned rdtowr:5;
-		unsigned wrtord:5;
-		unsigned bwratio:1;
-	} b;
-} NOC_TIMING_T;
-
-union noc_activate {
-	u32 d32;
-	struct {
-		unsigned rrd:4;
-		unsigned faw:6;
-		unsigned fawbank:1;
-		unsigned reserved1:21;
-	} b;
-};
-
-union noc_devtodev {
-	u32 d32;
-	struct {
-		unsigned busrdtord:2;
-		unsigned busrdtowr:2;
-		unsigned buswrtord:2;
-		unsigned reserved2:26;
-	} b;
-};
-
-union noc_ddr4timing {
-	u32 d32;
-	struct {
-		unsigned ccdl:3;
-		unsigned wrtordl:5;
-		unsigned rrdl:4;
-		unsigned reserved2:20;
-	} b;
+u16 ddr_cfg_2_rbc[] = {
+	/*
+	 * [5:4]  row(13+n)
+	 * [3]    cs(0:0 cs, 1:2 cs)
+	 * [2]  bank(0:0bank,1:8bank)
+	 * [1:0]    col(11+n)
+	 */
+	/* row,        cs,       bank,   col */
+	((3 << 4) | (0 << 3) | (1 << 2) | 0),
+	((3 << 4) | (0 << 3) | (1 << 2) | 1),
+	((2 << 4) | (0 << 3) | (1 << 2) | 2),
+	((3 << 4) | (0 << 3) | (1 << 2) | 2),
+	((2 << 4) | (0 << 3) | (1 << 2) | 3),
+	((3 << 4) | (1 << 3) | (1 << 2) | 0),
+	((3 << 4) | (1 << 3) | (1 << 2) | 1),
+	((2 << 4) | (1 << 3) | (1 << 2) | 2),
+	((3 << 4) | (0 << 3) | (0 << 2) | 1),
+	((2 << 4) | (0 << 3) | (1 << 2) | 1),
 };
 
-union noc_ddrmode {
-	u32 d32;
-	struct {
-		unsigned autoprecharge:1;
-		unsigned bwratioextended:1;
-		unsigned reserved3:30;
-	} b;
+u16 ddr4_cfg_2_rbc[] = {
+	/***************************
+	 * [6]	cs 0:0cs 1:2 cs
+	 * [5:3]  row(13+n)
+	 * [2]  cs(0:0 cs, 1:2 cs)
+	 * [1]  bw    0: 16bit 1:32bit
+	 * [0]  diebw 0:8bit 1:16bit
+	 ***************************/
+	/*  cs,       row,        cs,       bw,   diebw */
+	((0 << 6) | (3 << 3) | (0 << 2) | (1 << 1) | 0),
+	((1 << 6) | (2 << 3) | (0 << 2) | (1 << 1) | 0),
+	((0 << 6) | (4 << 3) | (0 << 2) | (0 << 1) | 0),
+	((1 << 6) | (3 << 3) | (0 << 2) | (0 << 1) | 0),
+	((0 << 6) | (4 << 3) | (0 << 2) | (1 << 1) | 1),
+	((1 << 6) | (3 << 3) | (0 << 2) | (1 << 1) | 1),
+	((1 << 6) | (4 << 3) | (0 << 2) | (0 << 1) | 1),
+	((0 << 6) | (2 << 3) | (1 << 2) | (1 << 1) | 0),
+	((0 << 6) | (3 << 3) | (1 << 2) | (0 << 1) | 0),
+	((0 << 6) | (3 << 3) | (1 << 2) | (1 << 1) | 1),
+	((0 << 6) | (4 << 3) | (1 << 2) | (0 << 1) | 1),
 };
 
 u32 addrmap[21][9] = {
@@ -355,17 +162,65 @@
 		0x07070707, 0x00000f07, 0x3f00}
 };
 
-struct rk3328_msch_timings {
-	union noc_ddrtiming ddrtiming;
-	union noc_ddrmode ddrmode;
-	u32 readlatency;
-	union noc_activate activate;
-	union noc_devtodev devtodev;
-	union noc_ddr4timing ddr4timing;
-	u32 agingx0;
+struct rk3328_ddr_grf_regs {
+	u32 ddr_grf_con[4];
+	u32 reserved[(0x100 - 0x10) / 4];
+	u32 ddr_grf_status[11];
 };
 
-struct rk3328_msch_regs {
+union noc_ddrtiming {
+	u32 d32;
+	struct {
+		unsigned acttoact:6;
+		unsigned rdtomiss:6;
+		unsigned wrtomiss:6;
+		unsigned burstlen:3;
+		unsigned rdtowr:5;
+		unsigned wrtord:5;
+		unsigned bwratio:1;
+	} b;
+};
+
+union noc_activate {
+	u32 d32;
+	struct {
+		unsigned rrd:4;
+		unsigned faw:6;
+		unsigned fawbank:1;
+		unsigned reserved1:21;
+	} b;
+};
+
+union noc_devtodev {
+	u32 d32;
+	struct {
+		unsigned busrdtord:2;
+		unsigned busrdtowr:2;
+		unsigned buswrtord:2;
+		unsigned reserved2:26;
+	} b;
+};
+
+union noc_ddr4timing {
+	u32 d32;
+	struct {
+		unsigned ccdl:3;
+		unsigned wrtordl:5;
+		unsigned rrdl:4;
+		unsigned reserved2:20;
+	} b;
+};
+
+union noc_ddrmode {
+	u32 d32;
+	struct {
+		unsigned autoprecharge:1;
+		unsigned bwratioextended:1;
+		unsigned reserved3:30;
+	} b;
+};
+
+struct msch_regs {
 	u32 coreid;
 	u32 revisionid;
 	u32 ddrconf;
@@ -384,58 +239,27 @@
 	u32 ddr4_timing;
 };
 
-struct rk3328_ddr_grf_regs {
-	u32 ddr_grf_con[4];
-	u32 reserved[(0x100 - 0x10) / 4];
-	u32 ddr_grf_status[11];
-};
-
-struct rk3328_ddr_pctl_regs {
-	u32 pctl[30][2];
-};
-
-struct rk3328_ddr_phy_regs {
-	u32 phy[5][2];
-};
-
-struct rk3328_ddr_skew {
-	u32 a0_a1_skew[15];
-	u32 cs0_dm0_skew[11];
-	u32 cs0_dm1_skew[11];
-	u32 cs0_dm2_skew[11];
-	u32 cs0_dm3_skew[11];
-	u32 cs1_dm0_skew[11];
-	u32 cs1_dm1_skew[11];
-	u32 cs1_dm2_skew[11];
-	u32 cs1_dm3_skew[11];
+struct sdram_msch_timings {
+	union noc_ddrtiming ddrtiming;
+	union noc_ddrmode ddrmode;
+	u32 readlatency;
+	union noc_activate activate;
+	union noc_devtodev devtodev;
+	union noc_ddr4timing ddr4timing;
+	u32 agingx0;
 };
 
 struct rk3328_sdram_channel {
-	unsigned int rank;
-	unsigned int col;
-	/* 3:8bank, 2:4bank */
-	unsigned int bk;
-	/* channel buswidth, 2:32bit, 1:16bit, 0:8bit */
-	unsigned int bw;
-	/* die buswidth, 2:32bit, 1:16bit, 0:8bit */
-	unsigned int dbw;
-	unsigned int row_3_4;
-	unsigned int cs0_row;
-	unsigned int cs1_row;
-	unsigned int ddrconfig;
-	struct rk3328_msch_timings noc_timings;
+	struct sdram_cap_info cap_info;
+	struct sdram_msch_timings noc_timings;
 };
 
 struct rk3328_sdram_params {
 	struct rk3328_sdram_channel ch;
-	unsigned int ddr_freq;
-	unsigned int dramtype;
-	unsigned int odt;
-	struct rk3328_ddr_pctl_regs pctl_regs;
-	struct rk3328_ddr_phy_regs phy_regs;
-	struct rk3328_ddr_skew skew;
+	struct sdram_base_params base;
+	struct ddr_pctl_regs pctl_regs;
+	struct ddr_phy_regs phy_regs;
+	struct ddr_phy_skew skew;
 };
 
-#define PHY_REG(base, n)		(base + 4 * (n))
-
 #endif
diff --git a/arch/arm/include/asm/arch-rockchip/sdram_rk3399.h b/arch/arm/include/asm/arch-rockchip/sdram_rk3399.h
index dc65ae7..267649f 100644
--- a/arch/arm/include/asm/arch-rockchip/sdram_rk3399.h
+++ b/arch/arm/include/asm/arch-rockchip/sdram_rk3399.h
@@ -5,6 +5,8 @@
 
 #ifndef _ASM_ARCH_SDRAM_RK3399_H
 #define _ASM_ARCH_SDRAM_RK3399_H
+#include <asm/arch-rockchip/sdram_common.h>
+#include <asm/arch-rockchip/sdram_msch.h>
 
 struct rk3399_ddr_pctl_regs {
 	u32 denali_ctl[332];
@@ -18,55 +20,6 @@
 	u32 denali_pi[200];
 };
 
-union noc_ddrtimingc0 {
-	u32 d32;
-	struct {
-		unsigned burstpenalty : 4;
-		unsigned reserved0 : 4;
-		unsigned wrtomwr : 6;
-		unsigned reserved1 : 18;
-	} b;
-};
-
-union noc_ddrmode {
-	u32 d32;
-	struct {
-		unsigned autoprecharge : 1;
-		unsigned bypassfiltering : 1;
-		unsigned fawbank : 1;
-		unsigned burstsize : 2;
-		unsigned mwrsize : 2;
-		unsigned reserved2 : 1;
-		unsigned forceorder : 8;
-		unsigned forceorderstate : 8;
-		unsigned reserved3 : 8;
-	} b;
-};
-
-struct rk3399_msch_regs {
-	u32 coreid;
-	u32 revisionid;
-	u32 ddrconf;
-	u32 ddrsize;
-	u32 ddrtiminga0;
-	u32 ddrtimingb0;
-	u32 ddrtimingc0;
-	u32 devtodev0;
-	u32 reserved0[(0x110 - 0x20) / 4];
-	u32 ddrmode;
-	u32 reserved1[(0x1000 - 0x114) / 4];
-	u32 agingx0;
-};
-
-struct rk3399_msch_timings {
-	u32 ddrtiminga0;
-	u32 ddrtimingb0;
-	union noc_ddrtimingc0 ddrtimingc0;
-	u32 devtodev0;
-	union noc_ddrmode ddrmode;
-	u32 agingx0;
-};
-
 struct rk3399_ddr_cic_regs {
 	u32 cic_ctrl0;
 	u32 cic_ctrl1;
@@ -83,14 +36,38 @@
 #define START		1
 
 /* DENALI_CTL_68 */
-#define PWRUP_SREFRESH_EXIT	(1 << 16)
+#define PWRUP_SREFRESH_EXIT	BIT(16)
 
 /* DENALI_CTL_274 */
 #define MEM_RST_VALID	1
 
+struct msch_regs {
+	u32 coreid;
+	u32 revisionid;
+	u32 ddrconf;
+	u32 ddrsize;
+	union noc_ddrtiminga0 ddrtiminga0;
+	union noc_ddrtimingb0 ddrtimingb0;
+	union noc_ddrtimingc0 ddrtimingc0;
+	union noc_devtodev0 devtodev0;
+	u32 reserved0[(0x110 - 0x20) / 4];
+	union noc_ddrmode ddrmode;
+	u32 reserved1[(0x1000 - 0x114) / 4];
+	u32 agingx0;
+};
+
+struct sdram_msch_timings {
+	union noc_ddrtiminga0 ddrtiminga0;
+	union noc_ddrtimingb0 ddrtimingb0;
+	union noc_ddrtimingc0 ddrtimingc0;
+	union noc_devtodev0 devtodev0;
+	union noc_ddrmode ddrmode;
+	u32 agingx0;
+};
+
 struct rk3399_sdram_channel {
 	struct sdram_cap_info cap_info;
-	struct rk3399_msch_timings noc_timings;
+	struct sdram_msch_timings noc_timings;
 };
 
 struct rk3399_sdram_params {
@@ -101,11 +78,20 @@
 	struct rk3399_ddr_publ_regs phy_regs;
 };
 
-#define PI_CA_TRAINING		(1 << 0)
-#define PI_WRITE_LEVELING	(1 << 1)
-#define PI_READ_GATE_TRAINING	(1 << 2)
-#define PI_READ_LEVELING	(1 << 3)
-#define PI_WDQ_LEVELING		(1 << 4)
+#define PI_CA_TRAINING		BIT(0)
+#define PI_WRITE_LEVELING	BIT(1)
+#define PI_READ_GATE_TRAINING	BIT(2)
+#define PI_READ_LEVELING	BIT(3)
+#define PI_WDQ_LEVELING		BIT(4)
 #define PI_FULL_TRAINING	0xff
 
+enum {
+	STRIDE_128B = 0,
+	STRIDE_256B = 1,
+	STRIDE_512B = 2,
+	STRIDE_4KB = 3,
+	UN_STRIDE = 4,
+	PART_STRIDE = 5,
+};
+
 #endif
diff --git a/arch/arm/include/asm/mach-imx/iomux-v3.h b/arch/arm/include/asm/mach-imx/iomux-v3.h
index 720e8f7..3d5586e 100644
--- a/arch/arm/include/asm/mach-imx/iomux-v3.h
+++ b/arch/arm/include/asm/mach-imx/iomux-v3.h
@@ -104,7 +104,7 @@
 #define PAD_CTL_ODE		(0x1 << 5)
 #define PAD_CTL_PUE		(0x1 << 6)
 #define PAD_CTL_HYS		(0x1 << 7)
-#ifdef CONFIG_IMX8MM
+#if defined(CONFIG_IMX8MM) || defined(CONFIG_IMX8MN)
 #define PAD_CTL_PE		(0x1 << 8)
 #else
 #define PAD_CTL_LVTTL		(0x1 << 8)
diff --git a/arch/arm/include/asm/mach-imx/sys_proto.h b/arch/arm/include/asm/mach-imx/sys_proto.h
index 1e627c8..52c83ba 100644
--- a/arch/arm/include/asm/mach-imx/sys_proto.h
+++ b/arch/arm/include/asm/mach-imx/sys_proto.h
@@ -53,6 +53,8 @@
 #define is_imx8mmdl() (is_cpu_type(MXC_CPU_IMX8MMDL))
 #define is_imx8mms() (is_cpu_type(MXC_CPU_IMX8MMS))
 #define is_imx8mmsl() (is_cpu_type(MXC_CPU_IMX8MMSL))
+#define is_imx8mn() (is_cpu_type(MXC_CPU_IMX8MN))
+
 #define is_imx8qxp() (is_cpu_type(MXC_CPU_IMX8QXP))
 
 #ifdef CONFIG_MX6
@@ -104,6 +106,39 @@
 
 #endif /* CONFIG_MX6 */
 
+#ifdef CONFIG_IMX8M
+struct rom_api {
+	u16 ver;
+	u16 tag;
+	u32 reserved1;
+	u32 (*download_image)(u8 *dest, u32 offset, u32 size,  u32 xor);
+	u32 (*query_boot_infor)(u32 info_type, u32 *info, u32 xor);
+};
+
+enum boot_dev_type_e {
+	BT_DEV_TYPE_SD = 1,
+	BT_DEV_TYPE_MMC = 2,
+	BT_DEV_TYPE_NAND = 3,
+	BT_DEV_TYPE_FLEXSPINOR = 4,
+
+	BT_DEV_TYPE_USB = 0xE,
+	BT_DEV_TYPE_MEM_DEV = 0xF,
+
+	BT_DEV_TYPE_INVALID = 0xFF
+};
+
+#define QUERY_ROM_VER		1
+#define QUERY_BT_DEV		2
+#define QUERY_PAGE_SZ		3
+#define QUERY_IVT_OFF		4
+#define QUERY_BT_STAGE		5
+#define QUERY_IMG_OFF		6
+
+#define ROM_API_OKAY		0xF0
+
+extern struct rom_api *g_rom_api;
+#endif
+
 u32 get_nr_cpus(void);
 u32 get_cpu_rev(void);
 u32 get_cpu_speed_grade_hz(void);
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index 48ee6c3..9de9a9a 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -35,7 +35,7 @@
 obj-$(CONFIG_CMD_BOOTZ) += bootm.o zimage.o
 obj-$(CONFIG_SYS_L2_PL310) += cache-pl310.o
 else
-obj-$(CONFIG_SPL_FRAMEWORK) += spl.o
+obj-$(CONFIG_$(SPL_TPL_)FRAMEWORK) += spl.o
 obj-$(CONFIG_SPL_FRAMEWORK) += zimage.o
 obj-$(CONFIG_OF_LIBFDT) += bootm-fdt.o
 endif
diff --git a/arch/arm/lib/crt0.S b/arch/arm/lib/crt0.S
index c74641d..fb6c37c 100644
--- a/arch/arm/lib/crt0.S
+++ b/arch/arm/lib/crt0.S
@@ -149,7 +149,7 @@
 
 	bl	c_runtime_cpu_setup	/* we still call old routine here */
 #endif
-#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_FRAMEWORK)
+#if !defined(CONFIG_SPL_BUILD) || CONFIG_IS_ENABLED(FRAMEWORK)
 
 #if !defined(CONFIG_SPL_EARLY_BSS)
 	SPL_CLEAR_BSS
diff --git a/arch/arm/lib/crt0_64.S b/arch/arm/lib/crt0_64.S
index e76b25a..04afa51 100644
--- a/arch/arm/lib/crt0_64.S
+++ b/arch/arm/lib/crt0_64.S
@@ -120,6 +120,7 @@
  */
 	bl	c_runtime_cpu_setup		/* still call old routine */
 #endif /* !CONFIG_SPL_BUILD */
+#if !defined(CONFIG_SPL_BUILD) || CONFIG_IS_ENABLED(FRAMEWORK)
 #if defined(CONFIG_SPL_BUILD)
 	bl	spl_relocate_stack_gd           /* may return NULL */
 	/* set up gd here, outside any C code, if new stack is returned */
@@ -152,5 +153,6 @@
 	b	board_init_r			/* PC relative jump */
 
 	/* NOTREACHED - board_init_r() does not return */
+#endif
 
 ENDPROC(_main)
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 3f93fe5..751c0b5 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -109,3 +109,7 @@
 	  NXP does NOT recommend to perform this calibration at each boot. One
 	  shall perform it on a new PCB and then use those values to program
 	  the ddrmc_cr_setting on relevant board file.
+
+config SPL_IMX_ROMAPI_LOADADDR
+	hex "Default load address to load image through ROM API"
+	depends on IMX8MN
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 6e87dc5..e14713c 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -226,3 +226,5 @@
 obj-$(CONFIG_ARCH_MX7ULP) += mx7ulp/
 obj-$(CONFIG_IMX8M) += imx8m/
 obj-$(CONFIG_ARCH_IMX8) += imx8/
+
+obj-$(CONFIG_SPL_BOOTROM_SUPPORT) += spl_imx_romapi.o
diff --git a/arch/arm/mach-imx/cpu.c b/arch/arm/mach-imx/cpu.c
index d39f607..51c7c05 100644
--- a/arch/arm/mach-imx/cpu.c
+++ b/arch/arm/mach-imx/cpu.c
@@ -92,6 +92,8 @@
 const char *get_imx_type(u32 imxtype)
 {
 	switch (imxtype) {
+	case MXC_CPU_IMX8MN:
+		return "8MNano";/* Quad-core version of the imx8mn */
 	case MXC_CPU_IMX8MM:
 		return "8MMQ";	/* Quad-core version of the imx8mm */
 	case MXC_CPU_IMX8MML:
@@ -375,7 +377,7 @@
 }
 #endif
 
-#if defined(CONFIG_MX7) || defined(CONFIG_IMX8M)
+#if defined(CONFIG_MX7) || defined(CONFIG_IMX8MQ) || defined(CONFIG_IMX8MM)
 enum boot_device get_boot_device(void)
 {
 	struct bootrom_sw_info **p =
diff --git a/arch/arm/mach-imx/imx8m/Kconfig b/arch/arm/mach-imx/imx8m/Kconfig
index f520075..eb4a73b 100644
--- a/arch/arm/mach-imx/imx8m/Kconfig
+++ b/arch/arm/mach-imx/imx8m/Kconfig
@@ -12,6 +12,10 @@
 	bool
 	select IMX8M
 
+config IMX8MN
+	bool
+	select IMX8M
+
 config SYS_SOC
 	default "imx8m"
 
@@ -30,9 +34,16 @@
 	select SUPPORT_SPL
 	select IMX8M_LPDDR4
 
+config TARGET_IMX8MN_EVK
+	bool "imx8mn DDR4 EVK board"
+	select IMX8MN
+	select SUPPORT_SPL
+	select IMX8M_DDR4
+
 endchoice
 
 source "board/freescale/imx8mq_evk/Kconfig"
 source "board/freescale/imx8mm_evk/Kconfig"
+source "board/freescale/imx8mn_evk/Kconfig"
 
 endif
diff --git a/arch/arm/mach-imx/imx8m/Makefile b/arch/arm/mach-imx/imx8m/Makefile
index 92184f3..db4ba30 100644
--- a/arch/arm/mach-imx/imx8m/Makefile
+++ b/arch/arm/mach-imx/imx8m/Makefile
@@ -5,4 +5,4 @@
 obj-y += lowlevel_init.o
 obj-y += clock_slice.o soc.o
 obj-$(CONFIG_IMX8MQ) += clock_imx8mq.o
-obj-$(CONFIG_IMX8MM) += clock_imx8mm.o
+obj-$(CONFIG_IMX8MM)$(CONFIG_IMX8MN) += clock_imx8mm.o
diff --git a/arch/arm/mach-imx/imx8m/clock_slice.c b/arch/arm/mach-imx/imx8m/clock_slice.c
index 780f643..09c5615 100644
--- a/arch/arm/mach-imx/imx8m/clock_slice.c
+++ b/arch/arm/mach-imx/imx8m/clock_slice.c
@@ -475,7 +475,7 @@
 	 {DRAM_PLL1_CLK}
 	},
 };
-#elif defined(CONFIG_IMX8MM)
+#elif defined(CONFIG_IMX8MM) || defined(CONFIG_IMX8MN)
 static struct clk_root_map root_array[] = {
 	{NAND_USDHC_BUS_CLK_ROOT, BUS_CLOCK_SLICE, 2,
 	 {OSC_24M_CLK, SYSTEM_PLL1_266M_CLK, SYSTEM_PLL1_800M_CLK,
@@ -487,11 +487,13 @@
 	  SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL2_500M_CLK,
 	  AUDIO_PLL1_CLK, VIDEO_PLL_CLK, AUDIO_PLL2_CLK}
 	},
+#ifdef CONFIG_IMX8MM
 	{NOC_APB_CLK_ROOT, BUS_CLOCK_SLICE, 11,
 	 {OSC_24M_CLK, SYSTEM_PLL1_400M_CLK, SYSTEM_PLL3_CLK,
 	  SYSTEM_PLL2_333M_CLK, SYSTEM_PLL2_200M_CLK,
 	  SYSTEM_PLL1_800M_CLK, AUDIO_PLL1_CLK, VIDEO_PLL_CLK}
 	},
+#endif
 	{DRAM_ALT_CLK_ROOT, IP_CLOCK_SLICE, 0,
 	 {OSC_24M_CLK, SYSTEM_PLL1_800M_CLK, SYSTEM_PLL1_100M_CLK,
 	  SYSTEM_PLL2_500M_CLK, SYSTEM_PLL2_1000M_CLK,
diff --git a/arch/arm/mach-imx/imx8m/imximage-8mn-ddr4.cfg b/arch/arm/mach-imx/imx8m/imximage-8mn-ddr4.cfg
new file mode 100644
index 0000000..1405c65
--- /dev/null
+++ b/arch/arm/mach-imx/imx8m/imximage-8mn-ddr4.cfg
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2019 NXP
+ */
+
+#define __ASSEMBLY__
+
+FIT
+ROM_VERSION	v2
+BOOT_FROM	sd
+LOADER		spl/u-boot-spl-ddr.bin	0x912000
+SECOND_LOADER	u-boot.itb		0x40200000 0x60000
+
+DDR_FW ddr4_imem_1d.bin
+DDR_FW ddr4_dmem_1d.bin
+DDR_FW ddr4_imem_2d.bin
+DDR_FW ddr4_dmem_2d.bin
diff --git a/arch/arm/mach-imx/imx8m/soc.c b/arch/arm/mach-imx/imx8m/soc.c
index a924af4..9a203e4 100644
--- a/arch/arm/mach-imx/imx8m/soc.c
+++ b/arch/arm/mach-imx/imx8m/soc.c
@@ -56,7 +56,7 @@
 	/* Enable TZASC and lock setting */
 	setbits_le32(&gpr->gpr[10], GPR_TZASC_EN);
 	setbits_le32(&gpr->gpr[10], GPR_TZASC_EN_LOCK);
-	if (IS_ENABLED(CONFIG_IMX8MM))
+	if (is_imx8mm() || is_imx8mn())
 		setbits_le32(&gpr->gpr[10], BIT(1));
 	/*
 	 * set Region 0 attribute to allow secure and non-secure
@@ -197,7 +197,9 @@
 	reg &= 0xff;
 
 	/* i.MX8MM */
-	if (major_low == 0x41) {
+	if (major_low == 0x42) {
+		return (MXC_CPU_IMX8MN << 12) | reg;
+	} else if (major_low == 0x41) {
 		type = get_cpu_variant_type(MXC_CPU_IMX8MM);
 	} else {
 		if (reg == CHIP_REV_1_0) {
@@ -241,12 +243,14 @@
 	struct udevice *dev;
 	int ret;
 
-	ret = uclass_get_device_by_name(UCLASS_CLK,
-					"clock-controller@30380000",
-					&dev);
-	if (ret < 0) {
-		printf("Failed to find clock node. Check device tree\n");
-		return ret;
+	if (CONFIG_IS_ENABLED(CLK)) {
+		ret = uclass_get_device_by_name(UCLASS_CLK,
+						"clock-controller@30380000",
+						&dev);
+		if (ret < 0) {
+			printf("Failed to find clock node. Check device tree\n");
+			return ret;
+		}
 	}
 
 	return 0;
@@ -280,6 +284,54 @@
 
 	return 0;
 }
+
+#if defined(CONFIG_IMX8MN) || defined(CONFIG_IMX8MP)
+struct rom_api *g_rom_api = (struct rom_api *)0x980;
+
+enum boot_device get_boot_device(void)
+{
+	volatile gd_t *pgd = gd;
+	int ret;
+	u32 boot;
+	u16 boot_type;
+	u8 boot_instance;
+	enum boot_device boot_dev = SD1_BOOT;
+
+	ret = g_rom_api->query_boot_infor(QUERY_BT_DEV, &boot,
+					  ((uintptr_t)&boot) ^ QUERY_BT_DEV);
+	gd = pgd;
+
+	if (ret != ROM_API_OKAY) {
+		puts("ROMAPI: failure at query_boot_info\n");
+		return -1;
+	}
+
+	boot_type = boot >> 16;
+	boot_instance = (boot >> 8) & 0xff;
+
+	switch (boot_type) {
+	case BT_DEV_TYPE_SD:
+		boot_dev = boot_instance + SD1_BOOT;
+		break;
+	case BT_DEV_TYPE_MMC:
+		boot_dev = boot_instance + MMC1_BOOT;
+		break;
+	case BT_DEV_TYPE_NAND:
+		boot_dev = NAND_BOOT;
+		break;
+	case BT_DEV_TYPE_FLEXSPINOR:
+		boot_dev = QSPI_BOOT;
+		break;
+	case BT_DEV_TYPE_USB:
+		boot_dev = USB_BOOT;
+		break;
+	default:
+		break;
+	}
+
+	return boot_dev;
+}
+#endif
 
 bool is_usb_boot(void)
 {
diff --git a/arch/arm/mach-imx/spl.c b/arch/arm/mach-imx/spl.c
index 5cc74b6..dde1635 100644
--- a/arch/arm/mach-imx/spl.c
+++ b/arch/arm/mach-imx/spl.c
@@ -135,7 +135,7 @@
 
 	enum boot_device boot_device_spl = get_boot_device();
 
-	if (IS_ENABLED(CONFIG_IMX8MM))
+	if (IS_ENABLED(CONFIG_IMX8MM) || IS_ENABLED(CONFIG_IMX8MN))
 		return spl_board_boot_device(boot_device_spl);
 
 	switch (boot_device_spl) {
diff --git a/arch/arm/mach-imx/spl_imx_romapi.c b/arch/arm/mach-imx/spl_imx_romapi.c
new file mode 100644
index 0000000..5dc0f71
--- /dev/null
+++ b/arch/arm/mach-imx/spl_imx_romapi.c
@@ -0,0 +1,292 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2019 NXP
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <image.h>
+#include <linux/libfdt.h>
+#include <spl.h>
+
+#include <asm/arch/sys_proto.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static int is_boot_from_stream_device(u32 boot)
+{
+	u32 interface;
+
+	interface = boot >> 16;
+	if (interface >= BT_DEV_TYPE_USB)
+		return 1;
+
+	if (interface == BT_DEV_TYPE_MMC && (boot & 1))
+		return 1;
+
+	return 0;
+}
+
+static ulong spl_romapi_read_seekable(struct spl_load_info *load,
+				      ulong sector, ulong count,
+				      void *buf)
+{
+	u32 pagesize = *(u32 *)load->priv;
+	volatile gd_t *pgd = gd;
+	ulong byte = count * pagesize;
+	int ret;
+	u32 offset;
+
+	offset = sector * pagesize;
+
+	debug("ROM API load from 0x%x, size 0x%x\n", offset, (u32)byte);
+
+	ret = g_rom_api->download_image(buf, offset, byte,
+					((uintptr_t)buf) ^ offset ^ byte);
+	gd = pgd;
+
+	if (ret == ROM_API_OKAY)
+		return count;
+
+	printf("ROM API Failure when load 0x%x\n", offset);
+
+	return 0;
+}
+
+static int spl_romapi_load_image_seekable(struct spl_image_info *spl_image,
+					  struct spl_boot_device *bootdev,
+					  u32 rom_bt_dev)
+{
+	volatile gd_t *pgd = gd;
+	int ret;
+	u32 offset;
+	u32 pagesize, size;
+	struct image_header *header;
+	u32 image_offset;
+
+	ret = g_rom_api->query_boot_infor(QUERY_IVT_OFF, &offset,
+					  ((uintptr_t)&offset) ^ QUERY_IVT_OFF);
+	ret |= g_rom_api->query_boot_infor(QUERY_PAGE_SZ, &pagesize,
+					   ((uintptr_t)&pagesize) ^ QUERY_PAGE_SZ);
+	ret |= g_rom_api->query_boot_infor(QUERY_IMG_OFF, &image_offset,
+					   ((uintptr_t)&image_offset) ^ QUERY_IMG_OFF);
+
+	gd = pgd;
+
+	if (ret != ROM_API_OKAY) {
+		puts("ROMAPI: Failure query boot infor pagesize/offset\n");
+		return -1;
+	}
+
+	header = (struct image_header *)(CONFIG_SPL_IMX_ROMAPI_LOADADDR);
+
+	printf("image offset 0x%x, pagesize 0x%x, ivt offset 0x%x\n",
+	       image_offset, pagesize, offset);
+
+	if (((rom_bt_dev >> 16) & 0xff) ==  BT_DEV_TYPE_FLEXSPINOR)
+		offset = CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR * 512;
+	else
+		offset = image_offset +
+			CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR * 512 - 0x8000;
+
+	size = ALIGN(sizeof(struct image_header), pagesize);
+	ret = g_rom_api->download_image((u8 *)header, offset, size,
+					((uintptr_t)header) ^ offset ^ size);
+	gd = pgd;
+
+	if (ret != ROM_API_OKAY) {
+		printf("ROMAPI: download failure offset 0x%x size 0x%x\n",
+		       offset, size);
+		return -1;
+	}
+
+	if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
+	    image_get_magic(header) == FDT_MAGIC) {
+		struct spl_load_info load;
+
+		memset(&load, 0, sizeof(load));
+		load.bl_len = pagesize;
+		load.read = spl_romapi_read_seekable;
+		load.priv = &pagesize;
+		return spl_load_simple_fit(spl_image, &load,
+					   offset / pagesize, header);
+	} else {
+		/* TODO */
+		puts("Can't support legacy image\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+static ulong spl_ram_load_read(struct spl_load_info *load, ulong sector,
+			       ulong count, void *buf)
+{
+	memcpy(buf, (void *)(sector), count);
+
+	if (load->priv) {
+		ulong *p = (ulong *)load->priv;
+		ulong total = sector + count;
+
+		if (total > *p)
+			*p = total;
+	}
+
+	return count;
+}
+
+static ulong get_fit_image_size(void *fit)
+{
+	struct spl_image_info spl_image;
+	struct spl_load_info spl_load_info;
+	ulong last = (ulong)fit;
+
+	memset(&spl_load_info, 0, sizeof(spl_load_info));
+	spl_load_info.bl_len = 1;
+	spl_load_info.read = spl_ram_load_read;
+	spl_load_info.priv = &last;
+
+	spl_load_simple_fit(&spl_image, &spl_load_info,
+			    (uintptr_t)fit, fit);
+
+	return last - (ulong)fit;
+}
+
+u8 *search_fit_header(u8 *p, int size)
+{
+	int i;
+
+	for (i = 0; i < size; i += 4)
+		if (genimg_get_format(p + i) == IMAGE_FORMAT_FIT)
+			return p + i;
+
+	return NULL;
+}
+
+static int spl_romapi_load_image_stream(struct spl_image_info *spl_image,
+					struct spl_boot_device *bootdev)
+{
+	struct spl_load_info load;
+	volatile gd_t *pgd = gd;
+	u32 pagesize, pg;
+	int ret;
+	int i = 0;
+	u8 *p = (u8 *)CONFIG_SPL_IMX_ROMAPI_LOADADDR;
+	u8 *pfit = NULL;
+	int imagesize;
+	int total;
+
+	ret = g_rom_api->query_boot_infor(QUERY_PAGE_SZ, &pagesize,
+					  ((uintptr_t)&pagesize) ^ QUERY_PAGE_SZ);
+	gd = pgd;
+
+	if (ret != ROM_API_OKAY)
+		puts("failure at query_boot_info\n");
+
+	pg = pagesize;
+	if (pg < 1024)
+		pg = 1024;
+
+	for (i = 0; i < 640; i++) {
+		ret = g_rom_api->download_image(p, 0, pg,
+						((uintptr_t)p) ^ pg);
+		gd = pgd;
+
+		if (ret != ROM_API_OKAY) {
+			puts("Steam(USB) download failure\n");
+			return -1;
+		}
+
+		pfit = search_fit_header(p, pg);
+		p += pg;
+
+		if (pfit)
+			break;
+	}
+
+	if (!pfit) {
+		puts("Can't found uboot FIT image in 640K range \n");
+		return -1;
+	}
+
+	if (p - pfit < sizeof(struct fdt_header)) {
+		ret = g_rom_api->download_image(p, 0, pg,  ((uintptr_t)p) ^ pg);
+		gd = pgd;
+
+		if (ret != ROM_API_OKAY) {
+			puts("Steam(USB) download failure\n");
+			return -1;
+		}
+
+		p += pg;
+	}
+
+	imagesize = fit_get_size(pfit);
+	printf("Find FIT header 0x&%p, size %d\n", pfit, imagesize);
+
+	if (p - pfit < imagesize) {
+		imagesize -= p - pfit;
+		/*need pagesize hear after ROM fix USB problme*/
+		imagesize += pg - 1;
+		imagesize /= pg;
+		imagesize *= pg;
+
+		printf("Need continue download %d\n", imagesize);
+
+		ret = g_rom_api->download_image(p, 0, imagesize,
+						((uintptr_t)p) ^ imagesize);
+		gd = pgd;
+
+		p += imagesize;
+
+		if (ret != ROM_API_OKAY) {
+			printf("Failure download %d\n", imagesize);
+			return -1;
+		}
+	}
+
+	total = get_fit_image_size(pfit);
+	total += 3;
+	total &= ~0x3;
+
+	imagesize = total - (p - pfit);
+
+	imagesize += pagesize - 1;
+	imagesize /= pagesize;
+	imagesize *= pagesize;
+
+	printf("Download %d, total fit %d\n", imagesize, total);
+
+	ret = g_rom_api->download_image(p, 0, imagesize,
+					((uintptr_t)p) ^ imagesize);
+	if (ret != ROM_API_OKAY)
+		printf("ROM download failure %d\n", imagesize);
+
+	memset(&load, 0, sizeof(load));
+	load.bl_len = 1;
+	load.read = spl_ram_load_read;
+
+	return spl_load_simple_fit(spl_image, &load, (ulong)pfit, pfit);
+}
+
+int board_return_to_bootrom(struct spl_image_info *spl_image,
+			    struct spl_boot_device *bootdev)
+{
+	volatile gd_t *pgd = gd;
+	int ret;
+	u32 boot;
+
+	ret = g_rom_api->query_boot_infor(QUERY_BT_DEV, &boot,
+					  ((uintptr_t)&boot) ^ QUERY_BT_DEV);
+	gd =  pgd;
+
+	if (ret != ROM_API_OKAY) {
+		puts("ROMAPI: failure at query_boot_info\n");
+		return -1;
+	}
+
+	if (is_boot_from_stream_device(boot))
+		return spl_romapi_load_image_stream(spl_image, bootdev);
+
+	return spl_romapi_load_image_seekable(spl_image, bootdev, boot);
+}
diff --git a/arch/arm/mach-mvebu/dram.c b/arch/arm/mach-mvebu/dram.c
index fa8c799..ba8ebc6 100644
--- a/arch/arm/mach-mvebu/dram.c
+++ b/arch/arm/mach-mvebu/dram.c
@@ -281,16 +281,6 @@
 			size = MVEBU_SDRAM_SIZE_MAX;
 	}
 
-	for (; i < CONFIG_NR_DRAM_BANKS; i++) {
-		/* If above loop terminated prematurely, we need to set
-		 * remaining banks' start address & size as 0. Otherwise other
-		 * u-boot functions and Linux kernel gets wrong values which
-		 * could result in crash */
-		gd->bd->bi_dram[i].start = 0;
-		gd->bd->bi_dram[i].size = 0;
-	}
-
-
 	if (ecc_enabled())
 		dram_ecc_scrubbing();
 
diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig
index f5a80b4..4936994 100644
--- a/arch/arm/mach-rockchip/Kconfig
+++ b/arch/arm/mach-rockchip/Kconfig
@@ -1,5 +1,27 @@
 if ARCH_ROCKCHIP
 
+config ROCKCHIP_PX30
+	bool "Support Rockchip PX30"
+	select ARM64
+	select SUPPORT_SPL
+	select SUPPORT_TPL
+	select SPL
+	select TPL
+	select TPL_TINY_FRAMEWORK if TPL
+	select TPL_NEEDS_SEPARATE_TEXT_BASE if SPL
+	select TPL_NEEDS_SEPARATE_STACK if TPL
+	imply SPL_SEPARATE_BSS
+	select SPL_SERIAL_SUPPORT
+	select TPL_SERIAL_SUPPORT
+	select DEBUG_UART_BOARD_INIT
+	imply ROCKCHIP_COMMON_BOARD
+	imply SPL_ROCKCHIP_COMMON_BOARD
+	help
+	  The Rockchip PX30 is a ARM-based SoC with a quad-core Cortex-A35
+	  including NEON and GPU, Mali-400 graphics, several DDR3 options
+	  and video codec support. Peripherals include Gigabit Ethernet,
+	  USB2 host and OTG, SDIO, I2S, UART, SPI, I2C and PWMs.
+
 config ROCKCHIP_RK3036
 	bool "Support Rockchip RK3036"
 	select CPU_V7A
@@ -105,6 +127,29 @@
 	  and video codec support. Peripherals include Gigabit Ethernet,
 	  USB2 host and OTG, SDIO, I2S, UARTs, SPI, I2C and PWMs.
 
+config ROCKCHIP_RK3308
+	bool "Support Rockchip RK3308"
+	select ARM64
+	select DEBUG_UART_BOARD_INIT
+	select SUPPORT_SPL
+	select SUPPORT_TPL
+	select SPL
+	select SPL_ATF
+	select SPL_ATF_NO_PLATFORM_PARAM
+	select SPL_LOAD_FIT
+	imply ROCKCHIP_COMMON_BOARD
+	imply SPL_ROCKCHIP_COMMON_BOARD
+	imply SPL_CLK
+	imply SPL_REGMAP
+	imply SPL_SYSCON
+	imply SPL_RAM
+	imply SPL_SERIAL_SUPPORT
+	imply TPL_SERIAL_SUPPORT
+	imply SPL_SEPARATE_BSS
+	help
+	  The Rockchip RK3308 is a ARM-based Soc which embedded with quad
+	  Cortex-A35 and highly integrated audio interfaces.
+
 config ROCKCHIP_RK3328
 	bool "Support Rockchip RK3328"
 	select ARM64
@@ -115,6 +160,7 @@
 	select TPL_NEEDS_SEPARATE_TEXT_BASE if TPL
 	select TPL_NEEDS_SEPARATE_STACK if TPL
 	imply ROCKCHIP_COMMON_BOARD
+	imply ROCKCHIP_SDRAM_COMMON
 	imply SPL_ROCKCHIP_COMMON_BOARD
 	imply SPL_SERIAL_SUPPORT
 	imply TPL_SERIAL_SUPPORT
@@ -183,6 +229,7 @@
 	select DM_REGULATOR_FIXED
 	select BOARD_LATE_INIT
 	imply ROCKCHIP_COMMON_BOARD
+	imply ROCKCHIP_SDRAM_COMMON
 	imply SPL_ROCKCHIP_COMMON_BOARD
 	imply TPL_SERIAL_SUPPORT
 	imply TPL_LIBCOMMON_SUPPORT
@@ -315,11 +362,13 @@
 config SPL_MMC_SUPPORT
 	default y if !SPL_ROCKCHIP_BACK_TO_BROM
 
+source "arch/arm/mach-rockchip/px30/Kconfig"
 source "arch/arm/mach-rockchip/rk3036/Kconfig"
 source "arch/arm/mach-rockchip/rk3128/Kconfig"
 source "arch/arm/mach-rockchip/rk3188/Kconfig"
 source "arch/arm/mach-rockchip/rk322x/Kconfig"
 source "arch/arm/mach-rockchip/rk3288/Kconfig"
+source "arch/arm/mach-rockchip/rk3308/Kconfig"
 source "arch/arm/mach-rockchip/rk3328/Kconfig"
 source "arch/arm/mach-rockchip/rk3368/Kconfig"
 source "arch/arm/mach-rockchip/rk3399/Kconfig"
diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile
index 45d9b06..a728acd 100644
--- a/arch/arm/mach-rockchip/Makefile
+++ b/arch/arm/mach-rockchip/Makefile
@@ -11,6 +11,7 @@
 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-tpl-$(CONFIG_ROCKCHIP_PX30) += px30-board-tpl.o
 
 obj-spl-$(CONFIG_ROCKCHIP_RK3036) += rk3036-board-spl.o
 
@@ -25,13 +26,15 @@
 obj-$(CONFIG_MISC_INIT_R) += misc.o
 endif
 
-obj-$(CONFIG_$(SPL_TPL_)RAM) += sdram_common.o
+obj-$(CONFIG_$(SPL_TPL_)RAM) += sdram.o
 
+obj-$(CONFIG_ROCKCHIP_PX30) += px30/
 obj-$(CONFIG_ROCKCHIP_RK3036) += rk3036/
 obj-$(CONFIG_ROCKCHIP_RK3128) += rk3128/
 obj-$(CONFIG_ROCKCHIP_RK3188) += rk3188/
 obj-$(CONFIG_ROCKCHIP_RK322X) += rk322x/
 obj-$(CONFIG_ROCKCHIP_RK3288) += rk3288/
+obj-$(CONFIG_ROCKCHIP_RK3308) += rk3308/
 obj-$(CONFIG_ROCKCHIP_RK3328) += rk3328/
 obj-$(CONFIG_ROCKCHIP_RK3368) += rk3368/
 obj-$(CONFIG_ROCKCHIP_RK3399) += rk3399/
diff --git a/arch/arm/mach-rockchip/board.c b/arch/arm/mach-rockchip/board.c
index 8ca3463..c90eb97 100644
--- a/arch/arm/mach-rockchip/board.c
+++ b/arch/arm/mach-rockchip/board.c
@@ -61,29 +61,55 @@
 
 int board_usb_init(int index, enum usb_init_type init)
 {
-	int node;
+	ofnode 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, "snps,dwc2");
-
-	while (node > 0) {
-		mode = fdt_getprop(blob, node, "dr_mode", NULL);
+	node = ofnode_by_compatible(ofnode_null(), "snps,dwc2");
+	while (ofnode_valid(node)) {
+		mode = ofnode_read_string(node, "dr_mode");
 		if (mode && strcmp(mode, "otg") == 0) {
 			matched = true;
 			break;
 		}
 
-		node = fdt_node_offset_by_compatible(blob, node, "snps,dwc2");
+		node = ofnode_by_compatible(node, "snps,dwc2");
 	}
 	if (!matched) {
 		debug("Not found usb_otg device\n");
 		return -ENODEV;
 	}
+	otg_data.regs_otg = ofnode_get_addr(node);
+
+#ifdef CONFIG_ROCKCHIP_RK3288
+	int ret;
+	u32 phandle, offset;
+	ofnode phy_node;
+
+	ret = ofnode_read_u32(node, "phys", &phandle);
+	if (ret)
+		return ret;
+
+	node = ofnode_get_by_phandle(phandle);
+	if (!ofnode_valid(node)) {
+		debug("Not found usb phy device\n");
+		return -ENODEV;
+	}
+
+	phy_node = ofnode_get_parent(node);
+	if (!ofnode_valid(node)) {
+		debug("Not found usb phy device\n");
+		return -ENODEV;
+	}
-	otg_data.regs_otg = fdtdec_get_addr(blob, node, "reg");
 
+	otg_data.phy_of_node = phy_node;
+	ret = ofnode_read_u32(node, "reg", &offset);
+	if (ret)
+		return ret;
+	otg_data.regs_phy =  offset +
+		(u32)syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+#endif
 	return dwc2_udc_probe(&otg_data);
 }
 
diff --git a/arch/arm/mach-rockchip/misc.c b/arch/arm/mach-rockchip/misc.c
index c0e4fdb..bed4317 100644
--- a/arch/arm/mach-rockchip/misc.c
+++ b/arch/arm/mach-rockchip/misc.c
@@ -57,13 +57,18 @@
 			      const u32 cpuid_length,
 			      u8 *cpuid)
 {
-#if CONFIG_IS_ENABLED(ROCKCHIP_EFUSE)
+#if CONFIG_IS_ENABLED(ROCKCHIP_EFUSE) || CONFIG_IS_ENABLED(ROCKCHIP_OTP)
 	struct udevice *dev;
 	int ret;
 
 	/* retrieve the device */
+#if CONFIG_IS_ENABLED(ROCKCHIP_EFUSE)
 	ret = uclass_get_device_by_driver(UCLASS_MISC,
 					  DM_GET_DRIVER(rockchip_efuse), &dev);
+#elif CONFIG_IS_ENABLED(ROCKCHIP_OTP)
+	ret = uclass_get_device_by_driver(UCLASS_MISC,
+					  DM_GET_DRIVER(rockchip_otp), &dev);
+#endif
 	if (ret) {
 		debug("%s: could not find efuse device\n", __func__);
 		return -1;
diff --git a/arch/arm/mach-rockchip/px30-board-tpl.c b/arch/arm/mach-rockchip/px30-board-tpl.c
new file mode 100644
index 0000000..8c8976f
--- /dev/null
+++ b/arch/arm/mach-rockchip/px30-board-tpl.c
@@ -0,0 +1,59 @@
+// 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 <version.h>
+#include <asm/io.h>
+#include <asm/arch-rockchip/bootrom.h>
+#include <asm/arch-rockchip/sdram_px30.h>
+
+#define TIMER_LOAD_COUNT0	0x00
+#define TIMER_LOAD_COUNT1	0x04
+#define TIMER_CUR_VALUE0	0x08
+#define TIMER_CUR_VALUE1	0x0c
+#define TIMER_CONTROL_REG	0x10
+
+#define TIMER_EN	0x1
+#define	TIMER_FMODE	(0 << 1)
+#define	TIMER_RMODE	(1 << 1)
+
+void secure_timer_init(void)
+{
+	writel(0, CONFIG_ROCKCHIP_STIMER_BASE + TIMER_CONTROL_REG);
+	writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE + TIMER_LOAD_COUNT0);
+	writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE + TIMER_LOAD_COUNT1);
+	writel(TIMER_EN | TIMER_FMODE,
+	       CONFIG_ROCKCHIP_STIMER_BASE + TIMER_CONTROL_REG);
+}
+
+void board_init_f(ulong dummy)
+{
+	int ret;
+
+#ifdef CONFIG_DEBUG_UART
+	debug_uart_init();
+	/*
+	 * Debug UART can be used from here if required:
+	 *
+	 * debug_uart_init();
+	 * printch('a');
+	 * printhex8(0x1234);
+	 * printascii("string");
+	 */
+	printascii("U-Boot TPL board init\n");
+#endif
+
+	secure_timer_init();
+	ret = sdram_init();
+	if (ret)
+		printascii("sdram_init failed\n");
+
+	/* return to maskrom */
+	back_to_bootrom(BROM_BOOT_NEXTSTAGE);
+}
diff --git a/arch/arm/mach-rockchip/px30/Kconfig b/arch/arm/mach-rockchip/px30/Kconfig
new file mode 100644
index 0000000..109a37b
--- /dev/null
+++ b/arch/arm/mach-rockchip/px30/Kconfig
@@ -0,0 +1,41 @@
+if ROCKCHIP_PX30
+
+config TARGET_EVB_PX30
+	bool "EVB_PX30"
+
+config ROCKCHIP_BOOT_MODE_REG
+	default 0xff010200
+
+config SYS_SOC
+	default "px30"
+
+config SYS_MALLOC_F_LEN
+	default 0x400
+
+config SPL_SERIAL_SUPPORT
+	default y
+
+config TPL_LDSCRIPT
+	default "arch/arm/mach-rockchip/u-boot-tpl-v8.lds"
+
+config TPL_TEXT_BASE
+	default 0xff0e1000
+
+config TPL_MAX_SIZE
+	default 10240
+
+config TPL_STACK
+	default 0xff0e4fff
+
+config DEBUG_UART2_CHANNEL
+	int "Mux channel to use for debug UART2"
+	depends on DEBUG_UART_BOARD_INIT
+	default 0
+	help
+	  UART2 can use two different set of pins to route the output.
+	  For using the UART for early debugging the route to use needs
+	  to be declared (0 or 1).
+
+source "board/rockchip/evb_px30/Kconfig"
+
+endif
diff --git a/arch/arm/mach-rockchip/px30/Makefile b/arch/arm/mach-rockchip/px30/Makefile
new file mode 100644
index 0000000..080ce14
--- /dev/null
+++ b/arch/arm/mach-rockchip/px30/Makefile
@@ -0,0 +1,13 @@
+#
+# (C) Copyright 2017 Rockchip Electronics Co., Ltd.
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-y += clk_px30.o
+
+ifndef CONFIG_TPL_BUILD
+obj-y += syscon_px30.o
+endif
+
+obj-y += px30.o
diff --git a/arch/arm/mach-rockchip/px30/clk_px30.c b/arch/arm/mach-rockchip/px30/clk_px30.c
new file mode 100644
index 0000000..0bd6b47
--- /dev/null
+++ b/arch/arm/mach-rockchip/px30/clk_px30.c
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * (C) Copyright 2017 Rockchip Electronics Co., Ltd.
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <syscon.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/cru_px30.h>
+
+int rockchip_get_clk(struct udevice **devp)
+{
+	return uclass_get_device_by_driver(UCLASS_CLK,
+			DM_GET_DRIVER(rockchip_px30_cru), devp);
+}
+
+void *rockchip_get_cru(void)
+{
+	struct px30_clk_priv *priv;
+	struct udevice *dev;
+	int ret;
+
+	ret = rockchip_get_clk(&dev);
+	if (ret)
+		return ERR_PTR(ret);
+
+	priv = dev_get_priv(dev);
+
+	return priv->cru;
+}
diff --git a/arch/arm/mach-rockchip/px30/px30.c b/arch/arm/mach-rockchip/px30/px30.c
new file mode 100644
index 0000000..bacdcc0
--- /dev/null
+++ b/arch/arm/mach-rockchip/px30/px30.c
@@ -0,0 +1,248 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2017 Rockchip Electronics Co., Ltd
+ */
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <asm/armv8/mmu.h>
+#include <asm/io.h>
+#include <asm/arch-rockchip/grf_px30.h>
+#include <asm/arch-rockchip/hardware.h>
+#include <asm/arch-rockchip/uart.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/cru_px30.h>
+#include <dt-bindings/clock/px30-cru.h>
+
+static struct mm_region px30_mem_map[] = {
+	{
+		.virt = 0x0UL,
+		.phys = 0x0UL,
+		.size = 0xff000000UL,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+			 PTE_BLOCK_INNER_SHARE
+	}, {
+		.virt = 0xff000000UL,
+		.phys = 0xff000000UL,
+		.size = 0x01000000UL,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+			 PTE_BLOCK_NON_SHARE |
+			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
+	}, {
+		/* List terminator */
+		0,
+	}
+};
+
+struct mm_region *mem_map = px30_mem_map;
+
+#define PMU_PWRDN_CON			0xff000018
+#define GRF_BASE			0xff140000
+#define CRU_BASE			0xff2b0000
+#define VIDEO_PHY_BASE			0xff2e0000
+#define SERVICE_CORE_ADDR		0xff508000
+#define DDR_FW_BASE			0xff534000
+
+#define FW_DDR_CON			0x40
+
+#define QOS_PRIORITY			0x08
+
+#define QOS_PRIORITY_LEVEL(h, l)	((((h) & 3) << 8) | ((l) & 3))
+
+/* GRF_GPIO1CL_IOMUX */
+enum {
+	GPIO1C1_SHIFT		= 4,
+	GPIO1C1_MASK		= 0xf << GPIO1C1_SHIFT,
+	GPIO1C1_GPIO		= 0,
+	GPIO1C1_UART1_TX,
+
+	GPIO1C0_SHIFT		= 0,
+	GPIO1C0_MASK		= 0xf << GPIO1C0_SHIFT,
+	GPIO1C0_GPIO		= 0,
+	GPIO1C0_UART1_RX,
+};
+
+/* GRF_GPIO1DL_IOMUX */
+enum {
+	GPIO1D3_SHIFT		= 12,
+	GPIO1D3_MASK		= 0xf << GPIO1D3_SHIFT,
+	GPIO1D3_GPIO		= 0,
+	GPIO1D3_SDMMC_D1,
+	GPIO1D3_UART2_RXM0,
+
+	GPIO1D2_SHIFT		= 8,
+	GPIO1D2_MASK		= 0xf << GPIO1D2_SHIFT,
+	GPIO1D2_GPIO		= 0,
+	GPIO1D2_SDMMC_D0,
+	GPIO1D2_UART2_TXM0,
+};
+
+/* GRF_GPIO1DH_IOMUX */
+enum {
+	GPIO1D7_SHIFT		= 12,
+	GPIO1D7_MASK		= 0xf << GPIO1D7_SHIFT,
+	GPIO1D7_GPIO		= 0,
+	GPIO1D7_SDMMC_CMD,
+
+	GPIO1D6_SHIFT		= 8,
+	GPIO1D6_MASK		= 0xf << GPIO1D6_SHIFT,
+	GPIO1D6_GPIO		= 0,
+	GPIO1D6_SDMMC_CLK,
+
+	GPIO1D5_SHIFT		= 4,
+	GPIO1D5_MASK		= 0xf << GPIO1D5_SHIFT,
+	GPIO1D5_GPIO		= 0,
+	GPIO1D5_SDMMC_D3,
+
+	GPIO1D4_SHIFT		= 0,
+	GPIO1D4_MASK		= 0xf << GPIO1D4_SHIFT,
+	GPIO1D4_GPIO		= 0,
+	GPIO1D4_SDMMC_D2,
+};
+
+/* GRF_GPIO2BH_IOMUX */
+enum {
+	GPIO2B6_SHIFT		= 8,
+	GPIO2B6_MASK		= 0xf << GPIO2B6_SHIFT,
+	GPIO2B6_GPIO		= 0,
+	GPIO2B6_CIF_D1M0,
+	GPIO2B6_UART2_RXM1,
+
+	GPIO2B4_SHIFT		= 0,
+	GPIO2B4_MASK		= 0xf << GPIO2B4_SHIFT,
+	GPIO2B4_GPIO		= 0,
+	GPIO2B4_CIF_D0M0,
+	GPIO2B4_UART2_TXM1,
+};
+
+/* GRF_GPIO3AL_IOMUX */
+enum {
+	GPIO3A2_SHIFT		= 8,
+	GPIO3A2_MASK		= 0xf << GPIO3A2_SHIFT,
+	GPIO3A2_GPIO		= 0,
+	GPIO3A2_UART5_TX	= 4,
+
+	GPIO3A1_SHIFT		= 4,
+	GPIO3A1_MASK		= 0xf << GPIO3A1_SHIFT,
+	GPIO3A1_GPIO		= 0,
+	GPIO3A1_UART5_RX	= 4,
+};
+
+int arch_cpu_init(void)
+{
+	static struct px30_grf * const grf = (void *)GRF_BASE;
+	u32 __maybe_unused val;
+
+#ifdef CONFIG_SPL_BUILD
+	/* We do some SoC one time setting here. */
+	/* Disable the ddr secure region setting to make it non-secure */
+	writel(0x0, DDR_FW_BASE + FW_DDR_CON);
+
+	/* Set cpu qos priority */
+	writel(QOS_PRIORITY_LEVEL(1, 1), SERVICE_CORE_ADDR + QOS_PRIORITY);
+
+#if !defined(CONFIG_DEBUG_UART_BOARD_INIT) || \
+	(CONFIG_DEBUG_UART_BASE != 0xff160000) || \
+	(CONFIG_DEBUG_UART_CHANNEL != 0)
+	/* fix sdmmc pinmux if not using uart2-channel0 as debug uart */
+	rk_clrsetreg(&grf->gpio1dl_iomux,
+		     GPIO1D3_MASK | GPIO1D2_MASK,
+		     GPIO1D3_SDMMC_D1 << GPIO1D3_SHIFT |
+		     GPIO1D2_SDMMC_D0 << GPIO1D2_SHIFT);
+	rk_clrsetreg(&grf->gpio1dh_iomux,
+		     GPIO1D7_MASK | GPIO1D6_MASK | GPIO1D5_MASK | GPIO1D4_MASK,
+		     GPIO1D7_SDMMC_CMD << GPIO1D7_SHIFT |
+		     GPIO1D6_SDMMC_CLK << GPIO1D6_SHIFT |
+		     GPIO1D5_SDMMC_D3 << GPIO1D5_SHIFT |
+		     GPIO1D4_SDMMC_D2 << GPIO1D4_SHIFT);
+#endif
+
+#endif
+
+	/* Enable PD_VO (default disable at reset) */
+	rk_clrreg(PMU_PWRDN_CON, 1 << 13);
+
+	/* Disable video phy bandgap by default */
+	writel(0x82, VIDEO_PHY_BASE + 0x0000);
+	writel(0x05, VIDEO_PHY_BASE + 0x03ac);
+
+	/* Clear the force_jtag */
+	rk_clrreg(&grf->cpu_con[1], 1 << 7);
+
+	return 0;
+}
+
+#ifdef CONFIG_DEBUG_UART_BOARD_INIT
+void board_debug_uart_init(void)
+{
+	static struct px30_grf * const grf = (void *)GRF_BASE;
+	static struct px30_cru * const cru = (void *)CRU_BASE;
+
+#if defined(CONFIG_DEBUG_UART_BASE) && (CONFIG_DEBUG_UART_BASE == 0xff158000)
+	/* uart_sel_clk default select 24MHz */
+	rk_clrsetreg(&cru->clksel_con[34],
+		     UART1_PLL_SEL_MASK | UART1_DIV_CON_MASK,
+		     UART1_PLL_SEL_24M << UART1_PLL_SEL_SHIFT | 0);
+	rk_clrsetreg(&cru->clksel_con[35],
+		     UART1_CLK_SEL_MASK,
+		     UART1_CLK_SEL_UART1 << UART1_CLK_SEL_SHIFT);
+
+	rk_clrsetreg(&grf->gpio1cl_iomux,
+		     GPIO1C1_MASK | GPIO1C0_MASK,
+		     GPIO1C1_UART1_TX << GPIO1C1_SHIFT |
+		     GPIO1C0_UART1_RX << GPIO1C0_SHIFT);
+#elif defined(CONFIG_DEBUG_UART_BASE) && (CONFIG_DEBUG_UART_BASE == 0xff178000)
+	/* uart_sel_clk default select 24MHz */
+	rk_clrsetreg(&cru->clksel_con[46],
+		     UART5_PLL_SEL_MASK | UART5_DIV_CON_MASK,
+		     UART5_PLL_SEL_24M << UART5_PLL_SEL_SHIFT | 0);
+	rk_clrsetreg(&cru->clksel_con[47],
+		     UART5_CLK_SEL_MASK,
+		     UART5_CLK_SEL_UART5 << UART5_CLK_SEL_SHIFT);
+
+	rk_clrsetreg(&grf->gpio3al_iomux,
+		     GPIO3A2_MASK | GPIO3A1_MASK,
+		     GPIO3A2_UART5_TX << GPIO3A2_SHIFT |
+		     GPIO3A1_UART5_RX << GPIO3A1_SHIFT);
+#else
+	/* GRF_IOFUNC_CON0 */
+	enum {
+		CON_IOMUX_UART2SEL_SHIFT	= 10,
+		CON_IOMUX_UART2SEL_MASK = 3 << CON_IOMUX_UART2SEL_SHIFT,
+		CON_IOMUX_UART2SEL_M0	= 0,
+		CON_IOMUX_UART2SEL_M1,
+		CON_IOMUX_UART2SEL_USBPHY,
+	};
+
+	/* uart_sel_clk default select 24MHz */
+	rk_clrsetreg(&cru->clksel_con[37],
+		     UART2_PLL_SEL_MASK | UART2_DIV_CON_MASK,
+		     UART2_PLL_SEL_24M << UART2_PLL_SEL_SHIFT | 0);
+	rk_clrsetreg(&cru->clksel_con[38],
+		     UART2_CLK_SEL_MASK,
+		     UART2_CLK_SEL_UART2 << UART2_CLK_SEL_SHIFT);
+
+#if (CONFIG_DEBUG_UART2_CHANNEL == 1)
+	/* Enable early UART2 */
+	rk_clrsetreg(&grf->iofunc_con0,
+		     CON_IOMUX_UART2SEL_MASK,
+		     CON_IOMUX_UART2SEL_M1 << CON_IOMUX_UART2SEL_SHIFT);
+
+	rk_clrsetreg(&grf->gpio2bh_iomux,
+		     GPIO2B6_MASK | GPIO2B4_MASK,
+		     GPIO2B6_UART2_RXM1 << GPIO2B6_SHIFT |
+		     GPIO2B4_UART2_TXM1 << GPIO2B4_SHIFT);
+#else
+	rk_clrsetreg(&grf->iofunc_con0,
+		     CON_IOMUX_UART2SEL_MASK,
+		     CON_IOMUX_UART2SEL_M0 << CON_IOMUX_UART2SEL_SHIFT);
+
+	rk_clrsetreg(&grf->gpio1dl_iomux,
+		     GPIO1D3_MASK | GPIO1D2_MASK,
+		     GPIO1D3_UART2_RXM0 << GPIO1D3_SHIFT |
+		     GPIO1D2_UART2_TXM0 << GPIO1D2_SHIFT);
+#endif /* CONFIG_DEBUG_UART2_CHANNEL == 1 */
+
+#endif /* CONFIG_DEBUG_UART_BASE && CONFIG_DEBUG_UART_BASE == ... */
+}
+#endif /* CONFIG_DEBUG_UART_BOARD_INIT */
diff --git a/arch/arm/mach-rockchip/px30/syscon_px30.c b/arch/arm/mach-rockchip/px30/syscon_px30.c
new file mode 100644
index 0000000..0331491
--- /dev/null
+++ b/arch/arm/mach-rockchip/px30/syscon_px30.c
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * (C) Copyright 2017 Rockchip Electronics Co., Ltd
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <syscon.h>
+#include <asm/arch-rockchip/clock.h>
+
+static const struct udevice_id px30_syscon_ids[] = {
+	{ .compatible = "rockchip,px30-pmu", .data = ROCKCHIP_SYSCON_PMU },
+	{ .compatible = "rockchip,px30-pmugrf", .data = ROCKCHIP_SYSCON_PMUGRF },
+	{ .compatible = "rockchip,px30-grf", .data = ROCKCHIP_SYSCON_GRF },
+	{ }
+};
+
+U_BOOT_DRIVER(syscon_px30) = {
+	.id = UCLASS_SYSCON,
+	.name = "px30_syscon",
+	.of_match = px30_syscon_ids,
+};
+
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+static int px30_syscon_bind_of_platdata(struct udevice *dev)
+{
+	dev->driver_data = dev->driver->of_match->data;
+	debug("syscon: %s %d\n", dev->name, (uint)dev->driver_data);
+
+	return 0;
+}
+
+U_BOOT_DRIVER(rockchip_px30_pmu) = {
+	.name = "rockchip_px30_pmu",
+	.id = UCLASS_SYSCON,
+	.of_match = px30_syscon_ids,
+	.bind = px30_syscon_bind_of_platdata,
+};
+
+U_BOOT_DRIVER(rockchip_px30_pmugrf) = {
+	.name = "rockchip_px30_pmugrf",
+	.id = UCLASS_SYSCON,
+	.of_match = px30_syscon_ids + 1,
+	.bind = px30_syscon_bind_of_platdata,
+};
+
+U_BOOT_DRIVER(rockchip_px30_grf) = {
+	.name = "rockchip_px30_grf",
+	.id = UCLASS_SYSCON,
+	.of_match = px30_syscon_ids + 2,
+	.bind = px30_syscon_bind_of_platdata,
+};
+#endif
diff --git a/arch/arm/mach-rockchip/rk3036/rk3036.c b/arch/arm/mach-rockchip/rk3036/rk3036.c
index be458cf..e9ada6d 100644
--- a/arch/arm/mach-rockchip/rk3036/rk3036.c
+++ b/arch/arm/mach-rockchip/rk3036/rk3036.c
@@ -43,7 +43,7 @@
 #if !CONFIG_IS_ENABLED(RAM)
 /*
  * When CONFIG_RAM is enabled, the dram_init() function is implemented
- * in sdram_common.c.
+ * in sdram.c.
  */
 int dram_init(void)
 {
diff --git a/arch/arm/mach-rockchip/rk3288/rk3288.c b/arch/arm/mach-rockchip/rk3288/rk3288.c
index 987b4e0..ee2fb67 100644
--- a/arch/arm/mach-rockchip/rk3288/rk3288.c
+++ b/arch/arm/mach-rockchip/rk3288/rk3288.c
@@ -15,7 +15,7 @@
 #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>
+#include <asm/arch-rockchip/sdram.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
diff --git a/arch/arm/mach-rockchip/rk3308/Kconfig b/arch/arm/mach-rockchip/rk3308/Kconfig
new file mode 100644
index 0000000..b9fdfe2
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3308/Kconfig
@@ -0,0 +1,27 @@
+if ROCKCHIP_RK3308
+
+config TARGET_EVB_RK3308
+	bool "EVB_RK3308"
+	select BOARD_LATE_INIT
+
+config TARGET_ROC_RK3308_CC
+       bool "Firefly roc-rk3308-cc"
+	select BOARD_LATE_INIT
+
+config SYS_SOC
+	default "rk3308"
+
+config SYS_MALLOC_F_LEN
+	default 0x400
+
+config SPL_SERIAL_SUPPORT
+	default y
+
+config ROCKCHIP_BOOT_MODE_REG
+	default 0xff000500
+
+
+source "board/rockchip/evb_rk3308/Kconfig"
+source "board/firefly/firefly-rk3308/Kconfig"
+
+endif
diff --git a/arch/arm/mach-rockchip/rk3308/Makefile b/arch/arm/mach-rockchip/rk3308/Makefile
new file mode 100644
index 0000000..ce4d44b
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3308/Makefile
@@ -0,0 +1,9 @@
+#
+# (C) Copyright 2018 Rockchip Electronics Co., Ltd.
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-y += syscon_rk3308.o
+obj-y += rk3308.o
+obj-y += clk_rk3308.o
diff --git a/arch/arm/mach-rockchip/rk3308/clk_rk3308.c b/arch/arm/mach-rockchip/rk3308/clk_rk3308.c
new file mode 100644
index 0000000..51b4315
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3308/clk_rk3308.c
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <syscon.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch/cru_rk3308.h>
+
+int rockchip_get_clk(struct udevice **devp)
+{
+	return uclass_get_device_by_driver(UCLASS_CLK,
+			DM_GET_DRIVER(rockchip_rk3308_cru), devp);
+}
+
+void *rockchip_get_cru(void)
+{
+	struct rk3308_clk_priv *priv;
+	struct udevice *dev;
+	int ret;
+
+	ret = rockchip_get_clk(&dev);
+	if (ret)
+		return ERR_PTR(ret);
+
+	priv = dev_get_priv(dev);
+
+	return priv->cru;
+}
diff --git a/arch/arm/mach-rockchip/rk3308/rk3308.c b/arch/arm/mach-rockchip/rk3308/rk3308.c
new file mode 100644
index 0000000..f27f9e8
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3308/rk3308.c
@@ -0,0 +1,175 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ *Copyright (c) 2018 Rockchip Electronics Co., Ltd
+ */
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/grf_rk3308.h>
+#include <asm/arch-rockchip/hardware.h>
+#include <asm/gpio.h>
+#include <debug_uart.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#include <asm/armv8/mmu.h>
+static struct mm_region rk3308_mem_map[] = {
+	{
+		.virt = 0x0UL,
+		.phys = 0x0UL,
+		.size = 0xff000000UL,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+			 PTE_BLOCK_INNER_SHARE
+	}, {
+		.virt = 0xff000000UL,
+		.phys = 0xff000000UL,
+		.size = 0x01000000UL,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+			 PTE_BLOCK_NON_SHARE |
+			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
+	}, {
+		/* List terminator */
+		0,
+	}
+};
+
+struct mm_region *mem_map = rk3308_mem_map;
+
+#define GRF_BASE	0xff000000
+#define SGRF_BASE	0xff2b0000
+
+enum {
+	GPIO1C7_SHIFT		= 8,
+	GPIO1C7_MASK		= GENMASK(11, 8),
+	GPIO1C7_GPIO		= 0,
+	GPIO1C7_UART1_RTSN,
+	GPIO1C7_UART2_TX_M0,
+	GPIO1C7_SPI2_MOSI,
+	GPIO1C7_JTAG_TMS,
+
+	GPIO1C6_SHIFT		= 4,
+	GPIO1C6_MASK		= GENMASK(7, 4),
+	GPIO1C6_GPIO		= 0,
+	GPIO1C6_UART1_CTSN,
+	GPIO1C6_UART2_RX_M0,
+	GPIO1C6_SPI2_MISO,
+	GPIO1C6_JTAG_TCLK,
+
+	GPIO4D3_SHIFT           = 6,
+	GPIO4D3_MASK            = GENMASK(7, 6),
+	GPIO4D3_GPIO            = 0,
+	GPIO4D3_SDMMC_D3,
+	GPIO4D3_UART2_TX_M1,
+
+	GPIO4D2_SHIFT           = 4,
+	GPIO4D2_MASK            = GENMASK(5, 4),
+	GPIO4D2_GPIO            = 0,
+	GPIO4D2_SDMMC_D2,
+	GPIO4D2_UART2_RX_M1,
+
+	UART2_IO_SEL_SHIFT	= 2,
+	UART2_IO_SEL_MASK	= GENMASK(3, 2),
+	UART2_IO_SEL_M0		= 0,
+	UART2_IO_SEL_M1,
+	UART2_IO_SEL_USB,
+
+	GPIO3B3_SEL_SRC_CTRL_SHIFT	= 7,
+	GPIO3B3_SEL_SRC_CTRL_MASK	= BIT(7),
+	GPIO3B3_SEL_SRC_CTRL_IOMUX	= 0,
+	GPIO3B3_SEL_SRC_CTRL_SEL_PLUS,
+
+	GPIO3B3_SEL_PLUS_SHIFT		= 4,
+	GPIO3B3_SEL_PLUS_MASK		= GENMASK(6, 4),
+	GPIO3B3_SEL_PLUS_GPIO3_B3	= 0,
+	GPIO3B3_SEL_PLUS_FLASH_ALE,
+	GPIO3B3_SEL_PLUS_EMMC_PWREN,
+	GPIO3B3_SEL_PLUS_SPI1_CLK,
+	GPIO3B3_SEL_PLUS_LCDC_D23_M1,
+
+	GPIO3B2_SEL_SRC_CTRL_SHIFT	= 3,
+	GPIO3B2_SEL_SRC_CTRL_MASK	= BIT(3),
+	GPIO3B2_SEL_SRC_CTRL_IOMUX	= 0,
+	GPIO3B2_SEL_SRC_CTRL_SEL_PLUS,
+
+	GPIO3B2_SEL_PLUS_SHIFT		= 0,
+	GPIO3B2_SEL_PLUS_MASK		= GENMASK(2, 0),
+	GPIO3B2_SEL_PLUS_GPIO3_B2	= 0,
+	GPIO3B2_SEL_PLUS_FLASH_RDN,
+	GPIO3B2_SEL_PLUS_EMMC_RSTN,
+	GPIO3B2_SEL_PLUS_SPI1_MISO,
+	GPIO3B2_SEL_PLUS_LCDC_D22_M1,
+};
+
+enum {
+	IOVSEL3_CTRL_SHIFT	= 8,
+	IOVSEL3_CTRL_MASK	= BIT(8),
+	VCCIO3_SEL_BY_GPIO	= 0,
+	VCCIO3_SEL_BY_IOVSEL3,
+
+	IOVSEL3_SHIFT		= 3,
+	IOVSEL3_MASK		= BIT(3),
+	VCCIO3_3V3		= 0,
+	VCCIO3_1V8,
+};
+
+/*
+ * The voltage of VCCIO3(which is the voltage domain of emmc/flash/sfc
+ * interface) can indicated by GPIO0_A4 or io_vsel3. The SOC defaults
+ * use GPIO0_A4 to indicate power supply voltage for VCCIO3 by hardware,
+ * then we can switch to io_vsel3 after system power on, and release GPIO0_A4
+ * for other usage.
+ */
+
+#define GPIO0_A4	4
+
+int rk_board_init(void)
+{
+	static struct rk3308_grf * const grf = (void *)GRF_BASE;
+	u32 val;
+	int ret;
+
+	ret = gpio_request(GPIO0_A4, "gpio0_a4");
+	if (ret < 0) {
+		printf("request for gpio0_a4 failed:%d\n", ret);
+		return 0;
+	}
+
+	gpio_direction_input(GPIO0_A4);
+
+	if (gpio_get_value(GPIO0_A4))
+		val = VCCIO3_SEL_BY_IOVSEL3 << IOVSEL3_CTRL_SHIFT |
+		      VCCIO3_1V8 << IOVSEL3_SHIFT;
+	else
+		val = VCCIO3_SEL_BY_IOVSEL3 << IOVSEL3_CTRL_SHIFT |
+		      VCCIO3_3V3 << IOVSEL3_SHIFT;
+	rk_clrsetreg(&grf->soc_con0, IOVSEL3_CTRL_MASK | IOVSEL3_MASK, val);
+
+	gpio_free(GPIO0_A4);
+	return 0;
+}
+
+#if defined(CONFIG_DEBUG_UART)
+__weak void board_debug_uart_init(void)
+{
+	static struct rk3308_grf * const grf = (void *)GRF_BASE;
+
+	/* Enable early UART2 channel m1 on the rk3308 */
+	rk_clrsetreg(&grf->soc_con5, UART2_IO_SEL_MASK,
+		     UART2_IO_SEL_M1 << UART2_IO_SEL_SHIFT);
+	rk_clrsetreg(&grf->gpio4d_iomux,
+		     GPIO4D3_MASK | GPIO4D2_MASK,
+		     GPIO4D2_UART2_RX_M1 << GPIO4D2_SHIFT |
+		     GPIO4D3_UART2_TX_M1 << GPIO4D3_SHIFT);
+}
+#endif
+
+#if defined(CONFIG_SPL_BUILD)
+int arch_cpu_init(void)
+{
+	static struct rk3308_sgrf * const sgrf = (void *)SGRF_BASE;
+
+	/* Set CRYPTO SDMMC EMMC NAND SFC USB master bus to be secure access */
+	rk_clrreg(&sgrf->con_secure0, 0x2b83);
+
+	return 0;
+}
+#endif
diff --git a/arch/arm/mach-rockchip/rk3308/syscon_rk3308.c b/arch/arm/mach-rockchip/rk3308/syscon_rk3308.c
new file mode 100644
index 0000000..b380ff5
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3308/syscon_rk3308.c
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier:     GPL-2.0+
+/*
+ * (C) Copyright 2018 Rockchip Electronics Co., Ltd
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <syscon.h>
+#include <asm/arch-rockchip/clock.h>
+
+static const struct udevice_id rk3308_syscon_ids[] = {
+	{ .compatible = "rockchip,rk3308-grf", .data = ROCKCHIP_SYSCON_GRF },
+	{ }
+};
+
+U_BOOT_DRIVER(syscon_rk3308) = {
+	.name = "rk3308_syscon",
+	.id = UCLASS_SYSCON,
+	.of_match = rk3308_syscon_ids,
+};
diff --git a/arch/arm/mach-rockchip/rk3399/Kconfig b/arch/arm/mach-rockchip/rk3399/Kconfig
index f781eac..01af3f1 100644
--- a/arch/arm/mach-rockchip/rk3399/Kconfig
+++ b/arch/arm/mach-rockchip/rk3399/Kconfig
@@ -62,6 +62,25 @@
 	  display. It includes a Chrome OS EC (Cortex-M3) to provide access to
 	  the keyboard and battery functions.
 
+config TARGET_ROCKPRO64_RK3399
+	bool "Pine64 Rockpro64 board"
+	help
+	  Rockro64 is SBC produced by Pine64. Key features:
+
+	   * Rockchip RK3399
+	   * 2/4GB Dual-Channel LPDDR3
+	   * SD card slot
+	   * eMMC socket
+	   * 128Mb SPI Flash
+	   * Gigabit ethernet
+	   * PCIe 4X slot
+	   * WiFI/BT module socket
+	   * HDMI In/Out, DP, MIPI DSI/CSI, eDP
+	   * USB 3.0, 2.0
+	   * USB Type C power and data
+	   * GPIO expansion ports
+	   * DC 12V/2A
+
 endchoice
 
 config ROCKCHIP_BOOT_MODE_REG
@@ -98,5 +117,6 @@
 source "board/theobroma-systems/puma_rk3399/Kconfig"
 source "board/vamrs/rock960_rk3399/Kconfig"
 source "board/google/gru/Kconfig"
+source "board/pine64/rockpro64_rk3399/Kconfig"
 
 endif
diff --git a/arch/arm/mach-rockchip/sdram_common.c b/arch/arm/mach-rockchip/sdram.c
similarity index 60%
rename from arch/arm/mach-rockchip/sdram_common.c
rename to arch/arm/mach-rockchip/sdram.c
index 22a4aca..af00a6b 100644
--- a/arch/arm/mach-rockchip/sdram_common.c
+++ b/arch/arm/mach-rockchip/sdram.c
@@ -7,7 +7,7 @@
 #include <dm.h>
 #include <ram.h>
 #include <asm/io.h>
-#include <asm/arch-rockchip/sdram_common.h>
+#include <asm/arch-rockchip/sdram.h>
 #include <dm/uclass-internal.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -76,39 +76,88 @@
 
 size_t rockchip_sdram_size(phys_addr_t reg)
 {
-	u32 rank, col, bk, cs0_row, cs1_row, bw, row_3_4;
+	u32 rank, cs0_col, bk, cs0_row, cs1_row, bw, row_3_4;
 	size_t chipsize_mb = 0;
 	size_t size_mb = 0;
 	u32 ch;
-
-	u32 sys_reg = readl(reg);
-	u32 ch_num = 1 + ((sys_reg >> SYS_REG_NUM_CH_SHIFT)
+	u32 cs1_col = 0;
+	u32 bg = 0;
+	u32 dbw, dram_type;
+	u32 sys_reg2 = readl(reg);
+	u32 sys_reg3 = readl(reg + 4);
+	u32 ch_num = 1 + ((sys_reg2 >> SYS_REG_NUM_CH_SHIFT)
 		       & SYS_REG_NUM_CH_MASK);
 
-	debug("%s %x %x\n", __func__, (u32)reg, sys_reg);
+	dram_type = (sys_reg2 >> SYS_REG_DDRTYPE_SHIFT) & SYS_REG_DDRTYPE_MASK;
+	debug("%s %x %x\n", __func__, (u32)reg, sys_reg2);
 	for (ch = 0; ch < ch_num; ch++) {
-		rank = 1 + (sys_reg >> SYS_REG_RANK_SHIFT(ch) &
+		rank = 1 + (sys_reg2 >> SYS_REG_RANK_SHIFT(ch) &
 			SYS_REG_RANK_MASK);
-		col = 9 + (sys_reg >> SYS_REG_COL_SHIFT(ch) & SYS_REG_COL_MASK);
-		bk = 3 - ((sys_reg >> SYS_REG_BK_SHIFT(ch)) & SYS_REG_BK_MASK);
-		cs0_row = 13 + (sys_reg >> SYS_REG_CS0_ROW_SHIFT(ch) &
+		cs0_col = 9 + (sys_reg2 >> SYS_REG_COL_SHIFT(ch) &
+			  SYS_REG_COL_MASK);
+		cs1_col = cs0_col;
+		bk = 3 - ((sys_reg2 >> SYS_REG_BK_SHIFT(ch)) & SYS_REG_BK_MASK);
+		if ((sys_reg3 >> SYS_REG_VERSION_SHIFT &
+		     SYS_REG_VERSION_MASK) == 0x2) {
+			cs1_col = 9 + (sys_reg3 >> SYS_REG_CS1_COL_SHIFT(ch) &
+				  SYS_REG_CS1_COL_MASK);
+			if (((sys_reg3 >> SYS_REG_EXTEND_CS0_ROW_SHIFT(ch) &
+			    SYS_REG_EXTEND_CS0_ROW_MASK) << 2) + (sys_reg2 >>
+			    SYS_REG_CS0_ROW_SHIFT(ch) &
+			    SYS_REG_CS0_ROW_MASK) == 7)
+				cs0_row = 12;
+			else
+				cs0_row = 13 + (sys_reg2 >>
+					  SYS_REG_CS0_ROW_SHIFT(ch) &
+					  SYS_REG_CS0_ROW_MASK) +
+					  ((sys_reg3 >>
+					  SYS_REG_EXTEND_CS0_ROW_SHIFT(ch) &
+					  SYS_REG_EXTEND_CS0_ROW_MASK) << 2);
+			if (((sys_reg3 >> SYS_REG_EXTEND_CS1_ROW_SHIFT(ch) &
+			    SYS_REG_EXTEND_CS1_ROW_MASK) << 2) + (sys_reg2 >>
+			    SYS_REG_CS1_ROW_SHIFT(ch) &
+			    SYS_REG_CS1_ROW_MASK) == 7)
+				cs1_row = 12;
+			else
+				cs1_row = 13 + (sys_reg2 >>
+					  SYS_REG_CS1_ROW_SHIFT(ch) &
+					  SYS_REG_CS1_ROW_MASK) +
+					  ((sys_reg3 >>
+					  SYS_REG_EXTEND_CS1_ROW_SHIFT(ch) &
+					  SYS_REG_EXTEND_CS1_ROW_MASK) << 2);
+		} else {
+			cs0_row = 13 + (sys_reg2 >> SYS_REG_CS0_ROW_SHIFT(ch) &
 				SYS_REG_CS0_ROW_MASK);
-		cs1_row = 13 + (sys_reg >> SYS_REG_CS1_ROW_SHIFT(ch) &
+			cs1_row = 13 + (sys_reg2 >> SYS_REG_CS1_ROW_SHIFT(ch) &
 				SYS_REG_CS1_ROW_MASK);
-		bw = (2 >> ((sys_reg >> SYS_REG_BW_SHIFT(ch)) &
+		}
+		bw = (2 >> ((sys_reg2 >> SYS_REG_BW_SHIFT(ch)) &
 			SYS_REG_BW_MASK));
-		row_3_4 = sys_reg >> SYS_REG_ROW_3_4_SHIFT(ch) &
+		row_3_4 = sys_reg2 >> SYS_REG_ROW_3_4_SHIFT(ch) &
 			SYS_REG_ROW_3_4_MASK;
-
-		chipsize_mb = (1 << (cs0_row + col + bk + bw - 20));
+		if (dram_type == DDR4) {
+			dbw = (sys_reg2 >> SYS_REG_DBW_SHIFT(ch)) &
+				SYS_REG_DBW_MASK;
+			bg = (dbw == 2) ? 2 : 1;
+		}
+		chipsize_mb = (1 << (cs0_row + cs0_col + bk + bg + bw - 20));
 
 		if (rank > 1)
-			chipsize_mb += chipsize_mb >> (cs0_row - cs1_row);
+			chipsize_mb += chipsize_mb >> ((cs0_row - cs1_row) +
+				       (cs0_col - cs1_col));
 		if (row_3_4)
 			chipsize_mb = chipsize_mb * 3 / 4;
 		size_mb += chipsize_mb;
-		debug("rank %d col %d bk %d cs0_row %d bw %d row_3_4 %d\n",
-		      rank, col, bk, cs0_row, bw, row_3_4);
+		if (rank > 1)
+			debug("rank %d cs0_col %d cs1_col %d bk %d cs0_row %d\
+			       cs1_row %d bw %d row_3_4 %d\n",
+			       rank, cs0_col, cs1_col, bk, cs0_row,
+			       cs1_row, bw, row_3_4);
+		else
+			debug("rank %d cs0_col %d bk %d cs0_row %d\
+			       bw %d row_3_4 %d\n",
+			       rank, cs0_col, bk, cs0_row,
+			       bw, row_3_4);
 	}
 
 	/*
diff --git a/arch/arm/mach-rockchip/spl.c b/arch/arm/mach-rockchip/spl.c
index 92102b3..514032a 100644
--- a/arch/arm/mach-rockchip/spl.c
+++ b/arch/arm/mach-rockchip/spl.c
@@ -9,7 +9,6 @@
 #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;
@@ -103,7 +102,7 @@
 void board_init_f(ulong dummy)
 {
 	int ret;
-#if !defined(CONFIG_SUPPORT_TPL) || defined(CONFIG_SPL_OS_BOOT)
+#if !defined(CONFIG_TPL) || defined(CONFIG_SPL_OS_BOOT)
 	struct udevice *dev;
 #endif
 
@@ -128,14 +127,6 @@
 		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
@@ -143,6 +134,14 @@
 	/* Init ARM arch timer in arch/arm/cpu/armv7/arch_timer.c */
 	timer_init();
 #endif
+#if !defined(CONFIG_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
 	preloader_console_init();
 }
 
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
index 8ac49bd..01c9dd5 100644
--- a/arch/powerpc/lib/Makefile
+++ b/arch/powerpc/lib/Makefile
@@ -41,5 +41,5 @@
 endif # not minimal
 
 ifdef CONFIG_SPL_BUILD
-obj-$(CONFIG_SPL_FRAMEWORK) += spl.o
+obj-$(CONFIG_$(SPL_TPL)_FRAMEWORK) += spl.o
 endif
diff --git a/arch/sandbox/config.mk b/arch/sandbox/config.mk
index 05fbbd7..a225c9c 100644
--- a/arch/sandbox/config.mk
+++ b/arch/sandbox/config.mk
@@ -27,3 +27,31 @@
 	$(PLATFORM_LIBS) -Wl,-Map -Wl,u-boot-spl.map -Wl,--gc-sections)
 
 CONFIG_ARCH_DEVICE_TREE := sandbox
+
+ifeq ($(HOST_ARCH),$(HOST_ARCH_X86_64))
+EFI_LDS := ${SRCDIR}/../../../arch/x86/lib/elf_x86_64_efi.lds
+EFI_TARGET := --target=efi-app-x86_64
+else ifeq ($(HOST_ARCH),$(HOST_ARCH_X86))
+EFI_LDS := ${SRCDIR}/../../../arch/x86/lib/elf_ia32_efi.lds
+EFI_TARGET := --target=efi-app-ia32
+else ifeq ($(HOST_ARCH),$(HOST_ARCH_AARCH64))
+EFI_LDS := ${SRCDIR}/../../../arch/arm/lib/elf_aarch64_efi.lds
+OBJCOPYFLAGS += -j .text -j .secure_text -j .secure_data -j .rodata -j .data \
+		-j .u_boot_list -j .rela.dyn -j .got -j .got.plt \
+		-j .binman_sym_table -j .text_rest \
+		-j .efi_runtime -j .efi_runtime_rel
+else ifeq ($(HOST_ARCH),$(HOST_ARCH_ARM))
+EFI_LDS := ${SRCDIR}/../../../arch/arm/lib/elf_arm_efi.lds
+OBJCOPYFLAGS += -j .text -j .secure_text -j .secure_data -j .rodata -j .hash \
+		-j .data -j .got -j .got.plt -j .u_boot_list -j .rel.dyn \
+		-j .binman_sym_table -j .text_rest \
+		-j .efi_runtime -j .efi_runtime_rel
+else ifeq ($(HOST_ARCH),$(HOST_ARCH_RISCV32))
+EFI_LDS := ${SRCDIR}/../../../arch/riscv/lib/elf_riscv32_efi.lds
+else ifeq ($(HOST_ARCH),$(HOST_ARCH_RISCV64))
+EFI_LDS := ${SRCDIR}/../../../arch/riscv/lib/elf_riscv64_efi.lds
+endif
+EFI_CRT0 := crt0_sandbox_efi.o
+EFI_RELOC := reloc_sandbox_efi.o
+AFLAGS_crt0_sandbox_efi.o += -DHOST_ARCH="$(HOST_ARCH)"
+CFLAGS_reloc_sandbox_efi.o += -DHOST_ARCH="$(HOST_ARCH)"
diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c
index 47dfb47..79094fb 100644
--- a/arch/sandbox/cpu/os.c
+++ b/arch/sandbox/cpu/os.c
@@ -816,10 +816,10 @@
 		char *end = memchr(line, '-', len);
 
 		if (end) {
-			unsigned long long addr;
+			uintptr_t addr;
 
 			*end = '\0';
-			if (sscanf(line, "%llx", &addr) == 1)
+			if (sscanf(line, "%zx", &addr) == 1)
 				base = (void *)addr;
 		}
 	}
diff --git a/arch/sandbox/lib/crt0_sandbox_efi.S b/arch/sandbox/lib/crt0_sandbox_efi.S
new file mode 100644
index 0000000..8853734
--- /dev/null
+++ b/arch/sandbox/lib/crt0_sandbox_efi.S
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * PE/COFF header for EFI applications
+ *
+ * Copyright (c) 2019 Heinrich Schuchardt
+ */
+
+#include <host_arch.h>
+
+#if HOST_ARCH == HOST_ARCH_X86_64
+#include "../../../arch/x86/lib/crt0_x86_64_efi.S"
+#endif
+
+#if HOST_ARCH == HOST_ARCH_X86
+#include "../../../arch/x86/lib/crt0_ia32_efi.S"
+#endif
+
+#if HOST_ARCH == HOST_ARCH_AARCH64
+#include "../../../arch/arm/lib/crt0_aarch64_efi.S"
+#endif
+
+#if HOST_ARCH == HOST_ARCH_ARM
+#include "../../../arch/arm/lib/crt0_arm_efi.S"
+#endif
+
+#if HOST_ARCH == HOST_ARCH_RISCV32
+#include "../../../arch/riscv/lib/crt0_riscv_efi.S"
+#endif
+
+#if HOST_ARCH == HOST_ARCH_RISCV64
+#include "../../../arch/riscv/lib/crt0_riscv_efi.S"
+#endif
diff --git a/arch/sandbox/lib/reloc_sandbox_efi.c b/arch/sandbox/lib/reloc_sandbox_efi.c
new file mode 100644
index 0000000..a21e675
--- /dev/null
+++ b/arch/sandbox/lib/reloc_sandbox_efi.c
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * position independent shared object relocator
+ *
+ * Copyright (c) 2019 Heinrich Schuchardt
+ */
+
+#include <host_arch.h>
+
+#if HOST_ARCH == HOST_ARCH_X86_64
+#include "../../../arch/x86/lib/reloc_x86_64_efi.c"
+#endif
+
+#if HOST_ARCH == HOST_ARCH_X86
+#include "../../../arch/x86/lib/reloc_ia32_efi.c"
+#endif
+
+#if HOST_ARCH == HOST_ARCH_AARCH64
+#include "../../../arch/arm/lib/reloc_aarch64_efi.c"
+#endif
+
+#if HOST_ARCH == HOST_ARCH_ARM
+#include "../../../arch/arm/lib/reloc_arm_efi.c"
+#endif
+
+#if HOST_ARCH == HOST_ARCH_RISCV32
+#include "../../../arch/riscv/lib/reloc_riscv_efi.c"
+#endif
+
+#if HOST_ARCH == HOST_ARCH_RISCV64
+#include "../../../arch/riscv/lib/reloc_riscv_efi.c"
+#endif
diff --git a/board/firefly/firefly-rk3308/Kconfig b/board/firefly/firefly-rk3308/Kconfig
new file mode 100644
index 0000000..80b1ad8
--- /dev/null
+++ b/board/firefly/firefly-rk3308/Kconfig
@@ -0,0 +1,15 @@
+if TARGET_ROC_RK3308_CC
+
+config SYS_BOARD
+	default "firefly-rk3308"
+
+config SYS_VENDOR
+	default "firefly"
+
+config SYS_CONFIG_NAME
+	default "firefly_rk3308"
+
+config BOARD_SPECIFIC_OPTIONS # dummy
+	def_bool y
+
+endif
diff --git a/board/firefly/firefly-rk3308/MAINTAINERS b/board/firefly/firefly-rk3308/MAINTAINERS
new file mode 100644
index 0000000..1990797
--- /dev/null
+++ b/board/firefly/firefly-rk3308/MAINTAINERS
@@ -0,0 +1,5 @@
+ROC-RK3308-CC
+M:      Andy Yan <andy.yan@rock-chips.com>
+S:      Maintained
+F:      board/firefly/firefly-rk3308/roc_cc_rk3308.c
+F:      configs/roc-cc-rk3308_defconfig
diff --git a/board/firefly/firefly-rk3308/Makefile b/board/firefly/firefly-rk3308/Makefile
new file mode 100644
index 0000000..4c50b26
--- /dev/null
+++ b/board/firefly/firefly-rk3308/Makefile
@@ -0,0 +1,7 @@
+#
+# (C) Copyright 2018 Rockchip Electronics Co., Ltd
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-y	+= roc_cc_rk3308.o
diff --git a/board/firefly/firefly-rk3308/roc_cc_rk3308.c b/board/firefly/firefly-rk3308/roc_cc_rk3308.c
new file mode 100644
index 0000000..5f0a659
--- /dev/null
+++ b/board/firefly/firefly-rk3308/roc_cc_rk3308.c
@@ -0,0 +1,81 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2019 Rockchip Electronics Co., Ltd
+ */
+
+#include <common.h>
+#include <adc.h>
+#include <asm/io.h>
+#include <asm/arch/grf_rk3308.h>
+#include <asm/arch-rockchip/hardware.h>
+
+#if defined(CONFIG_DEBUG_UART)
+#define GRF_BASE	0xff000000
+
+enum {
+	GPIO1C7_SHIFT		= 8,
+	GPIO1C7_MASK		= GENMASK(11, 8),
+	GPIO1C7_GPIO		= 0,
+	GPIO1C7_UART1_RTSN,
+	GPIO1C7_UART2_TX_M0,
+	GPIO1C7_SPI2_MOSI,
+	GPIO1C7_JTAG_TMS,
+
+	GPIO1C6_SHIFT		= 4,
+	GPIO1C6_MASK		= GENMASK(7, 4),
+	GPIO1C6_GPIO		= 0,
+	GPIO1C6_UART1_CTSN,
+	GPIO1C6_UART2_RX_M0,
+	GPIO1C6_SPI2_MISO,
+	GPIO1C6_JTAG_TCLK,
+
+	GPIO4D3_SHIFT           = 6,
+	GPIO4D3_MASK            = GENMASK(7, 6),
+	GPIO4D3_GPIO            = 0,
+	GPIO4D3_SDMMC_D3,
+	GPIO4D3_UART2_TX_M1,
+
+	GPIO4D2_SHIFT           = 4,
+	GPIO4D2_MASK            = GENMASK(5, 4),
+	GPIO4D2_GPIO            = 0,
+	GPIO4D2_SDMMC_D2,
+	GPIO4D2_UART2_RX_M1,
+
+	UART2_IO_SEL_SHIFT	= 2,
+	UART2_IO_SEL_MASK	= GENMASK(3, 2),
+	UART2_IO_SEL_M0		= 0,
+	UART2_IO_SEL_M1,
+	UART2_IO_SEL_USB,
+};
+
+void board_debug_uart_init(void)
+{
+	static struct rk3308_grf * const grf = (void *)GRF_BASE;
+
+	/* Enable early UART2 channel m0 on the rk3308 */
+	rk_clrsetreg(&grf->soc_con5, UART2_IO_SEL_MASK,
+		     UART2_IO_SEL_M0 << UART2_IO_SEL_SHIFT);
+	rk_clrsetreg(&grf->gpio1ch_iomux,
+		     GPIO1C6_MASK | GPIO1C7_MASK,
+		     GPIO1C6_UART2_RX_M0 << GPIO1C6_SHIFT |
+		     GPIO1C7_UART2_TX_M0 << GPIO1C7_SHIFT);
+}
+#endif
+
+#define KEY_DOWN_MIN_VAL        0
+#define KEY_DOWN_MAX_VAL        30
+
+int rockchip_dnl_key_pressed(void)
+{
+	unsigned int val;
+
+	if (adc_channel_single_shot("saradc", 1, &val)) {
+		printf("%s read adc key val failed\n", __func__);
+		return false;
+	}
+
+	if (val >= KEY_DOWN_MIN_VAL && val <= KEY_DOWN_MAX_VAL)
+		return true;
+	else
+		return false;
+}
diff --git a/board/freescale/imx8mm_evk/imx8mm_evk.c b/board/freescale/imx8mm_evk/imx8mm_evk.c
index e474233..a0af550 100644
--- a/board/freescale/imx8mm_evk/imx8mm_evk.c
+++ b/board/freescale/imx8mm_evk/imx8mm_evk.c
@@ -4,6 +4,11 @@
  */
 
 #include <common.h>
+#include <miiphy.h>
+#include <netdev.h>
+
+#include <asm/arch/clock.h>
+#include <asm/io.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -14,8 +19,40 @@
 	return 0;
 }
 
+#if IS_ENABLED(CONFIG_FEC_MXC)
+static int setup_fec(void)
+{
+	struct iomuxc_gpr_base_regs *gpr =
+		(struct iomuxc_gpr_base_regs *)IOMUXC_GPR_BASE_ADDR;
+
+	/* Use 125M anatop REF_CLK1 for ENET1, not from external */
+	clrsetbits_le32(&gpr->gpr[1], 0x2000, 0);
+
+	return 0;
+}
+
+int board_phy_config(struct phy_device *phydev)
+{
+	/* enable rgmii rxc skew and phy mode select to RGMII copper */
+	phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x1f);
+	phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x8);
+
+	phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x00);
+	phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x82ee);
+	phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x05);
+	phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x100);
+
+	if (phydev->drv->config)
+		phydev->drv->config(phydev);
+	return 0;
+}
+#endif
+
 int board_init(void)
 {
+	if (IS_ENABLED(CONFIG_FEC_MXC))
+		setup_fec();
+
 	return 0;
 }
 
diff --git a/board/freescale/imx8mn_evk/Kconfig b/board/freescale/imx8mn_evk/Kconfig
new file mode 100644
index 0000000..38ac846
--- /dev/null
+++ b/board/freescale/imx8mn_evk/Kconfig
@@ -0,0 +1,14 @@
+if TARGET_IMX8MN_EVK
+
+config SYS_BOARD
+	default "imx8mn_evk"
+
+config SYS_VENDOR
+	default "freescale"
+
+config SYS_CONFIG_NAME
+	default "imx8mn_evk"
+
+source "board/freescale/common/Kconfig"
+
+endif
diff --git a/board/freescale/imx8mn_evk/MAINTAINERS b/board/freescale/imx8mn_evk/MAINTAINERS
new file mode 100644
index 0000000..3b0653d
--- /dev/null
+++ b/board/freescale/imx8mn_evk/MAINTAINERS
@@ -0,0 +1,6 @@
+i.MX8MM EVK BOARD
+M:	Peng Fan <peng.fan@nxp.com>
+S:	Maintained
+F:	board/freescale/imx8mn_evk/
+F:	include/configs/imx8mn_evk.h
+F:	configs/imx8mn_ddr4_evk_defconfig
diff --git a/board/freescale/imx8mn_evk/Makefile b/board/freescale/imx8mn_evk/Makefile
new file mode 100644
index 0000000..9511a70
--- /dev/null
+++ b/board/freescale/imx8mn_evk/Makefile
@@ -0,0 +1,12 @@
+#
+# Copyright 2018 NXP
+#
+# SPDX-License-Identifier:      GPL-2.0+
+#
+
+obj-y += imx8mn_evk.o
+
+ifdef CONFIG_SPL_BUILD
+obj-y += spl.o
+obj-$(CONFIG_IMX8M_DDR4) += ddr4_timing.o
+endif
diff --git a/board/freescale/imx8mn_evk/ddr4_timing.c b/board/freescale/imx8mn_evk/ddr4_timing.c
new file mode 100644
index 0000000..cfd193a
--- /dev/null
+++ b/board/freescale/imx8mn_evk/ddr4_timing.c
@@ -0,0 +1,1214 @@
+/*
+ * Copyright 2019 NXP
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ *
+ * Generated code from MX8M_DDR_tool
+ * Align with uboot-imx_v2018.03_4.14.78_1.0.0_ga
+ */
+
+#include <linux/kernel.h>
+#include <asm/arch/ddr.h>
+
+struct dram_cfg_param ddr_ddrc_cfg[] = {
+	{0x3d400000, 0x81040010},
+	{0x3d400030, 0x00000020},
+	{0x3d400034, 0x00221306},
+	{0x3d400050, 0x00210070},
+	{0x3d400054, 0x00010008},
+	{0x3d400060, 0x00000000},
+	{0x3d400064, 0x0092014a},
+	{0x3d4000c0, 0x00000000},
+	{0x3d4000c4, 0x00001000},
+	{0x3d4000d0, 0xc0030126},
+	{0x3d4000d4, 0x00770000},
+	{0x3d4000dc, 0x08340105},
+	{0x3d4000e0, 0x00180200},
+	{0x3d4000e4, 0x00110000},
+	{0x3d4000e8, 0x02000740},
+	{0x3d4000ec, 0x00000850},
+	{0x3d4000f4, 0x00000ec7},
+	{0x3d400100, 0x11122914},
+	{0x3d400104, 0x0004051c},
+	{0x3d400108, 0x0608050d},
+	{0x3d40010c, 0x0000400c},
+	{0x3d400110, 0x08030409},
+	{0x3d400114, 0x06060403},
+	{0x3d40011c, 0x00000606},
+	{0x3d400120, 0x07070d0c},
+	{0x3d400124, 0x0002040a},
+	{0x3d40012c, 0x1809010e},
+	{0x3d400130, 0x00000008},
+	{0x3d40013c, 0x00000000},
+	{0x3d400180, 0x01000040},
+	{0x3d400184, 0x0000493e},
+	{0x3d400190, 0x038b8207},
+	{0x3d400194, 0x02020303},
+	{0x3d400198, 0x07f04011},
+	{0x3d40019c, 0x000000b0},
+	{0x3d4001a0, 0xe0400018},
+	{0x3d4001a4, 0x0048005a},
+	{0x3d4001a8, 0x80000000},
+	{0x3d4001b0, 0x00000001},
+	{0x3d4001b4, 0x00000b07},
+	{0x3d4001b8, 0x00000004},
+	{0x3d4001c0, 0x00000001},
+	{0x3d4001c4, 0x00000000},
+	{0x3d400240, 0x06000610},
+	{0x3d400244, 0x00001323},
+	{0x3d400200, 0x00003f1f},
+	{0x3d400204, 0x003f0909},
+	{0x3d400208, 0x01010100},
+	{0x3d40020c, 0x01010101},
+	{0x3d400210, 0x00001f1f},
+	{0x3d400214, 0x07070707},
+	{0x3d400218, 0x07070707},
+	{0x3d40021c, 0x00000f07},
+	{0x3d400220, 0x00003f01},
+	{0x3d402050, 0x00210070},
+	{0x3d402064, 0x00180037},
+	{0x3d4020dc, 0x00000105},
+	{0x3d4020e0, 0x00000000},
+	{0x3d4020e8, 0x02000740},
+	{0x3d4020ec, 0x00000050},
+	{0x3d402100, 0x08030604},
+	{0x3d402104, 0x00020205},
+	{0x3d402108, 0x05050309},
+	{0x3d40210c, 0x0000400c},
+	{0x3d402110, 0x02030202},
+	{0x3d402114, 0x03030202},
+	{0x3d402118, 0x0a070008},
+	{0x3d40211c, 0x00000d09},
+	{0x3d402120, 0x08084b09},
+	{0x3d402124, 0x00020308},
+	{0x3d402128, 0x000f0d06},
+	{0x3d40212c, 0x12060111},
+	{0x3d402130, 0x00000008},
+	{0x3d40213c, 0x00000000},
+	{0x3d402180, 0x01000040},
+	{0x3d402190, 0x03848204},
+	{0x3d402194, 0x02020303},
+	{0x3d4021b4, 0x00000404},
+	{0x3d4021b8, 0x00000004},
+	{0x3d402240, 0x07000600},
+	{0x3d403050, 0x00210070},
+	{0x3d403064, 0x0006000d},
+	{0x3d4030dc, 0x00000105},
+	{0x3d4030e0, 0x00000000},
+	{0x3d4030e8, 0x02000740},
+	{0x3d4030ec, 0x00000050},
+	{0x3d403100, 0x07010101},
+	{0x3d403104, 0x00020202},
+	{0x3d403108, 0x05050309},
+	{0x3d40310c, 0x0000400c},
+	{0x3d403110, 0x01030201},
+	{0x3d403114, 0x03030202},
+	{0x3d40311c, 0x00000303},
+	{0x3d403120, 0x02020d02},
+	{0x3d403124, 0x00020208},
+	{0x3d403128, 0x000f0d06},
+	{0x3d40312c, 0x0e02010e},
+	{0x3d403130, 0x00000008},
+	{0x3d40313c, 0x00000000},
+	{0x3d403180, 0x01000040},
+	{0x3d403190, 0x03848204},
+	{0x3d403194, 0x02020303},
+	{0x3d4031b4, 0x00000404},
+	{0x3d4031b8, 0x00000004},
+	{0x3d403240, 0x07000600},
+
+	/* performance setting */
+	{ 0x3d400250, 0x00001f05 },
+	{ 0x3d400254, 0x1f },
+	{ 0x3d400264, 0x900003ff },
+	{ 0x3d40026c, 0x200003ff },
+	{ 0x3d400494, 0x01000e00 },
+	{ 0x3d400498, 0x03ff0000 },
+	{ 0x3d40049c, 0x01000e00 },
+	{ 0x3d4004a0, 0x03ff0000 },
+};
+
+/* PHY Initialize Configuration */
+struct dram_cfg_param ddr_ddrphy_cfg[] = {
+	{0x0001005f, 0x000002fd},
+	{0x0001015f, 0x000002fd},
+	{0x0001105f, 0x000002fd},
+	{0x0001115f, 0x000002fd},
+	{0x0011005f, 0x000002fd},
+	{0x0011015f, 0x000002fd},
+	{0x0011105f, 0x000002fd},
+	{0x0011115f, 0x000002fd},
+	{0x0021005f, 0x000002fd},
+	{0x0021015f, 0x000002fd},
+	{0x0021105f, 0x000002fd},
+	{0x0021115f, 0x000002fd},
+	{0x00000055, 0x00000355},
+	{0x00001055, 0x00000355},
+	{0x00002055, 0x00000355},
+	{0x00003055, 0x00000355},
+	{0x00004055, 0x00000055},
+	{0x00005055, 0x00000055},
+	{0x00006055, 0x00000355},
+	{0x00007055, 0x00000355},
+	{0x00008055, 0x00000355},
+	{0x00009055, 0x00000355},
+	{0x000200c5, 0x0000000a},
+	{0x001200c5, 0x00000007},
+	{0x002200c5, 0x00000007},
+	{0x0002002e, 0x00000002},
+	{0x0012002e, 0x00000002},
+	{0x0022002e, 0x00000002},
+	{0x00020024, 0x00000008},
+	{0x0002003a, 0x00000002},
+	{0x0002007d, 0x00000212},
+	{0x0002007c, 0x00000061},
+	{0x00120024, 0x00000008},
+	{0x0002003a, 0x00000002},
+	{0x0012007d, 0x00000212},
+	{0x0012007c, 0x00000061},
+	{0x00220024, 0x00000008},
+	{0x0002003a, 0x00000002},
+	{0x0022007d, 0x00000212},
+	{0x0022007c, 0x00000061},
+	{0x00020056, 0x00000006},
+	{0x00120056, 0x0000000a},
+	{0x00220056, 0x0000000a},
+	{0x0001004d, 0x0000001a},
+	{0x0001014d, 0x0000001a},
+	{0x0001104d, 0x0000001a},
+	{0x0001114d, 0x0000001a},
+	{0x0011004d, 0x0000001a},
+	{0x0011014d, 0x0000001a},
+	{0x0011104d, 0x0000001a},
+	{0x0011114d, 0x0000001a},
+	{0x0021004d, 0x0000001a},
+	{0x0021014d, 0x0000001a},
+	{0x0021104d, 0x0000001a},
+	{0x0021114d, 0x0000001a},
+	{0x00010049, 0x00000e38},
+	{0x00010149, 0x00000e38},
+	{0x00011049, 0x00000e38},
+	{0x00011149, 0x00000e38},
+	{0x00110049, 0x00000e38},
+	{0x00110149, 0x00000e38},
+	{0x00111049, 0x00000e38},
+	{0x00111149, 0x00000e38},
+	{0x00210049, 0x00000e38},
+	{0x00210149, 0x00000e38},
+	{0x00211049, 0x00000e38},
+	{0x00211149, 0x00000e38},
+	{0x00000043, 0x00000063},
+	{0x00001043, 0x00000063},
+	{0x00002043, 0x00000063},
+	{0x00003043, 0x00000063},
+	{0x00004043, 0x00000063},
+	{0x00005043, 0x00000063},
+	{0x00006043, 0x00000063},
+	{0x00007043, 0x00000063},
+	{0x00008043, 0x00000063},
+	{0x00009043, 0x00000063},
+	{0x00020018, 0x00000001},
+	{0x00020075, 0x00000002},
+	{0x00020050, 0x00000000},
+	{0x00020008, 0x00000258},
+	{0x00120008, 0x00000064},
+	{0x00220008, 0x00000019},
+	{0x00020088, 0x00000009},
+	{0x000200b2, 0x00000268},
+	{0x00010043, 0x000005b1},
+	{0x00010143, 0x000005b1},
+	{0x00011043, 0x000005b1},
+	{0x00011143, 0x000005b1},
+	{0x001200b2, 0x00000268},
+	{0x00110043, 0x000005b1},
+	{0x00110143, 0x000005b1},
+	{0x00111043, 0x000005b1},
+	{0x00111143, 0x000005b1},
+	{0x002200b2, 0x00000268},
+	{0x00210043, 0x000005b1},
+	{0x00210143, 0x000005b1},
+	{0x00211043, 0x000005b1},
+	{0x00211143, 0x000005b1},
+	{0x0002005b, 0x00007529},
+	{0x0002005c, 0x00000000},
+	{0x000200fa, 0x00000001},
+	{0x001200fa, 0x00000001},
+	{0x002200fa, 0x00000001},
+	{0x00020019, 0x00000005},
+	{0x00120019, 0x00000005},
+	{0x00220019, 0x00000005},
+	{0x000200f0, 0x00005665},
+	{0x000200f1, 0x00005555},
+	{0x000200f2, 0x00005555},
+	{0x000200f3, 0x00005555},
+	{0x000200f4, 0x00005555},
+	{0x000200f5, 0x00005555},
+	{0x000200f6, 0x00005555},
+	{0x000200f7, 0x0000f000},
+	{0x0001004a, 0x00000500},
+	{0x0001104a, 0x00000500},
+	{0x00020025, 0x00000000},
+	{0x0002002d, 0x00000000},
+	{0x0012002d, 0x00000000},
+	{0x0022002d, 0x00000000},
+	{0x0002002c, 0x00000000},
+	{0x000200c7, 0x00000021},
+	{0x000200ca, 0x00000024},
+	{0x000200cc, 0x000001f7},
+	{0x001200c7, 0x00000021},
+	{0x001200ca, 0x00000024},
+	{0x001200cc, 0x000001f7},
+	{0x002200c7, 0x00000021},
+	{0x002200ca, 0x00000024},
+	{0x002200cc, 0x000001f7},
+};
+
+/* ddr phy trained csr */
+struct dram_cfg_param ddr_ddrphy_trained_csr[] = {
+	{0x0200b2, 0x0},
+	{0x1200b2, 0x0},
+	{0x2200b2, 0x0},
+	{0x0200cb, 0x0},
+	{0x010043, 0x0},
+	{0x110043, 0x0},
+	{0x210043, 0x0},
+	{0x010143, 0x0},
+	{0x110143, 0x0},
+	{0x210143, 0x0},
+	{0x011043, 0x0},
+	{0x111043, 0x0},
+	{0x211043, 0x0},
+	{0x011143, 0x0},
+	{0x111143, 0x0},
+	{0x211143, 0x0},
+	{0x000080, 0x0},
+	{0x100080, 0x0},
+	{0x200080, 0x0},
+	{0x001080, 0x0},
+	{0x101080, 0x0},
+	{0x201080, 0x0},
+	{0x002080, 0x0},
+	{0x102080, 0x0},
+	{0x202080, 0x0},
+	{0x003080, 0x0},
+	{0x103080, 0x0},
+	{0x203080, 0x0},
+	{0x004080, 0x0},
+	{0x104080, 0x0},
+	{0x204080, 0x0},
+	{0x005080, 0x0},
+	{0x105080, 0x0},
+	{0x205080, 0x0},
+	{0x006080, 0x0},
+	{0x106080, 0x0},
+	{0x206080, 0x0},
+	{0x007080, 0x0},
+	{0x107080, 0x0},
+	{0x207080, 0x0},
+	{0x008080, 0x0},
+	{0x108080, 0x0},
+	{0x208080, 0x0},
+	{0x009080, 0x0},
+	{0x109080, 0x0},
+	{0x209080, 0x0},
+	{0x010080, 0x0},
+	{0x110080, 0x0},
+	{0x210080, 0x0},
+	{0x010180, 0x0},
+	{0x110180, 0x0},
+	{0x210180, 0x0},
+	{0x010081, 0x0},
+	{0x110081, 0x0},
+	{0x210081, 0x0},
+	{0x010181, 0x0},
+	{0x110181, 0x0},
+	{0x210181, 0x0},
+	{0x010082, 0x0},
+	{0x110082, 0x0},
+	{0x210082, 0x0},
+	{0x010182, 0x0},
+	{0x110182, 0x0},
+	{0x210182, 0x0},
+	{0x010083, 0x0},
+	{0x110083, 0x0},
+	{0x210083, 0x0},
+	{0x010183, 0x0},
+	{0x110183, 0x0},
+	{0x210183, 0x0},
+	{0x011080, 0x0},
+	{0x111080, 0x0},
+	{0x211080, 0x0},
+	{0x011180, 0x0},
+	{0x111180, 0x0},
+	{0x211180, 0x0},
+	{0x011081, 0x0},
+	{0x111081, 0x0},
+	{0x211081, 0x0},
+	{0x011181, 0x0},
+	{0x111181, 0x0},
+	{0x211181, 0x0},
+	{0x011082, 0x0},
+	{0x111082, 0x0},
+	{0x211082, 0x0},
+	{0x011182, 0x0},
+	{0x111182, 0x0},
+	{0x211182, 0x0},
+	{0x011083, 0x0},
+	{0x111083, 0x0},
+	{0x211083, 0x0},
+	{0x011183, 0x0},
+	{0x111183, 0x0},
+	{0x211183, 0x0},
+	{0x0100d0, 0x0},
+	{0x1100d0, 0x0},
+	{0x2100d0, 0x0},
+	{0x0101d0, 0x0},
+	{0x1101d0, 0x0},
+	{0x2101d0, 0x0},
+	{0x0100d1, 0x0},
+	{0x1100d1, 0x0},
+	{0x2100d1, 0x0},
+	{0x0101d1, 0x0},
+	{0x1101d1, 0x0},
+	{0x2101d1, 0x0},
+	{0x0100d2, 0x0},
+	{0x1100d2, 0x0},
+	{0x2100d2, 0x0},
+	{0x0101d2, 0x0},
+	{0x1101d2, 0x0},
+	{0x2101d2, 0x0},
+	{0x0100d3, 0x0},
+	{0x1100d3, 0x0},
+	{0x2100d3, 0x0},
+	{0x0101d3, 0x0},
+	{0x1101d3, 0x0},
+	{0x2101d3, 0x0},
+	{0x0110d0, 0x0},
+	{0x1110d0, 0x0},
+	{0x2110d0, 0x0},
+	{0x0111d0, 0x0},
+	{0x1111d0, 0x0},
+	{0x2111d0, 0x0},
+	{0x0110d1, 0x0},
+	{0x1110d1, 0x0},
+	{0x2110d1, 0x0},
+	{0x0111d1, 0x0},
+	{0x1111d1, 0x0},
+	{0x2111d1, 0x0},
+	{0x0110d2, 0x0},
+	{0x1110d2, 0x0},
+	{0x2110d2, 0x0},
+	{0x0111d2, 0x0},
+	{0x1111d2, 0x0},
+	{0x2111d2, 0x0},
+	{0x0110d3, 0x0},
+	{0x1110d3, 0x0},
+	{0x2110d3, 0x0},
+	{0x0111d3, 0x0},
+	{0x1111d3, 0x0},
+	{0x2111d3, 0x0},
+	{0x010068, 0x0},
+	{0x010168, 0x0},
+	{0x010268, 0x0},
+	{0x010368, 0x0},
+	{0x010468, 0x0},
+	{0x010568, 0x0},
+	{0x010668, 0x0},
+	{0x010768, 0x0},
+	{0x010868, 0x0},
+	{0x010069, 0x0},
+	{0x010169, 0x0},
+	{0x010269, 0x0},
+	{0x010369, 0x0},
+	{0x010469, 0x0},
+	{0x010569, 0x0},
+	{0x010669, 0x0},
+	{0x010769, 0x0},
+	{0x010869, 0x0},
+	{0x01006a, 0x0},
+	{0x01016a, 0x0},
+	{0x01026a, 0x0},
+	{0x01036a, 0x0},
+	{0x01046a, 0x0},
+	{0x01056a, 0x0},
+	{0x01066a, 0x0},
+	{0x01076a, 0x0},
+	{0x01086a, 0x0},
+	{0x01006b, 0x0},
+	{0x01016b, 0x0},
+	{0x01026b, 0x0},
+	{0x01036b, 0x0},
+	{0x01046b, 0x0},
+	{0x01056b, 0x0},
+	{0x01066b, 0x0},
+	{0x01076b, 0x0},
+	{0x01086b, 0x0},
+	{0x011068, 0x0},
+	{0x011168, 0x0},
+	{0x011268, 0x0},
+	{0x011368, 0x0},
+	{0x011468, 0x0},
+	{0x011568, 0x0},
+	{0x011668, 0x0},
+	{0x011768, 0x0},
+	{0x011868, 0x0},
+	{0x011069, 0x0},
+	{0x011169, 0x0},
+	{0x011269, 0x0},
+	{0x011369, 0x0},
+	{0x011469, 0x0},
+	{0x011569, 0x0},
+	{0x011669, 0x0},
+	{0x011769, 0x0},
+	{0x011869, 0x0},
+	{0x01106a, 0x0},
+	{0x01116a, 0x0},
+	{0x01126a, 0x0},
+	{0x01136a, 0x0},
+	{0x01146a, 0x0},
+	{0x01156a, 0x0},
+	{0x01166a, 0x0},
+	{0x01176a, 0x0},
+	{0x01186a, 0x0},
+	{0x01106b, 0x0},
+	{0x01116b, 0x0},
+	{0x01126b, 0x0},
+	{0x01136b, 0x0},
+	{0x01146b, 0x0},
+	{0x01156b, 0x0},
+	{0x01166b, 0x0},
+	{0x01176b, 0x0},
+	{0x01186b, 0x0},
+	{0x01008c, 0x0},
+	{0x11008c, 0x0},
+	{0x21008c, 0x0},
+	{0x01018c, 0x0},
+	{0x11018c, 0x0},
+	{0x21018c, 0x0},
+	{0x01008d, 0x0},
+	{0x11008d, 0x0},
+	{0x21008d, 0x0},
+	{0x01018d, 0x0},
+	{0x11018d, 0x0},
+	{0x21018d, 0x0},
+	{0x01008e, 0x0},
+	{0x11008e, 0x0},
+	{0x21008e, 0x0},
+	{0x01018e, 0x0},
+	{0x11018e, 0x0},
+	{0x21018e, 0x0},
+	{0x01008f, 0x0},
+	{0x11008f, 0x0},
+	{0x21008f, 0x0},
+	{0x01018f, 0x0},
+	{0x11018f, 0x0},
+	{0x21018f, 0x0},
+	{0x01108c, 0x0},
+	{0x11108c, 0x0},
+	{0x21108c, 0x0},
+	{0x01118c, 0x0},
+	{0x11118c, 0x0},
+	{0x21118c, 0x0},
+	{0x01108d, 0x0},
+	{0x11108d, 0x0},
+	{0x21108d, 0x0},
+	{0x01118d, 0x0},
+	{0x11118d, 0x0},
+	{0x21118d, 0x0},
+	{0x01108e, 0x0},
+	{0x11108e, 0x0},
+	{0x21108e, 0x0},
+	{0x01118e, 0x0},
+	{0x11118e, 0x0},
+	{0x21118e, 0x0},
+	{0x01108f, 0x0},
+	{0x11108f, 0x0},
+	{0x21108f, 0x0},
+	{0x01118f, 0x0},
+	{0x11118f, 0x0},
+	{0x21118f, 0x0},
+	{0x0100c0, 0x0},
+	{0x1100c0, 0x0},
+	{0x2100c0, 0x0},
+	{0x0101c0, 0x0},
+	{0x1101c0, 0x0},
+	{0x2101c0, 0x0},
+	{0x0102c0, 0x0},
+	{0x1102c0, 0x0},
+	{0x2102c0, 0x0},
+	{0x0103c0, 0x0},
+	{0x1103c0, 0x0},
+	{0x2103c0, 0x0},
+	{0x0104c0, 0x0},
+	{0x1104c0, 0x0},
+	{0x2104c0, 0x0},
+	{0x0105c0, 0x0},
+	{0x1105c0, 0x0},
+	{0x2105c0, 0x0},
+	{0x0106c0, 0x0},
+	{0x1106c0, 0x0},
+	{0x2106c0, 0x0},
+	{0x0107c0, 0x0},
+	{0x1107c0, 0x0},
+	{0x2107c0, 0x0},
+	{0x0108c0, 0x0},
+	{0x1108c0, 0x0},
+	{0x2108c0, 0x0},
+	{0x0100c1, 0x0},
+	{0x1100c1, 0x0},
+	{0x2100c1, 0x0},
+	{0x0101c1, 0x0},
+	{0x1101c1, 0x0},
+	{0x2101c1, 0x0},
+	{0x0102c1, 0x0},
+	{0x1102c1, 0x0},
+	{0x2102c1, 0x0},
+	{0x0103c1, 0x0},
+	{0x1103c1, 0x0},
+	{0x2103c1, 0x0},
+	{0x0104c1, 0x0},
+	{0x1104c1, 0x0},
+	{0x2104c1, 0x0},
+	{0x0105c1, 0x0},
+	{0x1105c1, 0x0},
+	{0x2105c1, 0x0},
+	{0x0106c1, 0x0},
+	{0x1106c1, 0x0},
+	{0x2106c1, 0x0},
+	{0x0107c1, 0x0},
+	{0x1107c1, 0x0},
+	{0x2107c1, 0x0},
+	{0x0108c1, 0x0},
+	{0x1108c1, 0x0},
+	{0x2108c1, 0x0},
+	{0x0100c2, 0x0},
+	{0x1100c2, 0x0},
+	{0x2100c2, 0x0},
+	{0x0101c2, 0x0},
+	{0x1101c2, 0x0},
+	{0x2101c2, 0x0},
+	{0x0102c2, 0x0},
+	{0x1102c2, 0x0},
+	{0x2102c2, 0x0},
+	{0x0103c2, 0x0},
+	{0x1103c2, 0x0},
+	{0x2103c2, 0x0},
+	{0x0104c2, 0x0},
+	{0x1104c2, 0x0},
+	{0x2104c2, 0x0},
+	{0x0105c2, 0x0},
+	{0x1105c2, 0x0},
+	{0x2105c2, 0x0},
+	{0x0106c2, 0x0},
+	{0x1106c2, 0x0},
+	{0x2106c2, 0x0},
+	{0x0107c2, 0x0},
+	{0x1107c2, 0x0},
+	{0x2107c2, 0x0},
+	{0x0108c2, 0x0},
+	{0x1108c2, 0x0},
+	{0x2108c2, 0x0},
+	{0x0100c3, 0x0},
+	{0x1100c3, 0x0},
+	{0x2100c3, 0x0},
+	{0x0101c3, 0x0},
+	{0x1101c3, 0x0},
+	{0x2101c3, 0x0},
+	{0x0102c3, 0x0},
+	{0x1102c3, 0x0},
+	{0x2102c3, 0x0},
+	{0x0103c3, 0x0},
+	{0x1103c3, 0x0},
+	{0x2103c3, 0x0},
+	{0x0104c3, 0x0},
+	{0x1104c3, 0x0},
+	{0x2104c3, 0x0},
+	{0x0105c3, 0x0},
+	{0x1105c3, 0x0},
+	{0x2105c3, 0x0},
+	{0x0106c3, 0x0},
+	{0x1106c3, 0x0},
+	{0x2106c3, 0x0},
+	{0x0107c3, 0x0},
+	{0x1107c3, 0x0},
+	{0x2107c3, 0x0},
+	{0x0108c3, 0x0},
+	{0x1108c3, 0x0},
+	{0x2108c3, 0x0},
+	{0x0110c0, 0x0},
+	{0x1110c0, 0x0},
+	{0x2110c0, 0x0},
+	{0x0111c0, 0x0},
+	{0x1111c0, 0x0},
+	{0x2111c0, 0x0},
+	{0x0112c0, 0x0},
+	{0x1112c0, 0x0},
+	{0x2112c0, 0x0},
+	{0x0113c0, 0x0},
+	{0x1113c0, 0x0},
+	{0x2113c0, 0x0},
+	{0x0114c0, 0x0},
+	{0x1114c0, 0x0},
+	{0x2114c0, 0x0},
+	{0x0115c0, 0x0},
+	{0x1115c0, 0x0},
+	{0x2115c0, 0x0},
+	{0x0116c0, 0x0},
+	{0x1116c0, 0x0},
+	{0x2116c0, 0x0},
+	{0x0117c0, 0x0},
+	{0x1117c0, 0x0},
+	{0x2117c0, 0x0},
+	{0x0118c0, 0x0},
+	{0x1118c0, 0x0},
+	{0x2118c0, 0x0},
+	{0x0110c1, 0x0},
+	{0x1110c1, 0x0},
+	{0x2110c1, 0x0},
+	{0x0111c1, 0x0},
+	{0x1111c1, 0x0},
+	{0x2111c1, 0x0},
+	{0x0112c1, 0x0},
+	{0x1112c1, 0x0},
+	{0x2112c1, 0x0},
+	{0x0113c1, 0x0},
+	{0x1113c1, 0x0},
+	{0x2113c1, 0x0},
+	{0x0114c1, 0x0},
+	{0x1114c1, 0x0},
+	{0x2114c1, 0x0},
+	{0x0115c1, 0x0},
+	{0x1115c1, 0x0},
+	{0x2115c1, 0x0},
+	{0x0116c1, 0x0},
+	{0x1116c1, 0x0},
+	{0x2116c1, 0x0},
+	{0x0117c1, 0x0},
+	{0x1117c1, 0x0},
+	{0x2117c1, 0x0},
+	{0x0118c1, 0x0},
+	{0x1118c1, 0x0},
+	{0x2118c1, 0x0},
+	{0x0110c2, 0x0},
+	{0x1110c2, 0x0},
+	{0x2110c2, 0x0},
+	{0x0111c2, 0x0},
+	{0x1111c2, 0x0},
+	{0x2111c2, 0x0},
+	{0x0112c2, 0x0},
+	{0x1112c2, 0x0},
+	{0x2112c2, 0x0},
+	{0x0113c2, 0x0},
+	{0x1113c2, 0x0},
+	{0x2113c2, 0x0},
+	{0x0114c2, 0x0},
+	{0x1114c2, 0x0},
+	{0x2114c2, 0x0},
+	{0x0115c2, 0x0},
+	{0x1115c2, 0x0},
+	{0x2115c2, 0x0},
+	{0x0116c2, 0x0},
+	{0x1116c2, 0x0},
+	{0x2116c2, 0x0},
+	{0x0117c2, 0x0},
+	{0x1117c2, 0x0},
+	{0x2117c2, 0x0},
+	{0x0118c2, 0x0},
+	{0x1118c2, 0x0},
+	{0x2118c2, 0x0},
+	{0x0110c3, 0x0},
+	{0x1110c3, 0x0},
+	{0x2110c3, 0x0},
+	{0x0111c3, 0x0},
+	{0x1111c3, 0x0},
+	{0x2111c3, 0x0},
+	{0x0112c3, 0x0},
+	{0x1112c3, 0x0},
+	{0x2112c3, 0x0},
+	{0x0113c3, 0x0},
+	{0x1113c3, 0x0},
+	{0x2113c3, 0x0},
+	{0x0114c3, 0x0},
+	{0x1114c3, 0x0},
+	{0x2114c3, 0x0},
+	{0x0115c3, 0x0},
+	{0x1115c3, 0x0},
+	{0x2115c3, 0x0},
+	{0x0116c3, 0x0},
+	{0x1116c3, 0x0},
+	{0x2116c3, 0x0},
+	{0x0117c3, 0x0},
+	{0x1117c3, 0x0},
+	{0x2117c3, 0x0},
+	{0x0118c3, 0x0},
+	{0x1118c3, 0x0},
+	{0x2118c3, 0x0},
+	{0x010020, 0x0},
+	{0x110020, 0x0},
+	{0x210020, 0x0},
+	{0x011020, 0x0},
+	{0x111020, 0x0},
+	{0x211020, 0x0},
+	{0x02007d, 0x0},
+	{0x12007d, 0x0},
+	{0x22007d, 0x0},
+	{0x010040, 0x0},
+	{0x010140, 0x0},
+	{0x010240, 0x0},
+	{0x010340, 0x0},
+	{0x010440, 0x0},
+	{0x010540, 0x0},
+	{0x010640, 0x0},
+	{0x010740, 0x0},
+	{0x010840, 0x0},
+	{0x010030, 0x0},
+	{0x010130, 0x0},
+	{0x010230, 0x0},
+	{0x010330, 0x0},
+	{0x010430, 0x0},
+	{0x010530, 0x0},
+	{0x010630, 0x0},
+	{0x010730, 0x0},
+	{0x010830, 0x0},
+	{0x011040, 0x0},
+	{0x011140, 0x0},
+	{0x011240, 0x0},
+	{0x011340, 0x0},
+	{0x011440, 0x0},
+	{0x011540, 0x0},
+	{0x011640, 0x0},
+	{0x011740, 0x0},
+	{0x011840, 0x0},
+	{0x011030, 0x0},
+	{0x011130, 0x0},
+	{0x011230, 0x0},
+	{0x011330, 0x0},
+	{0x011430, 0x0},
+	{0x011530, 0x0},
+	{0x011630, 0x0},
+	{0x011730, 0x0},
+	{0x011830, 0x0},
+};
+
+/* P0 message block paremeter for training firmware */
+struct dram_cfg_param ddr_fsp0_cfg[] = {
+	{0x000d0000, 0x00000000},
+	{0x00020060, 0x00000002},
+	{0x00054000, 0x00000000},
+	{0x00054001, 0x00000000},
+	{0x00054002, 0x00000000},
+	{0x00054003, 0x00000960},
+	{0x00054004, 0x00000002},
+	{0x00054005, 0x00000000},
+	{0x00054006, 0x0000025e},
+	{0x00054007, 0x00001000},
+	{0x00054008, 0x00000101},
+	{0x00054009, 0x00000000},
+	{0x0005400a, 0x00000000},
+	{0x0005400b, 0x0000031f},
+	{0x0005400c, 0x000000c8},
+	{0x0005400d, 0x00000100},
+	{0x0005400e, 0x00000000},
+	{0x0005400f, 0x00000000},
+	{0x00054010, 0x00000000},
+	{0x00054011, 0x00000000},
+	{0x00054012, 0x00000001},
+	{0x0005402f, 0x00000834},
+	{0x00054030, 0x00000105},
+	{0x00054031, 0x00000018},
+	{0x00054032, 0x00000200},
+	{0x00054033, 0x00000200},
+	{0x00054034, 0x00000740},
+	{0x00054035, 0x00000850},
+	{0x00054036, 0x00000103},
+	{0x00054037, 0x00000000},
+	{0x00054038, 0x00000000},
+	{0x00054039, 0x00000000},
+	{0x0005403a, 0x00000000},
+	{0x0005403b, 0x00000000},
+	{0x0005403c, 0x00000000},
+	{0x0005403d, 0x00000000},
+	{0x0005403e, 0x00000000},
+	{0x0005403f, 0x00001221},
+	{0x000541fc, 0x00000100},
+	{0x000d0000, 0x00000001},
+};
+
+/* P1 message block paremeter for training firmware */
+struct dram_cfg_param ddr_fsp1_cfg[] = {
+	{0x000d0000, 0x00000000},
+	{0x00054000, 0x00000000},
+	{0x00054001, 0x00000000},
+	{0x00054002, 0x00000101},
+	{0x00054003, 0x00000190},
+	{0x00054004, 0x00000002},
+	{0x00054005, 0x00000000},
+	{0x00054006, 0x0000025e},
+	{0x00054007, 0x00001000},
+	{0x00054008, 0x00000101},
+	{0x00054009, 0x00000000},
+	{0x0005400a, 0x00000000},
+	{0x0005400b, 0x0000021f},
+	{0x0005400c, 0x000000c8},
+	{0x0005400d, 0x00000100},
+	{0x0005400e, 0x00000000},
+	{0x0005400f, 0x00000000},
+	{0x00054010, 0x00000000},
+	{0x00054011, 0x00000000},
+	{0x00054012, 0x00000001},
+	{0x0005402f, 0x00000000},
+	{0x00054030, 0x00000105},
+	{0x00054031, 0x00000000},
+	{0x00054032, 0x00000000},
+	{0x00054033, 0x00000200},
+	{0x00054034, 0x00000740},
+	{0x00054035, 0x00000050},
+	{0x00054036, 0x00000103},
+	{0x00054037, 0x00000000},
+	{0x00054038, 0x00000000},
+	{0x00054039, 0x00000000},
+	{0x0005403a, 0x00000000},
+	{0x0005403b, 0x00000000},
+	{0x0005403c, 0x00000000},
+	{0x0005403d, 0x00000000},
+	{0x0005403e, 0x00000000},
+	{0x0005403f, 0x00001221},
+	{0x000541fc, 0x00000100},
+	{0x000d0000, 0x00000001},
+};
+
+/* P2 message block paremeter for training firmware */
+struct dram_cfg_param ddr_fsp2_cfg[] = {
+	{0x000d0000, 0x00000000},
+	{0x00054000, 0x00000000},
+	{0x00054001, 0x00000000},
+	{0x00054002, 0x00000102},
+	{0x00054003, 0x00000064},
+	{0x00054004, 0x00000002},
+	{0x00054005, 0x00000000},
+	{0x00054006, 0x0000025e},
+	{0x00054007, 0x00001000},
+	{0x00054008, 0x00000101},
+	{0x00054009, 0x00000000},
+	{0x0005400a, 0x00000000},
+	{0x0005400b, 0x0000021f},
+	{0x0005400c, 0x000000c8},
+	{0x0005400d, 0x00000100},
+	{0x0005400e, 0x00000000},
+	{0x0005400f, 0x00000000},
+	{0x00054010, 0x00000000},
+	{0x00054011, 0x00000000},
+	{0x00054012, 0x00000001},
+	{0x0005402f, 0x00000000},
+	{0x00054030, 0x00000105},
+	{0x00054031, 0x00000000},
+	{0x00054032, 0x00000000},
+	{0x00054033, 0x00000200},
+	{0x00054034, 0x00000740},
+	{0x00054035, 0x00000050},
+	{0x00054036, 0x00000103},
+	{0x00054037, 0x00000000},
+	{0x00054038, 0x00000000},
+	{0x00054039, 0x00000000},
+	{0x0005403a, 0x00000000},
+	{0x0005403b, 0x00000000},
+	{0x0005403c, 0x00000000},
+	{0x0005403d, 0x00000000},
+	{0x0005403e, 0x00000000},
+	{0x0005403f, 0x00001221},
+	{0x000541fc, 0x00000100},
+	{0x000d0000, 0x00000001},
+};
+
+/* P0 2D message block paremeter for training firmware */
+struct dram_cfg_param ddr_fsp0_2d_cfg[] = {
+	{0x000d0000, 0x00000000},
+	{0x00054000, 0x00000000},
+	{0x00054001, 0x00000000},
+	{0x00054002, 0x00000000},
+	{0x00054003, 0x00000960},
+	{0x00054004, 0x00000002},
+	{0x00054005, 0x00000000},
+	{0x00054006, 0x0000025e},
+	{0x00054007, 0x00001000},
+	{0x00054008, 0x00000101},
+	{0x00054009, 0x00000000},
+	{0x0005400a, 0x00000000},
+	{0x0005400b, 0x00000061},
+	{0x0005400c, 0x000000c8},
+	{0x0005400d, 0x00000100},
+	{0x0005400e, 0x00001f7f},
+	{0x0005400f, 0x00000000},
+	{0x00054010, 0x00000000},
+	{0x00054011, 0x00000000},
+	{0x00054012, 0x00000001},
+	{0x0005402f, 0x00000834},
+	{0x00054030, 0x00000105},
+	{0x00054031, 0x00000018},
+	{0x00054032, 0x00000200},
+	{0x00054033, 0x00000200},
+	{0x00054034, 0x00000740},
+	{0x00054035, 0x00000850},
+	{0x00054036, 0x00000103},
+	{0x00054037, 0x00000000},
+	{0x00054038, 0x00000000},
+	{0x00054039, 0x00000000},
+	{0x0005403a, 0x00000000},
+	{0x0005403b, 0x00000000},
+	{0x0005403c, 0x00000000},
+	{0x0005403d, 0x00000000},
+	{0x0005403e, 0x00000000},
+	{0x0005403f, 0x00001221},
+	{0x000541fc, 0x00000100},
+	{0x000d0000, 0x00000001},
+};
+
+/* DRAM PHY init engine image */
+struct dram_cfg_param ddr_phy_pie[] = {
+	{0xd0000, 0x0},
+	{0x90000, 0x10},
+	{0x90001, 0x400},
+	{0x90002, 0x10e},
+	{0x90003, 0x0},
+	{0x90004, 0x0},
+	{0x90005, 0x8},
+	{0x90029, 0xb},
+	{0x9002a, 0x480},
+	{0x9002b, 0x109},
+	{0x9002c, 0x8},
+	{0x9002d, 0x448},
+	{0x9002e, 0x139},
+	{0x9002f, 0x8},
+	{0x90030, 0x478},
+	{0x90031, 0x109},
+	{0x90032, 0x2},
+	{0x90033, 0x10},
+	{0x90034, 0x139},
+	{0x90035, 0xb},
+	{0x90036, 0x7c0},
+	{0x90037, 0x139},
+	{0x90038, 0x44},
+	{0x90039, 0x633},
+	{0x9003a, 0x159},
+	{0x9003b, 0x14f},
+	{0x9003c, 0x630},
+	{0x9003d, 0x159},
+	{0x9003e, 0x47},
+	{0x9003f, 0x633},
+	{0x90040, 0x149},
+	{0x90041, 0x4f},
+	{0x90042, 0x633},
+	{0x90043, 0x179},
+	{0x90044, 0x8},
+	{0x90045, 0xe0},
+	{0x90046, 0x109},
+	{0x90047, 0x0},
+	{0x90048, 0x7c8},
+	{0x90049, 0x109},
+	{0x9004a, 0x0},
+	{0x9004b, 0x1},
+	{0x9004c, 0x8},
+	{0x9004d, 0x0},
+	{0x9004e, 0x45a},
+	{0x9004f, 0x9},
+	{0x90050, 0x0},
+	{0x90051, 0x448},
+	{0x90052, 0x109},
+	{0x90053, 0x40},
+	{0x90054, 0x633},
+	{0x90055, 0x179},
+	{0x90056, 0x1},
+	{0x90057, 0x618},
+	{0x90058, 0x109},
+	{0x90059, 0x40c0},
+	{0x9005a, 0x633},
+	{0x9005b, 0x149},
+	{0x9005c, 0x8},
+	{0x9005d, 0x4},
+	{0x9005e, 0x48},
+	{0x9005f, 0x4040},
+	{0x90060, 0x633},
+	{0x90061, 0x149},
+	{0x90062, 0x0},
+	{0x90063, 0x4},
+	{0x90064, 0x48},
+	{0x90065, 0x40},
+	{0x90066, 0x633},
+	{0x90067, 0x149},
+	{0x90068, 0x10},
+	{0x90069, 0x4},
+	{0x9006a, 0x18},
+	{0x9006b, 0x0},
+	{0x9006c, 0x4},
+	{0x9006d, 0x78},
+	{0x9006e, 0x549},
+	{0x9006f, 0x633},
+	{0x90070, 0x159},
+	{0x90071, 0xd49},
+	{0x90072, 0x633},
+	{0x90073, 0x159},
+	{0x90074, 0x94a},
+	{0x90075, 0x633},
+	{0x90076, 0x159},
+	{0x90077, 0x441},
+	{0x90078, 0x633},
+	{0x90079, 0x149},
+	{0x9007a, 0x42},
+	{0x9007b, 0x633},
+	{0x9007c, 0x149},
+	{0x9007d, 0x1},
+	{0x9007e, 0x633},
+	{0x9007f, 0x149},
+	{0x90080, 0x0},
+	{0x90081, 0xe0},
+	{0x90082, 0x109},
+	{0x90083, 0xa},
+	{0x90084, 0x10},
+	{0x90085, 0x109},
+	{0x90086, 0x9},
+	{0x90087, 0x3c0},
+	{0x90088, 0x149},
+	{0x90089, 0x9},
+	{0x9008a, 0x3c0},
+	{0x9008b, 0x159},
+	{0x9008c, 0x18},
+	{0x9008d, 0x10},
+	{0x9008e, 0x109},
+	{0x9008f, 0x0},
+	{0x90090, 0x3c0},
+	{0x90091, 0x109},
+	{0x90092, 0x18},
+	{0x90093, 0x4},
+	{0x90094, 0x48},
+	{0x90095, 0x18},
+	{0x90096, 0x4},
+	{0x90097, 0x58},
+	{0x90098, 0xb},
+	{0x90099, 0x10},
+	{0x9009a, 0x109},
+	{0x9009b, 0x1},
+	{0x9009c, 0x10},
+	{0x9009d, 0x109},
+	{0x9009e, 0x5},
+	{0x9009f, 0x7c0},
+	{0x900a0, 0x109},
+	{0x900a1, 0x0},
+	{0x900a2, 0x8140},
+	{0x900a3, 0x10c},
+	{0x900a4, 0x10},
+	{0x900a5, 0x8138},
+	{0x900a6, 0x10c},
+	{0x900a7, 0x8},
+	{0x900a8, 0x7c8},
+	{0x900a9, 0x101},
+	{0x900aa, 0x8},
+	{0x900ab, 0x448},
+	{0x900ac, 0x109},
+	{0x900ad, 0xf},
+	{0x900ae, 0x7c0},
+	{0x900af, 0x109},
+	{0x900b0, 0x47},
+	{0x900b1, 0x630},
+	{0x900b2, 0x109},
+	{0x900b3, 0x8},
+	{0x900b4, 0x618},
+	{0x900b5, 0x109},
+	{0x900b6, 0x8},
+	{0x900b7, 0xe0},
+	{0x900b8, 0x109},
+	{0x900b9, 0x0},
+	{0x900ba, 0x7c8},
+	{0x900bb, 0x109},
+	{0x900bc, 0x8},
+	{0x900bd, 0x8140},
+	{0x900be, 0x10c},
+	{0x900bf, 0x0},
+	{0x900c0, 0x1},
+	{0x900c1, 0x8},
+	{0x900c2, 0x8},
+	{0x900c3, 0x4},
+	{0x900c4, 0x8},
+	{0x900c5, 0x8},
+	{0x900c6, 0x7c8},
+	{0x900c7, 0x101},
+	{0x90006, 0x0},
+	{0x90007, 0x0},
+	{0x90008, 0x8},
+	{0x90009, 0x0},
+	{0x9000a, 0x0},
+	{0x9000b, 0x0},
+	{0xd00e7, 0x400},
+	{0x90017, 0x0},
+	{0x90026, 0x2b},
+	{0x2000b, 0x4b},
+	{0x2000c, 0x96},
+	{0x2000d, 0x5dc},
+	{0x2000e, 0x2c},
+	{0x12000b, 0xc},
+	{0x12000c, 0x16},
+	{0x12000d, 0xfa},
+	{0x12000e, 0x10},
+	{0x22000b, 0x3},
+	{0x22000c, 0x3},
+	{0x22000d, 0x3e},
+	{0x22000e, 0x10},
+	{0x9000c, 0x0},
+	{0x9000d, 0x173},
+	{0x9000e, 0x60},
+	{0x9000f, 0x6110},
+	{0x90010, 0x2152},
+	{0x90011, 0xdfbd},
+	{0x90012, 0xffff},
+	{0x90013, 0x6152},
+	{0x20089, 0x1},
+	{0x20088, 0x19},
+	{0xc0080, 0x0},
+	{0xd0000, 0x1},
+};
+
+struct dram_fsp_msg ddr_dram_fsp_msg[] = {
+	{
+		/* P0 2400mts 1D */
+		.drate = 2400,
+		.fw_type = FW_1D_IMAGE,
+		.fsp_cfg = ddr_fsp0_cfg,
+		.fsp_cfg_num = ARRAY_SIZE(ddr_fsp0_cfg),
+	},
+	{
+		/* P1 400mts 1D */
+		.drate = 400,
+		.fw_type = FW_1D_IMAGE,
+		.fsp_cfg = ddr_fsp1_cfg,
+		.fsp_cfg_num = ARRAY_SIZE(ddr_fsp1_cfg),
+	},
+	{
+		/* P2 100mts 1D */
+		.drate = 100,
+		.fw_type = FW_1D_IMAGE,
+		.fsp_cfg = ddr_fsp2_cfg,
+		.fsp_cfg_num = ARRAY_SIZE(ddr_fsp2_cfg),
+	},
+	{
+		/* P0 2400mts 2D */
+		.drate = 2400,
+		.fw_type = FW_2D_IMAGE,
+		.fsp_cfg = ddr_fsp0_2d_cfg,
+		.fsp_cfg_num = ARRAY_SIZE(ddr_fsp0_2d_cfg),
+	},
+};
+
+/* ddr timing config params */
+struct dram_timing_info dram_timing = {
+	.ddrc_cfg = ddr_ddrc_cfg,
+	.ddrc_cfg_num = ARRAY_SIZE(ddr_ddrc_cfg),
+	.ddrphy_cfg = ddr_ddrphy_cfg,
+	.ddrphy_cfg_num = ARRAY_SIZE(ddr_ddrphy_cfg),
+	.fsp_msg = ddr_dram_fsp_msg,
+	.fsp_msg_num = ARRAY_SIZE(ddr_dram_fsp_msg),
+	.ddrphy_trained_csr = ddr_ddrphy_trained_csr,
+	.ddrphy_trained_csr_num = ARRAY_SIZE(ddr_ddrphy_trained_csr),
+	.ddrphy_pie = ddr_phy_pie,
+	.ddrphy_pie_num = ARRAY_SIZE(ddr_phy_pie),
+	.fsp_table = { 2400, 400, 100,},
+};
+
diff --git a/board/freescale/imx8mn_evk/imx8mn_evk.c b/board/freescale/imx8mn_evk/imx8mn_evk.c
new file mode 100644
index 0000000..b22a2a6
--- /dev/null
+++ b/board/freescale/imx8mn_evk/imx8mn_evk.c
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2019 NXP
+ */
+
+#include <common.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int dram_init(void)
+{
+	gd->ram_size = PHYS_SDRAM_SIZE;
+
+	return 0;
+}
+
+int board_init(void)
+{
+	return 0;
+}
+
+int board_late_init(void)
+{
+#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
+	env_set("board_name", "DDR4 EVK");
+	env_set("board_rev", "iMX8MN");
+#endif
+	return 0;
+}
diff --git a/board/freescale/imx8mn_evk/spl.c b/board/freescale/imx8mn_evk/spl.c
new file mode 100644
index 0000000..cbde9f6
--- /dev/null
+++ b/board/freescale/imx8mn_evk/spl.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2018-2019 NXP
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <spl.h>
+#include <asm/io.h>
+#include <asm/mach-imx/iomux-v3.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/imx8mn_pins.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/mach-imx/boot_mode.h>
+#include <asm/arch/ddr.h>
+
+#include <dm/uclass.h>
+#include <dm/device.h>
+#include <dm/uclass-internal.h>
+#include <dm/device-internal.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int spl_board_boot_device(enum boot_device boot_dev_spl)
+{
+	return BOOT_DEVICE_BOOTROM;
+}
+
+void spl_dram_init(void)
+{
+	ddr_init(&dram_timing);
+}
+
+void spl_board_init(void)
+{
+	struct udevice *dev;
+	int ret;
+
+	puts("Normal Boot\n");
+
+	ret = uclass_get_device_by_name(UCLASS_CLK,
+					"clock-controller@30380000",
+					&dev);
+	if (ret < 0)
+		printf("Failed to find clock node. Check device tree\n");
+}
+
+#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
+
+#define UART_PAD_CTRL	(PAD_CTL_DSE6 | PAD_CTL_FSEL1)
+#define WDOG_PAD_CTRL	(PAD_CTL_DSE6 | PAD_CTL_ODE | PAD_CTL_PUE | PAD_CTL_PE)
+
+static iomux_v3_cfg_t const uart_pads[] = {
+	IMX8MN_PAD_UART2_RXD__UART2_DCE_RX | MUX_PAD_CTRL(UART_PAD_CTRL),
+	IMX8MN_PAD_UART2_TXD__UART2_DCE_TX | MUX_PAD_CTRL(UART_PAD_CTRL),
+};
+
+static iomux_v3_cfg_t const wdog_pads[] = {
+	IMX8MN_PAD_GPIO1_IO02__WDOG1_WDOG_B  | MUX_PAD_CTRL(WDOG_PAD_CTRL),
+};
+
+int board_early_init_f(void)
+{
+	struct wdog_regs *wdog = (struct wdog_regs *)WDOG1_BASE_ADDR;
+
+	imx_iomux_v3_setup_multiple_pads(wdog_pads, ARRAY_SIZE(wdog_pads));
+
+	set_wdog_reset(wdog);
+
+	imx_iomux_v3_setup_multiple_pads(uart_pads, ARRAY_SIZE(uart_pads));
+
+	init_uart_clk(1);
+
+	return 0;
+}
+
+void board_init_f(ulong dummy)
+{
+	int ret;
+
+	arch_cpu_init();
+
+	init_uart_clk(1);
+
+	board_early_init_f();
+
+	timer_init();
+
+	preloader_console_init();
+
+	/* Clear the BSS. */
+	memset(__bss_start, 0, __bss_end - __bss_start);
+
+	ret = spl_init();
+	if (ret) {
+		debug("spl_init() failed: %d\n", ret);
+		hang();
+	}
+
+	enable_tzc380();
+
+	/* DDR initialization */
+	spl_dram_init();
+
+	board_init_r(NULL, 0);
+}
+
+int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	puts("resetting ...\n");
+
+	reset_cpu(WDOG1_BASE_ADDR);
+
+	return 0;
+}
diff --git a/board/freescale/imx8qm_mek/spl.c b/board/freescale/imx8qm_mek/spl.c
index 95ce9f3..cb4006e 100644
--- a/board/freescale/imx8qm_mek/spl.c
+++ b/board/freescale/imx8qm_mek/spl.c
@@ -18,7 +18,6 @@
 void spl_board_init(void)
 {
 	struct udevice *dev;
-	int offset;
 
 	uclass_find_first_device(UCLASS_MISC, &dev);
 
@@ -27,21 +26,6 @@
 			continue;
 	}
 
-	offset = fdt_node_offset_by_compatible(gd->fdt_blob, -1, "nxp,imx8-pd");
-	while (offset != -FDT_ERR_NOTFOUND) {
-		lists_bind_fdt(gd->dm_root, offset_to_ofnode(offset),
-			       NULL, true);
-		offset = fdt_node_offset_by_compatible(gd->fdt_blob, offset,
-						       "nxp,imx8-pd");
-	}
-
-	uclass_find_first_device(UCLASS_POWER_DOMAIN, &dev);
-
-	for (; dev; uclass_find_next_device(&dev)) {
-		if (device_probe(dev))
-			continue;
-	}
-
 	arch_cpu_init();
 
 	board_early_init_f();
diff --git a/board/pine64/rockpro64_rk3399/Kconfig b/board/pine64/rockpro64_rk3399/Kconfig
new file mode 100644
index 0000000..3353f1f
--- /dev/null
+++ b/board/pine64/rockpro64_rk3399/Kconfig
@@ -0,0 +1,15 @@
+if TARGET_ROCKPRO64_RK3399
+
+config SYS_BOARD
+	default "rockpro64_rk3399"
+
+config SYS_VENDOR
+	default "pine64"
+
+config SYS_CONFIG_NAME
+	default "rockpro64_rk3399"
+
+config BOARD_SPECIFIC_OPTIONS # dummy
+	def_bool y
+
+endif
diff --git a/board/pine64/rockpro64_rk3399/MAINTAINERS b/board/pine64/rockpro64_rk3399/MAINTAINERS
new file mode 100644
index 0000000..303db14
--- /dev/null
+++ b/board/pine64/rockpro64_rk3399/MAINTAINERS
@@ -0,0 +1,8 @@
+ROCKPRO64
+M:	Akash Gajjar <akash@openedev.com>
+M:	Jagan Teki <jagan@amarulasolutions.com>
+S:	Maintained
+F:	board/pine64/rockpro64_rk3399
+F:	include/configs/rockpro64_rk3399.h
+F:	arch/arm/dts/rk3399-rockpro64-u-boot.dtsi
+F:	configs/rockpro64-rk3399_defconfig
diff --git a/board/pine64/rockpro64_rk3399/Makefile b/board/pine64/rockpro64_rk3399/Makefile
new file mode 100644
index 0000000..b015c47
--- /dev/null
+++ b/board/pine64/rockpro64_rk3399/Makefile
@@ -0,0 +1,7 @@
+#
+# (C) Copyright 2019 Vasily Khoruzhick
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-y	+= rockpro64-rk3399.o
diff --git a/board/pine64/rockpro64_rk3399/rockpro64-rk3399.c b/board/pine64/rockpro64_rk3399/rockpro64-rk3399.c
new file mode 100644
index 0000000..3f60235
--- /dev/null
+++ b/board/pine64/rockpro64_rk3399/rockpro64-rk3399.c
@@ -0,0 +1,55 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2019 Vasily Khoruzhick <anarsoul@gmail.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <syscon.h>
+#include <asm/io.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/grf_rk3399.h>
+#include <asm/arch-rockchip/hardware.h>
+#include <asm/arch-rockchip/misc.h>
+
+#define GRF_IO_VSEL_BT565_SHIFT 0
+#define PMUGRF_CON0_VSEL_SHIFT 8
+
+#ifdef CONFIG_MISC_INIT_R
+static void setup_iodomain(void)
+{
+	struct rk3399_grf_regs *grf =
+	    syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+	struct rk3399_pmugrf_regs *pmugrf =
+	    syscon_get_first_range(ROCKCHIP_SYSCON_PMUGRF);
+
+	/* BT565 is in 1.8v domain */
+	rk_setreg(&grf->io_vsel, 1 << GRF_IO_VSEL_BT565_SHIFT);
+
+	/* Set GPIO1 1.8v/3.0v source select to PMU1830_VOL */
+	rk_setreg(&pmugrf->soc_con0, 1 << PMUGRF_CON0_VSEL_SHIFT);
+}
+
+int misc_init_r(void)
+{
+	const u32 cpuid_offset = 0x7;
+	const u32 cpuid_length = 0x10;
+	u8 cpuid[cpuid_length];
+	int ret;
+
+	setup_iodomain();
+
+	ret = rockchip_cpuid_from_efuse(cpuid_offset, cpuid_length, cpuid);
+	if (ret)
+		return ret;
+
+	ret = rockchip_cpuid_set(cpuid, cpuid_length);
+	if (ret)
+		return ret;
+
+	ret = rockchip_setup_macaddr();
+
+	return ret;
+}
+
+#endif
diff --git a/board/rockchip/evb_px30/Kconfig b/board/rockchip/evb_px30/Kconfig
new file mode 100644
index 0000000..0042c8e
--- /dev/null
+++ b/board/rockchip/evb_px30/Kconfig
@@ -0,0 +1,15 @@
+if TARGET_EVB_PX30
+
+config SYS_BOARD
+	default "evb_px30"
+
+config SYS_VENDOR
+	default "rockchip"
+
+config SYS_CONFIG_NAME
+	default "evb_px30"
+
+config BOARD_SPECIFIC_OPTIONS # dummy
+	def_bool y
+
+endif
diff --git a/board/rockchip/evb_px30/MAINTAINERS b/board/rockchip/evb_px30/MAINTAINERS
new file mode 100644
index 0000000..cf13f24
--- /dev/null
+++ b/board/rockchip/evb_px30/MAINTAINERS
@@ -0,0 +1,6 @@
+EVB-PX30
+M:      Kever Yang <kever.yang@rock-chips.com>
+S:      Maintained
+F:      board/rockchip/evb_px30
+F:      include/configs/evb_px30.h
+F:      configs/evb-px30_defconfig
diff --git a/board/rockchip/evb_px30/Makefile b/board/rockchip/evb_px30/Makefile
new file mode 100644
index 0000000..74b0b9f
--- /dev/null
+++ b/board/rockchip/evb_px30/Makefile
@@ -0,0 +1,7 @@
+#
+# (C) Copyright 2017 Rockchip Electronics Co., Ltd
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-y	+= evb_px30.o
diff --git a/board/rockchip/evb_px30/evb_px30.c b/board/rockchip/evb_px30/evb_px30.c
new file mode 100644
index 0000000..29464ae
--- /dev/null
+++ b/board/rockchip/evb_px30/evb_px30.c
@@ -0,0 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2019 Rockchip Electronics Co., Ltd
+ */
diff --git a/board/rockchip/evb_rk3308/Kconfig b/board/rockchip/evb_rk3308/Kconfig
new file mode 100644
index 0000000..0074429
--- /dev/null
+++ b/board/rockchip/evb_rk3308/Kconfig
@@ -0,0 +1,15 @@
+if TARGET_EVB_RK3308
+
+config SYS_BOARD
+	default "evb_rk3308"
+
+config SYS_VENDOR
+	default "rockchip"
+
+config SYS_CONFIG_NAME
+	default "evb_rk3308"
+
+config BOARD_SPECIFIC_OPTIONS # dummy
+	def_bool y
+
+endif
diff --git a/board/rockchip/evb_rk3308/MAINTAINERS b/board/rockchip/evb_rk3308/MAINTAINERS
new file mode 100644
index 0000000..0af119a
--- /dev/null
+++ b/board/rockchip/evb_rk3308/MAINTAINERS
@@ -0,0 +1,6 @@
+EVB-RK3308
+M:      Andy Yan <andy.yan@rock-chips.com>
+S:      Maintained
+F:      board/rockchip/evb_rk3308
+F:      include/configs/evb_rk3308.h
+F:      configs/evb-rk3308_defconfig
diff --git a/board/rockchip/evb_rk3308/Makefile b/board/rockchip/evb_rk3308/Makefile
new file mode 100644
index 0000000..05de556
--- /dev/null
+++ b/board/rockchip/evb_rk3308/Makefile
@@ -0,0 +1,7 @@
+#
+# (C) Copyright 2018 Rockchip Electronics Co., Ltd
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-y	+= evb_rk3308.o
diff --git a/board/rockchip/evb_rk3308/evb_rk3308.c b/board/rockchip/evb_rk3308/evb_rk3308.c
new file mode 100644
index 0000000..180f1fe
--- /dev/null
+++ b/board/rockchip/evb_rk3308/evb_rk3308.c
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2018 Rockchip Electronics Co., Ltd
+ */
+
+#include <common.h>
+#include <adc.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define KEY_DOWN_MIN_VAL        0
+#define KEY_DOWN_MAX_VAL        30
+
+/*
+ * Two board variants whith adc channel 3 is for board id
+ * v10: 1024, v11: 512
+ * v10: adc channel 0 for dnl key
+ * v11: adc channel 1 for dnl key
+ */
+int rockchip_dnl_key_pressed(void)
+{
+	unsigned int key_val, id_val;
+	int key_ch;
+
+	if (adc_channel_single_shot("saradc", 3, &id_val)) {
+		printf("%s read board id failed\n", __func__);
+		return false;
+	}
+
+	if (abs(id_val - 1024) <= 30)
+		key_ch = 0;
+	else
+		key_ch = 1;
+
+	if (adc_channel_single_shot("saradc", key_ch, &key_val)) {
+		printf("%s read adc key val failed\n", __func__);
+		return false;
+	}
+
+	if (key_val >= KEY_DOWN_MIN_VAL && key_val <= KEY_DOWN_MAX_VAL)
+		return true;
+	else
+		return false;
+}
diff --git a/board/rockchip/evb_rk3399/MAINTAINERS b/board/rockchip/evb_rk3399/MAINTAINERS
index 1397917..eab4c4c 100644
--- a/board/rockchip/evb_rk3399/MAINTAINERS
+++ b/board/rockchip/evb_rk3399/MAINTAINERS
@@ -58,7 +58,7 @@
 ROC-RK3399-PC
 M:	Levin Du <djw@t-chip.com.cn>
 S:	Maintained
-F:	configs/roc-rk3399-pc_defconfig
+F:	configs/roc-pc-rk3399_defconfig
 F:	arch/arm/dts/rk3399-roc-pc-u-boot.dtsi
 
 ROCK-PI-4
@@ -67,10 +67,3 @@
 S:	Maintained
 F:	configs/rock-pi-4-rk3399_defconfig
 F:	arch/arm/dts/rk3399-rock-pi-4-u-boot.dtsi
-
-ROCKPRO64
-M:	Akash Gajjar <akash@openedev.com>
-M:	Jagan Teki <jagan@amarulasolutions.com>
-S:	Maintained
-F:	configs/rockpro64-rk3399_defconfig
-F:	arch/arm/dts/rk3399-rockpro64-u-boot.dtsi
diff --git a/board/rockchip/tinker_rk3288/MAINTAINERS b/board/rockchip/tinker_rk3288/MAINTAINERS
index cddceaf..ed5de68 100644
--- a/board/rockchip/tinker_rk3288/MAINTAINERS
+++ b/board/rockchip/tinker_rk3288/MAINTAINERS
@@ -4,3 +4,10 @@
 F:	board/rockchip/tinker_rk3288
 F:	include/configs/tinker_rk3288.h
 F:	configs/tinker-rk3288_defconfig
+
+TINKER-S-RK3288
+M:	Michael Trimarchi <michael@amarulasolutions.com>
+S:	Maintained
+F:	board/rockchip/tinker_rk3288
+F:	include/configs/tinker_rk3288.h
+F:	configs/tinker-s-rk3288_defconfig
diff --git a/board/rockchip/tinker_rk3288/tinker-rk3288.c b/board/rockchip/tinker_rk3288/tinker-rk3288.c
index 6c76c3c..7a0c3c9 100644
--- a/board/rockchip/tinker_rk3288/tinker-rk3288.c
+++ b/board/rockchip/tinker_rk3288/tinker-rk3288.c
@@ -8,6 +8,8 @@
 #include <env.h>
 #include <i2c_eeprom.h>
 #include <netdev.h>
+#include <asm/arch-rockchip/bootrom.h>
+#include <asm/io.h>
 
 static int get_ethaddr_from_eeprom(u8 *addr)
 {
@@ -33,3 +35,13 @@
 
 	return 0;
 }
+
+int mmc_get_env_dev(void)
+{
+	u32 bootdevice_brom_id = readl(BROM_BOOTSOURCE_ID_ADDR);
+
+	if (bootdevice_brom_id == BROM_BOOTSOURCE_EMMC)
+		return 0;
+
+	return 1;
+}
diff --git a/cmd/Kconfig b/cmd/Kconfig
index 99b8a0e..cf982ff 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -320,7 +320,7 @@
 
 config CMD_BOOTEFI_HELLO_COMPILE
 	bool "Compile a standard EFI hello world binary for testing"
-	depends on CMD_BOOTEFI && !CPU_V7M && !SANDBOX
+	depends on CMD_BOOTEFI && !CPU_V7M
 	default y
 	help
 	  This compiles a standard EFI hello world application with U-Boot so
diff --git a/common/image-fdt.c b/common/image-fdt.c
index 4247dce..4838848 100644
--- a/common/image-fdt.c
+++ b/common/image-fdt.c
@@ -17,6 +17,7 @@
 #include <linux/libfdt.h>
 #include <mapmem.h>
 #include <asm/io.h>
+#include <tee/optee.h>
 
 #ifndef CONFIG_SYS_FDT_PAD
 #define CONFIG_SYS_FDT_PAD 0x3000
@@ -561,6 +562,13 @@
 		}
 	}
 
+	fdt_ret = optee_copy_fdt_nodes(gd->fdt_blob, blob);
+	if (fdt_ret) {
+		printf("ERROR: transfer of optee nodes to new fdt failed: %s\n",
+		       fdt_strerror(fdt_ret));
+		goto err;
+	}
+
 	/* Delete the old LMB reservation */
 	if (lmb)
 		lmb_free(lmb, (phys_addr_t)(u32)(uintptr_t)blob,
diff --git a/common/spl/Kconfig b/common/spl/Kconfig
index 8f0ba8e..1f12283 100644
--- a/common/spl/Kconfig
+++ b/common/spl/Kconfig
@@ -1241,6 +1241,14 @@
 	  Specifies the maximum length of the U-Boot TPL image.
 	  If this value is zero, it is ignored.
 
+config TPL_FRAMEWORK
+	bool "Support TPL based upon the common SPL framework"
+	default y if SPL_FRAMEWORK
+	help
+	  Enable the SPL framework under common/spl/ for TPL builds.
+	  This framework supports MMC, NAND and YMODEM and other methods
+	  loading of U-Boot's SPL stage. If unsure, say Y.
+
 config TPL_HANDOFF
 	bool "Pass hand-off information from TPL to SPL and U-Boot proper"
 	depends on HANDOFF && TPL_BLOBLIST
diff --git a/common/spl/Makefile b/common/spl/Makefile
index 5ce6f4a..eaa57f5 100644
--- a/common/spl/Makefile
+++ b/common/spl/Makefile
@@ -7,7 +7,7 @@
 #
 
 ifdef CONFIG_SPL_BUILD
-obj-$(CONFIG_SPL_FRAMEWORK) += spl.o
+obj-$(CONFIG_$(SPL_TPL_)FRAMEWORK) += spl.o
 obj-$(CONFIG_$(SPL_TPL_)BOOTROM_SUPPORT) += spl_bootrom.o
 obj-$(CONFIG_$(SPL_TPL_)LOAD_FIT) += spl_fit.o
 obj-$(CONFIG_$(SPL_TPL_)NOR_SUPPORT) += spl_nor.o
diff --git a/configs/MPC8308RDB_defconfig b/configs/MPC8308RDB_defconfig
index 5faf20f..55ecf75 100644
--- a/configs/MPC8308RDB_defconfig
+++ b/configs/MPC8308RDB_defconfig
@@ -126,6 +126,7 @@
 CONFIG_CMD_PING=y
 CONFIG_CMD_DATE=y
 CONFIG_CMD_FAT=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_FSL_ESDHC=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
diff --git a/configs/MPC8313ERDB_NAND_33_defconfig b/configs/MPC8313ERDB_NAND_33_defconfig
index 4c30f75..a3c8117 100644
--- a/configs/MPC8313ERDB_NAND_33_defconfig
+++ b/configs/MPC8313ERDB_NAND_33_defconfig
@@ -150,6 +150,7 @@
 CONFIG_MTDPARTS_DEFAULT="mtdparts=e2800000.flash:512k(uboot),128k(env),6m@1m(kernel),-(fs)"
 # CONFIG_ENV_IS_IN_FLASH is not set
 CONFIG_ENV_IS_IN_NAND=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 # CONFIG_MMC is not set
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
diff --git a/configs/MPC8313ERDB_NAND_66_defconfig b/configs/MPC8313ERDB_NAND_66_defconfig
index 1c7c72d..4e2ffab 100644
--- a/configs/MPC8313ERDB_NAND_66_defconfig
+++ b/configs/MPC8313ERDB_NAND_66_defconfig
@@ -149,6 +149,7 @@
 CONFIG_MTDPARTS_DEFAULT="mtdparts=e2800000.flash:512k(uboot),128k(env),6m@1m(kernel),-(fs)"
 # CONFIG_ENV_IS_IN_FLASH is not set
 CONFIG_ENV_IS_IN_NAND=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 # CONFIG_MMC is not set
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
diff --git a/configs/MPC8349EMDS_PCI64_defconfig b/configs/MPC8349EMDS_PCI64_defconfig
index 00dc72d..873fabc 100644
--- a/configs/MPC8349EMDS_PCI64_defconfig
+++ b/configs/MPC8349EMDS_PCI64_defconfig
@@ -93,6 +93,7 @@
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
 CONFIG_CMD_DATE=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 # CONFIG_MMC is not set
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
diff --git a/configs/MPC8349EMDS_SDRAM_defconfig b/configs/MPC8349EMDS_SDRAM_defconfig
index ee2de0a..ed7445c 100644
--- a/configs/MPC8349EMDS_SDRAM_defconfig
+++ b/configs/MPC8349EMDS_SDRAM_defconfig
@@ -102,6 +102,7 @@
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
 CONFIG_CMD_DATE=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 # CONFIG_MMC is not set
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
diff --git a/configs/MPC8349EMDS_SLAVE_defconfig b/configs/MPC8349EMDS_SLAVE_defconfig
index 7550aa3..c39c362 100644
--- a/configs/MPC8349EMDS_SLAVE_defconfig
+++ b/configs/MPC8349EMDS_SLAVE_defconfig
@@ -93,6 +93,7 @@
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
 CONFIG_CMD_DATE=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 # CONFIG_MMC is not set
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
diff --git a/configs/MPC8349EMDS_defconfig b/configs/MPC8349EMDS_defconfig
index ba00a27..87e0419 100644
--- a/configs/MPC8349EMDS_defconfig
+++ b/configs/MPC8349EMDS_defconfig
@@ -94,6 +94,7 @@
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
 CONFIG_CMD_DATE=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 # CONFIG_MMC is not set
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
diff --git a/configs/TQM834x_defconfig b/configs/TQM834x_defconfig
index d2e85c9..f7d7d58 100644
--- a/configs/TQM834x_defconfig
+++ b/configs/TQM834x_defconfig
@@ -138,6 +138,7 @@
 CONFIG_CMD_MTDPARTS=y
 CONFIG_MTDIDS_DEFAULT="nor0=TQM834x-0"
 CONFIG_MTDPARTS_DEFAULT="mtdparts=TQM834x-0:256k(u-boot),256k(env),1m(kernel),2m(initrd),-(user);"
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 # CONFIG_MMC is not set
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_MTD_DEVICE=y
diff --git a/configs/am335x_boneblack_vboot_defconfig b/configs/am335x_boneblack_vboot_defconfig
index 5f11264..39b8d1c 100644
--- a/configs/am335x_boneblack_vboot_defconfig
+++ b/configs/am335x_boneblack_vboot_defconfig
@@ -31,6 +31,7 @@
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="am335x-boneblack"
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 # CONFIG_SPL_BLK is not set
 CONFIG_BOOTCOUNT_LIMIT=y
diff --git a/configs/am335x_igep003x_defconfig b/configs/am335x_igep003x_defconfig
index 8ed52a5..92a550d 100644
--- a/configs/am335x_igep003x_defconfig
+++ b/configs/am335x_igep003x_defconfig
@@ -56,6 +56,7 @@
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="am335x-base0033"
 CONFIG_ENV_IS_IN_UBI=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_ENV_UBI_PART="UBI"
 CONFIG_ENV_UBI_VOLUME="config"
 CONFIG_ENV_UBI_VOLUME_REDUND="config_r"
diff --git a/configs/am335x_shc_defconfig b/configs/am335x_shc_defconfig
index 5698208..fc40d17 100644
--- a/configs/am335x_shc_defconfig
+++ b/configs/am335x_shc_defconfig
@@ -43,6 +43,7 @@
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="am335x-shc"
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DM_MMC=y
 CONFIG_MMC_OMAP_HS=y
diff --git a/configs/am335x_shc_ict_defconfig b/configs/am335x_shc_ict_defconfig
index 3f8a6ba..ffd03a8 100644
--- a/configs/am335x_shc_ict_defconfig
+++ b/configs/am335x_shc_ict_defconfig
@@ -44,6 +44,7 @@
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="am335x-shc"
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DM_MMC=y
 CONFIG_MMC_OMAP_HS=y
diff --git a/configs/am335x_shc_netboot_defconfig b/configs/am335x_shc_netboot_defconfig
index d0a7d62..f9c1d50 100644
--- a/configs/am335x_shc_netboot_defconfig
+++ b/configs/am335x_shc_netboot_defconfig
@@ -45,6 +45,7 @@
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="am335x-shc"
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DM_MMC=y
 CONFIG_MMC_OMAP_HS=y
diff --git a/configs/am335x_shc_sdboot_defconfig b/configs/am335x_shc_sdboot_defconfig
index 30fa40a..1839b7c 100644
--- a/configs/am335x_shc_sdboot_defconfig
+++ b/configs/am335x_shc_sdboot_defconfig
@@ -44,6 +44,7 @@
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="am335x-shc"
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DM_MMC=y
 CONFIG_MMC_OMAP_HS=y
diff --git a/configs/am335x_sl50_defconfig b/configs/am335x_sl50_defconfig
index 01fc52b..9b1ffa5 100644
--- a/configs/am335x_sl50_defconfig
+++ b/configs/am335x_sl50_defconfig
@@ -42,6 +42,7 @@
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="am335x-sl50"
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_DM_MMC=y
diff --git a/configs/am43xx_evm_qspiboot_defconfig b/configs/am43xx_evm_qspiboot_defconfig
index 7a7591e..b8ddead 100644
--- a/configs/am43xx_evm_qspiboot_defconfig
+++ b/configs/am43xx_evm_qspiboot_defconfig
@@ -32,6 +32,7 @@
 CONFIG_DTB_RESELECT=y
 CONFIG_MULTI_DTB_FIT=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DM=y
 CONFIG_DFU_MMC=y
diff --git a/configs/am57xx_evm_defconfig b/configs/am57xx_evm_defconfig
index 8a867f6..588e589 100644
--- a/configs/am57xx_evm_defconfig
+++ b/configs/am57xx_evm_defconfig
@@ -40,6 +40,7 @@
 CONFIG_DEFAULT_DEVICE_TREE="am572x-idk"
 CONFIG_OF_LIST="am57xx-beagle-x15 am57xx-beagle-x15-revb1 am57xx-beagle-x15-revc am572x-idk am571x-idk am574x-idk"
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DM=y
 CONFIG_SPL_DM=y
diff --git a/configs/am57xx_hs_evm_defconfig b/configs/am57xx_hs_evm_defconfig
index d62581f..a09a1e0 100644
--- a/configs/am57xx_hs_evm_defconfig
+++ b/configs/am57xx_hs_evm_defconfig
@@ -42,6 +42,7 @@
 CONFIG_DEFAULT_DEVICE_TREE="am57xx-beagle-x15"
 CONFIG_OF_LIST="am57xx-beagle-x15 am57xx-beagle-x15-revb1 am57xx-beagle-x15-revc am572x-idk am571x-idk am574x-idk"
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DM=y
 CONFIG_SPL_DM=y
diff --git a/configs/am57xx_hs_evm_usb_defconfig b/configs/am57xx_hs_evm_usb_defconfig
index 438662b..c9e0083 100644
--- a/configs/am57xx_hs_evm_usb_defconfig
+++ b/configs/am57xx_hs_evm_usb_defconfig
@@ -47,6 +47,7 @@
 CONFIG_DEFAULT_DEVICE_TREE="am57xx-beagle-x15"
 CONFIG_OF_LIST="am57xx-beagle-x15 am57xx-beagle-x15-revb1 am57xx-beagle-x15-revc am572x-idk am571x-idk am574x-idk"
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DM=y
 CONFIG_SPL_DM=y
diff --git a/configs/am65x_evm_a53_defconfig b/configs/am65x_evm_a53_defconfig
index d1188d0..027e0a5 100644
--- a/configs/am65x_evm_a53_defconfig
+++ b/configs/am65x_evm_a53_defconfig
@@ -45,6 +45,7 @@
 CONFIG_SPL_MULTI_DTB_FIT=y
 CONFIG_SPL_MULTI_DTB_FIT_NO_COMPRESSION=y
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_DM=y
 CONFIG_SPL_DM=y
diff --git a/configs/apf27_defconfig b/configs/apf27_defconfig
index 2b82f05..650c2d2 100644
--- a/configs/apf27_defconfig
+++ b/configs/apf27_defconfig
@@ -39,6 +39,7 @@
 CONFIG_MTDPARTS_DEFAULT="mtdparts=mxc_nand.0:1M(u-boot)ro,512K(env),512K(env2),512K(firmware),512K(dtb),5M(kernel),-(rootfs)"
 CONFIG_CMD_UBI=y
 CONFIG_ENV_IS_IN_NAND=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_FPGA_XILINX=y
 CONFIG_FPGA_SPARTAN3=y
 CONFIG_MXC_GPIO=y
diff --git a/configs/apx4devkit_defconfig b/configs/apx4devkit_defconfig
index 89f58e5..993a4f6 100644
--- a/configs/apx4devkit_defconfig
+++ b/configs/apx4devkit_defconfig
@@ -31,6 +31,7 @@
 CONFIG_MTDPARTS_DEFAULT="mtdparts=gpmi-nand:128k(bootstrap),1024k(boot),768k(env),-(root)"
 CONFIG_CMD_UBI=y
 CONFIG_ENV_IS_IN_NAND=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_MXS_GPIO=y
 CONFIG_MMC_MXS=y
 CONFIG_NAND=y
diff --git a/configs/aristainetos2_defconfig b/configs/aristainetos2_defconfig
index 0bfc117..5c286a0 100644
--- a/configs/aristainetos2_defconfig
+++ b/configs/aristainetos2_defconfig
@@ -35,6 +35,7 @@
 CONFIG_CMD_MTDPARTS=y
 CONFIG_CMD_UBI=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_FSL_USDHC=y
 CONFIG_NAND=y
 CONFIG_NAND_MXS=y
diff --git a/configs/aristainetos2b_defconfig b/configs/aristainetos2b_defconfig
index e2da747..f19501d 100644
--- a/configs/aristainetos2b_defconfig
+++ b/configs/aristainetos2b_defconfig
@@ -35,6 +35,7 @@
 CONFIG_CMD_MTDPARTS=y
 CONFIG_CMD_UBI=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_FSL_USDHC=y
 CONFIG_NAND=y
 CONFIG_NAND_MXS=y
diff --git a/configs/aristainetos_defconfig b/configs/aristainetos_defconfig
index 5caf95c..f79c37e 100644
--- a/configs/aristainetos_defconfig
+++ b/configs/aristainetos_defconfig
@@ -35,6 +35,7 @@
 CONFIG_CMD_MTDPARTS=y
 CONFIG_CMD_UBI=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_FSL_USDHC=y
 CONFIG_NAND=y
 CONFIG_NAND_MXS=y
diff --git a/configs/at91sam9260ek_nandflash_defconfig b/configs/at91sam9260ek_nandflash_defconfig
index 3b4706b..2a2c9a6 100644
--- a/configs/at91sam9260ek_nandflash_defconfig
+++ b/configs/at91sam9260ek_nandflash_defconfig
@@ -29,6 +29,7 @@
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="at91sam9260ek"
 CONFIG_ENV_IS_IN_NAND=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_DM=y
 CONFIG_CLK=y
 CONFIG_CLK_AT91=y
diff --git a/configs/at91sam9261ek_nandflash_defconfig b/configs/at91sam9261ek_nandflash_defconfig
index bb1c1b8..a216716 100644
--- a/configs/at91sam9261ek_nandflash_defconfig
+++ b/configs/at91sam9261ek_nandflash_defconfig
@@ -29,6 +29,7 @@
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="at91sam9261ek"
 CONFIG_ENV_IS_IN_NAND=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_DM=y
 CONFIG_CLK=y
 CONFIG_CLK_AT91=y
diff --git a/configs/at91sam9263ek_nandflash_defconfig b/configs/at91sam9263ek_nandflash_defconfig
index 53eddd8..f286c5a 100644
--- a/configs/at91sam9263ek_nandflash_defconfig
+++ b/configs/at91sam9263ek_nandflash_defconfig
@@ -33,6 +33,7 @@
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="at91sam9263ek"
 CONFIG_ENV_IS_IN_NAND=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_DM=y
 CONFIG_CLK=y
 CONFIG_CLK_AT91=y
diff --git a/configs/at91sam9263ek_norflash_boot_defconfig b/configs/at91sam9263ek_norflash_boot_defconfig
index 9345a42..5253e63 100644
--- a/configs/at91sam9263ek_norflash_boot_defconfig
+++ b/configs/at91sam9263ek_norflash_boot_defconfig
@@ -34,6 +34,7 @@
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="at91sam9263ek"
 CONFIG_ENV_IS_IN_FLASH=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_DM=y
 CONFIG_CLK=y
 CONFIG_CLK_AT91=y
diff --git a/configs/at91sam9263ek_norflash_defconfig b/configs/at91sam9263ek_norflash_defconfig
index 86ae5f7..a008368 100644
--- a/configs/at91sam9263ek_norflash_defconfig
+++ b/configs/at91sam9263ek_norflash_defconfig
@@ -34,6 +34,7 @@
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="at91sam9263ek"
 CONFIG_ENV_IS_IN_FLASH=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_DM=y
 CONFIG_CLK=y
 CONFIG_CLK_AT91=y
diff --git a/configs/at91sam9g10ek_nandflash_defconfig b/configs/at91sam9g10ek_nandflash_defconfig
index 007f11d..7499293 100644
--- a/configs/at91sam9g10ek_nandflash_defconfig
+++ b/configs/at91sam9g10ek_nandflash_defconfig
@@ -29,6 +29,7 @@
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="at91sam9261ek"
 CONFIG_ENV_IS_IN_NAND=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_DM=y
 CONFIG_CLK=y
 CONFIG_CLK_AT91=y
diff --git a/configs/at91sam9g20ek_2mmc_nandflash_defconfig b/configs/at91sam9g20ek_2mmc_nandflash_defconfig
index c28b81b..6fb3a95 100644
--- a/configs/at91sam9g20ek_2mmc_nandflash_defconfig
+++ b/configs/at91sam9g20ek_2mmc_nandflash_defconfig
@@ -30,6 +30,7 @@
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="at91sam9g20ek_2mmc"
 CONFIG_ENV_IS_IN_NAND=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_DM=y
 CONFIG_CLK=y
 CONFIG_CLK_AT91=y
diff --git a/configs/at91sam9g20ek_nandflash_defconfig b/configs/at91sam9g20ek_nandflash_defconfig
index 3d97a52..addefca 100644
--- a/configs/at91sam9g20ek_nandflash_defconfig
+++ b/configs/at91sam9g20ek_nandflash_defconfig
@@ -29,6 +29,7 @@
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="at91sam9g20ek"
 CONFIG_ENV_IS_IN_NAND=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_DM=y
 CONFIG_CLK=y
 CONFIG_CLK_AT91=y
diff --git a/configs/at91sam9m10g45ek_nandflash_defconfig b/configs/at91sam9m10g45ek_nandflash_defconfig
index 44c5073..33b42e6 100644
--- a/configs/at91sam9m10g45ek_nandflash_defconfig
+++ b/configs/at91sam9m10g45ek_nandflash_defconfig
@@ -32,6 +32,7 @@
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="at91sam9m10g45ek"
 CONFIG_ENV_IS_IN_NAND=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_DM=y
 CONFIG_CLK=y
 CONFIG_CLK_AT91=y
diff --git a/configs/at91sam9n12ek_nandflash_defconfig b/configs/at91sam9n12ek_nandflash_defconfig
index 51175fb..0644f0b 100644
--- a/configs/at91sam9n12ek_nandflash_defconfig
+++ b/configs/at91sam9n12ek_nandflash_defconfig
@@ -31,6 +31,7 @@
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="at91sam9n12ek"
 CONFIG_ENV_IS_IN_NAND=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_DM=y
 CONFIG_CLK=y
 CONFIG_CLK_AT91=y
diff --git a/configs/at91sam9rlek_nandflash_defconfig b/configs/at91sam9rlek_nandflash_defconfig
index 7b74180..4d3f3cf 100644
--- a/configs/at91sam9rlek_nandflash_defconfig
+++ b/configs/at91sam9rlek_nandflash_defconfig
@@ -30,6 +30,7 @@
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="at91sam9rlek"
 CONFIG_ENV_IS_IN_NAND=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 # CONFIG_NET is not set
 CONFIG_DM=y
 CONFIG_CLK=y
diff --git a/configs/at91sam9x5ek_nandflash_defconfig b/configs/at91sam9x5ek_nandflash_defconfig
index 8f9efdf..dc3fec2 100644
--- a/configs/at91sam9x5ek_nandflash_defconfig
+++ b/configs/at91sam9x5ek_nandflash_defconfig
@@ -33,6 +33,7 @@
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="at91sam9g35ek"
 CONFIG_ENV_IS_IN_NAND=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_DM=y
 CONFIG_CLK=y
 CONFIG_CLK_AT91=y
diff --git a/configs/at91sam9xeek_nandflash_defconfig b/configs/at91sam9xeek_nandflash_defconfig
index 68d43ff..417626f 100644
--- a/configs/at91sam9xeek_nandflash_defconfig
+++ b/configs/at91sam9xeek_nandflash_defconfig
@@ -29,6 +29,7 @@
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="at91sam9260ek"
 CONFIG_ENV_IS_IN_NAND=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_DM=y
 CONFIG_CLK=y
 CONFIG_CLK_AT91=y
diff --git a/configs/axm_defconfig b/configs/axm_defconfig
index 9947ed9..8a635d2 100644
--- a/configs/axm_defconfig
+++ b/configs/axm_defconfig
@@ -50,6 +50,7 @@
 CONFIG_DEFAULT_DEVICE_TREE="at91sam9g20-taurus"
 CONFIG_SPL_OF_PLATDATA=y
 CONFIG_ENV_IS_IN_NAND=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_SPL_DM=y
 CONFIG_BLK=y
 CONFIG_HAVE_BLOCK_DEVICE=y
diff --git a/configs/bcm7260_defconfig b/configs/bcm7260_defconfig
index 2c18d36..163ba87 100644
--- a/configs/bcm7260_defconfig
+++ b/configs/bcm7260_defconfig
@@ -13,6 +13,7 @@
 CONFIG_EFI_PARTITION=y
 CONFIG_OF_PRIOR_STAGE=y
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_DM_MMC=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_BCMSTB=y
diff --git a/configs/bcm7445_defconfig b/configs/bcm7445_defconfig
index a3d6a61..017a8da 100644
--- a/configs/bcm7445_defconfig
+++ b/configs/bcm7445_defconfig
@@ -14,6 +14,7 @@
 CONFIG_CMD_SPI=y
 CONFIG_OF_PRIOR_STAGE=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_DM_MMC=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_BCMSTB=y
diff --git a/configs/bk4r1_defconfig b/configs/bk4r1_defconfig
index 6ad2b7c..68f0f24 100644
--- a/configs/bk4r1_defconfig
+++ b/configs/bk4r1_defconfig
@@ -32,6 +32,7 @@
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="vf610-bk4r1"
 CONFIG_ENV_IS_IN_NAND=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_NETCONSOLE=y
 CONFIG_DM=y
 CONFIG_BOOTCOUNT_LIMIT=y
diff --git a/configs/brppt1_mmc_defconfig b/configs/brppt1_mmc_defconfig
index d0ee619..50e447a 100644
--- a/configs/brppt1_mmc_defconfig
+++ b/configs/brppt1_mmc_defconfig
@@ -66,6 +66,7 @@
 CONFIG_DEFAULT_DEVICE_TREE="am335x-brppt1-mmc"
 CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clocks clock-names interrupt-parent interrupt-controller interrupt-cells dma-names dmas "
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_DM=y
 CONFIG_SPL_DM=y
diff --git a/configs/brppt1_spi_defconfig b/configs/brppt1_spi_defconfig
index aa4c7f7..ad7ae4d 100644
--- a/configs/brppt1_spi_defconfig
+++ b/configs/brppt1_spi_defconfig
@@ -72,6 +72,7 @@
 CONFIG_DEFAULT_DEVICE_TREE="am335x-brppt1-spi"
 CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clocks clock-names interrupt-parent interrupt-controller interrupt-cells dma-names dmas "
 CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_DM=y
 CONFIG_SPL_DM=y
diff --git a/configs/brsmarc1_defconfig b/configs/brsmarc1_defconfig
index b6626e1..1598a21 100644
--- a/configs/brsmarc1_defconfig
+++ b/configs/brsmarc1_defconfig
@@ -71,6 +71,7 @@
 CONFIG_SPL_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="am335x-brsmarc1"
 CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_NETCONSOLE=y
 CONFIG_DM=y
diff --git a/configs/brxre1_defconfig b/configs/brxre1_defconfig
index d9b0e32..e1fb102 100644
--- a/configs/brxre1_defconfig
+++ b/configs/brxre1_defconfig
@@ -65,6 +65,7 @@
 CONFIG_DEFAULT_DEVICE_TREE="am335x-brxre1"
 CONFIG_OF_SPL_REMOVE_PROPS=""
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_NETCONSOLE=y
 CONFIG_DM=y
diff --git a/configs/caddy2_defconfig b/configs/caddy2_defconfig
index 51c37e2..0760986 100644
--- a/configs/caddy2_defconfig
+++ b/configs/caddy2_defconfig
@@ -106,6 +106,7 @@
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
 CONFIG_CMD_DATE=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 # CONFIG_MMC is not set
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
diff --git a/configs/chiliboard_defconfig b/configs/chiliboard_defconfig
index f275d21..84517b3 100644
--- a/configs/chiliboard_defconfig
+++ b/configs/chiliboard_defconfig
@@ -35,6 +35,7 @@
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="am335x-chiliboard"
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_DM_GPIO=y
 CONFIG_MISC=y
diff --git a/configs/cm_t54_defconfig b/configs/cm_t54_defconfig
index 09c0a36..6c06675 100644
--- a/configs/cm_t54_defconfig
+++ b/configs/cm_t54_defconfig
@@ -32,6 +32,7 @@
 # CONFIG_CMD_NFS is not set
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_SCSI_AHCI=y
 CONFIG_SUPPORT_EMMC_BOOT=y
diff --git a/configs/corvus_defconfig b/configs/corvus_defconfig
index 56c6123..7683a80 100644
--- a/configs/corvus_defconfig
+++ b/configs/corvus_defconfig
@@ -41,6 +41,7 @@
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="at91sam9g45-corvus"
 CONFIG_ENV_IS_IN_NAND=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_BLK=y
 CONFIG_CLK=y
 CONFIG_CLK_AT91=y
diff --git a/configs/dh_imx6_defconfig b/configs/dh_imx6_defconfig
index db3341e..4055812 100644
--- a/configs/dh_imx6_defconfig
+++ b/configs/dh_imx6_defconfig
@@ -45,6 +45,7 @@
 CONFIG_OF_LIST="imx6q-dhcom-pdk2 imx6dl-dhcom-pdk2"
 CONFIG_MULTI_DTB_FIT=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_DWC_AHSATA=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_DM_GPIO=y
diff --git a/configs/display5_defconfig b/configs/display5_defconfig
index 7169b33..cd96272 100644
--- a/configs/display5_defconfig
+++ b/configs/display5_defconfig
@@ -68,6 +68,7 @@
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="imx6q-display5"
 CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_BOOTCOUNT_BOOTLIMIT=3
 CONFIG_I2C_SET_DEFAULT_BUS_NUM=y
diff --git a/configs/display5_factory_defconfig b/configs/display5_factory_defconfig
index 221f4b5..d4e738e 100644
--- a/configs/display5_factory_defconfig
+++ b/configs/display5_factory_defconfig
@@ -71,6 +71,7 @@
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="imx6q-display5"
 CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_DFU_MMC=y
 CONFIG_DFU_SF=y
 CONFIG_I2C_SET_DEFAULT_BUS_NUM=y
diff --git a/configs/dra7xx_evm_defconfig b/configs/dra7xx_evm_defconfig
index a1a5dc5..cb2cdcb 100644
--- a/configs/dra7xx_evm_defconfig
+++ b/configs/dra7xx_evm_defconfig
@@ -46,6 +46,7 @@
 CONFIG_OF_SPL_REMOVE_PROPS="clocks clock-names interrupt-parent"
 # CONFIG_ENV_IS_IN_FAT is not set
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DM=y
 CONFIG_SPL_DM=y
diff --git a/configs/dra7xx_hs_evm_defconfig b/configs/dra7xx_hs_evm_defconfig
index 85b5f59..1dff889 100644
--- a/configs/dra7xx_hs_evm_defconfig
+++ b/configs/dra7xx_hs_evm_defconfig
@@ -49,6 +49,7 @@
 CONFIG_OF_SPL_REMOVE_PROPS="clocks clock-names interrupt-parent"
 # CONFIG_ENV_IS_IN_FAT is not set
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DM=y
 CONFIG_SPL_DM=y
diff --git a/configs/dra7xx_hs_evm_usb_defconfig b/configs/dra7xx_hs_evm_usb_defconfig
index 8d8cc22..fa18e1d 100644
--- a/configs/dra7xx_hs_evm_usb_defconfig
+++ b/configs/dra7xx_hs_evm_usb_defconfig
@@ -48,6 +48,7 @@
 CONFIG_SPL_MULTI_DTB_FIT_UNCOMPRESS_SZ=0x9000
 CONFIG_OF_SPL_REMOVE_PROPS="clocks clock-names interrupt-parent"
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DM=y
 CONFIG_SPL_DM=y
diff --git a/configs/draco_defconfig b/configs/draco_defconfig
index 4ba3bde..52b234d 100644
--- a/configs/draco_defconfig
+++ b/configs/draco_defconfig
@@ -59,6 +59,7 @@
 CONFIG_OF_EMBED=y
 CONFIG_DEFAULT_DEVICE_TREE="am335x-draco"
 CONFIG_ENV_IS_IN_NAND=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_BOOTCOUNT_ENV=y
 CONFIG_BOOTCOUNT_BOOTLIMIT=3
diff --git a/configs/edb9315a_defconfig b/configs/edb9315a_defconfig
index f8f2e16..3c506fd 100644
--- a/configs/edb9315a_defconfig
+++ b/configs/edb9315a_defconfig
@@ -24,6 +24,7 @@
 CONFIG_CMD_JFFS2=y
 # CONFIG_DOS_PARTITION is not set
 CONFIG_ENV_IS_IN_FLASH=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_LED_STATUS=y
 CONFIG_LED_STATUS0=y
 CONFIG_LED_STATUS_BIT=0
diff --git a/configs/edison_defconfig b/configs/edison_defconfig
index 553b22c..672b2bb 100644
--- a/configs/edison_defconfig
+++ b/configs/edison_defconfig
@@ -28,6 +28,7 @@
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_DEFAULT_DEVICE_TREE="edison"
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_CPU=y
 CONFIG_DFU_MMC=y
 CONFIG_DFU_RAM=y
diff --git a/configs/etamin_defconfig b/configs/etamin_defconfig
index 31e711d..a74cad9 100644
--- a/configs/etamin_defconfig
+++ b/configs/etamin_defconfig
@@ -60,6 +60,7 @@
 CONFIG_OF_EMBED=y
 CONFIG_DEFAULT_DEVICE_TREE="am335x-draco"
 CONFIG_ENV_IS_IN_NAND=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_BOOTCOUNT_ENV=y
 CONFIG_BOOTCOUNT_BOOTLIMIT=3
diff --git a/configs/evb-px30_defconfig b/configs/evb-px30_defconfig
new file mode 100644
index 0000000..36fba60
--- /dev/null
+++ b/configs/evb-px30_defconfig
@@ -0,0 +1,111 @@
+CONFIG_ARM=y
+CONFIG_ARCH_ROCKCHIP=y
+CONFIG_SYS_TEXT_BASE=0x00200000
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_ROCKCHIP_PX30=y
+CONFIG_TARGET_EVB_PX30=y
+CONFIG_TPL_LIBGENERIC_SUPPORT=y
+CONFIG_SPL_DRIVERS_MISC_SUPPORT=y
+CONFIG_SPL_STACK_R_ADDR=0x600000
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_DEBUG_UART_BASE=0xFF160000
+CONFIG_DEBUG_UART_CLOCK=24000000
+CONFIG_DEBUG_UART=y
+CONFIG_SPL_TEXT_BASE=0x00000000
+CONFIG_TPL_SYS_MALLOC_F_LEN=0x600
+# CONFIG_ANDROID_BOOT_IMAGE is not set
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_SPL_LOAD_FIT=y
+# CONFIG_CONSOLE_MUX is not set
+CONFIG_DEFAULT_FDT_FILE="rockchip/px30-evb.dtb"
+CONFIG_MISC_INIT_R=y
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_DISPLAY_BOARDINFO_LATE=y
+CONFIG_SPL_BOOTROM_SUPPORT=y
+# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set
+CONFIG_SPL_STACK_R=y
+# CONFIG_TPL_BANNER_PRINT is not set
+CONFIG_SPL_CRC32_SUPPORT=y
+CONFIG_SPL_ATF=y
+# CONFIG_TPL_FRAMEWORK is not set
+# CONFIG_CMD_BOOTD is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_IMI is not set
+# CONFIG_CMD_XIMG is not set
+# CONFIG_CMD_LZMADEC is not set
+# CONFIG_CMD_UNZIP is not set
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_GPT=y
+# CONFIG_CMD_LOADB is not set
+# CONFIG_CMD_LOADS is not set
+CONFIG_CMD_MMC=y
+CONFIG_CMD_USB=y
+CONFIG_CMD_USB_MASS_STORAGE=y
+# CONFIG_CMD_ITEST is not set
+# CONFIG_CMD_SETEXPR is not set
+# CONFIG_CMD_MISC is not set
+# CONFIG_SPL_DOS_PARTITION is not set
+# CONFIG_ISO_PARTITION is not set
+CONFIG_EFI_PARTITION_ENTRIES_NUMBERS=64
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_OF_LIVE=y
+CONFIG_DEFAULT_DEVICE_TREE="px30-evb"
+CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents"
+CONFIG_ENV_IS_IN_MMC=y
+CONFIG_REGMAP=y
+CONFIG_SPL_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_SPL_SYSCON=y
+CONFIG_CLK=y
+CONFIG_SPL_CLK=y
+CONFIG_FASTBOOT_BUF_ADDR=0x800800
+CONFIG_FASTBOOT_BUF_SIZE=0x04000000
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_ROCKCHIP_GPIO=y
+CONFIG_SYS_I2C_ROCKCHIP=y
+CONFIG_MISC=y
+CONFIG_ROCKCHIP_OTP=y
+CONFIG_MMC_DW=y
+CONFIG_MMC_DW_ROCKCHIP=y
+CONFIG_PHY_REALTEK=y
+CONFIG_DM_ETH=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_GMAC_ROCKCHIP=y
+CONFIG_PINCTRL=y
+CONFIG_DM_PMIC=y
+CONFIG_PMIC_RK8XX=y
+CONFIG_REGULATOR_PWM=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_REGULATOR_RK8XX=y
+CONFIG_PWM_ROCKCHIP=y
+CONFIG_RAM=y
+CONFIG_SPL_RAM=y
+CONFIG_TPL_RAM=y
+CONFIG_ROCKCHIP_SDRAM_COMMON=y
+CONFIG_DM_RESET=y
+# CONFIG_SPECIFY_CONSOLE_INDEX is not set
+# CONFIG_TPL_DM_SERIAL is not set
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_DEBUG_UART_SKIP_INIT=y
+CONFIG_SOUND=y
+CONFIG_SYSRESET=y
+CONFIG_OPTEE=y
+CONFIG_DM_THERMAL=y
+CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_GENERIC=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_DWC2_OTG=y
+CONFIG_DM_VIDEO=y
+CONFIG_DISPLAY=y
+CONFIG_LCD=y
+CONFIG_SPL_TINY_MEMSET=y
+CONFIG_TPL_TINY_MEMSET=y
+CONFIG_LZ4=y
+CONFIG_LZO=y
+CONFIG_ERRNO_STR=y
+# CONFIG_EFI_LOADER is not set
diff --git a/configs/evb-rk3128_defconfig b/configs/evb-rk3128_defconfig
index ec2f143..cb3c537 100644
--- a/configs/evb-rk3128_defconfig
+++ b/configs/evb-rk3128_defconfig
@@ -17,6 +17,7 @@
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_CMD_TIME=y
 CONFIG_DEFAULT_DEVICE_TREE="rk3128-evb"
+CONFIG_ENV_IS_IN_MMC=y
 CONFIG_REGMAP=y
 CONFIG_SYSCON=y
 CONFIG_CLK=y
diff --git a/configs/evb-rk3308_defconfig b/configs/evb-rk3308_defconfig
new file mode 100644
index 0000000..36d30df
--- /dev/null
+++ b/configs/evb-rk3308_defconfig
@@ -0,0 +1,77 @@
+CONFIG_ARM=y
+CONFIG_ARCH_ROCKCHIP=y
+CONFIG_SYS_TEXT_BASE=0x00600000
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_ROCKCHIP_RK3308=y
+CONFIG_ROCKCHIP_SPL_RESERVE_IRAM=0x0
+CONFIG_SPL_DRIVERS_MISC_SUPPORT=y
+CONFIG_TARGET_EVB_RK3308=y
+CONFIG_SPL_STACK_R_ADDR=0xc00000
+CONFIG_DEBUG_UART_BASE=0xFF0C0000
+CONFIG_DEBUG_UART_CLOCK=24000000
+CONFIG_DEBUG_UART=y
+CONFIG_ANDROID_BOOT_IMAGE=y
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_BOOTDELAY=0
+CONFIG_SYS_CONSOLE_INFO_QUIET=y
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_SPL_STACK_R=y
+# CONFIG_CMD_BDI is not set
+# CONFIG_CMD_CONSOLE is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_IMI is not set
+# CONFIG_CMD_XIMG is not set
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_GPT=y
+# CONFIG_CMD_LOADB is not set
+# CONFIG_CMD_LOADS is not set
+CONFIG_CMD_MMC=y
+CONFIG_CMD_USB=y
+CONFIG_CMD_USB_MASS_STORAGE=y
+# CONFIG_CMD_ITEST is not set
+# CONFIG_CMD_SETEXPR is not set
+# CONFIG_CMD_MISC is not set
+# CONFIG_DOS_PARTITION is not set
+# CONFIG_ISO_PARTITION is not set
+CONFIG_EFI_PARTITION_ENTRIES_NUMBERS=64
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_OF_LIVE=y
+CONFIG_DEFAULT_DEVICE_TREE="rk3308-evb"
+CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents"
+CONFIG_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_CLK=y
+# CONFIG_USB_FUNCTION_FASTBOOT is not set
+CONFIG_ROCKCHIP_GPIO=y
+CONFIG_SYS_I2C_ROCKCHIP=y
+CONFIG_MMC_DW=y
+CONFIG_MMC_DW_ROCKCHIP=y
+CONFIG_DM_ETH=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_GMAC_ROCKCHIP=y
+CONFIG_PHY=y
+CONFIG_PINCTRL=y
+CONFIG_REGULATOR_PWM=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_PWM_ROCKCHIP=y
+CONFIG_RAM=y
+CONFIG_DM_RESET=y
+CONFIG_BAUDRATE=1500000
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_DEBUG_UART_SKIP_INIT=y
+CONFIG_SYSRESET=y
+CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_GENERIC=y
+CONFIG_USB_DWC2=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_DWC2_OTG=y
+CONFIG_USB_GADGET_DOWNLOAD=y
+CONFIG_SPL_TINY_MEMSET=y
+CONFIG_LZ4=y
+CONFIG_LZO=y
+CONFIG_ERRNO_STR=y
+# CONFIG_EFI_LOADER is not set
diff --git a/configs/evb-rk3328_defconfig b/configs/evb-rk3328_defconfig
index cc6164e..a59dab4 100644
--- a/configs/evb-rk3328_defconfig
+++ b/configs/evb-rk3328_defconfig
@@ -45,7 +45,6 @@
 CONFIG_TPL_SYSCON=y
 CONFIG_CLK=y
 CONFIG_SPL_CLK=y
-CONFIG_TPL_CLK=y
 CONFIG_FASTBOOT_BUF_ADDR=0x800800
 CONFIG_FASTBOOT_FLASH=y
 CONFIG_FASTBOOT_FLASH_MMC_DEV=1
@@ -75,6 +74,7 @@
 CONFIG_DEBUG_UART_ANNOUNCE=y
 CONFIG_DEBUG_UART_SKIP_INIT=y
 CONFIG_SYSRESET=y
+# CONFIG_TPL_SYSRESET is not set
 CONFIG_USB=y
 CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_XHCI_DWC3=y
diff --git a/configs/flea3_defconfig b/configs/flea3_defconfig
index a13f609..81c2971 100644
--- a/configs/flea3_defconfig
+++ b/configs/flea3_defconfig
@@ -22,6 +22,7 @@
 CONFIG_MTDIDS_DEFAULT="nand0=mxc_nand,nor0=physmap-flash.0"
 CONFIG_MTDPARTS_DEFAULT="mtdparts=mxc_nand:50m(root1),32m(rootfb),64m(pcache),64m(app1),10m(app2),-(spool);physmap-flash.0:512k(u-boot),64k(env1),64k(env2),3776k(kernel1),3776k(kernel2)"
 CONFIG_ENV_IS_IN_FLASH=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_MXC_GPIO=y
 # CONFIG_MMC is not set
 CONFIG_MTD_NOR_FLASH=y
diff --git a/configs/gardena-smart-gateway-at91sam_defconfig b/configs/gardena-smart-gateway-at91sam_defconfig
index 4a2cc33..e695b41 100644
--- a/configs/gardena-smart-gateway-at91sam_defconfig
+++ b/configs/gardena-smart-gateway-at91sam_defconfig
@@ -52,6 +52,7 @@
 CONFIG_DEFAULT_DEVICE_TREE="at91sam9g25-gardena-smart-gateway"
 CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clocks clock-names interrupts interrupt-parent interrupts-extended dmas dma-names"
 CONFIG_ENV_IS_IN_UBI=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_ENV_UBI_PART="ubi"
 CONFIG_ENV_UBI_VOLUME="env"
 CONFIG_ENV_UBI_VOLUME_REDUND="env_r"
diff --git a/configs/gardena-smart-gateway-mt7688-ram_defconfig b/configs/gardena-smart-gateway-mt7688-ram_defconfig
index d97b95d..fc45eb3 100644
--- a/configs/gardena-smart-gateway-mt7688-ram_defconfig
+++ b/configs/gardena-smart-gateway-mt7688-ram_defconfig
@@ -40,6 +40,7 @@
 CONFIG_CMD_UBI=y
 CONFIG_DEFAULT_DEVICE_TREE="gardena-smart-gateway-mt7688"
 CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_NET_RANDOM_ETHADDR=y
 # CONFIG_DM_DEVICE_REMOVE is not set
 CONFIG_HAVE_BLOCK_DEVICE=y
diff --git a/configs/gardena-smart-gateway-mt7688_defconfig b/configs/gardena-smart-gateway-mt7688_defconfig
index 8bf69c3..7d189cf 100644
--- a/configs/gardena-smart-gateway-mt7688_defconfig
+++ b/configs/gardena-smart-gateway-mt7688_defconfig
@@ -43,6 +43,7 @@
 CONFIG_CMD_UBI=y
 CONFIG_DEFAULT_DEVICE_TREE="gardena-smart-gateway-mt7688"
 CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_NET_RANDOM_ETHADDR=y
 # CONFIG_DM_DEVICE_REMOVE is not set
 CONFIG_HAVE_BLOCK_DEVICE=y
diff --git a/configs/gazerbeam_defconfig b/configs/gazerbeam_defconfig
index 3a29bb1..f7a6b11 100644
--- a/configs/gazerbeam_defconfig
+++ b/configs/gazerbeam_defconfig
@@ -140,6 +140,7 @@
 CONFIG_OF_CONTROL=y
 CONFIG_OF_LIVE=y
 CONFIG_DEFAULT_DEVICE_TREE="gazerbeam"
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_DM=y
 CONFIG_REGMAP=y
 CONFIG_AXI=y
diff --git a/configs/gwventana_emmc_defconfig b/configs/gwventana_emmc_defconfig
index 651d3396..30f246b 100644
--- a/configs/gwventana_emmc_defconfig
+++ b/configs/gwventana_emmc_defconfig
@@ -59,6 +59,7 @@
 CONFIG_MTDPARTS_DEFAULT="mtdparts=nand:16m(uboot),1m(env),-(rootfs)"
 CONFIG_CMD_UBI=y
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_DM=y
 CONFIG_DWC_AHSATA=y
 CONFIG_SUPPORT_EMMC_RPMB=y
diff --git a/configs/gwventana_gw5904_defconfig b/configs/gwventana_gw5904_defconfig
index e8de548..7972f73 100644
--- a/configs/gwventana_gw5904_defconfig
+++ b/configs/gwventana_gw5904_defconfig
@@ -59,6 +59,7 @@
 CONFIG_MTDPARTS_DEFAULT="mtdparts=nand:16m(uboot),1m(env),-(rootfs)"
 CONFIG_CMD_UBI=y
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_DM=y
 CONFIG_DWC_AHSATA=y
 CONFIG_SUPPORT_EMMC_RPMB=y
diff --git a/configs/gwventana_nand_defconfig b/configs/gwventana_nand_defconfig
index 7cd148e..4942a74 100644
--- a/configs/gwventana_nand_defconfig
+++ b/configs/gwventana_nand_defconfig
@@ -62,6 +62,7 @@
 CONFIG_MTDPARTS_DEFAULT="mtdparts=nand:16m(uboot),1m(env),-(rootfs)"
 CONFIG_CMD_UBI=y
 CONFIG_ENV_IS_IN_NAND=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_DM=y
 CONFIG_DWC_AHSATA=y
 CONFIG_SUPPORT_EMMC_RPMB=y
diff --git a/configs/hrcon_defconfig b/configs/hrcon_defconfig
index 6afd647..bfbe372 100644
--- a/configs/hrcon_defconfig
+++ b/configs/hrcon_defconfig
@@ -119,6 +119,7 @@
 CONFIG_CMD_PING=y
 CONFIG_CMD_EXT2=y
 CONFIG_DOS_PARTITION=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_FSL_ESDHC=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
diff --git a/configs/hrcon_dh_defconfig b/configs/hrcon_dh_defconfig
index 544a98c..fdf8af9 100644
--- a/configs/hrcon_dh_defconfig
+++ b/configs/hrcon_dh_defconfig
@@ -117,6 +117,7 @@
 CONFIG_CMD_PING=y
 CONFIG_CMD_EXT2=y
 CONFIG_DOS_PARTITION=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_FSL_ESDHC=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
diff --git a/configs/ids8313_defconfig b/configs/ids8313_defconfig
index 418a4b3..241763d 100644
--- a/configs/ids8313_defconfig
+++ b/configs/ids8313_defconfig
@@ -147,6 +147,7 @@
 CONFIG_MTDIDS_DEFAULT="nor0=ff800000.flash,nand0=e1000000.flash"
 CONFIG_MTDPARTS_DEFAULT="mtdparts=ff800000.flash:7m(dum),768k(BOOT-BIN),128k(BOOT-ENV),128k(BOOT-REDENV);e1000000.flash:-(ubi)"
 CONFIG_CMD_UBI=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_BOOTCOUNT_I2C=y
 # CONFIG_MMC is not set
diff --git a/configs/igep00x0_defconfig b/configs/igep00x0_defconfig
index 04e9c95..ab0b3b7 100644
--- a/configs/igep00x0_defconfig
+++ b/configs/igep00x0_defconfig
@@ -43,6 +43,7 @@
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="omap3-igep0020"
 CONFIG_ENV_IS_IN_UBI=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_ENV_UBI_PART="UBI"
 CONFIG_ENV_UBI_VOLUME="config"
 CONFIG_ENV_UBI_VOLUME_REDUND="config_r"
diff --git a/configs/imx8mm_evk_defconfig b/configs/imx8mm_evk_defconfig
index 4cbc62f..9bf5c45 100644
--- a/configs/imx8mm_evk_defconfig
+++ b/configs/imx8mm_evk_defconfig
@@ -35,6 +35,9 @@
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_I2C=y
 CONFIG_CMD_MMC=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
 CONFIG_CMD_CACHE=y
 CONFIG_CMD_REGULATOR=y
 CONFIG_CMD_EXT2=y
@@ -62,7 +65,11 @@
 CONFIG_SUPPORT_EMMC_BOOT=y
 CONFIG_FSL_ESDHC_IMX=y
 CONFIG_PHYLIB=y
+CONFIG_PHY_ATHEROS=y
 CONFIG_DM_ETH=y
+CONFIG_PHY_GIGE=y
+CONFIG_FEC_MXC=y
+CONFIG_MII=y
 CONFIG_PINCTRL=y
 CONFIG_SPL_PINCTRL=y
 CONFIG_PINCTRL_IMX8M=y
diff --git a/configs/imx8mn_ddr4_evk_defconfig b/configs/imx8mn_ddr4_evk_defconfig
new file mode 100644
index 0000000..75dad70
--- /dev/null
+++ b/configs/imx8mn_ddr4_evk_defconfig
@@ -0,0 +1,78 @@
+CONFIG_ARM=y
+CONFIG_SPL_SYS_ICACHE_OFF=y
+CONFIG_SPL_SYS_DCACHE_OFF=y
+CONFIG_ARCH_IMX8M=y
+CONFIG_SYS_TEXT_BASE=0x40200000
+CONFIG_SPL_GPIO_SUPPORT=y
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_SYS_MALLOC_F_LEN=0x10000
+CONFIG_TARGET_IMX8MN_EVK=y
+CONFIG_SPL_MMC_SUPPORT=y
+CONFIG_SPL_SERIAL_SUPPORT=y
+CONFIG_SPL_DRIVERS_MISC_SUPPORT=y
+CONFIG_SPL=y
+CONFIG_SPL_IMX_ROMAPI_LOADADDR=0x48000000
+CONFIG_FIT=y
+CONFIG_FIT_EXTERNAL_OFFSET=0x3000
+CONFIG_SPL_LOAD_FIT=y
+CONFIG_SPL_FIT_GENERATOR="arch/arm/mach-imx/mkimage_fit_atf.sh"
+CONFIG_OF_SYSTEM_SETUP=y
+CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/imx8m/imximage-8mn-ddr4.cfg"
+CONFIG_DEFAULT_FDT_FILE="imx8mn-ddr4-evk.dtb"
+CONFIG_BOARD_LATE_INIT=y
+CONFIG_SPL_TEXT_BASE=0x912000
+CONFIG_SPL_BOARD_INIT=y
+CONFIG_SPL_BOOTROM_SUPPORT=y
+CONFIG_SPL_SEPARATE_BSS=y
+CONFIG_SPL_I2C_SUPPORT=y
+CONFIG_HUSH_PARSER=y
+CONFIG_SYS_PROMPT="u-boot=> "
+# CONFIG_CMD_EXPORTENV is not set
+# CONFIG_CMD_IMPORTENV is not set
+# CONFIG_CMD_CRC32 is not set
+CONFIG_CMD_CLK=y
+CONFIG_CMD_FUSE=y
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_CACHE=y
+CONFIG_CMD_REGULATOR=y
+CONFIG_CMD_EXT2=y
+CONFIG_CMD_EXT4=y
+CONFIG_CMD_EXT4_WRITE=y
+CONFIG_CMD_FAT=y
+CONFIG_OF_CONTROL=y
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_DEFAULT_DEVICE_TREE="imx8mn-ddr4-evk"
+CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+CONFIG_SPL_DM=y
+CONFIG_SPL_CLK_COMPOSITE_CCF=y
+CONFIG_CLK_COMPOSITE_CCF=y
+CONFIG_SPL_CLK_IMX8MN=y
+CONFIG_CLK_IMX8MN=y
+CONFIG_DM_GPIO=y
+CONFIG_MXC_GPIO=y
+CONFIG_DM_I2C=y
+CONFIG_SYS_I2C_MXC=y
+CONFIG_SYS_I2C_MXC_I2C1=y
+CONFIG_SYS_I2C_MXC_I2C2=y
+CONFIG_SYS_I2C_MXC_I2C3=y
+CONFIG_DM_MMC=y
+CONFIG_SUPPORT_EMMC_BOOT=y
+CONFIG_FSL_ESDHC_IMX=y
+CONFIG_PHYLIB=y
+CONFIG_DM_ETH=y
+CONFIG_PINCTRL=y
+CONFIG_SPL_PINCTRL=y
+CONFIG_PINCTRL_IMX8M=y
+CONFIG_DM_REGULATOR=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_DM_REGULATOR_GPIO=y
+CONFIG_MXC_UART=y
+CONFIG_SYSRESET=y
+CONFIG_SYSRESET_PSCI=y
+CONFIG_DM_THERMAL=y
+CONFIG_CLK_IMX8MN=y
+CONFIG_SPL_CLK_IMX8MN=y
diff --git a/configs/imx8qm_mek_defconfig b/configs/imx8qm_mek_defconfig
index 8978a5c..6e7d9e6 100644
--- a/configs/imx8qm_mek_defconfig
+++ b/configs/imx8qm_mek_defconfig
@@ -6,7 +6,7 @@
 CONFIG_SPL_GPIO_SUPPORT=y
 CONFIG_SPL_LIBCOMMON_SUPPORT=y
 CONFIG_SPL_LIBGENERIC_SUPPORT=y
-CONFIG_SYS_MALLOC_F_LEN=0x4000
+CONFIG_SYS_MALLOC_F_LEN=0x8000
 CONFIG_SPL_LOAD_IMX_CONTAINER=y
 CONFIG_IMX_CONTAINER_CFG="board/freescale/imx8qm_mek/uboot-container.cfg"
 CONFIG_TARGET_IMX8QM_MEK=y
diff --git a/configs/km_kirkwood_128m16_defconfig b/configs/km_kirkwood_128m16_defconfig
index 1a3dee1..c863926 100644
--- a/configs/km_kirkwood_128m16_defconfig
+++ b/configs/km_kirkwood_128m16_defconfig
@@ -31,6 +31,7 @@
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="kirkwood-km_kirkwood"
 CONFIG_ENV_IS_IN_EEPROM=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_BOOTCOUNT_RAM=y
 CONFIG_BOOTCOUNT_BOOTLIMIT=3
diff --git a/configs/km_kirkwood_defconfig b/configs/km_kirkwood_defconfig
index 79e57e7..7ac5be4 100644
--- a/configs/km_kirkwood_defconfig
+++ b/configs/km_kirkwood_defconfig
@@ -31,6 +31,7 @@
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="kirkwood-km_kirkwood"
 CONFIG_ENV_IS_IN_EEPROM=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_BOOTCOUNT_RAM=y
 CONFIG_BOOTCOUNT_BOOTLIMIT=3
diff --git a/configs/km_kirkwood_pci_defconfig b/configs/km_kirkwood_pci_defconfig
index e5eda1a..3ee8b76 100644
--- a/configs/km_kirkwood_pci_defconfig
+++ b/configs/km_kirkwood_pci_defconfig
@@ -32,6 +32,7 @@
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="kirkwood-km_kirkwood"
 CONFIG_ENV_IS_IN_EEPROM=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_BOOTCOUNT_RAM=y
 CONFIG_BOOTCOUNT_BOOTLIMIT=3
diff --git a/configs/kmcoge4_defconfig b/configs/kmcoge4_defconfig
index 7ee4ce4..3b7ee33 100644
--- a/configs/kmcoge4_defconfig
+++ b/configs/kmcoge4_defconfig
@@ -36,6 +36,7 @@
 # CONFIG_CMD_UBIFS is not set
 CONFIG_DOS_PARTITION=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_BOOTCOUNT_BOOTLIMIT=3
 # CONFIG_MMC is not set
diff --git a/configs/kmcoge5ne_defconfig b/configs/kmcoge5ne_defconfig
index faeb0c7..edd9af9 100644
--- a/configs/kmcoge5ne_defconfig
+++ b/configs/kmcoge5ne_defconfig
@@ -177,6 +177,7 @@
 CONFIG_MTDPARTS_DEFAULT="mtdparts=boot:768k(u-boot),128k(env),128k(envred),-(ubi0);app:-(ubi1);"
 CONFIG_CMD_UBI=y
 # CONFIG_CMD_UBIFS is not set
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_BOOTCOUNT_BOOTLIMIT=3
 # CONFIG_MMC is not set
diff --git a/configs/kmcoge5un_defconfig b/configs/kmcoge5un_defconfig
index aebe52d..18c9647 100644
--- a/configs/kmcoge5un_defconfig
+++ b/configs/kmcoge5un_defconfig
@@ -34,6 +34,7 @@
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="kirkwood-km_kirkwood"
 CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_BOOTCOUNT_RAM=y
 CONFIG_BOOTCOUNT_BOOTLIMIT=3
diff --git a/configs/kmeter1_defconfig b/configs/kmeter1_defconfig
index 518e9f4..eb598b8 100644
--- a/configs/kmeter1_defconfig
+++ b/configs/kmeter1_defconfig
@@ -140,6 +140,7 @@
 CONFIG_MTDPARTS_DEFAULT="mtdparts=boot:768k(u-boot),128k(env),128k(envred),-(ubi0);"
 CONFIG_CMD_UBI=y
 # CONFIG_CMD_UBIFS is not set
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_BOOTCOUNT_BOOTLIMIT=3
 # CONFIG_MMC is not set
diff --git a/configs/kmnusa_defconfig b/configs/kmnusa_defconfig
index bca8e9b..15cb7d1 100644
--- a/configs/kmnusa_defconfig
+++ b/configs/kmnusa_defconfig
@@ -34,6 +34,7 @@
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="kirkwood-km_kirkwood"
 CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_BOOTCOUNT_RAM=y
 CONFIG_BOOTCOUNT_BOOTLIMIT=3
diff --git a/configs/kmopti2_defconfig b/configs/kmopti2_defconfig
index 8231ce4..c33b256 100644
--- a/configs/kmopti2_defconfig
+++ b/configs/kmopti2_defconfig
@@ -160,6 +160,7 @@
 CONFIG_MTDPARTS_DEFAULT="mtdparts=boot:768k(u-boot),128k(env),128k(envred),-(ubi0);"
 CONFIG_CMD_UBI=y
 # CONFIG_CMD_UBIFS is not set
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_BOOTCOUNT_BOOTLIMIT=3
 # CONFIG_MMC is not set
diff --git a/configs/kmsugp1_defconfig b/configs/kmsugp1_defconfig
index 4b4dff5..afb0dc4 100644
--- a/configs/kmsugp1_defconfig
+++ b/configs/kmsugp1_defconfig
@@ -34,6 +34,7 @@
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="kirkwood-km_kirkwood"
 CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_BOOTCOUNT_RAM=y
 CONFIG_BOOTCOUNT_BOOTLIMIT=3
diff --git a/configs/kmsupx5_defconfig b/configs/kmsupx5_defconfig
index 72931a7..2f7cca5 100644
--- a/configs/kmsupx5_defconfig
+++ b/configs/kmsupx5_defconfig
@@ -140,6 +140,7 @@
 CONFIG_MTDPARTS_DEFAULT="mtdparts=boot:768k(u-boot),128k(env),128k(envred),-(ubi0);"
 CONFIG_CMD_UBI=y
 # CONFIG_CMD_UBIFS is not set
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_BOOTCOUNT_BOOTLIMIT=3
 # CONFIG_MMC is not set
diff --git a/configs/kmsuv31_defconfig b/configs/kmsuv31_defconfig
index c63f3e5..3392507 100644
--- a/configs/kmsuv31_defconfig
+++ b/configs/kmsuv31_defconfig
@@ -33,6 +33,7 @@
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="kirkwood-km_kirkwood"
 CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_BOOTCOUNT_RAM=y
 CONFIG_BOOTCOUNT_BOOTLIMIT=3
diff --git a/configs/kmtegr1_defconfig b/configs/kmtegr1_defconfig
index 14f7c2f..d8a8465 100644
--- a/configs/kmtegr1_defconfig
+++ b/configs/kmtegr1_defconfig
@@ -141,6 +141,7 @@
 CONFIG_CMD_DIAG=y
 CONFIG_CMD_UBI=y
 # CONFIG_CMD_UBIFS is not set
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_BOOTCOUNT_BOOTLIMIT=3
 # CONFIG_MMC is not set
diff --git a/configs/kmtepr2_defconfig b/configs/kmtepr2_defconfig
index 42fbbbb..8e838ea 100644
--- a/configs/kmtepr2_defconfig
+++ b/configs/kmtepr2_defconfig
@@ -160,6 +160,7 @@
 CONFIG_MTDPARTS_DEFAULT="mtdparts=boot:768k(u-boot),128k(env),128k(envred),-(ubi0);"
 CONFIG_CMD_UBI=y
 # CONFIG_CMD_UBIFS is not set
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_BOOTCOUNT_BOOTLIMIT=3
 # CONFIG_MMC is not set
diff --git a/configs/kp_imx53_defconfig b/configs/kp_imx53_defconfig
index ea6f8f6..9a4c08c 100644
--- a/configs/kp_imx53_defconfig
+++ b/configs/kp_imx53_defconfig
@@ -29,6 +29,7 @@
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="imx53-kp"
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_I2C_SET_DEFAULT_BUS_NUM=y
 CONFIG_I2C_DEFAULT_BUS_NUMBER=0x1
 CONFIG_FSL_ESDHC_IMX=y
diff --git a/configs/kp_imx6q_tpc_defconfig b/configs/kp_imx6q_tpc_defconfig
index 2484e91..72f7d21 100644
--- a/configs/kp_imx6q_tpc_defconfig
+++ b/configs/kp_imx6q_tpc_defconfig
@@ -42,6 +42,7 @@
 CONFIG_DEFAULT_DEVICE_TREE="imx6q-kp"
 CONFIG_OF_SPL_REMOVE_PROPS="interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents interrupts dmas dma-names"
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 # CONFIG_BLOCK_CACHE is not set
 CONFIG_SPL_CLK_IMX6Q=y
 CONFIG_CLK_IMX6Q=y
diff --git a/configs/m53menlo_defconfig b/configs/m53menlo_defconfig
index b366088..2f31045 100644
--- a/configs/m53menlo_defconfig
+++ b/configs/m53menlo_defconfig
@@ -56,6 +56,7 @@
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="imx53-m53menlo"
 CONFIG_ENV_IS_IN_NAND=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_DM=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_BOOTCOUNT_BOOTLIMIT=3
diff --git a/configs/mccmon6_nor_defconfig b/configs/mccmon6_nor_defconfig
index 1c54595..d46c996 100644
--- a/configs/mccmon6_nor_defconfig
+++ b/configs/mccmon6_nor_defconfig
@@ -39,6 +39,7 @@
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="imx6q-mccmon6"
 CONFIG_ENV_IS_IN_FLASH=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_I2C_SET_DEFAULT_BUS_NUM=y
 CONFIG_SYS_I2C_MXC=y
diff --git a/configs/mccmon6_sd_defconfig b/configs/mccmon6_sd_defconfig
index 80b5c5c..196c7b3 100644
--- a/configs/mccmon6_sd_defconfig
+++ b/configs/mccmon6_sd_defconfig
@@ -37,6 +37,7 @@
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="imx6q-mccmon6"
 CONFIG_ENV_IS_IN_FLASH=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_I2C_SET_DEFAULT_BUS_NUM=y
 CONFIG_SYS_I2C_MXC=y
diff --git a/configs/mgcoge3un_defconfig b/configs/mgcoge3un_defconfig
index 8c21e11..a7944bf 100644
--- a/configs/mgcoge3un_defconfig
+++ b/configs/mgcoge3un_defconfig
@@ -33,6 +33,7 @@
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="kirkwood-km_kirkwood"
 CONFIG_ENV_IS_IN_EEPROM=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_BOOTCOUNT_RAM=y
 CONFIG_BOOTCOUNT_BOOTLIMIT=3
diff --git a/configs/mpc8308_p1m_defconfig b/configs/mpc8308_p1m_defconfig
index cb0da47..68d20b1 100644
--- a/configs/mpc8308_p1m_defconfig
+++ b/configs/mpc8308_p1m_defconfig
@@ -107,6 +107,7 @@
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 # CONFIG_MMC is not set
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
diff --git a/configs/mscc_jr2_defconfig b/configs/mscc_jr2_defconfig
index f6e7785..4256a75 100644
--- a/configs/mscc_jr2_defconfig
+++ b/configs/mscc_jr2_defconfig
@@ -40,6 +40,7 @@
 CONFIG_DTB_RESELECT=y
 CONFIG_MULTI_DTB_FIT=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_CLK=y
 CONFIG_DM_GPIO=y
diff --git a/configs/mscc_luton_defconfig b/configs/mscc_luton_defconfig
index c30e52f..0b2ae58 100644
--- a/configs/mscc_luton_defconfig
+++ b/configs/mscc_luton_defconfig
@@ -43,6 +43,7 @@
 CONFIG_DTB_RESELECT=y
 CONFIG_MULTI_DTB_FIT=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_CLK=y
 CONFIG_DM_GPIO=y
diff --git a/configs/mscc_ocelot_defconfig b/configs/mscc_ocelot_defconfig
index 53f8b32..a839526 100644
--- a/configs/mscc_ocelot_defconfig
+++ b/configs/mscc_ocelot_defconfig
@@ -42,6 +42,7 @@
 CONFIG_DTB_RESELECT=y
 CONFIG_MULTI_DTB_FIT=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_CLK=y
 CONFIG_DM_GPIO=y
diff --git a/configs/mscc_serval_defconfig b/configs/mscc_serval_defconfig
index 9f58764..543d450 100644
--- a/configs/mscc_serval_defconfig
+++ b/configs/mscc_serval_defconfig
@@ -37,6 +37,7 @@
 CONFIG_DTB_RESELECT=y
 CONFIG_MULTI_DTB_FIT=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_CLK=y
 CONFIG_DM_GPIO=y
diff --git a/configs/mscc_servalt_defconfig b/configs/mscc_servalt_defconfig
index aca97a0..5ef5bd6 100644
--- a/configs/mscc_servalt_defconfig
+++ b/configs/mscc_servalt_defconfig
@@ -35,6 +35,7 @@
 CONFIG_DTB_RESELECT=y
 CONFIG_MULTI_DTB_FIT=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_CLK=y
 CONFIG_DM_GPIO=y
diff --git a/configs/mx28evk_nand_defconfig b/configs/mx28evk_nand_defconfig
index d34d50a..7f1de12 100644
--- a/configs/mx28evk_nand_defconfig
+++ b/configs/mx28evk_nand_defconfig
@@ -37,6 +37,7 @@
 CONFIG_MTDPARTS_DEFAULT="mtdparts=gpmi-nand:3m(bootloader)ro,512k(environment),512k(redundant-environment),4m(kernel),512k(fdt),8m(ramdisk),-(filesystem)"
 CONFIG_CMD_UBI=y
 CONFIG_ENV_IS_IN_NAND=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_MXS_GPIO=y
 CONFIG_MMC_MXS=y
 CONFIG_NAND=y
diff --git a/configs/mx31pdk_defconfig b/configs/mx31pdk_defconfig
index bdeb6b2..cdf0853 100644
--- a/configs/mx31pdk_defconfig
+++ b/configs/mx31pdk_defconfig
@@ -22,6 +22,7 @@
 CONFIG_CMD_PING=y
 CONFIG_CMD_DATE=y
 CONFIG_ENV_IS_IN_NAND=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_MXC_GPIO=y
 # CONFIG_MMC is not set
 CONFIG_NAND=y
diff --git a/configs/mx35pdk_defconfig b/configs/mx35pdk_defconfig
index 3d36045..59457e3 100644
--- a/configs/mx35pdk_defconfig
+++ b/configs/mx35pdk_defconfig
@@ -25,6 +25,7 @@
 CONFIG_EFI_PARTITION=y
 # CONFIG_PARTITION_UUIDS is not set
 CONFIG_ENV_IS_IN_FLASH=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_MXC_GPIO=y
 CONFIG_FSL_ESDHC_IMX=y
 CONFIG_MTD_NOR_FLASH=y
diff --git a/configs/novena_defconfig b/configs/novena_defconfig
index f9fc289..034514e 100644
--- a/configs/novena_defconfig
+++ b/configs/novena_defconfig
@@ -45,6 +45,7 @@
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="imx6q-novena"
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_DM=y
 CONFIG_DWC_AHSATA=y
 CONFIG_DM_GPIO=y
diff --git a/configs/omap5_uevm_defconfig b/configs/omap5_uevm_defconfig
index cd30110..036a367 100644
--- a/configs/omap5_uevm_defconfig
+++ b/configs/omap5_uevm_defconfig
@@ -25,6 +25,7 @@
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_SCSI_AHCI=y
 CONFIG_DFU_MMC=y
diff --git a/configs/opos6uldev_defconfig b/configs/opos6uldev_defconfig
index 352d10a..5757a10 100644
--- a/configs/opos6uldev_defconfig
+++ b/configs/opos6uldev_defconfig
@@ -62,6 +62,7 @@
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="imx6ul-opos6uldev"
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_REGMAP=y
 CONFIG_SYSCON=y
diff --git a/configs/pcm052_defconfig b/configs/pcm052_defconfig
index 736a2e7..d1c7cf9 100644
--- a/configs/pcm052_defconfig
+++ b/configs/pcm052_defconfig
@@ -24,6 +24,7 @@
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="vf610-pcm052"
 CONFIG_ENV_IS_IN_NAND=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_DM=y
 CONFIG_DM_GPIO=y
 CONFIG_VYBRID_GPIO=y
diff --git a/configs/pcm058_defconfig b/configs/pcm058_defconfig
index 879f993..3534d00 100644
--- a/configs/pcm058_defconfig
+++ b/configs/pcm058_defconfig
@@ -43,6 +43,7 @@
 CONFIG_CMD_UBI=y
 # CONFIG_SPL_PARTITION_UUIDS is not set
 CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_DM=y
 CONFIG_FSL_USDHC=y
 CONFIG_MTD=y
diff --git a/configs/pfla02_defconfig b/configs/pfla02_defconfig
index 7bd146d..9af0fa9 100644
--- a/configs/pfla02_defconfig
+++ b/configs/pfla02_defconfig
@@ -42,6 +42,8 @@
 CONFIG_MTDPARTS_DEFAULT="mtdparts=gpmi-nand:-(nand);spi2.0:1024k(bootloader),64k(env1),64k(env2),-(rescue)"
 CONFIG_CMD_UBI=y
 # CONFIG_SPL_PARTITION_UUIDS is not set
+CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_DM=y
 CONFIG_FSL_USDHC=y
 CONFIG_MTD=y
diff --git a/configs/platinum_picon_defconfig b/configs/platinum_picon_defconfig
index fc0768a..053931e 100644
--- a/configs/platinum_picon_defconfig
+++ b/configs/platinum_picon_defconfig
@@ -48,6 +48,7 @@
 CONFIG_MTDPARTS_DEFAULT="mtdparts=gpmi-nand:14M(spl),2M(uboot),512k(env1),512k(env2),495M(ubi0),14M(res0),2M(res1),512k(res2),512k(res3),-(ubi1)"
 CONFIG_CMD_UBI=y
 CONFIG_ENV_IS_IN_NAND=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_FSL_USDHC=y
 CONFIG_NAND=y
 CONFIG_NAND_MXS=y
diff --git a/configs/platinum_titanium_defconfig b/configs/platinum_titanium_defconfig
index 8ab916e..5621220 100644
--- a/configs/platinum_titanium_defconfig
+++ b/configs/platinum_titanium_defconfig
@@ -48,6 +48,7 @@
 CONFIG_MTDPARTS_DEFAULT="mtdparts=gpmi-nand:14M(spl),2M(uboot),512k(env1),512k(env2),-(ubi)"
 CONFIG_CMD_UBI=y
 CONFIG_ENV_IS_IN_NAND=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_FSL_USDHC=y
 CONFIG_NAND=y
 CONFIG_NAND_MXS=y
diff --git a/configs/pm9g45_defconfig b/configs/pm9g45_defconfig
index b5304b9..0811d1e 100644
--- a/configs/pm9g45_defconfig
+++ b/configs/pm9g45_defconfig
@@ -32,6 +32,7 @@
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="at91sam9m10g45ek"
 CONFIG_ENV_IS_IN_NAND=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_DM=y
 CONFIG_CLK=y
diff --git a/configs/rastaban_defconfig b/configs/rastaban_defconfig
index 452e761..15f75e6 100644
--- a/configs/rastaban_defconfig
+++ b/configs/rastaban_defconfig
@@ -59,6 +59,7 @@
 CONFIG_OF_EMBED=y
 CONFIG_DEFAULT_DEVICE_TREE="am335x-draco"
 CONFIG_ENV_IS_IN_NAND=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_BOOTCOUNT_ENV=y
 CONFIG_BOOTCOUNT_BOOTLIMIT=3
diff --git a/configs/roc-cc-rk3308_defconfig b/configs/roc-cc-rk3308_defconfig
new file mode 100644
index 0000000..82ebe6a
--- /dev/null
+++ b/configs/roc-cc-rk3308_defconfig
@@ -0,0 +1,77 @@
+CONFIG_ARM=y
+CONFIG_ARCH_ROCKCHIP=y
+CONFIG_SYS_TEXT_BASE=0x00600000
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_ROCKCHIP_RK3308=y
+CONFIG_ROCKCHIP_SPL_RESERVE_IRAM=0x0
+CONFIG_SPL_DRIVERS_MISC_SUPPORT=y
+CONFIG_TARGET_ROC_RK3308_CC=y
+CONFIG_SPL_STACK_R_ADDR=0xc00000
+CONFIG_DEBUG_UART_BASE=0xFF0C0000
+CONFIG_DEBUG_UART_CLOCK=24000000
+CONFIG_DEBUG_UART=y
+CONFIG_ANDROID_BOOT_IMAGE=y
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_BOOTDELAY=0
+CONFIG_SYS_CONSOLE_INFO_QUIET=y
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_SPL_STACK_R=y
+# CONFIG_CMD_BDI is not set
+# CONFIG_CMD_CONSOLE is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_IMI is not set
+# CONFIG_CMD_XIMG is not set
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_GPT=y
+# CONFIG_CMD_LOADB is not set
+# CONFIG_CMD_LOADS is not set
+CONFIG_CMD_MMC=y
+CONFIG_CMD_USB=y
+CONFIG_CMD_USB_MASS_STORAGE=y
+# CONFIG_CMD_ITEST is not set
+# CONFIG_CMD_SETEXPR is not set
+# CONFIG_CMD_MISC is not set
+# CONFIG_DOS_PARTITION is not set
+# CONFIG_ISO_PARTITION is not set
+CONFIG_EFI_PARTITION_ENTRIES_NUMBERS=64
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_OF_LIVE=y
+CONFIG_DEFAULT_DEVICE_TREE="rk3308-roc-cc"
+CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents"
+CONFIG_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_CLK=y
+# CONFIG_USB_FUNCTION_FASTBOOT is not set
+CONFIG_ROCKCHIP_GPIO=y
+CONFIG_SYS_I2C_ROCKCHIP=y
+CONFIG_MMC_DW=y
+CONFIG_MMC_DW_ROCKCHIP=y
+CONFIG_DM_ETH=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_GMAC_ROCKCHIP=y
+CONFIG_PHY=y
+CONFIG_PINCTRL=y
+CONFIG_REGULATOR_PWM=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_PWM_ROCKCHIP=y
+CONFIG_RAM=y
+CONFIG_DM_RESET=y
+CONFIG_BAUDRATE=1500000
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_DEBUG_UART_SKIP_INIT=y
+CONFIG_SYSRESET=y
+CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_GENERIC=y
+CONFIG_USB_DWC2=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_DWC2_OTG=y
+CONFIG_USB_GADGET_DOWNLOAD=y
+CONFIG_SPL_TINY_MEMSET=y
+CONFIG_LZ4=y
+CONFIG_LZO=y
+CONFIG_ERRNO_STR=y
+# CONFIG_EFI_LOADER is not set
diff --git a/configs/roc-rk3399-pc_defconfig b/configs/roc-pc-rk3399_defconfig
similarity index 100%
rename from configs/roc-rk3399-pc_defconfig
rename to configs/roc-pc-rk3399_defconfig
diff --git a/configs/rock64-rk3328_defconfig b/configs/rock64-rk3328_defconfig
index b128635..021f982 100644
--- a/configs/rock64-rk3328_defconfig
+++ b/configs/rock64-rk3328_defconfig
@@ -47,7 +47,6 @@
 CONFIG_TPL_SYSCON=y
 CONFIG_CLK=y
 CONFIG_SPL_CLK=y
-CONFIG_TPL_CLK=y
 CONFIG_FASTBOOT_BUF_ADDR=0x800800
 CONFIG_FASTBOOT_FLASH=y
 CONFIG_FASTBOOT_FLASH_MMC_DEV=1
@@ -76,6 +75,7 @@
 CONFIG_BAUDRATE=1500000
 CONFIG_DEBUG_UART_SHIFT=2
 CONFIG_SYSRESET=y
+# CONFIG_TPL_SYSRESET is not set
 CONFIG_USB=y
 CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_XHCI_DWC3=y
diff --git a/configs/rock960-rk3399_defconfig b/configs/rock960-rk3399_defconfig
index 0d6c55c..979ca0f 100644
--- a/configs/rock960-rk3399_defconfig
+++ b/configs/rock960-rk3399_defconfig
@@ -7,13 +7,15 @@
 CONFIG_DEBUG_UART_BASE=0xFF1A0000
 CONFIG_DEBUG_UART_CLOCK=24000000
 CONFIG_DEBUG_UART=y
-CONFIG_SPL_TEXT_BASE=0xff8c2000
 CONFIG_DEFAULT_FDT_FILE="rockchip/rk3399-rock960.dtb"
 # CONFIG_DISPLAY_CPUINFO is not set
 CONFIG_DISPLAY_BOARDINFO_LATE=y
 # CONFIG_SPL_RAW_IMAGE_SUPPORT is not set
 CONFIG_SPL_STACK_R=y
-CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x4000
+CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x10000
+CONFIG_SPL_ATF=y
+CONFIG_SPL_ATF_NO_PLATFORM_PARAM=y
+CONFIG_TPL=y
 CONFIG_SYS_PROMPT="rock960 => "
 CONFIG_CMD_BOOTZ=y
 CONFIG_CMD_GPT=y
@@ -55,4 +57,6 @@
 CONFIG_USB_ETHER_MCS7830=y
 CONFIG_USB_ETHER_RTL8152=y
 CONFIG_USB_ETHER_SMSC95XX=y
+CONFIG_USE_TINY_PRINTF=y
+CONFIG_SPL_TINY_MEMSET=y
 CONFIG_ERRNO_STR=y
diff --git a/configs/rockpro64-rk3399_defconfig b/configs/rockpro64-rk3399_defconfig
index 423148b..94279ed 100644
--- a/configs/rockpro64-rk3399_defconfig
+++ b/configs/rockpro64-rk3399_defconfig
@@ -2,6 +2,7 @@
 CONFIG_ARCH_ROCKCHIP=y
 CONFIG_SYS_TEXT_BASE=0x00200000
 CONFIG_ROCKCHIP_RK3399=y
+CONFIG_TARGET_ROCKPRO64_RK3399=y
 CONFIG_NR_DRAM_BANKS=1
 CONFIG_DEBUG_UART_BASE=0xFF1A0000
 CONFIG_DEBUG_UART_CLOCK=24000000
diff --git a/configs/sam9x60ek_nandflash_defconfig b/configs/sam9x60ek_nandflash_defconfig
index b31bbec..c2a0f2f 100644
--- a/configs/sam9x60ek_nandflash_defconfig
+++ b/configs/sam9x60ek_nandflash_defconfig
@@ -34,6 +34,7 @@
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="sam9x60ek"
 CONFIG_ENV_IS_IN_NAND=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_DM=y
 CONFIG_CLK=y
 CONFIG_CLK_AT91=y
diff --git a/configs/sama5d2_ptc_ek_nandflash_defconfig b/configs/sama5d2_ptc_ek_nandflash_defconfig
index 4210a52..f886c6b 100644
--- a/configs/sama5d2_ptc_ek_nandflash_defconfig
+++ b/configs/sama5d2_ptc_ek_nandflash_defconfig
@@ -34,6 +34,7 @@
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="at91-sama5d2_ptc_ek"
 CONFIG_ENV_IS_IN_NAND=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_DM=y
 CONFIG_CLK=y
 CONFIG_CLK_AT91=y
diff --git a/configs/sama5d36ek_cmp_nandflash_defconfig b/configs/sama5d36ek_cmp_nandflash_defconfig
index c7f47cc..d48f47e 100644
--- a/configs/sama5d36ek_cmp_nandflash_defconfig
+++ b/configs/sama5d36ek_cmp_nandflash_defconfig
@@ -32,6 +32,7 @@
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="sama5d36ek_cmp"
 CONFIG_ENV_IS_IN_NAND=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DM=y
 CONFIG_CLK=y
diff --git a/configs/sama5d3_xplained_nandflash_defconfig b/configs/sama5d3_xplained_nandflash_defconfig
index 8a2b01f..f9b9563 100644
--- a/configs/sama5d3_xplained_nandflash_defconfig
+++ b/configs/sama5d3_xplained_nandflash_defconfig
@@ -45,6 +45,7 @@
 CONFIG_DEFAULT_DEVICE_TREE="at91-sama5d3_xplained"
 CONFIG_OF_SPL_REMOVE_PROPS="interrupts interrupt-parent dmas dma-names"
 CONFIG_ENV_IS_IN_NAND=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_DM=y
 CONFIG_SPL_DM=y
 CONFIG_SPL_DM_SEQ_ALIAS=y
diff --git a/configs/sama5d3xek_nandflash_defconfig b/configs/sama5d3xek_nandflash_defconfig
index bf5e861..a9df518 100644
--- a/configs/sama5d3xek_nandflash_defconfig
+++ b/configs/sama5d3xek_nandflash_defconfig
@@ -44,6 +44,7 @@
 CONFIG_DEFAULT_DEVICE_TREE="sama5d36ek"
 CONFIG_OF_SPL_REMOVE_PROPS="interrupts interrupt-parent dmas dma-names"
 CONFIG_ENV_IS_IN_NAND=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DM=y
 CONFIG_SPL_DM=y
diff --git a/configs/sama5d4_xplained_nandflash_defconfig b/configs/sama5d4_xplained_nandflash_defconfig
index f8ba5d5..0f7178d 100644
--- a/configs/sama5d4_xplained_nandflash_defconfig
+++ b/configs/sama5d4_xplained_nandflash_defconfig
@@ -40,6 +40,7 @@
 CONFIG_DEFAULT_DEVICE_TREE="at91-sama5d4_xplained"
 CONFIG_OF_SPL_REMOVE_PROPS="interrupts interrupt-parent dma-names dmas"
 CONFIG_ENV_IS_IN_NAND=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_DM=y
 CONFIG_SPL_DM=y
 CONFIG_CLK=y
diff --git a/configs/sama5d4ek_nandflash_defconfig b/configs/sama5d4ek_nandflash_defconfig
index e42180a..e042f0f 100644
--- a/configs/sama5d4ek_nandflash_defconfig
+++ b/configs/sama5d4ek_nandflash_defconfig
@@ -42,6 +42,7 @@
 CONFIG_DEFAULT_DEVICE_TREE="at91-sama5d4ek"
 CONFIG_OF_SPL_REMOVE_PROPS="interrupts interrupt-parent dma-names dmas"
 CONFIG_ENV_IS_IN_NAND=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_DM=y
 CONFIG_SPL_DM=y
 CONFIG_SPL_DM_SEQ_ALIAS=y
diff --git a/configs/sbc8349_PCI_33_defconfig b/configs/sbc8349_PCI_33_defconfig
index 915ba36..c0e513d 100644
--- a/configs/sbc8349_PCI_33_defconfig
+++ b/configs/sbc8349_PCI_33_defconfig
@@ -99,6 +99,7 @@
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 # CONFIG_MMC is not set
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
diff --git a/configs/sbc8349_PCI_66_defconfig b/configs/sbc8349_PCI_66_defconfig
index c224fea..f35973f 100644
--- a/configs/sbc8349_PCI_66_defconfig
+++ b/configs/sbc8349_PCI_66_defconfig
@@ -99,6 +99,7 @@
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 # CONFIG_MMC is not set
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
diff --git a/configs/sbc8349_defconfig b/configs/sbc8349_defconfig
index 6231057..0c90e57 100644
--- a/configs/sbc8349_defconfig
+++ b/configs/sbc8349_defconfig
@@ -76,6 +76,7 @@
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 # CONFIG_MMC is not set
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
diff --git a/configs/sh7763rdp_defconfig b/configs/sh7763rdp_defconfig
index 89fdc98..74c174b 100644
--- a/configs/sh7763rdp_defconfig
+++ b/configs/sh7763rdp_defconfig
@@ -27,6 +27,7 @@
 # CONFIG_CMD_MISC is not set
 CONFIG_CMD_JFFS2=y
 CONFIG_ENV_IS_IN_FLASH=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_SYS_FLASH_CFI=y
diff --git a/configs/sksimx6_defconfig b/configs/sksimx6_defconfig
index d8739fd..7d3322d 100644
--- a/configs/sksimx6_defconfig
+++ b/configs/sksimx6_defconfig
@@ -31,6 +31,7 @@
 CONFIG_CMD_CACHE=y
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_DM=y
 CONFIG_FSL_USDHC=y
 CONFIG_PHYLIB=y
diff --git a/configs/smartweb_defconfig b/configs/smartweb_defconfig
index 9e73051..b585a9f 100644
--- a/configs/smartweb_defconfig
+++ b/configs/smartweb_defconfig
@@ -43,6 +43,7 @@
 CONFIG_OF_EMBED=y
 CONFIG_DEFAULT_DEVICE_TREE="at91sam9260-smartweb"
 CONFIG_ENV_IS_IN_NAND=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_CLK=y
 CONFIG_CLK_AT91=y
 CONFIG_DFU_NAND=y
diff --git a/configs/socfpga_sr1500_defconfig b/configs/socfpga_sr1500_defconfig
index 0d4f582..1a3b673 100644
--- a/configs/socfpga_sr1500_defconfig
+++ b/configs/socfpga_sr1500_defconfig
@@ -35,6 +35,7 @@
 # CONFIG_EFI_PARTITION is not set
 CONFIG_DEFAULT_DEVICE_TREE="socfpga_cyclone5_sr1500"
 CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_SPL_DM_SEQ_ALIAS=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_DM_GPIO=y
diff --git a/configs/socfpga_vining_fpga_defconfig b/configs/socfpga_vining_fpga_defconfig
index f7f882f..e68267f 100644
--- a/configs/socfpga_vining_fpga_defconfig
+++ b/configs/socfpga_vining_fpga_defconfig
@@ -40,6 +40,7 @@
 # CONFIG_EFI_PARTITION is not set
 CONFIG_DEFAULT_DEVICE_TREE="socfpga_cyclone5_vining_fpga"
 CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_SPL_DM_SEQ_ALIAS=y
 CONFIG_DFU_MMC=y
diff --git a/configs/socrates_defconfig b/configs/socrates_defconfig
index 2241fbb..99e65f4 100644
--- a/configs/socrates_defconfig
+++ b/configs/socrates_defconfig
@@ -36,6 +36,7 @@
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="socrates"
 CONFIG_ENV_IS_IN_FLASH=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_DM=y
 CONFIG_BLK=y
 CONFIG_DM_I2C=y
diff --git a/configs/stm32mp15_basic_defconfig b/configs/stm32mp15_basic_defconfig
index c078b5c..79d8923 100644
--- a/configs/stm32mp15_basic_defconfig
+++ b/configs/stm32mp15_basic_defconfig
@@ -54,6 +54,7 @@
 CONFIG_ENV_IS_IN_EXT4=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
 CONFIG_ENV_IS_IN_UBI=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_ENV_EXT4_INTERFACE="mmc"
 CONFIG_ENV_EXT4_DEVICE_AND_PART="0:auto"
 CONFIG_ENV_EXT4_FILE="/uboot.env"
diff --git a/configs/stm32mp15_optee_defconfig b/configs/stm32mp15_optee_defconfig
index 4f4102c..73a1c02 100644
--- a/configs/stm32mp15_optee_defconfig
+++ b/configs/stm32mp15_optee_defconfig
@@ -41,6 +41,7 @@
 CONFIG_ENV_IS_IN_EXT4=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
 CONFIG_ENV_IS_IN_UBI=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_ENV_EXT4_INTERFACE="mmc"
 CONFIG_ENV_EXT4_DEVICE_AND_PART="0:auto"
 CONFIG_ENV_EXT4_FILE="/uboot.env"
diff --git a/configs/stm32mp15_trusted_defconfig b/configs/stm32mp15_trusted_defconfig
index 8712c79..5bb0ba5 100644
--- a/configs/stm32mp15_trusted_defconfig
+++ b/configs/stm32mp15_trusted_defconfig
@@ -40,6 +40,7 @@
 CONFIG_ENV_IS_IN_EXT4=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
 CONFIG_ENV_IS_IN_UBI=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_ENV_EXT4_INTERFACE="mmc"
 CONFIG_ENV_EXT4_DEVICE_AND_PART="0:auto"
 CONFIG_ENV_EXT4_FILE="/uboot.env"
diff --git a/configs/strider_con_defconfig b/configs/strider_con_defconfig
index 6a561d0..8fb955c 100644
--- a/configs/strider_con_defconfig
+++ b/configs/strider_con_defconfig
@@ -116,6 +116,7 @@
 CONFIG_CMD_PING=y
 CONFIG_CMD_EXT2=y
 CONFIG_DOS_PARTITION=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_FSL_ESDHC=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
diff --git a/configs/strider_con_dp_defconfig b/configs/strider_con_dp_defconfig
index eb4ad77..05272bd 100644
--- a/configs/strider_con_dp_defconfig
+++ b/configs/strider_con_dp_defconfig
@@ -116,6 +116,7 @@
 CONFIG_CMD_PING=y
 CONFIG_CMD_EXT2=y
 CONFIG_DOS_PARTITION=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_FSL_ESDHC=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
diff --git a/configs/strider_cpu_defconfig b/configs/strider_cpu_defconfig
index 8a48df2..f6bb254 100644
--- a/configs/strider_cpu_defconfig
+++ b/configs/strider_cpu_defconfig
@@ -116,6 +116,7 @@
 CONFIG_CMD_PING=y
 CONFIG_CMD_EXT2=y
 CONFIG_DOS_PARTITION=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_FSL_ESDHC=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
diff --git a/configs/strider_cpu_dp_defconfig b/configs/strider_cpu_dp_defconfig
index 26793db..0b1f161 100644
--- a/configs/strider_cpu_dp_defconfig
+++ b/configs/strider_cpu_dp_defconfig
@@ -116,6 +116,7 @@
 CONFIG_CMD_PING=y
 CONFIG_CMD_EXT2=y
 CONFIG_DOS_PARTITION=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_FSL_ESDHC=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
diff --git a/configs/suvd3_defconfig b/configs/suvd3_defconfig
index bb21bde..a7782d5 100644
--- a/configs/suvd3_defconfig
+++ b/configs/suvd3_defconfig
@@ -161,6 +161,7 @@
 CONFIG_MTDPARTS_DEFAULT="mtdparts=boot:768k(u-boot),128k(env),128k(envred),-(ubi0);"
 CONFIG_CMD_UBI=y
 # CONFIG_CMD_UBIFS is not set
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_BOOTCOUNT_BOOTLIMIT=3
 # CONFIG_MMC is not set
diff --git a/configs/taurus_defconfig b/configs/taurus_defconfig
index 027ae66..fcb9030 100644
--- a/configs/taurus_defconfig
+++ b/configs/taurus_defconfig
@@ -58,6 +58,7 @@
 CONFIG_DEFAULT_DEVICE_TREE="at91sam9g20-taurus"
 CONFIG_SPL_OF_PLATDATA=y
 CONFIG_ENV_IS_IN_NAND=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_SPL_DM=y
 CONFIG_BLK=y
 CONFIG_CLK=y
diff --git a/configs/theadorable-x86-conga-qa3-e3845-pcie-x4_defconfig b/configs/theadorable-x86-conga-qa3-e3845-pcie-x4_defconfig
index 770804f..d0e6464 100644
--- a/configs/theadorable-x86-conga-qa3-e3845-pcie-x4_defconfig
+++ b/configs/theadorable-x86-conga-qa3-e3845-pcie-x4_defconfig
@@ -45,6 +45,7 @@
 CONFIG_AMIGA_PARTITION=y
 CONFIG_EFI_PARTITION=y
 CONFIG_DEFAULT_DEVICE_TREE="conga-qeval20-qa3-e3845"
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_REGMAP=y
 CONFIG_SYSCON=y
 CONFIG_CPU=y
diff --git a/configs/theadorable-x86-conga-qa3-e3845_defconfig b/configs/theadorable-x86-conga-qa3-e3845_defconfig
index d69c2a9..eccfc5a 100644
--- a/configs/theadorable-x86-conga-qa3-e3845_defconfig
+++ b/configs/theadorable-x86-conga-qa3-e3845_defconfig
@@ -44,6 +44,7 @@
 CONFIG_ISO_PARTITION=y
 CONFIG_EFI_PARTITION=y
 CONFIG_DEFAULT_DEVICE_TREE="conga-qeval20-qa3-e3845"
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_REGMAP=y
 CONFIG_SYSCON=y
 CONFIG_CPU=y
diff --git a/configs/theadorable-x86-dfi-bt700_defconfig b/configs/theadorable-x86-dfi-bt700_defconfig
index d53aff0..e0678f4 100644
--- a/configs/theadorable-x86-dfi-bt700_defconfig
+++ b/configs/theadorable-x86-dfi-bt700_defconfig
@@ -42,6 +42,7 @@
 CONFIG_ISO_PARTITION=y
 CONFIG_EFI_PARTITION=y
 CONFIG_DEFAULT_DEVICE_TREE="theadorable-x86-dfi-bt700"
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_REGMAP=y
 CONFIG_SYSCON=y
 CONFIG_CPU=y
diff --git a/configs/thuban_defconfig b/configs/thuban_defconfig
index ade82c8..682f70c 100644
--- a/configs/thuban_defconfig
+++ b/configs/thuban_defconfig
@@ -59,6 +59,7 @@
 CONFIG_OF_EMBED=y
 CONFIG_DEFAULT_DEVICE_TREE="am335x-draco"
 CONFIG_ENV_IS_IN_NAND=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_BOOTCOUNT_ENV=y
 CONFIG_BOOTCOUNT_BOOTLIMIT=3
diff --git a/configs/ti816x_evm_defconfig b/configs/ti816x_evm_defconfig
index 2a817ed..c84cf48 100644
--- a/configs/ti816x_evm_defconfig
+++ b/configs/ti816x_evm_defconfig
@@ -40,6 +40,7 @@
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="dm8168-evm"
 CONFIG_ENV_IS_IN_NAND=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_DM=y
 CONFIG_DM_GPIO=y
 CONFIG_DM_I2C=y
diff --git a/configs/tinker-s-rk3288_defconfig b/configs/tinker-s-rk3288_defconfig
new file mode 100644
index 0000000..c851a93
--- /dev/null
+++ b/configs/tinker-s-rk3288_defconfig
@@ -0,0 +1,99 @@
+CONFIG_ARM=y
+CONFIG_ARCH_ROCKCHIP=y
+CONFIG_SYS_TEXT_BASE=0x01000000
+CONFIG_SPL_GPIO_SUPPORT=y
+CONFIG_ROCKCHIP_RK3288=y
+CONFIG_TARGET_TINKER_RK3288=y
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_SPL_SIZE_LIMIT=307200
+CONFIG_SPL_STACK_R_ADDR=0x800000
+CONFIG_DEBUG_UART_BASE=0xff690000
+CONFIG_DEBUG_UART_CLOCK=24000000
+CONFIG_DEBUG_UART=y
+CONFIG_TPL_SYS_MALLOC_F_LEN=0x4000
+CONFIG_SPL_SYS_MALLOC_F_LEN=0x4000
+CONFIG_SYS_MALLOC_F_LEN=0x4000
+# CONFIG_ANDROID_BOOT_IMAGE is not set
+CONFIG_USE_PREBOOT=y
+CONFIG_SILENT_CONSOLE=y
+CONFIG_CONSOLE_MUX=y
+CONFIG_DEFAULT_FDT_FILE="rk3288-tinker-s.dtb"
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_DISPLAY_BOARDINFO_LATE=y
+CONFIG_SPL_STACK_R=y
+CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x300000
+CONFIG_SPL_I2C_SUPPORT=y
+CONFIG_SPL_POWER_SUPPORT=y
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_GPT=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_SF=y
+CONFIG_CMD_SPI=y
+CONFIG_CMD_USB=y
+CONFIG_CMD_USB_MASS_STORAGE=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_BMP=y
+CONFIG_CMD_CACHE=y
+CONFIG_CMD_TIME=y
+CONFIG_CMD_PMIC=y
+CONFIG_CMD_REGULATOR=y
+# CONFIG_SPL_DOS_PARTITION is not set
+# CONFIG_SPL_EFI_PARTITION is not set
+CONFIG_SPL_PARTITION_UUIDS=y
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_DEFAULT_DEVICE_TREE="rk3288-tinker-s"
+CONFIG_OF_SPL_REMOVE_PROPS="clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents"
+CONFIG_ENV_IS_IN_MMC=y
+CONFIG_REGMAP=y
+CONFIG_SPL_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_SPL_SYSCON=y
+# CONFIG_SPL_SIMPLE_BUS is not set
+CONFIG_CLK=y
+CONFIG_SPL_CLK=y
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
+CONFIG_ROCKCHIP_GPIO=y
+CONFIG_SYS_I2C_ROCKCHIP=y
+CONFIG_MISC=y
+CONFIG_I2C_EEPROM=y
+CONFIG_MMC_DW=y
+CONFIG_MMC_DW_ROCKCHIP=y
+CONFIG_SPI_FLASH=y
+CONFIG_SF_DEFAULT_SPEED=20000000
+CONFIG_DM_ETH=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_GMAC_ROCKCHIP=y
+CONFIG_PINCTRL=y
+CONFIG_SPL_PINCTRL=y
+CONFIG_DM_PMIC=y
+CONFIG_PMIC_RK8XX=y
+CONFIG_SPL_DM_REGULATOR=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_SPL_DM_REGULATOR_FIXED=y
+CONFIG_REGULATOR_RK8XX=y
+CONFIG_PWM_ROCKCHIP=y
+CONFIG_RAM=y
+CONFIG_SPL_RAM=y
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_SYSRESET=y
+CONFIG_USB=y
+CONFIG_USB_DWC2=y
+CONFIG_ROCKCHIP_USB2_PHY=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_MANUFACTURER="Rockchip"
+CONFIG_USB_GADGET_VENDOR_NUM=0x2207
+CONFIG_USB_GADGET_PRODUCT_NUM=0x320a
+CONFIG_USB_GADGET_DWC2_OTG=y
+CONFIG_USB_HOST_ETHER=y
+CONFIG_USB_ETHER_ASIX=y
+CONFIG_USB_ETHER_SMSC95XX=y
+CONFIG_CMD_DHRYSTONE=y
+CONFIG_ERRNO_STR=y
+CONFIG_DM_VIDEO=y
+CONFIG_DISPLAY=y
+CONFIG_VIDEO_ROCKCHIP=y
+CONFIG_DISPLAY_ROCKCHIP_HDMI=y
+CONFIG_CONSOLE_SCROLL_LINES=10
diff --git a/configs/titanium_defconfig b/configs/titanium_defconfig
index 86d1da3..cb1dd56 100644
--- a/configs/titanium_defconfig
+++ b/configs/titanium_defconfig
@@ -34,6 +34,7 @@
 CONFIG_MTDPARTS_DEFAULT="mtdparts=gpmi-nand:16M(uboot),512k(env1),512k(env2),-(ubi)"
 CONFIG_CMD_UBI=y
 CONFIG_ENV_IS_IN_NAND=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_FSL_USDHC=y
 CONFIG_NAND=y
 CONFIG_NAND_MXS=y
diff --git a/configs/tqma6dl_mba6_spi_defconfig b/configs/tqma6dl_mba6_spi_defconfig
index 9ad9ea3..f5585a4 100644
--- a/configs/tqma6dl_mba6_spi_defconfig
+++ b/configs/tqma6dl_mba6_spi_defconfig
@@ -33,6 +33,7 @@
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_FSL_USDHC=y
 CONFIG_SPI_FLASH=y
 CONFIG_SF_DEFAULT_MODE=0
diff --git a/configs/tqma6q_mba6_spi_defconfig b/configs/tqma6q_mba6_spi_defconfig
index 21bc3fa..38c662c 100644
--- a/configs/tqma6q_mba6_spi_defconfig
+++ b/configs/tqma6q_mba6_spi_defconfig
@@ -32,6 +32,7 @@
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_FSL_USDHC=y
 CONFIG_SPI_FLASH=y
 CONFIG_SF_DEFAULT_MODE=0
diff --git a/configs/tqma6s_mba6_spi_defconfig b/configs/tqma6s_mba6_spi_defconfig
index e02b8a5..85d4a22 100644
--- a/configs/tqma6s_mba6_spi_defconfig
+++ b/configs/tqma6s_mba6_spi_defconfig
@@ -33,6 +33,7 @@
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_FSL_USDHC=y
 CONFIG_SPI_FLASH=y
 CONFIG_SF_DEFAULT_MODE=0
diff --git a/configs/tricorder_defconfig b/configs/tricorder_defconfig
index 730fd7f..4487ca2 100644
--- a/configs/tricorder_defconfig
+++ b/configs/tricorder_defconfig
@@ -26,6 +26,7 @@
 CONFIG_MTDPARTS_DEFAULT="mtdparts=omap2-nand.0:128k(SPL),1m(u-boot),384k(u-boot-env1),1152k(mtdoops),384k(u-boot-env2),5m(kernel),2m(fdt),-(ubi)"
 CONFIG_CMD_UBI=y
 CONFIG_ENV_IS_IN_NAND=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 # CONFIG_NET is not set
 CONFIG_LED_STATUS=y
 CONFIG_LED_STATUS0=y
diff --git a/configs/tuge1_defconfig b/configs/tuge1_defconfig
index 22ba192..30a36ee 100644
--- a/configs/tuge1_defconfig
+++ b/configs/tuge1_defconfig
@@ -140,6 +140,7 @@
 CONFIG_MTDPARTS_DEFAULT="mtdparts=boot:768k(u-boot),128k(env),128k(envred),-(ubi0);"
 CONFIG_CMD_UBI=y
 # CONFIG_CMD_UBIFS is not set
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_BOOTCOUNT_BOOTLIMIT=3
 # CONFIG_MMC is not set
diff --git a/configs/tuxx1_defconfig b/configs/tuxx1_defconfig
index 94214a2..bccc459 100644
--- a/configs/tuxx1_defconfig
+++ b/configs/tuxx1_defconfig
@@ -162,6 +162,7 @@
 CONFIG_MTDPARTS_DEFAULT="mtdparts=boot:768k(u-boot),128k(env),128k(envred),-(ubi0);"
 CONFIG_CMD_UBI=y
 # CONFIG_CMD_UBIFS is not set
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_BOOTCOUNT_BOOTLIMIT=3
 # CONFIG_MMC is not set
diff --git a/configs/vct_platinum_defconfig b/configs/vct_platinum_defconfig
index 2a35ace..2dacc1c 100644
--- a/configs/vct_platinum_defconfig
+++ b/configs/vct_platinum_defconfig
@@ -15,6 +15,7 @@
 CONFIG_CMD_SNTP=y
 CONFIG_CMD_FAT=y
 CONFIG_ENV_IS_IN_FLASH=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_SYS_FLASH_CFI=y
diff --git a/configs/vct_platinum_small_defconfig b/configs/vct_platinum_small_defconfig
index 8a3f94a..d53fd4f 100644
--- a/configs/vct_platinum_small_defconfig
+++ b/configs/vct_platinum_small_defconfig
@@ -20,6 +20,7 @@
 # CONFIG_CMD_MISC is not set
 # CONFIG_ISO_PARTITION is not set
 CONFIG_ENV_IS_IN_FLASH=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 # CONFIG_NET is not set
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
diff --git a/configs/vct_platinumavc_defconfig b/configs/vct_platinumavc_defconfig
index 3783bec..21f04a7 100644
--- a/configs/vct_platinumavc_defconfig
+++ b/configs/vct_platinumavc_defconfig
@@ -12,6 +12,7 @@
 # CONFIG_CMD_NET is not set
 # CONFIG_ISO_PARTITION is not set
 CONFIG_ENV_IS_IN_FLASH=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_SYS_FLASH_CFI=y
diff --git a/configs/vct_platinumavc_small_defconfig b/configs/vct_platinumavc_small_defconfig
index 0d8cd07..e7b2b1b 100644
--- a/configs/vct_platinumavc_small_defconfig
+++ b/configs/vct_platinumavc_small_defconfig
@@ -20,6 +20,7 @@
 # CONFIG_CMD_MISC is not set
 # CONFIG_ISO_PARTITION is not set
 CONFIG_ENV_IS_IN_FLASH=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 # CONFIG_NET is not set
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
diff --git a/configs/vct_premium_defconfig b/configs/vct_premium_defconfig
index 2396b24..2b53b09 100644
--- a/configs/vct_premium_defconfig
+++ b/configs/vct_premium_defconfig
@@ -15,6 +15,7 @@
 CONFIG_CMD_SNTP=y
 CONFIG_CMD_FAT=y
 CONFIG_ENV_IS_IN_FLASH=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_SYS_FLASH_CFI=y
diff --git a/configs/vct_premium_small_defconfig b/configs/vct_premium_small_defconfig
index a8eba61..706799a 100644
--- a/configs/vct_premium_small_defconfig
+++ b/configs/vct_premium_small_defconfig
@@ -20,6 +20,7 @@
 # CONFIG_CMD_MISC is not set
 # CONFIG_ISO_PARTITION is not set
 CONFIG_ENV_IS_IN_FLASH=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 # CONFIG_NET is not set
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
diff --git a/configs/ve8313_defconfig b/configs/ve8313_defconfig
index 5377709..2581d3c 100644
--- a/configs/ve8313_defconfig
+++ b/configs/ve8313_defconfig
@@ -134,6 +134,7 @@
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 # CONFIG_MMC is not set
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
diff --git a/configs/vining_2000_defconfig b/configs/vining_2000_defconfig
index b007a76..0eefc76 100644
--- a/configs/vining_2000_defconfig
+++ b/configs/vining_2000_defconfig
@@ -35,6 +35,7 @@
 CONFIG_EFI_PARTITION=y
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="imx6sx-softing-vining-2000"
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DM_GPIO=y
 CONFIG_DM_MMC=y
diff --git a/configs/vme8349_defconfig b/configs/vme8349_defconfig
index f6b9eb6..8533c4d 100644
--- a/configs/vme8349_defconfig
+++ b/configs/vme8349_defconfig
@@ -108,6 +108,7 @@
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
 CONFIG_CMD_DATE=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 # CONFIG_MMC is not set
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
diff --git a/configs/wb45n_defconfig b/configs/wb45n_defconfig
index 0f22a1e..5d783d2 100644
--- a/configs/wb45n_defconfig
+++ b/configs/wb45n_defconfig
@@ -28,6 +28,7 @@
 CONFIG_CMD_PING=y
 CONFIG_CMD_MTDPARTS=y
 CONFIG_ENV_IS_IN_NAND=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_NAND=y
 # CONFIG_SYS_NAND_USE_FLASH_BBT is not set
 CONFIG_NAND_ATMEL=y
diff --git a/configs/wb50n_defconfig b/configs/wb50n_defconfig
index 3e7f03a..b976d35 100644
--- a/configs/wb50n_defconfig
+++ b/configs/wb50n_defconfig
@@ -27,6 +27,7 @@
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
 CONFIG_ENV_IS_IN_NAND=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_NAND=y
 # CONFIG_SYS_NAND_USE_FLASH_BBT is not set
diff --git a/configs/woodburn_defconfig b/configs/woodburn_defconfig
index 73b76aa..40cd074 100644
--- a/configs/woodburn_defconfig
+++ b/configs/woodburn_defconfig
@@ -27,6 +27,7 @@
 CONFIG_EFI_PARTITION=y
 # CONFIG_PARTITION_UUIDS is not set
 CONFIG_ENV_IS_IN_FLASH=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_MXC_GPIO=y
 CONFIG_FSL_ESDHC_IMX=y
 CONFIG_MTD_NOR_FLASH=y
diff --git a/configs/woodburn_sd_defconfig b/configs/woodburn_sd_defconfig
index b26b084..c4826f4 100644
--- a/configs/woodburn_sd_defconfig
+++ b/configs/woodburn_sd_defconfig
@@ -39,6 +39,7 @@
 # CONFIG_PARTITION_UUIDS is not set
 # CONFIG_SPL_PARTITION_UUIDS is not set
 CONFIG_ENV_IS_IN_FLASH=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_MXC_GPIO=y
 CONFIG_FSL_ESDHC_IMX=y
 CONFIG_MTD_NOR_FLASH=y
diff --git a/configs/work_92105_defconfig b/configs/work_92105_defconfig
index a5d76e8..1196b78 100644
--- a/configs/work_92105_defconfig
+++ b/configs/work_92105_defconfig
@@ -36,6 +36,7 @@
 CONFIG_CMD_DATE=y
 CONFIG_DOS_PARTITION=y
 CONFIG_ENV_IS_IN_NAND=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 # CONFIG_MMC is not set
 CONFIG_PHYLIB=y
 CONFIG_PHY_ADDR_ENABLE=y
diff --git a/configs/x600_defconfig b/configs/x600_defconfig
index 62ca1d6..c7c9dc4 100644
--- a/configs/x600_defconfig
+++ b/configs/x600_defconfig
@@ -44,6 +44,7 @@
 CONFIG_MTDPARTS_DEFAULT="mtdparts=nand:64M(ubi0),64M(ubi1)"
 CONFIG_CMD_UBI=y
 CONFIG_ENV_IS_IN_FLASH=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_FPGA_XILINX=y
 CONFIG_FPGA_SPARTAN3=y
diff --git a/doc/README.rockchip b/doc/README.rockchip
index d17afea..67c1400 100644
--- a/doc/README.rockchip
+++ b/doc/README.rockchip
@@ -47,6 +47,11 @@
    - EVB RK3036 - use evb-rk3036 configuration
    - Kylin - use kylin_rk3036 configuration
 
+Two RK3308 boards are supported:
+
+   - EVB RK3308 - use evb-rk3308 configuration
+   - ROC-CC-RK3308 - use roc-rk3308-cc configuration
+
 Two RK3328 board are supported:
 
    - EVB RK3328 - use evb-rk3328_defconfig
@@ -94,7 +99,20 @@
 
     (or you can use another cross compiler if you prefer)
 
+2. To build RK3308 board:
+   - Get the rkbin
+     => git clone https://github.com/rockchip-linux/rkbin.git
+
+   - Compile U-Boot
+     => cd /path/to/u-boot
+     => export BL31=/path/to/rkbin/bin/rk33/rk3308_bl31_v2.22.elf
+     => make roc-rk3308-cc_defconfig
+     => make CROSS_COMPILE=aarch64-linux-gnu- all
+     => make CROSS_COMPILE=aarch64-linux-gnu- u-boot.itb
+     => ./tools/mkimage -n rk3308 -T rksd -d /path/to/rkbin/bin/rk33/rk3308_ddr_589MHz_uart2_m0_v1.26.bin idbloader.img
+     => cat spl/u-boot-spl.bin  >> idbloader.img
+
-2. To build RK3399 board:
+3. To build RK3399 board:
 
    Option 1: Package the image with Rockchip miniloader:
 
@@ -203,6 +221,78 @@
 use the existing boot ROM code from SPL.
 
 
+Writing to the eMMC with USB on ROC-RK3308-CC
+=============================================
+For USB to work you must get your board into Bootrom mode,
+either by erasing the eMMC or short circuit the GND and D0
+on core board.
+
+Connect the board to your computer via tyepc.
+=> rkdeveloptool db rk3308_loader_v1.26.117.bin
+=> rkdeveloptool wl 0x40 idbloader.img
+=> rkdeveloptool wl 0x4000 u-boot.itb
+=> rkdeveloptool rd
+
+Then you will see the boot log from Debug UART at baud rate 1500000:
+DDR Version V1.26
+REGFB: 0x00000032, 0x00000032
+In
+589MHz
+DDR3
+ Col=10 Bank=8 Row=14 Size=256MB
+msch:1
+Returning to boot ROM...
+
+U-Boot SPL 2020.01-rc1-00225-g34b681327f (Nov 14 2019 - 10:58:04 +0800)
+Trying to boot from MMC1
+INFO:    Preloader serial: 2
+NOTICE:  BL31: v1.3(release):30f1405
+NOTICE:  BL31: Built : 17:08:28, Sep 23 2019
+INFO:    Lastlog: last=0x100000, realtime=0x102000, size=0x2000
+INFO:    ARM GICv2 driver initialized
+INFO:    Using opteed sec cpu_context!
+INFO:    boot cpu mask: 1
+INFO:    plat_rockchip_pmu_init: pd status 0xe b
+INFO:    BL31: Initializing runtime services
+WARNING: No OPTEE provided by BL2 boot loader, Booting device without OPTEE initialization. SMC`s destined for OPTEE will rK
+ERROR:   Error initializing runtime service opteed_fast
+INFO:    BL31: Preparing for EL3 exit to normal world
+INFO:    Entry point address = 0x600000
+INFO:    SPSR = 0x3c9
+
+
+U-Boot 2020.01-rc1-00225-g34b681327f (Nov 14 2019 - 10:58:47 +0800)
+
+Model: Firefly ROC-RK3308-CC board
+DRAM:  254 MiB
+MMC:   dwmmc@ff480000: 0, dwmmc@ff490000: 1
+rockchip_dnl_key_pressed read adc key val failed
+Net:   No ethernet found.
+Hit any key to stop autoboot:  0
+Card did not respond to voltage select!
+switch to partitions #0, OK
+mmc1(part 0) is current device
+Scanning mmc 1:4...
+Found /extlinux/extlinux.conf
+Retrieving file: /extlinux/extlinux.conf
+151 bytes read in 3 ms (48.8 KiB/s)
+1:      kernel-mainline
+Retrieving file: /Image
+14737920 bytes read in 377 ms (37.3 MiB/s)
+append: earlycon=uart8250,mmio32,0xff0c0000 console=ttyS2,1500000n8
+Retrieving file: /rk3308-roc-cc.dtb
+28954 bytes read in 4 ms (6.9 MiB/s)
+Flattened Device Tree blob at 01f00000
+Booting using the fdt blob at 0x1f00000
+## Loading Device Tree to 000000000df3a000, end 000000000df44119 ... OK
+
+Starting kernel ...
+[    0.000000] Booting Linux on physical CPU 0x0000000000 [0x410fd042]
+[    0.000000] Linux version 5.4.0-rc1-00040-g4dc2d508fa47-dirty (andy@B150) (gcc version 6.3.1 20170404 (Linaro GCC 6.3-209
+[    0.000000] Machine model: Firefly ROC-RK3308-CC board
+[    0.000000] earlycon: uart8250 at MMIO32 0x00000000ff0c0000 (options '')
+[    0.000000] printk: bootconsole [uart8250] enabled
+
 Booting from an SD card
 =======================
 
diff --git a/drivers/clk/imx/Kconfig b/drivers/clk/imx/Kconfig
index aae69cf..0ba8bc9 100644
--- a/drivers/clk/imx/Kconfig
+++ b/drivers/clk/imx/Kconfig
@@ -36,3 +36,19 @@
 	select CLK_CCF
 	help
 	  This enables support clock driver for i.MX8MM platforms.
+
+config SPL_CLK_IMX8MN
+	bool "SPL clock support for i.MX8MN"
+	depends on ARCH_IMX8M && SPL
+	select SPL_CLK
+	select SPL_CLK_CCF
+	help
+	  This enables SPL DM/DTS support for clock driver in i.MX8MN
+
+config CLK_IMX8MN
+	bool "Clock support for i.MX8MN"
+	depends on ARCH_IMX8M
+	select CLK
+	select CLK_CCF
+	help
+	  This enables support clock driver for i.MX8MN platforms.
diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
index 5ad7967..222c5a4 100644
--- a/drivers/clk/imx/Makefile
+++ b/drivers/clk/imx/Makefile
@@ -12,3 +12,5 @@
 endif
 obj-$(CONFIG_$(SPL_TPL_)CLK_IMX8MM) += clk-imx8mm.o clk-pll14xx.o \
 				clk-composite-8m.o
+obj-$(CONFIG_$(SPL_TPL_)CLK_IMX8MN) += clk-imx8mn.o clk-pll14xx.o \
+				clk-composite-8m.o
diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c
index f4913e7..091b092 100644
--- a/drivers/clk/imx/clk-imx8mm.c
+++ b/drivers/clk/imx/clk-imx8mm.c
@@ -80,6 +80,17 @@
 static const char *imx8mm_enet_axi_sels[] = {"clock-osc-24m", "sys_pll1_266m", "sys_pll1_800m", "sys_pll2_250m",
 					     "sys_pll2_200m", "audio_pll1_out", "video_pll1_out", "sys_pll3_out", };
 
+#ifndef CONFIG_SPL_BUILD
+static const char *imx8mm_enet_ref_sels[] = {"clock-osc-24m", "sys_pll2_125m", "sys_pll2_50m", "sys_pll2_100m",
+					     "sys_pll1_160m", "audio_pll1_out", "video_pll1_out", "clk_ext4", };
+
+static const char *imx8mm_enet_timer_sels[] = {"clock-osc-24m", "sys_pll2_100m", "audio_pll1_out", "clk_ext1", "clk_ext2",
+					       "clk_ext3", "clk_ext4", "video_pll1_out", };
+
+static const char *imx8mm_enet_phy_sels[] = {"clock-osc-24m", "sys_pll2_50m", "sys_pll2_125m", "sys_pll2_200m",
+					     "sys_pll2_500m", "video_pll1_out", "audio_pll2_out", };
+#endif
+
 static const char *imx8mm_nand_usdhc_sels[] = {"clock-osc-24m", "sys_pll1_266m", "sys_pll1_800m", "sys_pll2_200m",
 					       "sys_pll1_133m", "sys_pll3_out", "sys_pll2_250m", "audio_pll1_out", };
 
@@ -164,11 +175,30 @@
 	return __imx8mm_clk_enable(clk, 1);
 }
 
+static int imx8mm_clk_set_parent(struct clk *clk, struct clk *parent)
+{
+	struct clk *c, *cp;
+	int ret;
+
+	debug("%s(#%lu), parent: %lu\n", __func__, clk->id, parent->id);
+
+	ret = clk_get_by_id(clk->id, &c);
+	if (ret)
+		return ret;
+
+	ret = clk_get_by_id(parent->id, &cp);
+	if (ret)
+		return ret;
+
+	return clk_set_parent(c, cp);
+}
+
 static struct clk_ops imx8mm_clk_ops = {
 	.set_rate = imx8mm_clk_set_rate,
 	.get_rate = imx8mm_clk_get_rate,
 	.enable = imx8mm_clk_enable,
 	.disable = imx8mm_clk_disable,
+	.set_parent = imx8mm_clk_set_parent,
 };
 
 static int imx8mm_clk_probe(struct udevice *dev)
@@ -363,6 +393,22 @@
 	clk_dm(IMX8MM_CLK_USDHC3_ROOT,
 	       imx_clk_gate4("usdhc3_root_clk", "usdhc3", base + 0x45e0, 0));
 
+	/* clks not needed in SPL stage */
+#ifndef CONFIG_SPL_BUILD
+	clk_dm(IMX8MM_CLK_ENET_REF,
+	       imx8m_clk_composite("enet_ref", imx8mm_enet_ref_sels,
+	       base + 0xa980));
+	clk_dm(IMX8MM_CLK_ENET_TIMER,
+	       imx8m_clk_composite("enet_timer", imx8mm_enet_timer_sels,
+	       base + 0xaa00));
+	clk_dm(IMX8MM_CLK_ENET_PHY_REF,
+	       imx8m_clk_composite("enet_phy", imx8mm_enet_phy_sels,
+	       base + 0xaa80));
+	clk_dm(IMX8MM_CLK_ENET1_ROOT,
+	       imx_clk_gate4("enet1_root_clk", "enet_axi",
+	       base + 0x40a0, 0));
+#endif
+
 #ifdef CONFIG_SPL_BUILD
 	struct clk *clkp, *clkp1;
 
diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c
new file mode 100644
index 0000000..4048cc6
--- /dev/null
+++ b/drivers/clk/imx/clk-imx8mn.c
@@ -0,0 +1,415 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019 NXP
+ * Peng Fan <peng.fan@nxp.com>
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/imx-regs.h>
+#include <dt-bindings/clock/imx8mn-clock.h>
+
+#include "clk.h"
+
+#define PLL_1416X_RATE(_rate, _m, _p, _s)		\
+	{						\
+		.rate	=	(_rate),		\
+		.mdiv	=	(_m),			\
+		.pdiv	=	(_p),			\
+		.sdiv	=	(_s),			\
+	}
+
+#define PLL_1443X_RATE(_rate, _m, _p, _s, _k)		\
+	{						\
+		.rate	=	(_rate),		\
+		.mdiv	=	(_m),			\
+		.pdiv	=	(_p),			\
+		.sdiv	=	(_s),			\
+		.kdiv	=	(_k),			\
+	}
+
+static const struct imx_pll14xx_rate_table imx8mn_pll1416x_tbl[] = {
+	PLL_1416X_RATE(1800000000U, 225, 3, 0),
+	PLL_1416X_RATE(1600000000U, 200, 3, 0),
+	PLL_1416X_RATE(1200000000U, 300, 3, 1),
+	PLL_1416X_RATE(1000000000U, 250, 3, 1),
+	PLL_1416X_RATE(800000000U,  200, 3, 1),
+	PLL_1416X_RATE(750000000U,  250, 2, 2),
+	PLL_1416X_RATE(700000000U,  350, 3, 2),
+	PLL_1416X_RATE(600000000U,  300, 3, 2),
+};
+
+static const struct imx_pll14xx_rate_table imx8mn_drampll_tbl[] = {
+	PLL_1443X_RATE(650000000U, 325, 3, 2, 0),
+};
+
+static struct imx_pll14xx_clk imx8mn_dram_pll __initdata = {
+		.type = PLL_1443X,
+		.rate_table = imx8mn_drampll_tbl,
+		.rate_count = ARRAY_SIZE(imx8mn_drampll_tbl),
+};
+
+static struct imx_pll14xx_clk imx8mn_arm_pll __initdata = {
+		.type = PLL_1416X,
+		.rate_table = imx8mn_pll1416x_tbl,
+		.rate_count = ARRAY_SIZE(imx8mn_pll1416x_tbl),
+};
+
+static struct imx_pll14xx_clk imx8mn_sys_pll __initdata = {
+		.type = PLL_1416X,
+		.rate_table = imx8mn_pll1416x_tbl,
+		.rate_count = ARRAY_SIZE(imx8mn_pll1416x_tbl),
+};
+
+static const char *pll_ref_sels[] = { "clock-osc-24m", "dummy", "dummy", "dummy", };
+static const char *dram_pll_bypass_sels[] = {"dram_pll", "dram_pll_ref_sel", };
+static const char *arm_pll_bypass_sels[] = {"arm_pll", "arm_pll_ref_sel", };
+static const char *sys_pll1_bypass_sels[] = {"sys_pll1", "sys_pll1_ref_sel", };
+static const char *sys_pll2_bypass_sels[] = {"sys_pll2", "sys_pll2_ref_sel", };
+static const char *sys_pll3_bypass_sels[] = {"sys_pll3", "sys_pll3_ref_sel", };
+
+static const char *imx8mn_a53_sels[] = {"clock-osc-24m", "arm_pll_out", "sys_pll2_500m", "sys_pll2_1000m",
+					"sys_pll1_800m", "sys_pll1_400m", "audio_pll1_out", "sys_pll3_out", };
+
+static const char *imx8mn_ahb_sels[] = {"clock-osc-24m", "sys_pll1_133m", "sys_pll1_800m", "sys_pll1_400m",
+					"sys_pll2_125m", "sys_pll3_out", "audio_pll1_out", "video_pll1_out", };
+
+static const char *imx8mn_enet_axi_sels[] = {"clock-osc-24m", "sys_pll1_266m", "sys_pll1_800m", "sys_pll2_250m",
+					     "sys_pll2_200m", "audio_pll1_out", "video_pll1_out", "sys_pll3_out", };
+
+static const char *imx8mn_nand_usdhc_sels[] = {"clock-osc-24m", "sys_pll1_266m", "sys_pll1_800m", "sys_pll2_200m",
+					       "sys_pll1_133m", "sys_pll3_out", "sys_pll2_250m", "audio_pll1_out", };
+
+static const char *imx8mn_usdhc1_sels[] = {"clock-osc-24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m",
+					   "sys_pll3_out", "sys_pll1_266m", "audio_pll2_out", "sys_pll1_100m", };
+
+static const char *imx8mn_usdhc2_sels[] = {"clock-osc-24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m",
+					   "sys_pll3_out", "sys_pll1_266m", "audio_pll2_out", "sys_pll1_100m", };
+
+static const char *imx8mn_i2c1_sels[] = {"clock-osc-24m", "sys_pll1_160m", "sys_pll2_50m", "sys_pll3_out", "audio_pll1_out",
+					 "video_pll1_out", "audio_pll2_out", "sys_pll1_133m", };
+
+static const char *imx8mn_i2c2_sels[] = {"clock-osc-24m", "sys_pll1_160m", "sys_pll2_50m", "sys_pll3_out", "audio_pll1_out",
+					 "video_pll1_out", "audio_pll2_out", "sys_pll1_133m", };
+
+static const char *imx8mn_i2c3_sels[] = {"clock-osc-24m", "sys_pll1_160m", "sys_pll2_50m", "sys_pll3_out", "audio_pll1_out",
+					 "video_pll1_out", "audio_pll2_out", "sys_pll1_133m", };
+
+static const char *imx8mn_i2c4_sels[] = {"clock-osc-24m", "sys_pll1_160m", "sys_pll2_50m", "sys_pll3_out", "audio_pll1_out",
+					 "video_pll1_out", "audio_pll2_out", "sys_pll1_133m", };
+
+static const char *imx8mn_wdog_sels[] = {"clock-osc-24m", "sys_pll1_133m", "sys_pll1_160m", "vpu_pll_out",
+					 "sys_pll2_125m", "sys_pll3_out", "sys_pll1_80m", "sys_pll2_166m", };
+
+static const char *imx8mn_usdhc3_sels[] = {"clock-osc-24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m",
+					   "sys_pll3_out", "sys_pll1_266m", "audio_pll2_clk", "sys_pll1_100m", };
+
+static ulong imx8mn_clk_get_rate(struct clk *clk)
+{
+	struct clk *c;
+	int ret;
+
+	debug("%s(#%lu)\n", __func__, clk->id);
+
+	ret = clk_get_by_id(clk->id, &c);
+	if (ret)
+		return ret;
+
+	return clk_get_rate(c);
+}
+
+static ulong imx8mn_clk_set_rate(struct clk *clk, unsigned long rate)
+{
+	struct clk *c;
+	int ret;
+
+	debug("%s(#%lu), rate: %lu\n", __func__, clk->id, rate);
+
+	ret = clk_get_by_id(clk->id, &c);
+	if (ret)
+		return ret;
+
+	return clk_set_rate(c, rate);
+}
+
+static int __imx8mn_clk_enable(struct clk *clk, bool enable)
+{
+	struct clk *c;
+	int ret;
+
+	debug("%s(#%lu) en: %d\n", __func__, clk->id, enable);
+
+	ret = clk_get_by_id(clk->id, &c);
+	if (ret)
+		return ret;
+
+	if (enable)
+		ret = clk_enable(c);
+	else
+		ret = clk_disable(c);
+
+	return ret;
+}
+
+static int imx8mn_clk_disable(struct clk *clk)
+{
+	return __imx8mn_clk_enable(clk, 0);
+}
+
+static int imx8mn_clk_enable(struct clk *clk)
+{
+	return __imx8mn_clk_enable(clk, 1);
+}
+
+static struct clk_ops imx8mn_clk_ops = {
+	.set_rate = imx8mn_clk_set_rate,
+	.get_rate = imx8mn_clk_get_rate,
+	.enable = imx8mn_clk_enable,
+	.disable = imx8mn_clk_disable,
+};
+
+static int imx8mn_clk_probe(struct udevice *dev)
+{
+	void __iomem *base;
+
+	base = (void *)ANATOP_BASE_ADDR;
+
+	clk_dm(IMX8MN_DRAM_PLL_REF_SEL,
+	       imx_clk_mux("dram_pll_ref_sel", base + 0x50, 0, 2,
+			   pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
+	clk_dm(IMX8MN_ARM_PLL_REF_SEL,
+	       imx_clk_mux("arm_pll_ref_sel", base + 0x84, 0, 2,
+			   pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
+	clk_dm(IMX8MN_SYS_PLL1_REF_SEL,
+	       imx_clk_mux("sys_pll1_ref_sel", base + 0x94, 0, 2,
+			   pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
+	clk_dm(IMX8MN_SYS_PLL2_REF_SEL,
+	       imx_clk_mux("sys_pll2_ref_sel", base + 0x104, 0, 2,
+			   pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
+	clk_dm(IMX8MN_SYS_PLL3_REF_SEL,
+	       imx_clk_mux("sys_pll3_ref_sel", base + 0x114, 0, 2,
+			   pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
+
+	clk_dm(IMX8MN_DRAM_PLL,
+	       imx_clk_pll14xx("dram_pll", "dram_pll_ref_sel",
+			       base + 0x50, &imx8mn_dram_pll));
+	clk_dm(IMX8MN_ARM_PLL,
+	       imx_clk_pll14xx("arm_pll", "arm_pll_ref_sel",
+			       base + 0x84, &imx8mn_arm_pll));
+	clk_dm(IMX8MN_SYS_PLL1,
+	       imx_clk_pll14xx("sys_pll1", "sys_pll1_ref_sel",
+			       base + 0x94, &imx8mn_sys_pll));
+	clk_dm(IMX8MN_SYS_PLL2,
+	       imx_clk_pll14xx("sys_pll2", "sys_pll2_ref_sel",
+			       base + 0x104, &imx8mn_sys_pll));
+	clk_dm(IMX8MN_SYS_PLL3,
+	       imx_clk_pll14xx("sys_pll3", "sys_pll3_ref_sel",
+			       base + 0x114, &imx8mn_sys_pll));
+
+	/* PLL bypass out */
+	clk_dm(IMX8MN_DRAM_PLL_BYPASS,
+	       imx_clk_mux_flags("dram_pll_bypass", base + 0x50, 4, 1,
+				 dram_pll_bypass_sels,
+				 ARRAY_SIZE(dram_pll_bypass_sels),
+				 CLK_SET_RATE_PARENT));
+	clk_dm(IMX8MN_ARM_PLL_BYPASS,
+	       imx_clk_mux_flags("arm_pll_bypass", base + 0x84, 4, 1,
+				 arm_pll_bypass_sels,
+				 ARRAY_SIZE(arm_pll_bypass_sels),
+				 CLK_SET_RATE_PARENT));
+	clk_dm(IMX8MN_SYS_PLL1_BYPASS,
+	       imx_clk_mux_flags("sys_pll1_bypass", base + 0x94, 4, 1,
+				 sys_pll1_bypass_sels,
+				 ARRAY_SIZE(sys_pll1_bypass_sels),
+				 CLK_SET_RATE_PARENT));
+	clk_dm(IMX8MN_SYS_PLL2_BYPASS,
+	       imx_clk_mux_flags("sys_pll2_bypass", base + 0x104, 4, 1,
+				 sys_pll2_bypass_sels,
+				 ARRAY_SIZE(sys_pll2_bypass_sels),
+				 CLK_SET_RATE_PARENT));
+	clk_dm(IMX8MN_SYS_PLL3_BYPASS,
+	       imx_clk_mux_flags("sys_pll3_bypass", base + 0x114, 4, 1,
+				 sys_pll3_bypass_sels,
+				 ARRAY_SIZE(sys_pll3_bypass_sels),
+				 CLK_SET_RATE_PARENT));
+
+	/* PLL out gate */
+	clk_dm(IMX8MN_DRAM_PLL_OUT,
+	       imx_clk_gate("dram_pll_out", "dram_pll_bypass",
+			    base + 0x50, 13));
+	clk_dm(IMX8MN_ARM_PLL_OUT,
+	       imx_clk_gate("arm_pll_out", "arm_pll_bypass",
+			    base + 0x84, 11));
+	clk_dm(IMX8MN_SYS_PLL1_OUT,
+	       imx_clk_gate("sys_pll1_out", "sys_pll1_bypass",
+			    base + 0x94, 11));
+	clk_dm(IMX8MN_SYS_PLL2_OUT,
+	       imx_clk_gate("sys_pll2_out", "sys_pll2_bypass",
+			    base + 0x104, 11));
+	clk_dm(IMX8MN_SYS_PLL3_OUT,
+	       imx_clk_gate("sys_pll3_out", "sys_pll3_bypass",
+			    base + 0x114, 11));
+
+	/* SYS PLL fixed output */
+	clk_dm(IMX8MN_SYS_PLL1_40M,
+	       imx_clk_fixed_factor("sys_pll1_40m", "sys_pll1_out", 1, 20));
+	clk_dm(IMX8MN_SYS_PLL1_80M,
+	       imx_clk_fixed_factor("sys_pll1_80m", "sys_pll1_out", 1, 10));
+	clk_dm(IMX8MN_SYS_PLL1_100M,
+	       imx_clk_fixed_factor("sys_pll1_100m", "sys_pll1_out", 1, 8));
+	clk_dm(IMX8MN_SYS_PLL1_133M,
+	       imx_clk_fixed_factor("sys_pll1_133m", "sys_pll1_out", 1, 6));
+	clk_dm(IMX8MN_SYS_PLL1_160M,
+	       imx_clk_fixed_factor("sys_pll1_160m", "sys_pll1_out", 1, 5));
+	clk_dm(IMX8MN_SYS_PLL1_200M,
+	       imx_clk_fixed_factor("sys_pll1_200m", "sys_pll1_out", 1, 4));
+	clk_dm(IMX8MN_SYS_PLL1_266M,
+	       imx_clk_fixed_factor("sys_pll1_266m", "sys_pll1_out", 1, 3));
+	clk_dm(IMX8MN_SYS_PLL1_400M,
+	       imx_clk_fixed_factor("sys_pll1_400m", "sys_pll1_out", 1, 2));
+	clk_dm(IMX8MN_SYS_PLL1_800M,
+	       imx_clk_fixed_factor("sys_pll1_800m", "sys_pll1_out", 1, 1));
+
+	clk_dm(IMX8MN_SYS_PLL2_50M,
+	       imx_clk_fixed_factor("sys_pll2_50m", "sys_pll2_out", 1, 20));
+	clk_dm(IMX8MN_SYS_PLL2_100M,
+	       imx_clk_fixed_factor("sys_pll2_100m", "sys_pll2_out", 1, 10));
+	clk_dm(IMX8MN_SYS_PLL2_125M,
+	       imx_clk_fixed_factor("sys_pll2_125m", "sys_pll2_out", 1, 8));
+	clk_dm(IMX8MN_SYS_PLL2_166M,
+	       imx_clk_fixed_factor("sys_pll2_166m", "sys_pll2_out", 1, 6));
+	clk_dm(IMX8MN_SYS_PLL2_200M,
+	       imx_clk_fixed_factor("sys_pll2_200m", "sys_pll2_out", 1, 5));
+	clk_dm(IMX8MN_SYS_PLL2_250M,
+	       imx_clk_fixed_factor("sys_pll2_250m", "sys_pll2_out", 1, 4));
+	clk_dm(IMX8MN_SYS_PLL2_333M,
+	       imx_clk_fixed_factor("sys_pll2_333m", "sys_pll2_out", 1, 3));
+	clk_dm(IMX8MN_SYS_PLL2_500M,
+	       imx_clk_fixed_factor("sys_pll2_500m", "sys_pll2_out", 1, 2));
+	clk_dm(IMX8MN_SYS_PLL2_1000M,
+	       imx_clk_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1));
+
+	base = dev_read_addr_ptr(dev);
+	if (base == (void *)FDT_ADDR_T_NONE)
+		return -EINVAL;
+
+	clk_dm(IMX8MN_CLK_A53_SRC,
+	       imx_clk_mux2("arm_a53_src", base + 0x8000, 24, 3,
+			    imx8mn_a53_sels, ARRAY_SIZE(imx8mn_a53_sels)));
+	clk_dm(IMX8MN_CLK_A53_CG,
+	       imx_clk_gate3("arm_a53_cg", "arm_a53_src", base + 0x8000, 28));
+	clk_dm(IMX8MN_CLK_A53_DIV,
+	       imx_clk_divider2("arm_a53_div", "arm_a53_cg",
+				base + 0x8000, 0, 3));
+
+	clk_dm(IMX8MN_CLK_AHB,
+	       imx8m_clk_composite_critical("ahb", imx8mn_ahb_sels,
+					    base + 0x9000));
+	clk_dm(IMX8MN_CLK_IPG_ROOT,
+	       imx_clk_divider2("ipg_root", "ahb", base + 0x9080, 0, 1));
+
+	clk_dm(IMX8MN_CLK_ENET_AXI,
+	       imx8m_clk_composite("enet_axi", imx8mn_enet_axi_sels,
+				   base + 0x8880));
+	clk_dm(IMX8MN_CLK_NAND_USDHC_BUS,
+	       imx8m_clk_composite_critical("nand_usdhc_bus",
+					    imx8mn_nand_usdhc_sels,
+					    base + 0x8900));
+
+	/* IP */
+	clk_dm(IMX8MN_CLK_USDHC1,
+	       imx8m_clk_composite("usdhc1", imx8mn_usdhc1_sels,
+				   base + 0xac00));
+	clk_dm(IMX8MN_CLK_USDHC2,
+	       imx8m_clk_composite("usdhc2", imx8mn_usdhc2_sels,
+				   base + 0xac80));
+	clk_dm(IMX8MN_CLK_I2C1,
+	       imx8m_clk_composite("i2c1", imx8mn_i2c1_sels, base + 0xad00));
+	clk_dm(IMX8MN_CLK_I2C2,
+	       imx8m_clk_composite("i2c2", imx8mn_i2c2_sels, base + 0xad80));
+	clk_dm(IMX8MN_CLK_I2C3,
+	       imx8m_clk_composite("i2c3", imx8mn_i2c3_sels, base + 0xae00));
+	clk_dm(IMX8MN_CLK_I2C4,
+	       imx8m_clk_composite("i2c4", imx8mn_i2c4_sels, base + 0xae80));
+	clk_dm(IMX8MN_CLK_WDOG,
+	       imx8m_clk_composite("wdog", imx8mn_wdog_sels, base + 0xb900));
+	clk_dm(IMX8MN_CLK_USDHC3,
+	       imx8m_clk_composite("usdhc3", imx8mn_usdhc3_sels,
+				   base + 0xbc80));
+
+	clk_dm(IMX8MN_CLK_I2C1_ROOT,
+	       imx_clk_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0));
+	clk_dm(IMX8MN_CLK_I2C2_ROOT,
+	       imx_clk_gate4("i2c2_root_clk", "i2c2", base + 0x4180, 0));
+	clk_dm(IMX8MN_CLK_I2C3_ROOT,
+	       imx_clk_gate4("i2c3_root_clk", "i2c3", base + 0x4190, 0));
+	clk_dm(IMX8MN_CLK_I2C4_ROOT,
+	       imx_clk_gate4("i2c4_root_clk", "i2c4", base + 0x41a0, 0));
+	clk_dm(IMX8MN_CLK_OCOTP_ROOT,
+	       imx_clk_gate4("ocotp_root_clk", "ipg_root", base + 0x4220, 0));
+	clk_dm(IMX8MN_CLK_USDHC1_ROOT,
+	       imx_clk_gate4("usdhc1_root_clk", "usdhc1", base + 0x4510, 0));
+	clk_dm(IMX8MN_CLK_USDHC2_ROOT,
+	       imx_clk_gate4("usdhc2_root_clk", "usdhc2", base + 0x4520, 0));
+	clk_dm(IMX8MN_CLK_WDOG1_ROOT,
+	       imx_clk_gate4("wdog1_root_clk", "wdog", base + 0x4530, 0));
+	clk_dm(IMX8MN_CLK_WDOG2_ROOT,
+	       imx_clk_gate4("wdog2_root_clk", "wdog", base + 0x4540, 0));
+	clk_dm(IMX8MN_CLK_WDOG3_ROOT,
+	       imx_clk_gate4("wdog3_root_clk", "wdog", base + 0x4550, 0));
+	clk_dm(IMX8MN_CLK_USDHC3_ROOT,
+	       imx_clk_gate4("usdhc3_root_clk", "usdhc3", base + 0x45e0, 0));
+
+#ifdef CONFIG_SPL_BUILD
+	struct clk *clkp, *clkp1;
+
+	clk_get_by_id(IMX8MN_CLK_WDOG1_ROOT, &clkp);
+	clk_enable(clkp);
+	clk_get_by_id(IMX8MN_CLK_WDOG2_ROOT, &clkp);
+	clk_enable(clkp);
+	clk_get_by_id(IMX8MN_CLK_WDOG3_ROOT, &clkp);
+	clk_enable(clkp);
+
+	/* Configure SYS_PLL3 to 600MHz */
+	clk_get_by_id(IMX8MN_SYS_PLL3, &clkp);
+	clk_set_rate(clkp, 600000000UL);
+	clk_enable(clkp);
+
+	/* Configure ARM to sys_pll2_500m */
+	clk_get_by_id(IMX8MN_CLK_A53_SRC, &clkp);
+	clk_get_by_id(IMX8MN_SYS_PLL2_OUT, &clkp1);
+	clk_enable(clkp1);
+	clk_get_by_id(IMX8MN_SYS_PLL2_500M, &clkp1);
+	clk_set_parent(clkp, clkp1);
+
+	/* Configure ARM PLL to 1.2GHz */
+	clk_get_by_id(IMX8MN_ARM_PLL, &clkp1);
+	clk_set_rate(clkp1, 1200000000UL);
+	clk_get_by_id(IMX8MN_ARM_PLL_OUT, &clkp1);
+	clk_enable(clkp1);
+	clk_set_parent(clkp, clkp1);
+
+	/* Configure DIV to 1.2GHz */
+	clk_get_by_id(IMX8MN_CLK_A53_DIV, &clkp1);
+	clk_set_rate(clkp1, 1200000000UL);
+#endif
+
+	return 0;
+}
+
+static const struct udevice_id imx8mn_clk_ids[] = {
+	{ .compatible = "fsl,imx8mn-ccm" },
+	{ },
+};
+
+U_BOOT_DRIVER(imx8mn_clk) = {
+	.name = "clk_imx8mn",
+	.id = UCLASS_CLK,
+	.of_match = imx8mn_clk_ids,
+	.ops = &imx8mn_clk_ops,
+	.probe = imx8mn_clk_probe,
+	.flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
index 41cfb7a..4cfcf83 100644
--- a/drivers/clk/rockchip/Makefile
+++ b/drivers/clk/rockchip/Makefile
@@ -3,11 +3,14 @@
 # Copyright (c) 2017 Rockchip Electronics Co., Ltd
 #
 
+obj-y += clk_pll.o
+obj-$(CONFIG_ROCKCHIP_PX30) += clk_px30.o
 obj-$(CONFIG_ROCKCHIP_RK3036) += clk_rk3036.o
 obj-$(CONFIG_ROCKCHIP_RK3128) += clk_rk3128.o
 obj-$(CONFIG_ROCKCHIP_RK3188) += clk_rk3188.o
 obj-$(CONFIG_ROCKCHIP_RK322X) += clk_rk322x.o
 obj-$(CONFIG_ROCKCHIP_RK3288) += clk_rk3288.o
+obj-$(CONFIG_ROCKCHIP_RK3308) += clk_rk3308.o
 obj-$(CONFIG_ROCKCHIP_RK3328) += clk_rk3328.o
 obj-$(CONFIG_ROCKCHIP_RK3368) += clk_rk3368.o
 obj-$(CONFIG_ROCKCHIP_RK3399) += clk_rk3399.o
diff --git a/drivers/clk/rockchip/clk_pll.c b/drivers/clk/rockchip/clk_pll.c
new file mode 100644
index 0000000..c4b4531
--- /dev/null
+++ b/drivers/clk/rockchip/clk_pll.c
@@ -0,0 +1,360 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * (C) Copyright 2018-2019 Rockchip Electronics Co., Ltd
+ */
+ #include <common.h>
+#include <bitfield.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <errno.h>
+#include <asm/io.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/hardware.h>
+#include <div64.h>
+
+static struct rockchip_pll_rate_table rockchip_auto_table;
+
+#define PLL_MODE_MASK				0x3
+#define PLL_RK3328_MODE_MASK			0x1
+
+#define RK3036_PLLCON0_FBDIV_MASK		0xfff
+#define RK3036_PLLCON0_FBDIV_SHIFT		0
+#define RK3036_PLLCON0_POSTDIV1_MASK		0x7 << 12
+#define RK3036_PLLCON0_POSTDIV1_SHIFT		12
+#define RK3036_PLLCON1_REFDIV_MASK		0x3f
+#define RK3036_PLLCON1_REFDIV_SHIFT		0
+#define RK3036_PLLCON1_POSTDIV2_MASK		0x7 << 6
+#define RK3036_PLLCON1_POSTDIV2_SHIFT		6
+#define RK3036_PLLCON1_DSMPD_MASK		0x1 << 12
+#define RK3036_PLLCON1_DSMPD_SHIFT		12
+#define RK3036_PLLCON2_FRAC_MASK		0xffffff
+#define RK3036_PLLCON2_FRAC_SHIFT		0
+#define RK3036_PLLCON1_PWRDOWN_SHIT		13
+
+#define MHZ		1000000
+#define KHZ		1000
+enum {
+	OSC_HZ			= 24 * 1000000,
+	VCO_MAX_HZ	= 3200U * 1000000,
+	VCO_MIN_HZ	= 800 * 1000000,
+	OUTPUT_MAX_HZ	= 3200U * 1000000,
+	OUTPUT_MIN_HZ	= 24 * 1000000,
+};
+
+#define MIN_FOUTVCO_FREQ	(800 * MHZ)
+#define MAX_FOUTVCO_FREQ	(2000 * MHZ)
+
+int gcd(int m, int n)
+{
+	int t;
+
+	while (m > 0) {
+		if (n > m) {
+			t = m;
+			m = n;
+			n = t;
+		} /* swap */
+		m -= n;
+	}
+	return n;
+}
+
+/*
+ * How to calculate the PLL(from TRM V0.3 Part 1 Page 63):
+ * Formulas also embedded within the Fractional PLL Verilog model:
+ * If DSMPD = 1 (DSM is disabled, "integer mode")
+ * FOUTVCO = FREF / REFDIV * FBDIV
+ * FOUTPOSTDIV = FOUTVCO / POSTDIV1 / POSTDIV2
+ * Where:
+ * FOUTVCO = Fractional PLL non-divided output frequency
+ * FOUTPOSTDIV = Fractional PLL divided output frequency
+ *               (output of second post divider)
+ * FREF = Fractional PLL input reference frequency, (the OSC_HZ 24MHz input)
+ * REFDIV = Fractional PLL input reference clock divider
+ * FBDIV = Integer value programmed into feedback divide
+ *
+ */
+
+static int rockchip_pll_clk_set_postdiv(ulong fout_hz,
+					u32 *postdiv1,
+					u32 *postdiv2,
+					u32 *foutvco)
+{
+	ulong freq;
+
+	if (fout_hz < MIN_FOUTVCO_FREQ) {
+		for (*postdiv1 = 1; *postdiv1 <= 7; (*postdiv1)++) {
+			for (*postdiv2 = 1; *postdiv2 <= 7; (*postdiv2)++) {
+				freq = fout_hz * (*postdiv1) * (*postdiv2);
+				if (freq >= MIN_FOUTVCO_FREQ &&
+				    freq <= MAX_FOUTVCO_FREQ) {
+					*foutvco = freq;
+					return 0;
+				}
+			}
+		}
+		printf("Can't FIND postdiv1/2 to make fout=%lu in 800~2000M.\n",
+		       fout_hz);
+	} else {
+		*postdiv1 = 1;
+		*postdiv2 = 1;
+	}
+	return 0;
+}
+
+static struct rockchip_pll_rate_table *
+rockchip_pll_clk_set_by_auto(ulong fin_hz,
+			     ulong fout_hz)
+{
+	struct rockchip_pll_rate_table *rate_table = &rockchip_auto_table;
+	/* FIXME set postdiv1/2 always 1*/
+	u32 foutvco = fout_hz;
+	ulong fin_64, frac_64;
+	u32 f_frac, postdiv1, postdiv2;
+	ulong clk_gcd = 0;
+
+	if (fin_hz == 0 || fout_hz == 0 || fout_hz == fin_hz)
+		return NULL;
+
+	rockchip_pll_clk_set_postdiv(fout_hz, &postdiv1, &postdiv2, &foutvco);
+	rate_table->postdiv1 = postdiv1;
+	rate_table->postdiv2 = postdiv2;
+	rate_table->dsmpd = 1;
+
+	if (fin_hz / MHZ * MHZ == fin_hz && fout_hz / MHZ * MHZ == fout_hz) {
+		fin_hz /= MHZ;
+		foutvco /= MHZ;
+		clk_gcd = gcd(fin_hz, foutvco);
+		rate_table->refdiv = fin_hz / clk_gcd;
+		rate_table->fbdiv = foutvco / clk_gcd;
+
+		rate_table->frac = 0;
+
+		debug("fin = %ld, fout = %ld, clk_gcd = %ld,\n",
+		      fin_hz, fout_hz, clk_gcd);
+		debug("refdiv= %d,fbdiv= %d,postdiv1= %d,postdiv2= %d\n",
+		      rate_table->refdiv,
+		      rate_table->fbdiv, rate_table->postdiv1,
+		      rate_table->postdiv2);
+	} else {
+		debug("frac div,fin_hz = %ld,fout_hz = %ld\n",
+		      fin_hz, fout_hz);
+		debug("frac get postdiv1 = %d,  postdiv2 = %d, foutvco = %d\n",
+		      rate_table->postdiv1, rate_table->postdiv2, foutvco);
+		clk_gcd = gcd(fin_hz / MHZ, foutvco / MHZ);
+		rate_table->refdiv = fin_hz / MHZ / clk_gcd;
+		rate_table->fbdiv = foutvco / MHZ / clk_gcd;
+		debug("frac get refdiv = %d,  fbdiv = %d\n",
+		      rate_table->refdiv, rate_table->fbdiv);
+
+		rate_table->frac = 0;
+
+		f_frac = (foutvco % MHZ);
+		fin_64 = fin_hz;
+		fin_64 = fin_64 / rate_table->refdiv;
+		frac_64 = f_frac << 24;
+		frac_64 = frac_64 / fin_64;
+		rate_table->frac = frac_64;
+		if (rate_table->frac > 0)
+			rate_table->dsmpd = 0;
+		debug("frac = %x\n", rate_table->frac);
+	}
+	return rate_table;
+}
+
+static const struct rockchip_pll_rate_table *
+rockchip_get_pll_settings(struct rockchip_pll_clock *pll, ulong rate)
+{
+	struct rockchip_pll_rate_table  *rate_table = pll->rate_table;
+
+	while (rate_table->rate) {
+		if (rate_table->rate == rate)
+			break;
+		rate_table++;
+	}
+	if (rate_table->rate != rate)
+		return rockchip_pll_clk_set_by_auto(24 * MHZ, rate);
+	else
+		return rate_table;
+}
+
+static int rk3036_pll_set_rate(struct rockchip_pll_clock *pll,
+			       void __iomem *base, ulong pll_id,
+			       ulong drate)
+{
+	const struct rockchip_pll_rate_table *rate;
+
+	rate = rockchip_get_pll_settings(pll, drate);
+	if (!rate) {
+		printf("%s unsupport rate\n", __func__);
+		return -EINVAL;
+	}
+
+	debug("%s: rate settings for %lu fbdiv: %d, postdiv1: %d, refdiv: %d\n",
+	      __func__, rate->rate, rate->fbdiv, rate->postdiv1, rate->refdiv);
+	debug("%s: rate settings for %lu postdiv2: %d, dsmpd: %d, frac: %d\n",
+	      __func__, rate->rate, rate->postdiv2, rate->dsmpd, rate->frac);
+
+	/*
+	 * When power on or changing PLL setting,
+	 * we must force PLL into slow mode to ensure output stable clock.
+	 */
+	rk_clrsetreg(base + pll->mode_offset,
+		     pll->mode_mask << pll->mode_shift,
+		     RKCLK_PLL_MODE_SLOW << pll->mode_shift);
+
+	/* Power down */
+	rk_setreg(base + pll->con_offset + 0x4,
+		  1 << RK3036_PLLCON1_PWRDOWN_SHIT);
+
+	rk_clrsetreg(base + pll->con_offset,
+		     (RK3036_PLLCON0_POSTDIV1_MASK |
+		     RK3036_PLLCON0_FBDIV_MASK),
+		     (rate->postdiv1 << RK3036_PLLCON0_POSTDIV1_SHIFT) |
+		     rate->fbdiv);
+	rk_clrsetreg(base + pll->con_offset + 0x4,
+		     (RK3036_PLLCON1_POSTDIV2_MASK |
+		     RK3036_PLLCON1_REFDIV_MASK),
+		     (rate->postdiv2 << RK3036_PLLCON1_POSTDIV2_SHIFT |
+		     rate->refdiv << RK3036_PLLCON1_REFDIV_SHIFT));
+	if (!rate->dsmpd) {
+		rk_clrsetreg(base + pll->con_offset + 0x4,
+			     RK3036_PLLCON1_DSMPD_MASK,
+			     rate->dsmpd << RK3036_PLLCON1_DSMPD_SHIFT);
+		writel((readl(base + pll->con_offset + 0x8) &
+			(~RK3036_PLLCON2_FRAC_MASK)) |
+			    (rate->frac << RK3036_PLLCON2_FRAC_SHIFT),
+			    base + pll->con_offset + 0x8);
+	}
+
+	/* Power Up */
+	rk_clrreg(base + pll->con_offset + 0x4,
+		  1 << RK3036_PLLCON1_PWRDOWN_SHIT);
+
+	/* waiting for pll lock */
+	while (!(readl(base + pll->con_offset + 0x4) & (1 << pll->lock_shift)))
+		udelay(1);
+
+	rk_clrsetreg(base + pll->mode_offset, pll->mode_mask << pll->mode_shift,
+		     RKCLK_PLL_MODE_NORMAL << pll->mode_shift);
+	debug("PLL at %p: con0=%x con1= %x con2= %x mode= %x\n",
+	      pll, readl(base + pll->con_offset),
+	      readl(base + pll->con_offset + 0x4),
+	      readl(base + pll->con_offset + 0x8),
+	      readl(base + pll->mode_offset));
+
+	return 0;
+}
+
+static ulong rk3036_pll_get_rate(struct rockchip_pll_clock *pll,
+				 void __iomem *base, ulong pll_id)
+{
+	u32 refdiv, fbdiv, postdiv1, postdiv2, dsmpd, frac;
+	u32 con = 0, shift, mask;
+	ulong rate;
+
+	con = readl(base + pll->mode_offset);
+	shift = pll->mode_shift;
+	mask = pll->mode_mask << shift;
+
+	switch ((con & mask) >> shift) {
+	case RKCLK_PLL_MODE_SLOW:
+		return OSC_HZ;
+	case RKCLK_PLL_MODE_NORMAL:
+		/* normal mode */
+		con = readl(base + pll->con_offset);
+		postdiv1 = (con & RK3036_PLLCON0_POSTDIV1_MASK) >>
+			   RK3036_PLLCON0_POSTDIV1_SHIFT;
+		fbdiv = (con & RK3036_PLLCON0_FBDIV_MASK) >>
+			RK3036_PLLCON0_FBDIV_SHIFT;
+		con = readl(base + pll->con_offset + 0x4);
+		postdiv2 = (con & RK3036_PLLCON1_POSTDIV2_MASK) >>
+			   RK3036_PLLCON1_POSTDIV2_SHIFT;
+		refdiv = (con & RK3036_PLLCON1_REFDIV_MASK) >>
+			 RK3036_PLLCON1_REFDIV_SHIFT;
+		dsmpd = (con & RK3036_PLLCON1_DSMPD_MASK) >>
+			RK3036_PLLCON1_DSMPD_SHIFT;
+		con = readl(base + pll->con_offset + 0x8);
+		frac = (con & RK3036_PLLCON2_FRAC_MASK) >>
+			RK3036_PLLCON2_FRAC_SHIFT;
+		rate = (24 * fbdiv / (refdiv * postdiv1 * postdiv2)) * 1000000;
+		if (dsmpd == 0) {
+			u64 frac_rate = OSC_HZ * (u64)frac;
+
+			do_div(frac_rate, refdiv);
+			frac_rate >>= 24;
+			do_div(frac_rate, postdiv1);
+			do_div(frac_rate, postdiv1);
+			rate += frac_rate;
+		}
+		return rate;
+	case RKCLK_PLL_MODE_DEEP:
+	default:
+		return 32768;
+	}
+}
+
+ulong rockchip_pll_get_rate(struct rockchip_pll_clock *pll,
+			    void __iomem *base,
+			    ulong pll_id)
+{
+	ulong rate = 0;
+
+	switch (pll->type) {
+	case pll_rk3036:
+		pll->mode_mask = PLL_MODE_MASK;
+		rate = rk3036_pll_get_rate(pll, base, pll_id);
+		break;
+	case pll_rk3328:
+		pll->mode_mask = PLL_RK3328_MODE_MASK;
+		rate = rk3036_pll_get_rate(pll, base, pll_id);
+		break;
+	default:
+		printf("%s: Unknown pll type for pll clk %ld\n",
+		       __func__, pll_id);
+	}
+	return rate;
+}
+
+int rockchip_pll_set_rate(struct rockchip_pll_clock *pll,
+			  void __iomem *base, ulong pll_id,
+			  ulong drate)
+{
+	int ret = 0;
+
+	if (rockchip_pll_get_rate(pll, base, pll_id) == drate)
+		return 0;
+
+	switch (pll->type) {
+	case pll_rk3036:
+		pll->mode_mask = PLL_MODE_MASK;
+		ret = rk3036_pll_set_rate(pll, base, pll_id, drate);
+		break;
+	case pll_rk3328:
+		pll->mode_mask = PLL_RK3328_MODE_MASK;
+		ret = rk3036_pll_set_rate(pll, base, pll_id, drate);
+		break;
+	default:
+		printf("%s: Unknown pll type for pll clk %ld\n",
+		       __func__, pll_id);
+	}
+	return ret;
+}
+
+const struct rockchip_cpu_rate_table *
+rockchip_get_cpu_settings(struct rockchip_cpu_rate_table *cpu_table,
+			  ulong rate)
+{
+	struct rockchip_cpu_rate_table *ps = cpu_table;
+
+	while (ps->rate) {
+		if (ps->rate == rate)
+			break;
+		ps++;
+	}
+	if (ps->rate != rate)
+		return NULL;
+	else
+		return ps;
+}
+
diff --git a/drivers/clk/rockchip/clk_px30.c b/drivers/clk/rockchip/clk_px30.c
new file mode 100644
index 0000000..36764c1
--- /dev/null
+++ b/drivers/clk/rockchip/clk_px30.c
@@ -0,0 +1,1630 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * (C) Copyright 2017 Rockchip Electronics Co., Ltd
+ */
+
+#include <common.h>
+#include <bitfield.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <errno.h>
+#include <syscon.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/cru_px30.h>
+#include <asm/arch-rockchip/hardware.h>
+#include <asm/io.h>
+#include <dm/lists.h>
+#include <dt-bindings/clock/px30-cru.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+enum {
+	VCO_MAX_HZ	= 3200U * 1000000,
+	VCO_MIN_HZ	= 800 * 1000000,
+	OUTPUT_MAX_HZ	= 3200U * 1000000,
+	OUTPUT_MIN_HZ	= 24 * 1000000,
+};
+
+#define PX30_VOP_PLL_LIMIT			600000000
+
+#define PX30_PLL_RATE(_rate, _refdiv, _fbdiv, _postdiv1,	\
+			_postdiv2, _dsmpd, _frac)		\
+{								\
+	.rate	= _rate##U,					\
+	.fbdiv = _fbdiv,					\
+	.postdiv1 = _postdiv1,					\
+	.refdiv = _refdiv,					\
+	.postdiv2 = _postdiv2,					\
+	.dsmpd = _dsmpd,					\
+	.frac = _frac,						\
+}
+
+#define PX30_CPUCLK_RATE(_rate, _aclk_div, _pclk_div)		\
+{								\
+	.rate	= _rate##U,					\
+	.aclk_div = _aclk_div,					\
+	.pclk_div = _pclk_div,					\
+}
+
+#define DIV_TO_RATE(input_rate, div)    ((input_rate) / ((div) + 1))
+
+#define PX30_CLK_DUMP(_id, _name, _iscru)	\
+{						\
+	.id = _id,				\
+	.name = _name,				\
+	.is_cru = _iscru,			\
+}
+
+static struct pll_rate_table px30_pll_rates[] = {
+	/* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
+	PX30_PLL_RATE(1200000000, 1, 50, 1, 1, 1, 0),
+	PX30_PLL_RATE(1188000000, 2, 99, 1, 1, 1, 0),
+	PX30_PLL_RATE(1100000000, 12, 550, 1, 1, 1, 0),
+	PX30_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0),
+	PX30_PLL_RATE(1000000000, 6, 500, 2, 1, 1, 0),
+	PX30_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0),
+	PX30_PLL_RATE(600000000, 1, 75, 3, 1, 1, 0),
+};
+
+static struct cpu_rate_table px30_cpu_rates[] = {
+	PX30_CPUCLK_RATE(1200000000, 1, 5),
+	PX30_CPUCLK_RATE(1008000000, 1, 5),
+	PX30_CPUCLK_RATE(816000000, 1, 3),
+	PX30_CPUCLK_RATE(600000000, 1, 3),
+	PX30_CPUCLK_RATE(408000000, 1, 1),
+};
+
+static u8 pll_mode_shift[PLL_COUNT] = {
+	APLL_MODE_SHIFT, DPLL_MODE_SHIFT, CPLL_MODE_SHIFT,
+	NPLL_MODE_SHIFT, GPLL_MODE_SHIFT
+};
+
+static u32 pll_mode_mask[PLL_COUNT] = {
+	APLL_MODE_MASK, DPLL_MODE_MASK, CPLL_MODE_MASK,
+	NPLL_MODE_MASK, GPLL_MODE_MASK
+};
+
+static struct pll_rate_table auto_table;
+
+static ulong px30_clk_get_pll_rate(struct px30_clk_priv *priv,
+				   enum px30_pll_id pll_id);
+
+static struct pll_rate_table *pll_clk_set_by_auto(u32 drate)
+{
+	struct pll_rate_table *rate = &auto_table;
+	u32 ref_khz = OSC_HZ / KHz, refdiv, fbdiv = 0;
+	u32 postdiv1, postdiv2 = 1;
+	u32 fref_khz;
+	u32 diff_khz, best_diff_khz;
+	const u32 max_refdiv = 63, max_fbdiv = 3200, min_fbdiv = 16;
+	const u32 max_postdiv1 = 7, max_postdiv2 = 7;
+	u32 vco_khz;
+	u32 rate_khz = drate / KHz;
+
+	if (!drate) {
+		printf("%s: the frequency can't be 0 Hz\n", __func__);
+		return NULL;
+	}
+
+	postdiv1 = DIV_ROUND_UP(VCO_MIN_HZ / 1000, rate_khz);
+	if (postdiv1 > max_postdiv1) {
+		postdiv2 = DIV_ROUND_UP(postdiv1, max_postdiv1);
+		postdiv1 = DIV_ROUND_UP(postdiv1, postdiv2);
+	}
+
+	vco_khz = rate_khz * postdiv1 * postdiv2;
+
+	if (vco_khz < (VCO_MIN_HZ / KHz) || vco_khz > (VCO_MAX_HZ / KHz) ||
+	    postdiv2 > max_postdiv2) {
+		printf("%s: Cannot find out a supported VCO for Freq (%uHz)\n",
+		       __func__, rate_khz);
+		return NULL;
+	}
+
+	rate->postdiv1 = postdiv1;
+	rate->postdiv2 = postdiv2;
+
+	best_diff_khz = vco_khz;
+	for (refdiv = 1; refdiv < max_refdiv && best_diff_khz; refdiv++) {
+		fref_khz = ref_khz / refdiv;
+
+		fbdiv = vco_khz / fref_khz;
+		if (fbdiv >= max_fbdiv || fbdiv <= min_fbdiv)
+			continue;
+
+		diff_khz = vco_khz - fbdiv * fref_khz;
+		if (fbdiv + 1 < max_fbdiv && diff_khz > fref_khz / 2) {
+			fbdiv++;
+			diff_khz = fref_khz - diff_khz;
+		}
+
+		if (diff_khz >= best_diff_khz)
+			continue;
+
+		best_diff_khz = diff_khz;
+		rate->refdiv = refdiv;
+		rate->fbdiv = fbdiv;
+	}
+
+	if (best_diff_khz > 4 * (MHz / KHz)) {
+		printf("%s: Failed to match output frequency %u bestis %u Hz\n",
+		       __func__, rate_khz,
+		       best_diff_khz * KHz);
+		return NULL;
+	}
+
+	return rate;
+}
+
+static const struct pll_rate_table *get_pll_settings(unsigned long rate)
+{
+	unsigned int rate_count = ARRAY_SIZE(px30_pll_rates);
+	int i;
+
+	for (i = 0; i < rate_count; i++) {
+		if (rate == px30_pll_rates[i].rate)
+			return &px30_pll_rates[i];
+	}
+
+	return pll_clk_set_by_auto(rate);
+}
+
+static const struct cpu_rate_table *get_cpu_settings(unsigned long rate)
+{
+	unsigned int rate_count = ARRAY_SIZE(px30_cpu_rates);
+	int i;
+
+	for (i = 0; i < rate_count; i++) {
+		if (rate == px30_cpu_rates[i].rate)
+			return &px30_cpu_rates[i];
+	}
+
+	return NULL;
+}
+
+/*
+ * How to calculate the PLL(from TRM V0.3 Part 1 Page 63):
+ * Formulas also embedded within the Fractional PLL Verilog model:
+ * If DSMPD = 1 (DSM is disabled, "integer mode")
+ * FOUTVCO = FREF / REFDIV * FBDIV
+ * FOUTPOSTDIV = FOUTVCO / POSTDIV1 / POSTDIV2
+ * Where:
+ * FOUTVCO = Fractional PLL non-divided output frequency
+ * FOUTPOSTDIV = Fractional PLL divided output frequency
+ *               (output of second post divider)
+ * FREF = Fractional PLL input reference frequency, (the OSC_HZ 24MHz input)
+ * REFDIV = Fractional PLL input reference clock divider
+ * FBDIV = Integer value programmed into feedback divide
+ *
+ */
+static int rkclk_set_pll(struct px30_pll *pll, unsigned int *mode,
+			 enum px30_pll_id pll_id,
+			 unsigned long drate)
+{
+	const struct pll_rate_table *rate;
+	uint vco_hz, output_hz;
+
+	rate = get_pll_settings(drate);
+	if (!rate) {
+		printf("%s unsupport rate\n", __func__);
+		return -EINVAL;
+	}
+
+	/* All PLLs have same VCO and output frequency range restrictions. */
+	vco_hz = OSC_HZ / 1000 * rate->fbdiv / rate->refdiv * 1000;
+	output_hz = vco_hz / rate->postdiv1 / rate->postdiv2;
+
+	debug("PLL at %p: fb=%d, ref=%d, pst1=%d, pst2=%d, vco=%u Hz, output=%u Hz\n",
+	      pll, rate->fbdiv, rate->refdiv, rate->postdiv1,
+	      rate->postdiv2, vco_hz, output_hz);
+	assert(vco_hz >= VCO_MIN_HZ && vco_hz <= VCO_MAX_HZ &&
+	       output_hz >= OUTPUT_MIN_HZ && output_hz <= OUTPUT_MAX_HZ);
+
+	/*
+	 * When power on or changing PLL setting,
+	 * we must force PLL into slow mode to ensure output stable clock.
+	 */
+	rk_clrsetreg(mode, pll_mode_mask[pll_id],
+		     PLLMUX_FROM_XIN24M << pll_mode_shift[pll_id]);
+
+	/* use integer mode */
+	rk_setreg(&pll->con1, 1 << PLL_DSMPD_SHIFT);
+	/* Power down */
+	rk_setreg(&pll->con1, 1 << PLL_PD_SHIFT);
+
+	rk_clrsetreg(&pll->con0,
+		     PLL_POSTDIV1_MASK | PLL_FBDIV_MASK,
+		     (rate->postdiv1 << PLL_POSTDIV1_SHIFT) | rate->fbdiv);
+	rk_clrsetreg(&pll->con1, PLL_POSTDIV2_MASK | PLL_REFDIV_MASK,
+		     (rate->postdiv2 << PLL_POSTDIV2_SHIFT |
+		     rate->refdiv << PLL_REFDIV_SHIFT));
+
+	/* Power Up */
+	rk_clrreg(&pll->con1, 1 << PLL_PD_SHIFT);
+
+	/* waiting for pll lock */
+	while (!(readl(&pll->con1) & (1 << PLL_LOCK_STATUS_SHIFT)))
+		udelay(1);
+
+	rk_clrsetreg(mode, pll_mode_mask[pll_id],
+		     PLLMUX_FROM_PLL << pll_mode_shift[pll_id]);
+
+	return 0;
+}
+
+static uint32_t rkclk_pll_get_rate(struct px30_pll *pll, unsigned int *mode,
+				   enum px30_pll_id pll_id)
+{
+	u32 refdiv, fbdiv, postdiv1, postdiv2;
+	u32 con, shift, mask;
+
+	con = readl(mode);
+	shift = pll_mode_shift[pll_id];
+	mask = pll_mode_mask[pll_id];
+
+	switch ((con & mask) >> shift) {
+	case PLLMUX_FROM_XIN24M:
+		return OSC_HZ;
+	case PLLMUX_FROM_PLL:
+		/* normal mode */
+		con = readl(&pll->con0);
+		postdiv1 = (con & PLL_POSTDIV1_MASK) >> PLL_POSTDIV1_SHIFT;
+		fbdiv = (con & PLL_FBDIV_MASK) >> PLL_FBDIV_SHIFT;
+		con = readl(&pll->con1);
+		postdiv2 = (con & PLL_POSTDIV2_MASK) >> PLL_POSTDIV2_SHIFT;
+		refdiv = (con & PLL_REFDIV_MASK) >> PLL_REFDIV_SHIFT;
+		return (24 * fbdiv / (refdiv * postdiv1 * postdiv2)) * 1000000;
+	case PLLMUX_FROM_RTC32K:
+	default:
+		return 32768;
+	}
+}
+
+static ulong px30_i2c_get_clk(struct px30_clk_priv *priv, ulong clk_id)
+{
+	struct px30_cru *cru = priv->cru;
+	u32 div, con;
+
+	switch (clk_id) {
+	case SCLK_I2C0:
+		con = readl(&cru->clksel_con[49]);
+		div = con >> CLK_I2C0_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK;
+		break;
+	case SCLK_I2C1:
+		con = readl(&cru->clksel_con[49]);
+		div = con >> CLK_I2C1_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK;
+		break;
+	case SCLK_I2C2:
+		con = readl(&cru->clksel_con[50]);
+		div = con >> CLK_I2C2_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK;
+		break;
+	case SCLK_I2C3:
+		con = readl(&cru->clksel_con[50]);
+		div = con >> CLK_I2C3_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK;
+		break;
+	default:
+		printf("do not support this i2c bus\n");
+		return -EINVAL;
+	}
+
+	return DIV_TO_RATE(priv->gpll_hz, div);
+}
+
+static ulong px30_i2c_set_clk(struct px30_clk_priv *priv, ulong clk_id, uint hz)
+{
+	struct px30_cru *cru = priv->cru;
+	int src_clk_div;
+
+	src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
+	assert(src_clk_div - 1 <= 127);
+
+	switch (clk_id) {
+	case SCLK_I2C0:
+		rk_clrsetreg(&cru->clksel_con[49],
+			     CLK_I2C_DIV_CON_MASK << CLK_I2C0_DIV_CON_SHIFT |
+			     CLK_I2C_PLL_SEL_MASK << CLK_I2C0_PLL_SEL_SHIFT,
+			     (src_clk_div - 1) << CLK_I2C0_DIV_CON_SHIFT |
+			     CLK_I2C_PLL_SEL_GPLL << CLK_I2C0_PLL_SEL_SHIFT);
+		break;
+	case SCLK_I2C1:
+		rk_clrsetreg(&cru->clksel_con[49],
+			     CLK_I2C_DIV_CON_MASK << CLK_I2C1_DIV_CON_SHIFT |
+			     CLK_I2C_PLL_SEL_MASK << CLK_I2C1_PLL_SEL_SHIFT,
+			     (src_clk_div - 1) << CLK_I2C1_DIV_CON_SHIFT |
+			     CLK_I2C_PLL_SEL_GPLL << CLK_I2C1_PLL_SEL_SHIFT);
+		break;
+	case SCLK_I2C2:
+		rk_clrsetreg(&cru->clksel_con[50],
+			     CLK_I2C_DIV_CON_MASK << CLK_I2C2_DIV_CON_SHIFT |
+			     CLK_I2C_PLL_SEL_MASK << CLK_I2C2_PLL_SEL_SHIFT,
+			     (src_clk_div - 1) << CLK_I2C2_DIV_CON_SHIFT |
+			     CLK_I2C_PLL_SEL_GPLL << CLK_I2C2_PLL_SEL_SHIFT);
+		break;
+	case SCLK_I2C3:
+		rk_clrsetreg(&cru->clksel_con[50],
+			     CLK_I2C_DIV_CON_MASK << CLK_I2C3_DIV_CON_SHIFT |
+			     CLK_I2C_PLL_SEL_MASK << CLK_I2C3_PLL_SEL_SHIFT,
+			     (src_clk_div - 1) << CLK_I2C3_DIV_CON_SHIFT |
+			     CLK_I2C_PLL_SEL_GPLL << CLK_I2C3_PLL_SEL_SHIFT);
+		break;
+	default:
+		printf("do not support this i2c bus\n");
+		return -EINVAL;
+	}
+
+	return px30_i2c_get_clk(priv, clk_id);
+}
+
+/*
+ * calculate best rational approximation for a given fraction
+ * taking into account restricted register size, e.g. to find
+ * appropriate values for a pll with 5 bit denominator and
+ * 8 bit numerator register fields, trying to set up with a
+ * frequency ratio of 3.1415, one would say:
+ *
+ * rational_best_approximation(31415, 10000,
+ *		(1 << 8) - 1, (1 << 5) - 1, &n, &d);
+ *
+ * you may look at given_numerator as a fixed point number,
+ * with the fractional part size described in given_denominator.
+ *
+ * for theoretical background, see:
+ * http://en.wikipedia.org/wiki/Continued_fraction
+ */
+static void rational_best_approximation(unsigned long given_numerator,
+					unsigned long given_denominator,
+					unsigned long max_numerator,
+					unsigned long max_denominator,
+					unsigned long *best_numerator,
+					unsigned long *best_denominator)
+{
+	unsigned long n, d, n0, d0, n1, d1;
+
+	n = given_numerator;
+	d = given_denominator;
+	n0 = 0;
+	d1 = 0;
+	n1 = 1;
+	d0 = 1;
+	for (;;) {
+		unsigned long t, a;
+
+		if (n1 > max_numerator || d1 > max_denominator) {
+			n1 = n0;
+			d1 = d0;
+			break;
+		}
+		if (d == 0)
+			break;
+		t = d;
+		a = n / d;
+		d = n % d;
+		n = t;
+		t = n0 + a * n1;
+		n0 = n1;
+		n1 = t;
+		t = d0 + a * d1;
+		d0 = d1;
+		d1 = t;
+	}
+	*best_numerator = n1;
+	*best_denominator = d1;
+}
+
+static ulong px30_i2s_get_clk(struct px30_clk_priv *priv, ulong clk_id)
+{
+	u32 con, fracdiv, gate;
+	u32 clk_src = priv->gpll_hz / 2;
+	unsigned long m, n;
+	struct px30_cru *cru = priv->cru;
+
+	switch (clk_id) {
+	case SCLK_I2S1:
+		con = readl(&cru->clksel_con[30]);
+		fracdiv = readl(&cru->clksel_con[31]);
+		gate = readl(&cru->clkgate_con[10]);
+		m = fracdiv & CLK_I2S1_FRAC_NUMERATOR_MASK;
+		m >>= CLK_I2S1_FRAC_NUMERATOR_SHIFT;
+		n = fracdiv & CLK_I2S1_FRAC_DENOMINATOR_MASK;
+		n >>= CLK_I2S1_FRAC_DENOMINATOR_SHIFT;
+		debug("con30: 0x%x, gate: 0x%x, frac: 0x%x\n",
+		      con, gate, fracdiv);
+		break;
+	default:
+		printf("do not support this i2s bus\n");
+		return -EINVAL;
+	}
+
+	return clk_src * n / m;
+}
+
+static ulong px30_i2s_set_clk(struct px30_clk_priv *priv, ulong clk_id, uint hz)
+{
+	u32 clk_src;
+	unsigned long m, n, val;
+	struct px30_cru *cru = priv->cru;
+
+	clk_src = priv->gpll_hz / 2;
+	rational_best_approximation(hz, clk_src,
+				    GENMASK(16 - 1, 0),
+				    GENMASK(16 - 1, 0),
+				    &m, &n);
+	switch (clk_id) {
+	case SCLK_I2S1:
+		rk_clrsetreg(&cru->clksel_con[30],
+			     CLK_I2S1_PLL_SEL_MASK, CLK_I2S1_PLL_SEL_GPLL);
+		rk_clrsetreg(&cru->clksel_con[30],
+			     CLK_I2S1_DIV_CON_MASK, 0x1);
+		rk_clrsetreg(&cru->clksel_con[30],
+			     CLK_I2S1_SEL_MASK, CLK_I2S1_SEL_FRAC);
+		val = m << CLK_I2S1_FRAC_NUMERATOR_SHIFT | n;
+		writel(val, &cru->clksel_con[31]);
+		rk_clrsetreg(&cru->clkgate_con[10],
+			     CLK_I2S1_OUT_MCLK_PAD_MASK,
+			     CLK_I2S1_OUT_MCLK_PAD_ENABLE);
+		break;
+	default:
+		printf("do not support this i2s bus\n");
+		return -EINVAL;
+	}
+
+	return px30_i2s_get_clk(priv, clk_id);
+}
+
+static ulong px30_nandc_get_clk(struct px30_clk_priv *priv)
+{
+	struct px30_cru *cru = priv->cru;
+	u32 div, con;
+
+	con = readl(&cru->clksel_con[15]);
+	div = (con & NANDC_DIV_MASK) >> NANDC_DIV_SHIFT;
+
+	return DIV_TO_RATE(priv->gpll_hz, div);
+}
+
+static ulong px30_nandc_set_clk(struct px30_clk_priv *priv,
+				ulong set_rate)
+{
+	struct px30_cru *cru = priv->cru;
+	int src_clk_div;
+
+	/* Select nandc source from GPLL by default */
+	/* nandc clock defaulg div 2 internal, need provide double in cru */
+	src_clk_div = DIV_ROUND_UP(priv->gpll_hz, set_rate);
+	assert(src_clk_div - 1 <= 31);
+
+	rk_clrsetreg(&cru->clksel_con[15],
+		     NANDC_CLK_SEL_MASK | NANDC_PLL_MASK |
+		     NANDC_DIV_MASK,
+		     NANDC_CLK_SEL_NANDC << NANDC_CLK_SEL_SHIFT |
+		     NANDC_SEL_GPLL << NANDC_PLL_SHIFT |
+		     (src_clk_div - 1) << NANDC_DIV_SHIFT);
+
+	return px30_nandc_get_clk(priv);
+}
+
+static ulong px30_mmc_get_clk(struct px30_clk_priv *priv, uint clk_id)
+{
+	struct px30_cru *cru = priv->cru;
+	u32 div, con, con_id;
+
+	switch (clk_id) {
+	case HCLK_SDMMC:
+	case SCLK_SDMMC:
+		con_id = 16;
+		break;
+	case HCLK_EMMC:
+	case SCLK_EMMC:
+	case SCLK_EMMC_SAMPLE:
+		con_id = 20;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	con = readl(&cru->clksel_con[con_id]);
+	div = (con & EMMC_DIV_MASK) >> EMMC_DIV_SHIFT;
+
+	if ((con & EMMC_PLL_MASK) >> EMMC_PLL_SHIFT
+	    == EMMC_SEL_24M)
+		return DIV_TO_RATE(OSC_HZ, div) / 2;
+	else
+		return DIV_TO_RATE(priv->gpll_hz, div) / 2;
+}
+
+static ulong px30_mmc_set_clk(struct px30_clk_priv *priv,
+			      ulong clk_id, ulong set_rate)
+{
+	struct px30_cru *cru = priv->cru;
+	int src_clk_div;
+	u32 con_id;
+
+	switch (clk_id) {
+	case HCLK_SDMMC:
+	case SCLK_SDMMC:
+		con_id = 16;
+		break;
+	case HCLK_EMMC:
+	case SCLK_EMMC:
+		con_id = 20;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* Select clk_sdmmc/emmc source from GPLL by default */
+	/* mmc clock defaulg div 2 internal, need provide double in cru */
+	src_clk_div = DIV_ROUND_UP(priv->gpll_hz / 2, set_rate);
+
+	if (src_clk_div > 127) {
+		/* use 24MHz source for 400KHz clock */
+		src_clk_div = DIV_ROUND_UP(OSC_HZ / 2, set_rate);
+		rk_clrsetreg(&cru->clksel_con[con_id],
+			     EMMC_PLL_MASK | EMMC_DIV_MASK,
+			     EMMC_SEL_24M << EMMC_PLL_SHIFT |
+			     (src_clk_div - 1) << EMMC_DIV_SHIFT);
+	} else {
+		rk_clrsetreg(&cru->clksel_con[con_id],
+			     EMMC_PLL_MASK | EMMC_DIV_MASK,
+			     EMMC_SEL_GPLL << EMMC_PLL_SHIFT |
+			     (src_clk_div - 1) << EMMC_DIV_SHIFT);
+	}
+	rk_clrsetreg(&cru->clksel_con[con_id + 1], EMMC_CLK_SEL_MASK,
+		     EMMC_CLK_SEL_EMMC);
+
+	return px30_mmc_get_clk(priv, clk_id);
+}
+
+static ulong px30_pwm_get_clk(struct px30_clk_priv *priv, ulong clk_id)
+{
+	struct px30_cru *cru = priv->cru;
+	u32 div, con;
+
+	switch (clk_id) {
+	case SCLK_PWM0:
+		con = readl(&cru->clksel_con[52]);
+		div = con >> CLK_PWM0_DIV_CON_SHIFT & CLK_PWM_DIV_CON_MASK;
+		break;
+	case SCLK_PWM1:
+		con = readl(&cru->clksel_con[52]);
+		div = con >> CLK_PWM1_DIV_CON_SHIFT & CLK_PWM_DIV_CON_MASK;
+		break;
+	default:
+		printf("do not support this pwm bus\n");
+		return -EINVAL;
+	}
+
+	return DIV_TO_RATE(priv->gpll_hz, div);
+}
+
+static ulong px30_pwm_set_clk(struct px30_clk_priv *priv, ulong clk_id, uint hz)
+{
+	struct px30_cru *cru = priv->cru;
+	int src_clk_div;
+
+	src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
+	assert(src_clk_div - 1 <= 127);
+
+	switch (clk_id) {
+	case SCLK_PWM0:
+		rk_clrsetreg(&cru->clksel_con[52],
+			     CLK_PWM_DIV_CON_MASK << CLK_PWM0_DIV_CON_SHIFT |
+			     CLK_PWM_PLL_SEL_MASK << CLK_PWM0_PLL_SEL_SHIFT,
+			     (src_clk_div - 1) << CLK_PWM0_DIV_CON_SHIFT |
+			     CLK_PWM_PLL_SEL_GPLL << CLK_PWM0_PLL_SEL_SHIFT);
+		break;
+	case SCLK_PWM1:
+		rk_clrsetreg(&cru->clksel_con[52],
+			     CLK_PWM_DIV_CON_MASK << CLK_PWM1_DIV_CON_SHIFT |
+			     CLK_PWM_PLL_SEL_MASK << CLK_PWM1_PLL_SEL_SHIFT,
+			     (src_clk_div - 1) << CLK_PWM1_DIV_CON_SHIFT |
+			     CLK_PWM_PLL_SEL_GPLL << CLK_PWM1_PLL_SEL_SHIFT);
+		break;
+	default:
+		printf("do not support this pwm bus\n");
+		return -EINVAL;
+	}
+
+	return px30_pwm_get_clk(priv, clk_id);
+}
+
+static ulong px30_saradc_get_clk(struct px30_clk_priv *priv)
+{
+	struct px30_cru *cru = priv->cru;
+	u32 div, con;
+
+	con = readl(&cru->clksel_con[55]);
+	div = con >> CLK_SARADC_DIV_CON_SHIFT & CLK_SARADC_DIV_CON_MASK;
+
+	return DIV_TO_RATE(OSC_HZ, div);
+}
+
+static ulong px30_saradc_set_clk(struct px30_clk_priv *priv, uint hz)
+{
+	struct px30_cru *cru = priv->cru;
+	int src_clk_div;
+
+	src_clk_div = DIV_ROUND_UP(OSC_HZ, hz);
+	assert(src_clk_div - 1 <= 2047);
+
+	rk_clrsetreg(&cru->clksel_con[55],
+		     CLK_SARADC_DIV_CON_MASK,
+		     (src_clk_div - 1) << CLK_SARADC_DIV_CON_SHIFT);
+
+	return px30_saradc_get_clk(priv);
+}
+
+static ulong px30_tsadc_get_clk(struct px30_clk_priv *priv)
+{
+	struct px30_cru *cru = priv->cru;
+	u32 div, con;
+
+	con = readl(&cru->clksel_con[54]);
+	div = con >> CLK_SARADC_DIV_CON_SHIFT & CLK_SARADC_DIV_CON_MASK;
+
+	return DIV_TO_RATE(OSC_HZ, div);
+}
+
+static ulong px30_tsadc_set_clk(struct px30_clk_priv *priv, uint hz)
+{
+	struct px30_cru *cru = priv->cru;
+	int src_clk_div;
+
+	src_clk_div = DIV_ROUND_UP(OSC_HZ, hz);
+	assert(src_clk_div - 1 <= 2047);
+
+	rk_clrsetreg(&cru->clksel_con[54],
+		     CLK_SARADC_DIV_CON_MASK,
+		     (src_clk_div - 1) << CLK_SARADC_DIV_CON_SHIFT);
+
+	return px30_tsadc_get_clk(priv);
+}
+
+static ulong px30_spi_get_clk(struct px30_clk_priv *priv, ulong clk_id)
+{
+	struct px30_cru *cru = priv->cru;
+	u32 div, con;
+
+	switch (clk_id) {
+	case SCLK_SPI0:
+		con = readl(&cru->clksel_con[53]);
+		div = con >> CLK_SPI0_DIV_CON_SHIFT & CLK_SPI_DIV_CON_MASK;
+		break;
+	case SCLK_SPI1:
+		con = readl(&cru->clksel_con[53]);
+		div = con >> CLK_SPI1_DIV_CON_SHIFT & CLK_SPI_DIV_CON_MASK;
+		break;
+	default:
+		printf("do not support this pwm bus\n");
+		return -EINVAL;
+	}
+
+	return DIV_TO_RATE(priv->gpll_hz, div);
+}
+
+static ulong px30_spi_set_clk(struct px30_clk_priv *priv, ulong clk_id, uint hz)
+{
+	struct px30_cru *cru = priv->cru;
+	int src_clk_div;
+
+	src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
+	assert(src_clk_div - 1 <= 127);
+
+	switch (clk_id) {
+	case SCLK_SPI0:
+		rk_clrsetreg(&cru->clksel_con[53],
+			     CLK_SPI_DIV_CON_MASK << CLK_SPI0_DIV_CON_SHIFT |
+			     CLK_SPI_PLL_SEL_MASK << CLK_SPI0_PLL_SEL_SHIFT,
+			     (src_clk_div - 1) << CLK_SPI0_DIV_CON_SHIFT |
+			     CLK_SPI_PLL_SEL_GPLL << CLK_SPI0_PLL_SEL_SHIFT);
+		break;
+	case SCLK_SPI1:
+		rk_clrsetreg(&cru->clksel_con[53],
+			     CLK_SPI_DIV_CON_MASK << CLK_SPI1_DIV_CON_SHIFT |
+			     CLK_SPI_PLL_SEL_MASK << CLK_SPI1_PLL_SEL_SHIFT,
+			     (src_clk_div - 1) << CLK_SPI1_DIV_CON_SHIFT |
+			     CLK_SPI_PLL_SEL_GPLL << CLK_SPI1_PLL_SEL_SHIFT);
+		break;
+	default:
+		printf("do not support this pwm bus\n");
+		return -EINVAL;
+	}
+
+	return px30_spi_get_clk(priv, clk_id);
+}
+
+static ulong px30_vop_get_clk(struct px30_clk_priv *priv, ulong clk_id)
+{
+	struct px30_cru *cru = priv->cru;
+	u32 div, con, parent;
+
+	switch (clk_id) {
+	case ACLK_VOPB:
+	case ACLK_VOPL:
+		con = readl(&cru->clksel_con[3]);
+		div = con & ACLK_VO_DIV_MASK;
+		parent = priv->gpll_hz;
+		break;
+	case DCLK_VOPB:
+		con = readl(&cru->clksel_con[5]);
+		div = con & DCLK_VOPB_DIV_MASK;
+		parent = rkclk_pll_get_rate(&cru->pll[CPLL], &cru->mode, CPLL);
+		break;
+	case DCLK_VOPL:
+		con = readl(&cru->clksel_con[8]);
+		div = con & DCLK_VOPL_DIV_MASK;
+		parent = rkclk_pll_get_rate(&cru->pll[NPLL], &cru->mode, NPLL);
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	return DIV_TO_RATE(parent, div);
+}
+
+static ulong px30_vop_set_clk(struct px30_clk_priv *priv, ulong clk_id, uint hz)
+{
+	struct px30_cru *cru = priv->cru;
+	ulong npll_hz;
+	int src_clk_div;
+
+	switch (clk_id) {
+	case ACLK_VOPB:
+	case ACLK_VOPL:
+		src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
+		assert(src_clk_div - 1 <= 31);
+		rk_clrsetreg(&cru->clksel_con[3],
+			     ACLK_VO_PLL_MASK | ACLK_VO_DIV_MASK,
+			     ACLK_VO_SEL_GPLL << ACLK_VO_PLL_SHIFT |
+			     (src_clk_div - 1) << ACLK_VO_DIV_SHIFT);
+		break;
+	case DCLK_VOPB:
+		if (hz < PX30_VOP_PLL_LIMIT) {
+			src_clk_div = DIV_ROUND_UP(PX30_VOP_PLL_LIMIT, hz);
+			if (src_clk_div % 2)
+				src_clk_div = src_clk_div - 1;
+		} else {
+			src_clk_div = 1;
+		}
+		assert(src_clk_div - 1 <= 255);
+		rkclk_set_pll(&cru->pll[CPLL], &cru->mode,
+			      CPLL, hz * src_clk_div);
+		rk_clrsetreg(&cru->clksel_con[5],
+			     DCLK_VOPB_SEL_MASK | DCLK_VOPB_PLL_SEL_MASK |
+			     DCLK_VOPB_DIV_MASK,
+			     DCLK_VOPB_SEL_DIVOUT << DCLK_VOPB_SEL_SHIFT |
+			     DCLK_VOPB_PLL_SEL_CPLL << DCLK_VOPB_PLL_SEL_SHIFT |
+			     (src_clk_div - 1) << DCLK_VOPB_DIV_SHIFT);
+		break;
+	case DCLK_VOPL:
+		npll_hz = px30_clk_get_pll_rate(priv, NPLL);
+		if (npll_hz >= PX30_VOP_PLL_LIMIT && npll_hz >= hz &&
+		    npll_hz % hz == 0) {
+			src_clk_div = npll_hz / hz;
+			assert(src_clk_div - 1 <= 255);
+		} else {
+			if (hz < PX30_VOP_PLL_LIMIT) {
+				src_clk_div = DIV_ROUND_UP(PX30_VOP_PLL_LIMIT,
+							   hz);
+				if (src_clk_div % 2)
+					src_clk_div = src_clk_div - 1;
+			} else {
+				src_clk_div = 1;
+			}
+			assert(src_clk_div - 1 <= 255);
+			rkclk_set_pll(&cru->pll[NPLL], &cru->mode, NPLL,
+				      hz * src_clk_div);
+		}
+		rk_clrsetreg(&cru->clksel_con[8],
+			     DCLK_VOPL_SEL_MASK | DCLK_VOPL_PLL_SEL_MASK |
+			     DCLK_VOPL_DIV_MASK,
+			     DCLK_VOPL_SEL_DIVOUT << DCLK_VOPL_SEL_SHIFT |
+			     DCLK_VOPL_PLL_SEL_NPLL << DCLK_VOPL_PLL_SEL_SHIFT |
+			     (src_clk_div - 1) << DCLK_VOPL_DIV_SHIFT);
+		break;
+	default:
+		printf("do not support this vop freq\n");
+		return -EINVAL;
+	}
+
+	return px30_vop_get_clk(priv, clk_id);
+}
+
+static ulong px30_bus_get_clk(struct px30_clk_priv *priv, ulong clk_id)
+{
+	struct px30_cru *cru = priv->cru;
+	u32 div, con, parent;
+
+	switch (clk_id) {
+	case ACLK_BUS_PRE:
+		con = readl(&cru->clksel_con[23]);
+		div = (con & BUS_ACLK_DIV_MASK) >> BUS_ACLK_DIV_SHIFT;
+		parent = priv->gpll_hz;
+		break;
+	case HCLK_BUS_PRE:
+		con = readl(&cru->clksel_con[24]);
+		div = (con & BUS_HCLK_DIV_MASK) >> BUS_HCLK_DIV_SHIFT;
+		parent = priv->gpll_hz;
+		break;
+	case PCLK_BUS_PRE:
+	case PCLK_WDT_NS:
+		parent = px30_bus_get_clk(priv, ACLK_BUS_PRE);
+		con = readl(&cru->clksel_con[24]);
+		div = (con & BUS_PCLK_DIV_MASK) >> BUS_PCLK_DIV_SHIFT;
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	return DIV_TO_RATE(parent, div);
+}
+
+static ulong px30_bus_set_clk(struct px30_clk_priv *priv, ulong clk_id,
+			      ulong hz)
+{
+	struct px30_cru *cru = priv->cru;
+	int src_clk_div;
+
+	/*
+	 * select gpll as pd_bus bus clock source and
+	 * set up dependent divisors for PCLK/HCLK and ACLK clocks.
+	 */
+	switch (clk_id) {
+	case ACLK_BUS_PRE:
+		src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
+		assert(src_clk_div - 1 <= 31);
+		rk_clrsetreg(&cru->clksel_con[23],
+			     BUS_PLL_SEL_MASK | BUS_ACLK_DIV_MASK,
+			     BUS_PLL_SEL_GPLL << BUS_PLL_SEL_SHIFT |
+			     (src_clk_div - 1) << BUS_ACLK_DIV_SHIFT);
+		break;
+	case HCLK_BUS_PRE:
+		src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
+		assert(src_clk_div - 1 <= 31);
+		rk_clrsetreg(&cru->clksel_con[24],
+			     BUS_PLL_SEL_MASK | BUS_HCLK_DIV_MASK,
+			     BUS_PLL_SEL_GPLL << BUS_PLL_SEL_SHIFT |
+			     (src_clk_div - 1) << BUS_HCLK_DIV_SHIFT);
+		break;
+	case PCLK_BUS_PRE:
+		src_clk_div =
+			DIV_ROUND_UP(px30_bus_get_clk(priv, ACLK_BUS_PRE), hz);
+		assert(src_clk_div - 1 <= 3);
+		rk_clrsetreg(&cru->clksel_con[24],
+			     BUS_PCLK_DIV_MASK,
+			     (src_clk_div - 1) << BUS_PCLK_DIV_SHIFT);
+		break;
+	default:
+		printf("do not support this bus freq\n");
+		return -EINVAL;
+	}
+
+	return px30_bus_get_clk(priv, clk_id);
+}
+
+static ulong px30_peri_get_clk(struct px30_clk_priv *priv, ulong clk_id)
+{
+	struct px30_cru *cru = priv->cru;
+	u32 div, con, parent;
+
+	switch (clk_id) {
+	case ACLK_PERI_PRE:
+		con = readl(&cru->clksel_con[14]);
+		div = (con & PERI_ACLK_DIV_MASK) >> PERI_ACLK_DIV_SHIFT;
+		parent = priv->gpll_hz;
+		break;
+	case HCLK_PERI_PRE:
+		con = readl(&cru->clksel_con[14]);
+		div = (con & PERI_HCLK_DIV_MASK) >> PERI_HCLK_DIV_SHIFT;
+		parent = priv->gpll_hz;
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	return DIV_TO_RATE(parent, div);
+}
+
+static ulong px30_peri_set_clk(struct px30_clk_priv *priv, ulong clk_id,
+			       ulong hz)
+{
+	struct px30_cru *cru = priv->cru;
+	int src_clk_div;
+
+	src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
+	assert(src_clk_div - 1 <= 31);
+
+	/*
+	 * select gpll as pd_peri bus clock source and
+	 * set up dependent divisors for HCLK and ACLK clocks.
+	 */
+	switch (clk_id) {
+	case ACLK_PERI_PRE:
+		rk_clrsetreg(&cru->clksel_con[14],
+			     PERI_PLL_SEL_MASK | PERI_ACLK_DIV_MASK,
+			     PERI_PLL_GPLL << PERI_PLL_SEL_SHIFT |
+			     (src_clk_div - 1) << PERI_ACLK_DIV_SHIFT);
+		break;
+	case HCLK_PERI_PRE:
+		rk_clrsetreg(&cru->clksel_con[14],
+			     PERI_PLL_SEL_MASK | PERI_HCLK_DIV_MASK,
+			     PERI_PLL_GPLL << PERI_PLL_SEL_SHIFT |
+			     (src_clk_div - 1) << PERI_HCLK_DIV_SHIFT);
+		break;
+	default:
+		printf("do not support this peri freq\n");
+		return -EINVAL;
+	}
+
+	return px30_peri_get_clk(priv, clk_id);
+}
+
+#ifndef CONFIG_SPL_BUILD
+static ulong px30_crypto_get_clk(struct px30_clk_priv *priv, ulong clk_id)
+{
+	struct px30_cru *cru = priv->cru;
+	u32 div, con, parent;
+
+	switch (clk_id) {
+	case SCLK_CRYPTO:
+		con = readl(&cru->clksel_con[25]);
+		div = (con & CRYPTO_DIV_MASK) >> CRYPTO_DIV_SHIFT;
+		parent = priv->gpll_hz;
+		break;
+	case SCLK_CRYPTO_APK:
+		con = readl(&cru->clksel_con[25]);
+		div = (con & CRYPTO_APK_DIV_MASK) >> CRYPTO_APK_DIV_SHIFT;
+		parent = priv->gpll_hz;
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	return DIV_TO_RATE(parent, div);
+}
+
+static ulong px30_crypto_set_clk(struct px30_clk_priv *priv, ulong clk_id,
+				 ulong hz)
+{
+	struct px30_cru *cru = priv->cru;
+	int src_clk_div;
+
+	src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
+	assert(src_clk_div - 1 <= 31);
+
+	/*
+	 * select gpll as crypto clock source and
+	 * set up dependent divisors for crypto clocks.
+	 */
+	switch (clk_id) {
+	case SCLK_CRYPTO:
+		rk_clrsetreg(&cru->clksel_con[25],
+			     CRYPTO_PLL_SEL_MASK | CRYPTO_DIV_MASK,
+			     CRYPTO_PLL_SEL_GPLL << CRYPTO_PLL_SEL_SHIFT |
+			     (src_clk_div - 1) << CRYPTO_DIV_SHIFT);
+		break;
+	case SCLK_CRYPTO_APK:
+		rk_clrsetreg(&cru->clksel_con[25],
+			     CRYPTO_APK_PLL_SEL_MASK | CRYPTO_APK_DIV_MASK,
+			     CRYPTO_PLL_SEL_GPLL << CRYPTO_APK_SEL_SHIFT |
+			     (src_clk_div - 1) << CRYPTO_APK_DIV_SHIFT);
+		break;
+	default:
+		printf("do not support this peri freq\n");
+		return -EINVAL;
+	}
+
+	return px30_crypto_get_clk(priv, clk_id);
+}
+
+static ulong px30_i2s1_mclk_get_clk(struct px30_clk_priv *priv, ulong clk_id)
+{
+	struct px30_cru *cru = priv->cru;
+	u32 con;
+
+	con = readl(&cru->clksel_con[30]);
+
+	if (!(con & CLK_I2S1_OUT_SEL_MASK))
+		return -ENOENT;
+
+	return 12000000;
+}
+
+static ulong px30_i2s1_mclk_set_clk(struct px30_clk_priv *priv, ulong clk_id,
+				    ulong hz)
+{
+	struct px30_cru *cru = priv->cru;
+
+	if (hz != 12000000) {
+		printf("do not support this i2s1_mclk freq\n");
+		return -EINVAL;
+	}
+
+	rk_clrsetreg(&cru->clksel_con[30], CLK_I2S1_OUT_SEL_MASK,
+		     CLK_I2S1_OUT_SEL_OSC);
+	rk_clrsetreg(&cru->clkgate_con[10], CLK_I2S1_OUT_MCLK_PAD_MASK,
+		     CLK_I2S1_OUT_MCLK_PAD_ENABLE);
+
+	return px30_i2s1_mclk_get_clk(priv, clk_id);
+}
+
+static ulong px30_mac_set_clk(struct px30_clk_priv *priv, uint hz)
+{
+	struct px30_cru *cru = priv->cru;
+	u32 con = readl(&cru->clksel_con[22]);
+	ulong pll_rate;
+	u8 div;
+
+	if ((con >> GMAC_PLL_SEL_SHIFT) & GMAC_PLL_SEL_CPLL)
+		pll_rate = px30_clk_get_pll_rate(priv, CPLL);
+	else if ((con >> GMAC_PLL_SEL_SHIFT) & GMAC_PLL_SEL_NPLL)
+		pll_rate = px30_clk_get_pll_rate(priv, NPLL);
+	else
+		pll_rate = priv->gpll_hz;
+
+	/*default set 50MHZ for gmac*/
+	if (!hz)
+		hz = 50000000;
+
+	div = DIV_ROUND_UP(pll_rate, hz) - 1;
+	assert(div < 32);
+	rk_clrsetreg(&cru->clksel_con[22], CLK_GMAC_DIV_MASK,
+		     div << CLK_GMAC_DIV_SHIFT);
+
+	return DIV_TO_RATE(pll_rate, div);
+}
+
+static int px30_mac_set_speed_clk(struct px30_clk_priv *priv, uint hz)
+{
+	struct px30_cru *cru = priv->cru;
+
+	if (hz != 2500000 && hz != 25000000) {
+		debug("Unsupported mac speed:%d\n", hz);
+		return -EINVAL;
+	}
+
+	rk_clrsetreg(&cru->clksel_con[23], RMII_CLK_SEL_MASK,
+		     ((hz == 2500000) ? 0 : 1) << RMII_CLK_SEL_SHIFT);
+
+	return 0;
+}
+
+#endif
+
+static ulong px30_clk_get_pll_rate(struct px30_clk_priv *priv,
+				   enum px30_pll_id pll_id)
+{
+	struct px30_cru *cru = priv->cru;
+
+	return rkclk_pll_get_rate(&cru->pll[pll_id], &cru->mode, pll_id);
+}
+
+static ulong px30_clk_set_pll_rate(struct px30_clk_priv *priv,
+				   enum px30_pll_id pll_id, ulong hz)
+{
+	struct px30_cru *cru = priv->cru;
+
+	if (rkclk_set_pll(&cru->pll[pll_id], &cru->mode, pll_id, hz))
+		return -EINVAL;
+	return rkclk_pll_get_rate(&cru->pll[pll_id], &cru->mode, pll_id);
+}
+
+static ulong px30_armclk_set_clk(struct px30_clk_priv *priv, ulong hz)
+{
+	struct px30_cru *cru = priv->cru;
+	const struct cpu_rate_table *rate;
+	ulong old_rate;
+
+	rate = get_cpu_settings(hz);
+	if (!rate) {
+		printf("%s unsupport rate\n", __func__);
+		return -EINVAL;
+	}
+
+	/*
+	 * select apll as cpu/core clock pll source and
+	 * set up dependent divisors for PERI and ACLK clocks.
+	 * core hz : apll = 1:1
+	 */
+	old_rate = px30_clk_get_pll_rate(priv, APLL);
+	if (old_rate > hz) {
+		if (rkclk_set_pll(&cru->pll[APLL], &cru->mode, APLL, hz))
+			return -EINVAL;
+		rk_clrsetreg(&cru->clksel_con[0],
+			     CORE_CLK_PLL_SEL_MASK | CORE_DIV_CON_MASK |
+			     CORE_ACLK_DIV_MASK | CORE_DBG_DIV_MASK,
+			     rate->aclk_div << CORE_ACLK_DIV_SHIFT |
+			     rate->pclk_div << CORE_DBG_DIV_SHIFT |
+			     CORE_CLK_PLL_SEL_APLL << CORE_CLK_PLL_SEL_SHIFT |
+			     0 << CORE_DIV_CON_SHIFT);
+	} else if (old_rate < hz) {
+		rk_clrsetreg(&cru->clksel_con[0],
+			     CORE_CLK_PLL_SEL_MASK | CORE_DIV_CON_MASK |
+			     CORE_ACLK_DIV_MASK | CORE_DBG_DIV_MASK,
+			     rate->aclk_div << CORE_ACLK_DIV_SHIFT |
+			     rate->pclk_div << CORE_DBG_DIV_SHIFT |
+			     CORE_CLK_PLL_SEL_APLL << CORE_CLK_PLL_SEL_SHIFT |
+			     0 << CORE_DIV_CON_SHIFT);
+		if (rkclk_set_pll(&cru->pll[APLL], &cru->mode, APLL, hz))
+			return -EINVAL;
+	}
+
+	return px30_clk_get_pll_rate(priv, APLL);
+}
+
+static ulong px30_clk_get_rate(struct clk *clk)
+{
+	struct px30_clk_priv *priv = dev_get_priv(clk->dev);
+	ulong rate = 0;
+
+	if (!priv->gpll_hz && clk->id > ARMCLK) {
+		printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
+		return -ENOENT;
+	}
+
+	debug("%s %ld\n", __func__, clk->id);
+	switch (clk->id) {
+	case PLL_APLL:
+		rate = px30_clk_get_pll_rate(priv, APLL);
+		break;
+	case PLL_DPLL:
+		rate = px30_clk_get_pll_rate(priv, DPLL);
+		break;
+	case PLL_CPLL:
+		rate = px30_clk_get_pll_rate(priv, CPLL);
+		break;
+	case PLL_NPLL:
+		rate = px30_clk_get_pll_rate(priv, NPLL);
+		break;
+	case ARMCLK:
+		rate = px30_clk_get_pll_rate(priv, APLL);
+		break;
+	case HCLK_SDMMC:
+	case HCLK_EMMC:
+	case SCLK_SDMMC:
+	case SCLK_EMMC:
+	case SCLK_EMMC_SAMPLE:
+		rate = px30_mmc_get_clk(priv, clk->id);
+		break;
+	case SCLK_I2C0:
+	case SCLK_I2C1:
+	case SCLK_I2C2:
+	case SCLK_I2C3:
+		rate = px30_i2c_get_clk(priv, clk->id);
+		break;
+	case SCLK_I2S1:
+		rate = px30_i2s_get_clk(priv, clk->id);
+		break;
+	case SCLK_NANDC:
+		rate = px30_nandc_get_clk(priv);
+		break;
+	case SCLK_PWM0:
+	case SCLK_PWM1:
+		rate = px30_pwm_get_clk(priv, clk->id);
+		break;
+	case SCLK_SARADC:
+		rate = px30_saradc_get_clk(priv);
+		break;
+	case SCLK_TSADC:
+		rate = px30_tsadc_get_clk(priv);
+		break;
+	case SCLK_SPI0:
+	case SCLK_SPI1:
+		rate = px30_spi_get_clk(priv, clk->id);
+		break;
+	case ACLK_VOPB:
+	case ACLK_VOPL:
+	case DCLK_VOPB:
+	case DCLK_VOPL:
+		rate = px30_vop_get_clk(priv, clk->id);
+		break;
+	case ACLK_BUS_PRE:
+	case HCLK_BUS_PRE:
+	case PCLK_BUS_PRE:
+	case PCLK_WDT_NS:
+		rate = px30_bus_get_clk(priv, clk->id);
+		break;
+	case ACLK_PERI_PRE:
+	case HCLK_PERI_PRE:
+		rate = px30_peri_get_clk(priv, clk->id);
+		break;
+#ifndef CONFIG_SPL_BUILD
+	case SCLK_CRYPTO:
+	case SCLK_CRYPTO_APK:
+		rate = px30_crypto_get_clk(priv, clk->id);
+		break;
+#endif
+	default:
+		return -ENOENT;
+	}
+
+	return rate;
+}
+
+static ulong px30_clk_set_rate(struct clk *clk, ulong rate)
+{
+	struct px30_clk_priv *priv = dev_get_priv(clk->dev);
+	ulong ret = 0;
+
+	if (!priv->gpll_hz && clk->id > ARMCLK) {
+		printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
+		return -ENOENT;
+	}
+
+	debug("%s %ld %ld\n", __func__, clk->id, rate);
+	switch (clk->id) {
+	case PLL_NPLL:
+		ret = px30_clk_set_pll_rate(priv, NPLL, rate);
+		break;
+	case ARMCLK:
+		ret = px30_armclk_set_clk(priv, rate);
+		break;
+	case HCLK_SDMMC:
+	case HCLK_EMMC:
+	case SCLK_SDMMC:
+	case SCLK_EMMC:
+		ret = px30_mmc_set_clk(priv, clk->id, rate);
+		break;
+	case SCLK_I2C0:
+	case SCLK_I2C1:
+	case SCLK_I2C2:
+	case SCLK_I2C3:
+		ret = px30_i2c_set_clk(priv, clk->id, rate);
+		break;
+	case SCLK_I2S1:
+		ret = px30_i2s_set_clk(priv, clk->id, rate);
+		break;
+	case SCLK_NANDC:
+		ret = px30_nandc_set_clk(priv, rate);
+		break;
+	case SCLK_PWM0:
+	case SCLK_PWM1:
+		ret = px30_pwm_set_clk(priv, clk->id, rate);
+		break;
+	case SCLK_SARADC:
+		ret = px30_saradc_set_clk(priv, rate);
+		break;
+	case SCLK_TSADC:
+		ret = px30_tsadc_set_clk(priv, rate);
+		break;
+	case SCLK_SPI0:
+	case SCLK_SPI1:
+		ret = px30_spi_set_clk(priv, clk->id, rate);
+		break;
+	case ACLK_VOPB:
+	case ACLK_VOPL:
+	case DCLK_VOPB:
+	case DCLK_VOPL:
+		ret = px30_vop_set_clk(priv, clk->id, rate);
+		break;
+	case ACLK_BUS_PRE:
+	case HCLK_BUS_PRE:
+	case PCLK_BUS_PRE:
+		ret = px30_bus_set_clk(priv, clk->id, rate);
+		break;
+	case ACLK_PERI_PRE:
+	case HCLK_PERI_PRE:
+		ret = px30_peri_set_clk(priv, clk->id, rate);
+		break;
+#ifndef CONFIG_SPL_BUILD
+	case SCLK_CRYPTO:
+	case SCLK_CRYPTO_APK:
+		ret = px30_crypto_set_clk(priv, clk->id, rate);
+		break;
+	case SCLK_I2S1_OUT:
+		ret = px30_i2s1_mclk_set_clk(priv, clk->id, rate);
+		break;
+	case SCLK_GMAC:
+	case SCLK_GMAC_SRC:
+		ret = px30_mac_set_clk(priv, rate);
+		break;
+	case SCLK_GMAC_RMII:
+		ret = px30_mac_set_speed_clk(priv, rate);
+		break;
+#endif
+	default:
+		return -ENOENT;
+	}
+
+	return ret;
+}
+
+#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
+static int px30_gmac_set_parent(struct clk *clk, struct clk *parent)
+{
+	struct px30_clk_priv *priv = dev_get_priv(clk->dev);
+	struct px30_cru *cru = priv->cru;
+
+	if (parent->id == SCLK_GMAC_SRC) {
+		debug("%s: switching GAMC to SCLK_GMAC_SRC\n", __func__);
+		rk_clrsetreg(&cru->clksel_con[23], RMII_EXTCLK_SEL_MASK,
+			     RMII_EXTCLK_SEL_INT << RMII_EXTCLK_SEL_SHIFT);
+	} else {
+		debug("%s: switching GMAC to external clock\n", __func__);
+		rk_clrsetreg(&cru->clksel_con[23], RMII_EXTCLK_SEL_MASK,
+			     RMII_EXTCLK_SEL_EXT << RMII_EXTCLK_SEL_SHIFT);
+	}
+	return 0;
+}
+
+static int px30_clk_set_parent(struct clk *clk, struct clk *parent)
+{
+	switch (clk->id) {
+	case SCLK_GMAC:
+		return px30_gmac_set_parent(clk, parent);
+	default:
+		return -ENOENT;
+	}
+}
+#endif
+
+static int px30_clk_enable(struct clk *clk)
+{
+	switch (clk->id) {
+	case HCLK_HOST:
+	case SCLK_GMAC:
+	case SCLK_GMAC_RX_TX:
+	case SCLK_MAC_REF:
+	case SCLK_MAC_REFOUT:
+	case ACLK_GMAC:
+	case PCLK_GMAC:
+	case SCLK_GMAC_RMII:
+		/* Required to successfully probe the Designware GMAC driver */
+		return 0;
+	}
+
+	debug("%s: unsupported clk %ld\n", __func__, clk->id);
+	return -ENOENT;
+}
+
+static struct clk_ops px30_clk_ops = {
+	.get_rate = px30_clk_get_rate,
+	.set_rate = px30_clk_set_rate,
+#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
+	.set_parent = px30_clk_set_parent,
+#endif
+	.enable = px30_clk_enable,
+};
+
+static void px30_clk_init(struct px30_clk_priv *priv)
+{
+	ulong npll_hz;
+	int ret;
+
+	npll_hz = px30_clk_get_pll_rate(priv, NPLL);
+	if (npll_hz != NPLL_HZ) {
+		ret = px30_clk_set_pll_rate(priv, NPLL, NPLL_HZ);
+		if (ret < 0)
+			printf("%s failed to set npll rate\n", __func__);
+	}
+
+	px30_bus_set_clk(priv, ACLK_BUS_PRE, ACLK_BUS_HZ);
+	px30_bus_set_clk(priv, HCLK_BUS_PRE, HCLK_BUS_HZ);
+	px30_bus_set_clk(priv, PCLK_BUS_PRE, PCLK_BUS_HZ);
+	px30_peri_set_clk(priv, ACLK_PERI_PRE, ACLK_PERI_HZ);
+	px30_peri_set_clk(priv, HCLK_PERI_PRE, HCLK_PERI_HZ);
+}
+
+static int px30_clk_probe(struct udevice *dev)
+{
+	struct px30_clk_priv *priv = dev_get_priv(dev);
+	struct clk clk_gpll;
+	int ret;
+
+	if (px30_clk_get_pll_rate(priv, APLL) != APLL_HZ)
+		px30_armclk_set_clk(priv, APLL_HZ);
+
+	/* get the GPLL rate from the pmucru */
+	ret = clk_get_by_name(dev, "gpll", &clk_gpll);
+	if (ret) {
+		printf("%s: failed to get gpll clk from pmucru\n", __func__);
+		return ret;
+	}
+
+	priv->gpll_hz = clk_get_rate(&clk_gpll);
+
+	px30_clk_init(priv);
+
+	return 0;
+}
+
+static int px30_clk_ofdata_to_platdata(struct udevice *dev)
+{
+	struct px30_clk_priv *priv = dev_get_priv(dev);
+
+	priv->cru = dev_read_addr_ptr(dev);
+
+	return 0;
+}
+
+static int px30_clk_bind(struct udevice *dev)
+{
+	int ret;
+	struct udevice *sys_child;
+	struct sysreset_reg *priv;
+
+	/* The reset driver does not have a device node, so bind it here */
+	ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
+				 &sys_child);
+	if (ret) {
+		debug("Warning: No sysreset driver: ret=%d\n", ret);
+	} else {
+		priv = malloc(sizeof(struct sysreset_reg));
+		priv->glb_srst_fst_value = offsetof(struct px30_cru,
+						    glb_srst_fst);
+		priv->glb_srst_snd_value = offsetof(struct px30_cru,
+						    glb_srst_snd);
+		sys_child->priv = priv;
+	}
+
+#if CONFIG_IS_ENABLED(RESET_ROCKCHIP)
+	ret = offsetof(struct px30_cru, softrst_con[0]);
+	ret = rockchip_reset_bind(dev, ret, 12);
+	if (ret)
+		debug("Warning: software reset driver bind faile\n");
+#endif
+
+	return 0;
+}
+
+static const struct udevice_id px30_clk_ids[] = {
+	{ .compatible = "rockchip,px30-cru" },
+	{ }
+};
+
+U_BOOT_DRIVER(rockchip_px30_cru) = {
+	.name		= "rockchip_px30_cru",
+	.id		= UCLASS_CLK,
+	.of_match	= px30_clk_ids,
+	.priv_auto_alloc_size = sizeof(struct px30_clk_priv),
+	.ofdata_to_platdata = px30_clk_ofdata_to_platdata,
+	.ops		= &px30_clk_ops,
+	.bind		= px30_clk_bind,
+	.probe		= px30_clk_probe,
+};
+
+static ulong px30_pclk_pmu_get_pmuclk(struct px30_pmuclk_priv *priv)
+{
+	struct px30_pmucru *pmucru = priv->pmucru;
+	u32 div, con;
+
+	con = readl(&pmucru->pmu_clksel_con[0]);
+	div = (con & CLK_PMU_PCLK_DIV_MASK) >> CLK_PMU_PCLK_DIV_SHIFT;
+
+	return DIV_TO_RATE(priv->gpll_hz, div);
+}
+
+static ulong px30_pclk_pmu_set_pmuclk(struct px30_pmuclk_priv *priv, ulong hz)
+{
+	struct px30_pmucru *pmucru = priv->pmucru;
+	int src_clk_div;
+
+	src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
+	assert(src_clk_div - 1 <= 31);
+
+	rk_clrsetreg(&pmucru->pmu_clksel_con[0],
+		     CLK_PMU_PCLK_DIV_MASK,
+		     (src_clk_div - 1) << CLK_PMU_PCLK_DIV_SHIFT);
+
+	return px30_pclk_pmu_get_pmuclk(priv);
+}
+
+static ulong px30_pmuclk_get_gpll_rate(struct px30_pmuclk_priv *priv)
+{
+	struct px30_pmucru *pmucru = priv->pmucru;
+
+	return rkclk_pll_get_rate(&pmucru->pll, &pmucru->pmu_mode, GPLL);
+}
+
+static ulong px30_pmuclk_set_gpll_rate(struct px30_pmuclk_priv *priv, ulong hz)
+{
+	struct px30_pmucru *pmucru = priv->pmucru;
+	ulong pclk_pmu_rate;
+	u32 div;
+
+	if (priv->gpll_hz == hz)
+		return priv->gpll_hz;
+
+	div = DIV_ROUND_UP(hz, priv->gpll_hz);
+
+	/* save clock rate */
+	pclk_pmu_rate = px30_pclk_pmu_get_pmuclk(priv);
+
+	/* avoid rate too large, reduce rate first */
+	px30_pclk_pmu_set_pmuclk(priv, pclk_pmu_rate / div);
+
+	/* change gpll rate */
+	rkclk_set_pll(&pmucru->pll, &pmucru->pmu_mode, GPLL, hz);
+	priv->gpll_hz = px30_pmuclk_get_gpll_rate(priv);
+
+	/* restore clock rate */
+	px30_pclk_pmu_set_pmuclk(priv, pclk_pmu_rate);
+
+	return priv->gpll_hz;
+}
+
+static ulong px30_pmuclk_get_rate(struct clk *clk)
+{
+	struct px30_pmuclk_priv *priv = dev_get_priv(clk->dev);
+	ulong rate = 0;
+
+	debug("%s %ld\n", __func__, clk->id);
+	switch (clk->id) {
+	case PLL_GPLL:
+		rate = px30_pmuclk_get_gpll_rate(priv);
+		break;
+	case PCLK_PMU_PRE:
+		rate = px30_pclk_pmu_get_pmuclk(priv);
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	return rate;
+}
+
+static ulong px30_pmuclk_set_rate(struct clk *clk, ulong rate)
+{
+	struct px30_pmuclk_priv *priv = dev_get_priv(clk->dev);
+	ulong ret = 0;
+
+	debug("%s %ld %ld\n", __func__, clk->id, rate);
+	switch (clk->id) {
+	case PLL_GPLL:
+		ret = px30_pmuclk_set_gpll_rate(priv, rate);
+		break;
+	case PCLK_PMU_PRE:
+		ret = px30_pclk_pmu_set_pmuclk(priv, rate);
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	return ret;
+}
+
+static struct clk_ops px30_pmuclk_ops = {
+	.get_rate = px30_pmuclk_get_rate,
+	.set_rate = px30_pmuclk_set_rate,
+};
+
+static void px30_pmuclk_init(struct px30_pmuclk_priv *priv)
+{
+	priv->gpll_hz = px30_pmuclk_get_gpll_rate(priv);
+	px30_pmuclk_set_gpll_rate(priv, GPLL_HZ);
+
+	px30_pclk_pmu_set_pmuclk(priv, PCLK_PMU_HZ);
+}
+
+static int px30_pmuclk_probe(struct udevice *dev)
+{
+	struct px30_pmuclk_priv *priv = dev_get_priv(dev);
+
+	px30_pmuclk_init(priv);
+
+	return 0;
+}
+
+static int px30_pmuclk_ofdata_to_platdata(struct udevice *dev)
+{
+	struct px30_pmuclk_priv *priv = dev_get_priv(dev);
+
+	priv->pmucru = dev_read_addr_ptr(dev);
+
+	return 0;
+}
+
+static const struct udevice_id px30_pmuclk_ids[] = {
+	{ .compatible = "rockchip,px30-pmucru" },
+	{ }
+};
+
+U_BOOT_DRIVER(rockchip_px30_pmucru) = {
+	.name		= "rockchip_px30_pmucru",
+	.id		= UCLASS_CLK,
+	.of_match	= px30_pmuclk_ids,
+	.priv_auto_alloc_size = sizeof(struct px30_pmuclk_priv),
+	.ofdata_to_platdata = px30_pmuclk_ofdata_to_platdata,
+	.ops		= &px30_pmuclk_ops,
+	.probe		= px30_pmuclk_probe,
+};
diff --git a/drivers/clk/rockchip/clk_rk3036.c b/drivers/clk/rockchip/clk_rk3036.c
index 9bf9ced..6d5ae3d 100644
--- a/drivers/clk/rockchip/clk_rk3036.c
+++ b/drivers/clk/rockchip/clk_rk3036.c
@@ -352,7 +352,7 @@
 		sys_child->priv = priv;
 	}
 
-#if CONFIG_IS_ENABLED(CONFIG_RESET_ROCKCHIP)
+#if CONFIG_IS_ENABLED(RESET_ROCKCHIP)
 	ret = offsetof(struct rk3036_cru, cru_softrst_con[0]);
 	ret = rockchip_reset_bind(dev, ret, 9);
 	if (ret)
diff --git a/drivers/clk/rockchip/clk_rk3188.c b/drivers/clk/rockchip/clk_rk3188.c
index dda686c..3ea9a81 100644
--- a/drivers/clk/rockchip/clk_rk3188.c
+++ b/drivers/clk/rockchip/clk_rk3188.c
@@ -590,7 +590,7 @@
 		sys_child->priv = priv;
 	}
 
-#if CONFIG_IS_ENABLED(CONFIG_RESET_ROCKCHIP)
+#if CONFIG_IS_ENABLED(RESET_ROCKCHIP)
 	ret = offsetof(struct rk3188_cru, cru_softrst_con[0]);
 	ret = rockchip_reset_bind(dev, ret, 9);
 	if (ret)
diff --git a/drivers/clk/rockchip/clk_rk322x.c b/drivers/clk/rockchip/clk_rk322x.c
index f09730c..6e8a164 100644
--- a/drivers/clk/rockchip/clk_rk322x.c
+++ b/drivers/clk/rockchip/clk_rk322x.c
@@ -508,7 +508,7 @@
 		sys_child->priv = priv;
 	}
 
-#if CONFIG_IS_ENABLED(CONFIG_RESET_ROCKCHIP)
+#if CONFIG_IS_ENABLED(RESET_ROCKCHIP)
 	ret = offsetof(struct rk322x_cru, cru_softrst_con[0]);
 	ret = rockchip_reset_bind(dev, ret, 9);
 	if (ret)
diff --git a/drivers/clk/rockchip/clk_rk3288.c b/drivers/clk/rockchip/clk_rk3288.c
index 0122381..85d1b67 100644
--- a/drivers/clk/rockchip/clk_rk3288.c
+++ b/drivers/clk/rockchip/clk_rk3288.c
@@ -1015,7 +1015,7 @@
 		sys_child->priv = priv;
 	}
 
-#if CONFIG_IS_ENABLED(CONFIG_RESET_ROCKCHIP)
+#if CONFIG_IS_ENABLED(RESET_ROCKCHIP)
 	ret = offsetof(struct rk3288_cru, cru_softrst_con[0]);
 	ret = rockchip_reset_bind(dev, ret, 12);
 	if (ret)
diff --git a/drivers/clk/rockchip/clk_rk3308.c b/drivers/clk/rockchip/clk_rk3308.c
new file mode 100644
index 0000000..f212c5f
--- /dev/null
+++ b/drivers/clk/rockchip/clk_rk3308.c
@@ -0,0 +1,1072 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * (C) Copyright 2017-2019 Rockchip Electronics Co., Ltd
+ */
+#include <common.h>
+#include <bitfield.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <div64.h>
+#include <errno.h>
+#include <syscon.h>
+#include <asm/io.h>
+#include <asm/arch/cru_rk3308.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/hardware.h>
+#include <dm/lists.h>
+#include <dt-bindings/clock/rk3308-cru.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+enum {
+	VCO_MAX_HZ	= 3200U * 1000000,
+	VCO_MIN_HZ	= 800 * 1000000,
+	OUTPUT_MAX_HZ	= 3200U * 1000000,
+	OUTPUT_MIN_HZ	= 24 * 1000000,
+};
+
+#define DIV_TO_RATE(input_rate, div)    ((input_rate) / ((div) + 1))
+
+#define RK3308_CPUCLK_RATE(_rate, _aclk_div, _pclk_div)         \
+{                                                               \
+	.rate   = _rate##U,                                     \
+	.aclk_div = _aclk_div,                                  \
+	.pclk_div = _pclk_div,                                  \
+}
+
+static struct rockchip_pll_rate_table rk3308_pll_rates[] = {
+	/* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
+	RK3036_PLL_RATE(1300000000, 6, 325, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1200000000, 1, 50, 1, 1, 1, 0),
+	RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0),
+	RK3036_PLL_RATE(748000000, 2, 187, 3, 1, 1, 0),
+};
+
+static struct rockchip_cpu_rate_table rk3308_cpu_rates[] = {
+	RK3308_CPUCLK_RATE(1200000000, 1, 5),
+	RK3308_CPUCLK_RATE(1008000000, 1, 5),
+	RK3308_CPUCLK_RATE(816000000, 1, 3),
+	RK3308_CPUCLK_RATE(600000000, 1, 3),
+	RK3308_CPUCLK_RATE(408000000, 1, 1),
+};
+
+static struct rockchip_pll_clock rk3308_pll_clks[] = {
+	[APLL] = PLL(pll_rk3328, PLL_APLL, RK3308_PLL_CON(0),
+		     RK3308_MODE_CON, 0, 10, 0, rk3308_pll_rates),
+	[DPLL] = PLL(pll_rk3328, PLL_DPLL, RK3308_PLL_CON(8),
+		     RK3308_MODE_CON, 2, 10, 0, NULL),
+	[VPLL0] = PLL(pll_rk3328, PLL_VPLL0, RK3308_PLL_CON(16),
+		      RK3308_MODE_CON, 4, 10, 0, NULL),
+	[VPLL1] = PLL(pll_rk3328, PLL_VPLL1, RK3308_PLL_CON(24),
+		      RK3308_MODE_CON, 6, 10, 0, NULL),
+};
+
+static ulong rk3308_armclk_set_clk(struct rk3308_clk_priv *priv, ulong hz)
+{
+	struct rk3308_cru *cru = priv->cru;
+	const struct rockchip_cpu_rate_table *rate;
+	ulong old_rate;
+
+	rate = rockchip_get_cpu_settings(rk3308_cpu_rates, hz);
+	if (!rate) {
+		printf("%s unsupport rate\n", __func__);
+		return -EINVAL;
+	}
+
+	/*
+	 * select apll as cpu/core clock pll source and
+	 * set up dependent divisors for PERI and ACLK clocks.
+	 * core hz : apll = 1:1
+	 */
+	old_rate = rockchip_pll_get_rate(&rk3308_pll_clks[APLL],
+					 priv->cru, APLL);
+	if (old_rate > hz) {
+		if (rockchip_pll_set_rate(&rk3308_pll_clks[APLL],
+					  priv->cru, APLL, hz))
+			return -EINVAL;
+		rk_clrsetreg(&cru->clksel_con[0],
+			     CORE_CLK_PLL_SEL_MASK | CORE_DIV_CON_MASK |
+			     CORE_ACLK_DIV_MASK | CORE_DBG_DIV_MASK,
+			     rate->aclk_div << CORE_ACLK_DIV_SHIFT |
+			     rate->pclk_div << CORE_DBG_DIV_SHIFT |
+			     CORE_CLK_PLL_SEL_APLL << CORE_CLK_PLL_SEL_SHIFT |
+			     0 << CORE_DIV_CON_SHIFT);
+	} else if (old_rate < hz) {
+		rk_clrsetreg(&cru->clksel_con[0],
+			     CORE_CLK_PLL_SEL_MASK | CORE_DIV_CON_MASK |
+			     CORE_ACLK_DIV_MASK | CORE_DBG_DIV_MASK,
+			     rate->aclk_div << CORE_ACLK_DIV_SHIFT |
+			     rate->pclk_div << CORE_DBG_DIV_SHIFT |
+			     CORE_CLK_PLL_SEL_APLL << CORE_CLK_PLL_SEL_SHIFT |
+			     0 << CORE_DIV_CON_SHIFT);
+		if (rockchip_pll_set_rate(&rk3308_pll_clks[APLL],
+					  priv->cru, APLL, hz))
+			return -EINVAL;
+	}
+
+	return rockchip_pll_get_rate(&rk3308_pll_clks[APLL], priv->cru, APLL);
+}
+
+static void rk3308_clk_get_pll_rate(struct rk3308_clk_priv *priv)
+{
+	if (!priv->dpll_hz)
+		priv->dpll_hz = rockchip_pll_get_rate(&rk3308_pll_clks[DPLL],
+						      priv->cru, DPLL);
+	if (!priv->vpll0_hz)
+		priv->vpll0_hz = rockchip_pll_get_rate(&rk3308_pll_clks[VPLL0],
+						       priv->cru, VPLL0);
+	if (!priv->vpll1_hz)
+		priv->vpll1_hz = rockchip_pll_get_rate(&rk3308_pll_clks[VPLL1],
+						       priv->cru, VPLL1);
+}
+
+static ulong rk3308_i2c_get_clk(struct clk *clk)
+{
+	struct rk3308_clk_priv *priv = dev_get_priv(clk->dev);
+	struct rk3308_cru *cru = priv->cru;
+	u32 div, con, con_id;
+
+	switch (clk->id) {
+	case SCLK_I2C0:
+		con_id = 25;
+		break;
+	case SCLK_I2C1:
+		con_id = 26;
+		break;
+	case SCLK_I2C2:
+		con_id = 27;
+		break;
+	case SCLK_I2C3:
+		con_id = 28;
+		break;
+	default:
+		printf("do not support this i2c bus\n");
+		return -EINVAL;
+	}
+
+	con = readl(&cru->clksel_con[con_id]);
+	div = con >> CLK_I2C_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK;
+
+	return DIV_TO_RATE(priv->dpll_hz, div);
+}
+
+static ulong rk3308_i2c_set_clk(struct clk *clk, uint hz)
+{
+	struct rk3308_clk_priv *priv = dev_get_priv(clk->dev);
+	struct rk3308_cru *cru = priv->cru;
+	u32 src_clk_div, con_id;
+
+	src_clk_div = DIV_ROUND_UP(priv->dpll_hz, hz);
+	assert(src_clk_div - 1 <= 127);
+
+	switch (clk->id) {
+	case SCLK_I2C0:
+		con_id = 25;
+		break;
+	case SCLK_I2C1:
+		con_id = 26;
+		break;
+	case SCLK_I2C2:
+		con_id = 27;
+		break;
+	case SCLK_I2C3:
+		con_id = 28;
+		break;
+	default:
+		printf("do not support this i2c bus\n");
+		return -EINVAL;
+	}
+	rk_clrsetreg(&cru->clksel_con[con_id],
+		     CLK_I2C_PLL_SEL_MASK | CLK_I2C_DIV_CON_MASK,
+		     CLK_I2C_PLL_SEL_DPLL << CLK_I2C_PLL_SEL_SHIFT |
+		     (src_clk_div - 1) << CLK_I2C_DIV_CON_SHIFT);
+
+	return rk3308_i2c_get_clk(clk);
+}
+
+static ulong rk3308_mac_set_clk(struct clk *clk, uint hz)
+{
+	struct rk3308_clk_priv *priv = dev_get_priv(clk->dev);
+	struct rk3308_cru *cru = priv->cru;
+	u32 con = readl(&cru->clksel_con[43]);
+	ulong pll_rate;
+	u8 div;
+
+	if ((con >> MAC_PLL_SHIFT) & MAC_SEL_VPLL0)
+		pll_rate = rockchip_pll_get_rate(&rk3308_pll_clks[VPLL0],
+						 priv->cru, VPLL0);
+	else if ((con >> MAC_PLL_SHIFT) & MAC_SEL_VPLL1)
+		pll_rate = rockchip_pll_get_rate(&rk3308_pll_clks[VPLL1],
+						 priv->cru, VPLL1);
+	else
+		pll_rate = rockchip_pll_get_rate(&rk3308_pll_clks[DPLL],
+						 priv->cru, DPLL);
+
+	/*default set 50MHZ for gmac*/
+	if (!hz)
+		hz = 50000000;
+
+	div = DIV_ROUND_UP(pll_rate, hz) - 1;
+	assert(div < 32);
+	rk_clrsetreg(&cru->clksel_con[43], MAC_DIV_MASK,
+		     div << MAC_DIV_SHIFT);
+
+	return DIV_TO_RATE(pll_rate, div);
+}
+
+static int rk3308_mac_set_speed_clk(struct clk *clk, uint hz)
+{
+	struct rk3308_clk_priv *priv = dev_get_priv(clk->dev);
+	struct rk3308_cru *cru = priv->cru;
+
+	if (hz != 2500000 && hz != 25000000) {
+		debug("Unsupported mac speed:%d\n", hz);
+		return -EINVAL;
+	}
+
+	rk_clrsetreg(&cru->clksel_con[43], MAC_CLK_SPEED_SEL_MASK,
+		     ((hz == 2500000) ? 0 : 1) << MAC_CLK_SPEED_SEL_SHIFT);
+
+	return 0;
+}
+
+static ulong rk3308_mmc_get_clk(struct clk *clk)
+{
+	struct rk3308_clk_priv *priv = dev_get_priv(clk->dev);
+	struct rk3308_cru *cru = priv->cru;
+	u32 div, con, con_id;
+
+	switch (clk->id) {
+	case HCLK_SDMMC:
+	case SCLK_SDMMC:
+		con_id = 39;
+		break;
+	case HCLK_EMMC:
+	case SCLK_EMMC:
+	case SCLK_EMMC_SAMPLE:
+		con_id = 41;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	con = readl(&cru->clksel_con[con_id]);
+	div = (con & EMMC_DIV_MASK) >> EMMC_DIV_SHIFT;
+
+	if ((con & EMMC_PLL_MASK) >> EMMC_PLL_SHIFT
+	    == EMMC_SEL_24M)
+		return DIV_TO_RATE(OSC_HZ, div) / 2;
+	else
+		return DIV_TO_RATE(priv->vpll0_hz, div) / 2;
+}
+
+static ulong rk3308_mmc_set_clk(struct clk *clk, ulong set_rate)
+{
+	struct rk3308_clk_priv *priv = dev_get_priv(clk->dev);
+	struct rk3308_cru *cru = priv->cru;
+	int src_clk_div;
+	u32 con_id;
+
+	switch (clk->id) {
+	case HCLK_SDMMC:
+	case SCLK_SDMMC:
+		con_id = 39;
+		break;
+	case HCLK_EMMC:
+	case SCLK_EMMC:
+		con_id = 41;
+		break;
+	default:
+		return -EINVAL;
+	}
+	/* Select clk_sdmmc/emmc source from VPLL0 by default */
+	/* mmc clock defaulg div 2 internal, need provide double in cru */
+	src_clk_div = DIV_ROUND_UP(priv->vpll0_hz / 2, set_rate);
+
+	if (src_clk_div > 127) {
+		/* use 24MHz source for 400KHz clock */
+		src_clk_div = DIV_ROUND_UP(OSC_HZ / 2, set_rate);
+		rk_clrsetreg(&cru->clksel_con[con_id],
+			     EMMC_PLL_MASK | EMMC_DIV_MASK | EMMC_CLK_SEL_MASK,
+			     EMMC_CLK_SEL_EMMC << EMMC_CLK_SEL_SHIFT |
+			     EMMC_SEL_24M << EMMC_PLL_SHIFT |
+			     (src_clk_div - 1) << EMMC_DIV_SHIFT);
+	} else {
+		rk_clrsetreg(&cru->clksel_con[con_id],
+			     EMMC_PLL_MASK | EMMC_DIV_MASK | EMMC_CLK_SEL_MASK,
+			     EMMC_CLK_SEL_EMMC << EMMC_CLK_SEL_SHIFT |
+			     EMMC_SEL_VPLL0 << EMMC_PLL_SHIFT |
+			     (src_clk_div - 1) << EMMC_DIV_SHIFT);
+	}
+
+	return rk3308_mmc_get_clk(clk);
+}
+
+static ulong rk3308_saradc_get_clk(struct clk *clk)
+{
+	struct rk3308_clk_priv *priv = dev_get_priv(clk->dev);
+	struct rk3308_cru *cru = priv->cru;
+	u32 div, con;
+
+	con = readl(&cru->clksel_con[34]);
+	div = con >> CLK_SARADC_DIV_CON_SHIFT & CLK_SARADC_DIV_CON_MASK;
+
+	return DIV_TO_RATE(OSC_HZ, div);
+}
+
+static ulong rk3308_saradc_set_clk(struct clk *clk, uint hz)
+{
+	struct rk3308_clk_priv *priv = dev_get_priv(clk->dev);
+	struct rk3308_cru *cru = priv->cru;
+	int src_clk_div;
+
+	src_clk_div = DIV_ROUND_UP(OSC_HZ, hz);
+	assert(src_clk_div - 1 <= 2047);
+
+	rk_clrsetreg(&cru->clksel_con[34],
+		     CLK_SARADC_DIV_CON_MASK,
+		     (src_clk_div - 1) << CLK_SARADC_DIV_CON_SHIFT);
+
+	return rk3308_saradc_get_clk(clk);
+}
+
+static ulong rk3308_tsadc_get_clk(struct clk *clk)
+{
+	struct rk3308_clk_priv *priv = dev_get_priv(clk->dev);
+	struct rk3308_cru *cru = priv->cru;
+	u32 div, con;
+
+	con = readl(&cru->clksel_con[33]);
+	div = con >> CLK_SARADC_DIV_CON_SHIFT & CLK_SARADC_DIV_CON_MASK;
+
+	return DIV_TO_RATE(OSC_HZ, div);
+}
+
+static ulong rk3308_tsadc_set_clk(struct clk *clk, uint hz)
+{
+	struct rk3308_clk_priv *priv = dev_get_priv(clk->dev);
+	struct rk3308_cru *cru = priv->cru;
+	int src_clk_div;
+
+	src_clk_div = DIV_ROUND_UP(OSC_HZ, hz);
+	assert(src_clk_div - 1 <= 2047);
+
+	rk_clrsetreg(&cru->clksel_con[33],
+		     CLK_SARADC_DIV_CON_MASK,
+		     (src_clk_div - 1) << CLK_SARADC_DIV_CON_SHIFT);
+
+	return rk3308_tsadc_get_clk(clk);
+}
+
+static ulong rk3308_spi_get_clk(struct clk *clk)
+{
+	struct rk3308_clk_priv *priv = dev_get_priv(clk->dev);
+	struct rk3308_cru *cru = priv->cru;
+	u32 div, con, con_id;
+
+	switch (clk->id) {
+	case SCLK_SPI0:
+		con_id = 30;
+		break;
+	case SCLK_SPI1:
+		con_id = 31;
+		break;
+	case SCLK_SPI2:
+		con_id = 32;
+		break;
+	default:
+		printf("do not support this spi bus\n");
+		return -EINVAL;
+	}
+
+	con = readl(&cru->clksel_con[con_id]);
+	div = con >> CLK_SPI_DIV_CON_SHIFT & CLK_SPI_DIV_CON_MASK;
+
+	return DIV_TO_RATE(priv->dpll_hz, div);
+}
+
+static ulong rk3308_spi_set_clk(struct clk *clk, uint hz)
+{
+	struct rk3308_clk_priv *priv = dev_get_priv(clk->dev);
+	struct rk3308_cru *cru = priv->cru;
+	u32 src_clk_div, con_id;
+
+	src_clk_div = DIV_ROUND_UP(priv->dpll_hz, hz);
+	assert(src_clk_div - 1 <= 127);
+
+	switch (clk->id) {
+	case SCLK_SPI0:
+		con_id = 30;
+		break;
+	case SCLK_SPI1:
+		con_id = 31;
+		break;
+	case SCLK_SPI2:
+		con_id = 32;
+		break;
+	default:
+		printf("do not support this spi bus\n");
+		return -EINVAL;
+	}
+
+	rk_clrsetreg(&cru->clksel_con[con_id],
+		     CLK_SPI_PLL_SEL_MASK | CLK_SPI_DIV_CON_MASK,
+		     CLK_SPI_PLL_SEL_DPLL << CLK_SPI_PLL_SEL_SHIFT |
+		     (src_clk_div - 1) << CLK_SPI_DIV_CON_SHIFT);
+
+	return rk3308_spi_get_clk(clk);
+}
+
+static ulong rk3308_pwm_get_clk(struct clk *clk)
+{
+	struct rk3308_clk_priv *priv = dev_get_priv(clk->dev);
+	struct rk3308_cru *cru = priv->cru;
+	u32 div, con;
+
+	con = readl(&cru->clksel_con[29]);
+	div = con >> CLK_PWM_DIV_CON_SHIFT & CLK_PWM_DIV_CON_MASK;
+
+	return DIV_TO_RATE(priv->dpll_hz, div);
+}
+
+static ulong rk3308_pwm_set_clk(struct clk *clk, uint hz)
+{
+	struct rk3308_clk_priv *priv = dev_get_priv(clk->dev);
+	struct rk3308_cru *cru = priv->cru;
+	int src_clk_div;
+
+	src_clk_div = DIV_ROUND_UP(priv->dpll_hz, hz);
+	assert(src_clk_div - 1 <= 127);
+
+	rk_clrsetreg(&cru->clksel_con[29],
+		     CLK_PWM_PLL_SEL_MASK | CLK_PWM_DIV_CON_MASK,
+		     CLK_PWM_PLL_SEL_DPLL << CLK_PWM_PLL_SEL_SHIFT |
+		     (src_clk_div - 1) << CLK_PWM_DIV_CON_SHIFT);
+
+	return rk3308_pwm_get_clk(clk);
+}
+
+static ulong rk3308_vop_get_clk(struct clk *clk)
+{
+	struct rk3308_clk_priv *priv = dev_get_priv(clk->dev);
+	struct rk3308_cru *cru = priv->cru;
+	u32 div, pll_sel, vol_sel, con, parent;
+
+	con = readl(&cru->clksel_con[8]);
+	vol_sel = (con & DCLK_VOP_SEL_MASK) >> DCLK_VOP_SEL_SHIFT;
+	pll_sel = (con & DCLK_VOP_PLL_SEL_MASK) >> DCLK_VOP_PLL_SEL_SHIFT;
+	div = con & DCLK_VOP_DIV_MASK;
+
+	if (vol_sel == DCLK_VOP_SEL_24M) {
+		parent = OSC_HZ;
+	} else if (vol_sel == DCLK_VOP_SEL_DIVOUT) {
+		switch (pll_sel) {
+		case DCLK_VOP_PLL_SEL_DPLL:
+			parent = priv->dpll_hz;
+			break;
+		case DCLK_VOP_PLL_SEL_VPLL0:
+			parent = priv->vpll0_hz;
+			break;
+		case DCLK_VOP_PLL_SEL_VPLL1:
+			parent = priv->vpll0_hz;
+			break;
+		default:
+			printf("do not support this vop pll sel\n");
+			return -EINVAL;
+		}
+	} else {
+		printf("do not support this vop sel\n");
+		return -EINVAL;
+	}
+
+	return DIV_TO_RATE(parent, div);
+}
+
+static ulong rk3308_vop_set_clk(struct clk *clk, ulong hz)
+{
+	struct rk3308_clk_priv *priv = dev_get_priv(clk->dev);
+	struct rk3308_cru *cru = priv->cru;
+	ulong pll_rate, now, best_rate = 0;
+	u32 i, div, best_div = 0, best_sel = 0;
+
+	for (i = 0; i <= DCLK_VOP_PLL_SEL_VPLL1; i++) {
+		switch (i) {
+		case DCLK_VOP_PLL_SEL_DPLL:
+			pll_rate = priv->dpll_hz;
+			break;
+		case DCLK_VOP_PLL_SEL_VPLL0:
+			pll_rate = priv->vpll0_hz;
+			break;
+		case DCLK_VOP_PLL_SEL_VPLL1:
+			pll_rate = priv->vpll1_hz;
+			break;
+		default:
+			printf("do not support this vop pll sel\n");
+			return -EINVAL;
+		}
+
+		div = DIV_ROUND_UP(pll_rate, hz);
+		if (div > 255)
+			continue;
+		now = pll_rate / div;
+		if (abs(hz - now) < abs(hz - best_rate)) {
+			best_rate = now;
+			best_div = div;
+			best_sel = i;
+		}
+		debug("pll_rate=%lu, best_rate=%lu, best_div=%u, best_sel=%u\n",
+		      pll_rate, best_rate, best_div, best_sel);
+	}
+
+	if (best_rate != hz && hz == OSC_HZ) {
+		rk_clrsetreg(&cru->clksel_con[8],
+			     DCLK_VOP_SEL_MASK,
+			     DCLK_VOP_SEL_24M << DCLK_VOP_SEL_SHIFT);
+	} else if (best_rate) {
+		rk_clrsetreg(&cru->clksel_con[8],
+			     DCLK_VOP_SEL_MASK | DCLK_VOP_PLL_SEL_MASK |
+			     DCLK_VOP_DIV_MASK,
+			     DCLK_VOP_SEL_DIVOUT << DCLK_VOP_SEL_SHIFT |
+			     best_sel << DCLK_VOP_PLL_SEL_SHIFT |
+			     (best_div - 1) << DCLK_VOP_DIV_SHIFT);
+	} else {
+		printf("do not support this vop freq\n");
+		return -EINVAL;
+	}
+
+	return rk3308_vop_get_clk(clk);
+}
+
+static ulong rk3308_bus_get_clk(struct rk3308_clk_priv *priv, ulong clk_id)
+{
+	struct rk3308_cru *cru = priv->cru;
+	u32 div, con, parent = priv->dpll_hz;
+
+	switch (clk_id) {
+	case ACLK_BUS:
+		con = readl(&cru->clksel_con[5]);
+		div = (con & BUS_ACLK_DIV_MASK) >> BUS_ACLK_DIV_SHIFT;
+		break;
+	case HCLK_BUS:
+		con = readl(&cru->clksel_con[6]);
+		div = (con & BUS_HCLK_DIV_MASK) >> BUS_HCLK_DIV_SHIFT;
+		break;
+	case PCLK_BUS:
+	case PCLK_WDT:
+		con = readl(&cru->clksel_con[6]);
+		div = (con & BUS_PCLK_DIV_MASK) >> BUS_PCLK_DIV_SHIFT;
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	return DIV_TO_RATE(parent, div);
+}
+
+static ulong rk3308_bus_set_clk(struct rk3308_clk_priv *priv, ulong clk_id,
+				ulong hz)
+{
+	struct rk3308_cru *cru = priv->cru;
+	int src_clk_div;
+
+	src_clk_div = DIV_ROUND_UP(priv->dpll_hz, hz);
+	assert(src_clk_div - 1 <= 31);
+
+	/*
+	 * select dpll as pd_bus bus clock source and
+	 * set up dependent divisors for PCLK/HCLK and ACLK clocks.
+	 */
+	switch (clk_id) {
+	case ACLK_BUS:
+		rk_clrsetreg(&cru->clksel_con[5],
+			     BUS_PLL_SEL_MASK | BUS_ACLK_DIV_MASK,
+			     BUS_PLL_SEL_DPLL << BUS_PLL_SEL_SHIFT |
+			     (src_clk_div - 1) << BUS_ACLK_DIV_SHIFT);
+		break;
+	case HCLK_BUS:
+		rk_clrsetreg(&cru->clksel_con[6],
+			     BUS_HCLK_DIV_MASK,
+			     (src_clk_div - 1) << BUS_HCLK_DIV_SHIFT);
+		break;
+	case PCLK_BUS:
+		rk_clrsetreg(&cru->clksel_con[6],
+			     BUS_PCLK_DIV_MASK,
+			     (src_clk_div - 1) << BUS_PCLK_DIV_SHIFT);
+		break;
+	default:
+		printf("do not support this bus freq\n");
+		return -EINVAL;
+	}
+
+	return rk3308_bus_get_clk(priv, clk_id);
+}
+
+static ulong rk3308_peri_get_clk(struct rk3308_clk_priv *priv, ulong clk_id)
+{
+	struct rk3308_cru *cru = priv->cru;
+	u32 div, con, parent = priv->dpll_hz;
+
+	switch (clk_id) {
+	case ACLK_PERI:
+		con = readl(&cru->clksel_con[36]);
+		div = (con & PERI_ACLK_DIV_MASK) >> PERI_ACLK_DIV_SHIFT;
+		break;
+	case HCLK_PERI:
+		con = readl(&cru->clksel_con[37]);
+		div = (con & PERI_HCLK_DIV_MASK) >> PERI_HCLK_DIV_SHIFT;
+		break;
+	case PCLK_PERI:
+		con = readl(&cru->clksel_con[37]);
+		div = (con & PERI_PCLK_DIV_MASK) >> PERI_PCLK_DIV_SHIFT;
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	return DIV_TO_RATE(parent, div);
+}
+
+static ulong rk3308_peri_set_clk(struct rk3308_clk_priv *priv, ulong clk_id,
+				 ulong hz)
+{
+	struct rk3308_cru *cru = priv->cru;
+	int src_clk_div;
+
+	src_clk_div = DIV_ROUND_UP(priv->dpll_hz, hz);
+	assert(src_clk_div - 1 <= 31);
+
+	/*
+	 * select dpll as pd_peri bus clock source and
+	 * set up dependent divisors for PCLK/HCLK and ACLK clocks.
+	 */
+	switch (clk_id) {
+	case ACLK_PERI:
+		rk_clrsetreg(&cru->clksel_con[36],
+			     PERI_PLL_SEL_MASK | PERI_ACLK_DIV_MASK,
+			     PERI_PLL_DPLL << PERI_PLL_SEL_SHIFT |
+			     (src_clk_div - 1) << PERI_ACLK_DIV_SHIFT);
+		break;
+	case HCLK_PERI:
+		rk_clrsetreg(&cru->clksel_con[37],
+			     PERI_HCLK_DIV_MASK,
+			     (src_clk_div - 1) << PERI_HCLK_DIV_SHIFT);
+		break;
+	case PCLK_PERI:
+		rk_clrsetreg(&cru->clksel_con[37],
+			     PERI_PCLK_DIV_MASK,
+			     (src_clk_div - 1) << PERI_PCLK_DIV_SHIFT);
+		break;
+	default:
+		printf("do not support this peri freq\n");
+		return -EINVAL;
+	}
+
+	return rk3308_peri_get_clk(priv, clk_id);
+}
+
+static ulong rk3308_audio_get_clk(struct rk3308_clk_priv *priv, ulong clk_id)
+{
+	struct rk3308_cru *cru = priv->cru;
+	u32 div, con, parent = priv->vpll0_hz;
+
+	switch (clk_id) {
+	case HCLK_AUDIO:
+		con = readl(&cru->clksel_con[45]);
+		div = (con & AUDIO_HCLK_DIV_MASK) >> AUDIO_HCLK_DIV_SHIFT;
+		break;
+	case PCLK_AUDIO:
+		con = readl(&cru->clksel_con[45]);
+		div = (con & AUDIO_PCLK_DIV_MASK) >> AUDIO_PCLK_DIV_SHIFT;
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	return DIV_TO_RATE(parent, div);
+}
+
+static ulong rk3308_audio_set_clk(struct rk3308_clk_priv *priv, ulong clk_id,
+				  ulong hz)
+{
+	struct rk3308_cru *cru = priv->cru;
+	int src_clk_div;
+
+	src_clk_div = DIV_ROUND_UP(priv->vpll0_hz, hz);
+	assert(src_clk_div - 1 <= 31);
+
+	/*
+	 * select vpll0 as audio bus clock source and
+	 * set up dependent divisors for HCLK and PCLK clocks.
+	 */
+	switch (clk_id) {
+	case HCLK_AUDIO:
+		rk_clrsetreg(&cru->clksel_con[45],
+			     AUDIO_PLL_SEL_MASK | AUDIO_HCLK_DIV_MASK,
+			     AUDIO_PLL_VPLL0 << AUDIO_PLL_SEL_SHIFT |
+			     (src_clk_div - 1) << AUDIO_HCLK_DIV_SHIFT);
+		break;
+	case PCLK_AUDIO:
+		rk_clrsetreg(&cru->clksel_con[45],
+			     AUDIO_PLL_SEL_MASK | AUDIO_PCLK_DIV_MASK,
+			     AUDIO_PLL_VPLL0 << AUDIO_PLL_SEL_SHIFT |
+			     (src_clk_div - 1) << AUDIO_PCLK_DIV_SHIFT);
+		break;
+	default:
+		printf("do not support this audio freq\n");
+		return -EINVAL;
+	}
+
+	return rk3308_peri_get_clk(priv, clk_id);
+}
+
+static ulong rk3308_crypto_get_clk(struct rk3308_clk_priv *priv, ulong clk_id)
+{
+	struct rk3308_cru *cru = priv->cru;
+	u32 div, con, parent;
+
+	switch (clk_id) {
+	case SCLK_CRYPTO:
+		con = readl(&cru->clksel_con[7]);
+		div = (con & CRYPTO_DIV_MASK) >> CRYPTO_DIV_SHIFT;
+		parent = priv->vpll0_hz;
+		break;
+	case SCLK_CRYPTO_APK:
+		con = readl(&cru->clksel_con[7]);
+		div = (con & CRYPTO_APK_DIV_MASK) >> CRYPTO_APK_DIV_SHIFT;
+		parent = priv->vpll0_hz;
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	return DIV_TO_RATE(parent, div);
+}
+
+static ulong rk3308_crypto_set_clk(struct rk3308_clk_priv *priv, ulong clk_id,
+				   ulong hz)
+{
+	struct rk3308_cru *cru = priv->cru;
+	int src_clk_div;
+
+	src_clk_div = DIV_ROUND_UP(priv->vpll0_hz, hz);
+	assert(src_clk_div - 1 <= 31);
+
+	/*
+	 * select gpll as crypto clock source and
+	 * set up dependent divisors for crypto clocks.
+	 */
+	switch (clk_id) {
+	case SCLK_CRYPTO:
+		rk_clrsetreg(&cru->clksel_con[7],
+			     CRYPTO_PLL_SEL_MASK | CRYPTO_DIV_MASK,
+			     CRYPTO_PLL_SEL_VPLL0 << CRYPTO_PLL_SEL_SHIFT |
+			     (src_clk_div - 1) << CRYPTO_DIV_SHIFT);
+		break;
+	case SCLK_CRYPTO_APK:
+		rk_clrsetreg(&cru->clksel_con[7],
+			     CRYPTO_APK_PLL_SEL_MASK | CRYPTO_APK_DIV_MASK,
+			     CRYPTO_PLL_SEL_VPLL0 << CRYPTO_APK_SEL_SHIFT |
+			     (src_clk_div - 1) << CRYPTO_APK_DIV_SHIFT);
+		break;
+	default:
+		printf("do not support this peri freq\n");
+		return -EINVAL;
+	}
+
+	return rk3308_crypto_get_clk(priv, clk_id);
+}
+
+static ulong rk3308_clk_get_rate(struct clk *clk)
+{
+	struct rk3308_clk_priv *priv = dev_get_priv(clk->dev);
+	ulong rate = 0;
+
+	debug("%s id:%ld\n", __func__, clk->id);
+
+	switch (clk->id) {
+	case PLL_APLL:
+	case ARMCLK:
+		rate = rockchip_pll_get_rate(&rk3308_pll_clks[APLL],
+					     priv->cru, APLL);
+		break;
+	case PLL_DPLL:
+		rate = rockchip_pll_get_rate(&rk3308_pll_clks[DPLL],
+					     priv->cru, DPLL);
+		break;
+	case PLL_VPLL0:
+		rate = rockchip_pll_get_rate(&rk3308_pll_clks[VPLL0],
+					     priv->cru, VPLL0);
+		break;
+	case PLL_VPLL1:
+		rate = rockchip_pll_get_rate(&rk3308_pll_clks[VPLL1],
+					     priv->cru, VPLL1);
+		break;
+	case HCLK_SDMMC:
+	case HCLK_EMMC:
+	case SCLK_SDMMC:
+	case SCLK_EMMC:
+	case SCLK_EMMC_SAMPLE:
+		rate = rk3308_mmc_get_clk(clk);
+		break;
+	case SCLK_I2C0:
+	case SCLK_I2C1:
+	case SCLK_I2C2:
+	case SCLK_I2C3:
+		rate = rk3308_i2c_get_clk(clk);
+		break;
+	case SCLK_SARADC:
+		rate = rk3308_saradc_get_clk(clk);
+		break;
+	case SCLK_TSADC:
+		rate = rk3308_tsadc_get_clk(clk);
+		break;
+	case SCLK_SPI0:
+	case SCLK_SPI1:
+		rate = rk3308_spi_get_clk(clk);
+		break;
+	case SCLK_PWM0:
+		rate = rk3308_pwm_get_clk(clk);
+		break;
+	case DCLK_VOP:
+		rate = rk3308_vop_get_clk(clk);
+		break;
+	case ACLK_BUS:
+	case HCLK_BUS:
+	case PCLK_BUS:
+	case PCLK_WDT:
+		rate = rk3308_bus_get_clk(priv, clk->id);
+		break;
+	case ACLK_PERI:
+	case HCLK_PERI:
+	case PCLK_PERI:
+		rate = rk3308_peri_get_clk(priv, clk->id);
+		break;
+	case HCLK_AUDIO:
+	case PCLK_AUDIO:
+		rate = rk3308_audio_get_clk(priv, clk->id);
+		break;
+	case SCLK_CRYPTO:
+	case SCLK_CRYPTO_APK:
+		rate = rk3308_crypto_get_clk(priv, clk->id);
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	return rate;
+}
+
+static ulong rk3308_clk_set_rate(struct clk *clk, ulong rate)
+{
+	struct rk3308_clk_priv *priv = dev_get_priv(clk->dev);
+	ulong ret = 0;
+
+	debug("%s %ld %ld\n", __func__, clk->id, rate);
+
+	switch (clk->id) {
+	case PLL_DPLL:
+		ret = rockchip_pll_set_rate(&rk3308_pll_clks[DPLL], priv->cru,
+					    DPLL, rate);
+		priv->dpll_hz = rockchip_pll_get_rate(&rk3308_pll_clks[DPLL],
+						      priv->cru, DPLL);
+		break;
+	case ARMCLK:
+		if (priv->armclk_hz)
+			rk3308_armclk_set_clk(priv, rate);
+		priv->armclk_hz = rate;
+		break;
+	case HCLK_SDMMC:
+	case HCLK_EMMC:
+	case SCLK_SDMMC:
+	case SCLK_EMMC:
+		ret = rk3308_mmc_set_clk(clk, rate);
+		break;
+	case SCLK_I2C0:
+	case SCLK_I2C1:
+	case SCLK_I2C2:
+	case SCLK_I2C3:
+		ret = rk3308_i2c_set_clk(clk, rate);
+		break;
+	case SCLK_MAC:
+		ret = rk3308_mac_set_clk(clk, rate);
+		break;
+	case SCLK_MAC_RMII:
+		ret = rk3308_mac_set_speed_clk(clk, rate);
+		break;
+	case SCLK_SARADC:
+		ret = rk3308_saradc_set_clk(clk, rate);
+		break;
+	case SCLK_TSADC:
+		ret = rk3308_tsadc_set_clk(clk, rate);
+		break;
+	case SCLK_SPI0:
+	case SCLK_SPI1:
+		ret = rk3308_spi_set_clk(clk, rate);
+		break;
+	case SCLK_PWM0:
+		ret = rk3308_pwm_set_clk(clk, rate);
+		break;
+	case DCLK_VOP:
+		ret = rk3308_vop_set_clk(clk, rate);
+		break;
+	case ACLK_BUS:
+	case HCLK_BUS:
+	case PCLK_BUS:
+		rate = rk3308_bus_set_clk(priv, clk->id, rate);
+		break;
+	case ACLK_PERI:
+	case HCLK_PERI:
+	case PCLK_PERI:
+		rate = rk3308_peri_set_clk(priv, clk->id, rate);
+		break;
+	case HCLK_AUDIO:
+	case PCLK_AUDIO:
+		rate = rk3308_audio_set_clk(priv, clk->id, rate);
+		break;
+	case SCLK_CRYPTO:
+	case SCLK_CRYPTO_APK:
+		ret = rk3308_crypto_set_clk(priv, clk->id, rate);
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	return ret;
+}
+
+#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
+static int __maybe_unused rk3308_mac_set_parent(struct clk *clk, struct clk *parent)
+{
+	struct rk3308_clk_priv *priv = dev_get_priv(clk->dev);
+
+	/*
+	 * If the requested parent is in the same clock-controller and
+	 * the id is SCLK_MAC_SRC, switch to the internal clock.
+	 */
+	if (parent->id == SCLK_MAC_SRC) {
+		debug("%s: switching RMII to SCLK_MAC\n", __func__);
+		rk_clrreg(&priv->cru->clksel_con[43], BIT(14));
+	} else {
+		debug("%s: switching RMII to CLKIN\n", __func__);
+		rk_setreg(&priv->cru->clksel_con[43], BIT(14));
+	}
+
+	return 0;
+}
+
+static int __maybe_unused rk3308_clk_set_parent(struct clk *clk, struct clk *parent)
+{
+	switch (clk->id) {
+	case SCLK_MAC:
+		return rk3308_mac_set_parent(clk, parent);
+	default:
+		break;
+	}
+
+	debug("%s: unsupported clk %ld\n", __func__, clk->id);
+	return -ENOENT;
+}
+#endif
+
+static struct clk_ops rk3308_clk_ops = {
+	.get_rate = rk3308_clk_get_rate,
+	.set_rate = rk3308_clk_set_rate,
+#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
+	.set_parent = rk3308_clk_set_parent,
+#endif
+};
+
+static void rk3308_clk_init(struct udevice *dev)
+{
+	struct rk3308_clk_priv *priv = dev_get_priv(dev);
+	int ret;
+
+	if (rockchip_pll_get_rate(&rk3308_pll_clks[APLL],
+				  priv->cru, APLL) != APLL_HZ) {
+		ret = rk3308_armclk_set_clk(priv, APLL_HZ);
+		if (ret < 0)
+			printf("%s failed to set armclk rate\n", __func__);
+	}
+
+	rk3308_clk_get_pll_rate(priv);
+
+	rk3308_bus_set_clk(priv, ACLK_BUS, BUS_ACLK_HZ);
+	rk3308_bus_set_clk(priv, HCLK_BUS, BUS_HCLK_HZ);
+	rk3308_bus_set_clk(priv, PCLK_BUS, BUS_PCLK_HZ);
+
+	rk3308_peri_set_clk(priv, ACLK_PERI, PERI_ACLK_HZ);
+	rk3308_peri_set_clk(priv, HCLK_PERI, PERI_HCLK_HZ);
+	rk3308_peri_set_clk(priv, PCLK_PERI, PERI_PCLK_HZ);
+
+	rk3308_audio_set_clk(priv, HCLK_AUDIO, AUDIO_HCLK_HZ);
+	rk3308_audio_set_clk(priv, PCLK_AUDIO, AUDIO_PCLK_HZ);
+}
+
+static int rk3308_clk_probe(struct udevice *dev)
+{
+	int ret;
+
+	rk3308_clk_init(dev);
+
+	/* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */
+	ret = clk_set_defaults(dev, 1);
+	if (ret)
+		debug("%s clk_set_defaults failed %d\n", __func__, ret);
+
+	return ret;
+}
+
+static int rk3308_clk_ofdata_to_platdata(struct udevice *dev)
+{
+	struct rk3308_clk_priv *priv = dev_get_priv(dev);
+
+	priv->cru = dev_read_addr_ptr(dev);
+
+	return 0;
+}
+
+static int rk3308_clk_bind(struct udevice *dev)
+{
+	int ret;
+	struct udevice *sys_child;
+	struct sysreset_reg *priv;
+
+	/* The reset driver does not have a device node, so bind it here */
+	ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
+				 &sys_child);
+	if (ret) {
+		debug("Warning: No sysreset driver: ret=%d\n", ret);
+	} else {
+		priv = malloc(sizeof(struct sysreset_reg));
+		priv->glb_srst_fst_value = offsetof(struct rk3308_cru,
+						    glb_srst_fst);
+		priv->glb_srst_snd_value = offsetof(struct rk3308_cru,
+						    glb_srst_snd);
+		sys_child->priv = priv;
+	}
+
+#if CONFIG_IS_ENABLED(RESET_ROCKCHIP)
+	ret = offsetof(struct rk3308_cru, softrst_con[0]);
+	ret = rockchip_reset_bind(dev, ret, 12);
+	if (ret)
+		debug("Warning: software reset driver bind faile\n");
+#endif
+
+	return 0;
+}
+
+static const struct udevice_id rk3308_clk_ids[] = {
+	{ .compatible = "rockchip,rk3308-cru" },
+	{ }
+};
+
+U_BOOT_DRIVER(rockchip_rk3308_cru) = {
+	.name		= "rockchip_rk3308_cru",
+	.id		= UCLASS_CLK,
+	.of_match	= rk3308_clk_ids,
+	.priv_auto_alloc_size = sizeof(struct rk3308_clk_priv),
+	.ofdata_to_platdata = rk3308_clk_ofdata_to_platdata,
+	.ops		= &rk3308_clk_ops,
+	.bind		= rk3308_clk_bind,
+	.probe		= rk3308_clk_probe,
+};
diff --git a/drivers/clk/rockchip/clk_rk3328.c b/drivers/clk/rockchip/clk_rk3328.c
index 4331048..e700a1b 100644
--- a/drivers/clk/rockchip/clk_rk3328.c
+++ b/drivers/clk/rockchip/clk_rk3328.c
@@ -791,7 +791,7 @@
 		sys_child->priv = priv;
 	}
 
-#if CONFIG_IS_ENABLED(CONFIG_RESET_ROCKCHIP)
+#if CONFIG_IS_ENABLED(RESET_ROCKCHIP)
 	ret = offsetof(struct rk3328_cru, softrst_con[0]);
 	ret = rockchip_reset_bind(dev, ret, 12);
 	if (ret)
diff --git a/drivers/clk/rockchip/clk_rk3368.c b/drivers/clk/rockchip/clk_rk3368.c
index c1a867b..b51d529 100644
--- a/drivers/clk/rockchip/clk_rk3368.c
+++ b/drivers/clk/rockchip/clk_rk3368.c
@@ -620,7 +620,7 @@
 		sys_child->priv = priv;
 	}
 
-#if CONFIG_IS_ENABLED(CONFIG_RESET_ROCKCHIP)
+#if CONFIG_IS_ENABLED(RESET_ROCKCHIP)
 	ret = offsetof(struct rk3368_cru, softrst_con[0]);
 	ret = rockchip_reset_bind(dev, ret, 15);
 	if (ret)
diff --git a/drivers/clk/rockchip/clk_rk3399.c b/drivers/clk/rockchip/clk_rk3399.c
index a273bd1..9020a9f 100644
--- a/drivers/clk/rockchip/clk_rk3399.c
+++ b/drivers/clk/rockchip/clk_rk3399.c
@@ -1195,7 +1195,7 @@
 		sys_child->priv = priv;
 	}
 
-#if CONFIG_IS_ENABLED(CONFIG_RESET_ROCKCHIP)
+#if CONFIG_IS_ENABLED(RESET_ROCKCHIP)
 	ret = offsetof(struct rk3399_cru, softrst_con[0]);
 	ret = rockchip_reset_bind(dev, ret, 21);
 	if (ret)
diff --git a/drivers/clk/rockchip/clk_rv1108.c b/drivers/clk/rockchip/clk_rv1108.c
index 3ebb007..97fdd09 100644
--- a/drivers/clk/rockchip/clk_rv1108.c
+++ b/drivers/clk/rockchip/clk_rv1108.c
@@ -679,9 +679,8 @@
 static int rv1108_clk_bind(struct udevice *dev)
 {
 	int ret;
-	struct udevice *sys_child, *sf_child;
+	struct udevice *sys_child;
 	struct sysreset_reg *priv;
-	struct softreset_reg *sf_priv;
 
 	/* The reset driver does not have a device node, so bind it here */
 	ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
@@ -697,23 +696,12 @@
 		sys_child->priv = priv;
 	}
 
-#if CONFIG_IS_ENABLED(CONFIG_RESET_ROCKCHIP)
-	ret = offsetof(struct rk3368_cru, softrst_con[0]);
+#if CONFIG_IS_ENABLED(RESET_ROCKCHIP)
+	ret = offsetof(struct rv1108_cru, softrst_con[0]);
 	ret = rockchip_reset_bind(dev, ret, 13);
 	if (ret)
 		debug("Warning: software reset driver bind faile\n");
 #endif
-	ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset",
-					 dev_ofnode(dev), &sf_child);
-	if (ret) {
-		debug("Warning: No rockchip reset driver: ret=%d\n", ret);
-	} else {
-		sf_priv = malloc(sizeof(struct softreset_reg));
-		sf_priv->sf_reset_offset = offsetof(struct rv1108_cru,
-						    softrst_con[0]);
-		sf_priv->sf_reset_num = 13;
-		sf_child->priv = sf_priv;
-	}
 
 	return 0;
 }
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 7a8ba58..82bb093 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -59,6 +59,15 @@
 	  extended (by porting the read function from the Linux kernel sources)
 	  to support other recent Rockchip devices.
 
+config ROCKCHIP_OTP
+	bool "Rockchip OTP Support"
+	depends on MISC
+	help
+	  Enable (read-only) access for the one-time-programmable memory block
+	  found in Rockchip SoCs: accesses can either be made using byte
+	  addressing and a length or through child-nodes that are generated
+	  based on the e-fuse map retrieved from the DTS.
+
 config VEXPRESS_CONFIG
 	bool "Enable support for Arm Versatile Express config bus"
 	depends on MISC
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 870655e..55976d6 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -53,6 +53,7 @@
 obj-$(CONFIG_$(SPL_)PWRSEQ) += pwrseq-uclass.o
 obj-$(CONFIG_QFW) += qfw.o
 obj-$(CONFIG_ROCKCHIP_EFUSE) += rockchip-efuse.o
+obj-$(CONFIG_ROCKCHIP_OTP) += rockchip-otp.o
 obj-$(CONFIG_SANDBOX) += syscon_sandbox.o misc_sandbox.o
 obj-$(CONFIG_SMSC_LPC47M) += smsc_lpc47m.o
 obj-$(CONFIG_SMSC_SIO1007) += smsc_sio1007.o
diff --git a/drivers/misc/imx8/scu.c b/drivers/misc/imx8/scu.c
index 9ec0045..a7654a7 100644
--- a/drivers/misc/imx8/scu.c
+++ b/drivers/misc/imx8/scu.c
@@ -26,8 +26,6 @@
 
 struct imx8_scu {
 	struct mu_type *base;
-	struct udevice *clk;
-	struct udevice *pinclk;
 };
 
 #define MU_CR_GIE_MASK		0xF0000000u
@@ -202,9 +200,6 @@
 
 	gd->arch.scu_dev = dev;
 
-	device_probe(plat->clk);
-	device_probe(plat->pinclk);
-
 	return 0;
 }
 
@@ -215,44 +210,17 @@
 
 static int imx8_scu_bind(struct udevice *dev)
 {
-	struct imx8_scu *plat = dev_get_platdata(dev);
 	int ret;
 	struct udevice *child;
-	int node;
-	char *clk_compatible, *iomuxc_compatible;
-
-	if (IS_ENABLED(CONFIG_IMX8QXP)) {
-		clk_compatible = "fsl,imx8qxp-clk";
-		iomuxc_compatible = "fsl,imx8qxp-iomuxc";
-	} else if (IS_ENABLED(CONFIG_IMX8QM)) {
-		clk_compatible = "fsl,imx8qm-clk";
-		iomuxc_compatible = "fsl,imx8qm-iomuxc";
-	} else {
-		return -EINVAL;
-	}
+	ofnode node;
 
 	debug("%s(dev=%p)\n", __func__, dev);
-
-	node = fdt_node_offset_by_compatible(gd->fdt_blob, -1, clk_compatible);
-	if (node < 0)
-		panic("No clk node found\n");
-
-	ret = lists_bind_fdt(dev, offset_to_ofnode(node), &child, true);
-	if (ret)
-		return ret;
-
-	plat->clk = child;
-
-	node = fdt_node_offset_by_compatible(gd->fdt_blob, -1,
-					     iomuxc_compatible);
-	if (node < 0)
-		panic("No iomuxc node found\n");
-
-	ret = lists_bind_fdt(dev, offset_to_ofnode(node), &child, true);
-	if (ret)
-		return ret;
-
-	plat->pinclk = child;
+	ofnode_for_each_subnode(node, dev_ofnode(dev)) {
+		ret = lists_bind_fdt(dev, node, &child, true);
+		if (ret)
+			return ret;
+		debug("bind child dev %s\n", child->name);
+	}
 
 	return 0;
 }
diff --git a/drivers/misc/rockchip-otp.c b/drivers/misc/rockchip-otp.c
new file mode 100644
index 0000000..bdd443b
--- /dev/null
+++ b/drivers/misc/rockchip-otp.c
@@ -0,0 +1,176 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <command.h>
+#include <dm.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <misc.h>
+
+/* OTP Register Offsets */
+#define OTPC_SBPI_CTRL			0x0020
+#define OTPC_SBPI_CMD_VALID_PRE		0x0024
+#define OTPC_SBPI_CS_VALID_PRE		0x0028
+#define OTPC_SBPI_STATUS		0x002C
+#define OTPC_USER_CTRL			0x0100
+#define OTPC_USER_ADDR			0x0104
+#define OTPC_USER_ENABLE		0x0108
+#define OTPC_USER_QP			0x0120
+#define OTPC_USER_Q			0x0124
+#define OTPC_INT_STATUS			0x0304
+#define OTPC_SBPI_CMD0_OFFSET		0x1000
+#define OTPC_SBPI_CMD1_OFFSET		0x1004
+
+/* OTP Register bits and masks */
+#define OTPC_USER_ADDR_MASK		GENMASK(31, 16)
+#define OTPC_USE_USER			BIT(0)
+#define OTPC_USE_USER_MASK		GENMASK(16, 16)
+#define OTPC_USER_FSM_ENABLE		BIT(0)
+#define OTPC_USER_FSM_ENABLE_MASK	GENMASK(16, 16)
+#define OTPC_SBPI_DONE			BIT(1)
+#define OTPC_USER_DONE			BIT(2)
+
+#define SBPI_DAP_ADDR			0x02
+#define SBPI_DAP_ADDR_SHIFT		8
+#define SBPI_DAP_ADDR_MASK		GENMASK(31, 24)
+#define SBPI_CMD_VALID_MASK		GENMASK(31, 16)
+#define SBPI_DAP_CMD_WRF		0xC0
+#define SBPI_DAP_REG_ECC		0x3A
+#define SBPI_ECC_ENABLE			0x00
+#define SBPI_ECC_DISABLE		0x09
+#define SBPI_ENABLE			BIT(0)
+#define SBPI_ENABLE_MASK		GENMASK(16, 16)
+
+#define OTPC_TIMEOUT			10000
+
+struct rockchip_otp_platdata {
+	void __iomem *base;
+	unsigned long secure_conf_base;
+	unsigned long otp_mask_base;
+};
+
+static int rockchip_otp_wait_status(struct rockchip_otp_platdata *otp,
+				    u32 flag)
+{
+	int delay = OTPC_TIMEOUT;
+
+	while (!(readl(otp->base + OTPC_INT_STATUS) & flag)) {
+		udelay(1);
+		delay--;
+		if (delay <= 0) {
+			printf("%s: wait init status timeout\n", __func__);
+			return -ETIMEDOUT;
+		}
+	}
+
+	/* clean int status */
+	writel(flag, otp->base + OTPC_INT_STATUS);
+
+	return 0;
+}
+
+static int rockchip_otp_ecc_enable(struct rockchip_otp_platdata *otp,
+				   bool enable)
+{
+	int ret = 0;
+
+	writel(SBPI_DAP_ADDR_MASK | (SBPI_DAP_ADDR << SBPI_DAP_ADDR_SHIFT),
+	       otp->base + OTPC_SBPI_CTRL);
+
+	writel(SBPI_CMD_VALID_MASK | 0x1, otp->base + OTPC_SBPI_CMD_VALID_PRE);
+	writel(SBPI_DAP_CMD_WRF | SBPI_DAP_REG_ECC,
+	       otp->base + OTPC_SBPI_CMD0_OFFSET);
+
+	if (enable)
+		writel(SBPI_ECC_ENABLE, otp->base + OTPC_SBPI_CMD1_OFFSET);
+	else
+		writel(SBPI_ECC_DISABLE, otp->base + OTPC_SBPI_CMD1_OFFSET);
+
+	writel(SBPI_ENABLE_MASK | SBPI_ENABLE, otp->base + OTPC_SBPI_CTRL);
+
+	ret = rockchip_otp_wait_status(otp, OTPC_SBPI_DONE);
+	if (ret < 0)
+		printf("%s timeout during ecc_enable\n", __func__);
+
+	return ret;
+}
+
+static int rockchip_px30_otp_read(struct udevice *dev, int offset,
+				  void *buf, int size)
+{
+	struct rockchip_otp_platdata *otp = dev_get_platdata(dev);
+	u8 *buffer = buf;
+	int ret = 0;
+
+	ret = rockchip_otp_ecc_enable(otp, false);
+	if (ret < 0) {
+		printf("%s rockchip_otp_ecc_enable err\n", __func__);
+		return ret;
+	}
+
+	writel(OTPC_USE_USER | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL);
+	udelay(5);
+	while (size--) {
+		writel(offset++ | OTPC_USER_ADDR_MASK,
+		       otp->base + OTPC_USER_ADDR);
+		writel(OTPC_USER_FSM_ENABLE | OTPC_USER_FSM_ENABLE_MASK,
+		       otp->base + OTPC_USER_ENABLE);
+
+		ret = rockchip_otp_wait_status(otp, OTPC_USER_DONE);
+		if (ret < 0) {
+			printf("%s timeout during read setup\n", __func__);
+			goto read_end;
+		}
+
+		*buffer++ = readb(otp->base + OTPC_USER_Q);
+	}
+
+read_end:
+	writel(0x0 | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL);
+
+	return ret;
+}
+
+static int rockchip_otp_read(struct udevice *dev, int offset,
+			     void *buf, int size)
+{
+	return rockchip_px30_otp_read(dev, offset, buf, size);
+}
+
+static const struct misc_ops rockchip_otp_ops = {
+	.read = rockchip_otp_read,
+};
+
+static int rockchip_otp_ofdata_to_platdata(struct udevice *dev)
+{
+	struct rockchip_otp_platdata *otp = dev_get_platdata(dev);
+
+	otp->base = dev_read_addr_ptr(dev);
+
+	return 0;
+}
+
+static const struct udevice_id rockchip_otp_ids[] = {
+	{
+		.compatible = "rockchip,px30-otp",
+		.data = (ulong)&rockchip_px30_otp_read,
+	},
+	{
+		.compatible = "rockchip,rk3308-otp",
+		.data = (ulong)&rockchip_px30_otp_read,
+	},
+	{}
+};
+
+U_BOOT_DRIVER(rockchip_otp) = {
+	.name = "rockchip_otp",
+	.id = UCLASS_MISC,
+	.of_match = rockchip_otp_ids,
+	.ops = &rockchip_otp_ops,
+	.ofdata_to_platdata = rockchip_otp_ofdata_to_platdata,
+	.platdata_auto_alloc_size = sizeof(struct rockchip_otp_platdata),
+};
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index eb3d7ed..4182897 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -236,7 +236,7 @@
 
 config FEC_MXC
 	bool "FEC Ethernet controller"
-	depends on MX28 || MX5 || MX6 || MX7 || IMX8 || VF610
+	depends on MX28 || MX5 || MX6 || MX7 || IMX8 || IMX8M || VF610
 	help
 	  This driver supports the 10/100 Fast Ethernet controller for
 	  NXP i.MX processors.
diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c
index 080dbcf..131d199 100644
--- a/drivers/net/fec_mxc.c
+++ b/drivers/net/fec_mxc.c
@@ -123,30 +123,38 @@
 	return val;
 }
 
+#ifndef imx_get_fecclk
+u32 __weak imx_get_fecclk(void)
+{
+	return 0;
+}
+#endif
+
 static int fec_get_clk_rate(void *udev, int idx)
 {
-#if IS_ENABLED(CONFIG_IMX8)
 	struct fec_priv *fec;
 	struct udevice *dev;
 	int ret;
 
-	dev = udev;
-	if (!dev) {
-		ret = uclass_get_device(UCLASS_ETH, idx, &dev);
-		if (ret < 0) {
-			debug("Can't get FEC udev: %d\n", ret);
-			return ret;
+	if (IS_ENABLED(CONFIG_IMX8) ||
+	    CONFIG_IS_ENABLED(CLK_CCF)) {
+		dev = udev;
+		if (!dev) {
+			ret = uclass_get_device(UCLASS_ETH, idx, &dev);
+			if (ret < 0) {
+				debug("Can't get FEC udev: %d\n", ret);
+				return ret;
+			}
 		}
-	}
 
-	fec = dev_get_priv(dev);
-	if (fec)
-		return fec->clk_rate;
+		fec = dev_get_priv(dev);
+		if (fec)
+			return fec->clk_rate;
 
-	return -EINVAL;
-#else
-	return imx_get_fecclk();
-#endif
+		return -EINVAL;
+	} else {
+		return imx_get_fecclk();
+	}
 }
 
 static void fec_mii_setspeed(struct ethernet_regs *eth)
@@ -1336,6 +1344,47 @@
 		}
 
 		priv->clk_rate = clk_get_rate(&priv->ipg_clk);
+	} else if (CONFIG_IS_ENABLED(CLK_CCF)) {
+		ret = clk_get_by_name(dev, "ipg", &priv->ipg_clk);
+		if (ret < 0) {
+			debug("Can't get FEC ipg clk: %d\n", ret);
+			return ret;
+		}
+		ret = clk_enable(&priv->ipg_clk);
+		if(ret)
+			return ret;
+
+		ret = clk_get_by_name(dev, "ahb", &priv->ahb_clk);
+		if (ret < 0) {
+			debug("Can't get FEC ahb clk: %d\n", ret);
+			return ret;
+		}
+		ret = clk_enable(&priv->ahb_clk);
+		if (ret)
+			return ret;
+
+		ret = clk_get_by_name(dev, "enet_out", &priv->clk_enet_out);
+		if (!ret) {
+			ret = clk_enable(&priv->clk_enet_out);
+			if (ret)
+				return ret;
+		}
+
+		ret = clk_get_by_name(dev, "enet_clk_ref", &priv->clk_ref);
+		if (!ret) {
+			ret = clk_enable(&priv->clk_ref);
+			if (ret)
+				return ret;
+		}
+
+		ret = clk_get_by_name(dev, "ptp", &priv->clk_ptp);
+		if (!ret) {
+			ret = clk_enable(&priv->clk_ptp);
+			if (ret)
+				return ret;
+		}
+
+		priv->clk_rate = clk_get_rate(&priv->ipg_clk);
 	}
 
 	ret = fec_alloc_descs(priv);
diff --git a/drivers/net/fec_mxc.h b/drivers/net/fec_mxc.h
index e5f2dd7..723b06a 100644
--- a/drivers/net/fec_mxc.h
+++ b/drivers/net/fec_mxc.h
@@ -264,6 +264,10 @@
 	u32 interface;
 #endif
 	struct clk ipg_clk;
+	struct clk ahb_clk;
+	struct clk clk_enet_out;
+	struct clk clk_ref;
+	struct clk clk_ptp;
 	u32 clk_rate;
 };
 
diff --git a/drivers/net/gmac_rockchip.c b/drivers/net/gmac_rockchip.c
index 26a6121..d2c52b4 100644
--- a/drivers/net/gmac_rockchip.c
+++ b/drivers/net/gmac_rockchip.c
@@ -14,6 +14,7 @@
 #include <asm/arch-rockchip/periph.h>
 #include <asm/arch-rockchip/clock.h>
 #include <asm/arch-rockchip/hardware.h>
+#include <asm/arch-rockchip/grf_px30.h>
 #include <asm/arch-rockchip/grf_rk322x.h>
 #include <asm/arch-rockchip/grf_rk3288.h>
 #include <asm/arch-rockchip/grf_rk3328.h>
@@ -72,6 +73,47 @@
 	return designware_eth_ofdata_to_platdata(dev);
 }
 
+static int px30_gmac_fix_mac_speed(struct dw_eth_dev *priv)
+{
+	struct px30_grf *grf;
+	struct clk clk_speed;
+	int speed, ret;
+	enum {
+		PX30_GMAC_SPEED_SHIFT = 0x2,
+		PX30_GMAC_SPEED_MASK  = BIT(2),
+		PX30_GMAC_SPEED_10M   = 0,
+		PX30_GMAC_SPEED_100M  = BIT(2),
+	};
+
+	ret = clk_get_by_name(priv->phydev->dev, "clk_mac_speed",
+			      &clk_speed);
+	if (ret)
+		return ret;
+
+	switch (priv->phydev->speed) {
+	case 10:
+		speed = PX30_GMAC_SPEED_10M;
+		ret = clk_set_rate(&clk_speed, 2500000);
+		if (ret)
+			return ret;
+		break;
+	case 100:
+		speed = PX30_GMAC_SPEED_100M;
+		ret = clk_set_rate(&clk_speed, 25000000);
+		if (ret)
+			return ret;
+		break;
+	default:
+		debug("Unknown phy speed: %d\n", priv->phydev->speed);
+		return -EINVAL;
+	}
+
+	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+	rk_clrsetreg(&grf->mac_con1, PX30_GMAC_SPEED_MASK, speed);
+
+	return 0;
+}
+
 static int rk3228_gmac_fix_mac_speed(struct dw_eth_dev *priv)
 {
 	struct rk322x_grf *grf;
@@ -257,6 +299,22 @@
 	return 0;
 }
 
+static void px30_gmac_set_to_rmii(struct gmac_rockchip_platdata *pdata)
+{
+	struct px30_grf *grf;
+	enum {
+		PX30_GMAC_PHY_INTF_SEL_SHIFT = 4,
+		PX30_GMAC_PHY_INTF_SEL_MASK  = GENMASK(4, 6),
+		PX30_GMAC_PHY_INTF_SEL_RMII  = BIT(6),
+	};
+
+	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+
+	rk_clrsetreg(&grf->mac_con1,
+		     PX30_GMAC_PHY_INTF_SEL_MASK,
+		     PX30_GMAC_PHY_INTF_SEL_RMII);
+}
+
 static void rk3228_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
 {
 	struct rk322x_grf *grf;
@@ -445,6 +503,10 @@
 	ulong rate;
 	int ret;
 
+	ret = clk_set_defaults(dev, 0);
+	if (ret)
+		debug("%s clk_set_defaults failed %d\n", __func__, ret);
+
 	ret = clk_get_by_index(dev, 0, &clk);
 	if (ret)
 		return ret;
@@ -569,6 +631,11 @@
 	.write_hwaddr		= designware_eth_write_hwaddr,
 };
 
+const struct rk_gmac_ops px30_gmac_ops = {
+	.fix_mac_speed = px30_gmac_fix_mac_speed,
+	.set_to_rmii = px30_gmac_set_to_rmii,
+};
+
 const struct rk_gmac_ops rk3228_gmac_ops = {
 	.fix_mac_speed = rk3228_gmac_fix_mac_speed,
 	.set_to_rgmii = rk3228_gmac_set_to_rgmii,
@@ -600,6 +667,8 @@
 };
 
 static const struct udevice_id rockchip_gmac_ids[] = {
+	{ .compatible = "rockchip,px30-gmac",
+	  .data = (ulong)&px30_gmac_ops },
 	{ .compatible = "rockchip,rk3228-gmac",
 	  .data = (ulong)&rk3228_gmac_ops },
 	{ .compatible = "rockchip,rk3288-gmac",
diff --git a/drivers/pinctrl/nxp/pinctrl-imx8m.c b/drivers/pinctrl/nxp/pinctrl-imx8m.c
index 8bb03b7..b384431 100644
--- a/drivers/pinctrl/nxp/pinctrl-imx8m.c
+++ b/drivers/pinctrl/nxp/pinctrl-imx8m.c
@@ -21,6 +21,7 @@
 static const struct udevice_id imx8m_pinctrl_match[] = {
 	{ .compatible = "fsl,imx8mq-iomuxc", .data = (ulong)&imx8mq_pinctrl_soc_info },
 	{ .compatible = "fsl,imx8mm-iomuxc", .data = (ulong)&imx8mq_pinctrl_soc_info },
+	{ .compatible = "fsl,imx8mn-iomuxc", .data = (ulong)&imx8mq_pinctrl_soc_info },
 	{ /* sentinel */ }
 };
 
diff --git a/drivers/pinctrl/pinctrl-uclass.c b/drivers/pinctrl/pinctrl-uclass.c
index 761ee29..3425ed1 100644
--- a/drivers/pinctrl/pinctrl-uclass.c
+++ b/drivers/pinctrl/pinctrl-uclass.c
@@ -15,18 +15,6 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-int pinctrl_decode_pin_config(const void *blob, int node)
-{
-	int flags = 0;
-
-	if (fdtdec_get_bool(blob, node, "bias-pull-up"))
-		flags |= 1 << PIN_CONFIG_BIAS_PULL_UP;
-	else if (fdtdec_get_bool(blob, node, "bias-pull-down"))
-		flags |= 1 << PIN_CONFIG_BIAS_PULL_DOWN;
-
-	return flags;
-}
-
 #if CONFIG_IS_ENABLED(PINCTRL_FULL)
 /**
  * pinctrl_config_one() - apply pinctrl settings for a single node
diff --git a/drivers/pinctrl/rockchip/Makefile b/drivers/pinctrl/rockchip/Makefile
index a616d85..83913f6 100644
--- a/drivers/pinctrl/rockchip/Makefile
+++ b/drivers/pinctrl/rockchip/Makefile
@@ -3,6 +3,7 @@
 # Copyright (c) 2017 Rockchip Electronics Co., Ltd
 
 obj-y += pinctrl-rockchip-core.o
+obj-$(CONFIG_ROCKCHIP_PX30) += pinctrl-px30.o
 obj-$(CONFIG_ROCKCHIP_RK3036) += pinctrl-rk3036.o
 obj-$(CONFIG_ROCKCHIP_RK3128) += pinctrl-rk3128.o
 obj-$(CONFIG_ROCKCHIP_RK3188) += pinctrl-rk3188.o
diff --git a/drivers/pinctrl/rockchip/pinctrl-px30.c b/drivers/pinctrl/rockchip/pinctrl-px30.c
new file mode 100644
index 0000000..bb56ae9
--- /dev/null
+++ b/drivers/pinctrl/rockchip/pinctrl-px30.c
@@ -0,0 +1,368 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2019 Rockchip Electronics Co., Ltd
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm/pinctrl.h>
+#include <regmap.h>
+#include <syscon.h>
+
+#include "pinctrl-rockchip.h"
+
+static struct rockchip_mux_route_data px30_mux_route_data[] = {
+	{
+		/* cif-d2m0 */
+		.bank_num = 2,
+		.pin = 0,
+		.func = 1,
+		.route_offset = 0x184,
+		.route_val = BIT(16 + 7),
+	}, {
+		/* cif-d2m1 */
+		.bank_num = 3,
+		.pin = 3,
+		.func = 3,
+		.route_offset = 0x184,
+		.route_val = BIT(16 + 7) | BIT(7),
+	}, {
+		/* pdm-m0 */
+		.bank_num = 3,
+		.pin = 22,
+		.func = 2,
+		.route_offset = 0x184,
+		.route_val = BIT(16 + 8),
+	}, {
+		/* pdm-m1 */
+		.bank_num = 2,
+		.pin = 22,
+		.func = 1,
+		.route_offset = 0x184,
+		.route_val = BIT(16 + 8) | BIT(8),
+	}, {
+		/* uart2-rxm0 */
+		.bank_num = 1,
+		.pin = 27,
+		.func = 2,
+		.route_offset = 0x184,
+		.route_val = BIT(16 + 10),
+	}, {
+		/* uart2-rxm1 */
+		.bank_num = 2,
+		.pin = 14,
+		.func = 2,
+		.route_offset = 0x184,
+		.route_val = BIT(16 + 10) | BIT(10),
+	}, {
+		/* uart3-rxm0 */
+		.bank_num = 0,
+		.pin = 17,
+		.func = 2,
+		.route_offset = 0x184,
+		.route_val = BIT(16 + 9),
+	}, {
+		/* uart3-rxm1 */
+		.bank_num = 1,
+		.pin = 15,
+		.func = 2,
+		.route_offset = 0x184,
+		.route_val = BIT(16 + 9) | BIT(9),
+	},
+};
+
+static int px30_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
+{
+	struct rockchip_pinctrl_priv *priv = bank->priv;
+	int iomux_num = (pin / 8);
+	struct regmap *regmap;
+	int reg, ret, mask, mux_type;
+	u8 bit;
+	u32 data, route_reg, route_val;
+
+	regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
+				? priv->regmap_pmu : priv->regmap_base;
+
+	/* get basic quadrupel of mux registers and the correct reg inside */
+	mux_type = bank->iomux[iomux_num].type;
+	reg = bank->iomux[iomux_num].offset;
+	reg += rockchip_get_mux_data(mux_type, pin, &bit, &mask);
+
+	if (bank->route_mask & BIT(pin)) {
+		if (rockchip_get_mux_route(bank, pin, mux, &route_reg,
+					   &route_val)) {
+			ret = regmap_write(regmap, route_reg, route_val);
+			if (ret)
+				return ret;
+		}
+	}
+
+	data = (mask << (bit + 16));
+	data |= (mux & mask) << bit;
+	ret = regmap_write(regmap, reg, data);
+
+	return ret;
+}
+
+#define PX30_PULL_PMU_OFFSET		0x10
+#define PX30_PULL_GRF_OFFSET		0x60
+#define PX30_PULL_BITS_PER_PIN		2
+#define PX30_PULL_PINS_PER_REG		8
+#define PX30_PULL_BANK_STRIDE		16
+
+static void px30_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
+				       int pin_num, struct regmap **regmap,
+				       int *reg, u8 *bit)
+{
+	struct rockchip_pinctrl_priv *priv = bank->priv;
+
+	/* The first 32 pins of the first bank are located in PMU */
+	if (bank->bank_num == 0) {
+		*regmap = priv->regmap_pmu;
+		*reg = PX30_PULL_PMU_OFFSET;
+	} else {
+		*regmap = priv->regmap_base;
+		*reg = PX30_PULL_GRF_OFFSET;
+
+		/* correct the offset, as we're starting with the 2nd bank */
+		*reg -= 0x10;
+		*reg += bank->bank_num * PX30_PULL_BANK_STRIDE;
+	}
+
+	*reg += ((pin_num / PX30_PULL_PINS_PER_REG) * 4);
+	*bit = (pin_num % PX30_PULL_PINS_PER_REG);
+	*bit *= PX30_PULL_BITS_PER_PIN;
+}
+
+static int px30_set_pull(struct rockchip_pin_bank *bank,
+			 int pin_num, int pull)
+{
+	struct regmap *regmap;
+	int reg, ret;
+	u8 bit, type;
+	u32 data;
+
+	if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT)
+		return -ENOTSUPP;
+
+	px30_calc_pull_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
+	type = bank->pull_type[pin_num / 8];
+	ret = rockchip_translate_pull_value(type, pull);
+	if (ret < 0) {
+		debug("unsupported pull setting %d\n", pull);
+		return ret;
+	}
+
+	/* enable the write to the equivalent lower bits */
+	data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16);
+	data |= (ret << bit);
+	ret = regmap_write(regmap, reg, data);
+
+	return ret;
+}
+
+#define PX30_DRV_PMU_OFFSET		0x20
+#define PX30_DRV_GRF_OFFSET		0xf0
+#define PX30_DRV_BITS_PER_PIN		2
+#define PX30_DRV_PINS_PER_REG		8
+#define PX30_DRV_BANK_STRIDE		16
+
+static void px30_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
+				      int pin_num, struct regmap **regmap,
+				      int *reg, u8 *bit)
+{
+	struct rockchip_pinctrl_priv *priv = bank->priv;
+
+	/* The first 32 pins of the first bank are located in PMU */
+	if (bank->bank_num == 0) {
+		*regmap = priv->regmap_pmu;
+		*reg = PX30_DRV_PMU_OFFSET;
+	} else {
+		*regmap = priv->regmap_base;
+		*reg = PX30_DRV_GRF_OFFSET;
+
+		/* correct the offset, as we're starting with the 2nd bank */
+		*reg -= 0x10;
+		*reg += bank->bank_num * PX30_DRV_BANK_STRIDE;
+	}
+
+	*reg += ((pin_num / PX30_DRV_PINS_PER_REG) * 4);
+	*bit = (pin_num % PX30_DRV_PINS_PER_REG);
+	*bit *= PX30_DRV_BITS_PER_PIN;
+}
+
+static int px30_set_drive(struct rockchip_pin_bank *bank,
+			  int pin_num, int strength)
+{
+	struct regmap *regmap;
+	int reg, ret;
+	u32 data, rmask_bits, temp;
+	u8 bit;
+	int drv_type = bank->drv[pin_num / 8].drv_type;
+
+	px30_calc_drv_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
+	ret = rockchip_translate_drive_value(drv_type, strength);
+	if (ret < 0) {
+		debug("unsupported driver strength %d\n", strength);
+		return ret;
+	}
+
+	switch (drv_type) {
+	case DRV_TYPE_IO_1V8_3V0_AUTO:
+	case DRV_TYPE_IO_3V3_ONLY:
+		rmask_bits = ROCKCHIP_DRV_3BITS_PER_PIN;
+		switch (bit) {
+		case 0 ... 12:
+			/* regular case, nothing to do */
+			break;
+		case 15:
+			/*
+			 * drive-strength offset is special, as it is spread
+			 * over 2 registers, the bit data[15] contains bit 0
+			 * of the value while temp[1:0] contains bits 2 and 1
+			 */
+			data = (ret & 0x1) << 15;
+			temp = (ret >> 0x1) & 0x3;
+
+			data |= BIT(31);
+			ret = regmap_write(regmap, reg, data);
+			if (ret)
+				return ret;
+
+			temp |= (0x3 << 16);
+			reg += 0x4;
+			ret = regmap_write(regmap, reg, temp);
+
+			return ret;
+		case 18 ... 21:
+			/* setting fully enclosed in the second register */
+			reg += 4;
+			bit -= 16;
+			break;
+		default:
+			debug("unsupported bit: %d for pinctrl drive type: %d\n",
+			      bit, drv_type);
+			return -EINVAL;
+		}
+		break;
+	case DRV_TYPE_IO_DEFAULT:
+	case DRV_TYPE_IO_1V8_OR_3V0:
+	case DRV_TYPE_IO_1V8_ONLY:
+		rmask_bits = ROCKCHIP_DRV_BITS_PER_PIN;
+		break;
+	default:
+		debug("unsupported pinctrl drive type: %d\n",
+		      drv_type);
+		return -EINVAL;
+	}
+
+	/* enable the write to the equivalent lower bits */
+	data = ((1 << rmask_bits) - 1) << (bit + 16);
+	data |= (ret << bit);
+	ret = regmap_write(regmap, reg, data);
+
+	return ret;
+}
+
+#define PX30_SCHMITT_PMU_OFFSET			0x38
+#define PX30_SCHMITT_GRF_OFFSET			0xc0
+#define PX30_SCHMITT_PINS_PER_PMU_REG		16
+#define PX30_SCHMITT_BANK_STRIDE		16
+#define PX30_SCHMITT_PINS_PER_GRF_REG		8
+
+static int px30_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
+					 int pin_num,
+					 struct regmap **regmap,
+					 int *reg, u8 *bit)
+{
+	struct rockchip_pinctrl_priv *priv = bank->priv;
+	int pins_per_reg;
+
+	if (bank->bank_num == 0) {
+		*regmap = priv->regmap_pmu;
+		*reg = PX30_SCHMITT_PMU_OFFSET;
+		pins_per_reg = PX30_SCHMITT_PINS_PER_PMU_REG;
+	} else {
+		*regmap = priv->regmap_base;
+		*reg = PX30_SCHMITT_GRF_OFFSET;
+		pins_per_reg = PX30_SCHMITT_PINS_PER_GRF_REG;
+		*reg += (bank->bank_num - 1) * PX30_SCHMITT_BANK_STRIDE;
+	}
+	*reg += ((pin_num / pins_per_reg) * 4);
+	*bit = pin_num % pins_per_reg;
+
+	return 0;
+}
+
+static int px30_set_schmitt(struct rockchip_pin_bank *bank,
+			    int pin_num, int enable)
+{
+	struct regmap *regmap;
+	int reg;
+	u8 bit;
+	u32 data;
+
+	px30_calc_schmitt_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
+	/* enable the write to the equivalent lower bits */
+	data = BIT(bit + 16) | (enable << bit);
+
+	return regmap_write(regmap, reg, data);
+}
+
+static struct rockchip_pin_bank px30_pin_banks[] = {
+	PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU,
+					     IOMUX_SOURCE_PMU,
+					     IOMUX_SOURCE_PMU,
+					     IOMUX_SOURCE_PMU
+			    ),
+	PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_4BIT,
+					     IOMUX_WIDTH_4BIT,
+					     IOMUX_WIDTH_4BIT,
+					     IOMUX_WIDTH_4BIT
+			    ),
+	PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_4BIT,
+					     IOMUX_WIDTH_4BIT,
+					     IOMUX_WIDTH_4BIT,
+					     IOMUX_WIDTH_4BIT
+			    ),
+	PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_4BIT,
+					     IOMUX_WIDTH_4BIT,
+					     IOMUX_WIDTH_4BIT,
+					     IOMUX_WIDTH_4BIT
+			    ),
+};
+
+static struct rockchip_pin_ctrl px30_pin_ctrl = {
+	.pin_banks		= px30_pin_banks,
+	.nr_banks		= ARRAY_SIZE(px30_pin_banks),
+	.grf_mux_offset		= 0x0,
+	.pmu_mux_offset		= 0x0,
+	.grf_drv_offset		= 0xf0,
+	.pmu_drv_offset		= 0x20,
+	.iomux_routes		= px30_mux_route_data,
+	.niomux_routes		= ARRAY_SIZE(px30_mux_route_data),
+	.set_mux		= px30_set_mux,
+	.set_pull		= px30_set_pull,
+	.set_drive		= px30_set_drive,
+	.set_schmitt		= px30_set_schmitt,
+};
+
+static const struct udevice_id px30_pinctrl_ids[] = {
+	{
+		.compatible = "rockchip,px30-pinctrl",
+		.data = (ulong)&px30_pin_ctrl
+	},
+	{ }
+};
+
+U_BOOT_DRIVER(pinctrl_px30) = {
+	.name		= "rockchip_px30_pinctrl",
+	.id		= UCLASS_PINCTRL,
+	.of_match	= px30_pinctrl_ids,
+	.priv_auto_alloc_size = sizeof(struct rockchip_pinctrl_priv),
+	.ops		= &rockchip_pinctrl_ops,
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
+	.bind		= dm_scan_fdt_dev,
+#endif
+	.probe		= rockchip_pinctrl_probe,
+};
diff --git a/drivers/power/domain/Makefile b/drivers/power/domain/Makefile
index d0dce14..45bf9f6 100644
--- a/drivers/power/domain/Makefile
+++ b/drivers/power/domain/Makefile
@@ -5,7 +5,7 @@
 
 obj-$(CONFIG_$(SPL_)POWER_DOMAIN) += power-domain-uclass.o
 obj-$(CONFIG_BCM6328_POWER_DOMAIN) += bcm6328-power-domain.o
-obj-$(CONFIG_IMX8_POWER_DOMAIN) += imx8-power-domain.o
+obj-$(CONFIG_IMX8_POWER_DOMAIN) += imx8-power-domain-legacy.o imx8-power-domain.o
 obj-$(CONFIG_IMX8M_POWER_DOMAIN) += imx8m-power-domain.o
 obj-$(CONFIG_MTK_POWER_DOMAIN) += mtk-power-domain.o
 obj-$(CONFIG_MESON_GX_VPU_POWER_DOMAIN) += meson-gx-pwrc-vpu.o
diff --git a/drivers/power/domain/imx8-power-domain-legacy.c b/drivers/power/domain/imx8-power-domain-legacy.c
new file mode 100644
index 0000000..d51dbaa
--- /dev/null
+++ b/drivers/power/domain/imx8-power-domain-legacy.c
@@ -0,0 +1,315 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2017 NXP
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <power-domain-uclass.h>
+#include <asm/io.h>
+#include <asm/arch/power-domain.h>
+#include <dm/device-internal.h>
+#include <dm/device.h>
+#include <asm/arch/sci/sci.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct imx8_power_domain_priv {
+	bool state_on;
+};
+
+static int imx8_power_domain_request(struct power_domain *power_domain)
+{
+	debug("%s(power_domain=%p)\n", __func__, power_domain);
+
+	return 0;
+}
+
+static int imx8_power_domain_free(struct power_domain *power_domain)
+{
+	debug("%s(power_domain=%p)\n", __func__, power_domain);
+
+	return 0;
+}
+
+static int imx8_power_domain_on(struct power_domain *power_domain)
+{
+	struct udevice *dev = power_domain->dev;
+	struct imx8_power_domain_platdata *pdata;
+	struct imx8_power_domain_priv *ppriv;
+	sc_err_t ret;
+	int err;
+
+	struct power_domain parent_domain;
+	struct udevice *parent = dev_get_parent(dev);
+
+	/* Need to power on parent node first */
+	if (device_get_uclass_id(parent) == UCLASS_POWER_DOMAIN) {
+		parent_domain.dev = parent;
+		err = imx8_power_domain_on(&parent_domain);
+		if (err)
+			return err;
+	}
+
+	pdata = (struct imx8_power_domain_platdata *)dev_get_platdata(dev);
+	ppriv = (struct imx8_power_domain_priv *)dev_get_priv(dev);
+
+	debug("%s(power_domain=%s) resource_id %d\n", __func__, dev->name,
+	      pdata->resource_id);
+
+	/* Already powered on */
+	if (ppriv->state_on)
+		return 0;
+
+	if (pdata->resource_id != SC_R_LAST) {
+		ret = sc_pm_set_resource_power_mode(-1, pdata->resource_id,
+						    SC_PM_PW_MODE_ON);
+		if (ret) {
+			printf("Error: %s Power up failed! (error = %d)\n",
+			       dev->name, ret);
+			return -EIO;
+		}
+	}
+
+	ppriv->state_on = true;
+	debug("%s is powered on\n", dev->name);
+
+	return 0;
+}
+
+static int imx8_power_domain_off_node(struct power_domain *power_domain)
+{
+	struct udevice *dev = power_domain->dev;
+	struct udevice *child;
+	struct imx8_power_domain_priv *ppriv;
+	struct imx8_power_domain_priv *child_ppriv;
+	struct imx8_power_domain_platdata *pdata;
+	sc_err_t ret;
+
+	ppriv = dev_get_priv(dev);
+	pdata = dev_get_platdata(dev);
+
+	debug("%s, %s, state_on %d\n", __func__, dev->name, ppriv->state_on);
+
+	/* Already powered off */
+	if (!ppriv->state_on)
+		return 0;
+
+	/* Check if all subnodes are off */
+	for (device_find_first_child(dev, &child);
+		child;
+		device_find_next_child(&child)) {
+		if (device_active(child)) {
+			child_ppriv =
+			(struct imx8_power_domain_priv *)dev_get_priv(child);
+			if (child_ppriv->state_on)
+				return -EPERM;
+		}
+	}
+
+	if (pdata->resource_id != SC_R_LAST) {
+		if (!sc_rm_is_resource_owned(-1, pdata->resource_id)) {
+			printf("%s not owned by curr partition\n", dev->name);
+			return 0;
+		}
+		ret = sc_pm_set_resource_power_mode(-1, pdata->resource_id,
+						    SC_PM_PW_MODE_OFF);
+		if (ret) {
+			printf("Error: %s Power off failed! (error = %d)\n",
+			       dev->name, ret);
+			return -EIO;
+		}
+	}
+
+	ppriv->state_on = false;
+	debug("%s is powered off\n", dev->name);
+
+	return 0;
+}
+
+static int imx8_power_domain_off_parentnodes(struct power_domain *power_domain)
+{
+	struct udevice *dev = power_domain->dev;
+	struct udevice *parent = dev_get_parent(dev);
+	struct udevice *child;
+	struct imx8_power_domain_priv *ppriv;
+	struct imx8_power_domain_priv *child_ppriv;
+	struct imx8_power_domain_platdata *pdata;
+	sc_err_t ret;
+	struct power_domain parent_pd;
+
+	if (device_get_uclass_id(parent) == UCLASS_POWER_DOMAIN) {
+		pdata =
+		(struct imx8_power_domain_platdata *)dev_get_platdata(parent);
+		ppriv = (struct imx8_power_domain_priv *)dev_get_priv(parent);
+
+		debug("%s, %s, state_on %d\n", __func__, parent->name,
+		      ppriv->state_on);
+
+		/* Already powered off */
+		if (!ppriv->state_on)
+			return 0;
+
+		/*
+		 * Check if all sibling nodes are off. If yes,
+		 * power off parent
+		 */
+		for (device_find_first_child(parent, &child); child;
+		     device_find_next_child(&child)) {
+			if (device_active(child)) {
+				child_ppriv = (struct imx8_power_domain_priv *)
+						dev_get_priv(child);
+				/* Find a power on sibling */
+				if (child_ppriv->state_on) {
+					debug("sibling %s, state_on %d\n",
+					      child->name,
+					      child_ppriv->state_on);
+					return 0;
+				}
+			}
+		}
+
+		/* power off parent */
+		if (pdata->resource_id != SC_R_LAST) {
+			ret = sc_pm_set_resource_power_mode(-1,
+							    pdata->resource_id,
+							    SC_PM_PW_MODE_OFF);
+			if (ret) {
+				printf("%s Power off failed! (error = %d)\n",
+				       parent->name, ret);
+				return -EIO;
+			}
+		}
+
+		ppriv->state_on = false;
+		debug("%s is powered off\n", parent->name);
+
+		parent_pd.dev = parent;
+		imx8_power_domain_off_parentnodes(&parent_pd);
+	}
+
+	return 0;
+}
+
+static int imx8_power_domain_off(struct power_domain *power_domain)
+{
+	int ret;
+
+	debug("%s(power_domain=%p)\n", __func__, power_domain);
+
+	/* Turn off the node */
+	ret = imx8_power_domain_off_node(power_domain);
+	if (ret) {
+		debug("Can't power off the node of dev %s, ret = %d\n",
+		      power_domain->dev->name, ret);
+		return ret;
+	}
+
+	/* Turn off parent nodes, if sibling nodes are all off */
+	ret = imx8_power_domain_off_parentnodes(power_domain);
+	if (ret) {
+		printf("Failed to power off parent nodes of dev %s, ret = %d\n",
+		       power_domain->dev->name, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int imx8_power_domain_of_xlate(struct power_domain *power_domain,
+				      struct ofnode_phandle_args *args)
+{
+	debug("%s(power_domain=%p)\n", __func__, power_domain);
+
+	/* Do nothing to the xlate, since we don't have args used */
+
+	return 0;
+}
+
+static int imx8_power_domain_bind(struct udevice *dev)
+{
+	int offset;
+	const char *name;
+	int ret = 0;
+
+	debug("%s(dev=%p)\n", __func__, dev);
+
+	offset = dev_of_offset(dev);
+	for (offset = fdt_first_subnode(gd->fdt_blob, offset); offset > 0;
+	     offset = fdt_next_subnode(gd->fdt_blob, offset)) {
+		/* Bind the subnode to this driver */
+		name = fdt_get_name(gd->fdt_blob, offset, NULL);
+
+		ret = device_bind_with_driver_data(dev, dev->driver, name,
+						   dev->driver_data,
+						   offset_to_ofnode(offset),
+						   NULL);
+
+		if (ret == -ENODEV)
+			printf("Driver '%s' refuses to bind\n",
+			       dev->driver->name);
+
+		if (ret)
+			printf("Error binding driver '%s': %d\n",
+			       dev->driver->name, ret);
+	}
+
+	return 0;
+}
+
+static int imx8_power_domain_probe(struct udevice *dev)
+{
+	struct imx8_power_domain_priv *ppriv;
+
+	debug("%s(dev=%s)\n", __func__, dev->name);
+
+	ppriv = (struct imx8_power_domain_priv *)dev_get_priv(dev);
+
+	/* Set default to power off */
+	if (ppriv)
+		ppriv->state_on = false;
+
+	return 0;
+}
+
+static int imx8_power_domain_ofdata_to_platdata(struct udevice *dev)
+{
+	int reg;
+	struct imx8_power_domain_platdata *pdata = dev_get_platdata(dev);
+
+	reg = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), "reg", -1);
+	if (reg == -1) {
+		debug("%s: Invalid resource id %d\n", __func__, reg);
+		return -EINVAL;
+	}
+	pdata->resource_id = (sc_rsrc_t)reg;
+
+	debug("%s resource_id %d\n", __func__, pdata->resource_id);
+
+	return 0;
+}
+
+static const struct udevice_id imx8_power_domain_ids[] = {
+	{ .compatible = "nxp,imx8-pd" },
+	{ }
+};
+
+struct power_domain_ops imx8_power_domain_ops = {
+	.request = imx8_power_domain_request,
+	.free = imx8_power_domain_free,
+	.on = imx8_power_domain_on,
+	.off = imx8_power_domain_off,
+	.of_xlate = imx8_power_domain_of_xlate,
+};
+
+U_BOOT_DRIVER(imx8_power_domain) = {
+	.name = "imx8_power_domain",
+	.id = UCLASS_POWER_DOMAIN,
+	.of_match = imx8_power_domain_ids,
+	.bind = imx8_power_domain_bind,
+	.probe = imx8_power_domain_probe,
+	.ofdata_to_platdata = imx8_power_domain_ofdata_to_platdata,
+	.platdata_auto_alloc_size = sizeof(struct imx8_power_domain_platdata),
+	.priv_auto_alloc_size = sizeof(struct imx8_power_domain_priv),
+	.ops = &imx8_power_domain_ops,
+};
diff --git a/drivers/power/domain/imx8-power-domain.c b/drivers/power/domain/imx8-power-domain.c
index d51dbaa..aa76836 100644
--- a/drivers/power/domain/imx8-power-domain.c
+++ b/drivers/power/domain/imx8-power-domain.c
@@ -1,23 +1,15 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Copyright 2017 NXP
+ * Copyright 2019 NXP
  */
 
+#define DEBUG
 #include <common.h>
 #include <dm.h>
 #include <power-domain-uclass.h>
-#include <asm/io.h>
 #include <asm/arch/power-domain.h>
-#include <dm/device-internal.h>
-#include <dm/device.h>
 #include <asm/arch/sci/sci.h>
 
-DECLARE_GLOBAL_DATA_PTR;
-
-struct imx8_power_domain_priv {
-	bool state_on;
-};
-
 static int imx8_power_domain_request(struct power_domain *power_domain)
 {
 	debug("%s(power_domain=%p)\n", __func__, power_domain);
@@ -34,158 +26,16 @@
 
 static int imx8_power_domain_on(struct power_domain *power_domain)
 {
-	struct udevice *dev = power_domain->dev;
-	struct imx8_power_domain_platdata *pdata;
-	struct imx8_power_domain_priv *ppriv;
-	sc_err_t ret;
-	int err;
-
-	struct power_domain parent_domain;
-	struct udevice *parent = dev_get_parent(dev);
-
-	/* Need to power on parent node first */
-	if (device_get_uclass_id(parent) == UCLASS_POWER_DOMAIN) {
-		parent_domain.dev = parent;
-		err = imx8_power_domain_on(&parent_domain);
-		if (err)
-			return err;
-	}
-
-	pdata = (struct imx8_power_domain_platdata *)dev_get_platdata(dev);
-	ppriv = (struct imx8_power_domain_priv *)dev_get_priv(dev);
-
-	debug("%s(power_domain=%s) resource_id %d\n", __func__, dev->name,
-	      pdata->resource_id);
-
-	/* Already powered on */
-	if (ppriv->state_on)
-		return 0;
-
-	if (pdata->resource_id != SC_R_LAST) {
-		ret = sc_pm_set_resource_power_mode(-1, pdata->resource_id,
-						    SC_PM_PW_MODE_ON);
-		if (ret) {
-			printf("Error: %s Power up failed! (error = %d)\n",
-			       dev->name, ret);
-			return -EIO;
-		}
-	}
-
-	ppriv->state_on = true;
-	debug("%s is powered on\n", dev->name);
-
-	return 0;
-}
-
-static int imx8_power_domain_off_node(struct power_domain *power_domain)
-{
-	struct udevice *dev = power_domain->dev;
-	struct udevice *child;
-	struct imx8_power_domain_priv *ppriv;
-	struct imx8_power_domain_priv *child_ppriv;
-	struct imx8_power_domain_platdata *pdata;
-	sc_err_t ret;
-
-	ppriv = dev_get_priv(dev);
-	pdata = dev_get_platdata(dev);
-
-	debug("%s, %s, state_on %d\n", __func__, dev->name, ppriv->state_on);
-
-	/* Already powered off */
-	if (!ppriv->state_on)
-		return 0;
-
-	/* Check if all subnodes are off */
-	for (device_find_first_child(dev, &child);
-		child;
-		device_find_next_child(&child)) {
-		if (device_active(child)) {
-			child_ppriv =
-			(struct imx8_power_domain_priv *)dev_get_priv(child);
-			if (child_ppriv->state_on)
-				return -EPERM;
-		}
-	}
-
-	if (pdata->resource_id != SC_R_LAST) {
-		if (!sc_rm_is_resource_owned(-1, pdata->resource_id)) {
-			printf("%s not owned by curr partition\n", dev->name);
-			return 0;
-		}
-		ret = sc_pm_set_resource_power_mode(-1, pdata->resource_id,
-						    SC_PM_PW_MODE_OFF);
-		if (ret) {
-			printf("Error: %s Power off failed! (error = %d)\n",
-			       dev->name, ret);
-			return -EIO;
-		}
-	}
-
-	ppriv->state_on = false;
-	debug("%s is powered off\n", dev->name);
-
-	return 0;
-}
-
-static int imx8_power_domain_off_parentnodes(struct power_domain *power_domain)
-{
-	struct udevice *dev = power_domain->dev;
-	struct udevice *parent = dev_get_parent(dev);
-	struct udevice *child;
-	struct imx8_power_domain_priv *ppriv;
-	struct imx8_power_domain_priv *child_ppriv;
-	struct imx8_power_domain_platdata *pdata;
-	sc_err_t ret;
-	struct power_domain parent_pd;
-
-	if (device_get_uclass_id(parent) == UCLASS_POWER_DOMAIN) {
-		pdata =
-		(struct imx8_power_domain_platdata *)dev_get_platdata(parent);
-		ppriv = (struct imx8_power_domain_priv *)dev_get_priv(parent);
-
-		debug("%s, %s, state_on %d\n", __func__, parent->name,
-		      ppriv->state_on);
-
-		/* Already powered off */
-		if (!ppriv->state_on)
-			return 0;
-
-		/*
-		 * Check if all sibling nodes are off. If yes,
-		 * power off parent
-		 */
-		for (device_find_first_child(parent, &child); child;
-		     device_find_next_child(&child)) {
-			if (device_active(child)) {
-				child_ppriv = (struct imx8_power_domain_priv *)
-						dev_get_priv(child);
-				/* Find a power on sibling */
-				if (child_ppriv->state_on) {
-					debug("sibling %s, state_on %d\n",
-					      child->name,
-					      child_ppriv->state_on);
-					return 0;
-				}
-			}
-		}
-
-		/* power off parent */
-		if (pdata->resource_id != SC_R_LAST) {
-			ret = sc_pm_set_resource_power_mode(-1,
-							    pdata->resource_id,
-							    SC_PM_PW_MODE_OFF);
-			if (ret) {
-				printf("%s Power off failed! (error = %d)\n",
-				       parent->name, ret);
-				return -EIO;
-			}
-		}
+	u32 resource_id = power_domain->id;
+	int ret;
 
-		ppriv->state_on = false;
-		debug("%s is powered off\n", parent->name);
+	debug("%s: resource_id %u\n", __func__, resource_id);
 
-		parent_pd.dev = parent;
-		imx8_power_domain_off_parentnodes(&parent_pd);
+	ret = sc_pm_set_resource_power_mode(-1, resource_id, SC_PM_PW_MODE_ON);
+	if (ret) {
+		printf("Error: %u Power up failed! (error = %d)\n",
+		       resource_id, ret);
+		return ret;
 	}
 
 	return 0;
@@ -193,123 +43,45 @@
 
 static int imx8_power_domain_off(struct power_domain *power_domain)
 {
+	u32 resource_id = power_domain->id;
 	int ret;
 
-	debug("%s(power_domain=%p)\n", __func__, power_domain);
+	debug("%s: resource_id %u\n", __func__, resource_id);
 
-	/* Turn off the node */
-	ret = imx8_power_domain_off_node(power_domain);
+	ret = sc_pm_set_resource_power_mode(-1, resource_id, SC_PM_PW_MODE_OFF);
 	if (ret) {
-		debug("Can't power off the node of dev %s, ret = %d\n",
-		      power_domain->dev->name, ret);
+		printf("Error: %u Power off failed! (error = %d)\n",
+		       resource_id, ret);
 		return ret;
 	}
 
-	/* Turn off parent nodes, if sibling nodes are all off */
-	ret = imx8_power_domain_off_parentnodes(power_domain);
-	if (ret) {
-		printf("Failed to power off parent nodes of dev %s, ret = %d\n",
-		       power_domain->dev->name, ret);
-		return ret;
-	}
-
-	return 0;
-}
-
-static int imx8_power_domain_of_xlate(struct power_domain *power_domain,
-				      struct ofnode_phandle_args *args)
-{
-	debug("%s(power_domain=%p)\n", __func__, power_domain);
-
-	/* Do nothing to the xlate, since we don't have args used */
-
-	return 0;
-}
-
-static int imx8_power_domain_bind(struct udevice *dev)
-{
-	int offset;
-	const char *name;
-	int ret = 0;
-
-	debug("%s(dev=%p)\n", __func__, dev);
-
-	offset = dev_of_offset(dev);
-	for (offset = fdt_first_subnode(gd->fdt_blob, offset); offset > 0;
-	     offset = fdt_next_subnode(gd->fdt_blob, offset)) {
-		/* Bind the subnode to this driver */
-		name = fdt_get_name(gd->fdt_blob, offset, NULL);
-
-		ret = device_bind_with_driver_data(dev, dev->driver, name,
-						   dev->driver_data,
-						   offset_to_ofnode(offset),
-						   NULL);
-
-		if (ret == -ENODEV)
-			printf("Driver '%s' refuses to bind\n",
-			       dev->driver->name);
-
-		if (ret)
-			printf("Error binding driver '%s': %d\n",
-			       dev->driver->name, ret);
-	}
-
 	return 0;
 }
 
 static int imx8_power_domain_probe(struct udevice *dev)
 {
-	struct imx8_power_domain_priv *ppriv;
-
 	debug("%s(dev=%s)\n", __func__, dev->name);
 
-	ppriv = (struct imx8_power_domain_priv *)dev_get_priv(dev);
-
-	/* Set default to power off */
-	if (ppriv)
-		ppriv->state_on = false;
-
-	return 0;
-}
-
-static int imx8_power_domain_ofdata_to_platdata(struct udevice *dev)
-{
-	int reg;
-	struct imx8_power_domain_platdata *pdata = dev_get_platdata(dev);
-
-	reg = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), "reg", -1);
-	if (reg == -1) {
-		debug("%s: Invalid resource id %d\n", __func__, reg);
-		return -EINVAL;
-	}
-	pdata->resource_id = (sc_rsrc_t)reg;
-
-	debug("%s resource_id %d\n", __func__, pdata->resource_id);
-
 	return 0;
 }
 
 static const struct udevice_id imx8_power_domain_ids[] = {
-	{ .compatible = "nxp,imx8-pd" },
+	{ .compatible = "fsl,imx8qxp-scu-pd" },
+	{ .compatible = "fsl,scu-pd" },
 	{ }
 };
 
-struct power_domain_ops imx8_power_domain_ops = {
+struct power_domain_ops imx8_power_domain_ops_v2 = {
 	.request = imx8_power_domain_request,
 	.free = imx8_power_domain_free,
 	.on = imx8_power_domain_on,
 	.off = imx8_power_domain_off,
-	.of_xlate = imx8_power_domain_of_xlate,
 };
 
-U_BOOT_DRIVER(imx8_power_domain) = {
-	.name = "imx8_power_domain",
+U_BOOT_DRIVER(imx8_power_domain_v2) = {
+	.name = "imx8_power_domain_v2",
 	.id = UCLASS_POWER_DOMAIN,
 	.of_match = imx8_power_domain_ids,
-	.bind = imx8_power_domain_bind,
 	.probe = imx8_power_domain_probe,
-	.ofdata_to_platdata = imx8_power_domain_ofdata_to_platdata,
-	.platdata_auto_alloc_size = sizeof(struct imx8_power_domain_platdata),
-	.priv_auto_alloc_size = sizeof(struct imx8_power_domain_priv),
-	.ops = &imx8_power_domain_ops,
+	.ops = &imx8_power_domain_ops_v2,
 };
diff --git a/drivers/ram/Kconfig b/drivers/ram/Kconfig
index bb431cc..b454ceb 100644
--- a/drivers/ram/Kconfig
+++ b/drivers/ram/Kconfig
@@ -19,7 +19,7 @@
 
 config TPL_RAM
 	bool "Enable RAM support in TPL"
-	depends on RAM && TPL_DM
+	depends on RAM
 	help
 	  The RAM subsystem adds a small amount of overhead to the image.
 	  If this is acceptable and you have a need to use RAM drivers in
diff --git a/drivers/ram/rockchip/Kconfig b/drivers/ram/rockchip/Kconfig
index 4f274e0..b75d581 100644
--- a/drivers/ram/rockchip/Kconfig
+++ b/drivers/ram/rockchip/Kconfig
@@ -5,10 +5,15 @@
 	help
 	  This enables support for ram drivers Rockchip SoCs.
 
-if RAM_ROCKCHIP
+config ROCKCHIP_SDRAM_COMMON
+	bool "Enable rockchip sdram common driver"
+	depends on TPL_RAM || SPL_RAM
+	help
+	  This enable sdram common driver
 
 config RAM_ROCKCHIP_DEBUG
 	bool "Rockchip ram drivers debugging"
+	default y
 	help
 	  This enables debugging ram driver API's for the platforms
 	  based on Rockchip SoCs.
@@ -16,18 +21,10 @@
 	  This is an option for developers to understand the ram drivers
 	  initialization, configurations and etc.
 
-config RAM_RK3399
-	bool "Ram driver for Rockchip RK3399"
-	default ROCKCHIP_RK3399
-	help
-	  This enables ram drivers support for the platforms based on
-	  Rockchip RK3399 SoC.
-
 config RAM_RK3399_LPDDR4
 	bool "LPDDR4 support for Rockchip RK3399"
-	depends on RAM_RK3399
+	depends on RAM_ROCKCHIP && ROCKCHIP_RK3399
 	help
 	  This enables LPDDR4 sdram code support for the platforms based
 	  on Rockchip RK3399 SoC.
 
-endif # RAM_ROCKCHIP
diff --git a/drivers/ram/rockchip/Makefile b/drivers/ram/rockchip/Makefile
index feb1f82..c3ec89a 100644
--- a/drivers/ram/rockchip/Makefile
+++ b/drivers/ram/rockchip/Makefile
@@ -3,11 +3,13 @@
 # Copyright (c) 2017 Theobroma Systems Design und Consulting GmbH
 #
 
-obj-$(CONFIG_RAM_ROCKCHIP_DEBUG) += sdram_debug.o
+obj-$(CONFIG_ROCKCHIP_PX30) += sdram_px30.o sdram_pctl_px30.o sdram_phy_px30.o
 obj-$(CONFIG_ROCKCHIP_RK3368) = dmc-rk3368.o
 obj-$(CONFIG_ROCKCHIP_RK3128) = sdram_rk3128.o
 obj-$(CONFIG_ROCKCHIP_RK3188) = sdram_rk3188.o
 obj-$(CONFIG_ROCKCHIP_RK322X) = sdram_rk322x.o
 obj-$(CONFIG_ROCKCHIP_RK3288) = sdram_rk3288.o
-obj-$(CONFIG_ROCKCHIP_RK3328) = sdram_rk3328.o
-obj-$(CONFIG_RAM_RK3399) += sdram_rk3399.o
+obj-$(CONFIG_ROCKCHIP_RK3308) = sdram_rk3308.o
+obj-$(CONFIG_ROCKCHIP_RK3328) = sdram_rk3328.o sdram_pctl_px30.o sdram_phy_px30.o
+obj-$(CONFIG_ROCKCHIP_RK3399) += sdram_rk3399.o
+obj-$(CONFIG_ROCKCHIP_SDRAM_COMMON) += sdram_common.o
diff --git a/drivers/ram/rockchip/dmc-rk3368.c b/drivers/ram/rockchip/dmc-rk3368.c
index e52fc3b..9df8f8f 100644
--- a/drivers/ram/rockchip/dmc-rk3368.c
+++ b/drivers/ram/rockchip/dmc-rk3368.c
@@ -17,7 +17,7 @@
 #include <asm/arch-rockchip/grf_rk3368.h>
 #include <asm/arch-rockchip/ddr_rk3368.h>
 #include <asm/arch-rockchip/sdram.h>
-#include <asm/arch-rockchip/sdram_common.h>
+#include <asm/arch-rockchip/sdram_rk3288.h>
 
 struct dram_info {
 	struct ram_info info;
diff --git a/drivers/ram/rockchip/sdram-px30-ddr3-detect-333.inc b/drivers/ram/rockchip/sdram-px30-ddr3-detect-333.inc
new file mode 100644
index 0000000..76cd8dc
--- /dev/null
+++ b/drivers/ram/rockchip/sdram-px30-ddr3-detect-333.inc
@@ -0,0 +1,72 @@
+{
+	{
+		{
+			.rank = 0x1,
+			.col = 0xC,
+			.bk = 0x3,
+			.bw = 0x1,
+			.dbw = 0x0,
+			.row_3_4 = 0x0,
+			.cs0_row = 0x10,
+			.cs1_row = 0x10,
+			.cs0_high16bit_row = 0x10,
+			.cs1_high16bit_row = 0x10,
+			.ddrconfig = 0,
+		},
+		{
+			{0x290b0609},
+			{0x08020401},
+			{0x00000002},
+			{0x00001111},
+			{0x0000000c},
+			{0x00000222},
+			0x000000ff
+		}
+	},
+	{
+		.ddr_freq = 333,
+		.dramtype = DDR3,
+		.num_channels = 1,
+		.stride = 0,
+		.odt = 0,
+	},
+	{
+		{
+			{0x00000000, 0x43041001},	/* MSTR */
+			{0x00000064, 0x0028003b},	/* RFSHTMG */
+			{0x000000d0, 0x00020053},	/* INIT0 */
+			{0x000000d4, 0x00020000},	/* INIT1 */
+			{0x000000d8, 0x00000100},	/* INIT2 */
+			{0x000000dc, 0x03200000},	/* INIT3 */
+			{0x000000e0, 0x00000000},	/* INIT4 */
+			{0x000000e4, 0x00090000},	/* INIT5 */
+			{0x000000f4, 0x000f012f},	/* RANKCTL */
+			{0x00000100, 0x07090b06},	/* DRAMTMG0 */
+			{0x00000104, 0x00050209},	/* DRAMTMG1 */
+			{0x00000108, 0x03030407},	/* DRAMTMG2 */
+			{0x0000010c, 0x00202006},	/* DRAMTMG3 */
+			{0x00000110, 0x03020204},	/* DRAMTMG4 */
+			{0x00000114, 0x03030202},	/* DRAMTMG5 */
+			{0x00000120, 0x00000903},	/* DRAMTMG8 */
+			{0x00000180, 0x00800020},	/* ZQCTL0 */
+			{0x00000184, 0x00000000},	/* ZQCTL1 */
+			{0x00000190, 0x07010001},	/* DFITMG0 */
+			{0x00000198, 0x07000101},	/* DFILPCFG0 */
+			{0x000001a0, 0xc0400003},	/* DFIUPD0 */
+			{0x00000240, 0x06000604},	/* ODTCFG */
+			{0x00000244, 0x00000201},	/* ODTMAP */
+			{0x00000250, 0x00001f00},	/* SCHED */
+			{0x00000490, 0x00000001},	/* PCTRL_0 */
+			{0xffffffff, 0xffffffff}
+		}
+	},
+	{
+		{
+			{0x00000004, 0x0000000a},	/* PHYREG01 */
+			{0x00000028, 0x00000006},	/* PHYREG0A */
+			{0x0000002c, 0x00000000},	/* PHYREG0B */
+			{0x00000030, 0x00000005},	/* PHYREG0C */
+			{0xffffffff, 0xffffffff}
+		}
+	}
+},
diff --git a/drivers/ram/rockchip/sdram-px30-ddr4-detect-333.inc b/drivers/ram/rockchip/sdram-px30-ddr4-detect-333.inc
new file mode 100644
index 0000000..f804d28
--- /dev/null
+++ b/drivers/ram/rockchip/sdram-px30-ddr4-detect-333.inc
@@ -0,0 +1,75 @@
+{
+	{
+		{
+			.rank = 0x1,
+			.col = 0xA,
+			.bk = 0x2,
+			.bw = 0x1,
+			.dbw = 0x0,
+			.row_3_4 = 0x0,
+			.cs0_row = 0x11,
+			.cs1_row = 0x0,
+			.cs0_high16bit_row = 0x11,
+			.cs1_high16bit_row = 0x0,
+			.ddrconfig = 0,
+		},
+		{
+			{0x4d110a08},
+			{0x06020501},
+			{0x00000002},
+			{0x00001111},
+			{0x0000000c},
+			{0x0000022a},
+			0x000000ff
+		}
+	},
+	{
+		.ddr_freq = 333,
+		.dramtype = DDR4,
+		.num_channels = 1,
+		.stride = 0,
+		.odt = 0,
+	},
+	{
+		{
+			{0x00000000, 0x43049010},	/* MSTR */
+			{0x00000064, 0x0028003b},	/* RFSHTMG */
+			{0x000000d0, 0x00020053},	/* INIT0 */
+			{0x000000d4, 0x00220000},	/* INIT1 */
+			{0x000000d8, 0x00000100},	/* INIT2 */
+			{0x000000dc, 0x00040000},	/* INIT3 */
+			{0x000000e0, 0x00000000},	/* INIT4 */
+			{0x000000e4, 0x00110000},	/* INIT5 */
+			{0x000000e8, 0x00000420},	/* INIT6 */
+			{0x000000ec, 0x00000400},	/* INIT7 */
+			{0x000000f4, 0x000f012f},	/* RANKCTL */
+			{0x00000100, 0x09060b06},	/* DRAMTMG0 */
+			{0x00000104, 0x00020209},	/* DRAMTMG1 */
+			{0x00000108, 0x0505040a},	/* DRAMTMG2 */
+			{0x0000010c, 0x0040400c},	/* DRAMTMG3 */
+			{0x00000110, 0x05030206},	/* DRAMTMG4 */
+			{0x00000114, 0x03030202},	/* DRAMTMG5 */
+			{0x00000120, 0x03030b03},	/* DRAMTMG8 */
+			{0x00000124, 0x00020208},	/* DRAMTMG9 */
+			{0x00000180, 0x01000040},	/* ZQCTL0 */
+			{0x00000184, 0x00000000},	/* ZQCTL1 */
+			{0x00000190, 0x07030003},	/* DFITMG0 */
+			{0x00000198, 0x07000101},	/* DFILPCFG0 */
+			{0x000001a0, 0xc0400003},	/* DFIUPD0 */
+			{0x00000240, 0x06000604},	/* ODTCFG */
+			{0x00000244, 0x00000201},	/* ODTMAP */
+			{0x00000250, 0x00001f00},	/* SCHED */
+			{0x00000490, 0x00000001},	/* PCTRL_0 */
+			{0xffffffff, 0xffffffff}
+		}
+	},
+	{
+		{
+			{0x00000004, 0x0000000c},	/* PHYREG01 */
+			{0x00000028, 0x0000000a},	/* PHYREG0A */
+			{0x0000002c, 0x00000000},	/* PHYREG0B */
+			{0x00000030, 0x00000009},	/* PHYREG0C */
+			{0xffffffff, 0xffffffff}
+		}
+	}
+},
\ No newline at end of file
diff --git a/drivers/ram/rockchip/sdram-px30-ddr_skew.inc b/drivers/ram/rockchip/sdram-px30-ddr_skew.inc
new file mode 100644
index 0000000..f24343d
--- /dev/null
+++ b/drivers/ram/rockchip/sdram-px30-ddr_skew.inc
@@ -0,0 +1,121 @@
+		{
+			0x77,
+			0x88,
+			0x79,
+			0x79,
+			0x87,
+			0x97,
+			0x87,
+			0x78,
+			0x77,
+			0x78,
+			0x87,
+			0x88,
+			0x87,
+			0x87,
+			0x77
+		},
+		{
+			0x78,
+			0x78,
+			0x78,
+			0x78,
+			0x78,
+			0x78,
+			0x78,
+			0x78,
+			0x78,
+			0x69,
+			0x9,
+		},
+		{
+			0x77,
+			0x78,
+			0x77,
+			0x78,
+			0x77,
+			0x78,
+			0x77,
+			0x78,
+			0x77,
+			0x79,
+			0x9,
+		},
+		{
+			0x78,
+			0x78,
+			0x78,
+			0x78,
+			0x78,
+			0x78,
+			0x78,
+			0x78,
+			0x78,
+			0x69,
+			0x9,
+		},
+		{
+			0x77,
+			0x78,
+			0x77,
+			0x77,
+			0x77,
+			0x77,
+			0x77,
+			0x77,
+			0x77,
+			0x79,
+			0x9,
+		},
+		{
+			0x78,
+			0x78,
+			0x78,
+			0x78,
+			0x78,
+			0x78,
+			0x78,
+			0x78,
+			0x78,
+			0x69,
+			0x9,
+		},
+		{
+			0x77,
+			0x78,
+			0x77,
+			0x78,
+			0x77,
+			0x78,
+			0x77,
+			0x78,
+			0x77,
+			0x79,
+			0x9,
+		},
+		{
+			0x78,
+			0x78,
+			0x78,
+			0x78,
+			0x78,
+			0x78,
+			0x78,
+			0x78,
+			0x78,
+			0x69,
+			0x9,
+		},
+		{
+			0x77,
+			0x78,
+			0x77,
+			0x77,
+			0x77,
+			0x77,
+			0x77,
+			0x77,
+			0x77,
+			0x79,
+			0x9,
+		}
diff --git a/drivers/ram/rockchip/sdram-px30-lpddr2-detect-333.inc b/drivers/ram/rockchip/sdram-px30-lpddr2-detect-333.inc
new file mode 100644
index 0000000..948ade4
--- /dev/null
+++ b/drivers/ram/rockchip/sdram-px30-lpddr2-detect-333.inc
@@ -0,0 +1,73 @@
+{
+	{
+		{
+			.rank = 0x1,
+			.col = 0xC,
+			.bk = 0x3,
+			.bw = 0x1,
+			.dbw = 0x0,
+			.row_3_4 = 0x0,
+			.cs0_row = 0xF,
+			.cs1_row = 0xF,
+			.cs0_high16bit_row = 0xF,
+			.cs1_high16bit_row = 0xF,
+			.ddrconfig = 0,
+		},
+		{
+			{0x2b0c070a},
+			{0x08020303},
+			{0x00000002},
+			{0x00001111},
+			{0x0000000c},
+			{0x00000219},
+			0x000000ff
+		}
+	},
+	{
+		.ddr_freq = 333,
+		.dramtype = LPDDR2,
+		.num_channels = 1,
+		.stride = 0,
+		.odt = 0,
+	},
+	{
+		{
+			{0x00000000, 0x41041004},	/* MSTR */
+			{0x00000064, 0x00140023},	/* RFSHTMG */
+			{0x000000d0, 0x00220002},	/* INIT0 */
+			{0x000000d4, 0x00010000},	/* INIT1 */
+			{0x000000d8, 0x00000703},	/* INIT2 */
+			{0x000000dc, 0x00630005},	/* INIT3 */
+			{0x000000e0, 0x00010000},	/* INIT4 */
+			{0x000000e4, 0x00070003},	/* INIT5 */
+			{0x000000f4, 0x000f012f},	/* RANKCTL */
+			{0x00000100, 0x07090b07},	/* DRAMTMG0 */
+			{0x00000104, 0x0002010b},	/* DRAMTMG1 */
+			{0x00000108, 0x02040506},	/* DRAMTMG2 */
+			{0x0000010c, 0x00303000},	/* DRAMTMG3 */
+			{0x00000110, 0x04010204},	/* DRAMTMG4 */
+			{0x00000114, 0x01010303},	/* DRAMTMG5 */
+			{0x00000118, 0x02020003},	/* DRAMTMG6 */
+			{0x00000120, 0x00000303},	/* DRAMTMG8 */
+			{0x00000138, 0x00000025},	/* DRAMTMG14 */
+			{0x00000180, 0x003c000f},	/* ZQCTL0 */
+			{0x00000184, 0x00900000},	/* ZQCTL1 */
+			{0x00000190, 0x07020001},	/* DFITMG0 */
+			{0x00000198, 0x07000101},	/* DFILPCFG0 */
+			{0x000001a0, 0xc0400003},	/* DFIUPD0 */
+			{0x00000240, 0x07030718},	/* ODTCFG */
+			{0x00000250, 0x00001f00},	/* SCHED */
+			{0x00000490, 0x00000001},	/* PCTRL_0 */
+			{0xffffffff, 0xffffffff}
+		}
+	},
+	{
+		{
+			{0x00000004, 0x00000009},	/* PHYREG01 */
+			{0x00000028, 0x00000007},	/* PHYREG0A */
+			{0x0000002c, 0x00000000},	/* PHYREG0B */
+			{0x00000030, 0x00000004},	/* PHYREG0C */
+			{0xffffffff, 0xffffffff}
+		}
+	}
+},
diff --git a/drivers/ram/rockchip/sdram-px30-lpddr3-detect-333.inc b/drivers/ram/rockchip/sdram-px30-lpddr3-detect-333.inc
new file mode 100644
index 0000000..f694a0e
--- /dev/null
+++ b/drivers/ram/rockchip/sdram-px30-lpddr3-detect-333.inc
@@ -0,0 +1,74 @@
+{
+	{
+		{
+			.rank = 0x1,
+			.col = 0xC,
+			.bk = 0x3,
+			.bw = 0x1,
+			.dbw = 0x0,
+			.row_3_4 = 0x0,
+			.cs0_row = 0x10,
+			.cs1_row = 0x10,
+			.cs0_high16bit_row = 0x10,
+			.cs1_high16bit_row = 0x10,
+			.ddrconfig = 0,
+		},
+		{
+			{0x290a060a},
+			{0x08020303},
+			{0x00000002},
+			{0x00001111},
+			{0x0000000c},
+			{0x0000021a},
+			0x000000ff
+		}
+	},
+	{
+		.ddr_freq = 333,
+		.dramtype = LPDDR3,
+		.num_channels = 1,
+		.stride = 0,
+		.odt = 0,
+	},
+	{
+		{
+			{0x00000000, 0x43041008},	/* MSTR */
+			{0x00000064, 0x00140023},	/* RFSHTMG */
+			{0x000000d0, 0x00220002},	/* INIT0 */
+			{0x000000d4, 0x00010000},	/* INIT1 */
+			{0x000000d8, 0x00000703},	/* INIT2 */
+			{0x000000dc, 0x00830004},	/* INIT3 */
+			{0x000000e0, 0x00010000},	/* INIT4 */
+			{0x000000e4, 0x00070003},	/* INIT5 */
+			{0x000000f4, 0x000f012f},	/* RANKCTL */
+			{0x00000100, 0x06090b07},	/* DRAMTMG0 */
+			{0x00000104, 0x0002020b},	/* DRAMTMG1 */
+			{0x00000108, 0x02030506},	/* DRAMTMG2 */
+			{0x0000010c, 0x00505000},	/* DRAMTMG3 */
+			{0x00000110, 0x03020204},	/* DRAMTMG4 */
+			{0x00000114, 0x01010303},	/* DRAMTMG5 */
+			{0x00000118, 0x02020003},	/* DRAMTMG6 */
+			{0x00000120, 0x00000303},	/* DRAMTMG8 */
+			{0x00000138, 0x00000025},	/* DRAMTMG14 */
+			{0x00000180, 0x003c000f},	/* ZQCTL0 */
+			{0x00000184, 0x00900000},	/* ZQCTL1 */
+			{0x00000190, 0x07020000},	/* DFITMG0 */
+			{0x00000198, 0x07000101},	/* DFILPCFG0 */
+			{0x000001a0, 0xc0400003},	/* DFIUPD0 */
+			{0x00000240, 0x0900090c},	/* ODTCFG */
+			{0x00000244, 0x00000101},	/* ODTMAP */
+			{0x00000250, 0x00001f00},	/* SCHED */
+			{0x00000490, 0x00000001},	/* PCTRL_0 */
+			{0xffffffff, 0xffffffff}
+		}
+	},
+	{
+		{
+			{0x00000004, 0x0000000b},	/* PHYREG01 */
+			{0x00000028, 0x00000006},	/* PHYREG0A */
+			{0x0000002c, 0x00000000},	/* PHYREG0B */
+			{0x00000030, 0x00000003},	/* PHYREG0C */
+			{0xffffffff, 0xffffffff}
+		}
+	}
+},
diff --git a/drivers/ram/rockchip/sdram-rk3399-lpddr4-400.inc b/drivers/ram/rockchip/sdram-rk3399-lpddr4-400.inc
index c50a03d..209ef57 100644
--- a/drivers/ram/rockchip/sdram-rk3399-lpddr4-400.inc
+++ b/drivers/ram/rockchip/sdram-rk3399-lpddr4-400.inc
@@ -16,15 +16,23 @@
 				.row_3_4 = 0x0,
 				.cs0_row = 0xF,
 				.cs1_row = 0xF,
+				.cs0_high16bit_row = 0xF,
+				.cs1_high16bit_row = 0xF,
 				.ddrconfig = 1,
 			},
 			{
-				.ddrtiminga0 = 0x80241d22,
-				.ddrtimingb0 = 0x15050f08,
+				.ddrtiminga0 = {
+					0x8010100d,
+				},
+				.ddrtimingb0 = {
+					0x08020b04,
+				},
 				.ddrtimingc0 = {
 					0x00000602,
 				},
+				.devtodev0 = {
+					0x00002562,
+				},
-				.devtodev0 = 0x00002122,
 				.ddrmode = {
 					0x0000004c,
 				},
@@ -41,15 +49,23 @@
 				.row_3_4 = 0x0,
 				.cs0_row = 0xF,
 				.cs1_row = 0xF,
+				.cs0_high16bit_row = 0xF,
+				.cs1_high16bit_row = 0xF,
 				.ddrconfig = 1,
 			},
 			{
-				.ddrtiminga0 = 0x80241d22,
-				.ddrtimingb0 = 0x15050f08,
+				.ddrtiminga0 = {
+					0x8010100d,
+				},
+				.ddrtimingb0 = {
+					0x08020b04,
+				},
 				.ddrtimingc0 = {
 					0x00000602,
 				},
-				.devtodev0 = 0x00002122,
+				.devtodev0 = {
+					0x00002562,
+				},
 				.ddrmode = {
 					0x0000004c,
 				},
diff --git a/drivers/ram/rockchip/sdram-rk3399-lpddr4-800.inc b/drivers/ram/rockchip/sdram-rk3399-lpddr4-800.inc
index d8ae335..7d11b4c 100644
--- a/drivers/ram/rockchip/sdram-rk3399-lpddr4-800.inc
+++ b/drivers/ram/rockchip/sdram-rk3399-lpddr4-800.inc
@@ -16,15 +16,23 @@
 				.row_3_4 = 0x0,
 				.cs0_row = 0xF,
 				.cs1_row = 0xF,
+				.cs0_high16bit_row = 0xF,
+				.cs1_high16bit_row = 0xF,
 				.ddrconfig = 1,
 			},
 			{
-				.ddrtiminga0 = 0x80241d22,
-				.ddrtimingb0 = 0x15050f08,
+				.ddrtiminga0 = {
+					0x801c1819,
+				},
+				.ddrtimingb0 = {
+					0x10040c05,
+				},
 				.ddrtimingc0 = {
 					0x00000602,
 				},
+				.devtodev0 = {
+					0x00002672,
+				},
-				.devtodev0 = 0x00002122,
 				.ddrmode = {
 					0x0000004c,
 				},
@@ -41,15 +49,23 @@
 				.row_3_4 = 0x0,
 				.cs0_row = 0xF,
 				.cs1_row = 0xF,
+				.cs0_high16bit_row = 0xF,
+				.cs1_high16bit_row = 0xF,
 				.ddrconfig = 1,
 			},
 			{
-				.ddrtiminga0 = 0x80241d22,
-				.ddrtimingb0 = 0x15050f08,
+				.ddrtiminga0 = {
+					0x80241d22,
+				},
+				.ddrtimingb0 = {
+					0x15050f08,
+				},
 				.ddrtimingc0 = {
 					0x00000602,
 				},
-				.devtodev0 = 0x00002122,
+				.devtodev0 = {
+					0x00002122,
+				},
 				.ddrmode = {
 					0x0000004c,
 				},
diff --git a/drivers/ram/rockchip/sdram_common.c b/drivers/ram/rockchip/sdram_common.c
new file mode 100644
index 0000000..6bc5157
--- /dev/null
+++ b/drivers/ram/rockchip/sdram_common.c
@@ -0,0 +1,429 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * (C) Copyright 2018 Rockchip Electronics Co., Ltd.
+ */
+
+#include <common.h>
+#include <debug_uart.h>
+#include <ram.h>
+#include <asm/io.h>
+#include <asm/arch-rockchip/sdram.h>
+#include <asm/arch-rockchip/sdram_common.h>
+
+#ifdef CONFIG_RAM_ROCKCHIP_DEBUG
+void sdram_print_dram_type(unsigned char dramtype)
+{
+	switch (dramtype) {
+	case DDR3:
+		printascii("DDR3");
+		break;
+	case DDR4:
+		printascii("DDR4");
+		break;
+	case LPDDR2:
+		printascii("LPDDR2");
+		break;
+	case LPDDR3:
+		printascii("LPDDR3");
+		break;
+	case LPDDR4:
+		printascii("LPDDR4");
+		break;
+	default:
+		printascii("Unknown Device");
+		break;
+	}
+}
+
+void sdram_print_ddr_info(struct sdram_cap_info *cap_info,
+			  struct sdram_base_params *base)
+{
+	u64 cap;
+	u32 bg;
+
+	bg = (cap_info->dbw == 0) ? 2 : 1;
+
+	sdram_print_dram_type(base->dramtype);
+
+	printascii(", ");
+	printdec(base->ddr_freq);
+	printascii("MHz\n");
+
+	printascii("BW=");
+	printdec(8 << cap_info->bw);
+	printascii(" Col=");
+	printdec(cap_info->col);
+	printascii(" Bk=");
+	printdec(0x1 << cap_info->bk);
+	if (base->dramtype == DDR4) {
+		printascii(" BG=");
+		printdec(1 << bg);
+	}
+	printascii(" CS0 Row=");
+	printdec(cap_info->cs0_row);
+	if (cap_info->cs0_high16bit_row !=
+		cap_info->cs0_row) {
+		printascii("/");
+		printdec(cap_info->cs0_high16bit_row);
+	}
+	if (cap_info->rank > 1) {
+		printascii(" CS1 Row=");
+		printdec(cap_info->cs1_row);
+		if (cap_info->cs1_high16bit_row !=
+			cap_info->cs1_row) {
+			printascii("/");
+			printdec(cap_info->cs1_high16bit_row);
+		}
+	}
+	printascii(" CS=");
+	printdec(cap_info->rank);
+	printascii(" Die BW=");
+	printdec(8 << cap_info->dbw);
+
+	cap = sdram_get_cs_cap(cap_info, 3, base->dramtype);
+	if (cap_info->row_3_4)
+		cap = cap * 3 / 4;
+
+	printascii(" Size=");
+	printdec(cap >> 20);
+	printascii("MB\n");
+}
+
+void sdram_print_stride(unsigned int stride)
+{
+	switch (stride) {
+	case 0xc:
+		printf("128B stride\n");
+		break;
+	case 5:
+	case 9:
+	case 0xd:
+	case 0x11:
+	case 0x19:
+		printf("256B stride\n");
+		break;
+	case 0xa:
+	case 0xe:
+	case 0x12:
+		printf("512B stride\n");
+		break;
+	case 0xf:
+		printf("4K stride\n");
+		break;
+	case 0x1f:
+		printf("32MB + 256B stride\n");
+		break;
+	default:
+		printf("no stride\n");
+	}
+}
+#endif
+
+/*
+ * cs: 0:cs0
+ *	   1:cs1
+ *     else cs0+cs1
+ * note: it didn't consider about row_3_4
+ */
+u64 sdram_get_cs_cap(struct sdram_cap_info *cap_info, u32 cs, u32 dram_type)
+{
+	u32 bg;
+	u64 cap[2];
+
+	if (dram_type == DDR4)
+		/* DDR4 8bit dram BG = 2(4bank groups),
+		 * 16bit dram BG = 1 (2 bank groups)
+		 */
+		bg = (cap_info->dbw == 0) ? 2 : 1;
+	else
+		bg = 0;
+	cap[0] = 1llu << (cap_info->bw + cap_info->col +
+		bg + cap_info->bk + cap_info->cs0_row);
+
+	if (cap_info->rank == 2)
+		cap[1] = 1llu << (cap_info->bw + cap_info->col +
+			bg + cap_info->bk + cap_info->cs1_row);
+	else
+		cap[1] = 0;
+
+	if (cs == 0)
+		return cap[0];
+	else if (cs == 1)
+		return cap[1];
+	else
+		return (cap[0] + cap[1]);
+}
+
+/* n: Unit bytes */
+void sdram_copy_to_reg(u32 *dest, const u32 *src, u32 n)
+{
+	int i;
+
+	for (i = 0; i < n / sizeof(u32); i++) {
+		writel(*src, dest);
+		src++;
+		dest++;
+	}
+}
+
+void sdram_org_config(struct sdram_cap_info *cap_info,
+		      struct sdram_base_params *base,
+		      u32 *p_os_reg2, u32 *p_os_reg3, u32 channel)
+{
+	*p_os_reg2 |= SYS_REG_ENC_DDRTYPE(base->dramtype);
+	*p_os_reg2 |= SYS_REG_ENC_NUM_CH(base->num_channels);
+
+	*p_os_reg2 |= SYS_REG_ENC_ROW_3_4(cap_info->row_3_4, channel);
+	*p_os_reg2 |= SYS_REG_ENC_CHINFO(channel);
+	*p_os_reg2 |= SYS_REG_ENC_RANK(cap_info->rank, channel);
+	*p_os_reg2 |= SYS_REG_ENC_COL(cap_info->col, channel);
+	*p_os_reg2 |= SYS_REG_ENC_BK(cap_info->bk, channel);
+	*p_os_reg2 |= SYS_REG_ENC_BW(cap_info->bw, channel);
+	*p_os_reg2 |= SYS_REG_ENC_DBW(cap_info->dbw, channel);
+
+	SYS_REG_ENC_CS0_ROW(cap_info->cs0_row, *p_os_reg2, *p_os_reg3, channel);
+	if (cap_info->cs1_row)
+		SYS_REG_ENC_CS1_ROW(cap_info->cs1_row, *p_os_reg2,
+				    *p_os_reg3, channel);
+	*p_os_reg3 |= SYS_REG_ENC_CS1_COL(cap_info->col, channel);
+	*p_os_reg3 |= SYS_REG_ENC_VERSION(DDR_SYS_REG_VERSION);
+}
+
+int sdram_detect_bw(struct sdram_cap_info *cap_info)
+{
+	return 0;
+}
+
+int sdram_detect_cs(struct sdram_cap_info *cap_info)
+{
+	return 0;
+}
+
+int sdram_detect_col(struct sdram_cap_info *cap_info,
+		     u32 coltmp)
+{
+	void __iomem *test_addr;
+	u32 col;
+	u32 bw = cap_info->bw;
+
+	for (col = coltmp; col >= 9; col -= 1) {
+		writel(0, CONFIG_SYS_SDRAM_BASE);
+		test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
+				(1ul << (col + bw - 1ul)));
+		writel(PATTERN, test_addr);
+		if ((readl(test_addr) == PATTERN) &&
+		    (readl(CONFIG_SYS_SDRAM_BASE) == 0))
+			break;
+	}
+	if (col == 8) {
+		printascii("col error\n");
+		return -1;
+	}
+
+	cap_info->col = col;
+
+	return 0;
+}
+
+int sdram_detect_bank(struct sdram_cap_info *cap_info,
+		      u32 coltmp, u32 bktmp)
+{
+	void __iomem *test_addr;
+	u32 bk;
+	u32 bw = cap_info->bw;
+
+	test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
+			(1ul << (coltmp + bktmp + bw - 1ul)));
+	writel(0, CONFIG_SYS_SDRAM_BASE);
+	writel(PATTERN, test_addr);
+	if ((readl(test_addr) == PATTERN) &&
+	    (readl(CONFIG_SYS_SDRAM_BASE) == 0))
+		bk = 3;
+	else
+		bk = 2;
+
+	cap_info->bk = bk;
+
+	return 0;
+}
+
+/* detect bg for ddr4 */
+int sdram_detect_bg(struct sdram_cap_info *cap_info,
+		    u32 coltmp)
+{
+	void __iomem *test_addr;
+	u32 dbw;
+	u32 bw = cap_info->bw;
+
+	test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
+			(1ul << (coltmp + bw + 1ul)));
+	writel(0, CONFIG_SYS_SDRAM_BASE);
+	writel(PATTERN, test_addr);
+	if ((readl(test_addr) == PATTERN) &&
+	    (readl(CONFIG_SYS_SDRAM_BASE) == 0))
+		dbw = 0;
+	else
+		dbw = 1;
+
+	cap_info->dbw = dbw;
+
+	return 0;
+}
+
+/* detect dbw for ddr3,lpddr2,lpddr3,lpddr4 */
+int sdram_detect_dbw(struct sdram_cap_info *cap_info, u32 dram_type)
+{
+	u32 row, col, bk, bw, cs_cap, cs;
+	u32 die_bw_0 = 0, die_bw_1 = 0;
+
+	if (dram_type == DDR3 || dram_type == LPDDR4) {
+		cap_info->dbw = 1;
+	} else if (dram_type == LPDDR3 || dram_type == LPDDR2) {
+		row = cap_info->cs0_row;
+		col = cap_info->col;
+		bk = cap_info->bk;
+		cs = cap_info->rank;
+		bw = cap_info->bw;
+		cs_cap = (1 << (row + col + bk + bw - 20));
+		if (bw == 2) {
+			if (cs_cap <= 0x2000000) /* 256Mb */
+				die_bw_0 = (col < 9) ? 2 : 1;
+			else if (cs_cap <= 0x10000000) /* 2Gb */
+				die_bw_0 = (col < 10) ? 2 : 1;
+			else if (cs_cap <= 0x40000000) /* 8Gb */
+				die_bw_0 = (col < 11) ? 2 : 1;
+			else
+				die_bw_0 = (col < 12) ? 2 : 1;
+			if (cs > 1) {
+				row = cap_info->cs1_row;
+				cs_cap = (1 << (row + col + bk + bw - 20));
+				if (cs_cap <= 0x2000000) /* 256Mb */
+					die_bw_0 = (col < 9) ? 2 : 1;
+				else if (cs_cap <= 0x10000000) /* 2Gb */
+					die_bw_0 = (col < 10) ? 2 : 1;
+				else if (cs_cap <= 0x40000000) /* 8Gb */
+					die_bw_0 = (col < 11) ? 2 : 1;
+				else
+					die_bw_0 = (col < 12) ? 2 : 1;
+			}
+		} else {
+			die_bw_1 = 1;
+			die_bw_0 = 1;
+		}
+		cap_info->dbw = (die_bw_0 > die_bw_1) ? die_bw_0 : die_bw_1;
+	}
+
+	return 0;
+}
+
+int sdram_detect_row(struct sdram_cap_info *cap_info,
+		     u32 coltmp, u32 bktmp, u32 rowtmp)
+{
+	u32 row;
+	u32 bw = cap_info->bw;
+	void __iomem *test_addr;
+
+	for (row = rowtmp; row > 12; row--) {
+		writel(0, CONFIG_SYS_SDRAM_BASE);
+		test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
+				(1ul << (row + bktmp + coltmp + bw - 1ul)));
+		writel(PATTERN, test_addr);
+		if ((readl(test_addr) == PATTERN) &&
+		    (readl(CONFIG_SYS_SDRAM_BASE) == 0))
+			break;
+	}
+	if (row == 12) {
+		printascii("row error");
+		return -1;
+	}
+
+	cap_info->cs0_row = row;
+
+	return 0;
+}
+
+int sdram_detect_row_3_4(struct sdram_cap_info *cap_info,
+			 u32 coltmp, u32 bktmp)
+{
+	u32 row_3_4;
+	u32 bw = cap_info->bw;
+	u32 row = cap_info->cs0_row;
+	void __iomem *test_addr, *test_addr1;
+
+	test_addr = CONFIG_SYS_SDRAM_BASE;
+	test_addr1 = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
+			(0x3ul << (row + bktmp + coltmp + bw - 1ul - 1ul)));
+
+	writel(0, test_addr);
+	writel(PATTERN, test_addr1);
+	if ((readl(test_addr) == 0) && (readl(test_addr1) == PATTERN))
+		row_3_4 = 0;
+	else
+		row_3_4 = 1;
+
+	cap_info->row_3_4 = row_3_4;
+
+	return 0;
+}
+
+int sdram_detect_high_row(struct sdram_cap_info *cap_info)
+{
+	cap_info->cs0_high16bit_row = cap_info->cs0_row;
+	cap_info->cs1_high16bit_row = cap_info->cs1_row;
+
+	return 0;
+}
+
+int sdram_detect_cs1_row(struct sdram_cap_info *cap_info, u32 dram_type)
+{
+	void __iomem *test_addr;
+	u32 row = 0, bktmp, coltmp, bw;
+	ulong cs0_cap;
+	u32 byte_mask;
+
+	if (cap_info->rank == 2) {
+		cs0_cap = sdram_get_cs_cap(cap_info, 0, dram_type);
+
+		if (dram_type == DDR4) {
+			if (cap_info->dbw == 0)
+				bktmp = cap_info->bk + 2;
+			else
+				bktmp = cap_info->bk + 1;
+		} else {
+			bktmp = cap_info->bk;
+		}
+		bw = cap_info->bw;
+		coltmp = cap_info->col;
+
+		/*
+		 * because px30 support axi split,min bandwidth
+		 * is 8bit. if cs0 is 32bit, cs1 may 32bit or 16bit
+		 * so we check low 16bit data when detect cs1 row.
+		 * if cs0 is 16bit/8bit, we check low 8bit data.
+		 */
+		if (bw == 2)
+			byte_mask = 0xFFFF;
+		else
+			byte_mask = 0xFF;
+
+		/* detect cs1 row */
+		for (row = cap_info->cs0_row; row > 12; row--) {
+			test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
+				    cs0_cap +
+				    (1ul << (row + bktmp + coltmp + bw - 1ul)));
+			writel(0, CONFIG_SYS_SDRAM_BASE + cs0_cap);
+			writel(PATTERN, test_addr);
+
+			if (((readl(test_addr) & byte_mask) ==
+			     (PATTERN & byte_mask)) &&
+			    ((readl(CONFIG_SYS_SDRAM_BASE + cs0_cap) &
+			      byte_mask) == 0)) {
+				break;
+			}
+		}
+	}
+
+	cap_info->cs1_row = row;
+
+	return 0;
+}
diff --git a/drivers/ram/rockchip/sdram_debug.c b/drivers/ram/rockchip/sdram_debug.c
deleted file mode 100644
index 9cf6626..0000000
--- a/drivers/ram/rockchip/sdram_debug.c
+++ /dev/null
@@ -1,147 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
-/*
- * (C) Copyright 2019 Rockchip Electronics Co., Ltd
- * (C) Copyright 2019 Amarula Solutions.
- * Author: Jagan Teki <jagan@amarulasolutions.com>
- */
-
-#include <common.h>
-#include <debug_uart.h>
-#include <asm/arch-rockchip/sdram_common.h>
-
-void sdram_print_dram_type(unsigned char dramtype)
-{
-	switch (dramtype) {
-	case DDR3:
-		printascii("DDR3");
-		break;
-	case DDR4:
-		printascii("DDR4");
-		break;
-	case LPDDR2:
-		printascii("LPDDR2");
-		break;
-	case LPDDR3:
-		printascii("LPDDR3");
-		break;
-	case LPDDR4:
-		printascii("LPDDR4");
-		break;
-	default:
-		printascii("Unknown Device");
-		break;
-	}
-}
-
-/**
- * cs  = 0, cs0
- * cs  = 1, cs1
- * cs => 2, cs0+cs1
- * note: it didn't consider about row_3_4
- */
-u64 sdram_get_cs_cap(struct sdram_cap_info *cap_info, u32 cs, u32 dram_type)
-{
-	u32 bg;
-	u64 cap[2];
-
-	if (dram_type == DDR4)
-		/* DDR4 8bit dram BG = 2(4bank groups),
-		 * 16bit dram BG = 1 (2 bank groups)
-		 */
-		bg = (cap_info->dbw == 0) ? 2 : 1;
-	else
-		bg = 0;
-
-	cap[0] = 1llu << (cap_info->bw + cap_info->col +
-		 bg + cap_info->bk + cap_info->cs0_row);
-
-	if (cap_info->rank == 2)
-		cap[1] = 1llu << (cap_info->bw + cap_info->col +
-			 bg + cap_info->bk + cap_info->cs1_row);
-	else
-		cap[1] = 0;
-
-	if (cs == 0)
-		return cap[0];
-	else if (cs == 1)
-		return cap[1];
-	else
-		return (cap[0] + cap[1]);
-}
-
-void sdram_print_ddr_info(struct sdram_cap_info *cap_info,
-			  struct sdram_base_params *base)
-{
-	u32 bg, cap;
-
-	bg = (cap_info->dbw == 0) ? 2 : 1;
-
-	sdram_print_dram_type(base->dramtype);
-
-	printascii(", ");
-	printdec(base->ddr_freq);
-	printascii("MHz\n");
-
-	printascii("BW=");
-	printdec(8 << cap_info->bw);
-
-	printascii(" Col=");
-	printdec(cap_info->col);
-
-	printascii(" Bk=");
-	printdec(0x1 << cap_info->bk);
-	if (base->dramtype == DDR4) {
-		printascii(" BG=");
-		printdec(1 << bg);
-	}
-
-	printascii(" CS0 Row=");
-	printdec(cap_info->cs0_row);
-	if (cap_info->rank > 1) {
-		printascii(" CS1 Row=");
-		printdec(cap_info->cs1_row);
-	}
-
-	printascii(" CS=");
-	printdec(cap_info->rank);
-
-	printascii(" Die BW=");
-	printdec(8 << cap_info->dbw);
-
-	cap = sdram_get_cs_cap(cap_info, 3, base->dramtype);
-	if (cap_info->row_3_4)
-		cap = cap * 3 / 4;
-
-	printascii(" Size=");
-	printdec(cap >> 20);
-	printascii("MB\n");
-}
-
-void sdram_print_stride(unsigned int stride)
-{
-	switch (stride) {
-	case 0xc:
-		printf("128B stride\n");
-		break;
-	case 5:
-	case 9:
-	case 0xd:
-	case 0x11:
-	case 0x19:
-		printf("256B stride\n");
-		break;
-	case 0xa:
-	case 0xe:
-	case 0x12:
-		printf("512B stride\n");
-		break;
-	case 0xf:
-		printf("4K stride\n");
-		break;
-	case 0x1f:
-		printf("32MB + 256B stride\n");
-		break;
-	default:
-		printf("no stride\n");
-	}
-}
diff --git a/drivers/ram/rockchip/sdram_pctl_px30.c b/drivers/ram/rockchip/sdram_pctl_px30.c
new file mode 100644
index 0000000..1839ceb
--- /dev/null
+++ b/drivers/ram/rockchip/sdram_pctl_px30.c
@@ -0,0 +1,205 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * (C) Copyright 2018 Rockchip Electronics Co., Ltd.
+ */
+
+#include <common.h>
+#include <ram.h>
+#include <asm/io.h>
+#include <asm/arch-rockchip/sdram.h>
+#include <asm/arch-rockchip/sdram_pctl_px30.h>
+
+/*
+ * rank = 1: cs0
+ * rank = 2: cs1
+ */
+void pctl_read_mr(void __iomem *pctl_base, u32 rank, u32 mr_num)
+{
+	writel((rank << 4) | (1 << 0), pctl_base + DDR_PCTL2_MRCTRL0);
+	writel((mr_num << 8), pctl_base + DDR_PCTL2_MRCTRL1);
+	setbits_le32(pctl_base + DDR_PCTL2_MRCTRL0, 1u << 31);
+	while (readl(pctl_base + DDR_PCTL2_MRCTRL0) & (1u << 31))
+		continue;
+	while (readl(pctl_base + DDR_PCTL2_MRSTAT) & MR_WR_BUSY)
+		continue;
+}
+
+/* rank = 1: cs0
+ * rank = 2: cs1
+ * rank = 3: cs0 & cs1
+ * note: be careful of keep mr original val
+ */
+int pctl_write_mr(void __iomem *pctl_base, u32 rank, u32 mr_num, u32 arg,
+		  u32 dramtype)
+{
+	while (readl(pctl_base + DDR_PCTL2_MRSTAT) & MR_WR_BUSY)
+		continue;
+	if (dramtype == DDR3 || dramtype == DDR4) {
+		writel((mr_num << 12) | (rank << 4) | (0 << 0),
+		       pctl_base + DDR_PCTL2_MRCTRL0);
+		writel(arg, pctl_base + DDR_PCTL2_MRCTRL1);
+	} else {
+		writel((rank << 4) | (0 << 0),
+		       pctl_base + DDR_PCTL2_MRCTRL0);
+		writel((mr_num << 8) | (arg & 0xff),
+		       pctl_base + DDR_PCTL2_MRCTRL1);
+	}
+
+	setbits_le32(pctl_base + DDR_PCTL2_MRCTRL0, 1u << 31);
+	while (readl(pctl_base + DDR_PCTL2_MRCTRL0) & (1u << 31))
+		continue;
+	while (readl(pctl_base + DDR_PCTL2_MRSTAT) & MR_WR_BUSY)
+		continue;
+
+	return 0;
+}
+
+/*
+ * rank : 1:cs0, 2:cs1, 3:cs0&cs1
+ * vrefrate: 4500: 45%,
+ */
+int pctl_write_vrefdq(void __iomem *pctl_base, u32 rank, u32 vrefrate,
+		      u32 dramtype)
+{
+	u32 tccd_l, value;
+	u32 dis_auto_zq = 0;
+
+	if (dramtype != DDR4 || vrefrate < 4500 ||
+	    vrefrate > 9200)
+		return (-1);
+
+	tccd_l = (readl(pctl_base + DDR_PCTL2_DRAMTMG4) >> 16) & 0xf;
+	tccd_l = (tccd_l - 4) << 10;
+
+	if (vrefrate > 7500) {
+		/* range 1 */
+		value = ((vrefrate - 6000) / 65) | tccd_l;
+	} else {
+		/* range 2 */
+		value = ((vrefrate - 4500) / 65) | tccd_l | (1 << 6);
+	}
+
+	dis_auto_zq = pctl_dis_zqcs_aref(pctl_base);
+
+	/* enable vrefdq calibratin */
+	pctl_write_mr(pctl_base, rank, 6, value | (1 << 7), dramtype);
+	udelay(1);/* tvrefdqe */
+	/* write vrefdq value */
+	pctl_write_mr(pctl_base, rank, 6, value | (1 << 7), dramtype);
+	udelay(1);/* tvref_time */
+	pctl_write_mr(pctl_base, rank, 6, value | (0 << 7), dramtype);
+	udelay(1);/* tvrefdqx */
+
+	pctl_rest_zqcs_aref(pctl_base, dis_auto_zq);
+
+	return 0;
+}
+
+static int upctl2_update_ref_reg(void __iomem *pctl_base)
+{
+	u32 ret;
+
+	ret = readl(pctl_base + DDR_PCTL2_RFSHCTL3) ^ (1 << 1);
+	writel(ret, pctl_base + DDR_PCTL2_RFSHCTL3);
+
+	return 0;
+}
+
+u32 pctl_dis_zqcs_aref(void __iomem *pctl_base)
+{
+	u32 dis_auto_zq = 0;
+
+	/* disable zqcs */
+	if (!(readl(pctl_base + DDR_PCTL2_ZQCTL0) &
+		(1ul << 31))) {
+		dis_auto_zq = 1;
+		setbits_le32(pctl_base + DDR_PCTL2_ZQCTL0, 1 << 31);
+	}
+
+	/* disable auto refresh */
+	setbits_le32(pctl_base + DDR_PCTL2_RFSHCTL3, 1);
+
+	upctl2_update_ref_reg(pctl_base);
+
+	return dis_auto_zq;
+}
+
+void pctl_rest_zqcs_aref(void __iomem *pctl_base, u32 dis_auto_zq)
+{
+	/* restore zqcs */
+	if (dis_auto_zq)
+		clrbits_le32(pctl_base + DDR_PCTL2_ZQCTL0, 1 << 31);
+
+	/* restore auto refresh */
+	clrbits_le32(pctl_base + DDR_PCTL2_RFSHCTL3, 1);
+
+	upctl2_update_ref_reg(pctl_base);
+}
+
+u32 pctl_remodify_sdram_params(struct ddr_pctl_regs *pctl_regs,
+			       struct sdram_cap_info *cap_info,
+			       u32 dram_type)
+{
+	u32 tmp = 0, tmp_adr = 0, i;
+
+	for (i = 0; pctl_regs->pctl[i][0] != 0xFFFFFFFF; i++) {
+		if (pctl_regs->pctl[i][0] == 0) {
+			tmp = pctl_regs->pctl[i][1];/* MSTR */
+			tmp_adr = i;
+		}
+	}
+
+	tmp &= ~((3ul << 30) | (3ul << 24) | (3ul << 12));
+
+	switch (cap_info->dbw) {
+	case 2:
+		tmp |= (3ul << 30);
+		break;
+	case 1:
+		tmp |= (2ul << 30);
+		break;
+	case 0:
+	default:
+		tmp |= (1ul << 30);
+		break;
+	}
+
+	/*
+	 * If DDR3 or DDR4 MSTR.active_ranks=1,
+	 * it will gate memory clock when enter power down.
+	 * Force set active_ranks to 3 to workaround it.
+	 */
+	if (cap_info->rank == 2 || dram_type == DDR3 ||
+	    dram_type == DDR4)
+		tmp |= 3 << 24;
+	else
+		tmp |= 1 << 24;
+
+	tmp |= (2 - cap_info->bw) << 12;
+
+	pctl_regs->pctl[tmp_adr][1] = tmp;
+
+	return 0;
+}
+
+int pctl_cfg(void __iomem *pctl_base, struct ddr_pctl_regs *pctl_regs,
+	     u32 sr_idle, u32 pd_idle)
+{
+	u32 i;
+
+	for (i = 0; pctl_regs->pctl[i][0] != 0xFFFFFFFF; i++) {
+		writel(pctl_regs->pctl[i][1],
+		       pctl_base + pctl_regs->pctl[i][0]);
+	}
+	clrsetbits_le32(pctl_base + DDR_PCTL2_PWRTMG,
+			(0xff << 16) | 0x1f,
+			((sr_idle & 0xff) << 16) | (pd_idle & 0x1f));
+
+	clrsetbits_le32(pctl_base + DDR_PCTL2_HWLPCTL,
+			0xfff << 16,
+			5 << 16);
+	/* disable zqcs */
+	setbits_le32(pctl_base + DDR_PCTL2_ZQCTL0, 1u << 31);
+
+	return 0;
+}
diff --git a/drivers/ram/rockchip/sdram_phy_px30.c b/drivers/ram/rockchip/sdram_phy_px30.c
new file mode 100644
index 0000000..5de7377
--- /dev/null
+++ b/drivers/ram/rockchip/sdram_phy_px30.c
@@ -0,0 +1,205 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * (C) Copyright 2018 Rockchip Electronics Co., Ltd.
+ */
+
+#include <common.h>
+#include <ram.h>
+#include <asm/io.h>
+#include <asm/arch-rockchip/sdram.h>
+#include <asm/arch-rockchip/sdram_common.h>
+#include <asm/arch-rockchip/sdram_phy_px30.h>
+
+static void sdram_phy_dll_bypass_set(void __iomem *phy_base, u32 freq)
+{
+	u32 tmp;
+	u32 i, j;
+	u32 dqs_dll_freq;
+
+	setbits_le32(PHY_REG(phy_base, 0x13), 1 << 4);
+	clrbits_le32(PHY_REG(phy_base, 0x14), 1 << 3);
+	for (i = 0; i < 4; i++) {
+		j = 0x26 + i * 0x10;
+		setbits_le32(PHY_REG(phy_base, j), 1 << 4);
+		clrbits_le32(PHY_REG(phy_base, j + 0x1), 1 << 3);
+	}
+
+	if (freq <= 400)
+		/* DLL bypass */
+		setbits_le32(PHY_REG(phy_base, 0xa4), 0x1f);
+	else
+		clrbits_le32(PHY_REG(phy_base, 0xa4), 0x1f);
+
+	#ifdef CONFIG_ROCKCHIP_RK3328
+	dqs_dll_freq = 680;
+	#else
+	dqs_dll_freq = 801;
+	#endif
+
+	if (freq <= dqs_dll_freq)
+		tmp = 2;
+	else
+		tmp = 1;
+
+	for (i = 0; i < 4; i++) {
+		j = 0x28 + i * 0x10;
+		writel(tmp, PHY_REG(phy_base, j));
+	}
+}
+
+static void sdram_phy_set_ds_odt(void __iomem *phy_base,
+				 u32 dram_type)
+{
+	u32 cmd_drv, clk_drv, dqs_drv, dqs_odt;
+	u32 i, j;
+
+	if (dram_type == DDR3) {
+		cmd_drv = PHY_DDR3_RON_RTT_34ohm;
+		clk_drv = PHY_DDR3_RON_RTT_45ohm;
+		dqs_drv = PHY_DDR3_RON_RTT_34ohm;
+		dqs_odt = PHY_DDR3_RON_RTT_225ohm;
+	} else {
+		cmd_drv = PHY_DDR4_LPDDR3_RON_RTT_34ohm;
+		clk_drv = PHY_DDR4_LPDDR3_RON_RTT_43ohm;
+		dqs_drv = PHY_DDR4_LPDDR3_RON_RTT_34ohm;
+		if (dram_type == LPDDR2)
+			dqs_odt = PHY_DDR4_LPDDR3_RON_RTT_DISABLE;
+		else
+			dqs_odt = PHY_DDR4_LPDDR3_RON_RTT_240ohm;
+	}
+	/* DS */
+	writel(cmd_drv, PHY_REG(phy_base, 0x11));
+	clrsetbits_le32(PHY_REG(phy_base, 0x12), 0x1f << 3, cmd_drv << 3);
+	writel(clk_drv, PHY_REG(phy_base, 0x16));
+	writel(clk_drv, PHY_REG(phy_base, 0x18));
+
+	for (i = 0; i < 4; i++) {
+		j = 0x20 + i * 0x10;
+		writel(dqs_drv, PHY_REG(phy_base, j));
+		writel(dqs_drv, PHY_REG(phy_base, j + 0xf));
+		/* ODT */
+		writel(dqs_odt, PHY_REG(phy_base, j + 0x1));
+		writel(dqs_odt, PHY_REG(phy_base, j + 0xe));
+	}
+}
+
+void phy_soft_reset(void __iomem *phy_base)
+{
+	clrbits_le32(PHY_REG(phy_base, 0), 0x3 << 2);
+	udelay(1);
+	setbits_le32(PHY_REG(phy_base, 0), ANALOG_DERESET);
+	udelay(5);
+	setbits_le32(PHY_REG(phy_base, 0), DIGITAL_DERESET);
+	udelay(1);
+}
+
+void phy_dram_set_bw(void __iomem *phy_base, u32 bw)
+{
+	if (bw == 2) {
+		clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 0xf << 4);
+		setbits_le32(PHY_REG(phy_base, 0x46), 1 << 3);
+		setbits_le32(PHY_REG(phy_base, 0x56), 1 << 3);
+	} else if (bw == 1) {
+		clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 3 << 4);
+		clrbits_le32(PHY_REG(phy_base, 0x46), 1 << 3);
+		clrbits_le32(PHY_REG(phy_base, 0x56), 1 << 3);
+	} else if (bw == 0) {
+		clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 1 << 4);
+		clrbits_le32(PHY_REG(phy_base, 0x36), 1 << 3);
+		clrbits_le32(PHY_REG(phy_base, 0x46), 1 << 3);
+		clrbits_le32(PHY_REG(phy_base, 0x56), 1 << 3);
+	}
+
+	phy_soft_reset(phy_base);
+}
+
+int phy_data_training(void __iomem *phy_base, u32 cs, u32 dramtype)
+{
+	u32 ret;
+	u32 odt_val;
+	u32 i, j;
+
+	odt_val = readl(PHY_REG(phy_base, 0x2e));
+
+	for (i = 0; i < 4; i++) {
+		j = 0x20 + i * 0x10;
+		writel(PHY_DDR3_RON_RTT_225ohm, PHY_REG(phy_base, j + 0x1));
+		writel(0, PHY_REG(phy_base, j + 0xe));
+	}
+
+	if (dramtype == DDR4) {
+		clrsetbits_le32(PHY_REG(phy_base, 0x29), 0x3, 0);
+		clrsetbits_le32(PHY_REG(phy_base, 0x39), 0x3, 0);
+		clrsetbits_le32(PHY_REG(phy_base, 0x49), 0x3, 0);
+		clrsetbits_le32(PHY_REG(phy_base, 0x59), 0x3, 0);
+	}
+	/* choose training cs */
+	clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs));
+	/* enable gate training */
+	clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs) | 1);
+	udelay(50);
+	ret = readl(PHY_REG(phy_base, 0xff));
+	/* disable gate training */
+	clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs) | 0);
+	#ifndef CONFIG_ROCKCHIP_RK3328
+	clrbits_le32(PHY_REG(phy_base, 2), 0x30);
+	#endif
+
+	if (dramtype == DDR4) {
+		clrsetbits_le32(PHY_REG(phy_base, 0x29), 0x3, 0x2);
+		clrsetbits_le32(PHY_REG(phy_base, 0x39), 0x3, 0x2);
+		clrsetbits_le32(PHY_REG(phy_base, 0x49), 0x3, 0x2);
+		clrsetbits_le32(PHY_REG(phy_base, 0x59), 0x3, 0x2);
+	}
+
+	if (ret & 0x10) {
+		ret = -1;
+	} else {
+		ret = (ret & 0xf) ^ (readl(PHY_REG(phy_base, 0)) >> 4);
+		ret = (ret == 0) ? 0 : -1;
+	}
+
+	for (i = 0; i < 4; i++) {
+		j = 0x20 + i * 0x10;
+		writel(odt_val, PHY_REG(phy_base, j + 0x1));
+		writel(odt_val, PHY_REG(phy_base, j + 0xe));
+	}
+	return ret;
+}
+
+void phy_cfg(void __iomem *phy_base,
+	     struct ddr_phy_regs *phy_regs, struct ddr_phy_skew *skew,
+	     struct sdram_base_params *base, u32 bw)
+{
+	u32 i;
+
+	sdram_phy_dll_bypass_set(phy_base, base->ddr_freq);
+	for (i = 0; phy_regs->phy[i][0] != 0xFFFFFFFF; i++) {
+		writel(phy_regs->phy[i][1],
+		       phy_base + phy_regs->phy[i][0]);
+	}
+	if (bw == 2) {
+		clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 0xf << 4);
+	} else if (bw == 1) {
+		clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 3 << 4);
+		/* disable DQS2,DQS3 tx dll  for saving power */
+		clrbits_le32(PHY_REG(phy_base, 0x46), 1 << 3);
+		clrbits_le32(PHY_REG(phy_base, 0x56), 1 << 3);
+	} else {
+		clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 1 << 4);
+		/* disable DQS2,DQS3 tx dll  for saving power */
+		clrbits_le32(PHY_REG(phy_base, 0x36), 1 << 3);
+		clrbits_le32(PHY_REG(phy_base, 0x46), 1 << 3);
+		clrbits_le32(PHY_REG(phy_base, 0x56), 1 << 3);
+	}
+	sdram_phy_set_ds_odt(phy_base, base->dramtype);
+
+	/* deskew */
+	setbits_le32(PHY_REG(phy_base, 2), 8);
+	sdram_copy_to_reg(PHY_REG(phy_base, 0xb0),
+			  &skew->a0_a1_skew[0], 15 * 4);
+	sdram_copy_to_reg(PHY_REG(phy_base, 0x70),
+			  &skew->cs0_dm0_skew[0], 44 * 4);
+	sdram_copy_to_reg(PHY_REG(phy_base, 0xc0),
+			  &skew->cs1_dm0_skew[0], 44 * 4);
+}
diff --git a/drivers/ram/rockchip/sdram_px30.c b/drivers/ram/rockchip/sdram_px30.c
new file mode 100644
index 0000000..7292554
--- /dev/null
+++ b/drivers/ram/rockchip/sdram_px30.c
@@ -0,0 +1,751 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * (C) Copyright 2018 Rockchip Electronics Co., Ltd.
+ */
+
+#include <common.h>
+#include <debug_uart.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_px30.h>
+#include <asm/arch-rockchip/grf_px30.h>
+#include <asm/arch-rockchip/hardware.h>
+#include <asm/arch-rockchip/sdram.h>
+#include <asm/arch-rockchip/sdram_px30.h>
+
+struct dram_info {
+#ifdef CONFIG_TPL_BUILD
+	struct ddr_pctl_regs *pctl;
+	struct ddr_phy_regs *phy;
+	struct px30_cru *cru;
+	struct msch_regs *msch;
+	struct px30_ddr_grf_regs *ddr_grf;
+	struct px30_grf *grf;
+#endif
+	struct ram_info info;
+	struct px30_pmugrf *pmugrf;
+};
+
+#ifdef CONFIG_TPL_BUILD
+
+u8 ddr_cfg_2_rbc[] = {
+	/*
+	 * [6:4] max row: 13+n
+	 * [3]  bank(0:4bank,1:8bank)
+	 * [2:0]    col(10+n)
+	 */
+	((5 << 4) | (1 << 3) | 0), /* 0 */
+	((5 << 4) | (1 << 3) | 1), /* 1 */
+	((4 << 4) | (1 << 3) | 2), /* 2 */
+	((3 << 4) | (1 << 3) | 3), /* 3 */
+	((2 << 4) | (1 << 3) | 4), /* 4 */
+	((5 << 4) | (0 << 3) | 2), /* 5 */
+	((4 << 4) | (1 << 3) | 2), /* 6 */
+	/*((0<<3)|3),*/	 /* 12 for ddr4 */
+	/*((1<<3)|1),*/  /* 13 B,C exchange for rkvdec */
+};
+
+/*
+ * for ddr4 if ddrconfig=7, upctl should set 7 and noc should
+ * set to 1 for more efficient.
+ * noc ddrconf, upctl addrmap
+ * 1  7
+ * 2  8
+ * 3  9
+ * 12 10
+ * 5  11
+ */
+u8 d4_rbc_2_d3_rbc[] = {
+	1, /* 7 */
+	2, /* 8 */
+	3, /* 9 */
+	12, /* 10 */
+	5, /* 11 */
+};
+
+/*
+ * row higher than cs should be disabled by set to 0xf
+ * rank addrmap calculate by real cap.
+ */
+u32 addrmap[][8] = {
+	/* map0 map1,   map2,       map3,       map4,      map5
+	 * map6,        map7,       map8
+	 * -------------------------------------------------------
+	 * bk2-0       col 5-2     col 9-6    col 11-10   row 11-0
+	 * row 15-12   row 17-16   bg1,0
+	 * -------------------------------------------------------
+	 * 4,3,2       5-2         9-6                    6
+	 *                         3,2
+	 */
+	{0x00060606, 0x00000000, 0x1f1f0000, 0x00001f1f, 0x05050505,
+		0x05050505, 0x00000505, 0x3f3f}, /* 0 */
+	{0x00070707, 0x00000000, 0x1f000000, 0x00001f1f, 0x06060606,
+		0x06060606, 0x06060606, 0x3f3f}, /* 1 */
+	{0x00080808, 0x00000000, 0x00000000, 0x00001f1f, 0x07070707,
+		0x07070707, 0x00000f07, 0x3f3f}, /* 2 */
+	{0x00090909, 0x00000000, 0x00000000, 0x00001f00, 0x08080808,
+		0x08080808, 0x00000f0f, 0x3f3f}, /* 3 */
+	{0x000a0a0a, 0x00000000, 0x00000000, 0x00000000, 0x09090909,
+		0x0f090909, 0x00000f0f, 0x3f3f}, /* 4 */
+	{0x00080808, 0x00000000, 0x00000000, 0x00001f1f, 0x06060606,
+		0x06060606, 0x00000606, 0x3f3f}, /* 5 */
+	{0x00080808, 0x00000000, 0x00000000, 0x00001f1f, 0x07070707,
+		0x07070707, 0x00000f0f, 0x3f3f}, /* 6 */
+	{0x003f0808, 0x00000006, 0x1f1f0000, 0x00001f1f, 0x06060606,
+		0x06060606, 0x00000606, 0x0600}, /* 7 */
+	{0x003f0909, 0x00000007, 0x1f000000, 0x00001f1f, 0x07070707,
+		0x07070707, 0x00000f07, 0x0700}, /* 8 */
+	{0x003f0a0a, 0x01010100, 0x01010101, 0x00001f1f, 0x08080808,
+		0x08080808, 0x00000f0f, 0x0801}, /* 9 */
+	{0x003f0909, 0x01010100, 0x01010101, 0x00001f1f, 0x07070707,
+		0x07070707, 0x00000f07, 0x3f01}, /* 10 */
+	{0x003f0808, 0x00000007, 0x1f000000, 0x00001f1f, 0x06060606,
+		0x06060606, 0x00000606, 0x3f00}, /* 11 */
+	/* when ddr4 12 map to 10, when ddr3 12 unused */
+	{0x003f0909, 0x01010100, 0x01010101, 0x00001f1f, 0x07070707,
+		0x07070707, 0x00000f07, 0x3f01}, /* 10 */
+	{0x00070706, 0x00000000, 0x1f010000, 0x00001f1f, 0x06060606,
+		0x06060606, 0x00000606, 0x3f3f}, /* 13 */
+};
+
+#define PMUGRF_BASE_ADDR		0xFF010000
+#define CRU_BASE_ADDR			0xFF2B0000
+#define GRF_BASE_ADDR			0xFF140000
+#define DDRC_BASE_ADDR			0xFF600000
+#define DDR_PHY_BASE_ADDR		0xFF2A0000
+#define SERVER_MSCH0_BASE_ADDR		0xFF530000
+#define DDR_GRF_BASE_ADDR		0xff630000
+
+struct dram_info dram_info;
+
+struct px30_sdram_params sdram_configs[] = {
+#include	"sdram-px30-ddr3-detect-333.inc"
+};
+
+struct ddr_phy_skew skew = {
+#include	"sdram-px30-ddr_skew.inc"
+};
+
+static void rkclk_ddr_reset(struct dram_info *dram,
+			    u32 ctl_srstn, u32 ctl_psrstn,
+			    u32 phy_srstn, u32 phy_psrstn)
+{
+	writel(upctl2_srstn_req(ctl_srstn) | upctl2_psrstn_req(ctl_psrstn) |
+	       upctl2_asrstn_req(ctl_srstn),
+	       &dram->cru->softrst_con[1]);
+	writel(ddrphy_srstn_req(phy_srstn) | ddrphy_psrstn_req(phy_psrstn),
+	       &dram->cru->softrst_con[2]);
+}
+
+static void rkclk_set_dpll(struct dram_info *dram, unsigned int hz)
+{
+	unsigned int refdiv, postdiv1, postdiv2, fbdiv;
+	int delay = 1000;
+	u32 mhz = hz / MHz;
+
+	refdiv = 1;
+	if (mhz <= 300) {
+		postdiv1 = 4;
+		postdiv2 = 2;
+	} else if (mhz <= 400) {
+		postdiv1 = 6;
+		postdiv2 = 1;
+	} else if (mhz <= 600) {
+		postdiv1 = 4;
+		postdiv2 = 1;
+	} else if (mhz <= 800) {
+		postdiv1 = 3;
+		postdiv2 = 1;
+	} else if (mhz <= 1600) {
+		postdiv1 = 2;
+		postdiv2 = 1;
+	} else {
+		postdiv1 = 1;
+		postdiv2 = 1;
+	}
+	fbdiv = (mhz * refdiv * postdiv1 * postdiv2) / 24;
+
+	writel(DPLL_MODE(CLOCK_FROM_XIN_OSC), &dram->cru->mode);
+
+	writel(POSTDIV1(postdiv1) | FBDIV(fbdiv), &dram->cru->pll[1].con0);
+	writel(DSMPD(1) | POSTDIV2(postdiv2) | REFDIV(refdiv),
+	       &dram->cru->pll[1].con1);
+
+	while (delay > 0) {
+		udelay(1);
+		if (LOCK(readl(&dram->cru->pll[1].con1)))
+			break;
+		delay--;
+	}
+
+	writel(DPLL_MODE(CLOCK_FROM_PLL), &dram->cru->mode);
+}
+
+static void rkclk_configure_ddr(struct dram_info *dram,
+				struct px30_sdram_params *sdram_params)
+{
+	/* for inno ddr phy need 2*freq */
+	rkclk_set_dpll(dram,  sdram_params->base.ddr_freq * MHz * 2);
+}
+
+/* return ddrconfig value
+ *       (-1), find ddrconfig fail
+ *       other, the ddrconfig value
+ * only support cs0_row >= cs1_row
+ */
+static unsigned int calculate_ddrconfig(struct px30_sdram_params *sdram_params)
+{
+	struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
+	u32 bw, die_bw, col, bank;
+	u32 i, tmp;
+	u32 ddrconf = -1;
+
+	bw = cap_info->bw;
+	die_bw = cap_info->dbw;
+	col = cap_info->col;
+	bank = cap_info->bk;
+
+	if (sdram_params->base.dramtype == DDR4) {
+		if (die_bw == 0)
+			ddrconf = 7 + bw;
+		else
+			ddrconf = 12 - bw;
+		ddrconf = d4_rbc_2_d3_rbc[ddrconf - 7];
+	} else {
+		tmp = ((bank - 2) << 3) | (col + bw - 10);
+		for (i = 0; i < 7; i++)
+			if ((ddr_cfg_2_rbc[i] & 0xf) == tmp) {
+				ddrconf = i;
+				break;
+			}
+		if (i > 6)
+			printascii("calculate ddrconfig error\n");
+	}
+
+	return ddrconf;
+}
+
+/*
+ * calculate controller dram address map, and setting to register.
+ * argument sdram_params->ch.ddrconf must be right value before
+ * call this function.
+ */
+static void set_ctl_address_map(struct dram_info *dram,
+				struct px30_sdram_params *sdram_params)
+{
+	struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
+	void __iomem *pctl_base = dram->pctl;
+	u32 cs_pst, bg, max_row, ddrconf;
+	u32 i;
+
+	if (sdram_params->base.dramtype == DDR4)
+		/*
+		 * DDR4 8bit dram BG = 2(4bank groups),
+		 * 16bit dram BG = 1 (2 bank groups)
+		 */
+		bg = (cap_info->dbw == 0) ? 2 : 1;
+	else
+		bg = 0;
+
+	cs_pst = cap_info->bw + cap_info->col +
+		bg + cap_info->bk + cap_info->cs0_row;
+	if (cs_pst >= 32 || cap_info->rank == 1)
+		writel(0x1f, pctl_base + DDR_PCTL2_ADDRMAP0);
+	else
+		writel(cs_pst - 8, pctl_base + DDR_PCTL2_ADDRMAP0);
+
+	ddrconf = cap_info->ddrconfig;
+	if (sdram_params->base.dramtype == DDR4) {
+		for (i = 0; i < ARRAY_SIZE(d4_rbc_2_d3_rbc); i++) {
+			if (d4_rbc_2_d3_rbc[i] == ddrconf) {
+				ddrconf = 7 + i;
+				break;
+			}
+		}
+	}
+
+	sdram_copy_to_reg((u32 *)(pctl_base + DDR_PCTL2_ADDRMAP1),
+			  &addrmap[ddrconf][0], 8 * 4);
+	max_row = cs_pst - 1 - 8 - (addrmap[ddrconf][5] & 0xf);
+
+	if (max_row < 12)
+		printascii("set addrmap fail\n");
+	/* need to disable row ahead of rank by set to 0xf */
+	for (i = 17; i > max_row; i--)
+		clrsetbits_le32(pctl_base + DDR_PCTL2_ADDRMAP6 +
+			((i - 12) * 8 / 32) * 4,
+			0xf << ((i - 12) * 8 % 32),
+			0xf << ((i - 12) * 8 % 32));
+
+	if ((sdram_params->base.dramtype == LPDDR3 ||
+	     sdram_params->base.dramtype == LPDDR2) &&
+		 cap_info->row_3_4)
+		setbits_le32(pctl_base + DDR_PCTL2_ADDRMAP6, 1 << 31);
+	if (sdram_params->base.dramtype == DDR4 && cap_info->bw != 0x2)
+		setbits_le32(pctl_base + DDR_PCTL2_PCCFG, 1 << 8);
+}
+
+/*
+ * rank = 1: cs0
+ * rank = 2: cs1
+ */
+int read_mr(struct dram_info *dram, u32 rank, u32 mr_num)
+{
+	void __iomem *ddr_grf_base = dram->ddr_grf;
+
+	pctl_read_mr(dram->pctl, rank, mr_num);
+
+	return (readl(ddr_grf_base + DDR_GRF_STATUS(0)) & 0xff);
+}
+
+#define MIN(a, b)	(((a) > (b)) ? (b) : (a))
+#define MAX(a, b)	(((a) > (b)) ? (a) : (b))
+static u32 check_rd_gate(struct dram_info *dram)
+{
+	void __iomem *phy_base = dram->phy;
+
+	u32 max_val = 0;
+	u32 min_val = 0xff;
+	u32 gate[4];
+	u32 i, bw;
+
+	bw = (readl(PHY_REG(phy_base, 0x0)) >> 4) & 0xf;
+	switch (bw) {
+	case 0x1:
+		bw = 1;
+		break;
+	case 0x3:
+		bw = 2;
+		break;
+	case 0xf:
+	default:
+		bw = 4;
+		break;
+	}
+
+	for (i = 0; i < bw; i++) {
+		gate[i] = readl(PHY_REG(phy_base, 0xfb + i));
+		max_val = MAX(max_val, gate[i]);
+		min_val = MIN(min_val, gate[i]);
+	}
+
+	if (max_val > 0x80 || min_val < 0x20)
+		return -1;
+	else
+		return 0;
+}
+
+static int data_training(struct dram_info *dram, u32 cs, u32 dramtype)
+{
+	void __iomem *pctl_base = dram->pctl;
+	u32 dis_auto_zq = 0;
+	u32 pwrctl;
+	u32 ret;
+
+	/* disable auto low-power */
+	pwrctl = readl(pctl_base + DDR_PCTL2_PWRCTL);
+	writel(0, pctl_base + DDR_PCTL2_PWRCTL);
+
+	dis_auto_zq = pctl_dis_zqcs_aref(dram->pctl);
+
+	ret = phy_data_training(dram->phy, cs, dramtype);
+
+	pctl_rest_zqcs_aref(dram->pctl, dis_auto_zq);
+
+	/* restore auto low-power */
+	writel(pwrctl, pctl_base + DDR_PCTL2_PWRCTL);
+
+	return ret;
+}
+
+static void dram_set_bw(struct dram_info *dram, u32 bw)
+{
+	phy_dram_set_bw(dram->phy, bw);
+}
+
+static void set_ddrconfig(struct dram_info *dram, u32 ddrconfig)
+{
+	writel(ddrconfig | (ddrconfig << 8), &dram->msch->deviceconf);
+	rk_clrsetreg(&dram->grf->soc_noc_con[1], 0x3 << 14, 0 << 14);
+}
+
+static void sdram_msch_config(struct msch_regs *msch,
+			      struct sdram_msch_timings *noc_timings,
+			      struct sdram_cap_info *cap_info,
+			      struct sdram_base_params *base)
+{
+	u64 cs_cap[2];
+
+	cs_cap[0] = sdram_get_cs_cap(cap_info, 0, base->dramtype);
+	cs_cap[1] = sdram_get_cs_cap(cap_info, 1, base->dramtype);
+	writel(((((cs_cap[1] >> 20) / 64) & 0xff) << 8) |
+			(((cs_cap[0] >> 20) / 64) & 0xff),
+			&msch->devicesize);
+
+	writel(noc_timings->ddrtiminga0.d32,
+	       &msch->ddrtiminga0);
+	writel(noc_timings->ddrtimingb0.d32,
+	       &msch->ddrtimingb0);
+	writel(noc_timings->ddrtimingc0.d32,
+	       &msch->ddrtimingc0);
+	writel(noc_timings->devtodev0.d32,
+	       &msch->devtodev0);
+	writel(noc_timings->ddrmode.d32, &msch->ddrmode);
+	writel(noc_timings->ddr4timing.d32,
+	       &msch->ddr4timing);
+	writel(noc_timings->agingx0, &msch->agingx0);
+	writel(noc_timings->agingx0, &msch->aging0);
+	writel(noc_timings->agingx0, &msch->aging1);
+	writel(noc_timings->agingx0, &msch->aging2);
+	writel(noc_timings->agingx0, &msch->aging3);
+}
+
+static void dram_all_config(struct dram_info *dram,
+			    struct px30_sdram_params *sdram_params)
+{
+	struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
+	u32 sys_reg2 = 0;
+	u32 sys_reg3 = 0;
+
+	set_ddrconfig(dram, cap_info->ddrconfig);
+	sdram_org_config(cap_info, &sdram_params->base, &sys_reg2,
+			 &sys_reg3, 0);
+	writel(sys_reg2, &dram->pmugrf->os_reg[2]);
+	writel(sys_reg3, &dram->pmugrf->os_reg[3]);
+	sdram_msch_config(dram->msch, &sdram_params->ch.noc_timings, cap_info,
+			  &sdram_params->base);
+}
+
+static void enable_low_power(struct dram_info *dram,
+			     struct px30_sdram_params *sdram_params)
+{
+	void __iomem *pctl_base = dram->pctl;
+	void __iomem *phy_base = dram->phy;
+	void __iomem *ddr_grf_base = dram->ddr_grf;
+	u32 grf_lp_con;
+
+	/*
+	 * bit0: grf_upctl_axi_cg_en = 1 enable upctl2 axi clk auto gating
+	 * bit1: grf_upctl_apb_cg_en = 1 ungated axi,core clk for apb access
+	 * bit2: grf_upctl_core_cg_en = 1 enable upctl2 core clk auto gating
+	 * bit3: grf_selfref_type2_en = 0 disable core clk gating when type2 sr
+	 * bit4: grf_upctl_syscreq_cg_en = 1
+	 *       ungating coreclk when c_sysreq assert
+	 * bit8-11: grf_auto_sr_dly = 6
+	 */
+	writel(0x1f1f0617, &dram->ddr_grf->ddr_grf_con[1]);
+
+	if (sdram_params->base.dramtype == DDR4)
+		grf_lp_con = (0x7 << 16) | (1 << 1);
+	else if (sdram_params->base.dramtype == DDR3)
+		grf_lp_con = (0x7 << 16) | (1 << 0);
+	else
+		grf_lp_con = (0x7 << 16) | (1 << 2);
+
+	/* en lpckdis_en */
+	grf_lp_con = grf_lp_con | (0x1 << (9 + 16)) | (0x1 << 9);
+	writel(grf_lp_con, ddr_grf_base + DDR_GRF_LP_CON);
+
+	/* off digit module clock when enter power down */
+	setbits_le32(PHY_REG(phy_base, 7), 1 << 7);
+
+	/* enable sr, pd */
+	if (PD_IDLE == 0)
+		clrbits_le32(pctl_base + DDR_PCTL2_PWRCTL, (1 << 1));
+	else
+		setbits_le32(pctl_base + DDR_PCTL2_PWRCTL, (1 << 1));
+	if (SR_IDLE == 0)
+		clrbits_le32(pctl_base + DDR_PCTL2_PWRCTL, 1);
+	else
+		setbits_le32(pctl_base + DDR_PCTL2_PWRCTL, 1);
+	setbits_le32(pctl_base + DDR_PCTL2_PWRCTL, (1 << 3));
+}
+
+/*
+ * pre_init: 0: pre init for dram cap detect
+ * 1: detect correct cap(except cs1 row)info, than reinit
+ * 2: after reinit, we detect cs1_row, if cs1_row not equal
+ *    to cs0_row and cs is in middle on ddrconf map, we need
+ *    to reinit dram, than set the correct ddrconf.
+ */
+static int sdram_init_(struct dram_info *dram,
+		       struct px30_sdram_params *sdram_params, u32 pre_init)
+{
+	struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
+	void __iomem *pctl_base = dram->pctl;
+
+	rkclk_ddr_reset(dram, 1, 1, 1, 1);
+	udelay(10);
+	/*
+	 * dereset ddr phy psrstn to config pll,
+	 * if using phy pll psrstn must be dereset
+	 * before config pll
+	 */
+	rkclk_ddr_reset(dram, 1, 1, 1, 0);
+	rkclk_configure_ddr(dram, sdram_params);
+
+	/* release phy srst to provide clk to ctrl */
+	rkclk_ddr_reset(dram, 1, 1, 0, 0);
+	udelay(10);
+	phy_soft_reset(dram->phy);
+	/* release ctrl presetn, and config ctl registers */
+	rkclk_ddr_reset(dram, 1, 0, 0, 0);
+	pctl_cfg(dram->pctl, &sdram_params->pctl_regs, SR_IDLE, PD_IDLE);
+	cap_info->ddrconfig = calculate_ddrconfig(sdram_params);
+	set_ctl_address_map(dram, sdram_params);
+	phy_cfg(dram->phy, &sdram_params->phy_regs, sdram_params->skew,
+		&sdram_params->base, cap_info->bw);
+
+	/* enable dfi_init_start to init phy after ctl srstn deassert */
+	setbits_le32(pctl_base + DDR_PCTL2_DFIMISC, (1 << 5) | (1 << 4));
+
+	rkclk_ddr_reset(dram, 0, 0, 0, 0);
+	/* wait for dfi_init_done and dram init complete */
+	while ((readl(pctl_base + DDR_PCTL2_STAT) & 0x7) == 0)
+		continue;
+
+	if (sdram_params->base.dramtype == LPDDR3)
+		pctl_write_mr(dram->pctl, 3, 11, 3, LPDDR3);
+
+	/* do ddr gate training */
+redo_cs0_training:
+	if (data_training(dram, 0, sdram_params->base.dramtype) != 0) {
+		if (pre_init != 0)
+			printascii("DTT cs0 error\n");
+		return -1;
+	}
+	if (check_rd_gate(dram)) {
+		printascii("re training cs0");
+		goto redo_cs0_training;
+	}
+
+	if (sdram_params->base.dramtype == LPDDR3) {
+		if ((read_mr(dram, 1, 8) & 0x3) != 0x3)
+			return -1;
+	} else if (sdram_params->base.dramtype == LPDDR2) {
+		if ((read_mr(dram, 1, 8) & 0x3) != 0x0)
+			return -1;
+	}
+	/* for px30: when 2cs, both 2 cs should be training */
+	if (pre_init != 0 && cap_info->rank == 2) {
+redo_cs1_training:
+		if (data_training(dram, 1, sdram_params->base.dramtype) != 0) {
+			printascii("DTT cs1 error\n");
+			return -1;
+		}
+		if (check_rd_gate(dram)) {
+			printascii("re training cs1");
+			goto redo_cs1_training;
+		}
+	}
+
+	if (sdram_params->base.dramtype == DDR4)
+		pctl_write_vrefdq(dram->pctl, 0x3, 5670,
+				  sdram_params->base.dramtype);
+
+	dram_all_config(dram, sdram_params);
+	enable_low_power(dram, sdram_params);
+
+	return 0;
+}
+
+static int dram_detect_cap(struct dram_info *dram,
+			   struct px30_sdram_params *sdram_params,
+			   unsigned char channel)
+{
+	struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
+
+	/*
+	 * for ddr3: ddrconf = 3
+	 * for ddr4: ddrconf = 12
+	 * for lpddr3: ddrconf = 3
+	 * default bw = 1
+	 */
+	u32 bk, bktmp;
+	u32 col, coltmp;
+	u32 rowtmp;
+	u32 cs;
+	u32 bw = 1;
+	u32 dram_type = sdram_params->base.dramtype;
+
+	if (dram_type != DDR4) {
+		/* detect col and bk for ddr3/lpddr3 */
+		coltmp = 12;
+		bktmp = 3;
+		if (dram_type == LPDDR2)
+			rowtmp = 15;
+		else
+			rowtmp = 16;
+
+		if (sdram_detect_col(cap_info, coltmp) != 0)
+			goto cap_err;
+		sdram_detect_bank(cap_info, coltmp, bktmp);
+		sdram_detect_dbw(cap_info, dram_type);
+	} else {
+		/* detect bg for ddr4 */
+		coltmp = 10;
+		bktmp = 4;
+		rowtmp = 17;
+
+		col = 10;
+		bk = 2;
+		cap_info->col = col;
+		cap_info->bk = bk;
+		sdram_detect_bg(cap_info, coltmp);
+	}
+
+	/* detect row */
+	if (sdram_detect_row(cap_info, coltmp, bktmp, rowtmp) != 0)
+		goto cap_err;
+
+	/* detect row_3_4 */
+	sdram_detect_row_3_4(cap_info, coltmp, bktmp);
+
+	/* bw and cs detect using data training */
+	if (data_training(dram, 1, dram_type) == 0)
+		cs = 1;
+	else
+		cs = 0;
+	cap_info->rank = cs + 1;
+
+	dram_set_bw(dram, 2);
+	if (data_training(dram, 0, dram_type) == 0)
+		bw = 2;
+	else
+		bw = 1;
+	cap_info->bw = bw;
+
+	cap_info->cs0_high16bit_row = cap_info->cs0_row;
+	if (cs) {
+		cap_info->cs1_row = cap_info->cs0_row;
+		cap_info->cs1_high16bit_row = cap_info->cs0_row;
+	} else {
+		cap_info->cs1_row = 0;
+		cap_info->cs1_high16bit_row = 0;
+	}
+
+	return 0;
+cap_err:
+	return -1;
+}
+
+/* return: 0 = success, other = fail */
+static int sdram_init_detect(struct dram_info *dram,
+			     struct px30_sdram_params *sdram_params)
+{
+	struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
+	u32 ret;
+	u32 sys_reg = 0;
+	u32 sys_reg3 = 0;
+
+	if (sdram_init_(dram, sdram_params, 0) != 0)
+		return -1;
+
+	if (dram_detect_cap(dram, sdram_params, 0) != 0)
+		return -1;
+
+	/* modify bw, cs related timing */
+	pctl_remodify_sdram_params(&sdram_params->pctl_regs, cap_info,
+				   sdram_params->base.dramtype);
+	/* reinit sdram by real dram cap */
+	ret = sdram_init_(dram, sdram_params, 1);
+	if (ret != 0)
+		goto out;
+
+	/* redetect cs1 row */
+	sdram_detect_cs1_row(cap_info, sdram_params->base.dramtype);
+	if (cap_info->cs1_row) {
+		sys_reg = readl(&dram->pmugrf->os_reg[2]);
+		sys_reg3 = readl(&dram->pmugrf->os_reg[3]);
+		SYS_REG_ENC_CS1_ROW(cap_info->cs1_row,
+				    sys_reg, sys_reg3, 0);
+		writel(sys_reg, &dram->pmugrf->os_reg[2]);
+		writel(sys_reg3, &dram->pmugrf->os_reg[3]);
+	}
+
+	ret = sdram_detect_high_row(cap_info);
+
+out:
+	return ret;
+}
+
+struct px30_sdram_params
+		*get_default_sdram_config(void)
+{
+	sdram_configs[0].skew = &skew;
+
+	return &sdram_configs[0];
+}
+
+/* return: 0 = success, other = fail */
+int sdram_init(void)
+{
+	struct px30_sdram_params *sdram_params;
+	int ret = 0;
+
+	dram_info.phy = (void *)DDR_PHY_BASE_ADDR;
+	dram_info.pctl = (void *)DDRC_BASE_ADDR;
+	dram_info.grf = (void *)GRF_BASE_ADDR;
+	dram_info.cru = (void *)CRU_BASE_ADDR;
+	dram_info.msch = (void *)SERVER_MSCH0_BASE_ADDR;
+	dram_info.ddr_grf = (void *)DDR_GRF_BASE_ADDR;
+	dram_info.pmugrf = (void *)PMUGRF_BASE_ADDR;
+
+	sdram_params = get_default_sdram_config();
+	ret = sdram_init_detect(&dram_info, sdram_params);
+
+	if (ret)
+		goto error;
+
+	sdram_print_ddr_info(&sdram_params->ch.cap_info, &sdram_params->base);
+
+	printascii("out\n");
+	return ret;
+error:
+	return (-1);
+}
+#else
+
+static int px30_dmc_probe(struct udevice *dev)
+{
+	struct dram_info *priv = dev_get_priv(dev);
+
+	priv->pmugrf = syscon_get_first_range(ROCKCHIP_SYSCON_PMUGRF);
+	debug("%s: grf=%p\n", __func__, priv->pmugrf);
+	priv->info.base = CONFIG_SYS_SDRAM_BASE;
+	priv->info.size =
+		rockchip_sdram_size((phys_addr_t)&priv->pmugrf->os_reg[2]);
+
+	return 0;
+}
+
+static int px30_dmc_get_info(struct udevice *dev, struct ram_info *info)
+{
+	struct dram_info *priv = dev_get_priv(dev);
+
+	*info = priv->info;
+
+	return 0;
+}
+
+static struct ram_ops px30_dmc_ops = {
+	.get_info = px30_dmc_get_info,
+};
+
+static const struct udevice_id px30_dmc_ids[] = {
+	{ .compatible = "rockchip,px30-dmc" },
+	{ }
+};
+
+U_BOOT_DRIVER(dmc_px30) = {
+	.name = "rockchip_px30_dmc",
+	.id = UCLASS_RAM,
+	.of_match = px30_dmc_ids,
+	.ops = &px30_dmc_ops,
+	.probe = px30_dmc_probe,
+	.priv_auto_alloc_size = sizeof(struct dram_info),
+};
+#endif /* CONFIG_TPL_BUILD */
diff --git a/drivers/ram/rockchip/sdram_rk3128.c b/drivers/ram/rockchip/sdram_rk3128.c
index bfabc22..8486653 100644
--- a/drivers/ram/rockchip/sdram_rk3128.c
+++ b/drivers/ram/rockchip/sdram_rk3128.c
@@ -9,7 +9,7 @@
 #include <syscon.h>
 #include <asm/arch-rockchip/clock.h>
 #include <asm/arch-rockchip/grf_rk3128.h>
-#include <asm/arch-rockchip/sdram_common.h>
+#include <asm/arch-rockchip/sdram.h>
 
 struct dram_info {
 	struct ram_info info;
diff --git a/drivers/ram/rockchip/sdram_rk3188.c b/drivers/ram/rockchip/sdram_rk3188.c
index 00e52ec..d3e4316 100644
--- a/drivers/ram/rockchip/sdram_rk3188.c
+++ b/drivers/ram/rockchip/sdram_rk3188.c
@@ -21,7 +21,7 @@
 #include <asm/arch-rockchip/grf_rk3188.h>
 #include <asm/arch-rockchip/pmu_rk3188.h>
 #include <asm/arch-rockchip/sdram.h>
-#include <asm/arch-rockchip/sdram_common.h>
+#include <asm/arch-rockchip/sdram_rk3288.h>
 #include <linux/err.h>
 
 struct chan_info {
diff --git a/drivers/ram/rockchip/sdram_rk322x.c b/drivers/ram/rockchip/sdram_rk322x.c
index 94893e1..223f048 100644
--- a/drivers/ram/rockchip/sdram_rk322x.c
+++ b/drivers/ram/rockchip/sdram_rk322x.c
@@ -17,7 +17,7 @@
 #include <asm/arch-rockchip/hardware.h>
 #include <asm/arch-rockchip/sdram_rk322x.h>
 #include <asm/arch-rockchip/uart.h>
-#include <asm/arch-rockchip/sdram_common.h>
+#include <asm/arch-rockchip/sdram.h>
 #include <asm/types.h>
 #include <linux/err.h>
 
diff --git a/drivers/ram/rockchip/sdram_rk3288.c b/drivers/ram/rockchip/sdram_rk3288.c
index 5775254..690751d 100644
--- a/drivers/ram/rockchip/sdram_rk3288.c
+++ b/drivers/ram/rockchip/sdram_rk3288.c
@@ -21,7 +21,7 @@
 #include <asm/arch-rockchip/grf_rk3288.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/sdram_rk3288.h>
 #include <linux/err.h>
 #include <power/regulator.h>
 #include <power/rk8xx_pmic.h>
diff --git a/drivers/ram/rockchip/sdram_rk3308.c b/drivers/ram/rockchip/sdram_rk3308.c
new file mode 100644
index 0000000..310df79
--- /dev/null
+++ b/drivers/ram/rockchip/sdram_rk3308.c
@@ -0,0 +1,55 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * (C) Copyright 2019 Rockchip Electronics Co., Ltd.
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <ram.h>
+#include <syscon.h>
+#include <asm/arch/grf_rk3308.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/sdram.h>
+
+struct dram_info {
+	struct ram_info info;
+	struct rk3308_grf *grf;
+};
+
+static int rk3308_dmc_probe(struct udevice *dev)
+{
+	struct dram_info *priv = dev_get_priv(dev);
+
+	priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+	priv->info.base = CONFIG_SYS_SDRAM_BASE;
+	priv->info.size = rockchip_sdram_size((phys_addr_t)&priv->grf->os_reg2);
+
+	return 0;
+}
+
+static int rk3308_dmc_get_info(struct udevice *dev, struct ram_info *info)
+{
+	struct dram_info *priv = dev_get_priv(dev);
+
+	*info = priv->info;
+
+	return 0;
+}
+
+static struct ram_ops rk3308_dmc_ops = {
+	.get_info = rk3308_dmc_get_info,
+};
+
+static const struct udevice_id rk3308_dmc_ids[] = {
+	{ .compatible = "rockchip,rk3308-dmc" },
+	{ }
+};
+
+U_BOOT_DRIVER(dmc_rk3308) = {
+	.name = "rockchip_rk3308_dmc",
+	.id = UCLASS_RAM,
+	.of_match = rk3308_dmc_ids,
+	.ops = &rk3308_dmc_ops,
+	.probe = rk3308_dmc_probe,
+	.priv_auto_alloc_size = sizeof(struct dram_info),
+};
diff --git a/drivers/ram/rockchip/sdram_rk3328.c b/drivers/ram/rockchip/sdram_rk3328.c
index e84c9be..69521ce 100644
--- a/drivers/ram/rockchip/sdram_rk3328.c
+++ b/drivers/ram/rockchip/sdram_rk3328.c
@@ -14,17 +14,17 @@
 #include <asm/arch-rockchip/clock.h>
 #include <asm/arch-rockchip/cru_rk3328.h>
 #include <asm/arch-rockchip/grf_rk3328.h>
-#include <asm/arch-rockchip/sdram_common.h>
+#include <asm/arch-rockchip/sdram.h>
 #include <asm/arch-rockchip/sdram_rk3328.h>
 #include <asm/arch-rockchip/uart.h>
 
 struct dram_info {
 #ifdef CONFIG_TPL_BUILD
-	struct rk3328_ddr_pctl_regs *pctl;
-	struct rk3328_ddr_phy_regs *phy;
+	struct ddr_pctl_regs *pctl;
+	struct ddr_phy_regs *phy;
 	struct clk ddr_clk;
 	struct rk3328_cru *cru;
-	struct rk3328_msch_regs *msch;
+	struct msch_regs *msch;
 	struct rk3328_ddr_grf_regs *ddr_grf;
 #endif
 	struct ram_info info;
@@ -71,10 +71,11 @@
 	writel(ddrctrl_asrstn_req(ctl_srstn), &dram->cru->softrst_con[9]);
 }
 
-static void rkclk_set_dpll(struct dram_info *dram, unsigned int mhz)
+static void rkclk_set_dpll(struct dram_info *dram, unsigned int hz)
 {
 	unsigned int refdiv, postdiv1, postdiv2, fbdiv;
 	int delay = 1000;
+	u32 mhz = hz / MHZ;
 
 	refdiv = 1;
 	if (mhz <= 300) {
@@ -122,115 +123,47 @@
 	clrbits_le32(PHY_REG(phy_base, 0xef), 1 << 7);
 
 	/* for inno ddr phy need 2*freq */
-	rkclk_set_dpll(dram,  sdram_params->ddr_freq * 2);
+	rkclk_set_dpll(dram,  sdram_params->base.ddr_freq * MHZ * 2);
 }
 
-static void phy_soft_reset(struct dram_info *dram)
-{
-	void __iomem *phy_base = dram->phy;
-
-	clrbits_le32(PHY_REG(phy_base, 0), 0x3 << 2);
-	udelay(1);
-	setbits_le32(PHY_REG(phy_base, 0), ANALOG_DERESET);
-	udelay(5);
-	setbits_le32(PHY_REG(phy_base, 0), DIGITAL_DERESET);
-	udelay(1);
-}
-
-static int pctl_cfg(struct dram_info *dram,
-		    struct rk3328_sdram_params *sdram_params)
-{
-	u32 i;
-	void __iomem *pctl_base = dram->pctl;
-
-	for (i = 0; sdram_params->pctl_regs.pctl[i][0] != 0xFFFFFFFF; i++) {
-		writel(sdram_params->pctl_regs.pctl[i][1],
-		       pctl_base + sdram_params->pctl_regs.pctl[i][0]);
-	}
-	clrsetbits_le32(pctl_base + DDR_PCTL2_PWRTMG,
-			(0xff << 16) | 0x1f,
-			((SR_IDLE & 0xff) << 16) | (PD_IDLE & 0x1f));
-	/*
-	 * dfi_lp_en_pd=1,dfi_lp_wakeup_pd=2
-	 * hw_lp_idle_x32=1
-	 */
-	if (sdram_params->dramtype == LPDDR3) {
-		setbits_le32(pctl_base + DDR_PCTL2_DFILPCFG0, 1);
-		clrsetbits_le32(pctl_base + DDR_PCTL2_DFILPCFG0,
-				0xf << 4,
-				2 << 4);
-	}
-	clrsetbits_le32(pctl_base + DDR_PCTL2_HWLPCTL,
-			0xfff << 16,
-			1 << 16);
-	/* disable zqcs */
-	setbits_le32(pctl_base + DDR_PCTL2_ZQCTL0, 1u << 31);
-	setbits_le32(pctl_base + 0x2000 + DDR_PCTL2_ZQCTL0, 1u << 31);
-
-	return 0;
-}
-
 /* return ddrconfig value
  *       (-1), find ddrconfig fail
  *       other, the ddrconfig value
  * only support cs0_row >= cs1_row
  */
-static unsigned int calculate_ddrconfig(struct rk3328_sdram_params *sdram_params)
+static u32 calculate_ddrconfig(struct rk3328_sdram_params *sdram_params)
 {
-	static const u16 ddr_cfg_2_rbc[] = {
-		/***************************
-		 * [5:4]  row(13+n)
-		 * [3]    cs(0:0 cs, 1:2 cs)
-		 * [2]  bank(0:0bank,1:8bank)
-		 * [1:0]    col(11+n)
-		 ****************************/
-		/* row,        cs,       bank,   col */
-		((3 << 4) | (0 << 3) | (1 << 2) | 0),
-		((3 << 4) | (0 << 3) | (1 << 2) | 1),
-		((2 << 4) | (0 << 3) | (1 << 2) | 2),
-		((3 << 4) | (0 << 3) | (1 << 2) | 2),
-		((2 << 4) | (0 << 3) | (1 << 2) | 3),
-		((3 << 4) | (1 << 3) | (1 << 2) | 0),
-		((3 << 4) | (1 << 3) | (1 << 2) | 1),
-		((2 << 4) | (1 << 3) | (1 << 2) | 2),
-		((3 << 4) | (0 << 3) | (0 << 2) | 1),
-		((2 << 4) | (0 << 3) | (1 << 2) | 1),
-	};
-
-	static const u16 ddr4_cfg_2_rbc[] = {
-		/***************************
-		 * [6]	cs 0:0cs 1:2 cs
-		 * [5:3]  row(13+n)
-		 * [2]  cs(0:0 cs, 1:2 cs)
-		 * [1]  bw    0: 16bit 1:32bit
-		 * [0]  diebw 0:8bit 1:16bit
-		 ***************************/
-		/*  cs,       row,        cs,       bw,   diebw */
-		((0 << 6) | (3 << 3) | (0 << 2) | (1 << 1) | 0),
-		((1 << 6) | (2 << 3) | (0 << 2) | (1 << 1) | 0),
-		((0 << 6) | (4 << 3) | (0 << 2) | (0 << 1) | 0),
-		((1 << 6) | (3 << 3) | (0 << 2) | (0 << 1) | 0),
-		((0 << 6) | (4 << 3) | (0 << 2) | (1 << 1) | 1),
-		((1 << 6) | (3 << 3) | (0 << 2) | (1 << 1) | 1),
-		((1 << 6) | (4 << 3) | (0 << 2) | (0 << 1) | 1),
-		((0 << 6) | (2 << 3) | (1 << 2) | (1 << 1) | 0),
-		((0 << 6) | (3 << 3) | (1 << 2) | (0 << 1) | 0),
-		((0 << 6) | (3 << 3) | (1 << 2) | (1 << 1) | 1),
-		((0 << 6) | (4 << 3) | (1 << 2) | (0 << 1) | 1),
-	};
-
+	struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
 	u32 cs, bw, die_bw, col, row, bank;
+	u32 cs1_row;
 	u32 i, tmp;
 	u32 ddrconf = -1;
 
+	cs = cap_info->rank;
+	bw = cap_info->bw;
+	die_bw = cap_info->dbw;
+	col = cap_info->col;
+	row = cap_info->cs0_row;
+	cs1_row = cap_info->cs1_row;
+	bank = cap_info->bk;
+
-	cs = sdram_ch.rank;
-	bw = sdram_ch.bw;
-	die_bw = sdram_ch.dbw;
-	col = sdram_ch.col;
-	row = sdram_ch.cs0_row;
-	bank = sdram_ch.bk;
+	if (sdram_params->base.dramtype == DDR4) {
+		/* when DDR_TEST, CS always at MSB position for easy test */
+		if (cs == 2 && row == cs1_row) {
+			/* include 2cs cap both 2^n  or both (2^n - 2^(n-2)) */
+			tmp = ((row - 13) << 3) | (1 << 2) | (bw & 0x2) |
+			      die_bw;
+			for (i = 17; i < 21; i++) {
+				if (((tmp & 0x7) ==
+				     (ddr4_cfg_2_rbc[i - 10] & 0x7)) &&
+				    ((tmp & 0x3c) <=
+				     (ddr4_cfg_2_rbc[i - 10] & 0x3c))) {
+					ddrconf = i;
+					goto out;
+				}
+			}
+		}
 
-	if (sdram_params->dramtype == DDR4) {
 		tmp = ((cs - 1) << 6) | ((row - 13) << 3) | (bw & 0x2) | die_bw;
 		for (i = 10; i < 17; i++) {
 			if (((tmp & 0x7) == (ddr4_cfg_2_rbc[i - 10] & 0x7)) &&
@@ -246,6 +179,18 @@
 			goto out;
 		}
 
+		/* when DDR_TEST, CS always at MSB position for easy test */
+		if (cs == 2 && row == cs1_row) {
+			/* include 2cs cap both 2^n  or both (2^n - 2^(n-2)) */
+			for (i = 5; i < 8; i++) {
+				if ((bw + col - 11) == (ddr_cfg_2_rbc[i] &
+							0x3)) {
+					ddrconf = i;
+					goto out;
+				}
+			}
+		}
+
 		tmp = ((row - 13) << 4) | (1 << 2) | ((bw + col - 11) << 0);
 		for (i = 0; i < 5; i++)
 			if (((tmp & 0xf) == (ddr_cfg_2_rbc[i] & 0xf)) &&
@@ -257,23 +202,11 @@
 
 out:
 	if (ddrconf > 20)
-		printf("calculate_ddrconfig error\n");
+		printf("calculate ddrconfig error\n");
 
 	return ddrconf;
 }
 
-/* n: Unit bytes */
-static void copy_to_reg(u32 *dest, u32 *src, u32 n)
-{
-	int i;
-
-	for (i = 0; i < n / sizeof(u32); i++) {
-		writel(*src, dest);
-		src++;
-		dest++;
-	}
-}
-
 /*******
  * calculate controller dram address map, and setting to register.
  * argument sdram_ch.ddrconf must be right value before
@@ -282,274 +215,43 @@
 static void set_ctl_address_map(struct dram_info *dram,
 				struct rk3328_sdram_params *sdram_params)
 {
+	struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
 	void __iomem *pctl_base = dram->pctl;
 
-	copy_to_reg((u32 *)(pctl_base + DDR_PCTL2_ADDRMAP0),
-		    &addrmap[sdram_ch.ddrconfig][0], 9 * 4);
-	if (sdram_params->dramtype == LPDDR3 && sdram_ch.row_3_4)
+	sdram_copy_to_reg((u32 *)(pctl_base + DDR_PCTL2_ADDRMAP0),
+			  &addrmap[cap_info->ddrconfig][0], 9 * 4);
+	if (sdram_params->base.dramtype == LPDDR3 && cap_info->row_3_4)
 		setbits_le32(pctl_base + DDR_PCTL2_ADDRMAP6, 1 << 31);
-	if (sdram_params->dramtype == DDR4 && sdram_ch.bw == 0x1)
+	if (sdram_params->base.dramtype == DDR4 && cap_info->bw == 0x1)
 		setbits_le32(pctl_base + DDR_PCTL2_PCCFG, 1 << 8);
 
-	if (sdram_ch.rank == 1)
+	if (cap_info->rank == 1)
 		clrsetbits_le32(pctl_base + DDR_PCTL2_ADDRMAP0, 0x1f, 0x1f);
 }
 
-static void phy_dll_bypass_set(struct dram_info *dram, u32 freq)
-{
-	u32 tmp;
-	void __iomem *phy_base = dram->phy;
-
-	setbits_le32(PHY_REG(phy_base, 0x13), 1 << 4);
-	clrbits_le32(PHY_REG(phy_base, 0x14), 1 << 3);
-	setbits_le32(PHY_REG(phy_base, 0x26), 1 << 4);
-	clrbits_le32(PHY_REG(phy_base, 0x27), 1 << 3);
-	setbits_le32(PHY_REG(phy_base, 0x36), 1 << 4);
-	clrbits_le32(PHY_REG(phy_base, 0x37), 1 << 3);
-	setbits_le32(PHY_REG(phy_base, 0x46), 1 << 4);
-	clrbits_le32(PHY_REG(phy_base, 0x47), 1 << 3);
-	setbits_le32(PHY_REG(phy_base, 0x56), 1 << 4);
-	clrbits_le32(PHY_REG(phy_base, 0x57), 1 << 3);
-
-	if (freq <= 400)
-		/* DLL bypass */
-		setbits_le32(PHY_REG(phy_base, 0xa4), 0x1f);
-	else
-		clrbits_le32(PHY_REG(phy_base, 0xa4), 0x1f);
-	if (freq <= 680)
-		tmp = 2;
-	else
-		tmp = 1;
-	writel(tmp, PHY_REG(phy_base, 0x28));
-	writel(tmp, PHY_REG(phy_base, 0x38));
-	writel(tmp, PHY_REG(phy_base, 0x48));
-	writel(tmp, PHY_REG(phy_base, 0x58));
-}
-
-static void set_ds_odt(struct dram_info *dram,
-		       struct rk3328_sdram_params *sdram_params)
-{
-	u32 cmd_drv, clk_drv, dqs_drv, dqs_odt;
-	void __iomem *phy_base = dram->phy;
-
-	if (sdram_params->dramtype == DDR3) {
-		cmd_drv = PHY_DDR3_RON_RTT_34ohm;
-		clk_drv = PHY_DDR3_RON_RTT_45ohm;
-		dqs_drv = PHY_DDR3_RON_RTT_34ohm;
-		dqs_odt = PHY_DDR3_RON_RTT_225ohm;
-	} else {
-		cmd_drv = PHY_DDR4_LPDDR3_RON_RTT_34ohm;
-		clk_drv = PHY_DDR4_LPDDR3_RON_RTT_43ohm;
-		dqs_drv = PHY_DDR4_LPDDR3_RON_RTT_34ohm;
-		dqs_odt = PHY_DDR4_LPDDR3_RON_RTT_240ohm;
-	}
-	/* DS */
-	writel(cmd_drv, PHY_REG(phy_base, 0x11));
-	clrsetbits_le32(PHY_REG(phy_base, 0x12), 0x1f << 3, cmd_drv << 3);
-	writel(clk_drv, PHY_REG(phy_base, 0x16));
-	writel(clk_drv, PHY_REG(phy_base, 0x18));
-	writel(dqs_drv, PHY_REG(phy_base, 0x20));
-	writel(dqs_drv, PHY_REG(phy_base, 0x2f));
-	writel(dqs_drv, PHY_REG(phy_base, 0x30));
-	writel(dqs_drv, PHY_REG(phy_base, 0x3f));
-	writel(dqs_drv, PHY_REG(phy_base, 0x40));
-	writel(dqs_drv, PHY_REG(phy_base, 0x4f));
-	writel(dqs_drv, PHY_REG(phy_base, 0x50));
-	writel(dqs_drv, PHY_REG(phy_base, 0x5f));
-	/* ODT */
-	writel(dqs_odt, PHY_REG(phy_base, 0x21));
-	writel(dqs_odt, PHY_REG(phy_base, 0x2e));
-	writel(dqs_odt, PHY_REG(phy_base, 0x31));
-	writel(dqs_odt, PHY_REG(phy_base, 0x3e));
-	writel(dqs_odt, PHY_REG(phy_base, 0x41));
-	writel(dqs_odt, PHY_REG(phy_base, 0x4e));
-	writel(dqs_odt, PHY_REG(phy_base, 0x51));
-	writel(dqs_odt, PHY_REG(phy_base, 0x5e));
-}
-
-static void phy_cfg(struct dram_info *dram,
-		    struct rk3328_sdram_params *sdram_params)
-{
-	u32 i;
-	void __iomem *phy_base = dram->phy;
-
-	phy_dll_bypass_set(dram, sdram_params->ddr_freq);
-	for (i = 0; sdram_params->phy_regs.phy[i][0] != 0xFFFFFFFF; i++) {
-		writel(sdram_params->phy_regs.phy[i][1],
-		       phy_base + sdram_params->phy_regs.phy[i][0]);
-	}
-	if (sdram_ch.bw == 2) {
-		clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 0xf << 4);
-	} else {
-		clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 3 << 4);
-		/* disable DQS2,DQS3 tx dll  for saving power */
-		clrbits_le32(PHY_REG(phy_base, 0x46), 1 << 3);
-		clrbits_le32(PHY_REG(phy_base, 0x56), 1 << 3);
-	}
-	set_ds_odt(dram, sdram_params);
-	/* deskew */
-	setbits_le32(PHY_REG(phy_base, 2), 8);
-	copy_to_reg(PHY_REG(phy_base, 0xb0),
-		    &sdram_params->skew.a0_a1_skew[0], 15 * 4);
-	copy_to_reg(PHY_REG(phy_base, 0x70),
-		    &sdram_params->skew.cs0_dm0_skew[0], 44 * 4);
-	copy_to_reg(PHY_REG(phy_base, 0xc0),
-		    &sdram_params->skew.cs1_dm0_skew[0], 44 * 4);
-}
-
-static int update_refresh_reg(struct dram_info *dram)
-{
-	void __iomem *pctl_base = dram->pctl;
-	u32 ret;
-
-	ret = readl(pctl_base + DDR_PCTL2_RFSHCTL3) ^ (1 << 1);
-	writel(ret, pctl_base + DDR_PCTL2_RFSHCTL3);
-
-	return 0;
-}
-
 static int data_training(struct dram_info *dram, u32 cs, u32 dramtype)
 {
-	u32 ret;
-	u32 dis_auto_zq = 0;
-	void __iomem *pctl_base = dram->pctl;
-	void __iomem *phy_base = dram->phy;
-
-	/* disable zqcs */
-	if (!(readl(pctl_base + DDR_PCTL2_ZQCTL0) &
-		(1ul << 31))) {
-		dis_auto_zq = 1;
-		setbits_le32(pctl_base + DDR_PCTL2_ZQCTL0, 1 << 31);
-	}
-	/* disable auto refresh */
-	setbits_le32(pctl_base + DDR_PCTL2_RFSHCTL3, 1);
-	update_refresh_reg(dram);
-
-	if (dramtype == DDR4) {
-		clrsetbits_le32(PHY_REG(phy_base, 0x29), 0x3, 0);
-		clrsetbits_le32(PHY_REG(phy_base, 0x39), 0x3, 0);
-		clrsetbits_le32(PHY_REG(phy_base, 0x49), 0x3, 0);
-		clrsetbits_le32(PHY_REG(phy_base, 0x59), 0x3, 0);
-	}
-	/* choose training cs */
-	clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs));
-	/* enable gate training */
-	clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs) | 1);
-	udelay(50);
-	ret = readl(PHY_REG(phy_base, 0xff));
-	/* disable gate training */
-	clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs) | 0);
-	/* restore zqcs */
-	if (dis_auto_zq)
-		clrbits_le32(pctl_base + DDR_PCTL2_ZQCTL0, 1 << 31);
-	/* restore auto refresh */
-	clrbits_le32(pctl_base + DDR_PCTL2_RFSHCTL3, 1);
-	update_refresh_reg(dram);
-
-	if (dramtype == DDR4) {
-		clrsetbits_le32(PHY_REG(phy_base, 0x29), 0x3, 0x2);
-		clrsetbits_le32(PHY_REG(phy_base, 0x39), 0x3, 0x2);
-		clrsetbits_le32(PHY_REG(phy_base, 0x49), 0x3, 0x2);
-		clrsetbits_le32(PHY_REG(phy_base, 0x59), 0x3, 0x2);
-	}
-
-	if (ret & 0x10) {
-		ret = -1;
-	} else {
-		ret = (ret & 0xf) ^ (readl(PHY_REG(phy_base, 0)) >> 4);
-		ret = (ret == 0) ? 0 : -1;
-	}
-	return ret;
-}
-
-/* rank = 1: cs0
- * rank = 2: cs1
- * rank = 3: cs0 & cs1
- * note: be careful of keep mr original val
- */
-static int write_mr(struct dram_info *dram, u32 rank, u32 mr_num, u32 arg,
-		    u32 dramtype)
-{
 	void __iomem *pctl_base = dram->pctl;
-
-	while (readl(pctl_base + DDR_PCTL2_MRSTAT) & MR_WR_BUSY)
-		continue;
-	if (dramtype == DDR3 || dramtype == DDR4) {
-		writel((mr_num << 12) | (rank << 4) | (0 << 0),
-		       pctl_base + DDR_PCTL2_MRCTRL0);
-		writel(arg, pctl_base + DDR_PCTL2_MRCTRL1);
-	} else {
-		writel((rank << 4) | (0 << 0),
-		       pctl_base + DDR_PCTL2_MRCTRL0);
-		writel((mr_num << 8) | (arg & 0xff),
-		       pctl_base + DDR_PCTL2_MRCTRL1);
-	}
-
-	setbits_le32(pctl_base + DDR_PCTL2_MRCTRL0, 1u << 31);
-	while (readl(pctl_base + DDR_PCTL2_MRCTRL0) & (1u << 31))
-		continue;
-	while (readl(pctl_base + DDR_PCTL2_MRSTAT) & MR_WR_BUSY)
-		continue;
-
-	return 0;
-}
-
-/*
- * rank : 1:cs0, 2:cs1, 3:cs0&cs1
- * vrefrate: 4500: 45%,
- */
-static int write_vrefdq(struct dram_info *dram, u32 rank, u32 vrefrate,
-			u32 dramtype)
-{
-	u32 tccd_l, value;
 	u32 dis_auto_zq = 0;
-	void __iomem *pctl_base = dram->pctl;
-
-	if (dramtype != DDR4 || vrefrate < 4500 || vrefrate > 9200)
-		return -1;
+	u32 pwrctl;
+	u32 ret;
 
-	tccd_l = (readl(pctl_base + DDR_PCTL2_DRAMTMG4) >> 16) & 0xf;
-	tccd_l = (tccd_l - 4) << 10;
+	/* disable auto low-power */
+	pwrctl = readl(pctl_base + DDR_PCTL2_PWRCTL);
+	writel(0, pctl_base + DDR_PCTL2_PWRCTL);
 
-	if (vrefrate > 7500) {
-		/* range 1 */
-		value = ((vrefrate - 6000) / 65) | tccd_l;
-	} else {
-		/* range 2 */
-		value = ((vrefrate - 4500) / 65) | tccd_l | (1 << 6);
-	}
+	dis_auto_zq = pctl_dis_zqcs_aref(dram->pctl);
 
-	/* disable zqcs */
-	if (!(readl(pctl_base + DDR_PCTL2_ZQCTL0) &
-		(1ul << 31))) {
-		dis_auto_zq = 1;
-		setbits_le32(pctl_base + DDR_PCTL2_ZQCTL0, 1 << 31);
-	}
-	/* disable auto refresh */
-	setbits_le32(pctl_base + DDR_PCTL2_RFSHCTL3, 1);
-	update_refresh_reg(dram);
+	ret = phy_data_training(dram->phy, cs, dramtype);
 
-	/* enable vrefdq calibratin */
-	write_mr(dram, rank, 6, value | (1 << 7), dramtype);
-	udelay(1);/* tvrefdqe */
-	/* write vrefdq value */
-	write_mr(dram, rank, 6, value | (1 << 7), dramtype);
-	udelay(1);/* tvref_time */
-	write_mr(dram, rank, 6, value | (0 << 7), dramtype);
-	udelay(1);/* tvrefdqx */
+	pctl_rest_zqcs_aref(dram->pctl, dis_auto_zq);
 
-	/* restore zqcs */
-	if (dis_auto_zq)
-		clrbits_le32(pctl_base + DDR_PCTL2_ZQCTL0, 1 << 31);
-	/* restore auto refresh */
-	clrbits_le32(pctl_base + DDR_PCTL2_RFSHCTL3, 1);
-	update_refresh_reg(dram);
+	/* restore auto low-power */
+	writel(pwrctl, pctl_base + DDR_PCTL2_PWRCTL);
 
-	return 0;
+	return ret;
 }
 
-#define _MAX_(x, y) ((x) > (y) ? (x) : (y))
-
 static void rx_deskew_switch_adjust(struct dram_info *dram)
 {
 	u32 i, deskew_val;
@@ -557,7 +259,7 @@
 	void __iomem *phy_base = dram->phy;
 
 	for (i = 0; i < 4; i++)
-		gate_val = _MAX_(readl(PHY_REG(phy_base, 0xfb + i)), gate_val);
+		gate_val = MAX(readl(PHY_REG(phy_base, 0xfb + i)), gate_val);
 
 	deskew_val = (gate_val >> 3) + 1;
 	deskew_val = (deskew_val > 0x1f) ? 0x1f : deskew_val;
@@ -566,8 +268,6 @@
 			(deskew_val & 0x1c) << 2);
 }
 
-#undef _MAX_
-
 static void tx_deskew_switch_adjust(struct dram_info *dram)
 {
 	void __iomem *phy_base = dram->phy;
@@ -580,40 +280,39 @@
 	writel(ddrconfig, &dram->msch->ddrconf);
 }
 
-static void dram_all_config(struct dram_info *dram,
-			    struct rk3328_sdram_params *sdram_params)
+static void sdram_msch_config(struct msch_regs *msch,
+			      struct sdram_msch_timings *noc_timings)
 {
-	u32 sys_reg = 0, tmp = 0;
+	writel(noc_timings->ddrtiming.d32, &msch->ddrtiming);
 
-	set_ddrconfig(dram, sdram_ch.ddrconfig);
+	writel(noc_timings->ddrmode.d32, &msch->ddrmode);
+	writel(noc_timings->readlatency, &msch->readlatency);
 
-	sys_reg |= SYS_REG_ENC_DDRTYPE(sdram_params->dramtype);
-	sys_reg |= SYS_REG_ENC_ROW_3_4(sdram_ch.row_3_4, 0);
-	sys_reg |= SYS_REG_ENC_RANK(sdram_ch.rank, 0);
-	sys_reg |= SYS_REG_ENC_COL(sdram_ch.col, 0);
-	sys_reg |= SYS_REG_ENC_BK(sdram_ch.bk, 0);
-	SYS_REG_ENC_CS0_ROW(sdram_ch.cs0_row, sys_reg, tmp, 0);
-	if (sdram_ch.cs1_row)
-		SYS_REG_ENC_CS1_ROW(sdram_ch.cs1_row, sys_reg, tmp, 0);
-	sys_reg |= SYS_REG_ENC_BW(sdram_ch.bw, 0);
-	sys_reg |= SYS_REG_ENC_DBW(sdram_ch.dbw, 0);
-
-	writel(sys_reg, &dram->grf->os_reg[2]);
+	writel(noc_timings->activate.d32, &msch->activate);
+	writel(noc_timings->devtodev.d32, &msch->devtodev);
+	writel(noc_timings->ddr4timing.d32, &msch->ddr4_timing);
+	writel(noc_timings->agingx0, &msch->aging0);
+	writel(noc_timings->agingx0, &msch->aging1);
+	writel(noc_timings->agingx0, &msch->aging2);
+	writel(noc_timings->agingx0, &msch->aging3);
+	writel(noc_timings->agingx0, &msch->aging4);
+	writel(noc_timings->agingx0, &msch->aging5);
+}
 
-	writel(sdram_ch.noc_timings.ddrtiming.d32, &dram->msch->ddrtiming);
+static void dram_all_config(struct dram_info *dram,
+			    struct rk3328_sdram_params *sdram_params)
+{
+	struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
+	u32 sys_reg2 = 0;
+	u32 sys_reg3 = 0;
 
-	writel(sdram_ch.noc_timings.ddrmode.d32, &dram->msch->ddrmode);
-	writel(sdram_ch.noc_timings.readlatency, &dram->msch->readlatency);
+	set_ddrconfig(dram, cap_info->ddrconfig);
+	sdram_org_config(cap_info, &sdram_params->base, &sys_reg2,
+			 &sys_reg3, 0);
+	writel(sys_reg2, &dram->grf->os_reg[2]);
+	writel(sys_reg3, &dram->grf->os_reg[3]);
 
-	writel(sdram_ch.noc_timings.activate.d32, &dram->msch->activate);
-	writel(sdram_ch.noc_timings.devtodev.d32, &dram->msch->devtodev);
-	writel(sdram_ch.noc_timings.ddr4timing.d32, &dram->msch->ddr4_timing);
-	writel(sdram_ch.noc_timings.agingx0, &dram->msch->aging0);
-	writel(sdram_ch.noc_timings.agingx0, &dram->msch->aging1);
-	writel(sdram_ch.noc_timings.agingx0, &dram->msch->aging2);
-	writel(sdram_ch.noc_timings.agingx0, &dram->msch->aging3);
-	writel(sdram_ch.noc_timings.agingx0, &dram->msch->aging4);
-	writel(sdram_ch.noc_timings.agingx0, &dram->msch->aging5);
+	sdram_msch_config(dram->msch, &sdram_ch.noc_timings);
 }
 
 static void enable_low_power(struct dram_info *dram,
@@ -641,6 +340,7 @@
 static int sdram_init(struct dram_info *dram,
 		      struct rk3328_sdram_params *sdram_params, u32 pre_init)
 {
+	struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
 	void __iomem *pctl_base = dram->pctl;
 
 	rkclk_ddr_reset(dram, 1, 1, 1, 1);
@@ -652,30 +352,18 @@
 	 */
 	rkclk_ddr_reset(dram, 1, 1, 1, 0);
 	rkclk_configure_ddr(dram, sdram_params);
-	if (pre_init == 0) {
-		switch (sdram_params->dramtype) {
-		case DDR3:
-			printf("DDR3\n");
-			break;
-		case DDR4:
-			printf("DDR4\n");
-			break;
-		case LPDDR3:
-		default:
-			printf("LPDDR3\n");
-			break;
-		}
-	}
+
 	/* release phy srst to provide clk to ctrl */
 	rkclk_ddr_reset(dram, 1, 1, 0, 0);
 	udelay(10);
-	phy_soft_reset(dram);
+	phy_soft_reset(dram->phy);
 	/* release ctrl presetn, and config ctl registers */
 	rkclk_ddr_reset(dram, 1, 0, 0, 0);
-	pctl_cfg(dram, sdram_params);
-	sdram_ch.ddrconfig = calculate_ddrconfig(sdram_params);
+	pctl_cfg(dram->pctl, &sdram_params->pctl_regs, SR_IDLE, PD_IDLE);
+	cap_info->ddrconfig = calculate_ddrconfig(sdram_params);
 	set_ctl_address_map(dram, sdram_params);
-	phy_cfg(dram, sdram_params);
+	phy_cfg(dram->phy, &sdram_params->phy_regs, &sdram_params->skew,
+		&sdram_params->base, cap_info->bw);
 
 	/* enable dfi_init_start to init phy after ctl srstn deassert */
 	setbits_le32(pctl_base + DDR_PCTL2_DFIMISC, (1 << 5) | (1 << 4));
@@ -685,13 +373,18 @@
 		continue;
 
 	/* do ddr gate training */
-	if (data_training(dram, 0, sdram_params->dramtype) != 0) {
+	if (data_training(dram, 0, sdram_params->base.dramtype) != 0) {
+		printf("data training error\n");
+		return -1;
+	}
+	if (data_training(dram, 1, sdram_params->base.dramtype) != 0) {
 		printf("data training error\n");
 		return -1;
 	}
 
-	if (sdram_params->dramtype == DDR4)
-		write_vrefdq(dram, 0x3, 5670, sdram_params->dramtype);
+	if (sdram_params->base.dramtype == DDR4)
+		pctl_write_vrefdq(dram->pctl, 0x3, 5670,
+				  sdram_params->base.dramtype);
 
 	if (pre_init == 0) {
 		rx_deskew_switch_adjust(dram);
@@ -708,7 +401,7 @@
 			   struct rk3328_sdram_params *sdram_params,
 			   unsigned char channel)
 {
-	void __iomem *pctl_base = dram->pctl;
+	struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
 
 	/*
 	 * for ddr3: ddrconf = 3
@@ -718,14 +411,10 @@
 	 */
 	u32 bk, bktmp;
 	u32 col, coltmp;
-	u32 row, rowtmp, row_3_4;
-	void __iomem *test_addr, *test_addr1;
-	u32 dbw;
+	u32 rowtmp;
 	u32 cs;
 	u32 bw = 1;
-	u64 cap = 0;
-	u32 dram_type = sdram_params->dramtype;
-	u32 pwrctl;
+	u32 dram_type = sdram_params->base.dramtype;
 
 	if (dram_type != DDR4) {
 		/* detect col and bk for ddr3/lpddr3 */
@@ -733,33 +422,10 @@
 		bktmp = 3;
 		rowtmp = 16;
 
-		for (col = coltmp; col >= 9; col -= 1) {
-			writel(0, SDRAM_ADDR);
-			test_addr = (void __iomem *)(SDRAM_ADDR +
-					(1ul << (col + bw - 1ul)));
-			writel(PATTERN, test_addr);
-			if ((readl(test_addr) == PATTERN) &&
-			    (readl(SDRAM_ADDR) == 0))
-				break;
-		}
-		if (col == 8) {
-			printf("col error\n");
+		if (sdram_detect_col(cap_info, coltmp) != 0)
 			goto cap_err;
-		}
-
-		test_addr = (void __iomem *)(SDRAM_ADDR +
-				(1ul << (coltmp + bktmp + bw - 1ul)));
-		writel(0, SDRAM_ADDR);
-		writel(PATTERN, test_addr);
-		if ((readl(test_addr) == PATTERN) &&
-		    (readl(SDRAM_ADDR) == 0))
-			bk = 3;
-		else
-			bk = 2;
-		if (dram_type == LPDDR3)
-			dbw = 2;
-		else
-			dbw = 1;
+		sdram_detect_bank(cap_info, coltmp, bktmp);
+		sdram_detect_dbw(cap_info, dram_type);
 	} else {
 		/* detect bg for ddr4 */
 		coltmp = 10;
@@ -768,178 +434,49 @@
 
 		col = 10;
 		bk = 2;
-		test_addr = (void __iomem *)(SDRAM_ADDR +
-				(1ul << (coltmp + bw + 1ul)));
-		writel(0, SDRAM_ADDR);
-		writel(PATTERN, test_addr);
-		if ((readl(test_addr) == PATTERN) &&
-		    (readl(SDRAM_ADDR) == 0))
-			dbw = 0;
-		else
-			dbw = 1;
+		cap_info->col = col;
+		cap_info->bk = bk;
+		sdram_detect_bg(cap_info, coltmp);
 	}
+
 	/* detect row */
-	for (row = rowtmp; row > 12; row--) {
-		writel(0, SDRAM_ADDR);
-		test_addr = (void __iomem *)(SDRAM_ADDR +
-				(1ul << (row + bktmp + coltmp + bw - 1ul)));
-		writel(PATTERN, test_addr);
-		if ((readl(test_addr) == PATTERN) &&
-		    (readl(SDRAM_ADDR) == 0))
-			break;
-	}
-	if (row == 12) {
-		printf("row error");
+	if (sdram_detect_row(cap_info, coltmp, bktmp, rowtmp) != 0)
 		goto cap_err;
-	}
-	/* detect row_3_4 */
-	test_addr = SDRAM_ADDR;
-	test_addr1 = (void __iomem *)(SDRAM_ADDR +
-			(0x3ul << (row + bktmp + coltmp + bw - 1ul - 1ul)));
-
-	writel(0, test_addr);
-	writel(PATTERN, test_addr1);
-	if ((readl(test_addr) == 0) &&
-	    (readl(test_addr1) == PATTERN))
-		row_3_4 = 0;
-	else
-		row_3_4 = 1;
 
-	/* disable auto low-power */
-	pwrctl = readl(pctl_base + DDR_PCTL2_PWRCTL);
-	writel(0, pctl_base + DDR_PCTL2_PWRCTL);
+	/* detect row_3_4 */
+	sdram_detect_row_3_4(cap_info, coltmp, bktmp);
 
-	/* bw and cs detect using phy read gate training */
+	/* bw and cs detect using data training */
 	if (data_training(dram, 1, dram_type) == 0)
 		cs = 1;
 	else
 		cs = 0;
+	cap_info->rank = cs + 1;
 
 	bw = 2;
-
-	/* restore auto low-power */
-	writel(pwrctl, pctl_base + DDR_PCTL2_PWRCTL);
-
-	sdram_ch.rank = cs + 1;
-	sdram_ch.col = col;
-	sdram_ch.bk = bk;
-	sdram_ch.dbw = dbw;
-	sdram_ch.bw = bw;
-	sdram_ch.cs0_row = row;
-	if (cs)
-		sdram_ch.cs1_row = row;
-	else
-		sdram_ch.cs1_row = 0;
-	sdram_ch.row_3_4 = row_3_4;
-
-	if (dram_type == DDR4)
-		cap = 1llu << (cs + row + bk + col + ((dbw == 0) ? 2 : 1) + bw);
-	else
-		cap = 1llu << (cs + row + bk + col + bw);
-
-	return cap;
-
-cap_err:
-	return 0;
-}
-
-static u32 remodify_sdram_params(struct rk3328_sdram_params *sdram_params)
-{
-	u32 tmp = 0, tmp_adr = 0, i;
-
-	for (i = 0; sdram_params->pctl_regs.pctl[i][0] != 0xFFFFFFFF; i++) {
-		if (sdram_params->pctl_regs.pctl[i][0] == 0) {
-			tmp = sdram_params->pctl_regs.pctl[i][1];/* MSTR */
-			tmp_adr = i;
-		}
-	}
-
-	tmp &= ~((3ul << 30) | (3ul << 24) | (3ul << 12));
+	cap_info->bw = bw;
 
-	switch (sdram_ch.dbw) {
-	case 2:
-		tmp |= (3ul << 30);
-		break;
-	case 1:
-		tmp |= (2ul << 30);
-		break;
-	case 0:
-	default:
-		tmp |= (1ul << 30);
-		break;
+	cap_info->cs0_high16bit_row = cap_info->cs0_row;
+	if (cs) {
+		cap_info->cs1_row = cap_info->cs0_row;
+		cap_info->cs1_high16bit_row = cap_info->cs0_row;
+	} else {
+		cap_info->cs1_row = 0;
+		cap_info->cs1_high16bit_row = 0;
 	}
 
-	if (sdram_ch.rank == 2)
-		tmp |= 3 << 24;
-	else
-		tmp |= 1 << 24;
-
-	tmp |= (2 - sdram_ch.bw) << 12;
-
-	sdram_params->pctl_regs.pctl[tmp_adr][1] = tmp;
-
-	if (sdram_ch.bw == 2)
-		sdram_ch.noc_timings.ddrtiming.b.bwratio = 0;
-	else
-		sdram_ch.noc_timings.ddrtiming.b.bwratio = 1;
-
 	return 0;
-}
-
-static int dram_detect_cs1_row(struct rk3328_sdram_params *sdram_params,
-			       unsigned char channel)
-{
-	u32 ret = 0;
-	u32 cs1_bit;
-	void __iomem *test_addr, *cs1_addr;
-	u32 row, bktmp, coltmp, bw;
-	u32 ddrconf = sdram_ch.ddrconfig;
-
-	if (sdram_ch.rank == 2) {
-		cs1_bit = addrmap[ddrconf][0] + 8;
-
-		if (cs1_bit > 31)
-			goto out;
-
-		cs1_addr = (void __iomem *)(1ul << cs1_bit);
-		if (cs1_bit < 20)
-			cs1_bit = 1;
-		else
-			cs1_bit = 0;
-
-		if (sdram_params->dramtype == DDR4) {
-			if (sdram_ch.dbw == 0)
-				bktmp = sdram_ch.bk + 2;
-			else
-				bktmp = sdram_ch.bk + 1;
-		} else {
-			bktmp = sdram_ch.bk;
-		}
-		bw = sdram_ch.bw;
-		coltmp = sdram_ch.col;
-
-		/* detect cs1 row */
-		for (row = sdram_ch.cs0_row; row > 12; row--) {
-			test_addr = (void __iomem *)(SDRAM_ADDR + cs1_addr +
-					(1ul << (row + cs1_bit + bktmp +
-					 coltmp + bw - 1ul)));
-			writel(0, SDRAM_ADDR + cs1_addr);
-			writel(PATTERN, test_addr);
-			if ((readl(test_addr) == PATTERN) &&
-			    (readl(SDRAM_ADDR + cs1_addr) == 0)) {
-				ret = row;
-				break;
-			}
-		}
-	}
-
-out:
-	return ret;
+cap_err:
+	return -1;
 }
 
 static int sdram_init_detect(struct dram_info *dram,
 			     struct rk3328_sdram_params *sdram_params)
 {
+	u32 sys_reg = 0;
+	u32 sys_reg3 = 0;
+	struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
+
 	debug("Starting SDRAM initialization...\n");
 
 	memcpy(&sdram_ch, &sdram_params->ch,
@@ -949,13 +486,29 @@
 	dram_detect_cap(dram, sdram_params, 0);
 
 	/* modify bw, cs related timing */
-	remodify_sdram_params(sdram_params);
+	pctl_remodify_sdram_params(&sdram_params->pctl_regs, cap_info,
+				   sdram_params->base.dramtype);
+
+	if (cap_info->bw == 2)
+		sdram_ch.noc_timings.ddrtiming.b.bwratio = 0;
+	else
+		sdram_ch.noc_timings.ddrtiming.b.bwratio = 1;
+
 	/* reinit sdram by real dram cap */
 	sdram_init(dram, sdram_params, 0);
 
 	/* redetect cs1 row */
-	sdram_ch.cs1_row =
-		dram_detect_cs1_row(sdram_params, 0);
+	sdram_detect_cs1_row(cap_info, sdram_params->base.dramtype);
+	if (cap_info->cs1_row) {
+		sys_reg = readl(&dram->grf->os_reg[2]);
+		sys_reg3 = readl(&dram->grf->os_reg[3]);
+		SYS_REG_ENC_CS1_ROW(cap_info->cs1_row,
+				    sys_reg, sys_reg3, 0);
+		writel(sys_reg, &dram->grf->os_reg[2]);
+		writel(sys_reg3, &dram->grf->os_reg[3]);
+	}
+
+	sdram_print_ddr_info(&sdram_params->ch.cap_info, &sdram_params->base);
 
 	return 0;
 }
diff --git a/drivers/ram/rockchip/sdram_rk3399.c b/drivers/ram/rockchip/sdram_rk3399.c
index ed70137..7b2bba0 100644
--- a/drivers/ram/rockchip/sdram_rk3399.c
+++ b/drivers/ram/rockchip/sdram_rk3399.c
@@ -18,7 +18,7 @@
 #include <asm/arch-rockchip/grf_rk3399.h>
 #include <asm/arch-rockchip/pmu_rk3399.h>
 #include <asm/arch-rockchip/hardware.h>
-#include <asm/arch-rockchip/sdram_common.h>
+#include <asm/arch-rockchip/sdram.h>
 #include <asm/arch-rockchip/sdram_rk3399.h>
 #include <linux/err.h>
 #include <time.h>
@@ -44,6 +44,11 @@
 #define CS0_MR22_VAL		0
 #define CS1_MR22_VAL		3
 
+/* LPDDR3 DRAM DS */
+#define LPDDR3_DS_34		0x1
+#define LPDDR3_DS_40		0x2
+#define LPDDR3_DS_48		0x3
+
 #define CRU_SFTRST_DDR_CTRL(ch, n)	((0x1 << (8 + 16 + (ch) * 4)) | \
 					((n) << (8 + (ch) * 4)))
 #define CRU_SFTRST_DDR_PHY(ch, n)	((0x1 << (9 + 16 + (ch) * 4)) | \
@@ -52,7 +57,7 @@
 	struct rk3399_ddr_pctl_regs *pctl;
 	struct rk3399_ddr_pi_regs *pi;
 	struct rk3399_ddr_publ_regs *publ;
-	struct rk3399_msch_regs *msch;
+	struct msch_regs *msch;
 };
 
 struct dram_info {
@@ -74,10 +79,15 @@
 };
 
 struct sdram_rk3399_ops {
-	int (*data_training)(struct dram_info *dram, u32 channel, u8 rank,
-			     struct rk3399_sdram_params *sdram);
-	int (*set_rate)(struct dram_info *dram,
-			struct rk3399_sdram_params *params);
+	int (*data_training_first)(struct dram_info *dram, u32 channel, u8 rank,
+				   struct rk3399_sdram_params *sdram);
+	int (*set_rate_index)(struct dram_info *dram,
+			      struct rk3399_sdram_params *params);
+	void (*modify_param)(const struct chan_info *chan,
+			     struct rk3399_sdram_params *params);
+	struct rk3399_sdram_params *
+		(*get_phy_index_params)(u32 phy_fn,
+					struct rk3399_sdram_params *params);
 };
 
 #if defined(CONFIG_TPL_BUILD) || \
@@ -144,38 +154,21 @@
 		32,	/* rd_vref; (unit %, range 3.3% - 48.7%) */
 	},
 	{
-		800 * MHz,
+		933 * MHz,
 		0,
 		/* dram side */
 		1,	/* dq_odt; */
 		0,	/* ca_odt; */
-		1,	/* pdds; */
+		3,	/* pdds; */
 		0x72,	/* dq_vref; */
 		0x72,	/* ca_vref; */
 		/* phy side */
-		PHY_DRV_ODT_40,	/* rd_odt; */
-		PHY_DRV_ODT_48,	/* wr_dq_drv; */
+		PHY_DRV_ODT_80,	/* rd_odt; */
+		PHY_DRV_ODT_40,	/* wr_dq_drv; */
 		PHY_DRV_ODT_40,	/* wr_ca_drv; */
 		PHY_DRV_ODT_40,	/* wr_ckcs_drv; */
 		1,	/* rd_odt_en; */
-		17,	/* rd_vref; (unit %, range 3.3% - 48.7%) */
-	},
-	{
-		933 * MHz,
-		0,
-		/* dram side */
-		3,	/* dq_odt; */
-		0,	/* ca_odt; */
-		6,	/* pdds; */
-		0x59,	/* dq_vref; 32% */
-		0x72,	/* ca_vref; */
-		/* phy side */
-		PHY_DRV_ODT_HI_Z,	/* rd_odt; */
-		PHY_DRV_ODT_48,	/* wr_dq_drv; */
-		PHY_DRV_ODT_40,	/* wr_ca_drv; */
-		PHY_DRV_ODT_40,	/* wr_ckcs_drv; */
-		0,	/* rd_odt_en; */
-		32,	/* rd_vref; (unit %, range 3.3% - 48.7%) */
+		20,	/* rd_vref; (unit %, range 3.3% - 48.7%) */
 	},
 	{
 		1066 * MHz,
@@ -183,24 +176,19 @@
 		/* dram side */
 		6,	/* dq_odt; */
 		0,	/* ca_odt; */
-		1,	/* pdds; */
+		3,	/* pdds; */
 		0x10,	/* dq_vref; */
 		0x72,	/* ca_vref; */
 		/* phy side */
-		PHY_DRV_ODT_40,	/* rd_odt; */
+		PHY_DRV_ODT_80,	/* rd_odt; */
 		PHY_DRV_ODT_60,	/* wr_dq_drv; */
 		PHY_DRV_ODT_40,	/* wr_ca_drv; */
 		PHY_DRV_ODT_40,	/* wr_ckcs_drv; */
 		1,	/* rd_odt_en; */
-		17,	/* rd_vref; (unit %, range 3.3% - 48.7%) */
+		20,	/* rd_vref; (unit %, range 3.3% - 48.7%) */
 	},
 };
 
-/**
- * phy = 0, PHY boot freq
- * phy = 1, PHY index 0
- * phy = 2, PHY index 1
- */
 static struct io_setting *
 lpddr4_get_io_settings(const struct rk3399_sdram_params *params, u32 mr5)
 {
@@ -223,32 +211,21 @@
 	return io;
 }
 
-static void *get_denali_phy(const struct chan_info *chan,
-			    struct rk3399_sdram_params *params, bool reg)
-{
-	return reg ? &chan->publ->denali_phy : &params->phy_regs.denali_phy;
-}
-
 static void *get_denali_ctl(const struct chan_info *chan,
 			    struct rk3399_sdram_params *params, bool reg)
 {
 	return reg ? &chan->pctl->denali_ctl : &params->pctl_regs.denali_ctl;
 }
 
-static void *get_ddrc0_con(struct dram_info *dram, u8 channel)
+static void *get_denali_phy(const struct chan_info *chan,
+			    struct rk3399_sdram_params *params, bool reg)
 {
-	return (channel == 0) ? &dram->grf->ddrc0_con0 : &dram->grf->ddrc0_con1;
+	return reg ? &chan->publ->denali_phy : &params->phy_regs.denali_phy;
 }
 
-static void copy_to_reg(u32 *dest, const u32 *src, u32 n)
+static void *get_ddrc0_con(struct dram_info *dram, u8 channel)
 {
-	int i;
-
-	for (i = 0; i < n / sizeof(u32); i++) {
-		writel(*src, dest);
-		src++;
-		dest++;
-	}
+	return (channel == 0) ? &dram->grf->ddrc0_con0 : &dram->grf->ddrc1_con0;
 }
 
 static void rkclk_ddr_reset(struct rk3399_cru *cru, u32 channel, u32 ctl,
@@ -319,7 +296,8 @@
 	if (sdram_ch->cap_info.ddrconfig < 2 ||
 	    sdram_ch->cap_info.ddrconfig == 4)
 		row = 16;
-	else if (sdram_ch->cap_info.ddrconfig == 3)
+	else if (sdram_ch->cap_info.ddrconfig == 3 ||
+		 sdram_ch->cap_info.ddrconfig == 5)
 		row = 14;
 	else
 		row = 15;
@@ -344,7 +322,7 @@
 			((3 - sdram_ch->cap_info.bk) << 16) |
 			((16 - row) << 24));
 
-	if (IS_ENABLED(CONFIG_RAM_RK3399_LPDDR4)) {
+	if (params->base.dramtype == LPDDR4) {
 		if (cs_map == 1)
 			cs_map = 0x5;
 		else if (cs_map == 2)
@@ -363,11 +341,12 @@
 			 const struct rk3399_sdram_params *params, u32 mr5)
 {
 	u32 *denali_phy = chan->publ->denali_phy;
+	u32 *denali_ctl = chan->pctl->denali_ctl;
 	u32 vref_mode_dq, vref_value_dq, vref_mode_ac, vref_value_ac;
 	u32 mode_sel;
-	u32 reg_value;
-	u32 drv_value, odt_value;
 	u32 speed;
+	u32 reg_value;
+	u32 ds_value, odt_value;
 
 	/* vref setting & mode setting */
 	if (params->base.dramtype == LPDDR4) {
@@ -393,12 +372,12 @@
 	} else if (params->base.dramtype == LPDDR3) {
 		if (params->base.odt == 1) {
 			vref_mode_dq = 0x5;  /* LPDDR3 ODT */
-			drv_value = (readl(&denali_phy[6]) >> 12) & 0xf;
+			ds_value = readl(&denali_ctl[138]) & 0xf;
 			odt_value = (readl(&denali_phy[6]) >> 4) & 0xf;
-			if (drv_value == PHY_DRV_ODT_48) {
+			if (ds_value == LPDDR3_DS_48) {
 				switch (odt_value) {
 				case PHY_DRV_ODT_240:
-					vref_value_dq = 0x16;
+					vref_value_dq = 0x1B;
 					break;
 				case PHY_DRV_ODT_120:
 					vref_value_dq = 0x26;
@@ -410,7 +389,7 @@
 					debug("Invalid ODT value.\n");
 					return -EINVAL;
 				}
-			} else if (drv_value == PHY_DRV_ODT_40) {
+			} else if (ds_value == LPDDR3_DS_40) {
 				switch (odt_value) {
 				case PHY_DRV_ODT_240:
 					vref_value_dq = 0x19;
@@ -425,7 +404,7 @@
 					debug("Invalid ODT value.\n");
 					return -EINVAL;
 				}
-			} else if (drv_value == PHY_DRV_ODT_34_3) {
+			} else if (ds_value == LPDDR3_DS_34) {
 				switch (odt_value) {
 				case PHY_DRV_ODT_240:
 					vref_value_dq = 0x17;
@@ -496,7 +475,7 @@
 	/* PHY_939 PHY_PAD_CS_DRIVE */
 	clrsetbits_le32(&denali_phy[939], 0x7 << 14, mode_sel << 14);
 
-	if (IS_ENABLED(CONFIG_RAM_RK3399_LPDDR4)) {
+	if (params->base.dramtype == LPDDR4) {
 		/* BOOSTP_EN & BOOSTN_EN */
 		reg_value = ((PHY_BOOSTP_EN << 4) | PHY_BOOSTN_EN);
 		/* PHY_925 PHY_PAD_FDBK_DRIVE2 */
@@ -537,14 +516,7 @@
 	}
 
 	/* speed setting */
-	if (params->base.ddr_freq < 400)
-		speed = 0x0;
-	else if (params->base.ddr_freq < 800)
-		speed = 0x1;
-	else if (params->base.ddr_freq < 1200)
-		speed = 0x2;
-	else
-		speed = 0x3;
+	speed = 0x2;
 
 	/* PHY_924 PHY_PAD_FDBK_DRIVE */
 	clrsetbits_le32(&denali_phy[924], 0x3 << 21, speed << 21);
@@ -563,7 +535,7 @@
 	/* PHY_939 PHY_PAD_CS_DRIVE */
 	clrsetbits_le32(&denali_phy[939], 0x3 << 17, speed << 17);
 
-	if (IS_ENABLED(CONFIG_RAM_RK3399_LPDDR4)) {
+	if (params->base.dramtype == LPDDR4) {
 		/* RX_CM_INPUT */
 		reg_value = PHY_RX_CM_INPUT;
 		/* PHY_924 PHY_PAD_FDBK_DRIVE */
@@ -610,16 +582,17 @@
 		tsel_rd_select_n = io->rd_odt;
 
 		tsel_idle_select_p = PHY_DRV_ODT_HI_Z;
-		tsel_idle_select_n = PHY_DRV_ODT_240;
+		tsel_idle_select_n = PHY_DRV_ODT_HI_Z;
 
 		tsel_wr_select_dq_p = io->wr_dq_drv;
-		tsel_wr_select_dq_n = PHY_DRV_ODT_40;
+		tsel_wr_select_dq_n = PHY_DRV_ODT_34_3;
 
 		tsel_wr_select_ca_p = io->wr_ca_drv;
-		tsel_wr_select_ca_n = PHY_DRV_ODT_40;
+		tsel_wr_select_ca_n = PHY_DRV_ODT_34_3;
 
 		tsel_ckcs_select_p = io->wr_ckcs_drv;
 		tsel_ckcs_select_n = PHY_DRV_ODT_34_3;
+
 		switch (tsel_rd_select_n) {
 		case PHY_DRV_ODT_240:
 			soc_odt = 1;
@@ -659,8 +632,8 @@
 		tsel_wr_select_dq_p = PHY_DRV_ODT_34_3;
 		tsel_wr_select_dq_n = PHY_DRV_ODT_34_3;
 
-		tsel_wr_select_ca_p = PHY_DRV_ODT_48;
-		tsel_wr_select_ca_n = PHY_DRV_ODT_48;
+		tsel_wr_select_ca_p = PHY_DRV_ODT_34_3;
+		tsel_wr_select_ca_n = PHY_DRV_ODT_34_3;
 
 		tsel_ckcs_select_p = PHY_DRV_ODT_34_3;
 		tsel_ckcs_select_n = PHY_DRV_ODT_34_3;
@@ -733,7 +706,7 @@
 
 	/* phy_adr_tsel_select_ 8bits DENALI_PHY_544/672/800 offset_0 */
 	reg_value = tsel_wr_select_ca_n | (tsel_wr_select_ca_p << 0x4);
-	if (IS_ENABLED(CONFIG_RAM_RK3399_LPDDR4)) {
+	if (params->base.dramtype == LPDDR4) {
 		/* LPDDR4 these register read always return 0, so
 		 * can not use clrsetbits_le32(), need to write32
 		 */
@@ -766,9 +739,9 @@
 
 	/* phy_pad_fdbk_drive 23bit DENALI_PHY_924/925 */
 	clrsetbits_le32(&denali_phy[924], 0xff,
-			tsel_wr_select_dq_n | (tsel_wr_select_dq_p << 4));
+			tsel_wr_select_ca_n | (tsel_wr_select_ca_p << 4));
 	clrsetbits_le32(&denali_phy[925], 0xff,
-			tsel_rd_select_n | (tsel_rd_select_p << 4));
+			tsel_wr_select_dq_n | (tsel_wr_select_dq_p << 4));
 
 	/* phy_dq_tsel_enable_X 3bits DENALI_PHY_5/133/261/389 offset_16 */
 	reg_value = (tsel_rd_en | (tsel_wr_en << 1) | (tsel_idle_en << 2))
@@ -810,46 +783,107 @@
 	phy_io_config(chan, params, mr5);
 }
 
-static void pctl_start(struct dram_info *dram, u8 channel)
+static void pctl_start(struct dram_info *dram,
+		       struct rk3399_sdram_params *params,
+		       u32 channel_mask)
 {
-	const struct chan_info *chan = &dram->chan[channel];
-	u32 *denali_ctl = chan->pctl->denali_ctl;
-	u32 *denali_phy = chan->publ->denali_phy;
-	u32 *ddrc0_con = get_ddrc0_con(dram, channel);
+	const struct chan_info *chan_0 = &dram->chan[0];
+	const struct chan_info *chan_1 = &dram->chan[1];
+
+	u32 *denali_ctl_0 = chan_0->pctl->denali_ctl;
+	u32 *denali_phy_0 = chan_0->publ->denali_phy;
+	u32 *ddrc0_con_0 = get_ddrc0_con(dram, 0);
+	u32 *denali_ctl_1 = chan_1->pctl->denali_ctl;
+	u32 *denali_phy_1 = chan_1->publ->denali_phy;
+	u32 *ddrc1_con_0 = get_ddrc0_con(dram, 1);
 	u32 count = 0;
 	u32 byte, tmp;
 
-	writel(0x01000000, &ddrc0_con);
+	/* PHY_DLL_RST_EN */
+	if (channel_mask & 1) {
+		writel(0x01000000, &ddrc0_con_0);
+		clrsetbits_le32(&denali_phy_0[957], 0x3 << 24, 0x2 << 24);
+	}
 
-	clrsetbits_le32(&denali_phy[957], 0x3 << 24, 0x2 << 24);
+	if (channel_mask & 1) {
+		count = 0;
+		while (!(readl(&denali_ctl_0[203]) & (1 << 3))) {
+			if (count > 1000) {
+				printf("%s: Failed to init pctl channel 0\n",
+				       __func__);
+				while (1)
+					;
+			}
+			udelay(1);
+			count++;
+		}
 
-	while (!(readl(&denali_ctl[203]) & (1 << 3))) {
-		if (count > 1000) {
-			printf("%s: Failed to init pctl for channel %d\n",
-			       __func__, channel);
-			while (1)
-				;
+		writel(0x01000100, &ddrc0_con_0);
+		for (byte = 0; byte < 4; byte++)	{
+			tmp = 0x820;
+			writel((tmp << 16) | tmp,
+			       &denali_phy_0[53 + (128 * byte)]);
+			writel((tmp << 16) | tmp,
+			       &denali_phy_0[54 + (128 * byte)]);
+			writel((tmp << 16) | tmp,
+			       &denali_phy_0[55 + (128 * byte)]);
+			writel((tmp << 16) | tmp,
+			       &denali_phy_0[56 + (128 * byte)]);
+			writel((tmp << 16) | tmp,
+			       &denali_phy_0[57 + (128 * byte)]);
+			clrsetbits_le32(&denali_phy_0[58 + (128 * byte)],
+					0xffff, tmp);
 		}
+		clrsetbits_le32(&denali_ctl_0[68], PWRUP_SREFRESH_EXIT,
+				dram->pwrup_srefresh_exit[0]);
+	}
 
-		udelay(1);
-		count++;
+	if (channel_mask & 2) {
+		writel(0x01000000, &ddrc1_con_0);
+		clrsetbits_le32(&denali_phy_1[957], 0x3 << 24, 0x2 << 24);
 	}
+	if (channel_mask & 2) {
+		count = 0;
+		while (!(readl(&denali_ctl_1[203]) & (1 << 3))) {
+			if (count > 1000) {
+				printf("%s: Failed to init pctl channel 1\n",
+				       __func__);
+				while (1)
+					;
+			}
+			udelay(1);
+			count++;
+		}
 
-	writel(0x01000100, &ddrc0_con);
+		writel(0x01000100, &ddrc1_con_0);
+		for (byte = 0; byte < 4; byte++)	{
+			tmp = 0x820;
+			writel((tmp << 16) | tmp,
+			       &denali_phy_1[53 + (128 * byte)]);
+			writel((tmp << 16) | tmp,
+			       &denali_phy_1[54 + (128 * byte)]);
+			writel((tmp << 16) | tmp,
+			       &denali_phy_1[55 + (128 * byte)]);
+			writel((tmp << 16) | tmp,
+			       &denali_phy_1[56 + (128 * byte)]);
+			writel((tmp << 16) | tmp,
+			       &denali_phy_1[57 + (128 * byte)]);
+			clrsetbits_le32(&denali_phy_1[58 + (128 * byte)],
+					0xffff, tmp);
+		}
 
-	for (byte = 0; byte < 4; byte++) {
-		tmp = 0x820;
-		writel((tmp << 16) | tmp, &denali_phy[53 + (128 * byte)]);
-		writel((tmp << 16) | tmp, &denali_phy[54 + (128 * byte)]);
-		writel((tmp << 16) | tmp, &denali_phy[55 + (128 * byte)]);
-		writel((tmp << 16) | tmp, &denali_phy[56 + (128 * byte)]);
-		writel((tmp << 16) | tmp, &denali_phy[57 + (128 * byte)]);
+		clrsetbits_le32(&denali_ctl_1[68], PWRUP_SREFRESH_EXIT,
+				dram->pwrup_srefresh_exit[1]);
 
-		clrsetbits_le32(&denali_phy[58 + (128 * byte)], 0xffff, tmp);
+		/*
+		 * restore channel 1 RESET original setting
+		 * to avoid 240ohm too weak to prevent ESD test
+		 */
+		if (params->base.dramtype == LPDDR4)
+			clrsetbits_le32(&denali_phy_1[937], 0xff,
+					params->phy_regs.denali_phy[937] &
+					0xFF);
 	}
-
-	clrsetbits_le32(&denali_ctl[68], PWRUP_SREFRESH_EXIT,
-			dram->pwrup_srefresh_exit[channel]);
 }
 
 static int pctl_cfg(struct dram_info *dram, const struct chan_info *chan,
@@ -861,13 +895,16 @@
 	const u32 *params_ctl = params->pctl_regs.denali_ctl;
 	const u32 *params_phy = params->phy_regs.denali_phy;
 	u32 tmp, tmp1, tmp2;
+	struct rk3399_sdram_params *params_cfg;
+	u32 byte;
 
+	dram->ops->modify_param(chan, params);
 	/*
 	 * work around controller bug:
 	 * Do not program DRAM_CLASS until NO_PHY_IND_TRAIN_INT is programmed
 	 */
-	copy_to_reg(&denali_ctl[1], &params_ctl[1],
-		    sizeof(struct rk3399_ddr_pctl_regs) - 4);
+	sdram_copy_to_reg(&denali_ctl[1], &params_ctl[1],
+			  sizeof(struct rk3399_ddr_pctl_regs) - 4);
 	writel(params_ctl[0], &denali_ctl[0]);
 
 	/*
@@ -884,8 +921,8 @@
 		writel(tmp + tmp1, &denali_ctl[14]);
 	}
 
-	copy_to_reg(denali_pi, &params->pi_regs.denali_pi[0],
-		    sizeof(struct rk3399_ddr_pi_regs));
+	sdram_copy_to_reg(denali_pi, &params->pi_regs.denali_pi[0],
+			  sizeof(struct rk3399_ddr_pi_regs));
 
 	/* rank count need to set for init */
 	set_memory_map(chan, channel, params);
@@ -894,7 +931,7 @@
 	writel(params->phy_regs.denali_phy[911], &denali_phy[911]);
 	writel(params->phy_regs.denali_phy[912], &denali_phy[912]);
 
-	if (IS_ENABLED(CONFIG_RAM_RK3399_LPDDR4)) {
+	if (params->base.dramtype == LPDDR4) {
 		writel(params->phy_regs.denali_phy[898], &denali_phy[898]);
 		writel(params->phy_regs.denali_phy[919], &denali_phy[919]);
 	}
@@ -927,41 +964,67 @@
 		}
 	}
 
-	copy_to_reg(&denali_phy[896], &params_phy[896], (958 - 895) * 4);
-	copy_to_reg(&denali_phy[0], &params_phy[0], (90 - 0 + 1) * 4);
-	copy_to_reg(&denali_phy[128], &params_phy[128], (218 - 128 + 1) * 4);
-	copy_to_reg(&denali_phy[256], &params_phy[256], (346 - 256 + 1) * 4);
-	copy_to_reg(&denali_phy[384], &params_phy[384], (474 - 384 + 1) * 4);
-	copy_to_reg(&denali_phy[512], &params_phy[512], (549 - 512 + 1) * 4);
-	copy_to_reg(&denali_phy[640], &params_phy[640], (677 - 640 + 1) * 4);
-	copy_to_reg(&denali_phy[768], &params_phy[768], (805 - 768 + 1) * 4);
-	set_ds_odt(chan, params, true, 0);
+	sdram_copy_to_reg(&denali_phy[896], &params_phy[896], (958 - 895) * 4);
+	sdram_copy_to_reg(&denali_phy[0], &params_phy[0], (90 - 0 + 1) * 4);
+	sdram_copy_to_reg(&denali_phy[128], &params_phy[128],
+			  (218 - 128 + 1) * 4);
+	sdram_copy_to_reg(&denali_phy[256], &params_phy[256],
+			  (346 - 256 + 1) * 4);
+	sdram_copy_to_reg(&denali_phy[384], &params_phy[384],
+			  (474 - 384 + 1) * 4);
+	sdram_copy_to_reg(&denali_phy[512], &params_phy[512],
+			  (549 - 512 + 1) * 4);
+	sdram_copy_to_reg(&denali_phy[640], &params_phy[640],
+			  (677 - 640 + 1) * 4);
+	sdram_copy_to_reg(&denali_phy[768], &params_phy[768],
+			  (805 - 768 + 1) * 4);
 
-	/*
-	 * phy_dqs_tsel_wr_timing_X 8bits DENALI_PHY_84/212/340/468 offset_8
-	 * dqs_tsel_wr_end[7:4] add Half cycle
-	 */
-	tmp = (readl(&denali_phy[84]) >> 8) & 0xff;
-	clrsetbits_le32(&denali_phy[84], 0xff << 8, (tmp + 0x10) << 8);
-	tmp = (readl(&denali_phy[212]) >> 8) & 0xff;
-	clrsetbits_le32(&denali_phy[212], 0xff << 8, (tmp + 0x10) << 8);
-	tmp = (readl(&denali_phy[340]) >> 8) & 0xff;
-	clrsetbits_le32(&denali_phy[340], 0xff << 8, (tmp + 0x10) << 8);
-	tmp = (readl(&denali_phy[468]) >> 8) & 0xff;
-	clrsetbits_le32(&denali_phy[468], 0xff << 8, (tmp + 0x10) << 8);
+	if (params->base.dramtype == LPDDR4)
+		params_cfg = dram->ops->get_phy_index_params(1, params);
+	else
+		params_cfg = dram->ops->get_phy_index_params(0, params);
 
-	/*
-	 * phy_dqs_tsel_wr_timing_X 8bits DENALI_PHY_83/211/339/467 offset_8
-	 * dq_tsel_wr_end[7:4] add Half cycle
-	 */
-	tmp = (readl(&denali_phy[83]) >> 16) & 0xff;
-	clrsetbits_le32(&denali_phy[83], 0xff << 16, (tmp + 0x10) << 16);
-	tmp = (readl(&denali_phy[211]) >> 16) & 0xff;
-	clrsetbits_le32(&denali_phy[211], 0xff << 16, (tmp + 0x10) << 16);
-	tmp = (readl(&denali_phy[339]) >> 16) & 0xff;
-	clrsetbits_le32(&denali_phy[339], 0xff << 16, (tmp + 0x10) << 16);
-	tmp = (readl(&denali_phy[467]) >> 16) & 0xff;
-	clrsetbits_le32(&denali_phy[467], 0xff << 16, (tmp + 0x10) << 16);
+	clrsetbits_le32(&params_cfg->phy_regs.denali_phy[896], 0x3 << 8,
+			0 << 8);
+	writel(params_cfg->phy_regs.denali_phy[896], &denali_phy[896]);
+
+	writel(params->phy_regs.denali_phy[83] + (0x10 << 16),
+	       &denali_phy[83]);
+	writel(params->phy_regs.denali_phy[84] + (0x10 << 8),
+	       &denali_phy[84]);
+	writel(params->phy_regs.denali_phy[211] + (0x10 << 16),
+	       &denali_phy[211]);
+	writel(params->phy_regs.denali_phy[212] + (0x10 << 8),
+	       &denali_phy[212]);
+	writel(params->phy_regs.denali_phy[339] + (0x10 << 16),
+	       &denali_phy[339]);
+	writel(params->phy_regs.denali_phy[340] + (0x10 << 8),
+	       &denali_phy[340]);
+	writel(params->phy_regs.denali_phy[467] + (0x10 << 16),
+	       &denali_phy[467]);
+	writel(params->phy_regs.denali_phy[468] + (0x10 << 8),
+	       &denali_phy[468]);
+
+	if (params->base.dramtype == LPDDR4) {
+		/*
+		 * to improve write dqs and dq phase from 1.5ns to 3.5ns
+		 * at 50MHz. this's the measure result from oscilloscope
+		 * of dqs and dq write signal.
+		 */
+		for (byte = 0; byte < 4; byte++) {
+			tmp = 0x680;
+			clrsetbits_le32(&denali_phy[1 + (128 * byte)],
+					0xfff << 8, tmp << 8);
+		}
+		/*
+		 * to workaround 366ball two channel's RESET connect to
+		 * one RESET signal of die
+		 */
+		if (channel == 1)
+			clrsetbits_le32(&denali_phy[937], 0xff,
+					PHY_DRV_ODT_240 |
+					(PHY_DRV_ODT_240 << 0x4));
+	}
 
 	return 0;
 }
@@ -1277,10 +1340,9 @@
 
 		/*
 		 * disable PI_WDQLVL_VREF_EN before wdq leveling?
-		 * PI_181 PI_WDQLVL_VREF_EN:RW:8:1
+		 * PI_117 PI_WDQLVL_VREF_EN:RW:8:1
 		 */
-		clrbits_le32(&denali_pi[181], 0x1 << 8);
-
+		clrbits_le32(&denali_pi[117], 0x1 << 8);
 		/* PI_124 PI_WDQLVL_EN:RW:16:2 */
 		clrsetbits_le32(&denali_pi[124], 0x3 << 16, 0x2 << 16);
 
@@ -1392,7 +1454,7 @@
 			  unsigned char channel, u32 ddrconfig)
 {
 	/* only need to set ddrconfig */
-	struct rk3399_msch_regs *ddr_msch_regs = chan->msch;
+	struct msch_regs *ddr_msch_regs = chan->msch;
 	unsigned int cs0_cap = 0;
 	unsigned int cs1_cap = 0;
 
@@ -1413,52 +1475,43 @@
 	       &ddr_msch_regs->ddrsize);
 }
 
+static void sdram_msch_config(struct msch_regs *msch,
+			      struct sdram_msch_timings *noc_timings)
+{
+	writel(noc_timings->ddrtiminga0.d32,
+	       &msch->ddrtiminga0.d32);
+	writel(noc_timings->ddrtimingb0.d32,
+	       &msch->ddrtimingb0.d32);
+	writel(noc_timings->ddrtimingc0.d32,
+	       &msch->ddrtimingc0.d32);
+	writel(noc_timings->devtodev0.d32,
+	       &msch->devtodev0.d32);
+	writel(noc_timings->ddrmode.d32,
+	       &msch->ddrmode.d32);
+}
+
 static void dram_all_config(struct dram_info *dram,
-			    const struct rk3399_sdram_params *params)
+			    struct rk3399_sdram_params *params)
 {
 	u32 sys_reg2 = 0;
 	u32 sys_reg3 = 0;
 	unsigned int channel, idx;
 
-	sys_reg2 |= SYS_REG_ENC_DDRTYPE(params->base.dramtype);
-	sys_reg2 |= SYS_REG_ENC_NUM_CH(params->base.num_channels);
-
 	for (channel = 0, idx = 0;
 	     (idx < params->base.num_channels) && (channel < 2);
 	     channel++) {
-		const struct rk3399_sdram_channel *info = &params->ch[channel];
-		struct rk3399_msch_regs *ddr_msch_regs;
-		const struct rk3399_msch_timings *noc_timing;
+		struct msch_regs *ddr_msch_regs;
+		struct sdram_msch_timings *noc_timing;
 
 		if (params->ch[channel].cap_info.col == 0)
 			continue;
 		idx++;
-		sys_reg2 |= SYS_REG_ENC_ROW_3_4(info->cap_info.row_3_4, channel);
-		sys_reg2 |= SYS_REG_ENC_CHINFO(channel);
-		sys_reg2 |= SYS_REG_ENC_RANK(info->cap_info.rank, channel);
-		sys_reg2 |= SYS_REG_ENC_COL(info->cap_info.col, channel);
-		sys_reg2 |= SYS_REG_ENC_BK(info->cap_info.bk, channel);
-		sys_reg2 |= SYS_REG_ENC_BW(info->cap_info.bw, channel);
-		sys_reg2 |= SYS_REG_ENC_DBW(info->cap_info.dbw, channel);
-		SYS_REG_ENC_CS0_ROW(info->cap_info.cs0_row, sys_reg2, sys_reg3, channel);
-		if (info->cap_info.cs1_row)
-			SYS_REG_ENC_CS1_ROW(info->cap_info.cs1_row, sys_reg2,
-					    sys_reg3, channel);
-		sys_reg3 |= SYS_REG_ENC_CS1_COL(info->cap_info.col, channel);
-		sys_reg3 |= SYS_REG_ENC_VERSION(DDR_SYS_REG_VERSION);
-
+		sdram_org_config(&params->ch[channel].cap_info,
+				 &params->base, &sys_reg2,
+				 &sys_reg3, channel);
 		ddr_msch_regs = dram->chan[channel].msch;
 		noc_timing = &params->ch[channel].noc_timings;
-		writel(noc_timing->ddrtiminga0,
-		       &ddr_msch_regs->ddrtiminga0);
-		writel(noc_timing->ddrtimingb0,
-		       &ddr_msch_regs->ddrtimingb0);
-		writel(noc_timing->ddrtimingc0.d32,
-		       &ddr_msch_regs->ddrtimingc0);
-		writel(noc_timing->devtodev0,
-		       &ddr_msch_regs->devtodev0);
-		writel(noc_timing->ddrmode.d32,
-		       &ddr_msch_regs->ddrmode);
+		sdram_msch_config(ddr_msch_regs, noc_timing);
 
 		/**
 		 * rank 1 memory clock disable (dfi_dram_clk_disable = 1)
@@ -1494,7 +1547,7 @@
 {
 	u32 *denali_ctl = chan->pctl->denali_ctl;
 	u32 tmp;
-	struct rk3399_msch_timings *noc_timing;
+	struct sdram_msch_timings *noc_timing;
 
 	if (params->base.dramtype == LPDDR3) {
 		tmp = (8 << params->ch[channel].cap_info.bw) /
@@ -1566,9 +1619,14 @@
 	return i;
 }
 
+static void set_ddr_stride(struct rk3399_pmusgrf_regs *pmusgrf, u32 stride)
+{
+	rk_clrsetreg(&pmusgrf->soc_con4, 0x1f << 10, stride << 10);
+}
+
 #if !defined(CONFIG_RAM_RK3399_LPDDR4)
-static int default_data_training(struct dram_info *dram, u32 channel, u8 rank,
-				 struct rk3399_sdram_params *params)
+static int data_training_first(struct dram_info *dram, u32 channel, u8 rank,
+			       struct rk3399_sdram_params *params)
 {
 	u8 training_flag = PI_READ_GATE_TRAINING;
 
@@ -1629,31 +1687,72 @@
 	return 0;
 }
 
+struct rk3399_sdram_params
+	*get_phy_index_params(u32 phy_fn,
+			      struct rk3399_sdram_params *params)
+{
+	if (phy_fn == 0)
+		return params;
+	else
+		return NULL;
+}
+
+void modify_param(const struct chan_info *chan,
+		  struct rk3399_sdram_params *params)
+{
+	struct rk3399_sdram_params *params_cfg;
+	u32 *denali_pi_params;
+
+	denali_pi_params = params->pi_regs.denali_pi;
+
+	/* modify PHY F0/F1/F2 params */
+	params_cfg = get_phy_index_params(0, params);
+	set_ds_odt(chan, params_cfg, false, 0);
+
+	clrsetbits_le32(&denali_pi_params[45], 0x1 << 24, 0x1 << 24);
+	clrsetbits_le32(&denali_pi_params[61], 0x1 << 24, 0x1 << 24);
+	clrsetbits_le32(&denali_pi_params[76], 0x1 << 24, 0x1 << 24);
+	clrsetbits_le32(&denali_pi_params[77], 0x1, 0x1);
+}
 #else
 
-struct rk3399_sdram_params lpddr4_timings[] = {
-	#include "sdram-rk3399-lpddr4-400.inc"
-	#include "sdram-rk3399-lpddr4-800.inc"
+struct rk3399_sdram_params dfs_cfgs_lpddr4[] = {
+#include "sdram-rk3399-lpddr4-400.inc"
+#include "sdram-rk3399-lpddr4-800.inc"
 };
 
+static struct rk3399_sdram_params
+	*lpddr4_get_phy_index_params(u32 phy_fn,
+				     struct rk3399_sdram_params *params)
+{
+	if (phy_fn == 0)
+		return params;
+	else if (phy_fn == 1)
+		return &dfs_cfgs_lpddr4[1];
+	else if (phy_fn == 2)
+		return &dfs_cfgs_lpddr4[0];
+	else
+		return NULL;
+}
+
 static void *get_denali_pi(const struct chan_info *chan,
 			   struct rk3399_sdram_params *params, bool reg)
 {
 	return reg ? &chan->pi->denali_pi : &params->pi_regs.denali_pi;
 }
 
-static u32 lpddr4_get_phy(struct rk3399_sdram_params *params, u32 ctl)
+static u32 lpddr4_get_phy_fn(struct rk3399_sdram_params *params, u32 ctl_fn)
 {
-	u32 lpddr4_phy[] = {1, 0, 0xb};
+	u32 lpddr4_phy_fn[] = {1, 0, 0xb};
 
-	return lpddr4_phy[ctl];
+	return lpddr4_phy_fn[ctl_fn];
 }
 
-static u32 lpddr4_get_ctl(struct rk3399_sdram_params *params, u32 phy)
+static u32 lpddr4_get_ctl_fn(struct rk3399_sdram_params *params, u32 phy_fn)
 {
-	u32 lpddr4_ctl[] = {1, 0, 2};
+	u32 lpddr4_ctl_fn[] = {1, 0, 2};
 
-	return lpddr4_ctl[phy];
+	return lpddr4_ctl_fn[phy_fn];
 }
 
 static u32 get_ddr_stride(struct rk3399_pmusgrf_regs *pmusgrf)
@@ -1661,12 +1760,7 @@
 	return ((readl(&pmusgrf->soc_con4) >> 10) & 0x1F);
 }
 
-static void set_ddr_stride(struct rk3399_pmusgrf_regs *pmusgrf, u32 stride)
-{
-	rk_clrsetreg(&pmusgrf->soc_con4, 0x1f << 10, stride << 10);
-}
-
-/**
+/*
  * read mr_num mode register
  * rank = 1: cs0
  * rank = 2: cs1
@@ -1797,7 +1891,7 @@
 }
 
 static void set_lpddr4_dq_odt(const struct chan_info *chan,
-			      struct rk3399_sdram_params *params, u32 ctl,
+			      struct rk3399_sdram_params *params, u32 ctl_fn,
 			      bool en, bool ctl_phy_reg, u32 mr5)
 {
 	u32 *denali_ctl = get_denali_ctl(chan, params, ctl_phy_reg);
@@ -1805,14 +1899,13 @@
 	struct io_setting *io;
 	u32 reg_value;
 
-	if (!en)
-		return;
-
 	io = lpddr4_get_io_settings(params, mr5);
-
-	reg_value = io->dq_odt;
+	if (en)
+		reg_value = io->dq_odt;
+	else
+		reg_value = 0;
 
-	switch (ctl) {
+	switch (ctl_fn) {
 	case 0:
 		clrsetbits_le32(&denali_ctl[139], 0x7 << 24, reg_value << 24);
 		clrsetbits_le32(&denali_ctl[153], 0x7 << 24, reg_value << 24);
@@ -1845,7 +1938,7 @@
 }
 
 static void set_lpddr4_ca_odt(const struct chan_info *chan,
-			      struct rk3399_sdram_params *params, u32 ctl,
+			      struct rk3399_sdram_params *params, u32 ctl_fn,
 			      bool en, bool ctl_phy_reg, u32 mr5)
 {
 	u32 *denali_ctl = get_denali_ctl(chan, params, ctl_phy_reg);
@@ -1853,14 +1946,13 @@
 	struct io_setting *io;
 	u32 reg_value;
 
-	if (!en)
-		return;
-
 	io = lpddr4_get_io_settings(params, mr5);
-
-	reg_value = io->ca_odt;
+	if (en)
+		reg_value = io->ca_odt;
+	else
+		reg_value = 0;
 
-	switch (ctl) {
+	switch (ctl_fn) {
 	case 0:
 		clrsetbits_le32(&denali_ctl[139], 0x7 << 28, reg_value << 28);
 		clrsetbits_le32(&denali_ctl[153], 0x7 << 28, reg_value << 28);
@@ -1893,7 +1985,7 @@
 }
 
 static void set_lpddr4_MR3(const struct chan_info *chan,
-			   struct rk3399_sdram_params *params, u32 ctl,
+			   struct rk3399_sdram_params *params, u32 ctl_fn,
 			   bool ctl_phy_reg, u32 mr5)
 {
 	u32 *denali_ctl = get_denali_ctl(chan, params, ctl_phy_reg);
@@ -1905,7 +1997,7 @@
 
 	reg_value = ((io->pdds << 3) | 1);
 
-	switch (ctl) {
+	switch (ctl_fn) {
 	case 0:
 		clrsetbits_le32(&denali_ctl[138], 0xFFFF, reg_value);
 		clrsetbits_le32(&denali_ctl[152], 0xFFFF, reg_value);
@@ -1940,7 +2032,7 @@
 }
 
 static void set_lpddr4_MR12(const struct chan_info *chan,
-			    struct rk3399_sdram_params *params, u32 ctl,
+			    struct rk3399_sdram_params *params, u32 ctl_fn,
 			    bool ctl_phy_reg, u32 mr5)
 {
 	u32 *denali_ctl = get_denali_ctl(chan, params, ctl_phy_reg);
@@ -1952,7 +2044,7 @@
 
 	reg_value = io->ca_vref;
 
-	switch (ctl) {
+	switch (ctl_fn) {
 	case 0:
 		clrsetbits_le32(&denali_ctl[140], 0xFFFF << 16,
 				reg_value << 16);
@@ -1989,7 +2081,7 @@
 }
 
 static void set_lpddr4_MR14(const struct chan_info *chan,
-			    struct rk3399_sdram_params *params, u32 ctl,
+			    struct rk3399_sdram_params *params, u32 ctl_fn,
 			    bool ctl_phy_reg, u32 mr5)
 {
 	u32 *denali_ctl = get_denali_ctl(chan, params, ctl_phy_reg);
@@ -2001,7 +2093,7 @@
 
 	reg_value = io->dq_vref;
 
-	switch (ctl) {
+	switch (ctl_fn) {
 	case 0:
 		clrsetbits_le32(&denali_ctl[142], 0xFFFF << 16,
 				reg_value << 16);
@@ -2037,22 +2129,73 @@
 	}
 }
 
+void lpddr4_modify_param(const struct chan_info *chan,
+			 struct rk3399_sdram_params *params)
+{
+	struct rk3399_sdram_params *params_cfg;
+	u32 *denali_ctl_params;
+	u32 *denali_pi_params;
+	u32 *denali_phy_params;
+
+	denali_ctl_params = params->pctl_regs.denali_ctl;
+	denali_pi_params = params->pi_regs.denali_pi;
+	denali_phy_params = params->phy_regs.denali_phy;
+
+	set_lpddr4_dq_odt(chan, params, 2, true, false, 0);
+	set_lpddr4_ca_odt(chan, params, 2, true, false, 0);
+	set_lpddr4_MR3(chan, params, 2, false, 0);
+	set_lpddr4_MR12(chan, params, 2, false, 0);
+	set_lpddr4_MR14(chan, params, 2, false, 0);
+	params_cfg = lpddr4_get_phy_index_params(0, params);
+	set_ds_odt(chan, params_cfg, false, 0);
+	/* read two cycle preamble */
+	clrsetbits_le32(&denali_ctl_params[200], 0x3 << 24, 0x3 << 24);
+	clrsetbits_le32(&denali_phy_params[7], 0x3 << 24, 0x3 << 24);
+	clrsetbits_le32(&denali_phy_params[135], 0x3 << 24, 0x3 << 24);
+	clrsetbits_le32(&denali_phy_params[263], 0x3 << 24, 0x3 << 24);
+	clrsetbits_le32(&denali_phy_params[391], 0x3 << 24, 0x3 << 24);
+
+	/* boot frequency two cycle preamble */
+	clrsetbits_le32(&denali_phy_params[2], 0x3 << 16, 0x3 << 16);
+	clrsetbits_le32(&denali_phy_params[130], 0x3 << 16, 0x3 << 16);
+	clrsetbits_le32(&denali_phy_params[258], 0x3 << 16, 0x3 << 16);
+	clrsetbits_le32(&denali_phy_params[386], 0x3 << 16, 0x3 << 16);
+
+	clrsetbits_le32(&denali_pi_params[45], 0x3 << 8, 0x3 << 8);
+	clrsetbits_le32(&denali_pi_params[58], 0x1, 0x1);
+
+	/*
+	 * bypass mode need PHY_SLICE_PWR_RDC_DISABLE_x = 1,
+	 * boot frequency mode use bypass mode
+	 */
+	setbits_le32(&denali_phy_params[10], 1 << 16);
+	setbits_le32(&denali_phy_params[138], 1 << 16);
+	setbits_le32(&denali_phy_params[266], 1 << 16);
+	setbits_le32(&denali_phy_params[394], 1 << 16);
+
+	clrsetbits_le32(&denali_pi_params[45], 0x1 << 24, 0x1 << 24);
+	clrsetbits_le32(&denali_pi_params[61], 0x1 << 24, 0x1 << 24);
+	clrsetbits_le32(&denali_pi_params[76], 0x1 << 24, 0x1 << 24);
+	clrsetbits_le32(&denali_pi_params[77], 0x1, 0x1);
+}
+
 static void lpddr4_copy_phy(struct dram_info *dram,
-			    struct rk3399_sdram_params *params, u32 phy,
-			    struct rk3399_sdram_params *timings,
+			    struct rk3399_sdram_params *params, u32 phy_fn,
+			    struct rk3399_sdram_params *params_cfg,
 			    u32 channel)
 {
 	u32 *denali_ctl, *denali_phy;
 	u32 *denali_phy_params;
 	u32 speed = 0;
-	u32 ctl, mr5;
+	u32 ctl_fn, mr5;
 
 	denali_ctl = dram->chan[channel].pctl->denali_ctl;
 	denali_phy = dram->chan[channel].publ->denali_phy;
-	denali_phy_params = timings->phy_regs.denali_phy;
+	denali_phy_params = params_cfg->phy_regs.denali_phy;
 
 	/* switch index */
-	clrsetbits_le32(&denali_phy_params[896], 0x3 << 8, phy << 8);
+	clrsetbits_le32(&denali_phy_params[896], 0x3 << 8,
+			phy_fn << 8);
 	writel(denali_phy_params[896], &denali_phy[896]);
 
 	/* phy_pll_ctrl_ca, phy_pll_ctrl */
@@ -2112,14 +2255,14 @@
 	 * phy_clk_wrdqz_slave_delay_x
 	 * phy_clk_wrdqs_slave_delay_x
 	 */
-	copy_to_reg((u32 *)&denali_phy[59], (u32 *)&denali_phy_params[59],
-		    (63 - 58) * 4);
-	copy_to_reg((u32 *)&denali_phy[187], (u32 *)&denali_phy_params[187],
-		    (191 - 186) * 4);
-	copy_to_reg((u32 *)&denali_phy[315], (u32 *)&denali_phy_params[315],
-		    (319 - 314) * 4);
-	copy_to_reg((u32 *)&denali_phy[443], (u32 *)&denali_phy_params[443],
-		    (447 - 442) * 4);
+	sdram_copy_to_reg((u32 *)&denali_phy[59],
+			  (u32 *)&denali_phy_params[59], (63 - 58) * 4);
+	sdram_copy_to_reg((u32 *)&denali_phy[187],
+			  (u32 *)&denali_phy_params[187], (191 - 186) * 4);
+	sdram_copy_to_reg((u32 *)&denali_phy[315],
+			  (u32 *)&denali_phy_params[315], (319 - 314) * 4);
+	sdram_copy_to_reg((u32 *)&denali_phy[443],
+			  (u32 *)&denali_phy_params[443], (447 - 442) * 4);
 
 	/*
 	 * phy_dqs_tsel_wr_timing_x 8bits denali_phy_84/212/340/468 offset_8
@@ -2218,31 +2361,30 @@
 	 * phy_wrlvl_delay_period_threshold_x
 	 * phy_wrlvl_early_force_zero_x
 	 */
-	copy_to_reg((u32 *)&denali_phy[64], (u32 *)&denali_phy_params[64],
-		    (67 - 63) * 4);
+	sdram_copy_to_reg((u32 *)&denali_phy[64],
+			  (u32 *)&denali_phy_params[64], (67 - 63) * 4);
 	clrsetbits_le32(&denali_phy[68], 0xfffffc00,
 			denali_phy_params[68] & 0xfffffc00);
-	copy_to_reg((u32 *)&denali_phy[69], (u32 *)&denali_phy_params[69],
-		    (79 - 68) * 4);
-	copy_to_reg((u32 *)&denali_phy[192], (u32 *)&denali_phy_params[192],
-		    (195 - 191) * 4);
+	sdram_copy_to_reg((u32 *)&denali_phy[69],
+			  (u32 *)&denali_phy_params[69], (79 - 68) * 4);
+	sdram_copy_to_reg((u32 *)&denali_phy[192],
+			  (u32 *)&denali_phy_params[192], (195 - 191) * 4);
 	clrsetbits_le32(&denali_phy[196], 0xfffffc00,
 			denali_phy_params[196] & 0xfffffc00);
-	copy_to_reg((u32 *)&denali_phy[197], (u32 *)&denali_phy_params[197],
-		    (207 - 196) * 4);
-	copy_to_reg((u32 *)&denali_phy[320], (u32 *)&denali_phy_params[320],
-		    (323 - 319) * 4);
+	sdram_copy_to_reg((u32 *)&denali_phy[197],
+			  (u32 *)&denali_phy_params[197], (207 - 196) * 4);
+	sdram_copy_to_reg((u32 *)&denali_phy[320],
+			  (u32 *)&denali_phy_params[320], (323 - 319) * 4);
 	clrsetbits_le32(&denali_phy[324], 0xfffffc00,
 			denali_phy_params[324] & 0xfffffc00);
-	copy_to_reg((u32 *)&denali_phy[325], (u32 *)&denali_phy_params[325],
-		    (335 - 324) * 4);
-
-	copy_to_reg((u32 *)&denali_phy[448], (u32 *)&denali_phy_params[448],
-		    (451 - 447) * 4);
+	sdram_copy_to_reg((u32 *)&denali_phy[325],
+			  (u32 *)&denali_phy_params[325], (335 - 324) * 4);
+	sdram_copy_to_reg((u32 *)&denali_phy[448],
+			  (u32 *)&denali_phy_params[448], (451 - 447) * 4);
 	clrsetbits_le32(&denali_phy[452], 0xfffffc00,
 			denali_phy_params[452] & 0xfffffc00);
-	copy_to_reg((u32 *)&denali_phy[453], (u32 *)&denali_phy_params[453],
-		    (463 - 452) * 4);
+	sdram_copy_to_reg((u32 *)&denali_phy[453],
+			  (u32 *)&denali_phy_params[453], (463 - 452) * 4);
 
 	/* phy_two_cyc_preamble_x */
 	clrsetbits_le32(&denali_phy[7], 0x3 << 24,
@@ -2255,11 +2397,11 @@
 			denali_phy_params[391] & (0x3 << 24));
 
 	/* speed */
-	if (timings->base.ddr_freq < 400 * MHz)
+	if (params_cfg->base.ddr_freq < 400)
 		speed = 0x0;
-	else if (timings->base.ddr_freq < 800 * MHz)
+	else if (params_cfg->base.ddr_freq < 800)
 		speed = 0x1;
-	else if (timings->base.ddr_freq < 1200 * MHz)
+	else if (params_cfg->base.ddr_freq < 1200)
 		speed = 0x2;
 
 	/* phy_924 phy_pad_fdbk_drive */
@@ -2279,52 +2421,63 @@
 	/* phy_939 phy_pad_cs_drive */
 	clrsetbits_le32(&denali_phy[939], 0x3 << 17, speed << 17);
 
-	read_mr(dram->chan[channel].pctl, 1, 5, &mr5);
-	set_ds_odt(&dram->chan[channel], timings, true, mr5);
+	if (params_cfg->base.dramtype == LPDDR4) {
+		read_mr(dram->chan[channel].pctl, 1, 5, &mr5);
+		set_ds_odt(&dram->chan[channel], params_cfg, true, mr5);
 
-	ctl = lpddr4_get_ctl(timings, phy);
-	set_lpddr4_dq_odt(&dram->chan[channel], timings, ctl, true, true, mr5);
-	set_lpddr4_ca_odt(&dram->chan[channel], timings, ctl, true, true, mr5);
-	set_lpddr4_MR3(&dram->chan[channel], timings, ctl, true, mr5);
-	set_lpddr4_MR12(&dram->chan[channel], timings, ctl, true, mr5);
-	set_lpddr4_MR14(&dram->chan[channel], timings, ctl, true, mr5);
+		ctl_fn = lpddr4_get_ctl_fn(params_cfg, phy_fn);
+		set_lpddr4_dq_odt(&dram->chan[channel], params_cfg,
+				  ctl_fn, true, true, mr5);
+		set_lpddr4_ca_odt(&dram->chan[channel], params_cfg,
+				  ctl_fn, true, true, mr5);
+		set_lpddr4_MR3(&dram->chan[channel], params_cfg,
+			       ctl_fn, true, mr5);
+		set_lpddr4_MR12(&dram->chan[channel], params_cfg,
+				ctl_fn, true, mr5);
+		set_lpddr4_MR14(&dram->chan[channel], params_cfg,
+				ctl_fn, true, mr5);
 
-	/*
-	 * if phy_sw_master_mode_x not bypass mode,
-	 * clear phy_slice_pwr_rdc_disable.
-	 * note: need use timings, not ddr_publ_regs
-	 */
-	if (!((denali_phy_params[86] >> 8) & (1 << 2))) {
-		clrbits_le32(&denali_phy[10], 1 << 16);
-		clrbits_le32(&denali_phy[138], 1 << 16);
-		clrbits_le32(&denali_phy[266], 1 << 16);
-		clrbits_le32(&denali_phy[394], 1 << 16);
-	}
+		/*
+		 * if phy_sw_master_mode_x not bypass mode,
+		 * clear phy_slice_pwr_rdc_disable.
+		 * note: need use timings, not ddr_publ_regs
+		 */
+		if (!((denali_phy_params[86] >> 8) & (1 << 2))) {
+			clrbits_le32(&denali_phy[10], 1 << 16);
+			clrbits_le32(&denali_phy[138], 1 << 16);
+			clrbits_le32(&denali_phy[266], 1 << 16);
+			clrbits_le32(&denali_phy[394], 1 << 16);
+		}
 
-	/*
-	 * when PHY_PER_CS_TRAINING_EN=1, W2W_DIFFCS_DLY_Fx can't
-	 * smaller than 8
-	 * NOTE: need use timings, not ddr_publ_regs
-	 */
-	if ((denali_phy_params[84] >> 16) & 1) {
-		if (((readl(&denali_ctl[217 + ctl]) >> 16) & 0x1f) < 8)
-			clrsetbits_le32(&denali_ctl[217 + ctl],
-					0x1f << 16, 8 << 16);
+		/*
+		 * when PHY_PER_CS_TRAINING_EN=1, W2W_DIFFCS_DLY_Fx can't
+		 * smaller than 8
+		 * NOTE: need use timings, not ddr_publ_regs
+		 */
+		if ((denali_phy_params[84] >> 16) & 1) {
+			if (((readl(&denali_ctl[217 + ctl_fn]) >>
+				16) & 0x1f) < 8)
+				clrsetbits_le32(&denali_ctl[217 + ctl_fn],
+						0x1f << 16,
+						8 << 16);
+		}
 	}
 }
 
 static void lpddr4_set_phy(struct dram_info *dram,
-			   struct rk3399_sdram_params *params, u32 phy,
-			   struct rk3399_sdram_params *timings)
+			   struct rk3399_sdram_params *params, u32 phy_fn,
+			   struct rk3399_sdram_params *params_cfg)
 {
 	u32 channel;
 
 	for (channel = 0; channel < 2; channel++)
-		lpddr4_copy_phy(dram, params, phy, timings, channel);
+		lpddr4_copy_phy(dram, params, phy_fn, params_cfg,
+				channel);
 }
 
 static int lpddr4_set_ctl(struct dram_info *dram,
-			  struct rk3399_sdram_params *params, u32 ctl, u32 hz)
+			  struct rk3399_sdram_params *params,
+			  u32 fn, u32 hz)
 {
 	u32 channel;
 	int ret_clk, ret;
@@ -2343,7 +2496,7 @@
 
 	/* change freq */
 	writel((((0x3 << 4) | (1 << 2) | 1) << 16) |
-		(ctl << 4) | (1 << 2) | 1, &dram->cic->cic_ctrl0);
+		(fn << 4) | (1 << 2) | 1, &dram->cic->cic_ctrl0);
 	while (!(readl(&dram->cic->cic_status0) & (1 << 2)))
 		;
 
@@ -2366,12 +2519,12 @@
 	clrbits_le32(&dram->pmu->pmu_noc_auto_ena, (0x3 << 7));
 
 	/* lpddr4 ctl2 can not do training, all training will fail */
-	if (!(params->base.dramtype == LPDDR4 && ctl == 2)) {
+	if (!(params->base.dramtype == LPDDR4 && fn == 2)) {
 		for (channel = 0; channel < 2; channel++) {
 			if (!(params->ch[channel].cap_info.col))
 				continue;
 			ret = data_training(dram, channel, params,
-						     PI_FULL_TRAINING);
+					    PI_FULL_TRAINING);
 			if (ret)
 				printf("%s: channel %d training failed!\n",
 				       __func__, channel);
@@ -2387,35 +2540,237 @@
 static int lpddr4_set_rate(struct dram_info *dram,
 			   struct rk3399_sdram_params *params)
 {
-	u32 ctl;
-	u32 phy;
+	u32 ctl_fn;
+	u32 phy_fn;
 
-	for (ctl = 0; ctl < 2; ctl++) {
-		phy = lpddr4_get_phy(params, ctl);
+	for (ctl_fn = 0; ctl_fn < 2; ctl_fn++) {
+		phy_fn = lpddr4_get_phy_fn(params, ctl_fn);
 
-		lpddr4_set_phy(dram, params, phy, &lpddr4_timings[ctl]);
-		lpddr4_set_ctl(dram, params, ctl,
-			       lpddr4_timings[ctl].base.ddr_freq);
+		lpddr4_set_phy(dram, params, phy_fn, &dfs_cfgs_lpddr4[ctl_fn]);
+		lpddr4_set_ctl(dram, params, ctl_fn,
+			       dfs_cfgs_lpddr4[ctl_fn].base.ddr_freq);
 
-		debug("%s: change freq to %d mhz %d, %d\n", __func__,
-		      lpddr4_timings[ctl].base.ddr_freq / MHz, ctl, phy);
+		printf("%s: change freq to %d mhz %d, %d\n", __func__,
+		       dfs_cfgs_lpddr4[ctl_fn].base.ddr_freq, ctl_fn, phy_fn);
 	}
 
 	return 0;
 }
 #endif /* CONFIG_RAM_RK3399_LPDDR4 */
 
+/* CS0,n=1
+ * CS1,n=2
+ * CS0 & CS1, n=3
+ * cs0_cap: MB unit
+ */
+static void dram_set_cs(const struct chan_info *chan, u32 cs_map, u32 cs0_cap,
+			unsigned char dramtype)
+{
+	u32 *denali_ctl = chan->pctl->denali_ctl;
+	u32 *denali_pi = chan->pi->denali_pi;
+	struct msch_regs *ddr_msch_regs = chan->msch;
+
+	clrsetbits_le32(&denali_ctl[196], 0x3, cs_map);
+	writel((cs0_cap / 32) | (((4096 - cs0_cap) / 32) << 8),
+	       &ddr_msch_regs->ddrsize);
+	if (dramtype == LPDDR4) {
+		if (cs_map == 1)
+			cs_map = 0x5;
+		else if (cs_map == 2)
+			cs_map = 0xa;
+		else
+			cs_map = 0xF;
+	}
+	/*PI_41 PI_CS_MAP:RW:24:4*/
+	clrsetbits_le32(&denali_pi[41],
+			0xf << 24, cs_map << 24);
+	if (cs_map == 1 && dramtype == DDR3)
+		writel(0x2EC7FFFF, &denali_pi[34]);
+}
+
+static void dram_set_bw(const struct chan_info *chan, u32 bw)
+{
+	u32 *denali_ctl = chan->pctl->denali_ctl;
+
+	if (bw == 2)
+		clrbits_le32(&denali_ctl[196], 1 << 16);
+	else
+		setbits_le32(&denali_ctl[196], 1 << 16);
+}
+
+static void dram_set_max_col(const struct chan_info *chan, u32 bw, u32 *pcol)
+{
+	u32 *denali_ctl = chan->pctl->denali_ctl;
+	struct msch_regs *ddr_msch_regs = chan->msch;
+	u32 *denali_pi = chan->pi->denali_pi;
+	u32 ddrconfig;
+
+	clrbits_le32(&denali_ctl[191], 0xf);
+	clrsetbits_le32(&denali_ctl[190],
+			(7 << 24),
+			((16 - ((bw == 2) ? 14 : 15)) << 24));
+	/*PI_199 PI_COL_DIFF:RW:0:4*/
+	clrbits_le32(&denali_pi[199], 0xf);
+	/*PI_155 PI_ROW_DIFF:RW:24:3*/
+	clrsetbits_le32(&denali_pi[155],
+			(7 << 24),
+			((16 - 12) << 24));
+	ddrconfig = (bw == 2) ? 3 : 2;
+	writel(ddrconfig | (ddrconfig << 8), &ddr_msch_regs->ddrconf);
+	/* set max cs0 size */
+	writel((4096 / 32) | ((0 / 32) << 8),
+	       &ddr_msch_regs->ddrsize);
+
+	*pcol = 12;
+}
+
+static void dram_set_max_bank(const struct chan_info *chan, u32 bw, u32 *pbank,
+			      u32 *pcol)
+{
+	u32 *denali_ctl = chan->pctl->denali_ctl;
+	u32 *denali_pi = chan->pi->denali_pi;
+
+	clrbits_le32(&denali_ctl[191], 0xf);
+	clrbits_le32(&denali_ctl[190], (3 << 16));
+	/*PI_199 PI_COL_DIFF:RW:0:4*/
+	clrbits_le32(&denali_pi[199], 0xf);
+	/*PI_155 PI_BANK_DIFF:RW:16:2*/
+	clrbits_le32(&denali_pi[155], (3 << 16));
+
+	*pbank = 3;
+	*pcol = 12;
+}
+
+static void dram_set_max_row(const struct chan_info *chan, u32 bw, u32 *prow,
+			     u32 *pbank, u32 *pcol)
+{
+	u32 *denali_ctl = chan->pctl->denali_ctl;
+	u32 *denali_pi = chan->pi->denali_pi;
+	struct msch_regs *ddr_msch_regs = chan->msch;
+
+	clrsetbits_le32(&denali_ctl[191], 0xf, 12 - 10);
+	clrbits_le32(&denali_ctl[190],
+		     (0x3 << 16) | (0x7 << 24));
+	/*PI_199 PI_COL_DIFF:RW:0:4*/
+	clrsetbits_le32(&denali_pi[199], 0xf, 12 - 10);
+	/*PI_155 PI_ROW_DIFF:RW:24:3 PI_BANK_DIFF:RW:16:2*/
+	clrbits_le32(&denali_pi[155],
+		     (0x3 << 16) | (0x7 << 24));
+	writel(1 | (1 << 8), &ddr_msch_regs->ddrconf);
+	/* set max cs0 size */
+	writel((4096 / 32) | ((0 / 32) << 8),
+	       &ddr_msch_regs->ddrsize);
+
+	*prow = 16;
+	*pbank = 3;
+	*pcol = (bw == 2) ? 10 : 11;
+}
+
+static u64 dram_detect_cap(struct dram_info *dram,
+			   struct rk3399_sdram_params *params,
+			   unsigned char channel)
+{
+	const struct chan_info *chan = &dram->chan[channel];
+	struct sdram_cap_info *cap_info = &params->ch[channel].cap_info;
+	u32 bw;
+	u32 col_tmp;
+	u32 bk_tmp;
+	u32 row_tmp;
+	u32 cs0_cap;
+	u32 training_flag;
+	u32 ddrconfig;
+
+	/* detect bw */
+	bw = 2;
+	if (params->base.dramtype != LPDDR4) {
+		dram_set_bw(chan, bw);
+		cap_info->bw = bw;
+		if (data_training(dram, channel, params,
+				  PI_READ_GATE_TRAINING)) {
+			bw = 1;
+			dram_set_bw(chan, 1);
+			cap_info->bw = bw;
+			if (data_training(dram, channel, params,
+					  PI_READ_GATE_TRAINING)) {
+				printf("16bit error!!!\n");
+				goto error;
+			}
+		}
+	}
+	/*
+	 * LPDDR3 CA training msut be trigger before other training.
+	 * DDR3 is not have CA training.
+	 */
+	if (params->base.dramtype == LPDDR3)
+		training_flag = PI_WRITE_LEVELING;
+	else
+		training_flag = PI_FULL_TRAINING;
+
+	if (params->base.dramtype != LPDDR4) {
+		if (data_training(dram, channel, params, training_flag)) {
+			printf("full training error!!!\n");
+			goto error;
+		}
+	}
+
+	/* detect col */
+	dram_set_max_col(chan, bw, &col_tmp);
+	if (sdram_detect_col(cap_info, col_tmp) != 0)
+		goto error;
+
+	/* detect bank */
+	dram_set_max_bank(chan, bw, &bk_tmp, &col_tmp);
+	sdram_detect_bank(cap_info, col_tmp, bk_tmp);
+
+	/* detect row */
+	dram_set_max_row(chan, bw, &row_tmp, &bk_tmp, &col_tmp);
+	if (sdram_detect_row(cap_info, col_tmp, bk_tmp, row_tmp) != 0)
+		goto error;
+
+	/* detect row_3_4 */
+	sdram_detect_row_3_4(cap_info, col_tmp, bk_tmp);
+
+	/* set ddrconfig */
+	cs0_cap = (1 << (cap_info->cs0_row + cap_info->col + cap_info->bk +
+			 cap_info->bw - 20));
+	if (cap_info->row_3_4)
+		cs0_cap = cs0_cap * 3 / 4;
+
+	cap_info->cs1_row = cap_info->cs0_row;
+	set_memory_map(chan, channel, params);
+	ddrconfig = calculate_ddrconfig(params, channel);
+	if (-1 == ddrconfig)
+		goto error;
+	set_ddrconfig(chan, params, channel,
+		      cap_info->ddrconfig);
+
+	/* detect cs1 row */
+	sdram_detect_cs1_row(cap_info, params->base.dramtype);
+
+	/* detect die bw */
+	sdram_detect_dbw(cap_info, params->base.dramtype);
+
+	return 0;
+error:
+	return (-1);
+}
+
 static unsigned char calculate_stride(struct rk3399_sdram_params *params)
 {
-	unsigned int stride = params->base.stride;
-	unsigned int channel, chinfo = 0;
+	unsigned int gstride_type;
+	unsigned int channel;
+	unsigned int chinfo = 0;
+	unsigned int cap = 0;
+	unsigned int stride = -1;
 	unsigned int ch_cap[2] = {0, 0};
-	u64 cap;
+
+	gstride_type = STRIDE_256B;
 
 	for (channel = 0; channel < 2; channel++) {
 		unsigned int cs0_cap = 0;
 		unsigned int cs1_cap = 0;
-		struct sdram_cap_info *cap_info = &params->ch[channel].cap_info;
+		struct sdram_cap_info *cap_info =
+			&params->ch[channel].cap_info;
 
 		if (cap_info->col == 0)
 			continue;
@@ -2433,49 +2788,124 @@
 		chinfo |= 1 << channel;
 	}
 
-	/* stride calculation for 1 channel */
-	if (params->base.num_channels == 1 && chinfo & 1)
-		return 0x17;	/* channel a */
-
-	/* stride calculation for 2 channels, default gstride type is 256B */
-	if (ch_cap[0] == ch_cap[1]) {
-		cap = ch_cap[0] + ch_cap[1];
-		switch (cap) {
-		/* 512MB */
-		case 512:
-			stride = 0;
-			break;
-		/* 1GB */
-		case 1024:
-			stride = 0x5;
-			break;
+	cap = ch_cap[0] + ch_cap[1];
+	if (params->base.num_channels == 1) {
+		if (chinfo & 1) /* channel a only */
+			stride = 0x17;
+		else /* channel b only */
+			stride = 0x18;
+	} else {/* 2 channel */
+		if (ch_cap[0] == ch_cap[1]) {
+			/* interleaved */
+			if (gstride_type == PART_STRIDE) {
+			/*
+			 * first 64MB no interleaved other 256B interleaved
+			 * if 786M+768M.useful space from 0-1280MB and
+			 * 1536MB-1792MB
+			 * if 1.5G+1.5G(continuous).useful space from 0-2560MB
+			 * and 3072MB-3584MB
+			 */
+				stride = 0x1F;
+			} else {
+				switch (cap) {
+				/* 512MB */
+				case 512:
+					stride = 0;
+					break;
+				/* 1GB unstride or 256B stride*/
+				case 1024:
+					stride = (gstride_type == UN_STRIDE) ?
+						0x1 : 0x5;
+					break;
+				/*
+				 * 768MB + 768MB same as total 2GB memory
+				 * useful space: 0-768MB 1GB-1792MB
+				 */
+				case 1536:
+				/* 2GB unstride or 256B or 512B stride */
+				case 2048:
+					stride = (gstride_type == UN_STRIDE) ?
+						0x2 :
+						((gstride_type == STRIDE_512B) ?
+						 0xA : 0x9);
+					break;
+				/* 1536MB + 1536MB */
+				case 3072:
+					stride = (gstride_type == UN_STRIDE) ?
+						0x3 :
+						((gstride_type == STRIDE_512B) ?
+						 0x12 : 0x11);
+					break;
+				/* 4GB  unstride or 128B,256B,512B,4KB stride */
+				case 4096:
+					stride = (gstride_type == UN_STRIDE) ?
+						0x3 : (0xC + gstride_type);
+					break;
+				}
+			}
+		}
+		if (ch_cap[0] == 2048 && ch_cap[1] == 1024) {
+			/* 2GB + 1GB */
+			stride = (gstride_type == UN_STRIDE) ? 0x3 : 0x19;
+		}
 		/*
-		 * 768MB + 768MB same as total 2GB memory
-		 * useful space: 0-768MB 1GB-1792MB
+		 * remain two channel capability not equal OR capability
+		 * power function of 2
 		 */
-		case 1536:
-		/* 2GB */
-		case 2048:
-			stride = 0x9;
-			break;
-		/* 1536MB + 1536MB */
-		case 3072:
-			stride = 0x11;
-			break;
-		/* 4GB */
-		case 4096:
-			stride = 0xD;
-			break;
-		default:
-			printf("%s: Unable to calculate stride for ", __func__);
-			print_size((cap * (1 << 20)), " capacity\n");
-			break;
+		if (stride == (-1)) {
+			switch ((ch_cap[0] > ch_cap[1]) ?
+				ch_cap[0] : ch_cap[1]) {
+			case 256: /* 256MB + 128MB */
+				stride = 0;
+				break;
+			case 512: /* 512MB + 256MB */
+				stride = 1;
+				break;
+			case 1024:/* 1GB + 128MB/256MB/384MB/512MB/768MB */
+				stride = 2;
+				break;
+			case 2048: /* 2GB + 128MB/256MB/384MB/512MB/768MB/1GB */
+				stride = 3;
+				break;
+			default:
+				break;
+			}
 		}
+		if (stride == (-1))
+			goto error;
+	}
+	switch (stride) {
+	case 0xc:
+		printf("128B stride\n");
+		break;
+	case 5:
+	case 9:
+	case 0xd:
+	case 0x11:
+	case 0x19:
+		printf("256B stride\n");
+		break;
+	case 0xa:
+	case 0xe:
+	case 0x12:
+		printf("512B stride\n");
+		break;
+	case 0xf:
+		printf("4K stride\n");
+		break;
+	case 0x1f:
+		printf("32MB + 256B stride\n");
+		break;
+	default:
+		printf("no stride\n");
 	}
 
 	sdram_print_stride(stride);
 
 	return stride;
+error:
+	printf("Cap not support!\n");
+	return (-1);
 }
 
 static void clear_channel_params(struct rk3399_sdram_params *params, u8 channel)
@@ -2491,39 +2921,13 @@
 	params->ch[channel].cap_info.ddrconfig = 0;
 }
 
-static int pctl_init(struct dram_info *dram, struct rk3399_sdram_params *params)
-{
-	int channel;
-	int ret;
-
-	for (channel = 0; channel < 2; channel++) {
-		const struct chan_info *chan = &dram->chan[channel];
-		struct rk3399_cru *cru = dram->cru;
-		struct rk3399_ddr_publ_regs *publ = chan->publ;
-
-		phy_pctrl_reset(cru, channel);
-		phy_dll_bypass_set(publ, params->base.ddr_freq);
-
-		ret = pctl_cfg(dram, chan, channel, params);
-		if (ret < 0) {
-			printf("%s: pctl config failed\n", __func__);
-			return ret;
-		}
-
-		/* start to trigger initialization */
-		pctl_start(dram, channel);
-	}
-
-	return 0;
-}
-
 static int sdram_init(struct dram_info *dram,
 		      struct rk3399_sdram_params *params)
 {
 	unsigned char dramtype = params->base.dramtype;
 	unsigned int ddr_freq = params->base.ddr_freq;
 	int channel, ch, rank;
-	int ret;
+	u32 tmp, ret;
 
 	debug("Starting SDRAM initialization...\n");
 
@@ -2534,22 +2938,35 @@
 		return -E2BIG;
 	}
 
+	/* detect rank */
 	for (ch = 0; ch < 2; ch++) {
 		params->ch[ch].cap_info.rank = 2;
 		for (rank = 2; rank != 0; rank--) {
-			ret = pctl_init(dram, params);
-			if (ret < 0) {
-				printf("%s: pctl init failed\n", __func__);
-				return ret;
+			for (channel = 0; channel < 2; channel++) {
+				const struct chan_info *chan =
+					&dram->chan[channel];
+				struct rk3399_cru *cru = dram->cru;
+				struct rk3399_ddr_publ_regs *publ = chan->publ;
+
+				phy_pctrl_reset(cru, channel);
+				phy_dll_bypass_set(publ, ddr_freq);
+				pctl_cfg(dram, chan, channel, params);
 			}
 
+			/* start to trigger initialization */
+			pctl_start(dram, params, 3);
+
 			/* LPDDR2/LPDDR3 need to wait DAI complete, max 10us */
 			if (dramtype == LPDDR3)
 				udelay(10);
 
+			tmp = (rank == 2) ? 3 : 1;
+			dram_set_cs(&dram->chan[ch], tmp, 2048,
+				    params->base.dramtype);
 			params->ch[ch].cap_info.rank = rank;
 
-			ret = dram->ops->data_training(dram, ch, rank, params);
+			ret = dram->ops->data_training_first(dram, ch,
+							     rank, params);
 			if (!ret) {
 				debug("%s: data trained for rank %d, ch %d\n",
 				      __func__, rank, ch);
@@ -2563,38 +2980,37 @@
 	params->base.num_channels = 0;
 	for (channel = 0; channel < 2; channel++) {
 		const struct chan_info *chan = &dram->chan[channel];
-		struct sdram_cap_info *cap_info = &params->ch[channel].cap_info;
-		u8 training_flag = PI_FULL_TRAINING;
+		struct sdram_cap_info *cap_info =
+			&params->ch[channel].cap_info;
 
 		if (cap_info->rank == 0) {
-			clear_channel_params(params, channel);
+			clear_channel_params(params, 1);
 			continue;
 		} else {
 			params->base.num_channels++;
 		}
 
-		debug("Channel ");
-		debug(channel ? "1: " : "0: ");
+		printf("Channel ");
+		printf(channel ? "1: " : "0: ");
 
-		/* LPDDR3 should have write and read gate training */
-		if (params->base.dramtype == LPDDR3)
-			training_flag = PI_WRITE_LEVELING |
-					PI_READ_GATE_TRAINING;
+		if (channel == 0)
+			set_ddr_stride(dram->pmusgrf, 0x17);
+		else
+			set_ddr_stride(dram->pmusgrf, 0x18);
 
-		if (params->base.dramtype != LPDDR4) {
-			ret = data_training(dram, channel, params,
-					    training_flag);
-			if (!ret) {
-				debug("%s: data train failed for channel %d\n",
-				      __func__, ret);
-				continue;
-			}
+		if (dram_detect_cap(dram, params, channel)) {
+			printf("Cap error!\n");
+			continue;
 		}
 
 		sdram_print_ddr_info(cap_info, &params->base);
 		set_memory_map(chan, channel, params);
-		cap_info->ddrconfig = calculate_ddrconfig(params, channel);
-
+		cap_info->ddrconfig =
+			calculate_ddrconfig(params, channel);
+		if (-1 == cap_info->ddrconfig) {
+			printf("no ddrconfig find, Cap not support!\n");
+			continue;
+		}
 		set_ddrconfig(chan, params, channel, cap_info->ddrconfig);
 		set_cap_relate_config(chan, params, channel);
 	}
@@ -2608,7 +3024,8 @@
 
 	params->base.stride = calculate_stride(params);
 	dram_all_config(dram, params);
-	dram->ops->set_rate(dram, params);
+
+	dram->ops->set_rate_index(dram, params);
 
 	debug("Finish SDRAM initialization...\n");
 	return 0;
@@ -2655,11 +3072,15 @@
 
 static const struct sdram_rk3399_ops rk3399_ops = {
 #if !defined(CONFIG_RAM_RK3399_LPDDR4)
-	.data_training = default_data_training,
-	.set_rate = switch_to_phy_index1,
+	.data_training_first = data_training_first,
+	.set_rate_index = switch_to_phy_index1,
+	.modify_param = modify_param,
+	.get_phy_index_params = get_phy_index_params,
 #else
-	.data_training = lpddr4_mr_detect,
-	.set_rate = lpddr4_set_rate,
+	.data_training_first = lpddr4_mr_detect,
+	.set_rate_index = lpddr4_set_rate,
+	.modify_param = lpddr4_modify_param,
+	.get_phy_index_params = lpddr4_get_phy_index_params,
 #endif
 };
 
diff --git a/drivers/usb/phy/rockchip_usb2_phy.c b/drivers/usb/phy/rockchip_usb2_phy.c
index 16e8999..69e408b 100644
--- a/drivers/usb/phy/rockchip_usb2_phy.c
+++ b/drivers/usb/phy/rockchip_usb2_phy.c
@@ -5,7 +5,6 @@
 
 #include <common.h>
 #include <asm/io.h>
-#include <linux/libfdt.h>
 
 #include "../gadget/dwc2_udc_otg_priv.h"
 
@@ -71,8 +70,8 @@
 
 	for (i = 0; i < ARRAY_SIZE(rockchip_usb2_phy_dt_ids); i++) {
 		of_id = &rockchip_usb2_phy_dt_ids[i];
-		if (fdt_node_check_compatible(gd->fdt_blob, pdata->phy_of_node,
-					      of_id->compatible) == 0) {
+		if (ofnode_device_is_compatible(pdata->phy_of_node,
+						of_id->compatible)){
 			phy_cfg = (struct rockchip_usb2_phy_cfg *)of_id->data;
 			break;
 		}
diff --git a/env/Kconfig b/env/Kconfig
index bc03816..090cc79 100644
--- a/env/Kconfig
+++ b/env/Kconfig
@@ -393,6 +393,16 @@
 	  the environment in.  This will enable redundant environments in UBI.
 	  It is assumed that both volumes are in the same MTD partition.
 
+config SYS_REDUNDAND_ENVIRONMENT
+	bool "Enable redundant environment support"
+	depends on ENV_IS_IN_EEPROM || ENV_IS_IN_FLASH || ENV_IS_IN_MMC || \
+		ENV_IS_IN_NAND || ENV_IS_IN_SPI_FLASH || ENV_IS_IN_UBI
+	help
+	  Normally, the environemt is stored in a single location.  By
+	  selecting this option, you can then define where to hold a redundant
+	  copy of the environment data, so that there is a valid backup copy in
+	  case there is a power failure during a "saveenv" operation.
+
 config ENV_FAT_INTERFACE
 	string "Name of the block device for the environment"
 	depends on ENV_IS_IN_FAT
@@ -512,16 +522,10 @@
 
 config ENV_UBI_VOLUME_REDUND
 	string "UBI redundant volume name"
-	depends on ENV_IS_IN_UBI
+	depends on ENV_IS_IN_UBI && SYS_REDUNDAND_ENVIRONMENT
 	help
 	  Name of the redundant volume that you want to store the environment in.
 
-config ENV_UBI_IS_VOLUME_REDUND
-	bool
-	depends on ENV_IS_IN_UBI
-	default y if ENV_UBI_VOLUME_REDUND != ""
-	default n
-
 config ENV_UBI_VID_OFFSET
 	int "ubi environment VID offset"
 	depends on ENV_IS_IN_UBI
diff --git a/include/configs/UCP1020.h b/include/configs/UCP1020.h
index 6a01a90..40080f5 100644
--- a/include/configs/UCP1020.h
+++ b/include/configs/UCP1020.h
@@ -120,8 +120,6 @@
 #define CONFIG_NETMASK		255.255.255.0
 #define CONFIG_ETHPRIME		"eTSEC1"
 
-#undef CONFIG_SYS_REDUNDAND_ENVIRONMENT
-
 #define CONFIG_SYS_L2_SIZE	(256 << 10)
 
 #endif
diff --git a/include/configs/am335x_evm.h b/include/configs/am335x_evm.h
index be57106..15cda80 100644
--- a/include/configs/am335x_evm.h
+++ b/include/configs/am335x_evm.h
@@ -275,7 +275,6 @@
 #if defined(CONFIG_SPI_BOOT)
 /* SPL related */
 
-#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
 #define CONFIG_ENV_SECT_SIZE		(4 << 10) /* 4 KB sectors */
 #define CONFIG_ENV_OFFSET		(768 << 10) /* 768 KiB in */
 #define CONFIG_ENV_OFFSET_REDUND	(896 << 10) /* 896 KiB in */
@@ -284,7 +283,6 @@
 #define CONFIG_SYS_MMC_ENV_PART		0
 #define CONFIG_ENV_OFFSET		0x260000
 #define CONFIG_ENV_OFFSET_REDUND	(CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE)
-#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
 #define CONFIG_SYS_MMC_MAX_DEVICE	2
 #elif defined(CONFIG_NOR_BOOT)
 #define CONFIG_ENV_SECT_SIZE		(128 << 10)	/* 128 KiB */
diff --git a/include/configs/am335x_sl50.h b/include/configs/am335x_sl50.h
index a08e6bf..7bb2bff 100644
--- a/include/configs/am335x_sl50.h
+++ b/include/configs/am335x_sl50.h
@@ -80,7 +80,6 @@
 #define CONFIG_SYS_MMC_ENV_PART		2
 #define CONFIG_ENV_OFFSET		0x0
 #define CONFIG_ENV_OFFSET_REDUND	(CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE)
-#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
 #endif
 
 /* Network. */
diff --git a/include/configs/am43xx_evm.h b/include/configs/am43xx_evm.h
index d355b80..9db0068 100644
--- a/include/configs/am43xx_evm.h
+++ b/include/configs/am43xx_evm.h
@@ -109,7 +109,6 @@
 #endif
 
 #ifdef CONFIG_QSPI_BOOT
-#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
 #define CONFIG_ENV_OFFSET_REDUND       0x120000
 #endif
 
diff --git a/include/configs/am57xx_evm.h b/include/configs/am57xx_evm.h
index 531f79e..baeca54 100644
--- a/include/configs/am57xx_evm.h
+++ b/include/configs/am57xx_evm.h
@@ -20,7 +20,6 @@
 #define CONFIG_SYS_MMC_ENV_DEV		1		/* eMMC */
 #define CONFIG_SYS_MMC_ENV_PART		0
 #define CONFIG_ENV_OFFSET_REDUND	(CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE)
-#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
 
 #define CONFIG_SYS_BOOTM_LEN		SZ_64M
 
diff --git a/include/configs/am65x_evm.h b/include/configs/am65x_evm.h
index 1149d55..9c06f10 100644
--- a/include/configs/am65x_evm.h
+++ b/include/configs/am65x_evm.h
@@ -121,7 +121,6 @@
 #define CONFIG_ENV_SIZE		(128 << 10)
 #define CONFIG_ENV_OFFSET		0x680000
 #define CONFIG_ENV_OFFSET_REDUND	(CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE)
-#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
 #endif
 
 #define CONFIG_SUPPORT_EMMC_BOOT
diff --git a/include/configs/aristainetos-common.h b/include/configs/aristainetos-common.h
index b451c7e..041abb5 100644
--- a/include/configs/aristainetos-common.h
+++ b/include/configs/aristainetos-common.h
@@ -147,7 +147,6 @@
 
 /* Environment organization */
 #define CONFIG_ENV_SIZE			(12 * 1024)
-#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
 #define CONFIG_ENV_SECT_SIZE		(0x010000)
 #define CONFIG_ENV_OFFSET		(0x0d0000)
 #define CONFIG_ENV_OFFSET_REDUND	(0x0e0000)
diff --git a/include/configs/bav335x.h b/include/configs/bav335x.h
index db21a47..4ecf8de 100644
--- a/include/configs/bav335x.h
+++ b/include/configs/bav335x.h
@@ -444,7 +444,6 @@
 #if defined(CONFIG_SPI_BOOT)
 /* SPL related */
 
-#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
 #define CONFIG_ENV_SECT_SIZE		(4 << 10) /* 4 KB sectors */
 #define CONFIG_ENV_OFFSET		(768 << 10) /* 768 KiB in */
 #define CONFIG_ENV_OFFSET_REDUND	(896 << 10) /* 896 KiB in */
@@ -453,7 +452,6 @@
 #define CONFIG_SYS_MMC_ENV_PART		2
 #define CONFIG_ENV_OFFSET		0x0
 #define CONFIG_ENV_OFFSET_REDUND	(CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE)
-#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
 #endif
 
 /* SPI flash. */
diff --git a/include/configs/bcmstb.h b/include/configs/bcmstb.h
index b843705..2feabdd 100644
--- a/include/configs/bcmstb.h
+++ b/include/configs/bcmstb.h
@@ -149,7 +149,6 @@
 /*
  * Environment configuration.
  */
-#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
 #define CONFIG_ENV_SIZE			(64 << 10) /* 64 KiB */
 #define CONFIG_ENV_OFFSET_REDUND	(CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE)
 #define CONFIG_ENV_OVERWRITE
diff --git a/include/configs/brppt1.h b/include/configs/brppt1.h
index bc0dabb..c9c28be 100644
--- a/include/configs/brppt1.h
+++ b/include/configs/brppt1.h
@@ -182,7 +182,6 @@
 #if defined(CONFIG_SPI)
 /* SPI Flash */
 /* Environment */
-#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
 #define CONFIG_ENV_OFFSET_REDUND		(CONFIG_ENV_OFFSET + \
 						 CONFIG_ENV_SECT_SIZE)
 #elif defined(CONFIG_ENV_IS_IN_MMC)
@@ -190,7 +189,6 @@
 #define CONFIG_SYS_MMC_ENV_PART		2
 #define CONFIG_ENV_OFFSET		0x40000	/* TODO: Adresse definieren */
 #define CONFIG_ENV_OFFSET_REDUND	(CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE)
-#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
 
 #elif defined(CONFIG_ENV_IS_IN_NAND)
 /* No NAND env support in SPL */
diff --git a/include/configs/brsmarc1.h b/include/configs/brsmarc1.h
index 19e796e..47d7a87 100644
--- a/include/configs/brsmarc1.h
+++ b/include/configs/brsmarc1.h
@@ -69,7 +69,6 @@
 /* SPI Flash */
 
 /* Environment */
-#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
 #define CONFIG_ENV_OFFSET_REDUND		(CONFIG_ENV_OFFSET + \
 						 CONFIG_ENV_SECT_SIZE)
 
diff --git a/include/configs/brxre1.h b/include/configs/brxre1.h
index c6e308b..30bd8cb 100644
--- a/include/configs/brxre1.h
+++ b/include/configs/brxre1.h
@@ -69,6 +69,5 @@
 #define CONFIG_ENV_SIZE			0x10000
 #define CONFIG_ENV_OFFSET		0x40000	/* TODO: Adresse definieren */
 #define CONFIG_ENV_OFFSET_REDUND	(CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE)
-#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
 
 #endif	/* __CONFIG_BRXRE1_H__ */
diff --git a/include/configs/chiliboard.h b/include/configs/chiliboard.h
index 13c15bd..8141aec 100644
--- a/include/configs/chiliboard.h
+++ b/include/configs/chiliboard.h
@@ -166,7 +166,6 @@
 #else
 #define CONFIG_SYS_MMC_ENV_DEV		0
 #define CONFIG_ENV_OFFSET_REDUND	(CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE)
-#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
 #endif
 
 /* Network. */
diff --git a/include/configs/cm_t54.h b/include/configs/cm_t54.h
index 2387f86..7368fd8 100644
--- a/include/configs/cm_t54.h
+++ b/include/configs/cm_t54.h
@@ -37,7 +37,6 @@
 #define CONFIG_ENV_OFFSET		0xc0000		/* (in bytes) 768 KB */
 #define CONFIG_ENV_SIZE			(16 << 10)	/* 16 KB */
 #define CONFIG_ENV_OFFSET_REDUND	(CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE)
-#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
 
 /* Enhance our eMMC support / experience. */
 #define CONFIG_HSMMC2_8BIT
diff --git a/include/configs/dart_6ul.h b/include/configs/dart_6ul.h
index 4f99805..801011c 100644
--- a/include/configs/dart_6ul.h
+++ b/include/configs/dart_6ul.h
@@ -41,7 +41,6 @@
 /* Environment settings */
 #define CONFIG_ENV_SIZE			SZ_8K
 #define CONFIG_ENV_OFFSET		(14 * SZ_64K)
-#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
 #define CONFIG_ENV_OFFSET_REDUND	\
 	(CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE)
 
diff --git a/include/configs/dh_imx6.h b/include/configs/dh_imx6.h
index 86c1192..d4bd88f 100644
--- a/include/configs/dh_imx6.h
+++ b/include/configs/dh_imx6.h
@@ -138,7 +138,6 @@
 
 /* Environment */
 #define CONFIG_ENV_SIZE			(16 * 1024)
-#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
 
 #if defined(CONFIG_ENV_IS_IN_SPI_FLASH)
 #define CONFIG_ENV_OFFSET		(1024 * 1024)
diff --git a/include/configs/display5.h b/include/configs/display5.h
index 65dae1f..7b17148 100644
--- a/include/configs/display5.h
+++ b/include/configs/display5.h
@@ -352,7 +352,6 @@
 /* The 0x120000 value corresponds to above SPI-NOR memory MAP */
 #define CONFIG_ENV_OFFSET		(0x120000)
 #define CONFIG_ENV_SECT_SIZE		(SZ_64K)
-#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
 #define CONFIG_ENV_OFFSET_REDUND	(CONFIG_ENV_OFFSET + \
 						CONFIG_ENV_SECT_SIZE)
 #define CONFIG_ENV_SIZE_REDUND		CONFIG_ENV_SIZE
diff --git a/include/configs/dra7xx_evm.h b/include/configs/dra7xx_evm.h
index 3487b8a..0ad23ce 100644
--- a/include/configs/dra7xx_evm.h
+++ b/include/configs/dra7xx_evm.h
@@ -22,7 +22,6 @@
 /* MMC ENV related defines */
 #define CONFIG_SYS_MMC_ENV_DEV		1	/* SLOT2: eMMC(1) */
 #define CONFIG_ENV_OFFSET_REDUND	(CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE)
-#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
 #endif
 
 #if (CONFIG_CONS_INDEX == 1)
@@ -84,7 +83,6 @@
 #define CONFIG_SYS_SPI_ARGS_OFFS	0x140000
 #define CONFIG_SYS_SPI_ARGS_SIZE	0x80000
 #if defined(CONFIG_QSPI_BOOT)
-#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
 #define CONFIG_ENV_SIZE			(64 << 10)
 #define CONFIG_ENV_SECT_SIZE		(64 << 10) /* 64 KB sectors */
 #define CONFIG_ENV_OFFSET		0x1C0000
diff --git a/include/configs/evb_px30.h b/include/configs/evb_px30.h
new file mode 100644
index 0000000..e761c7c
--- /dev/null
+++ b/include/configs/evb_px30.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2017 Rockchip Electronics Co., Ltd
+ */
+
+#ifndef __EVB_PX30_H
+#define __EVB_PX30_H
+
+#include <configs/px30_common.h>
+
+#define CONFIG_SYS_MMC_ENV_DEV 0
+
+#define ROCKCHIP_DEVICE_SETTINGS \
+		"stdout=serial,vidconsole\0" \
+		"stderr=serial,vidconsole\0"
+
+#define CONFIG_SUPPORT_EMMC_RPMB
+
+#endif
diff --git a/include/configs/evb_rk3128.h b/include/configs/evb_rk3128.h
index 73ceab0..bf6c7ea 100644
--- a/include/configs/evb_rk3128.h
+++ b/include/configs/evb_rk3128.h
@@ -8,7 +8,6 @@
 
 #include <configs/rk3128_common.h>
 
-#define CONFIG_ENV_IS_IN_MMC
 #define CONFIG_SYS_MMC_ENV_DEV 0
 
 #endif
diff --git a/include/configs/evb_rk3308.h b/include/configs/evb_rk3308.h
new file mode 100644
index 0000000..4d40606
--- /dev/null
+++ b/include/configs/evb_rk3308.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * (C) Copyright 2018 Rockchip Electronics Co., Ltd
+ */
+
+#ifndef __EVB_RK3308_H
+#define __EVB_RK3308_H
+
+#include <configs/rk3308_common.h>
+
+#define CONFIG_SUPPORT_EMMC_RPMB
+#define CONFIG_SYS_MMC_ENV_DEV 0
+
+#define ROCKCHIP_DEVICE_SETTINGS \
+			"stdout=serial,vidconsole\0" \
+			"stderr=serial,vidconsole\0"
+#undef CONFIG_CONSOLE_SCROLL_LINES
+#define CONFIG_CONSOLE_SCROLL_LINES            10
+
+#endif
diff --git a/include/configs/firefly_rk3308.h b/include/configs/firefly_rk3308.h
new file mode 100644
index 0000000..2cc7b4a
--- /dev/null
+++ b/include/configs/firefly_rk3308.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2019 Rockchip Electronics Co., Ltd
+ */
+
+#ifndef __FIREFLY_RK3308_H
+#define __FIREFLY_RK3308_H
+
+#include <configs/rk3308_common.h>
+
+#define CONFIG_SUPPORT_EMMC_RPMB
+#define CONFIG_SYS_MMC_ENV_DEV 0
+
+#define ROCKCHIP_DEVICE_SETTINGS \
+			"stdout=serial,vidconsole\0" \
+			"stderr=serial,vidconsole\0"
+#undef CONFIG_CONSOLE_SCROLL_LINES
+#define CONFIG_CONSOLE_SCROLL_LINES            10
+
+#endif
diff --git a/include/configs/gardena-smart-gateway-mt7688.h b/include/configs/gardena-smart-gateway-mt7688.h
index e83a96a..94c5b8d 100644
--- a/include/configs/gardena-smart-gateway-mt7688.h
+++ b/include/configs/gardena-smart-gateway-mt7688.h
@@ -41,7 +41,6 @@
 #define CONFIG_ENV_OFFSET		0xa0000
 #define CONFIG_ENV_SIZE			(64 << 10)
 #define CONFIG_ENV_SECT_SIZE		(64 << 10)
-#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
 #define CONFIG_ENV_OFFSET_REDUND	(CONFIG_ENV_OFFSET + \
 						CONFIG_ENV_SECT_SIZE)
 #define CONFIG_ENV_SIZE_REDUND		CONFIG_ENV_SIZE
diff --git a/include/configs/imx8mm_evk.h b/include/configs/imx8mm_evk.h
index a9d99ec..e0c5f5a 100644
--- a/include/configs/imx8mm_evk.h
+++ b/include/configs/imx8mm_evk.h
@@ -150,4 +150,12 @@
 
 #define CONFIG_SYS_I2C_SPEED		100000
 
+#define CONFIG_ETHPRIME                 "FEC"
+
+#define CONFIG_FEC_XCV_TYPE             RGMII
+#define CONFIG_FEC_MXC_PHYADDR          0
+#define FEC_QUIRK_ENET_MAC
+
+#define IMX_FEC_BASE			0x30BE0000
+
 #endif
diff --git a/include/configs/imx8mn_evk.h b/include/configs/imx8mn_evk.h
new file mode 100644
index 0000000..8d4a88b
--- /dev/null
+++ b/include/configs/imx8mn_evk.h
@@ -0,0 +1,156 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2018 NXP
+ */
+
+#ifndef __IMX8MN_EVK_H
+#define __IMX8MN_EVK_H
+
+#include <linux/sizes.h>
+#include <asm/arch/imx-regs.h>
+
+#ifdef CONFIG_SECURE_BOOT
+#define CONFIG_CSF_SIZE			SZ_8K
+#endif
+
+#define CONFIG_SPL_MAX_SIZE		(148 * 1024)
+#define CONFIG_SYS_MONITOR_LEN		SZ_512K
+#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR
+#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR	0x300
+#define CONFIG_SYS_MMCSD_FS_BOOT_PARTITION	1
+#define CONFIG_SYS_UBOOT_BASE	\
+	(QSPI0_AMBA_BASE + CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR * 512)
+
+#ifdef CONFIG_SPL_BUILD
+#define CONFIG_SPL_STACK		0x95fff0
+#define CONFIG_SPL_BSS_START_ADDR	0x00950000
+#define CONFIG_SPL_BSS_MAX_SIZE		SZ_8K	/* 8 KB */
+#define CONFIG_SYS_SPL_MALLOC_START	0x42200000
+#define CONFIG_SYS_SPL_MALLOC_SIZE	SZ_512K	/* 512 KB */
+#define CONFIG_SYS_ICACHE_OFF
+#define CONFIG_SYS_DCACHE_OFF
+
+/* malloc f used before GD_FLG_FULL_MALLOC_INIT set */
+#define CONFIG_MALLOC_F_ADDR		0x00940000
+
+/* For RAW image gives a error info not panic */
+#define CONFIG_SPL_ABORT_ON_RAW_IMAGE
+
+#endif
+
+/* Initial environment variables */
+#define CONFIG_EXTRA_ENV_SETTINGS		\
+	"script=boot.scr\0" \
+	"image=Image.itb\0" \
+	"console=ttymxc1,115200 earlycon=ec_imx6q,0x30890000,115200\0" \
+	"fdt_addr=0x43000000\0"			\
+	"fdt_high=0xffffffffffffffff\0"		\
+	"boot_fit=try\0" \
+	"fdt_file=" CONFIG_DEFAULT_FDT_FILE "\0" \
+	"initrd_addr=0x43800000\0"		\
+	"initrd_high=0xffffffffffffffff\0" \
+	"mmcdev="__stringify(CONFIG_SYS_MMC_ENV_DEV)"\0" \
+	"mmcpart=" __stringify(CONFIG_SYS_MMC_IMG_LOAD_PART) "\0" \
+	"mmcroot=" CONFIG_MMCROOT " rootwait rw\0" \
+	"mmcautodetect=yes\0" \
+	"mmcargs=setenv bootargs console=${console} root=${mmcroot}\0 " \
+	"loadbootscript=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};\0" \
+	"bootscript=echo Running bootscript from mmc ...; " \
+		"source\0" \
+	"loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}\0" \
+	"loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}\0" \
+	"mmcboot=echo Booting from mmc ...; " \
+		"run mmcargs; " \
+		"if test ${boot_fit} = yes || test ${boot_fit} = try; then " \
+			"bootm ${loadaddr}; " \
+		"else " \
+			"if run loadfdt; then " \
+				"booti ${loadaddr} - ${fdt_addr}; " \
+			"else " \
+				"echo WARN: Cannot load the DT; " \
+			"fi; " \
+		"fi;\0" \
+	"netargs=setenv bootargs console=${console} " \
+		"root=/dev/nfs " \
+		"ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp\0" \
+	"netboot=echo Booting from net ...; " \
+		"run netargs;  " \
+		"if test ${ip_dyn} = yes; then " \
+			"setenv get_cmd dhcp; " \
+		"else " \
+			"setenv get_cmd tftp; " \
+		"fi; " \
+		"${get_cmd} ${loadaddr} ${image}; " \
+		"if test ${boot_fit} = yes || test ${boot_fit} = try; then " \
+			"bootm ${loadaddr}; " \
+		"else " \
+			"if ${get_cmd} ${fdt_addr} ${fdt_file}; then " \
+				"booti ${loadaddr} - ${fdt_addr}; " \
+			"else " \
+				"echo WARN: Cannot load the DT; " \
+			"fi; " \
+		"fi;\0"
+
+#define CONFIG_BOOTCOMMAND \
+	   "mmc dev ${mmcdev}; if mmc rescan; then " \
+		   "if run loadbootscript; then " \
+			   "run bootscript; " \
+		   "else " \
+			   "if run loadimage; then " \
+				   "run mmcboot; " \
+			   "else run netboot; " \
+			   "fi; " \
+		   "fi; " \
+	   "fi;"
+
+/* Link Definitions */
+#define CONFIG_LOADADDR			0x40480000
+
+#define CONFIG_SYS_LOAD_ADDR           CONFIG_LOADADDR
+
+#define CONFIG_SYS_INIT_RAM_ADDR        0x40000000
+#define CONFIG_SYS_INIT_RAM_SIZE        0x200000
+#define CONFIG_SYS_INIT_SP_OFFSET \
+	(CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE)
+#define CONFIG_SYS_INIT_SP_ADDR \
+	(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET)
+
+#define CONFIG_ENV_OVERWRITE
+#if defined(CONFIG_ENV_IS_IN_MMC)
+#define CONFIG_ENV_OFFSET               (64 * SZ_64K)
+#endif
+#define CONFIG_ENV_SIZE			SZ_4K
+#define CONFIG_SYS_MMC_ENV_DEV		0   /* USDHC2 */
+#define CONFIG_MMCROOT			"/dev/mmcblk1p2"  /* USDHC2 */
+
+/* Size of malloc() pool */
+#define CONFIG_SYS_MALLOC_LEN		SZ_32M
+
+#define CONFIG_SYS_SDRAM_BASE           0x40000000
+#define PHYS_SDRAM                      0x40000000
+#define PHYS_SDRAM_SIZE			0x80000000 /* 2GB DDR */
+
+#define CONFIG_SYS_MEMTEST_START    PHYS_SDRAM
+#define CONFIG_SYS_MEMTEST_END      (CONFIG_SYS_MEMTEST_START + (PHYS_SDRAM_SIZE >> 1))
+
+#define CONFIG_MXC_UART_BASE		UART2_BASE_ADDR
+
+/* Monitor Command Prompt */
+#define CONFIG_SYS_PROMPT_HUSH_PS2	"> "
+#define CONFIG_SYS_CBSIZE		2048
+#define CONFIG_SYS_MAXARGS		64
+#define CONFIG_SYS_BARGSIZE		CONFIG_SYS_CBSIZE
+#define CONFIG_SYS_PBSIZE		(CONFIG_SYS_CBSIZE + \
+					sizeof(CONFIG_SYS_PROMPT) + 16)
+
+/* USDHC */
+#define CONFIG_FSL_USDHC
+
+#define CONFIG_SYS_FSL_USDHC_NUM	2
+#define CONFIG_SYS_FSL_ESDHC_ADDR	0
+
+#define CONFIG_SYS_MMC_IMG_LOAD_PART	1
+
+#define CONFIG_SYS_I2C_SPEED		100000
+
+#endif
diff --git a/include/configs/km/km_arm.h b/include/configs/km/km_arm.h
index 829a5c7..64c968b 100644
--- a/include/configs/km/km_arm.h
+++ b/include/configs/km/km_arm.h
@@ -158,8 +158,6 @@
 #define CONFIG_ENV_SIZE_REDUND		(CONFIG_ENV_SIZE)
 #endif
 
-#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
-
 #define KM_FLASH_GPIO_PIN	16
 
 #define	CONFIG_KM_UPDATE_UBOOT						\
diff --git a/include/configs/kmp204x.h b/include/configs/kmp204x.h
index 75480a8..f83b98c 100644
--- a/include/configs/kmp204x.h
+++ b/include/configs/kmp204x.h
@@ -56,8 +56,6 @@
 #define CONFIG_ENV_OFFSET_REDUND	0x110000
 #define CONFIG_ENV_TOTAL_SIZE		0x020000
 
-#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
-
 #ifndef __ASSEMBLY__
 unsigned long get_board_sys_clk(unsigned long dummy);
 #endif
diff --git a/include/configs/kp_imx53.h b/include/configs/kp_imx53.h
index 55bfa0f..ff564b2 100644
--- a/include/configs/kp_imx53.h
+++ b/include/configs/kp_imx53.h
@@ -99,7 +99,6 @@
 /* environment organization */
 #define CONFIG_ENV_OFFSET      (SZ_1M)
 #define CONFIG_ENV_SIZE        (SZ_8K)
-#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
 #define CONFIG_ENV_SIZE_REDUND CONFIG_ENV_SIZE
 #define CONFIG_ENV_OFFSET_REDUND        (CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE)
 #define CONFIG_SYS_MMC_ENV_DEV 0
diff --git a/include/configs/kp_imx6q_tpc.h b/include/configs/kp_imx6q_tpc.h
index f6746a9..fc3896e 100644
--- a/include/configs/kp_imx6q_tpc.h
+++ b/include/configs/kp_imx6q_tpc.h
@@ -129,6 +129,5 @@
 #define CONFIG_ENV_SIZE	(SZ_8K)
 #define CONFIG_ENV_OFFSET       0x100000
 #define CONFIG_ENV_OFFSET_REDUND (CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE)
-#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
 
 #endif	/* __KP_IMX6Q_TPC_IMX6_CONFIG_H_ */
diff --git a/include/configs/mccmon6.h b/include/configs/mccmon6.h
index c685de6..c75519c 100644
--- a/include/configs/mccmon6.h
+++ b/include/configs/mccmon6.h
@@ -251,7 +251,6 @@
 #define CONFIG_ENV_SECT_SIZE    (SZ_128K)
 #define CONFIG_ENV_ADDR	(CONFIG_SYS_FLASH_BASE + 0x40000)
 
-#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
 #define CONFIG_ENV_ADDR_REDUND	(CONFIG_SYS_FLASH_BASE + 0x60000)
 #define CONFIG_ENV_SIZE_REDUND	CONFIG_ENV_SIZE
 
diff --git a/include/configs/mx28evk.h b/include/configs/mx28evk.h
index dd04580..2fad2c7 100644
--- a/include/configs/mx28evk.h
+++ b/include/configs/mx28evk.h
@@ -44,7 +44,6 @@
 
 /* Environment is in SPI flash */
 #if defined(CONFIG_CMD_SF) && defined(CONFIG_ENV_IS_IN_SPI_FLASH)
-#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
 #define CONFIG_ENV_OFFSET		0x40000		/* 256K */
 #define CONFIG_ENV_OFFSET_REDUND	(CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE)
 #define CONFIG_ENV_SECT_SIZE		0x1000
diff --git a/include/configs/omap5_uevm.h b/include/configs/omap5_uevm.h
index 3710a71..ff81156 100644
--- a/include/configs/omap5_uevm.h
+++ b/include/configs/omap5_uevm.h
@@ -33,7 +33,6 @@
 /* MMC ENV related defines */
 #define CONFIG_SYS_MMC_ENV_DEV		1	/* SLOT2: eMMC(1) */
 #define CONFIG_ENV_OFFSET_REDUND	(CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE)
-#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
 
 /* Enhance our eMMC support / experience. */
 #define CONFIG_HSMMC2_8BIT
diff --git a/include/configs/pcl063_ull.h b/include/configs/pcl063_ull.h
index 650caaa..23e4912 100644
--- a/include/configs/pcl063_ull.h
+++ b/include/configs/pcl063_ull.h
@@ -23,7 +23,6 @@
 /* Environment settings */
 #define CONFIG_ENV_SIZE			(0x4000)
 #define CONFIG_ENV_OFFSET		(0x80000)
-#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
 #define CONFIG_ENV_OFFSET_REDUND	\
 	(CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE)
 
diff --git a/include/configs/pcm058.h b/include/configs/pcm058.h
index 855bc44..b9f5ad3 100644
--- a/include/configs/pcm058.h
+++ b/include/configs/pcm058.h
@@ -76,7 +76,6 @@
 #define CONFIG_ENV_SIZE                (16 * 1024)
 #define CONFIG_ENV_OFFSET		(1024 * SZ_1K)
 #define CONFIG_ENV_SECT_SIZE		(64 * SZ_1K)
-#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
 #define CONFIG_ENV_OFFSET_REDUND       (CONFIG_ENV_OFFSET + \
 						CONFIG_ENV_SECT_SIZE)
 #define CONFIG_ENV_SIZE_REDUND         CONFIG_ENV_SIZE
diff --git a/include/configs/pfla02.h b/include/configs/pfla02.h
index 8731d89..9a16935 100644
--- a/include/configs/pfla02.h
+++ b/include/configs/pfla02.h
@@ -74,11 +74,9 @@
 #define CONFIG_SYS_FSL_USDHC_NUM	2
 
 /* Environment organization */
-#define CONFIG_ENV_IS_IN_SPI_FLASH
 #define CONFIG_ENV_SIZE                (16 * 1024)
 #define CONFIG_ENV_OFFSET		(1024 * SZ_1K)
 #define CONFIG_ENV_SECT_SIZE		(64 * SZ_1K)
-#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
 #define CONFIG_ENV_OFFSET_REDUND       (CONFIG_ENV_OFFSET + \
 						CONFIG_ENV_SECT_SIZE)
 #define CONFIG_ENV_SIZE_REDUND         CONFIG_ENV_SIZE
diff --git a/include/configs/px30_common.h b/include/configs/px30_common.h
new file mode 100644
index 0000000..d6c7060
--- /dev/null
+++ b/include/configs/px30_common.h
@@ -0,0 +1,62 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2017 Rockchip Electronics Co., Ltd
+ */
+
+#ifndef __CONFIG_PX30_COMMON_H
+#define __CONFIG_PX30_COMMON_H
+
+#include "rockchip-common.h"
+
+#define CONFIG_SYS_CBSIZE		1024
+#define CONFIG_SKIP_LOWLEVEL_INIT
+
+#define CONFIG_SYS_NS16550_MEM32
+
+#define CONFIG_ROCKCHIP_STIMER_BASE	0xff220020
+#define COUNTER_FREQUENCY		24000000
+
+/* FIXME: ff020000 is pmu_mem (10k), while ff0e0000 is regular int_mem */
+#define CONFIG_IRAM_BASE		0xff020000
+
+#define CONFIG_SYS_INIT_SP_ADDR		0x00400000
+#define CONFIG_SYS_LOAD_ADDR		0x00800800
+#define CONFIG_SPL_STACK		0x00400000
+#define CONFIG_SPL_MAX_SIZE		0x20000
+#define CONFIG_SPL_BSS_START_ADDR	0x4000000
+#define CONFIG_SPL_BSS_MAX_SIZE		0x4000
+#define CONFIG_SYS_BOOTM_LEN		(64 << 20)	/* 64M */
+
+#define GICD_BASE			0xff131000
+#define GICC_BASE			0xff132000
+
+#define CONFIG_SYS_BOOTM_LEN	(64 << 20)	/* 64M */
+
+/* MMC/SD IP block */
+//#define CONFIG_BOUNCE_BUFFER
+
+#define CONFIG_SYS_SDRAM_BASE		0
+#define SDRAM_MAX_SIZE			0xff000000
+#define SDRAM_BANK_SIZE			(2UL << 30)
+
+#ifndef CONFIG_SPL_BUILD
+
+#define ENV_MEM_LAYOUT_SETTINGS \
+	"scriptaddr=0x00500000\0" \
+	"pxefile_addr_r=0x00600000\0" \
+	"fdt_addr_r=0x08300000\0" \
+	"kernel_addr_r=0x00280000\0" \
+	"kernel_addr_c=0x03e80000\0" \
+	"ramdisk_addr_r=0x0a200000\0"
+
+#include <config_distro_bootcmd.h>
+#define CONFIG_EXTRA_ENV_SETTINGS \
+	ENV_MEM_LAYOUT_SETTINGS \
+	"fdtfile=" CONFIG_DEFAULT_FDT_FILE "\0" \
+	"partitions=" PARTS_DEFAULT \
+	ROCKCHIP_DEVICE_SETTINGS \
+	BOOTENV
+
+#endif
+
+#endif
diff --git a/include/configs/rk3308_common.h b/include/configs/rk3308_common.h
new file mode 100644
index 0000000..a67d3d7
--- /dev/null
+++ b/include/configs/rk3308_common.h
@@ -0,0 +1,58 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2017 Rockchip Electronics Co., Ltd
+ */
+
+#ifndef __CONFIG_RK3308_COMMON_H
+#define __CONFIG_RK3308_COMMON_H
+
+#include "rockchip-common.h"
+
+#define CONFIG_SYS_CBSIZE		1024
+#define CONFIG_SKIP_LOWLEVEL_INIT
+#define CONFIG_SYS_MAX_NAND_DEVICE	1
+#define CONFIG_SYS_NAND_ONFI_DETECTION
+#define CONFIG_SYS_NAND_PAGE_SIZE	2048
+#define CONFIG_SYS_NAND_PAGE_COUNT	64
+#define CONFIG_SYS_NAND_SIZE		(256 * 1024 * 1024)
+#define CONFIG_SPL_MAX_SIZE		0x20000
+#define CONFIG_SPL_BSS_START_ADDR	0x00400000
+#define CONFIG_SPL_BSS_MAX_SIZE		0x2000
+#define CONFIG_SYS_SPI_U_BOOT_OFFS	0x8000
+
+#define CONFIG_SYS_NS16550_MEM32
+
+#define CONFIG_ROCKCHIP_STIMER_BASE	0xff1b00a0
+#define CONFIG_IRAM_BASE		0xfff80000
+#define CONFIG_SYS_INIT_SP_ADDR		0x00800000
+#define CONFIG_SYS_LOAD_ADDR		0x00C00800
+#define CONFIG_SPL_STACK		0x00400000
+#define CONFIG_SYS_BOOTM_LEN		(64 << 20)	/* 64M */
+
+#define COUNTER_FREQUENCY		24000000
+
+#define CONFIG_SYS_BOOTM_LEN	(64 << 20)	/* 64M */
+
+#define CONFIG_SYS_SDRAM_BASE		0
+#define SDRAM_MAX_SIZE			0xff000000
+#define SDRAM_BANK_SIZE			(2UL << 30)
+
+#ifndef CONFIG_SPL_BUILD
+
+#define ENV_MEM_LAYOUT_SETTINGS \
+	"scriptaddr=0x00500000\0" \
+	"pxefile_addr_r=0x00600000\0" \
+	"fdt_addr_r=0x01f00000\0" \
+	"kernel_addr_r=0x00680000\0" \
+	"ramdisk_addr_r=0x04000000\0"
+
+#include <config_distro_bootcmd.h>
+#define CONFIG_EXTRA_ENV_SETTINGS \
+	ENV_MEM_LAYOUT_SETTINGS \
+	"partitions=" PARTS_DEFAULT \
+	ROCKCHIP_DEVICE_SETTINGS \
+	BOOTENV
+
+#endif
+
+#endif
diff --git a/include/configs/rockpro64_rk3399.h b/include/configs/rockpro64_rk3399.h
new file mode 100644
index 0000000..5f52c1e
--- /dev/null
+++ b/include/configs/rockpro64_rk3399.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2019 Vasily Khoruzhick <anarsoul@gmail.com>
+ */
+
+#ifndef __ROCKPRO64_RK3399_H
+#define __ROCKPRO64_RK3399_H
+
+#include <configs/rk3399_common.h>
+
+#define CONFIG_SYS_MMC_ENV_DEV 0
+
+#define SDRAM_BANK_SIZE			(2UL << 30)
+
+#endif
diff --git a/include/configs/sksimx6.h b/include/configs/sksimx6.h
index 4f7ec2d..e1a7d72 100644
--- a/include/configs/sksimx6.h
+++ b/include/configs/sksimx6.h
@@ -56,7 +56,6 @@
 #define CONFIG_ENV_SIZE                (16 * 1024)
 #define CONFIG_ENV_OFFSET		(6 * 64 * 1024)
 #define CONFIG_SYS_MMC_ENV_DEV		0
-#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
 #define CONFIG_ENV_OFFSET_REDUND       (CONFIG_ENV_OFFSET + \
 						CONFIG_ENV_SIZE)
 #define CONFIG_ENV_SIZE_REDUND         CONFIG_ENV_SIZE
diff --git a/include/configs/socfpga_sr1500.h b/include/configs/socfpga_sr1500.h
index 3a8ccc3..e1a4871 100644
--- a/include/configs/socfpga_sr1500.h
+++ b/include/configs/socfpga_sr1500.h
@@ -28,7 +28,6 @@
 #define CONFIG_SYS_BOOTCOUNT_BE
 
 /* Environment setting for SPI flash */
-#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
 #define CONFIG_ENV_SECT_SIZE	(64 * 1024)
 #define CONFIG_ENV_SIZE		(16 * 1024)
 #define CONFIG_ENV_OFFSET	0x000e0000
diff --git a/include/configs/socfpga_vining_fpga.h b/include/configs/socfpga_vining_fpga.h
index debf3ea..abde883 100644
--- a/include/configs/socfpga_vining_fpga.h
+++ b/include/configs/socfpga_vining_fpga.h
@@ -195,7 +195,6 @@
 		"fi\0"							\
 		"socfpga_legacy_reset_compat=1\0"
 
-#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
 #define CONFIG_ENV_SIZE_REDUND		CONFIG_ENV_SIZE
 #define CONFIG_ENV_SECT_SIZE		(64 * 1024)
 #define CONFIG_ENV_OFFSET		0x100000
diff --git a/include/configs/theadorable-x86-common.h b/include/configs/theadorable-x86-common.h
index 0c563e7..2d7be7d 100644
--- a/include/configs/theadorable-x86-common.h
+++ b/include/configs/theadorable-x86-common.h
@@ -23,7 +23,6 @@
 #define CONFIG_BMP_16BPP
 
 /* Environment settings */
-#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
 #undef CONFIG_ENV_SIZE
 #define CONFIG_ENV_SIZE			0x2000
 #define CONFIG_ENV_SECT_SIZE		0x1000
diff --git a/include/configs/tinker_rk3288.h b/include/configs/tinker_rk3288.h
index 5adae68..f8a55a2 100644
--- a/include/configs/tinker_rk3288.h
+++ b/include/configs/tinker_rk3288.h
@@ -12,6 +12,7 @@
 #undef BOOT_TARGET_DEVICES
 
 #define BOOT_TARGET_DEVICES(func) \
+	func(MMC, mmc, 0) \
 	func(MMC, mmc, 1) \
 	func(USB, usb, 0) \
 	func(PXE, pxe, na) \
diff --git a/include/configs/tqma6.h b/include/configs/tqma6.h
index 13e3d60..3c1d629 100644
--- a/include/configs/tqma6.h
+++ b/include/configs/tqma6.h
@@ -148,7 +148,6 @@
 #define TQMA6_UBOOT_SIZE		(TQMA6_UBOOT_SECTOR_SIZE * \
 					 TQMA6_UBOOT_SECTOR_COUNT)
 
-#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
 #define CONFIG_ENV_OFFSET		(TQMA6_UBOOT_SIZE)
 #define CONFIG_ENV_SECT_SIZE		TQMA6_SPI_FLASH_SECTOR_SIZE
 #define CONFIG_ENV_OFFSET_REDUND	(CONFIG_ENV_OFFSET + \
diff --git a/include/configs/vcoreiii.h b/include/configs/vcoreiii.h
index 8c68372..7ed9524 100644
--- a/include/configs/vcoreiii.h
+++ b/include/configs/vcoreiii.h
@@ -30,7 +30,6 @@
 #define CONFIG_ENV_SIZE			(8 * 1024)
 #define CONFIG_ENV_SECT_SIZE		(256 * 1024)
 
-#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
 #define CONFIG_ENV_SIZE_REDUND		CONFIG_ENV_SIZE
 #define CONFIG_ENV_OFFSET_REDUND      (CONFIG_ENV_OFFSET + CONFIG_ENV_SECT_SIZE)
 
diff --git a/include/dm/pinctrl.h b/include/dm/pinctrl.h
index 3eca34f..692e5fc 100644
--- a/include/dm/pinctrl.h
+++ b/include/dm/pinctrl.h
@@ -370,19 +370,6 @@
 int pinctrl_get_periph_id(struct udevice *dev, struct udevice *periph);
 
 /**
- * pinctrl_decode_pin_config() - decode pin configuration flags
- *
- * This decodes some of the PIN_CONFIG values into flags, with each value
- * being (1 << pin_cfg). This does not support things with values like the
- * slew rate.
- *
- * @blob:	Device tree blob
- * @node:	Node containing the PIN_CONFIG values
- * @return decoded flag value, or -ve on error
- */
-int pinctrl_decode_pin_config(const void *blob, int node);
-
-/**
  * pinctrl_get_gpio_mux() - get the mux value for a particular GPIO
  *
  * This allows the raw mux value for a GPIO to be obtained. It is
diff --git a/include/dt-bindings/clock/imx8mn-clock.h b/include/dt-bindings/clock/imx8mn-clock.h
new file mode 100644
index 0000000..5255b1c
--- /dev/null
+++ b/include/dt-bindings/clock/imx8mn-clock.h
@@ -0,0 +1,215 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2018-2019 NXP
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_IMX8MN_H
+#define __DT_BINDINGS_CLOCK_IMX8MN_H
+
+#define IMX8MN_CLK_DUMMY			0
+#define IMX8MN_CLK_32K				1
+#define IMX8MN_CLK_24M				2
+#define IMX8MN_OSC_HDMI_CLK			3
+#define IMX8MN_CLK_EXT1				4
+#define IMX8MN_CLK_EXT2				5
+#define IMX8MN_CLK_EXT3				6
+#define IMX8MN_CLK_EXT4				7
+#define IMX8MN_AUDIO_PLL1_REF_SEL		8
+#define IMX8MN_AUDIO_PLL2_REF_SEL		9
+#define IMX8MN_VIDEO_PLL1_REF_SEL		10
+#define IMX8MN_DRAM_PLL_REF_SEL			11
+#define IMX8MN_GPU_PLL_REF_SEL			12
+#define IMX8MN_VPU_PLL_REF_SEL			13
+#define IMX8MN_ARM_PLL_REF_SEL			14
+#define IMX8MN_SYS_PLL1_REF_SEL			15
+#define IMX8MN_SYS_PLL2_REF_SEL			16
+#define IMX8MN_SYS_PLL3_REF_SEL			17
+#define IMX8MN_AUDIO_PLL1			18
+#define IMX8MN_AUDIO_PLL2			19
+#define IMX8MN_VIDEO_PLL1			20
+#define IMX8MN_DRAM_PLL				21
+#define IMX8MN_GPU_PLL				22
+#define IMX8MN_VPU_PLL				23
+#define IMX8MN_ARM_PLL				24
+#define IMX8MN_SYS_PLL1				25
+#define IMX8MN_SYS_PLL2				26
+#define IMX8MN_SYS_PLL3				27
+#define IMX8MN_AUDIO_PLL1_BYPASS		28
+#define IMX8MN_AUDIO_PLL2_BYPASS		29
+#define IMX8MN_VIDEO_PLL1_BYPASS		30
+#define IMX8MN_DRAM_PLL_BYPASS			31
+#define IMX8MN_GPU_PLL_BYPASS			32
+#define IMX8MN_VPU_PLL_BYPASS			33
+#define IMX8MN_ARM_PLL_BYPASS			34
+#define IMX8MN_SYS_PLL1_BYPASS			35
+#define IMX8MN_SYS_PLL2_BYPASS			36
+#define IMX8MN_SYS_PLL3_BYPASS			37
+#define IMX8MN_AUDIO_PLL1_OUT			38
+#define IMX8MN_AUDIO_PLL2_OUT			39
+#define IMX8MN_VIDEO_PLL1_OUT			40
+#define IMX8MN_DRAM_PLL_OUT			41
+#define IMX8MN_GPU_PLL_OUT			42
+#define IMX8MN_VPU_PLL_OUT			43
+#define IMX8MN_ARM_PLL_OUT			44
+#define IMX8MN_SYS_PLL1_OUT			45
+#define IMX8MN_SYS_PLL2_OUT			46
+#define IMX8MN_SYS_PLL3_OUT			47
+#define IMX8MN_SYS_PLL1_40M			48
+#define IMX8MN_SYS_PLL1_80M			49
+#define IMX8MN_SYS_PLL1_100M			50
+#define IMX8MN_SYS_PLL1_133M			51
+#define IMX8MN_SYS_PLL1_160M			52
+#define IMX8MN_SYS_PLL1_200M			53
+#define IMX8MN_SYS_PLL1_266M			54
+#define IMX8MN_SYS_PLL1_400M			55
+#define IMX8MN_SYS_PLL1_800M			56
+#define IMX8MN_SYS_PLL2_50M			57
+#define IMX8MN_SYS_PLL2_100M			58
+#define IMX8MN_SYS_PLL2_125M			59
+#define IMX8MN_SYS_PLL2_166M			60
+#define IMX8MN_SYS_PLL2_200M			61
+#define IMX8MN_SYS_PLL2_250M			62
+#define IMX8MN_SYS_PLL2_333M			63
+#define IMX8MN_SYS_PLL2_500M			64
+#define IMX8MN_SYS_PLL2_1000M			65
+
+/* CORE CLOCK ROOT */
+#define IMX8MN_CLK_A53_SRC			66
+#define IMX8MN_CLK_GPU_CORE_SRC			67
+#define IMX8MN_CLK_GPU_SHADER_SRC		68
+#define IMX8MN_CLK_A53_CG			69
+#define IMX8MN_CLK_GPU_CORE_CG			70
+#define IMX8MN_CLK_GPU_SHADER_CG		71
+#define IMX8MN_CLK_A53_DIV			72
+#define IMX8MN_CLK_GPU_CORE_DIV			73
+#define IMX8MN_CLK_GPU_SHADER_DIV		74
+
+/* BUS CLOCK ROOT */
+#define IMX8MN_CLK_MAIN_AXI			75
+#define IMX8MN_CLK_ENET_AXI			76
+#define IMX8MN_CLK_NAND_USDHC_BUS		77
+#define IMX8MN_CLK_DISP_AXI			78
+#define IMX8MN_CLK_DISP_APB			79
+#define IMX8MN_CLK_USB_BUS			80
+#define IMX8MN_CLK_GPU_AXI			81
+#define IMX8MN_CLK_GPU_AHB			82
+#define IMX8MN_CLK_NOC				83
+#define IMX8MN_CLK_AHB				84
+#define IMX8MN_CLK_AUDIO_AHB			85
+
+/* IPG CLOCK ROOT */
+#define IMX8MN_CLK_IPG_ROOT			86
+#define IMX8MN_CLK_IPG_AUDIO_ROOT		87
+
+/* IP */
+#define IMX8MN_CLK_DRAM_CORE			88
+#define IMX8MN_CLK_DRAM_ALT			89
+#define IMX8MN_CLK_DRAM_APB			90
+#define IMX8MN_CLK_DRAM_ALT_ROOT		91
+#define IMX8MN_CLK_DISP_PIXEL			92
+#define IMX8MN_CLK_SAI2				93
+#define IMX8MN_CLK_SAI3				94
+#define IMX8MN_CLK_SAI5				95
+#define IMX8MN_CLK_SAI6				96
+#define IMX8MN_CLK_SPDIF1			97
+#define IMX8MN_CLK_ENET_REF			98
+#define IMX8MN_CLK_ENET_TIMER			99
+#define IMX8MN_CLK_ENET_PHY_REF			100
+#define IMX8MN_CLK_NAND				101
+#define IMX8MN_CLK_QSPI				102
+#define IMX8MN_CLK_USDHC1			103
+#define IMX8MN_CLK_USDHC2			104
+#define IMX8MN_CLK_I2C1				105
+#define IMX8MN_CLK_I2C2				106
+#define IMX8MN_CLK_I2C3				107
+#define IMX8MN_CLK_I2C4				118
+#define IMX8MN_CLK_UART1			119
+#define IMX8MN_CLK_UART2			110
+#define IMX8MN_CLK_UART3			111
+#define IMX8MN_CLK_UART4			112
+#define IMX8MN_CLK_USB_CORE_REF			113
+#define IMX8MN_CLK_USB_PHY_REF			114
+#define IMX8MN_CLK_ECSPI1			115
+#define IMX8MN_CLK_ECSPI2			116
+#define IMX8MN_CLK_PWM1				117
+#define IMX8MN_CLK_PWM2				118
+#define IMX8MN_CLK_PWM3				119
+#define IMX8MN_CLK_PWM4				120
+#define IMX8MN_CLK_WDOG				121
+#define IMX8MN_CLK_WRCLK			122
+#define IMX8MN_CLK_CLKO1			123
+#define IMX8MN_CLK_CLKO2			124
+#define IMX8MN_CLK_DSI_CORE			125
+#define IMX8MN_CLK_DSI_PHY_REF			126
+#define IMX8MN_CLK_DSI_DBI			127
+#define IMX8MN_CLK_USDHC3			128
+#define IMX8MN_CLK_CAMERA_PIXEL			129
+#define IMX8MN_CLK_CSI1_PHY_REF			130
+#define IMX8MN_CLK_CSI2_PHY_REF			131
+#define IMX8MN_CLK_CSI2_ESC			132
+#define IMX8MN_CLK_ECSPI3			133
+#define IMX8MN_CLK_PDM				134
+#define IMX8MN_CLK_SAI7				135
+
+#define IMX8MN_CLK_ECSPI1_ROOT			136
+#define IMX8MN_CLK_ECSPI2_ROOT			137
+#define IMX8MN_CLK_ECSPI3_ROOT			138
+#define IMX8MN_CLK_ENET1_ROOT			139
+#define IMX8MN_CLK_GPIO1_ROOT			140
+#define IMX8MN_CLK_GPIO2_ROOT			141
+#define IMX8MN_CLK_GPIO3_ROOT			142
+#define IMX8MN_CLK_GPIO4_ROOT			143
+#define IMX8MN_CLK_GPIO5_ROOT			144
+#define IMX8MN_CLK_I2C1_ROOT			145
+#define IMX8MN_CLK_I2C2_ROOT			146
+#define IMX8MN_CLK_I2C3_ROOT			147
+#define IMX8MN_CLK_I2C4_ROOT			148
+#define IMX8MN_CLK_MU_ROOT			149
+#define IMX8MN_CLK_OCOTP_ROOT			150
+#define IMX8MN_CLK_PWM1_ROOT			151
+#define IMX8MN_CLK_PWM2_ROOT			152
+#define IMX8MN_CLK_PWM3_ROOT			153
+#define IMX8MN_CLK_PWM4_ROOT			154
+#define IMX8MN_CLK_QSPI_ROOT			155
+#define IMX8MN_CLK_NAND_ROOT			156
+#define IMX8MN_CLK_SAI2_ROOT			157
+#define IMX8MN_CLK_SAI2_IPG			158
+#define IMX8MN_CLK_SAI3_ROOT			159
+#define IMX8MN_CLK_SAI3_IPG			160
+#define IMX8MN_CLK_SAI5_ROOT			161
+#define IMX8MN_CLK_SAI5_IPG			162
+#define IMX8MN_CLK_SAI6_ROOT			163
+#define IMX8MN_CLK_SAI6_IPG			164
+#define IMX8MN_CLK_SAI7_ROOT			165
+#define IMX8MN_CLK_SAI7_IPG			166
+#define IMX8MN_CLK_SDMA1_ROOT			167
+#define IMX8MN_CLK_SDMA2_ROOT			168
+#define IMX8MN_CLK_UART1_ROOT			169
+#define IMX8MN_CLK_UART2_ROOT			170
+#define IMX8MN_CLK_UART3_ROOT			171
+#define IMX8MN_CLK_UART4_ROOT			172
+#define IMX8MN_CLK_USB1_CTRL_ROOT		173
+#define IMX8MN_CLK_USDHC1_ROOT			174
+#define IMX8MN_CLK_USDHC2_ROOT			175
+#define IMX8MN_CLK_WDOG1_ROOT			176
+#define IMX8MN_CLK_WDOG2_ROOT			177
+#define IMX8MN_CLK_WDOG3_ROOT			178
+#define IMX8MN_CLK_GPU_BUS_ROOT			179
+#define IMX8MN_CLK_ASRC_ROOT			180
+#define IMX8MN_CLK_GPU3D_ROOT			181
+#define IMX8MN_CLK_PDM_ROOT			182
+#define IMX8MN_CLK_PDM_IPG			183
+#define IMX8MN_CLK_DISP_AXI_ROOT		184
+#define IMX8MN_CLK_DISP_APB_ROOT		185
+#define IMX8MN_CLK_DISP_PIXEL_ROOT		186
+#define IMX8MN_CLK_CAMERA_PIXEL_ROOT		187
+#define IMX8MN_CLK_USDHC3_ROOT			188
+#define IMX8MN_CLK_SDMA3_ROOT			189
+#define IMX8MN_CLK_TMU_ROOT			190
+#define IMX8MN_CLK_ARM				191
+#define IMX8MN_CLK_NAND_USDHC_BUS_RAWNAND_CLK	192
+#define IMX8MN_CLK_GPU_CORE_ROOT		193
+
+#define IMX8MN_CLK_END				194
+
+#endif
diff --git a/include/dt-bindings/clock/px30-cru.h b/include/dt-bindings/clock/px30-cru.h
new file mode 100644
index 0000000..e5e5969
--- /dev/null
+++ b/include/dt-bindings/clock/px30-cru.h
@@ -0,0 +1,389 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2017 Rockchip Electronics Co. Ltd.
+ * Author: Elaine <zhangqing@rock-chips.com>
+ */
+
+#ifndef _DT_BINDINGS_CLK_ROCKCHIP_PX30_H
+#define _DT_BINDINGS_CLK_ROCKCHIP_PX30_H
+
+/* core clocks */
+#define PLL_APLL		1
+#define PLL_DPLL		2
+#define PLL_CPLL		3
+#define PLL_NPLL		4
+#define APLL_BOOST_H		5
+#define APLL_BOOST_L		6
+#define ARMCLK			7
+
+/* sclk gates (special clocks) */
+#define USB480M			14
+#define SCLK_PDM		15
+#define SCLK_I2S0_TX		16
+#define SCLK_I2S0_TX_OUT	17
+#define SCLK_I2S0_RX		18
+#define SCLK_I2S0_RX_OUT	19
+#define SCLK_I2S1		20
+#define SCLK_I2S1_OUT		21
+#define SCLK_I2S2		22
+#define SCLK_I2S2_OUT		23
+#define SCLK_UART1		24
+#define SCLK_UART2		25
+#define SCLK_UART3		26
+#define SCLK_UART4		27
+#define SCLK_UART5		28
+#define SCLK_I2C0		29
+#define SCLK_I2C1		30
+#define SCLK_I2C2		31
+#define SCLK_I2C3		32
+#define SCLK_I2C4		33
+#define SCLK_PWM0		34
+#define SCLK_PWM1		35
+#define SCLK_SPI0		36
+#define SCLK_SPI1		37
+#define SCLK_TIMER0		38
+#define SCLK_TIMER1		39
+#define SCLK_TIMER2		40
+#define SCLK_TIMER3		41
+#define SCLK_TIMER4		42
+#define SCLK_TIMER5		43
+#define SCLK_TSADC		44
+#define SCLK_SARADC		45
+#define SCLK_OTP		46
+#define SCLK_OTP_USR		47
+#define SCLK_CRYPTO		48
+#define SCLK_CRYPTO_APK		49
+#define SCLK_DDRC		50
+#define SCLK_ISP		51
+#define SCLK_CIF_OUT		52
+#define SCLK_RGA_CORE		53
+#define SCLK_VOPB_PWM		54
+#define SCLK_NANDC		55
+#define SCLK_SDIO		56
+#define SCLK_EMMC		57
+#define SCLK_SFC		58
+#define SCLK_SDMMC		59
+#define SCLK_OTG_ADP		60
+#define SCLK_GMAC_SRC		61
+#define SCLK_GMAC		62
+#define SCLK_GMAC_RX_TX		63
+#define SCLK_MAC_REF		64
+#define SCLK_MAC_REFOUT		65
+#define SCLK_MAC_OUT		66
+#define SCLK_SDMMC_DRV		67
+#define SCLK_SDMMC_SAMPLE	68
+#define SCLK_SDIO_DRV		69
+#define SCLK_SDIO_SAMPLE	70
+#define SCLK_EMMC_DRV		71
+#define SCLK_EMMC_SAMPLE	72
+#define SCLK_GPU		73
+#define SCLK_PVTM		74
+#define SCLK_CORE_VPU		75
+#define SCLK_GMAC_RMII		76
+#define SCLK_UART2_SRC		77
+#define SCLK_NANDC_DIV		78
+#define SCLK_NANDC_DIV50	79
+#define SCLK_SDIO_DIV		80
+#define SCLK_SDIO_DIV50		81
+#define SCLK_EMMC_DIV		82
+#define SCLK_EMMC_DIV50		83
+
+/* dclk gates */
+#define DCLK_VOPB		150
+#define DCLK_VOPL		151
+
+/* aclk gates */
+#define ACLK_GPU		170
+#define ACLK_BUS_PRE		171
+#define ACLK_CRYPTO		172
+#define ACLK_VI_PRE		173
+#define ACLK_VO_PRE		174
+#define ACLK_VPU		175
+#define ACLK_PERI_PRE		176
+#define ACLK_GMAC		178
+#define ACLK_CIF		179
+#define ACLK_ISP		180
+#define ACLK_VOPB		181
+#define ACLK_VOPL		182
+#define ACLK_RGA		183
+#define ACLK_GIC		184
+#define ACLK_DCF		186
+#define ACLK_DMAC		187
+
+/* hclk gates */
+#define HCLK_BUS_PRE		240
+#define HCLK_CRYPTO		241
+#define HCLK_VI_PRE		242
+#define HCLK_VO_PRE		243
+#define HCLK_VPU		244
+#define HCLK_PERI_PRE		245
+#define HCLK_MMC_NAND		246
+#define HCLK_SDMMC		247
+#define HCLK_USB		248
+#define HCLK_CIF		249
+#define HCLK_ISP		250
+#define HCLK_VOPB		251
+#define HCLK_VOPL		252
+#define HCLK_RGA		253
+#define HCLK_NANDC		254
+#define HCLK_SDIO		255
+#define HCLK_EMMC		256
+#define HCLK_SFC		257
+#define HCLK_OTG		258
+#define HCLK_HOST		259
+#define HCLK_HOST_ARB		260
+#define HCLK_PDM		261
+#define HCLK_I2S0		262
+#define HCLK_I2S1		263
+#define HCLK_I2S2		264
+
+/* pclk gates */
+#define PCLK_BUS_PRE		320
+#define PCLK_DDR		321
+#define PCLK_VO_PRE		322
+#define PCLK_GMAC		323
+#define PCLK_MIPI_DSI		324
+#define PCLK_MIPIDSIPHY		325
+#define PCLK_MIPICSIPHY		326
+#define PCLK_USB_GRF		327
+#define PCLK_DCF		328
+#define PCLK_UART1		329
+#define PCLK_UART2		330
+#define PCLK_UART3		331
+#define PCLK_UART4		332
+#define PCLK_UART5		333
+#define PCLK_I2C0		334
+#define PCLK_I2C1		335
+#define PCLK_I2C2		336
+#define PCLK_I2C3		337
+#define PCLK_I2C4		338
+#define PCLK_PWM0		339
+#define PCLK_PWM1		340
+#define PCLK_SPI0		341
+#define PCLK_SPI1		342
+#define PCLK_SARADC		343
+#define PCLK_TSADC		344
+#define PCLK_TIMER		345
+#define PCLK_OTP_NS		346
+#define PCLK_WDT_NS		347
+#define PCLK_GPIO1		348
+#define PCLK_GPIO2		349
+#define PCLK_GPIO3		350
+#define PCLK_ISP		351
+#define PCLK_CIF		352
+#define PCLK_OTP_PHY		353
+
+#define CLK_NR_CLKS		(PCLK_OTP_PHY + 1)
+
+/* pmu-clocks indices */
+
+#define PLL_GPLL		1
+
+#define SCLK_RTC32K_PMU		4
+#define SCLK_WIFI_PMU		5
+#define SCLK_UART0_PMU		6
+#define SCLK_PVTM_PMU		7
+#define PCLK_PMU_PRE		8
+#define SCLK_REF24M_PMU		9
+#define SCLK_USBPHY_REF		10
+#define SCLK_MIPIDSIPHY_REF	11
+
+#define XIN24M_DIV		12
+
+#define PCLK_GPIO0_PMU		20
+#define PCLK_UART0_PMU		21
+
+#define CLKPMU_NR_CLKS		(PCLK_UART0_PMU + 1)
+
+/* soft-reset indices */
+#define SRST_CORE0_PO		0
+#define SRST_CORE1_PO		1
+#define SRST_CORE2_PO		2
+#define SRST_CORE3_PO		3
+#define SRST_CORE0		4
+#define SRST_CORE1		5
+#define SRST_CORE2		6
+#define SRST_CORE3		7
+#define SRST_CORE0_DBG		8
+#define SRST_CORE1_DBG		9
+#define SRST_CORE2_DBG		10
+#define SRST_CORE3_DBG		11
+#define SRST_TOPDBG		12
+#define SRST_CORE_NOC		13
+#define SRST_STRC_A		14
+#define SRST_L2C		15
+
+#define SRST_DAP		16
+#define SRST_CORE_PVTM		17
+#define SRST_GPU		18
+#define SRST_GPU_NIU		19
+#define SRST_UPCTL2		20
+#define SRST_UPCTL2_A		21
+#define SRST_UPCTL2_P		22
+#define SRST_MSCH		23
+#define SRST_MSCH_P		24
+#define SRST_DDRMON_P		25
+#define SRST_DDRSTDBY_P		26
+#define SRST_DDRSTDBY		27
+#define SRST_DDRGRF_p		28
+#define SRST_AXI_SPLIT_A	29
+#define SRST_AXI_CMD_A		30
+#define SRST_AXI_CMD_P		31
+
+#define SRST_DDRPHY		32
+#define SRST_DDRPHYDIV		33
+#define SRST_DDRPHY_P		34
+#define SRST_VPU_A		36
+#define SRST_VPU_NIU_A		37
+#define SRST_VPU_H		38
+#define SRST_VPU_NIU_H		39
+#define SRST_VI_NIU_A		40
+#define SRST_VI_NIU_H		41
+#define SRST_ISP_H		42
+#define SRST_ISP		43
+#define SRST_CIF_A		44
+#define SRST_CIF_H		45
+#define SRST_CIF_PCLKIN		46
+#define SRST_MIPICSIPHY_P	47
+
+#define SRST_VO_NIU_A		48
+#define SRST_VO_NIU_H		49
+#define SRST_VO_NIU_P		50
+#define SRST_VOPB_A		51
+#define SRST_VOPB_H		52
+#define SRST_VOPB		53
+#define SRST_PWM_VOPB		54
+#define SRST_VOPL_A		55
+#define SRST_VOPL_H		56
+#define SRST_VOPL		57
+#define SRST_RGA_A		58
+#define SRST_RGA_H		59
+#define SRST_RGA		60
+#define SRST_MIPIDSI_HOST_P	61
+#define SRST_MIPIDSIPHY_P	62
+#define SRST_VPU_CORE		63
+
+#define SRST_PERI_NIU_A		64
+#define SRST_USB_NIU_H		65
+#define SRST_USB2OTG_H		66
+#define SRST_USB2OTG		67
+#define SRST_USB2OTG_ADP	68
+#define SRST_USB2HOST_H		69
+#define SRST_USB2HOST_ARB_H	70
+#define SRST_USB2HOST_AUX_H	71
+#define SRST_USB2HOST_EHCI	72
+#define SRST_USB2HOST		73
+#define SRST_USBPHYPOR		74
+#define SRST_USBPHY_OTG_PORT	75
+#define SRST_USBPHY_HOST_PORT	76
+#define SRST_USBPHY_GRF		77
+#define SRST_CPU_BOOST_P	78
+#define SRST_CPU_BOOST		79
+
+#define SRST_MMC_NAND_NIU_H	80
+#define SRST_SDIO_H		81
+#define SRST_EMMC_H		82
+#define SRST_SFC_H		83
+#define SRST_SFC		84
+#define SRST_SDCARD_NIU_H	85
+#define SRST_SDMMC_H		86
+#define SRST_NANDC_H		89
+#define SRST_NANDC		90
+#define SRST_GMAC_NIU_A		92
+#define SRST_GMAC_NIU_P		93
+#define SRST_GMAC_A		94
+
+#define SRST_PMU_NIU_P		96
+#define SRST_PMU_SGRF_P		97
+#define SRST_PMU_GRF_P		98
+#define SRST_PMU		99
+#define SRST_PMU_MEM_P		100
+#define SRST_PMU_GPIO0_P	101
+#define SRST_PMU_UART0_P	102
+#define SRST_PMU_CRU_P		103
+#define SRST_PMU_PVTM		104
+#define SRST_PMU_UART		105
+#define SRST_PMU_NIU_H		106
+#define SRST_PMU_DDR_FAIL_SAVE	107
+#define SRST_PMU_CORE_PERF_A	108
+#define SRST_PMU_CORE_GRF_P	109
+#define SRST_PMU_GPU_PERF_A	110
+#define SRST_PMU_GPU_GRF_P	111
+
+#define SRST_CRYPTO_NIU_A	112
+#define SRST_CRYPTO_NIU_H	113
+#define SRST_CRYPTO_A		114
+#define SRST_CRYPTO_H		115
+#define SRST_CRYPTO		116
+#define SRST_CRYPTO_APK		117
+#define SRST_BUS_NIU_H		120
+#define SRST_USB_NIU_P		121
+#define SRST_BUS_TOP_NIU_P	122
+#define SRST_INTMEM_A		123
+#define SRST_GIC_A		124
+#define SRST_ROM_H		126
+#define SRST_DCF_A		127
+
+#define SRST_DCF_P		128
+#define SRST_PDM_H		129
+#define SRST_PDM		130
+#define SRST_I2S0_H		131
+#define SRST_I2S0_TX		132
+#define SRST_I2S1_H		133
+#define SRST_I2S1		134
+#define SRST_I2S2_H		135
+#define SRST_I2S2		136
+#define SRST_UART1_P		137
+#define SRST_UART1		138
+#define SRST_UART2_P		139
+#define SRST_UART2		140
+#define SRST_UART3_P		141
+#define SRST_UART3		142
+#define SRST_UART4_P		143
+
+#define SRST_UART4		144
+#define SRST_UART5_P		145
+#define SRST_UART5		146
+#define SRST_I2C0_P		147
+#define SRST_I2C0		148
+#define SRST_I2C1_P		149
+#define SRST_I2C1		150
+#define SRST_I2C2_P		151
+#define SRST_I2C2		152
+#define SRST_I2C3_P		153
+#define SRST_I2C3		154
+#define SRST_PWM0_P		157
+#define SRST_PWM0		158
+#define SRST_PWM1_P		159
+
+#define SRST_PWM1		160
+#define SRST_SPI0_P		161
+#define SRST_SPI0		162
+#define SRST_SPI1_P		163
+#define SRST_SPI1		164
+#define SRST_SARADC_P		165
+#define SRST_SARADC		166
+#define SRST_TSADC_P		167
+#define SRST_TSADC		168
+#define SRST_TIMER_P		169
+#define SRST_TIMER0		170
+#define SRST_TIMER1		171
+#define SRST_TIMER2		172
+#define SRST_TIMER3		173
+#define SRST_TIMER4		174
+#define SRST_TIMER5		175
+
+#define SRST_OTP_NS_P		176
+#define SRST_OTP_NS_SBPI	177
+#define SRST_OTP_NS_USR		178
+#define SRST_OTP_PHY_P		179
+#define SRST_OTP_PHY		180
+#define SRST_WDT_NS_P		181
+#define SRST_GPIO1_P		182
+#define SRST_GPIO2_P		183
+#define SRST_GPIO3_P		184
+#define SRST_SGRF_P		185
+#define SRST_GRF_P		186
+#define SRST_I2S0_RX		191
+
+#endif
diff --git a/include/dt-bindings/clock/rk3308-cru.h b/include/dt-bindings/clock/rk3308-cru.h
new file mode 100644
index 0000000..d97840f
--- /dev/null
+++ b/include/dt-bindings/clock/rk3308-cru.h
@@ -0,0 +1,387 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 Rockchip Electronics Co. Ltd.
+ * Author: Finley Xiao <finley.xiao@rock-chips.com>
+ */
+
+#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RK3308_H
+#define _DT_BINDINGS_CLK_ROCKCHIP_RK3308_H
+
+/* core clocks */
+#define PLL_APLL		1
+#define PLL_DPLL		2
+#define PLL_VPLL0		3
+#define PLL_VPLL1		4
+#define ARMCLK			5
+
+/* sclk (special clocks) */
+#define USB480M			14
+#define SCLK_RTC32K		15
+#define SCLK_PVTM_CORE		16
+#define SCLK_UART0		17
+#define SCLK_UART1		18
+#define SCLK_UART2		19
+#define SCLK_UART3		20
+#define SCLK_UART4		21
+#define SCLK_I2C0		22
+#define SCLK_I2C1		23
+#define SCLK_I2C2		24
+#define SCLK_I2C3		25
+#define SCLK_PWM0		26
+#define SCLK_SPI0		27
+#define SCLK_SPI1		28
+#define SCLK_SPI2		29
+#define SCLK_TIMER0		30
+#define SCLK_TIMER1		31
+#define SCLK_TIMER2		32
+#define SCLK_TIMER3		33
+#define SCLK_TIMER4		34
+#define SCLK_TIMER5		35
+#define SCLK_TSADC		36
+#define SCLK_SARADC		37
+#define SCLK_OTP		38
+#define SCLK_OTP_USR		39
+#define SCLK_CPU_BOOST		40
+#define SCLK_CRYPTO		41
+#define SCLK_CRYPTO_APK		42
+#define SCLK_NANDC_DIV		43
+#define SCLK_NANDC_DIV50	44
+#define SCLK_NANDC		45
+#define SCLK_SDMMC_DIV		46
+#define SCLK_SDMMC_DIV50	47
+#define SCLK_SDMMC		48
+#define SCLK_SDMMC_DRV		49
+#define SCLK_SDMMC_SAMPLE	50
+#define SCLK_SDIO_DIV		51
+#define SCLK_SDIO_DIV50		52
+#define SCLK_SDIO		53
+#define SCLK_SDIO_DRV		54
+#define SCLK_SDIO_SAMPLE	55
+#define SCLK_EMMC_DIV		56
+#define SCLK_EMMC_DIV50		57
+#define SCLK_EMMC		58
+#define SCLK_EMMC_DRV		59
+#define SCLK_EMMC_SAMPLE	60
+#define SCLK_SFC		61
+#define SCLK_OTG_ADP		62
+#define SCLK_MAC_SRC		63
+#define SCLK_MAC		64
+#define SCLK_MAC_REF		65
+#define SCLK_MAC_RX_TX		66
+#define SCLK_MAC_RMII		67
+#define SCLK_DDR_MON_TIMER	68
+#define SCLK_DDR_MON		69
+#define SCLK_DDRCLK		70
+#define SCLK_PMU		71
+#define SCLK_USBPHY_REF		72
+#define SCLK_WIFI		73
+#define SCLK_PVTM_PMU		74
+#define SCLK_PDM		75
+#define SCLK_I2S0_8CH_TX	76
+#define SCLK_I2S0_8CH_TX_OUT	77
+#define SCLK_I2S0_8CH_RX	78
+#define SCLK_I2S0_8CH_RX_OUT	79
+#define SCLK_I2S1_8CH_TX	80
+#define SCLK_I2S1_8CH_TX_OUT	81
+#define SCLK_I2S1_8CH_RX	82
+#define SCLK_I2S1_8CH_RX_OUT	83
+#define SCLK_I2S2_8CH_TX	84
+#define SCLK_I2S2_8CH_TX_OUT	85
+#define SCLK_I2S2_8CH_RX	86
+#define SCLK_I2S2_8CH_RX_OUT	87
+#define SCLK_I2S3_8CH_TX	88
+#define SCLK_I2S3_8CH_TX_OUT	89
+#define SCLK_I2S3_8CH_RX	90
+#define SCLK_I2S3_8CH_RX_OUT	91
+#define SCLK_I2S0_2CH		92
+#define SCLK_I2S0_2CH_OUT	93
+#define SCLK_I2S1_2CH		94
+#define SCLK_I2S1_2CH_OUT	95
+#define SCLK_SPDIF_TX_DIV	96
+#define SCLK_SPDIF_TX_DIV50	97
+#define SCLK_SPDIF_TX		98
+#define SCLK_SPDIF_RX_DIV	99
+#define SCLK_SPDIF_RX_DIV50	100
+#define SCLK_SPDIF_RX		101
+#define SCLK_I2S0_8CH_TX_MUX	102
+#define SCLK_I2S0_8CH_RX_MUX	103
+#define SCLK_I2S1_8CH_TX_MUX	104
+#define SCLK_I2S1_8CH_RX_MUX	105
+#define SCLK_I2S2_8CH_TX_MUX	106
+#define SCLK_I2S2_8CH_RX_MUX	107
+#define SCLK_I2S3_8CH_TX_MUX	108
+#define SCLK_I2S3_8CH_RX_MUX	109
+#define SCLK_I2S0_8CH_TX_SRC	110
+#define SCLK_I2S0_8CH_RX_SRC	111
+#define SCLK_I2S1_8CH_TX_SRC	112
+#define SCLK_I2S1_8CH_RX_SRC	113
+#define SCLK_I2S2_8CH_TX_SRC	114
+#define SCLK_I2S2_8CH_RX_SRC	115
+#define SCLK_I2S3_8CH_TX_SRC	116
+#define SCLK_I2S3_8CH_RX_SRC	117
+#define SCLK_I2S0_2CH_SRC	118
+#define SCLK_I2S1_2CH_SRC	119
+#define SCLK_PWM1		120
+#define SCLK_PWM2		121
+#define SCLK_OWIRE		122
+
+/* dclk */
+#define DCLK_VOP		125
+
+/* aclk */
+#define ACLK_BUS_SRC		130
+#define ACLK_BUS		131
+#define ACLK_PERI_SRC		132
+#define ACLK_PERI		133
+#define ACLK_MAC		134
+#define ACLK_CRYPTO		135
+#define ACLK_VOP		136
+#define ACLK_GIC		137
+#define ACLK_DMAC0		138
+#define ACLK_DMAC1		139
+
+/* hclk */
+#define HCLK_BUS		150
+#define HCLK_PERI		151
+#define HCLK_AUDIO		152
+#define HCLK_NANDC		153
+#define HCLK_SDMMC		154
+#define HCLK_SDIO		155
+#define HCLK_EMMC		156
+#define HCLK_SFC		157
+#define HCLK_OTG		158
+#define HCLK_HOST		159
+#define HCLK_HOST_ARB		160
+#define HCLK_PDM		161
+#define HCLK_SPDIFTX		162
+#define HCLK_SPDIFRX		163
+#define HCLK_I2S0_8CH		164
+#define HCLK_I2S1_8CH		165
+#define HCLK_I2S2_8CH		166
+#define HCLK_I2S3_8CH		167
+#define HCLK_I2S0_2CH		168
+#define HCLK_I2S1_2CH		169
+#define HCLK_VAD		170
+#define HCLK_CRYPTO		171
+#define HCLK_VOP		172
+
+/* pclk */
+#define PCLK_BUS		190
+#define PCLK_DDR		191
+#define PCLK_PERI		192
+#define PCLK_PMU		193
+#define PCLK_AUDIO		194
+#define PCLK_MAC		195
+#define PCLK_ACODEC		196
+#define PCLK_UART0		197
+#define PCLK_UART1		198
+#define PCLK_UART2		199
+#define PCLK_UART3		200
+#define PCLK_UART4		201
+#define PCLK_I2C0		202
+#define PCLK_I2C1		203
+#define PCLK_I2C2		204
+#define PCLK_I2C3		205
+#define PCLK_PWM0		206
+#define PCLK_SPI0		207
+#define PCLK_SPI1		208
+#define PCLK_SPI2		209
+#define PCLK_SARADC		210
+#define PCLK_TSADC		211
+#define PCLK_TIMER		212
+#define PCLK_OTP_NS		213
+#define PCLK_WDT		214
+#define PCLK_GPIO0		215
+#define PCLK_GPIO1		216
+#define PCLK_GPIO2		217
+#define PCLK_GPIO3		218
+#define PCLK_GPIO4		219
+#define PCLK_SGRF		220
+#define PCLK_GRF		221
+#define PCLK_USBSD_DET		222
+#define PCLK_DDR_UPCTL		223
+#define PCLK_DDR_MON		224
+#define PCLK_DDRPHY		225
+#define PCLK_DDR_STDBY		226
+#define PCLK_USB_GRF		227
+#define PCLK_CRU		228
+#define PCLK_OTP_PHY		229
+#define PCLK_CPU_BOOST		230
+#define PCLK_PWM1		231
+#define PCLK_PWM2		232
+#define PCLK_CAN		233
+#define PCLK_OWIRE		234
+
+#define CLK_NR_CLKS		(PCLK_OWIRE + 1)
+
+/* soft-reset indices */
+
+/* cru_softrst_con0 */
+#define SRST_CORE0_PO		0
+#define SRST_CORE1_PO		1
+#define SRST_CORE2_PO		2
+#define SRST_CORE3_PO		3
+#define SRST_CORE0		4
+#define SRST_CORE1		5
+#define SRST_CORE2		6
+#define SRST_CORE3		7
+#define SRST_CORE0_DBG		8
+#define SRST_CORE1_DBG		9
+#define SRST_CORE2_DBG		10
+#define SRST_CORE3_DBG		11
+#define SRST_TOPDBG		12
+#define SRST_CORE_NOC		13
+#define SRST_STRC_A		14
+#define SRST_L2C		15
+
+/* cru_softrst_con1 */
+#define SRST_DAP		16
+#define SRST_CORE_PVTM		17
+#define SRST_CORE_PRF		18
+#define SRST_CORE_GRF		19
+#define SRST_DDRUPCTL		20
+#define SRST_DDRUPCTL_P		22
+#define SRST_MSCH		23
+#define SRST_DDRMON_P		25
+#define SRST_DDRSTDBY_P		26
+#define SRST_DDRSTDBY		27
+#define SRST_DDRPHY		28
+#define SRST_DDRPHY_DIV		29
+#define SRST_DDRPHY_P		30
+
+/* cru_softrst_con2 */
+#define SRST_BUS_NIU_H		32
+#define SRST_USB_NIU_P		33
+#define SRST_CRYPTO_A		34
+#define SRST_CRYPTO_H		35
+#define SRST_CRYPTO		36
+#define SRST_CRYPTO_APK		37
+#define SRST_VOP_A		38
+#define SRST_VOP_H		39
+#define SRST_VOP_D		40
+#define SRST_INTMEM_A		41
+#define SRST_ROM_H		42
+#define SRST_GIC_A		43
+#define SRST_UART0_P		44
+#define SRST_UART0		45
+#define SRST_UART1_P		46
+#define SRST_UART1		47
+
+/* cru_softrst_con3 */
+#define SRST_UART2_P		48
+#define SRST_UART2		49
+#define SRST_UART3_P		50
+#define SRST_UART3		51
+#define SRST_UART4_P		52
+#define SRST_UART4		53
+#define SRST_I2C0_P		54
+#define SRST_I2C0		55
+#define SRST_I2C1_P		56
+#define SRST_I2C1		57
+#define SRST_I2C2_P		58
+#define SRST_I2C2		59
+#define SRST_I2C3_P		60
+#define SRST_I2C3		61
+#define SRST_PWM0_P		62
+#define SRST_PWM0		63
+
+/* cru_softrst_con4 */
+#define SRST_SPI0_P		64
+#define SRST_SPI0		65
+#define SRST_SPI1_P		66
+#define SRST_SPI1		67
+#define SRST_SPI2_P		68
+#define SRST_SPI2		69
+#define SRST_SARADC_P		70
+#define SRST_TSADC_P		71
+#define SRST_TSADC		72
+#define SRST_TIMER0_P		73
+#define SRST_TIMER0		74
+#define SRST_TIMER1		75
+#define SRST_TIMER2		76
+#define SRST_TIMER3		77
+#define SRST_TIMER4		78
+#define SRST_TIMER5		79
+
+/* cru_softrst_con5 */
+#define SRST_OTP_NS_P		80
+#define SRST_OTP_NS_SBPI	81
+#define SRST_OTP_NS_USR		82
+#define SRST_OTP_PHY_P		83
+#define SRST_OTP_PHY		84
+#define SRST_GPIO0_P		86
+#define SRST_GPIO1_P		87
+#define SRST_GPIO2_P		88
+#define SRST_GPIO3_P		89
+#define SRST_GPIO4_P		90
+#define SRST_GRF_P		91
+#define SRST_USBSD_DET_P	92
+#define SRST_PMU		93
+#define SRST_PMU_PVTM		94
+#define SRST_USB_GRF_P		95
+
+/* cru_softrst_con6 */
+#define SRST_CPU_BOOST		96
+#define SRST_CPU_BOOST_P	97
+#define SRST_PWM1_P		98
+#define SRST_PWM1		99
+#define SRST_PWM2_P		100
+#define SRST_PWM2		101
+#define SRST_PERI_NIU_A		104
+#define SRST_PERI_NIU_H		105
+#define SRST_PERI_NIU_p		106
+#define SRST_USB2OTG_H		107
+#define SRST_USB2OTG		108
+#define SRST_USB2OTG_ADP	109
+#define SRST_USB2HOST_H		110
+#define SRST_USB2HOST_ARB_H	111
+
+/* cru_softrst_con7 */
+#define SRST_USB2HOST_AUX_H	112
+#define SRST_USB2HOST_EHCI	113
+#define SRST_USB2HOST		114
+#define SRST_USBPHYPOR		115
+#define SRST_UTMI0		116
+#define SRST_UTMI1		117
+#define SRST_SDIO_H		118
+#define SRST_EMMC_H		119
+#define SRST_SFC_H		120
+#define SRST_SFC		121
+#define SRST_SD_H		122
+#define SRST_NANDC_H		123
+#define SRST_NANDC_N		124
+#define SRST_MAC_A		125
+#define SRST_CAN_P		126
+#define SRST_OWIRE_P		127
+
+/* cru_softrst_con8 */
+#define SRST_AUDIO_NIU_H	128
+#define SRST_AUDIO_NIU_P	129
+#define SRST_PDM_H		130
+#define SRST_PDM_M		131
+#define SRST_SPDIFTX_H		132
+#define SRST_SPDIFTX_M		133
+#define SRST_SPDIFRX_H		134
+#define SRST_SPDIFRX_M		135
+#define SRST_I2S0_8CH_H		136
+#define SRST_I2S0_8CH_TX_M	137
+#define SRST_I2S0_8CH_RX_M	138
+#define SRST_I2S1_8CH_H		139
+#define SRST_I2S1_8CH_TX_M	140
+#define SRST_I2S1_8CH_RX_M	141
+#define SRST_I2S2_8CH_H		142
+#define SRST_I2S2_8CH_TX_M	143
+
+/* cru_softrst_con9 */
+#define SRST_I2S2_8CH_RX_M	144
+#define SRST_I2S3_8CH_H		145
+#define SRST_I2S3_8CH_TX_M	146
+#define SRST_I2S3_8CH_RX_M	147
+#define SRST_I2S0_2CH_H		148
+#define SRST_I2S0_2CH_M		149
+#define SRST_I2S1_2CH_H		150
+#define SRST_I2S1_2CH_M		151
+#define SRST_VAD_H		152
+#define SRST_ACODEC_P		153
+
+#endif
diff --git a/include/dt-bindings/power/px30-power.h b/include/dt-bindings/power/px30-power.h
new file mode 100644
index 0000000..30917a9
--- /dev/null
+++ b/include/dt-bindings/power/px30-power.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __DT_BINDINGS_POWER_PX30_POWER_H__
+#define __DT_BINDINGS_POWER_PX30_POWER_H__
+
+/* VD_CORE */
+#define PX30_PD_A35_0		0
+#define PX30_PD_A35_1		1
+#define PX30_PD_A35_2		2
+#define PX30_PD_A35_3		3
+#define PX30_PD_SCU		4
+
+/* VD_LOGIC */
+#define PX30_PD_USB		5
+#define PX30_PD_DDR		6
+#define PX30_PD_SDCARD		7
+#define PX30_PD_CRYPTO		8
+#define PX30_PD_GMAC		9
+#define PX30_PD_MMC_NAND	10
+#define PX30_PD_VPU		11
+#define PX30_PD_VO		12
+#define PX30_PD_VI		13
+#define PX30_PD_GPU		14
+
+/* VD_PMU */
+#define PX30_PD_PMU		15
+
+#endif
diff --git a/include/dt-bindings/soc/rockchip,boot-mode.h b/include/dt-bindings/soc/rockchip,boot-mode.h
new file mode 100644
index 0000000..4b0914c
--- /dev/null
+++ b/include/dt-bindings/soc/rockchip,boot-mode.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ROCKCHIP_BOOT_MODE_H
+#define __ROCKCHIP_BOOT_MODE_H
+
+/*high 24 bits is tag, low 8 bits is type*/
+#define REBOOT_FLAG		0x5242C300
+/* normal boot */
+#define BOOT_NORMAL		(REBOOT_FLAG + 0)
+/* enter bootloader rockusb mode */
+#define BOOT_BL_DOWNLOAD	(REBOOT_FLAG + 1)
+/* enter recovery */
+#define BOOT_RECOVERY		(REBOOT_FLAG + 3)
+ /* enter fastboot mode */
+#define BOOT_FASTBOOT		(REBOOT_FLAG + 9)
+
+#endif
diff --git a/include/env_internal.h b/include/env_internal.h
index 88c36b3..d520e6a 100644
--- a/include/env_internal.h
+++ b/include/env_internal.h
@@ -58,21 +58,12 @@
 	(CONFIG_SYS_MONITOR_BASE + CONFIG_SYS_MONITOR_LEN)
 #  define ENV_IS_EMBEDDED
 # endif
-# if defined(CONFIG_ENV_ADDR_REDUND) || defined(CONFIG_ENV_OFFSET_REDUND)
-#  define CONFIG_SYS_REDUNDAND_ENVIRONMENT
-# endif
 # ifdef CONFIG_ENV_IS_EMBEDDED
 #  error "do not define CONFIG_ENV_IS_EMBEDDED in your board config"
 #  error "it is calculated automatically for you"
 # endif
 #endif	/* CONFIG_ENV_IS_IN_FLASH */
 
-#if defined(CONFIG_ENV_IS_IN_MMC)
-# ifdef CONFIG_ENV_OFFSET_REDUND
-#  define CONFIG_SYS_REDUNDAND_ENVIRONMENT
-# endif
-#endif
-
 #if defined(CONFIG_ENV_IS_IN_NAND)
 # if defined(CONFIG_ENV_OFFSET_OOB)
 #  ifdef CONFIG_ENV_OFFSET_REDUND
@@ -85,9 +76,6 @@
 #  ifndef CONFIG_ENV_OFFSET
 #   error "Need to define CONFIG_ENV_OFFSET when using CONFIG_ENV_IS_IN_NAND"
 #  endif
-#  ifdef CONFIG_ENV_OFFSET_REDUND
-#   define CONFIG_SYS_REDUNDAND_ENVIRONMENT
-#  endif
 # endif /* CONFIG_ENV_OFFSET_OOB */
 # ifndef CONFIG_ENV_SIZE
 #  error "Need to define CONFIG_ENV_SIZE when using CONFIG_ENV_IS_IN_NAND"
@@ -101,9 +89,6 @@
 # ifndef CONFIG_ENV_UBI_VOLUME
 #  error "Need to define CONFIG_ENV_UBI_VOLUME when using CONFIG_ENV_IS_IN_UBI"
 # endif
-# if defined(CONFIG_ENV_UBI_IS_VOLUME_REDUND)
-#  define CONFIG_SYS_REDUNDAND_ENVIRONMENT
-# endif
 # ifndef CONFIG_ENV_SIZE
 #  error "Need to define CONFIG_ENV_SIZE when using CONFIG_ENV_IS_IN_UBI"
 # endif
diff --git a/include/fdtdec.h b/include/fdtdec.h
index f1e58f9..696e0fd 100644
--- a/include/fdtdec.h
+++ b/include/fdtdec.h
@@ -1061,6 +1061,7 @@
  * @param basename	base name of the node to create
  * @param carveout	information about the carveout region
  * @param phandlep	return location for the phandle of the carveout region
+ *			can be NULL if no phandle should be added
  * @return 0 on success or a negative error code on failure
  */
 int fdtdec_add_reserved_memory(void *blob, const char *basename,
diff --git a/include/host_arch.h b/include/host_arch.h
new file mode 100644
index 0000000..169d494
--- /dev/null
+++ b/include/host_arch.h
@@ -0,0 +1,24 @@
+#if 0
+# SPDX SPDX-License-Identifier: GPL-2.0+
+#
+# Constants defining the host architecture in assembler, C, and make files.
+# The values are arbitrary.
+#
+# Copyright 2019 Heinrich Schuchardt <xypron.glpk@gmx.de>
+#endif
+
+#if 0
+export HOST_ARCH_AARCH64=0xaa64
+export HOST_ARCH_ARM=0x00a7
+export HOST_ARCH_RISCV32=0x5032
+export HOST_ARCH_RISCV64=0x5064
+export HOST_ARCH_X86=0x0386
+export HOST_ARCH_X86_64=0x8664
+#endif
+
+#define HOST_ARCH_AARCH64 0xaa64
+#define HOST_ARCH_ARM 0x00a7
+#define HOST_ARCH_RISCV32 0x5032
+#define HOST_ARCH_RISCV64 0x5064
+#define HOST_ARCH_X86 0x0386
+#define HOST_ARCH_X86_64 0x8664
diff --git a/include/imximage.h b/include/imximage.h
index 544babb..ace5cf8 100644
--- a/include/imximage.h
+++ b/include/imximage.h
@@ -79,6 +79,7 @@
 	CMD_LOADER,
 	CMD_SECOND_LOADER,
 	CMD_DDR_FW,
+	CMD_ROM_VERSION,
 };
 
 enum imximage_fld_types {
diff --git a/include/tee/optee.h b/include/tee/optee.h
index 9446928f..121b30a 100644
--- a/include/tee/optee.h
+++ b/include/tee/optee.h
@@ -67,4 +67,13 @@
 }
 #endif
 
+#if defined(CONFIG_OPTEE) && defined(CONFIG_OF_LIBFDT)
+int optee_copy_fdt_nodes(const void *old_blob, void *new_blob);
+#else
+static inline int optee_copy_fdt_nodes(const void *old_blob, void *new_blob)
+{
+	return 0;
+}
+#endif
+
 #endif /* _OPTEE_H */
diff --git a/include/test/optee.h b/include/test/optee.h
new file mode 100644
index 0000000..a8c6e63
--- /dev/null
+++ b/include/test/optee.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2019, Theobroma Systems Design und Consulting GmbH
+ */
+
+#ifndef __TEST_OPTEE_H__
+#define __TEST_OPTEE_H__
+
+#include <test/test.h>
+
+/* Declare a new environment test */
+#define OPTEE_TEST(_name, _flags)	UNIT_TEST(_name, _flags, optee_test)
+
+#endif /* __TEST_OPTEE_H__ */
diff --git a/include/test/suites.h b/include/test/suites.h
index 01bee09..20970f0 100644
--- a/include/test/suites.h
+++ b/include/test/suites.h
@@ -28,6 +28,7 @@
 int do_ut_dm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
 int do_ut_env(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
 int do_ut_lib(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+int do_ut_optee(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
 int do_ut_overlay(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
 int do_ut_time(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
 int do_ut_unicode(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
diff --git a/include/usb/dwc2_udc.h b/include/usb/dwc2_udc.h
index a6c1221..a2af381 100644
--- a/include/usb/dwc2_udc.h
+++ b/include/usb/dwc2_udc.h
@@ -8,12 +8,14 @@
 #ifndef __DWC2_USB_GADGET
 #define __DWC2_USB_GADGET
 
+#include <dm/ofnode.h>
+
 #define PHY0_SLEEP              (1 << 5)
 #define DWC2_MAX_HW_ENDPOINTS	16
 
 struct dwc2_plat_otg_data {
 	void		*priv;
-	int		phy_of_node;
+	ofnode		phy_of_node;
 	int		(*phy_control)(int on);
 	uintptr_t	regs_phy;
 	uintptr_t	regs_otg;
diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile
index 01769ea..7db4060 100644
--- a/lib/efi_loader/Makefile
+++ b/lib/efi_loader/Makefile
@@ -6,6 +6,9 @@
 # This file only gets included with CONFIG_EFI_LOADER set, so all
 # object inclusion implicitly depends on it
 
+asflags-y += -DHOST_ARCH="$(HOST_ARCH)"
+ccflags-y += -DHOST_ARCH="$(HOST_ARCH)"
+
 CFLAGS_efi_boottime.o += \
   -DFW_VERSION="0x$(VERSION)" \
   -DFW_PATCHLEVEL="0x$(PATCHLEVEL)"
diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c
index ac5e6f7..17a0c5b 100644
--- a/lib/efi_loader/efi_device_path.c
+++ b/lib/efi_loader/efi_device_path.c
@@ -1032,6 +1032,16 @@
 	return EFI_SUCCESS;
 }
 
+/**
+ * efi_dp_from_name() - convert U-Boot device and file path to device path
+ *
+ * @dev:	U-Boot device, e.g. 'mmc'
+ * @devnr:	U-Boot device number, e.g. 1 for 'mmc:1'
+ * @path:	file path relative to U-Boot device, may be NULL
+ * @device:	pointer to receive device path of the device
+ * @file:	pointer to receive device path for the file
+ * Return:	status code
+ */
 efi_status_t efi_dp_from_name(const char *dev, const char *devnr,
 			      const char *path,
 			      struct efi_device_path **device,
@@ -1071,10 +1081,9 @@
 	s = filename;
 	while ((s = strchr(s, '/')))
 		*s++ = '\\';
-	*file = efi_dp_from_file(((!is_net && device) ? desc : NULL),
-				 part, filename);
+	*file = efi_dp_from_file(is_net ? NULL : desc, part, filename);
 
-	if (!file)
+	if (!*file)
 		return EFI_INVALID_PARAMETER;
 
 	return EFI_SUCCESS;
diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c
index 861fcaf..ed7fb3f 100644
--- a/lib/efi_loader/efi_disk.c
+++ b/lib/efi_loader/efi_disk.c
@@ -337,7 +337,9 @@
 			       diskobj->dp);
 	if (ret != EFI_SUCCESS)
 		return ret;
-	if (part >= 1 && efi_fs_exists(desc, part)) {
+	/* partitions or whole disk without partitions */
+	if ((part || desc->part_type == PART_TYPE_UNKNOWN) &&
+	    efi_fs_exists(desc, part)) {
 		diskobj->volume = efi_simple_file_system(desc, part,
 							 diskobj->dp);
 		ret = efi_add_protocol(&diskobj->header,
diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c
index 83cbc91..d46001f 100644
--- a/lib/efi_loader/efi_memory.c
+++ b/lib/efi_loader/efi_memory.c
@@ -738,8 +738,10 @@
 	unsigned long uboot_stack_size = 16 * 1024 * 1024;
 
 	/* Add U-Boot */
-	uboot_start = (gd->start_addr_sp - uboot_stack_size) & ~EFI_PAGE_MASK;
-	uboot_pages = (gd->ram_top - uboot_start) >> EFI_PAGE_SHIFT;
+	uboot_start = ((uintptr_t)map_sysmem(gd->start_addr_sp, 0) -
+		       uboot_stack_size) & ~EFI_PAGE_MASK;
+	uboot_pages = ((uintptr_t)map_sysmem(gd->ram_top - 1, 0) -
+		       uboot_start + EFI_PAGE_MASK) >> EFI_PAGE_SHIFT;
 	efi_add_memory_map(uboot_start, uboot_pages, EFI_LOADER_DATA, false);
 
 #if defined(__aarch64__)
@@ -767,8 +769,7 @@
 {
 	efi_add_known_memory();
 
-	if (!IS_ENABLED(CONFIG_SANDBOX))
-		add_u_boot_and_runtime();
+	add_u_boot_and_runtime();
 
 #ifdef CONFIG_EFI_LOADER_BOUNCE_BUFFER
 	/* Request a 32bit 64MB bounce buffer region */
diff --git a/lib/efi_selftest/Makefile b/lib/efi_selftest/Makefile
index 8348014..487cb4c 100644
--- a/lib/efi_selftest/Makefile
+++ b/lib/efi_selftest/Makefile
@@ -5,6 +5,9 @@
 # This file only gets included with CONFIG_EFI_LOADER set, so all
 # object inclusion implicitly depends on it
 
+asflags-y += -DHOST_ARCH="$(HOST_ARCH)"
+ccflags-y += -DHOST_ARCH="$(HOST_ARCH)"
+
 CFLAGS_efi_selftest_miniapp_exit.o := $(CFLAGS_EFI) -Os -ffreestanding
 CFLAGS_REMOVE_efi_selftest_miniapp_exit.o := $(CFLAGS_NON_EFI)
 CFLAGS_efi_selftest_miniapp_return.o := $(CFLAGS_EFI) -Os -ffreestanding
@@ -55,8 +58,8 @@
 endif
 
 # TODO: As of v2019.10 the relocation code for the EFI application cannot
-# be built on ARMv7-M and Sandbox.
-ifeq ($(CONFIG_SANDBOX)$(CONFIG_CPU_V7M),)
+# be built on ARMv7-M.
+ifeq ($(CONFIG_CPU_V7M),)
 
 obj-y += \
 efi_selftest_exception.o \
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index 125d9db..61af347 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -1309,7 +1309,8 @@
 		}
 
 		if (addr == carveout->start && (addr + size) == carveout->end) {
-			*phandlep = fdt_get_phandle(blob, node);
+			if (phandlep)
+				*phandlep = fdt_get_phandle(blob, node);
 			return 0;
 		}
 	}
@@ -1338,13 +1339,15 @@
 	if (node < 0)
 		return node;
 
-	err = fdt_generate_phandle(blob, &phandle);
-	if (err < 0)
-		return err;
+	if (phandlep) {
+		err = fdt_generate_phandle(blob, &phandle);
+		if (err < 0)
+			return err;
 
-	err = fdtdec_set_phandle(blob, node, phandle);
-	if (err < 0)
-		return err;
+		err = fdtdec_set_phandle(blob, node, phandle);
+		if (err < 0)
+			return err;
+	}
 
 	/* store one or two address cells */
 	if (na > 1)
diff --git a/lib/optee/optee.c b/lib/optee/optee.c
index db92cd9..c883c49 100644
--- a/lib/optee/optee.c
+++ b/lib/optee/optee.c
@@ -5,6 +5,8 @@
  */
 
 #include <common.h>
+#include <malloc.h>
+#include <linux/libfdt.h>
 #include <tee/optee.h>
 
 #define optee_hdr_err_msg \
@@ -63,3 +65,141 @@
 
 	return ret;
 }
+
+#if defined(CONFIG_OF_LIBFDT)
+static int optee_copy_firmware_node(const void *old_blob, void *fdt_blob)
+{
+	int old_offs, offs, ret, len;
+	const void *prop;
+
+	old_offs = fdt_path_offset(old_blob, "/firmware/optee");
+	if (old_offs < 0) {
+		debug("Original OP-TEE Device Tree node not found");
+		return old_offs;
+	}
+
+	offs = fdt_path_offset(fdt_blob, "/firmware");
+	if (offs < 0) {
+		offs = fdt_path_offset(fdt_blob, "/");
+		if (offs < 0)
+			return offs;
+
+		offs = fdt_add_subnode(fdt_blob, offs, "firmware");
+		if (offs < 0)
+			return offs;
+	}
+
+	offs = fdt_add_subnode(fdt_blob, offs, "optee");
+	if (offs < 0)
+		return ret;
+
+	/* copy the compatible property */
+	prop = fdt_getprop(old_blob, old_offs, "compatible", &len);
+	if (!prop) {
+		debug("missing OP-TEE compatible property");
+		return -EINVAL;
+	}
+
+	ret = fdt_setprop(fdt_blob, offs, "compatible", prop, len);
+	if (ret < 0)
+		return ret;
+
+	/* copy the method property */
+	prop = fdt_getprop(old_blob, old_offs, "method", &len);
+	if (!prop) {
+		debug("missing OP-TEE method property");
+		return -EINVAL;
+	}
+
+	ret = fdt_setprop(fdt_blob, offs, "method", prop, len);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+int optee_copy_fdt_nodes(const void *old_blob, void *new_blob)
+{
+	int nodeoffset, subnode, ret;
+	struct fdt_resource res;
+
+	if (fdt_check_header(old_blob))
+		return -EINVAL;
+
+	if (fdt_check_header(new_blob))
+		return -EINVAL;
+
+	/* only proceed if there is an /firmware/optee node */
+	if (fdt_path_offset(old_blob, "/firmware/optee") < 0) {
+		debug("No OP-TEE firmware node in old fdt, nothing to do");
+		return 0;
+	}
+
+	/*
+	 * Do not proceed if the target dt already has an OP-TEE node.
+	 * In this case assume that the system knows better somehow,
+	 * so do not interfere.
+	 */
+	if (fdt_path_offset(new_blob, "/firmware/optee") >= 0) {
+		debug("OP-TEE Device Tree node already exists in target");
+		return 0;
+	}
+
+	ret = optee_copy_firmware_node(old_blob, new_blob);
+	if (ret < 0) {
+		printf("Failed to add OP-TEE firmware node\n");
+		return ret;
+	}
+
+	/* optee inserts its memory regions as reserved-memory nodes */
+	nodeoffset = fdt_subnode_offset(old_blob, 0, "reserved-memory");
+	if (nodeoffset >= 0) {
+		subnode = fdt_first_subnode(old_blob, nodeoffset);
+		while (subnode >= 0) {
+			const char *name = fdt_get_name(old_blob,
+							subnode, NULL);
+			if (!name)
+				return -EINVAL;
+
+			/* only handle optee reservations */
+			if (strncmp(name, "optee", 5))
+				continue;
+
+			/* check if this subnode has a reg property */
+			ret = fdt_get_resource(old_blob, subnode, "reg", 0,
+					       &res);
+			if (!ret) {
+				struct fdt_memory carveout = {
+					.start = res.start,
+					.end = res.end,
+				};
+				char *oldname, *nodename, *tmp;
+
+				oldname = strdup(name);
+				if (!oldname)
+					return -ENOMEM;
+
+				tmp = oldname;
+				nodename = strsep(&tmp, "@");
+				if (!nodename) {
+					free(oldname);
+					return -EINVAL;
+				}
+
+				ret = fdtdec_add_reserved_memory(new_blob,
+								 nodename,
+								 &carveout,
+								 NULL);
+				free(oldname);
+
+				if (ret < 0)
+					return ret;
+			}
+
+			subnode = fdt_next_subnode(old_blob, subnode);
+		}
+	}
+
+	return 0;
+}
+#endif
diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl
index f8ce7da..314b02b 100644
--- a/scripts/Makefile.spl
+++ b/scripts/Makefile.spl
@@ -71,7 +71,11 @@
 libs-y += $(if $(BOARDDIR),board/$(BOARDDIR)/)
 libs-$(HAVE_VENDOR_COMMON_LIB) += board/$(VENDOR)/common/
 
+ifeq ($(CONFIG_TPL_BUILD),y)
+libs-$(CONFIG_TPL_FRAMEWORK) += common/spl/
+else
 libs-$(CONFIG_SPL_FRAMEWORK) += common/spl/
+endif
 libs-y += common/init/
 
 # Special handling for a few options which support SPL/TPL
diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt
index bbc1cb1..b680c554 100644
--- a/scripts/config_whitelist.txt
+++ b/scripts/config_whitelist.txt
@@ -3756,7 +3756,6 @@
 CONFIG_SYS_RCAR_I2C3_BASE
 CONFIG_SYS_RCWH_PCIHOST
 CONFIG_SYS_READ_SPD
-CONFIG_SYS_REDUNDAND_ENVIRONMENT
 CONFIG_SYS_RESET_ADDR
 CONFIG_SYS_RESET_ADDRESS
 CONFIG_SYS_RESET_SCTRL
diff --git a/test/Kconfig b/test/Kconfig
index 48a0e50..f53629a 100644
--- a/test/Kconfig
+++ b/test/Kconfig
@@ -33,4 +33,5 @@
 
 source "test/dm/Kconfig"
 source "test/env/Kconfig"
+source "test/optee/Kconfig"
 source "test/overlay/Kconfig"
diff --git a/test/cmd_ut.c b/test/cmd_ut.c
index e3b8950..2781f8b 100644
--- a/test/cmd_ut.c
+++ b/test/cmd_ut.c
@@ -43,6 +43,9 @@
 #if defined(CONFIG_UT_ENV)
 	U_BOOT_CMD_MKENT(env, CONFIG_SYS_MAXARGS, 1, do_ut_env, "", ""),
 #endif
+#ifdef CONFIG_UT_OPTEE
+	U_BOOT_CMD_MKENT(optee, CONFIG_SYS_MAXARGS, 1, do_ut_optee, "", ""),
+#endif
 #ifdef CONFIG_UT_OVERLAY
 	U_BOOT_CMD_MKENT(overlay, CONFIG_SYS_MAXARGS, 1, do_ut_overlay, "", ""),
 #endif
@@ -114,6 +117,9 @@
 #ifdef CONFIG_UT_LIB
 	"ut lib [test-name] - test library functions\n"
 #endif
+#ifdef CONFIG_UT_OPTEE
+	"ut optee [test-name]\n"
+#endif
 #ifdef CONFIG_UT_OVERLAY
 	"ut overlay [test-name]\n"
 #endif
diff --git a/test/optee/Kconfig b/test/optee/Kconfig
new file mode 100644
index 0000000..2f6834a
--- /dev/null
+++ b/test/optee/Kconfig
@@ -0,0 +1,7 @@
+config UT_OPTEE
+	bool "Enable OP-TEE Unit Tests"
+	depends on UNIT_TEST && OF_CONTROL && OPTEE
+	default y
+	help
+	  This enables the 'ut optee' command which runs a series of unit
+	  tests on the optee library code..
diff --git a/test/optee/Makefile b/test/optee/Makefile
new file mode 100644
index 0000000..8793fd7
--- /dev/null
+++ b/test/optee/Makefile
@@ -0,0 +1,13 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2019, Theobroma Systems Design und Consulting GmbH
+
+# Test files
+obj-y += cmd_ut_optee.o
+
+DTC_FLAGS += -@
+
+# DT overlays
+obj-y += test-optee-base.dtb.o
+obj-y += test-optee-optee.dtb.o
+obj-y += test-optee-no-optee.dtb.o
diff --git a/test/optee/cmd_ut_optee.c b/test/optee/cmd_ut_optee.c
new file mode 100644
index 0000000..670682f
--- /dev/null
+++ b/test/optee/cmd_ut_optee.c
@@ -0,0 +1,149 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019, Theobroma Systems Design und Consulting GmbH
+ */
+
+#include <common.h>
+#include <command.h>
+#include <errno.h>
+#include <fdt_support.h>
+#include <malloc.h>
+#include <tee/optee.h>
+
+#include <linux/sizes.h>
+
+#include <test/ut.h>
+#include <test/optee.h>
+#include <test/suites.h>
+
+/* 4k ought to be enough for anybody */
+#define FDT_COPY_SIZE	(4 * SZ_1K)
+
+extern u32 __dtb_test_optee_base_begin;
+extern u32 __dtb_test_optee_optee_begin;
+extern u32 __dtb_test_optee_no_optee_begin;
+
+static void *fdt;
+static bool expect_success;
+
+static int optee_fdt_firmware(struct unit_test_state *uts)
+{
+	const void *prop;
+	int offs, len;
+
+	offs = fdt_path_offset(fdt, "/firmware/optee");
+	ut_assert(expect_success ? offs >= 0 : offs < 0);
+
+	/* only continue if we have an optee node */
+	if (offs < 0)
+		return CMD_RET_SUCCESS;
+
+	prop = fdt_getprop(fdt, offs, "compatible", &len);
+	ut_assertok(strncmp((const char *)prop, "linaro,optee-tz", len));
+
+	prop = fdt_getprop(fdt, offs, "method", &len);
+	ut_assert(strncmp(prop, "hvc", 3) == 0 || strncmp(prop, "smc", 3) == 0);
+
+	return CMD_RET_SUCCESS;
+}
+OPTEE_TEST(optee_fdt_firmware, 0);
+
+static int optee_fdt_protected_memory(struct unit_test_state *uts)
+{
+	int offs, subnode;
+	bool found;
+
+	offs = fdt_path_offset(fdt, "/firmware/optee");
+	ut_assert(expect_success ? offs >= 0 : offs < 0);
+
+	/* only continue if we have an optee node */
+	if (offs < 0)
+		return CMD_RET_SUCCESS;
+
+	/* optee inserts its memory regions as reserved-memory nodes */
+	offs = fdt_subnode_offset(fdt, 0, "reserved-memory");
+	ut_assert(offs >= 0);
+
+	subnode = fdt_first_subnode(fdt, offs);
+	ut_assert(subnode);
+
+	found = 0;
+	while (subnode >= 0) {
+		const char *name = fdt_get_name(fdt, subnode, NULL);
+		struct fdt_resource res;
+
+		ut_assert(name);
+
+		/* only handle optee reservations */
+		if (strncmp(name, "optee", 5))
+			continue;
+
+		found = true;
+
+		/* check if this subnode has a reg property */
+		ut_assertok(fdt_get_resource(fdt, subnode, "reg", 0, &res));
+		subnode = fdt_next_subnode(fdt, subnode);
+	}
+
+	ut_assert(found);
+
+	return CMD_RET_SUCCESS;
+}
+OPTEE_TEST(optee_fdt_protected_memory, 0);
+
+int do_ut_optee(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	struct unit_test *tests = ll_entry_start(struct unit_test,
+						 optee_test);
+	const int n_ents = ll_entry_count(struct unit_test, optee_test);
+	struct unit_test_state *uts;
+	void *fdt_optee = &__dtb_test_optee_optee_begin;
+	void *fdt_no_optee = &__dtb_test_optee_no_optee_begin;
+	void *fdt_base = &__dtb_test_optee_base_begin;
+	int ret = -ENOMEM;
+
+	uts = calloc(1, sizeof(*uts));
+	if (!uts)
+		return -ENOMEM;
+
+	ut_assertok(fdt_check_header(fdt_base));
+	ut_assertok(fdt_check_header(fdt_optee));
+	ut_assertok(fdt_check_header(fdt_no_optee));
+
+	fdt = malloc(FDT_COPY_SIZE);
+	if (!fdt)
+		return ret;
+
+	/*
+	 * Resize the FDT to 4k so that we have room to operate on
+	 *
+	 * (and relocate it since the memory might be mapped
+	 * read-only)
+	 */
+	ut_assertok(fdt_open_into(fdt_base, fdt, FDT_COPY_SIZE));
+
+	/*
+	 * (1) Try to copy optee nodes from empty dt.
+	 * This should still run successfully.
+	 */
+	ut_assertok(optee_copy_fdt_nodes(fdt_no_optee, fdt));
+
+	expect_success = false;
+	ret = cmd_ut_category("optee", tests, n_ents, argc, argv);
+
+	/* (2) Try to copy optee nodes from prefilled dt */
+	ut_assertok(optee_copy_fdt_nodes(fdt_optee, fdt));
+
+	expect_success = true;
+	ret = cmd_ut_category("optee", tests, n_ents, argc, argv);
+
+	/* (3) Try to copy OP-TEE nodes into a already filled DT */
+	ut_assertok(fdt_open_into(fdt_optee, fdt, FDT_COPY_SIZE));
+	ut_assertok(optee_copy_fdt_nodes(fdt_optee, fdt));
+
+	expect_success = true;
+	ret = cmd_ut_category("optee", tests, n_ents, argc, argv);
+
+	free(fdt);
+	return ret;
+}
diff --git a/test/optee/test-optee-base.dts b/test/optee/test-optee-base.dts
new file mode 100644
index 0000000..3c1d0c6
--- /dev/null
+++ b/test/optee/test-optee-base.dts
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019, Theobroma Systems Design und Consulting GmbH
+ */
+
+/dts-v1/;
+
+/ {
+	#address-cells = <2>;
+	#size-cells = <2>;
+};
+
+
diff --git a/test/optee/test-optee-no-optee.dts b/test/optee/test-optee-no-optee.dts
new file mode 100644
index 0000000..3c1d0c6
--- /dev/null
+++ b/test/optee/test-optee-no-optee.dts
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019, Theobroma Systems Design und Consulting GmbH
+ */
+
+/dts-v1/;
+
+/ {
+	#address-cells = <2>;
+	#size-cells = <2>;
+};
+
+
diff --git a/test/optee/test-optee-optee.dts b/test/optee/test-optee-optee.dts
new file mode 100644
index 0000000..11e26a2
--- /dev/null
+++ b/test/optee/test-optee-optee.dts
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019, Theobroma Systems Design und Consulting GmbH
+ */
+
+/dts-v1/;
+
+/ {
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	firmware {
+		optee {
+			compatible = "linaro,optee-tz";
+			method = "smc";
+		};
+	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		optee_shm@32000000 {
+			reg = <0x00 0x32000000 0x00 0x400000>;
+		};
+
+		optee_core@30000000 {
+			reg = <0x00 0x30000000 0x00 0x2000000>;
+		};
+	};
+};
diff --git a/tools/envcrc.c b/tools/envcrc.c
index 672ef4d..9577682 100644
--- a/tools/envcrc.c
+++ b/tools/envcrc.c
@@ -40,9 +40,6 @@
      ((CONFIG_ENV_ADDR + CONFIG_ENV_SIZE) <= (CONFIG_SYS_MONITOR_BASE + CONFIG_SYS_MONITOR_LEN))
 #  define ENV_IS_EMBEDDED
 # endif
-# if defined(CONFIG_ENV_ADDR_REDUND) || defined(CONFIG_ENV_OFFSET_REDUND)
-#  define CONFIG_SYS_REDUNDAND_ENVIRONMENT
-# endif
 #endif	/* CONFIG_ENV_IS_IN_FLASH */
 
 #if defined(ENV_IS_EMBEDDED) && !defined(CONFIG_BUILD_ENVCRC)
diff --git a/tools/imx8m_image.sh b/tools/imx8m_image.sh
index 08a6a48..603ba6e 100755
--- a/tools/imx8m_image.sh
+++ b/tools/imx8m_image.sh
@@ -39,6 +39,16 @@
 		cat spl/u-boot-spl-pad.bin lpddr4_pmu_train_1d_fw.bin lpddr4_pmu_train_2d_fw.bin > spl/u-boot-spl-ddr.bin
 		rm -f lpddr4_pmu_train_1d_fw.bin lpddr4_pmu_train_2d_fw.bin lpddr4_pmu_train_1d_imem_pad.bin lpddr4_pmu_train_1d_dmem_pad.bin lpddr4_pmu_train_2d_imem_pad.bin spl/u-boot-spl-pad.bin
 	fi
+	if [ -f $srctree/ddr4_imem_1d.bin ]; then
+		objcopy -I binary -O binary --pad-to 0x8000 --gap-fill=0x0 $srctree/ddr4_imem_1d.bin ddr4_imem_1d_pad.bin
+		objcopy -I binary -O binary --pad-to 0x4000 --gap-fill=0x0 $srctree/ddr4_dmem_1d.bin ddr4_dmem_1d_pad.bin
+		objcopy -I binary -O binary --pad-to 0x8000 --gap-fill=0x0 $srctree/ddr4_imem_2d.bin ddr4_imem_2d_pad.bin
+		cat ddr4_imem_1d_pad.bin ddr4_dmem_1d_pad.bin > ddr4_1d_fw.bin
+		cat ddr4_imem_2d_pad.bin $srctree/ddr4_dmem_2d.bin > ddr4_2d_fw.bin
+		dd if=spl/u-boot-spl.bin of=spl/u-boot-spl-pad.bin bs=4 conv=sync
+		cat spl/u-boot-spl-pad.bin ddr4_1d_fw.bin ddr4_2d_fw.bin > spl/u-boot-spl-ddr.bin
+		rm -f ddr4_1d_fw.bin ddr4_2d_fw.bin ddr4_imem_1d_pad.bin ddr4_dmem_1d_pad.bin ddr4_imem_2d_pad.bin spl/u-boot-spl-pad.bin
+	fi
 fi
 
 exit 0
diff --git a/tools/imx8mimage.c b/tools/imx8mimage.c
index 6c02337..2b0d946 100644
--- a/tools/imx8mimage.c
+++ b/tools/imx8mimage.c
@@ -21,6 +21,11 @@
 static uint32_t ivt_offset;
 static uint32_t using_fit;
 
+#define ROM_V1 1
+#define ROM_V2 2
+
+static uint32_t rom_version = ROM_V1;
+
 #define CSF_SIZE 0x2000
 #define HDMI_IVT_ID 0
 #define IMAGE_IVT_ID 1
@@ -71,6 +76,7 @@
 	{CMD_LOADER,            "LOADER",               "loader image",       },
 	{CMD_SECOND_LOADER,     "SECOND_LOADER",        "2nd loader image",   },
 	{CMD_DDR_FW,            "DDR_FW",               "ddr firmware",       },
+	{CMD_ROM_VERSION,       "ROM_VERSION",          "rom version",        },
 	{-1,                    "",                     "",	              },
 };
 
@@ -90,6 +96,9 @@
 						token);
 		if (!strncmp(token, "sd", 2))
 			rom_image_offset = 0x8000;
+
+		if (rom_version == ROM_V2)
+			ivt_offset = 0;
 		break;
 	case CMD_LOADER:
 		ap_img = token;
@@ -103,6 +112,15 @@
 	case CMD_DDR_FW:
 		/* Do nothing */
 		break;
+	case CMD_ROM_VERSION:
+		if (!strncmp(token, "v2", 2)) {
+			rom_version = ROM_V2;
+			ivt_offset = 0;
+		} else if (!strncmp(token, "v1", 2)) {
+			rom_version = ROM_V1;
+		}
+		break;
+
 	}
 }
 
@@ -491,8 +509,10 @@
 			 * Record the second bootloader relative offset in
 			 * image's IVT reserved1
 			 */
-			imx_header[IMAGE_IVT_ID].fhdr.reserved1 =
-				sld_header_off - header_image_off;
+			if (rom_version == ROM_V1) {
+				imx_header[IMAGE_IVT_ID].fhdr.reserved1 =
+					sld_header_off - header_image_off;
+			}
 			sld_fd = open(sld_img, O_RDONLY | O_BINARY);
 			if (sld_fd < 0) {
 				fprintf(stderr, "%s: Can't open: %s\n",
diff --git a/tools/patman/cros_subprocess.py b/tools/patman/cros_subprocess.py
index 0f0d60d..efd0a5a 100644
--- a/tools/patman/cros_subprocess.py
+++ b/tools/patman/cros_subprocess.py
@@ -6,11 +6,11 @@
 # Licensed to PSF under a Contributor Agreement.
 # See http://www.python.org/2.4/license for licensing details.
 
-"""Subprocress execution
+"""Subprocess execution
 
 This module holds a subclass of subprocess.Popen with our own required
 features, mainly that we get access to the subprocess output while it
-is running rather than just at the end. This makes it easiler to show
+is running rather than just at the end. This makes it easier to show
 progress information and filter output in real time.
 """
 
diff --git a/tools/patman/gitutil.py b/tools/patman/gitutil.py
index dce7fa2..a2a225c 100644
--- a/tools/patman/gitutil.py
+++ b/tools/patman/gitutil.py
@@ -23,7 +23,7 @@
 
     Args:
         commit_range: Range expression to use for log, None for none
-        git_dir: Path to git repositiory (None to use default)
+        git_dir: Path to git repository (None to use default)
         oneline: True to use --oneline, else False
         reverse: True to reverse the log (--reverse)
         count: Number of commits to list, or None for no limit
@@ -166,7 +166,7 @@
         git_dir: Directory containing git repo
         range_expr: Range to check
     Return:
-        Number of patches that exist in the supplied rangem or None if none
+        Number of patches that exist in the supplied range or None if none
         were found
     """
     pipe = [LogCmd(range_expr, git_dir=git_dir, oneline=True)]
diff --git a/tools/patman/series.py b/tools/patman/series.py
index 02a1113..a15f762 100644
--- a/tools/patman/series.py
+++ b/tools/patman/series.py
@@ -251,7 +251,7 @@
             cover_cc = [tools.FromUnicode(m) for m in cover_cc]
             cc_list = '\0'.join([tools.ToUnicode(x)
                                  for x in sorted(set(cover_cc + all_ccs))])
-            print(cover_fname, cc_list.encode('utf-8'), file=fd)
+            print(cover_fname, cc_list, file=fd)
 
         fd.close()
         return fname
diff --git a/tools/patman/terminal.py b/tools/patman/terminal.py
index 4ceab18..7a3b658 100644
--- a/tools/patman/terminal.py
+++ b/tools/patman/terminal.py
@@ -128,7 +128,7 @@
         return ''
 
     def Stop(self):
-        """Retruns a stop color code.
+        """Returns a stop color code.
 
         Returns:
           If color is enabled, returns an ANSI color reset sequence,
diff --git a/tools/rkcommon.c b/tools/rkcommon.c
index 831c2ad..0d908da 100644
--- a/tools/rkcommon.c
+++ b/tools/rkcommon.c
@@ -67,11 +67,13 @@
 };
 
 static struct spl_info spl_infos[] = {
+	{ "px30", "RK33", 0x2800, false },
 	{ "rk3036", "RK30", 0x1000, false },
 	{ "rk3128", "RK31", 0x1800, false },
 	{ "rk3188", "RK31", 0x8000 - 0x800, true },
 	{ "rk322x", "RK32", 0x8000 - 0x1000, false },
 	{ "rk3288", "RK32", 0x8000, false },
+	{ "rk3308", "RK33", 0x40000 - 0x1000, false},
 	{ "rk3328", "RK32", 0x8000 - 0x1000, false },
 	{ "rk3368", "RK33", 0x8000 - 0x1000, false },
 	{ "rk3399", "RK33", 0x30000 - 0x2000, false },