Merge tag 'rockchip-for-v2019.07' of https://gitlab.denx.de/u-boot/custodians/u-boot-rockchip

- rk3399 lpddr4 support
- rk3399-rock960 board support improvement
- Eliminate pyelftools dependency by make_fit_atf.py
- clean up rockchip dts to use -u-boot.dtsi
- use ARM arch/generic timer instead of rk_timer
- clean up Kconfig options for board support
diff --git a/arch/arm/dts/rk3288-evb-u-boot.dtsi b/arch/arm/dts/rk3288-evb-u-boot.dtsi
new file mode 100644
index 0000000..8ac7840
--- /dev/null
+++ b/arch/arm/dts/rk3288-evb-u-boot.dtsi
@@ -0,0 +1,46 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 Rockchip Electronics Co., Ltd
+ */
+
+#include "rk3288-u-boot.dtsi"
+
+&pinctrl {
+	u-boot,dm-pre-reloc;
+};
+
+&uart2 {
+	u-boot,dm-pre-reloc;
+};
+
+&sdmmc {
+	u-boot,dm-pre-reloc;
+};
+
+&emmc {
+	u-boot,dm-pre-reloc;
+};
+
+&gpio3 {
+	u-boot,dm-pre-reloc;
+};
+
+&gpio8 {
+	u-boot,dm-pre-reloc;
+};
+
+&sdmmc_bus4 {
+	u-boot,dm-spl;
+};
+
+&sdmmc_clk {
+	u-boot,dm-spl;
+};
+
+&sdmmc_cmd {
+	u-boot,dm-spl;
+};
+
+&sdmmc_pwr {
+	u-boot,dm-spl;
+};
diff --git a/arch/arm/dts/rk3288-evb.dts b/arch/arm/dts/rk3288-evb.dts
index 575de44..eac91a8 100644
--- a/arch/arm/dts/rk3288-evb.dts
+++ b/arch/arm/dts/rk3288-evb.dts
@@ -26,31 +26,6 @@
 	rockchip,sdram-params = <0x20d266a4 0x5b6 2 533000000 6 9 0>;
 };
 
-&pinctrl {
-	u-boot,dm-pre-reloc;
-};
-
 &pwm1 {
 	status = "okay";
 };
-
-&uart2 {
-	u-boot,dm-pre-reloc;
-	reg-shift = <2>;
-};
-
-&sdmmc {
-	u-boot,dm-pre-reloc;
-};
-
-&emmc {
-	u-boot,dm-pre-reloc;
-};
-
-&gpio3 {
-	u-boot,dm-pre-reloc;
-};
-
-&gpio8 {
-	u-boot,dm-pre-reloc;
-};
diff --git a/arch/arm/dts/rk3288-fennec-u-boot.dtsi b/arch/arm/dts/rk3288-fennec-u-boot.dtsi
new file mode 100644
index 0000000..2efb309
--- /dev/null
+++ b/arch/arm/dts/rk3288-fennec-u-boot.dtsi
@@ -0,0 +1,54 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 Rockchip Electronics Co., Ltd
+ */
+
+#include "rk3288-u-boot.dtsi"
+
+&pinctrl {
+	u-boot,dm-pre-reloc;
+};
+
+&uart2 {
+	u-boot,dm-pre-reloc;
+};
+
+&sdmmc {
+	u-boot,dm-pre-reloc;
+};
+
+&emmc {
+	u-boot,dm-pre-reloc;
+};
+
+&gpio3 {
+	u-boot,dm-pre-reloc;
+};
+
+&gpio8 {
+	u-boot,dm-pre-reloc;
+};
+
+&pcfg_pull_none_drv_8ma {
+	u-boot,dm-spl;
+};
+
+&pcfg_pull_up_drv_8ma {
+	u-boot,dm-spl;
+};
+
+&sdmmc_bus4 {
+	u-boot,dm-spl;
+};
+
+&sdmmc_clk {
+	u-boot,dm-spl;
+};
+
+&sdmmc_cmd {
+	u-boot,dm-spl;
+};
+
+&sdmmc_pwr {
+	u-boot,dm-spl;
+};
diff --git a/arch/arm/dts/rk3288-fennec.dts b/arch/arm/dts/rk3288-fennec.dts
index b569307..e1d55e3 100644
--- a/arch/arm/dts/rk3288-fennec.dts
+++ b/arch/arm/dts/rk3288-fennec.dts
@@ -26,31 +26,6 @@
 	rockchip,sdram-params = <0x20d266a4 0x5b6 2 533000000 6 9 0>;
 };
 
-&pinctrl {
-	u-boot,dm-pre-reloc;
-};
-
 &pwm1 {
 	status = "okay";
 };
-
-&uart2 {
-	u-boot,dm-pre-reloc;
-	reg-shift = <2>;
-};
-
-&sdmmc {
-	u-boot,dm-pre-reloc;
-};
-
-&emmc {
-	u-boot,dm-pre-reloc;
-};
-
-&gpio3 {
-	u-boot,dm-pre-reloc;
-};
-
-&gpio8 {
-	u-boot,dm-pre-reloc;
-};
diff --git a/arch/arm/dts/rk3288-firefly-u-boot.dtsi b/arch/arm/dts/rk3288-firefly-u-boot.dtsi
new file mode 100644
index 0000000..8b9c383
--- /dev/null
+++ b/arch/arm/dts/rk3288-firefly-u-boot.dtsi
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 Rockchip Electronics Co., Ltd
+ */
+
+#include "rk3288-u-boot.dtsi"
+
+&pinctrl {
+	u-boot,dm-pre-reloc;
+};
+
+&uart2 {
+	u-boot,dm-pre-reloc;
+};
+
+&sdmmc {
+	u-boot,dm-pre-reloc;
+};
+
+&emmc {
+	u-boot,dm-pre-reloc;
+};
+
+&gpio3 {
+	u-boot,dm-pre-reloc;
+};
+
+&gpio8 {
+	u-boot,dm-pre-reloc;
+};
+
+&pcfg_pull_up_drv_12ma {
+	u-boot,dm-spl;
+};
+
+&sdmmc_bus4 {
+	u-boot,dm-spl;
+};
+
+&sdmmc_clk {
+	u-boot,dm-spl;
+};
+
+&sdmmc_cmd {
+	u-boot,dm-spl;
+};
+
+&sdmmc_pwr {
+	u-boot,dm-spl;
+};
diff --git a/arch/arm/dts/rk3288-firefly.dts b/arch/arm/dts/rk3288-firefly.dts
index 2e075406..1cff04e 100644
--- a/arch/arm/dts/rk3288-firefly.dts
+++ b/arch/arm/dts/rk3288-firefly.dts
@@ -37,7 +37,6 @@
 };
 
 &pinctrl {
-	u-boot,dm-pre-reloc;
 	act8846 {
 		pmic_vsel: pmic-vsel {
 			rockchip,pins = <7 14 RK_FUNC_GPIO &pcfg_output_low>;
@@ -59,25 +58,3 @@
 &pwm1 {
 	status = "okay";
 };
-
-&uart2 {
-	u-boot,dm-pre-reloc;
-	reg-shift = <2>;
-};
-
-&usb_host1 {
-	vbus-supply = <&vcc_host_5v>;
-	status = "okay";
-};
-
-&sdmmc {
-	u-boot,dm-pre-reloc;
-};
-
-&gpio3 {
-	u-boot,dm-pre-reloc;
-};
-
-&gpio8 {
-	u-boot,dm-pre-reloc;
-};
diff --git a/arch/arm/dts/rk3288-firefly.dtsi b/arch/arm/dts/rk3288-firefly.dtsi
index 2239ab9..b7f279f 100644
--- a/arch/arm/dts/rk3288-firefly.dtsi
+++ b/arch/arm/dts/rk3288-firefly.dtsi
@@ -320,6 +320,11 @@
 		output-low;
 	};
 
+	pcfg_pull_up_drv_12ma: pcfg-pull-up-drv-12ma {
+		bias-pull-up;
+		drive-strength = <12>;
+	};
+
 	act8846 {
 		pwr_hold: pwr-hold {
 			rockchip,pins = <0 1 RK_FUNC_GPIO &pcfg_output_high>;
@@ -363,8 +368,27 @@
 	};
 
 	sdmmc {
+		/*
+		 * Default drive strength isn't enough to achieve even
+		 * high-speed mode on firefly board so bump up to 12ma.
+		 */
+		sdmmc_bus4: sdmmc-bus4 {
+			rockchip,pins = <6 RK_PC0 1 &pcfg_pull_up_drv_12ma>,
+					<6 RK_PC1 1 &pcfg_pull_up_drv_12ma>,
+					<6 RK_PC2 1 &pcfg_pull_up_drv_12ma>,
+					<6 RK_PC3 1 &pcfg_pull_up_drv_12ma>;
+		};
+
+		sdmmc_clk: sdmmc-clk {
+			rockchip,pins = <6 RK_PC4 1 &pcfg_pull_none_12ma>;
+		};
+
+		sdmmc_cmd: sdmmc-cmd {
+			rockchip,pins = <6 RK_PC5 1 &pcfg_pull_up_drv_12ma>;
+		};
+
 		sdmmc_pwr: sdmmc-pwr {
-			rockchip,pins = <7 11 RK_FUNC_GPIO &pcfg_pull_none>;
+			rockchip,pins = <7 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
 		};
 	};
 
diff --git a/arch/arm/dts/rk3288-miqi-u-boot.dtsi b/arch/arm/dts/rk3288-miqi-u-boot.dtsi
new file mode 100644
index 0000000..4f63fc9
--- /dev/null
+++ b/arch/arm/dts/rk3288-miqi-u-boot.dtsi
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 Rockchip Electronics Co., Ltd
+ */
+
+#include "rk3288-u-boot.dtsi"
+
+&pinctrl {
+	u-boot,dm-pre-reloc;
+};
+
+&uart2 {
+	u-boot,dm-pre-reloc;
+};
+
+&sdmmc {
+	u-boot,dm-pre-reloc;
+};
+
+&emmc {
+	u-boot,dm-pre-reloc;
+};
+
+&sdmmc_bus4 {
+	u-boot,dm-spl;
+};
+
+&sdmmc_clk {
+	u-boot,dm-spl;
+};
+
+&sdmmc_cmd {
+	u-boot,dm-spl;
+};
+
+&sdmmc_pwr {
+	u-boot,dm-spl;
+};
diff --git a/arch/arm/dts/rk3288-miqi.dts b/arch/arm/dts/rk3288-miqi.dts
index 29e60dd..e47170c 100644
--- a/arch/arm/dts/rk3288-miqi.dts
+++ b/arch/arm/dts/rk3288-miqi.dts
@@ -25,21 +25,3 @@
 		0xa60 0x40 0x10 0x0>;
 	rockchip,sdram-params = <0x30B25564 0x627 3 666000000 3 9 1>;
 };
-
-
-&pinctrl {
-	u-boot,dm-pre-reloc;
-};
-
-&uart2 {
-	u-boot,dm-pre-reloc;
-	reg-shift = <2>;
-};
-
-&sdmmc {
-	u-boot,dm-pre-reloc;
-};
-
-&emmc {
-	u-boot,dm-pre-reloc;
-};
diff --git a/arch/arm/dts/rk3288-popmetal-u-boot.dtsi b/arch/arm/dts/rk3288-popmetal-u-boot.dtsi
new file mode 100644
index 0000000..8ac7840
--- /dev/null
+++ b/arch/arm/dts/rk3288-popmetal-u-boot.dtsi
@@ -0,0 +1,46 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 Rockchip Electronics Co., Ltd
+ */
+
+#include "rk3288-u-boot.dtsi"
+
+&pinctrl {
+	u-boot,dm-pre-reloc;
+};
+
+&uart2 {
+	u-boot,dm-pre-reloc;
+};
+
+&sdmmc {
+	u-boot,dm-pre-reloc;
+};
+
+&emmc {
+	u-boot,dm-pre-reloc;
+};
+
+&gpio3 {
+	u-boot,dm-pre-reloc;
+};
+
+&gpio8 {
+	u-boot,dm-pre-reloc;
+};
+
+&sdmmc_bus4 {
+	u-boot,dm-spl;
+};
+
+&sdmmc_clk {
+	u-boot,dm-spl;
+};
+
+&sdmmc_cmd {
+	u-boot,dm-spl;
+};
+
+&sdmmc_pwr {
+	u-boot,dm-spl;
+};
diff --git a/arch/arm/dts/rk3288-popmetal.dts b/arch/arm/dts/rk3288-popmetal.dts
index d1e1cd5..5c6d06f 100644
--- a/arch/arm/dts/rk3288-popmetal.dts
+++ b/arch/arm/dts/rk3288-popmetal.dts
@@ -26,32 +26,6 @@
 	rockchip,sdram-params = <0x30B25564 0x627 3 666000000 3 9 1>;
 };
 
-
-&pinctrl {
-	u-boot,dm-pre-reloc;
-};
-
 &pwm1 {
 	status = "okay";
 };
-
-&uart2 {
-	u-boot,dm-pre-reloc;
-	reg-shift = <2>;
-};
-
-&sdmmc {
-	u-boot,dm-pre-reloc;
-};
-
-&emmc {
-	u-boot,dm-pre-reloc;
-};
-
-&gpio3 {
-	u-boot,dm-pre-reloc;
-};
-
-&gpio8 {
-	u-boot,dm-pre-reloc;
-};
diff --git a/arch/arm/dts/rk3288-u-boot.dtsi b/arch/arm/dts/rk3288-u-boot.dtsi
index 4cf75c7..3f00a3b 100644
--- a/arch/arm/dts/rk3288-u-boot.dtsi
+++ b/arch/arm/dts/rk3288-u-boot.dtsi
@@ -3,6 +3,13 @@
  * Copyright (C) 2019 Rockchip Electronics Co., Ltd
  */
 
+/ {
+	chosen {
+		u-boot,spl-boot-order = \
+			"same-as-spl", &emmc, &sdmmc;
+	};
+};
+
 &dmc {
 	u-boot,dm-pre-reloc;
 };
diff --git a/arch/arm/dts/rk3368-lion-u-boot.dtsi b/arch/arm/dts/rk3368-lion-u-boot.dtsi
index fb4a4fb..edc93e4 100644
--- a/arch/arm/dts/rk3368-lion-u-boot.dtsi
+++ b/arch/arm/dts/rk3368-lion-u-boot.dtsi
@@ -12,7 +12,6 @@
 	chosen {
 		stdout-path = "serial0:115200n8";
 		u-boot,spl-boot-order = &emmc, &sdmmc;
-		tick-timer = "/timer@ff810000";
 	};
 
 };
diff --git a/arch/arm/dts/rk3368-px5-evb-u-boot.dtsi b/arch/arm/dts/rk3368-px5-evb-u-boot.dtsi
index f5406d4..002767a 100644
--- a/arch/arm/dts/rk3368-px5-evb-u-boot.dtsi
+++ b/arch/arm/dts/rk3368-px5-evb-u-boot.dtsi
@@ -5,7 +5,6 @@
 / {
 	chosen {
 		u-boot,spl-boot-order = &emmc;
-		tick-timer = "/timer@ff810000";
 	};
 };
 
diff --git a/arch/arm/dts/rk3399-ficus.dts b/arch/arm/dts/rk3399-ficus.dts
index 4b2dd82..6b059bd 100644
--- a/arch/arm/dts/rk3399-ficus.dts
+++ b/arch/arm/dts/rk3399-ficus.dts
@@ -23,6 +23,52 @@
 		clock-output-names = "clkin_gmac";
 		#clock-cells = <0>;
 	};
+
+	leds {
+		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&user_led1>, <&user_led2>, <&user_led3>,
+			    <&user_led4>, <&wlan_led>, <&bt_led>;
+
+		user_led1 {
+			label = "red:user1";
+			gpios = <&gpio4 25 0>;
+			linux,default-trigger = "heartbeat";
+		};
+
+		user_led2 {
+			label = "red:user2";
+			gpios = <&gpio4 26 0>;
+			linux,default-trigger = "mmc0";
+		};
+
+		user_led3 {
+			label = "red:user3";
+			gpios = <&gpio4 30 0>;
+			linux,default-trigger = "mmc1";
+		};
+
+		user_led4 {
+			label = "red:user4";
+			gpios = <&gpio1 0 0>;
+			panic-indicator;
+			linux,default-trigger = "none";
+		};
+
+		wlan_active_led {
+			label = "red:wlan";
+			gpios = <&gpio1 1 0>;
+			linux,default-trigger = "phy0tx";
+			default-state = "off";
+		};
+
+		bt_active_led {
+			label = "red:bt";
+			gpios = <&gpio1 4 0>;
+			linux,default-trigger = "hci0-power";
+			default-state = "off";
+		};
+	};
 };
 
 &gmac {
@@ -49,23 +95,63 @@
 	gmac {
 		rgmii_sleep_pins: rgmii-sleep-pins {
 			rockchip,pins =
-				<3 15 RK_FUNC_GPIO &pcfg_output_low>;
+				<3 RK_PB7 RK_FUNC_GPIO &pcfg_output_low>;
 		};
 	};
 
 	pcie {
 		pcie_drv: pcie-drv {
 			rockchip,pins =
-				<1 24 RK_FUNC_GPIO &pcfg_pull_none>;
+				<1 RK_PD0 RK_FUNC_GPIO &pcfg_pull_none>;
 			};
 	};
 
 	usb2 {
 		host_vbus_drv: host-vbus-drv {
 			rockchip,pins =
-				<4 27 RK_FUNC_GPIO &pcfg_pull_none>;
+				<4 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>;
 		};
 	};
+
+	leds {
+		user_led1: user_led1 {
+			rockchip,pins =
+				<4 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		user_led2: user_led2 {
+			rockchip,pins =
+				<4 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		user_led3: user_led3 {
+			rockchip,pins =
+				<4 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		user_led4: user_led4 {
+			rockchip,pins =
+				<1 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		wlan_led: wlan_led {
+			rockchip,pins =
+				<1 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		bt_led: bt_led {
+			rockchip,pins =
+				<1 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+};
+
+&usbdrd_dwc3_0 {
+	dr_mode = "host";
+};
+
+&usbdrd_dwc3_1 {
+	dr_mode = "host";
 };
 
 &vcc3v3_pcie {
diff --git a/arch/arm/dts/rk3399-nanopi-neo4-u-boot.dtsi b/arch/arm/dts/rk3399-nanopi-neo4-u-boot.dtsi
index 7d22528..eb0aca4 100644
--- a/arch/arm/dts/rk3399-nanopi-neo4-u-boot.dtsi
+++ b/arch/arm/dts/rk3399-nanopi-neo4-u-boot.dtsi
@@ -4,3 +4,4 @@
  */
 
 #include "rk3399-nanopi4-u-boot.dtsi"
+#include "rk3399-sdram-ddr3-1866.dtsi"
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 7bddc3a..5bd8696 100644
--- a/arch/arm/dts/rk3399-rock-pi-4-u-boot.dtsi
+++ b/arch/arm/dts/rk3399-rock-pi-4-u-boot.dtsi
@@ -4,3 +4,10 @@
  */
 
 #include "rk3399-u-boot.dtsi"
+#include "rk3399-sdram-lpddr4-100.dtsi"
+
+/ {
+	chosen {
+		u-boot,spl-boot-order = "same-as-spl", &sdhci, &sdmmc;
+	};
+};
diff --git a/arch/arm/dts/rk3399-rock960.dts b/arch/arm/dts/rk3399-rock960.dts
index 7e06bc9..12285c5 100644
--- a/arch/arm/dts/rk3399-rock960.dts
+++ b/arch/arm/dts/rk3399-rock960.dts
@@ -1,6 +1,6 @@
-// SPDX-License-Identifier: GPL-2.0+
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
- * Copyright (C) 2018 Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+ * Copyright (c) 2018 Linaro Ltd.
  */
 
 /dts-v1/;
@@ -13,6 +13,53 @@
 	chosen {
 		stdout-path = "serial2:1500000n8";
 	};
+
+	leds {
+		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&user_led1>, <&user_led2>, <&user_led3>,
+			    <&user_led4>, <&wlan_led>, <&bt_led>;
+
+		user_led1 {
+			label = "green:user1";
+			gpios = <&gpio4 RK_PC2 0>;
+			linux,default-trigger = "heartbeat";
+		};
+
+		user_led2 {
+			label = "green:user2";
+			gpios = <&gpio4 RK_PC6 0>;
+			linux,default-trigger = "mmc0";
+		};
+
+		user_led3 {
+			label = "green:user3";
+			gpios = <&gpio4 RK_PD0 0>;
+			linux,default-trigger = "mmc1";
+		};
+
+		user_led4 {
+			label = "green:user4";
+			gpios = <&gpio4 RK_PD4 0>;
+			panic-indicator;
+			linux,default-trigger = "none";
+		};
+
+		wlan_active_led {
+			label = "yellow:wlan";
+			gpios = <&gpio4 RK_PD5 0>;
+			linux,default-trigger = "phy0tx";
+			default-state = "off";
+		};
+
+		bt_active_led {
+			label = "blue:bt";
+			gpios = <&gpio4 RK_PD6 0>;
+			linux,default-trigger = "hci0-power";
+			default-state = "off";
+		};
+	};
+
 };
 
 &pcie0 {
@@ -20,6 +67,38 @@
 };
 
 &pinctrl {
+	leds {
+		user_led1: user_led1 {
+			rockchip,pins =
+				<4 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		user_led2: user_led2 {
+			rockchip,pins =
+				<4 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		user_led3: user_led3 {
+			rockchip,pins =
+				<4 RK_PD0 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		user_led4: user_led4 {
+			rockchip,pins =
+				<4 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		wlan_led: wlan_led {
+			rockchip,pins =
+				<4 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		bt_led: bt_led {
+			rockchip,pins =
+				<4 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
 	pcie {
 		pcie_drv: pcie-drv {
 			rockchip,pins =
@@ -35,6 +114,14 @@
 	};
 };
 
+&usbdrd_dwc3_0 {
+	dr_mode = "otg";
+};
+
+&usbdrd_dwc3_1 {
+	dr_mode = "host";
+};
+
 &vcc3v3_pcie {
 	gpio = <&gpio2 5 GPIO_ACTIVE_HIGH>;
 };
diff --git a/arch/arm/dts/rk3399-rock960.dtsi b/arch/arm/dts/rk3399-rock960.dtsi
index 51644d6..c7d48d4 100644
--- a/arch/arm/dts/rk3399-rock960.dtsi
+++ b/arch/arm/dts/rk3399-rock960.dtsi
@@ -1,13 +1,32 @@
-// SPDX-License-Identifier: GPL-2.0+
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
+ * Copyright (c) 2018 Collabora Ltd.
+ * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd.
  * Copyright (c) 2018 Linaro Ltd.
  */
 
-#include <dt-bindings/pwm/pwm.h>
-#include <dt-bindings/pinctrl/rockchip.h>
 #include "rk3399.dtsi"
+#include "rk3399-opp.dtsi"
 
 / {
+	sdio_pwrseq: sdio-pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		clocks = <&rk808 1>;
+		clock-names = "ext_clock";
+		pinctrl-names = "default";
+		pinctrl-0 = <&wifi_enable_h>;
+		reset-gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>;
+	};
+
+	vcc12v_dcin: vcc12v-dcin {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc12v_dcin";
+		regulator-min-microvolt = <12000000>;
+		regulator-max-microvolt = <12000000>;
+		regulator-always-on;
+		regulator-boot-on;
+	};
+
 	vcc1v8_s0: vcc1v8-s0 {
 		compatible = "regulator-fixed";
 		regulator-name = "vcc1v8_s0";
@@ -16,12 +35,13 @@
 		regulator-always-on;
 	};
 
-	vcc_sys: vcc-sys {
+	vcc5v0_sys: vcc5v0-sys {
 		compatible = "regulator-fixed";
-		regulator-name = "vcc_sys";
+		regulator-name = "vcc5v0_sys";
 		regulator-min-microvolt = <5000000>;
 		regulator-max-microvolt = <5000000>;
 		regulator-always-on;
+		vin-supply = <&vcc12v_dcin>;
 	};
 
 	vcc3v3_sys: vcc3v3-sys {
@@ -30,7 +50,7 @@
 		regulator-min-microvolt = <3300000>;
 		regulator-max-microvolt = <3300000>;
 		regulator-always-on;
-		vin-supply = <&vcc_sys>;
+		vin-supply = <&vcc5v0_sys>;
 	};
 
 	vcc3v3_pcie: vcc3v3-pcie-regulator {
@@ -54,20 +74,8 @@
 		regulator-min-microvolt = <5000000>;
 		regulator-max-microvolt = <5000000>;
 		regulator-always-on;
-		vin-supply = <&vcc_sys>;
+		vin-supply = <&vcc5v0_sys>;
 	};
-
-	vdd_log: vdd-log {
-		compatible = "pwm-regulator";
-		pwms = <&pwm2 0 25000 0>;
-		regulator-name = "vdd_log";
-		regulator-min-microvolt = <800000>;
-		regulator-max-microvolt = <1400000>;
-		regulator-always-on;
-		regulator-boot-on;
-		vin-supply = <&vcc_sys>;
-	};
-
 };
 
 &cpu_l0 {
@@ -98,7 +106,19 @@
 	status = "okay";
 };
 
+&gpu {
+	mali-supply = <&vdd_gpu>;
+	status = "okay";
+};
+
 &hdmi {
+	ddc-i2c-bus = <&i2c3>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&hdmi_cec>;
+	status = "okay";
+};
+
+&hdmi_sound {
 	status = "okay";
 };
 
@@ -118,7 +138,7 @@
 		regulator-ramp-delay = <1000>;
 		regulator-always-on;
 		regulator-boot-on;
-		vin-supply = <&vcc_sys>;
+		vin-supply = <&vcc5v0_sys>;
 		status = "okay";
 
 		regulator-state-mem {
@@ -136,7 +156,7 @@
 		regulator-ramp-delay = <1000>;
 		regulator-always-on;
 		regulator-boot-on;
-		vin-supply = <&vcc_sys>;
+		vin-supply = <&vcc5v0_sys>;
 		regulator-state-mem {
 			regulator-off-in-suspend;
 		};
@@ -154,16 +174,16 @@
 		#clock-cells = <1>;
 		clock-output-names = "xin32k", "rk808-clkout2";
 
-		vcc1-supply = <&vcc_sys>;
-		vcc2-supply = <&vcc_sys>;
-		vcc3-supply = <&vcc_sys>;
-		vcc4-supply = <&vcc_sys>;
-		vcc6-supply = <&vcc_sys>;
-		vcc7-supply = <&vcc_sys>;
+		vcc1-supply = <&vcc5v0_sys>;
+		vcc2-supply = <&vcc5v0_sys>;
+		vcc3-supply = <&vcc5v0_sys>;
+		vcc4-supply = <&vcc5v0_sys>;
+		vcc6-supply = <&vcc5v0_sys>;
+		vcc7-supply = <&vcc5v0_sys>;
 		vcc8-supply = <&vcc3v3_sys>;
-		vcc9-supply = <&vcc_sys>;
-		vcc10-supply = <&vcc_sys>;
-		vcc11-supply = <&vcc_sys>;
+		vcc9-supply = <&vcc5v0_sys>;
+		vcc10-supply = <&vcc5v0_sys>;
+		vcc11-supply = <&vcc5v0_sys>;
 		vcc12-supply = <&vcc3v3_sys>;
 		vddio-supply = <&vcc_1v8>;
 
@@ -344,6 +364,10 @@
 	status = "okay";
 };
 
+&i2s2 {
+        status = "okay";
+};
+
 &io_domains {
 	bt656-supply = <&vcc1v8_s0>; /* bt656_gpio2ab_ms */
 	audio-supply = <&vcc1v8_s0>; /* audio_gpio3d4a_ms */
@@ -370,45 +394,92 @@
 };
 
 &pinctrl {
+	bt {
+		bt_enable_h: bt-enable-h {
+			rockchip,pins = <0 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		bt_host_wake_l: bt-host-wake-l {
+			rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		bt_wake_l: bt-wake-l {
+			rockchip,pins = <2 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
 	sdmmc {
 		sdmmc_bus1: sdmmc-bus1 {
 			rockchip,pins =
-				<4 8 RK_FUNC_1 &pcfg_pull_up_8ma>;
+				<4 RK_PB0 1 &pcfg_pull_up_8ma>;
 		};
 
 		sdmmc_bus4: sdmmc-bus4 {
 			rockchip,pins =
-				<4 8 RK_FUNC_1 &pcfg_pull_up_8ma>,
-				<4 9 RK_FUNC_1 &pcfg_pull_up_8ma>,
-				<4 10 RK_FUNC_1 &pcfg_pull_up_8ma>,
-				<4 11 RK_FUNC_1 &pcfg_pull_up_8ma>;
+				<4 RK_PB0 1 &pcfg_pull_up_8ma>,
+				<4 RK_PB1 1 &pcfg_pull_up_8ma>,
+				<4 RK_PB2 1 &pcfg_pull_up_8ma>,
+				<4 RK_PB3 1 &pcfg_pull_up_8ma>;
 		};
 
 		sdmmc_clk: sdmmc-clk {
 			rockchip,pins =
-				<4 12 RK_FUNC_1 &pcfg_pull_none_18ma>;
+				<4 RK_PB4 1 &pcfg_pull_none_18ma>;
 		};
 
 		sdmmc_cmd: sdmmc-cmd {
 			rockchip,pins =
-				<4 13 RK_FUNC_1 &pcfg_pull_up_8ma>;
+				<4 RK_PB5 1 &pcfg_pull_up_8ma>;
+		};
+	};
+
+	sdio0 {
+		sdio0_bus4: sdio0-bus4 {
+			rockchip,pins =
+				<2 RK_PC4 1 &pcfg_pull_up_20ma>,
+				<2 RK_PC5 1 &pcfg_pull_up_20ma>,
+				<2 RK_PC6 1 &pcfg_pull_up_20ma>,
+				<2 RK_PC7 1 &pcfg_pull_up_20ma>;
+		};
+
+		sdio0_cmd: sdio0-cmd {
+			rockchip,pins =
+				<2 RK_PD0 1 &pcfg_pull_up_20ma>;
+		};
+
+		sdio0_clk: sdio0-clk {
+			rockchip,pins =
+				<2 RK_PD1 1 &pcfg_pull_none_20ma>;
 		};
 	};
 
 	pmic {
 		pmic_int_l: pmic-int-l {
 			rockchip,pins =
-				<1 21 RK_FUNC_GPIO &pcfg_pull_up>;
+				<1 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>;
 		};
 
 		vsel1_gpio: vsel1-gpio {
 			rockchip,pins =
-				<1 17 RK_FUNC_GPIO &pcfg_pull_down>;
+				<1 RK_PC1 RK_FUNC_GPIO &pcfg_pull_down>;
 		};
 
 		vsel2_gpio: vsel2-gpio {
 			rockchip,pins =
-				<1 14 RK_FUNC_GPIO &pcfg_pull_down>;
+				<1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_down>;
+		};
+	};
+
+	sdio-pwrseq {
+		wifi_enable_h: wifi-enable-h {
+			rockchip,pins =
+				<0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	wifi {
+		wifi_host_wake_l: wifi-host-wake-l {
+			rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none>;
 		};
 	};
 };
@@ -421,6 +492,32 @@
 	status = "okay";
 };
 
+&sdio0 {
+	bus-width = <4>;
+	clock-frequency = <50000000>;
+	cap-sdio-irq;
+	cap-sd-highspeed;
+	keep-power-in-suspend;
+	mmc-pwrseq = <&sdio_pwrseq>;
+	non-removable;
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdio0_bus4 &sdio0_cmd &sdio0_clk>;
+	sd-uhs-sdr104;
+	#address-cells = <1>;
+	#size-cells = <0>;
+	status = "okay";
+
+	brcmf: wifi@1 {
+		compatible = "brcm,bcm4329-fmac";
+		reg = <1>;
+		interrupt-parent = <&gpio0>;
+		interrupts = <RK_PA3 GPIO_ACTIVE_HIGH>;
+		interrupt-names = "host-wake";
+		pinctrl-names = "default";
+		pinctrl-0 = <&wifi_host_wake_l>;
+	};
+};
+
 &sdhci {
 	bus-width = <8>;
 	mmc-hs400-1_8v;
@@ -445,16 +542,42 @@
 	status = "okay";
 };
 
-&uart0 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&uart0_xfer &uart0_cts>;
+&tsadc {
+	rockchip,hw-tshut-mode = <1>;
+	rockchip,hw-tshut-polarity = <1>;
+	rockchip,hw-tshut-temp = <110000>;
 	status = "okay";
 };
 
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>;
+	status = "okay";
+
+	bluetooth {
+		compatible = "brcm,bcm43438-bt";
+		clocks = <&rk808 1>;
+		clock-names = "ext_clock";
+		device-wakeup-gpios = <&gpio2 RK_PD3 GPIO_ACTIVE_HIGH>;
+		host-wakeup-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_HIGH>;
+		shutdown-gpios = <&gpio0 RK_PB1 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&bt_host_wake_l &bt_wake_l &bt_enable_h>;
+	};
+};
+
 &uart2 {
 	status = "okay";
 };
 
+&tcphy0 {
+	status = "okay";
+};
+
+&tcphy1 {
+	status = "okay";
+};
+
 &u2phy0 {
 	status = "okay";
 };
@@ -497,10 +620,34 @@
 	status = "okay";
 };
 
+&usbdrd3_0 {
+	status = "okay";
+};
+
+&usbdrd_dwc3_0 {
+	status = "okay";
+};
+
+&usbdrd3_1 {
+	status = "okay";
+};
+
+&usbdrd_dwc3_1 {
+	status = "okay";
+};
+
 &vopb {
 	status = "okay";
 };
 
+&vopb_mmu {
+	status = "okay";
+};
+
 &vopl {
 	status = "okay";
 };
+
+&vopl_mmu {
+	status = "okay";
+};
diff --git a/arch/arm/dts/rk3399-rockpro64-u-boot.dtsi b/arch/arm/dts/rk3399-rockpro64-u-boot.dtsi
index 50b0ca0..f7f26d5 100644
--- a/arch/arm/dts/rk3399-rockpro64-u-boot.dtsi
+++ b/arch/arm/dts/rk3399-rockpro64-u-boot.dtsi
@@ -4,6 +4,7 @@
  */
 
 #include "rk3399-u-boot.dtsi"
+#include "rk3399-sdram-lpddr4-100.dtsi"
 
 &vdd_log {
 	regulator-init-microvolt = <950000>;
diff --git a/arch/arm/dts/rk3399-sdram-lpddr4-100.dtsi b/arch/arm/dts/rk3399-sdram-lpddr4-100.dtsi
new file mode 100644
index 0000000..4a4414a
--- /dev/null
+++ b/arch/arm/dts/rk3399-sdram-lpddr4-100.dtsi
@@ -0,0 +1,1537 @@
+// 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>
+ */
+
+&dmc {
+	rockchip,sdram-params = <
+		0x2
+		0xa
+		0x3
+		0x2
+		0x1
+		0x0
+		0xf
+		0xf
+		1
+		0x80241d22
+		0x15050f08
+		0x00000602
+		0x00002122
+		0x0000004c
+		0x00000000
+		0x2
+		0xa
+		0x3
+		0x2
+		0x1
+		0x0
+		0xf
+		0xf
+		1
+		0x80241d22
+		0x15050f08
+		0x00000602
+		0x00002122
+		0x0000004c
+		0x00000000
+		50
+		7
+		2
+		13
+		1
+		0x00000b00
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00013880
+		0x000c3500
+		0x00000005
+		0x00000320
+		0x00027100
+		0x00186a00
+		0x00000005
+		0x00000640
+		0x00002710
+		0x000186a0
+		0x00000005
+		0x01000064
+		0x00000000
+		0x02020101
+		0x00000102
+		0x00000050
+		0x000000c8
+		0x00000000
+		0x06140000
+		0x00081c00
+		0x0400040c
+		0x19042008
+		0x10080a11
+		0x22310800
+		0x00200f0a
+		0x0a030704
+		0x08000204
+		0x00000a0a
+		0x04006db0
+		0x0a0a0804
+		0x0600db60
+		0x0a0a0806
+		0x04000db6
+		0x02030404
+		0x0f0a0800
+		0x08040411
+		0x1400640a
+		0x02010a0a
+		0x00010001
+		0x04082012
+		0x00041109
+		0x00000000
+		0x03010000
+		0x06100048
+		0x0c280090
+		0x00bb0009
+		0x00000000
+		0x00060005
+		0x000a0005
+		0x000a0014
+		0x01000000
+		0x030a0000
+		0x0c000002
+		0x00000103
+		0x0005030a
+		0x00060037
+		0x0005006e
+		0x05050007
+		0x03030605
+		0x06050301
+		0x06030c05
+		0x05050302
+		0x03030305
+		0x00000301
+		0x00000301
+		0x00000001
+		0x00000000
+		0x00000000
+		0x01000000
+		0x80104002
+		0x00040003
+		0x00040005
+		0x00030000
+		0x00050004
+		0x00000004
+		0x00040003
+		0x00040005
+		0x18400000
+		0x00000c20
+		0x185030a0
+		0x02ec0000
+		0x00000176
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x06030300
+		0x00030303
+		0x02030200
+		0x00040703
+		0x03020302
+		0x02000407
+		0x07030203
+		0x00030f04
+		0x00070004
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00010000
+		0x20040020
+		0x00200400
+		0x01000400
+		0x00000b80
+		0x00000000
+		0x00000001
+		0x00000002
+		0x0000000e
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00500000
+		0x00640028
+		0x00640404
+		0x005000a0
+		0x060600c8
+		0x000a00c8
+		0x000d0005
+		0x000d0404
+		0x00000000
+		0x00000000
+		0x00000000
+		0x001400a3
+		0x00e30009
+		0x00120024
+		0x00040063
+		0x00000000
+		0x00310031
+		0x00000031
+		0x004d0000
+		0x004d004d
+		0x004d0000
+		0x004d004d
+		0x00010101
+		0x00000000
+		0x00000000
+		0x001400a3
+		0x00e30009
+		0x00120024
+		0x00040063
+		0x00000000
+		0x00310031
+		0x00000031
+		0x004d0000
+		0x004d004d
+		0x004d0000
+		0x004d004d
+		0x00010101
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000001
+		0x00000000
+		0x18151100
+		0x0000000c
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00020003
+		0x00400100
+		0x000c0190
+		0x01000200
+		0x03200040
+		0x00020018
+		0x00400100
+		0x00080032
+		0x00140000
+		0x00030028
+		0x01010100
+		0x02000202
+		0x0b000002
+		0x01000f0f
+		0x00000000
+		0x00000000
+		0x00010003
+		0x00000c03
+		0x00040101
+		0x04010100
+		0x01000000
+		0x02010000
+		0x00000001
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00010000
+		0x00000001
+		0x01010001
+		0x05040001
+		0x040a0703
+		0x02080808
+		0x020e000a
+		0x020f010b
+		0x000d0008
+		0x00080b0a
+		0x03000200
+		0x00000100
+		0x00000000
+		0x00000000
+		0x0d000001
+		0x00000028
+		0x00010000
+		0x00000003
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00010100
+		0x01000000
+		0x00000001
+		0x00000303
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x000556aa
+		0x000aaaaa
+		0x000aa955
+		0x00055555
+		0x000b3133
+		0x0004cd33
+		0x0004cecc
+		0x000b32cc
+		0x00010300
+		0x03000100
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00ffff00
+		0x1a160000
+		0x08000012
+		0x00000c20
+		0x00000200
+		0x00000200
+		0x00000200
+		0x00000200
+		0x00000c20
+		0x00007940
+		0x18500409
+		0x00000200
+		0x00000200
+		0x00000200
+		0x00000200
+		0x00001850
+		0x0000f320
+		0x0176060c
+		0x00000200
+		0x00000200
+		0x00000200
+		0x00000200
+		0x00000176
+		0x00000e9c
+		0x02020205
+		0x03030202
+		0x00000018
+		0x00000000
+		0x00000000
+		0x00001403
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00030000
+		0x000a001c
+		0x000e0020
+		0x00060018
+		0x00000000
+		0x00000000
+		0x02000000
+		0x00090305
+		0x00050101
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x01000001
+		0x01010101
+		0x01000101
+		0x01000100
+		0x00010001
+		0x00010002
+		0x00020100
+		0x00000002
+		0x00000b00
+		0x00000000
+		0x000002ec
+		0x00000176
+		0x000030a0
+		0x00001850
+		0x00001840
+		0x01760c20
+		0x00000200
+		0x00000200
+		0x00000200
+		0x00000200
+		0x00001850
+		0x00000200
+		0x00000200
+		0x00000200
+		0x00000200
+		0x00000c20
+		0x00000200
+		0x00000200
+		0x00000200
+		0x00000200
+		0x00010000
+		0x00000007
+		0x01000001
+		0x00000000
+		0x3fffffff
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x0f000101
+		0x082b3223
+		0x080c0004
+		0x00061c00
+		0x00000214
+		0x00bb0009
+		0x0c280090
+		0x06100048
+		0x00000500
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x04040100
+		0x0a000004
+		0x00000128
+		0x00000000
+		0x0003000f
+		0x00000018
+		0x00000000
+		0x00000000
+		0x00060002
+		0x00010001
+		0x00000101
+		0x00020001
+		0x00080004
+		0x00000000
+		0x05030000
+		0x070a0404
+		0x00000000
+		0x00000000
+		0x00000000
+		0x000f0f00
+		0x0000001e
+		0x00000000
+		0x01010300
+		0x00000000
+		0x00000000
+		0x01000000
+		0x00000101
+		0x55555a5a
+		0x55555a5a
+		0x55555a5a
+		0x55555a5a
+		0x0c050001
+		0x06020009
+		0x00010004
+		0x00000203
+		0x00030000
+		0x170f0000
+		0x00060018
+		0x000e0020
+		0x000a001c
+		0x00000000
+		0x00000000
+		0x00000100
+		0x140a0000
+		0x000d010a
+		0x0100c802
+		0x010a0064
+		0x000e0100
+		0x0100000e
+		0x00c900c9
+		0x00650100
+		0x1e1a0065
+		0x10010204
+		0x06070605
+		0x20000202
+		0x00201000
+		0x00201000
+		0x04041000
+		0x10020100
+		0x0003010c
+		0x004b004a
+		0x1a0f0000
+		0x0102041e
+		0x34000000
+		0x00000000
+		0x00000000
+		0x00010000
+		0x00000400
+		0x00310000
+		0x004d4d00
+		0x00120024
+		0x4d000031
+		0x0000144d
+		0x00310009
+		0x004d4d00
+		0x00000004
+		0x4d000031
+		0x0000244d
+		0x00310012
+		0x004d4d00
+		0x00090014
+		0x4d000031
+		0x0004004d
+		0x00310000
+		0x004d4d00
+		0x00120024
+		0x4d000031
+		0x0000144d
+		0x00310009
+		0x004d4d00
+		0x00000004
+		0x4d000031
+		0x0000244d
+		0x00310012
+		0x004d4d00
+		0x00090014
+		0x4d000031
+		0x0200004d
+		0x00c8000d
+		0x08080064
+		0x040a0404
+		0x03000d92
+		0x010a2001
+		0x0f11080a
+		0x0000110a
+		0x2200d92e
+		0x080c2003
+		0x0809080a
+		0x00000a0a
+		0x11006c97
+		0x040a2002
+		0x0200020a
+		0x02000200
+		0x02000200
+		0x02000200
+		0x02000200
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x01000400
+		0x00017600
+		0x00000e9c
+		0x00001850
+		0x0000f320
+		0x00000c20
+		0x00007940
+		0x08000000
+		0x00000100
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000002
+		0x76543210
+		0x0004f008
+		0x00020159
+		0x00000000
+		0x00000000
+		0x00010000
+		0x01665555
+		0x03665555
+		0x00010f00
+		0x04000100
+		0x00000000
+		0x00170180
+		0x00cc0201
+		0x00030066
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x04080000
+		0x04080400
+		0x30000000
+		0x0c00c007
+		0x00000100
+		0x00000000
+		0xfd02fe01
+		0xf708fb04
+		0xdf20ef10
+		0x7f80bf40
+		0x0001aaaa
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00200000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x02800280
+		0x02800280
+		0x02800280
+		0x02800280
+		0x00000280
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00800000
+		0x00800080
+		0x00800080
+		0x00800080
+		0x00800080
+		0x00800080
+		0x00800080
+		0x00800080
+		0x00800080
+		0x01590080
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000200
+		0x00000000
+		0x51315152
+		0xc0003150
+		0x010000c0
+		0x00100c00
+		0x07044204
+		0x000f0c18
+		0x01000140
+		0x00000c10
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x76543210
+		0x0004f008
+		0x00020159
+		0x00000000
+		0x00000000
+		0x00010000
+		0x01665555
+		0x03665555
+		0x00010f00
+		0x04000100
+		0x00000000
+		0x00170180
+		0x00cc0201
+		0x00030066
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x04080000
+		0x04080400
+		0x30000000
+		0x0c00c007
+		0x00000100
+		0x00000000
+		0xfd02fe01
+		0xf708fb04
+		0xdf20ef10
+		0x7f80bf40
+		0x0000aaaa
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00200000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x02800280
+		0x02800280
+		0x02800280
+		0x02800280
+		0x00000280
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00800000
+		0x00800080
+		0x00800080
+		0x00800080
+		0x00800080
+		0x00800080
+		0x00800080
+		0x00800080
+		0x00800080
+		0x01590080
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000200
+		0x00000000
+		0x51315152
+		0xc0003150
+		0x010000c0
+		0x00100c00
+		0x07044204
+		0x000f0c18
+		0x01000140
+		0x00000c10
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x76543210
+		0x0004f008
+		0x00020159
+		0x00000000
+		0x00000000
+		0x00010000
+		0x01665555
+		0x03665555
+		0x00010f00
+		0x04000100
+		0x00000000
+		0x00170180
+		0x00cc0201
+		0x00030066
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x04080000
+		0x04080400
+		0x30000000
+		0x0c00c007
+		0x00000100
+		0x00000000
+		0xfd02fe01
+		0xf708fb04
+		0xdf20ef10
+		0x7f80bf40
+		0x0001aaaa
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00200000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x02800280
+		0x02800280
+		0x02800280
+		0x02800280
+		0x00000280
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00800000
+		0x00800080
+		0x00800080
+		0x00800080
+		0x00800080
+		0x00800080
+		0x00800080
+		0x00800080
+		0x00800080
+		0x01590080
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000200
+		0x00000000
+		0x51315152
+		0xc0003150
+		0x010000c0
+		0x00100c00
+		0x07044204
+		0x000f0c18
+		0x01000140
+		0x00000c10
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x76543210
+		0x0004f008
+		0x00020159
+		0x00000000
+		0x00000000
+		0x00010000
+		0x01665555
+		0x03665555
+		0x00010f00
+		0x04000100
+		0x00000000
+		0x00170180
+		0x00cc0201
+		0x00030066
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x04080000
+		0x04080400
+		0x30000000
+		0x0c00c007
+		0x00000100
+		0x00000000
+		0xfd02fe01
+		0xf708fb04
+		0xdf20ef10
+		0x7f80bf40
+		0x0000aaaa
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00200000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x02800280
+		0x02800280
+		0x02800280
+		0x02800280
+		0x00000280
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00800000
+		0x00800080
+		0x00800080
+		0x00800080
+		0x00800080
+		0x00800080
+		0x00800080
+		0x00800080
+		0x00800080
+		0x01590080
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000200
+		0x00000000
+		0x51315152
+		0xc0003150
+		0x010000c0
+		0x00100c00
+		0x07044204
+		0x000f0c18
+		0x01000140
+		0x00000c10
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000002
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00400320
+		0x00000040
+		0x00dcba98
+		0x00000000
+		0x00dcba98
+		0x01000000
+		0x00020003
+		0x00000000
+		0x00000000
+		0x00000000
+		0x0000002a
+		0x00000015
+		0x00000015
+		0x0000002a
+		0x00000033
+		0x0000000c
+		0x0000000c
+		0x00000033
+		0x0a418820
+		0x003f0000
+		0x0000003f
+		0x00030055
+		0x03000300
+		0x03000300
+		0x000c0300
+		0x42080010
+		0x00000003
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000002
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00400320
+		0x00000040
+		0x00000000
+		0x00000000
+		0x00000000
+		0x01000000
+		0x00020003
+		0x00000000
+		0x00000000
+		0x00000000
+		0x0000002a
+		0x00000015
+		0x00000015
+		0x0000002a
+		0x00000033
+		0x0000000c
+		0x0000000c
+		0x00000033
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00030055
+		0x03000300
+		0x03000300
+		0x000c0300
+		0x42080010
+		0x00000003
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000002
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00400320
+		0x00000040
+		0x00000000
+		0x00000000
+		0x00000000
+		0x01000000
+		0x00020003
+		0x00000000
+		0x00000000
+		0x00000000
+		0x0000002a
+		0x00000015
+		0x00000015
+		0x0000002a
+		0x00000033
+		0x0000000c
+		0x0000000c
+		0x00000033
+		0x1ee6b16a
+		0x10000000
+		0x00000000
+		0x00030055
+		0x03000300
+		0x03000300
+		0x000c0300
+		0x42080010
+		0x00000003
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000005
+		0x04000f01
+		0x00020040
+		0x00020055
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000050
+		0x00000000
+		0x01010100
+		0x00000600
+		0x00000000
+		0x00006400
+		0x09221902
+		0x00000000
+		0x000d1f01
+		0x0d1f0d1f
+		0x0d1f0d1f
+		0x00030003
+		0x03000300
+		0x00000300
+		0x09221902
+		0x00000000
+		0x00000000
+		0x01020000
+		0x00000001
+		0x00000411
+		0x00000411
+		0x00000040
+		0x00000040
+		0x00000411
+		0x00000411
+		0x00004410
+		0x00004410
+		0x00004410
+		0x00004410
+		0x00004410
+		0x00000411
+		0x00004410
+		0x00000411
+		0x00004410
+		0x00000411
+		0x00004410
+		0x00000000
+		0x00000000
+		0x00000000
+		0x64000000
+		0x00000000
+		0x00000000
+		0x00000108
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0xe4000000
+		0x00000000
+		0x00000000
+		0x01010000
+		0x00000000
+	>;
+};
diff --git a/arch/arm/dts/rk3399-u-boot.dtsi b/arch/arm/dts/rk3399-u-boot.dtsi
index fcfce9a..2738a38 100644
--- a/arch/arm/dts/rk3399-u-boot.dtsi
+++ b/arch/arm/dts/rk3399-u-boot.dtsi
@@ -3,6 +3,10 @@
  * Copyright (C) 2019 Jagan Teki <jagan@amarulasolutions.com>
  */
 
+&pmu {
+	u-boot,dm-pre-reloc;
+};
+
 &sdmmc {
 	u-boot,dm-pre-reloc;
 };
diff --git a/arch/arm/include/asm/arch-rockchip/pmu_rk3399.h b/arch/arm/include/asm/arch-rockchip/pmu_rk3399.h
new file mode 100644
index 0000000..f1096dc
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/pmu_rk3399.h
@@ -0,0 +1,72 @@
+/* SPDX-License-Identifier:     GPL-2.0+ */
+/*
+ * (C) Copyright 2018 Rockchip Electronics Co., Ltd.
+ *
+ */
+
+#ifndef __SOC_ROCKCHIP_RK3399_PMU_H__
+#define __SOC_ROCKCHIP_RK3399_PMU_H__
+
+struct rk3399_pmu_regs {
+	u32 pmu_wakeup_cfg[5];
+	u32 pmu_pwrdn_con;
+	u32 pmu_pwrdn_st;
+	u32 pmu_pll_con;
+	u32 pmu_pwrmode_con;
+	u32 pmu_sft_con;
+	u32 pmu_int_con;
+	u32 pmu_int_st;
+	u32 pmu_gpio0_pos_int_con;
+	u32 pmu_gpio0_net_int_con;
+	u32 pmu_gpio1_pos_int_con;
+	u32 pmu_gpio1_net_int_con;
+	u32 pmu_gpio0_pos_int_st;
+	u32 pmu_gpio0_net_int_st;
+	u32 pmu_gpio1_pos_int_st;
+	u32 pmu_gpio1_net_int_st;
+	u32 pmu_pwrdn_inten;
+	u32 pmu_pwrdn_status;
+	u32 pmu_wakeup_status;
+	u32 pmu_bus_clr;
+	u32 pmu_bus_idle_req;
+	u32 pmu_bus_idle_st;
+	u32 pmu_bus_idle_ack;
+	u32 pmu_cci500_con;
+	u32 pmu_adb400_con;
+	u32 pmu_adb400_st;
+	u32 pmu_power_st;
+	u32 pmu_core_pwr_st;
+	u32 pmu_osc_cnt;
+	u32 pmu_plllock_cnt;
+	u32 pmu_pllrst_cnt;
+	u32 pmu_stable_cnt;
+	u32 pmu_ddrio_pwron_cnt;
+	u32 pmu_wakeup_rst_clr_cnt;
+	u32 pmu_ddr_sref_st;
+	u32 pmu_scu_l_pwrdn_cnt;
+	u32 pmu_scu_l_pwrup_cnt;
+	u32 pmu_scu_b_pwrdn_cnt;
+	u32 pmu_scu_b_pwrup_cnt;
+	u32 pmu_gpu_pwrdn_cnt;
+	u32 pmu_gpu_pwrup_cnt;
+	u32 pmu_center_pwrdn_cnt;
+	u32 pmu_center_pwrup_cnt;
+	u32 pmu_timeout_cnt;
+	u32 pmu_cpu0apm_con;
+	u32 pmu_cpu1apm_con;
+	u32 pmu_cpu2apm_con;
+	u32 pmu_cpu3apm_con;
+	u32 pmu_cpu0bpm_con;
+	u32 pmu_cpu1bpm_con;
+	u32 pmu_noc_auto_ena;
+	u32 pmu_pwrdn_con1;
+	u32 reserved0[0x4];
+	u32 pmu_sys_reg_reg0;
+	u32 pmu_sys_reg_reg1;
+	u32 pmu_sys_reg_reg2;
+	u32 pmu_sys_reg_reg3;
+};
+
+check_member(rk3399_pmu_regs, pmu_sys_reg_reg3, 0xfc);
+
+#endif	/* __SOC_ROCKCHIP_RK3399_PMU_H__ */
diff --git a/arch/arm/include/asm/arch-rockchip/sdram.h b/arch/arm/include/asm/arch-rockchip/sdram.h
index bbe425d..9220763 100644
--- a/arch/arm/include/asm/arch-rockchip/sdram.h
+++ b/arch/arm/include/asm/arch-rockchip/sdram.h
@@ -8,12 +8,6 @@
 #ifndef _ASM_ARCH_RK3288_SDRAM_H__
 #define _ASM_ARCH_RK3288_SDRAM_H__
 
-enum {
-	DDR3 = 3,
-	LPDDR3 = 6,
-	UNUSED = 0xFF,
-};
-
 struct rk3288_sdram_channel {
 	/*
 	 * bit width in address, eg:
diff --git a/arch/arm/include/asm/arch-rockchip/sdram_common.h b/arch/arm/include/asm/arch-rockchip/sdram_common.h
index 671c318..8027b53 100644
--- a/arch/arm/include/asm/arch-rockchip/sdram_common.h
+++ b/arch/arm/include/asm/arch-rockchip/sdram_common.h
@@ -5,6 +5,44 @@
 
 #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
+};
+
+struct sdram_cap_info {
+	unsigned int rank;
+	/* dram column number, 0 means this channel is invalid */
+	unsigned int col;
+	/* dram bank number, 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;
+	/*
+	 * row_3_4 = 1: 6Gb or 12Gb die
+	 * row_3_4 = 0: normal die, power of 2
+	 */
+	unsigned int row_3_4;
+	unsigned int cs0_row;
+	unsigned int cs1_row;
+	unsigned int ddrconfig;
+};
+
+struct sdram_base_params {
+	unsigned int ddr_freq;
+	unsigned int dramtype;
+	unsigned int num_channels;
+	unsigned int stride;
+	unsigned int odt;
+};
+
 /*
  * sys_reg bitfield struct
  * [31]		row_3_4_ch1
@@ -28,30 +66,82 @@
  * [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_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))
+
+#define SYS_REG_ENC_VERSION(n)		((n) << 28)
+#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_ENC_CS1_ROW(n, os_reg2, os_reg3, ch) do { \
+			(os_reg2) &= (~(0x3 << (4 + 16 * (ch)))); \
+			(os_reg3) &= (~(0x1 << (4 + 2 * (ch)))); \
+			(os_reg2) |= (((n) - 13) & 0x3) << (4 + 16 * (ch)); \
+			(os_reg3) |= ((((n) - 13) & 0x4) >> 2) << \
+				     (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);
 
 /* Called by U-Boot board_init_r for Rockchip SoCs */
 int dram_init(void);
+
+#if !defined(CONFIG_RAM_ROCKCHIP_DEBUG)
+inline void sdram_print_dram_type(unsigned char dramtype)
+{
+}
+
+inline void sdram_print_ddr_info(struct sdram_cap_info *cap_info,
+				 struct sdram_base_params *base)
+{
+}
+
+inline void sdram_print_stride(unsigned int stride)
+{
+}
+#else
+void sdram_print_dram_type(unsigned char dramtype);
+void sdram_print_ddr_info(struct sdram_cap_info *cap_info,
+			  struct sdram_base_params *base);
+void sdram_print_stride(unsigned int stride);
+#endif /* CONFIG_RAM_ROCKCHIP_DEBUG */
+
 #endif
diff --git a/arch/arm/include/asm/arch-rockchip/sdram_rk322x.h b/arch/arm/include/asm/arch-rockchip/sdram_rk322x.h
index d0091a7..336c5d7 100644
--- a/arch/arm/include/asm/arch-rockchip/sdram_rk322x.h
+++ b/arch/arm/include/asm/arch-rockchip/sdram_rk322x.h
@@ -7,13 +7,6 @@
 
 #include <common.h>
 
-enum {
-	DDR3		= 3,
-	LPDDR2		= 5,
-	LPDDR3		= 6,
-	UNUSED		= 0xFF,
-};
-
 struct rk322x_sdram_channel {
 	/*
 	 * bit width in address, eg:
diff --git a/arch/arm/include/asm/arch-rockchip/sdram_rk3399.h b/arch/arm/include/asm/arch-rockchip/sdram_rk3399.h
index c6a260b..dc65ae7 100644
--- a/arch/arm/include/asm/arch-rockchip/sdram_rk3399.h
+++ b/arch/arm/include/asm/arch-rockchip/sdram_rk3399.h
@@ -6,14 +6,6 @@
 #ifndef _ASM_ARCH_SDRAM_RK3399_H
 #define _ASM_ARCH_SDRAM_RK3399_H
 
-enum {
-	DDR3 = 0x3,
-	LPDDR2 = 0x5,
-	LPDDR3 = 0x6,
-	LPDDR4 = 0x7,
-	UNUSED = 0xFF
-};
-
 struct rk3399_ddr_pctl_regs {
 	u32 denali_ctl[332];
 };
@@ -26,6 +18,31 @@
 	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;
@@ -44,9 +61,9 @@
 struct rk3399_msch_timings {
 	u32 ddrtiminga0;
 	u32 ddrtimingb0;
-	u32 ddrtimingc0;
+	union noc_ddrtimingc0 ddrtimingc0;
 	u32 devtodev0;
-	u32 ddrmode;
+	union noc_ddrmode ddrmode;
 	u32 agingx0;
 };
 
@@ -72,37 +89,13 @@
 #define MEM_RST_VALID	1
 
 struct rk3399_sdram_channel {
-	unsigned int rank;
-	/* dram column number, 0 means this channel is invalid */
-	unsigned int col;
-	/* dram bank number, 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;
-	/*
-	 * row_3_4 = 1: 6Gb or 12Gb die
-	 * row_3_4 = 0: normal die, power of 2
-	 */
-	unsigned int row_3_4;
-	unsigned int cs0_row;
-	unsigned int cs1_row;
-	unsigned int ddrconfig;
+	struct sdram_cap_info cap_info;
 	struct rk3399_msch_timings noc_timings;
 };
 
-struct rk3399_base_params {
-	unsigned int ddr_freq;
-	unsigned int dramtype;
-	unsigned int num_channels;
-	unsigned int stride;
-	unsigned int odt;
-};
-
 struct rk3399_sdram_params {
 	struct rk3399_sdram_channel ch[2];
-	struct rk3399_base_params base;
+	struct sdram_base_params base;
 	struct rk3399_ddr_pctl_regs pctl_regs;
 	struct rk3399_ddr_pi_regs pi_regs;
 	struct rk3399_ddr_publ_regs phy_regs;
diff --git a/arch/arm/include/asm/arch-rockchip/sys_proto.h b/arch/arm/include/asm/arch-rockchip/sys_proto.h
index 928e4f2..905c774 100644
--- a/arch/arm/include/asm/arch-rockchip/sys_proto.h
+++ b/arch/arm/include/asm/arch-rockchip/sys_proto.h
@@ -6,28 +6,6 @@
 #ifndef _ASM_ARCH_SYS_PROTO_H
 #define _ASM_ARCH_SYS_PROTO_H
 
-#ifdef CONFIG_ROCKCHIP_RK3288
-#include <asm/armv7.h>
-
-static void configure_l2ctlr(void)
-{
-	uint32_t l2ctlr;
-
-	l2ctlr = read_l2ctlr();
-	l2ctlr &= 0xfffc0000; /* clear bit0~bit17 */
-
-	/*
-	* Data RAM write latency: 2 cycles
-	* Data RAM read latency: 2 cycles
-	* Data RAM setup latency: 1 cycle
-	* Tag RAM write latency: 1 cycle
-	* Tag RAM read latency: 1 cycle
-	* Tag RAM setup latency: 1 cycle
-	*/
-	l2ctlr |= (1 << 3 | 1 << 0);
-	write_l2ctlr(l2ctlr);
-}
-#endif /* CONFIG_ROCKCHIP_RK3288 */
 
 /* provided to defeat compiler optimisation in board_init_f() */
 void gru_dummy_function(int i);
diff --git a/arch/arm/include/asm/arch-rockchip/timer.h b/arch/arm/include/asm/arch-rockchip/timer.h
index a8379be..77b5422 100644
--- a/arch/arm/include/asm/arch-rockchip/timer.h
+++ b/arch/arm/include/asm/arch-rockchip/timer.h
@@ -15,7 +15,4 @@
 	u32 timer_int_status;
 };
 
-void rockchip_timer_init(void);
-void rockchip_udelay(unsigned int usec);
-
 #endif
diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig
index 1090d21..17f31e8 100644
--- a/arch/arm/mach-rockchip/Kconfig
+++ b/arch/arm/mach-rockchip/Kconfig
@@ -59,6 +59,8 @@
 	select SPL_DRIVERS_MISC_SUPPORT
 	imply SPL_SERIAL_SUPPORT
 	imply TPL_SERIAL_SUPPORT
+	imply TPL_BOOTROM_SUPPORT
+	imply TPL_ROCKCHIP_COMMON_BOARD
 	select ROCKCHIP_BROM_HELPER
 	select TPL_LIBCOMMON_SUPPORT
 	select TPL_LIBGENERIC_SUPPORT
@@ -68,19 +70,6 @@
 	  and video codec support. Peripherals include Gigabit Ethernet,
 	  USB2 host and OTG, SDIO, I2S, UART, SPI, I2C and PWMs.
 
-if ROCKCHIP_RK322X
-
-config TPL_TEXT_BASE
-        default 0x10081000
-
-config TPL_MAX_SIZE
-        default 28672
-
-config TPL_STACK
-        default 0x10088000
-
-endif
-
 config ROCKCHIP_RK3288
 	bool "Support Rockchip RK3288"
 	select CPU_V7A
@@ -100,6 +89,7 @@
 	imply TPL_OF_PLATDATA
 	imply TPL_RAM
 	imply TPL_REGMAP
+	imply TPL_ROCKCHIP_COMMON_BOARD
 	imply TPL_SERIAL_SUPPORT
 	imply TPL_SYSCON
 	imply USB_FUNCTION_ROCKUSB
@@ -111,19 +101,6 @@
 	  and video codec support. Peripherals include Gigabit Ethernet,
 	  USB2 host and OTG, SDIO, I2S, UARTs, SPI, I2C and PWMs.
 
-if ROCKCHIP_RK3288
-
-config TPL_TEXT_BASE
-	default 0xff704000
-
-config TPL_MAX_SIZE
-	default 32768
-
-config TPL_STACK
-        default 0xff718000
-
-endif
-
 config ROCKCHIP_RK3328
 	bool "Support Rockchip RK3328"
 	select ARM64
@@ -151,6 +128,7 @@
 	imply SPL_SEPARATE_BSS
 	imply SPL_SERIAL_SUPPORT
 	imply TPL_SERIAL_SUPPORT
+	imply TPL_ROCKCHIP_COMMON_BOARD
 	help
 	  The Rockchip RK3368 is a ARM-based SoC with a octa-core (organised
 	  into a big and little cluster with 4 cores each) Cortex-A53 including
@@ -162,19 +140,6 @@
 	  On-chip peripherals include Gigabit Ethernet, USB2 host and OTG, SDIO,
 	  I2S, UARTs, SPI, I2C and PWMs.
 
-if ROCKCHIP_RK3368
-
-config TPL_TEXT_BASE
-        default 0xff8c1000
-
-config TPL_MAX_SIZE
-        default 28672
-
-config TPL_STACK
-        default 0xff8cffff
-
-endif
-
 config ROCKCHIP_RK3399
 	bool "Support Rockchip RK3399"
 	select ARM64
@@ -209,7 +174,6 @@
 	imply TPL_LIBCOMMON_SUPPORT
 	imply TPL_LIBGENERIC_SUPPORT
 	imply TPL_SYS_MALLOC_SIMPLE
-	imply TPL_BOARD_INIT
 	imply TPL_BOOTROM_SUPPORT
 	imply TPL_DRIVERS_MISC_SUPPORT
 	imply TPL_OF_CONTROL
@@ -219,6 +183,7 @@
 	imply TPL_RAM
 	imply TPL_CLK
 	imply TPL_TINY_MEMSET
+	imply TPL_ROCKCHIP_COMMON_BOARD
 	help
 	  The Rockchip RK3399 is a ARM-based SoC with a dual-core Cortex-A72
 	  and quad-core Cortex-A53.
@@ -227,22 +192,6 @@
 	  and video codec support. Peripherals include Gigabit Ethernet,
 	  USB2 host and OTG, SDIO, I2S, UARTs, SPI, I2C and PWMs.
 
-if ROCKCHIP_RK3399
-
-config TPL_LDSCRIPT
-	default "arch/arm/mach-rockchip/u-boot-tpl-v8.lds"
-
-config TPL_TEXT_BASE
-        default 0xff8c2000
-
-config TPL_MAX_SIZE
-        default 188416
-
-config TPL_STACK
-        default 0xff8effff
-
-endif
-
 config ROCKCHIP_RV1108
 	bool "Support Rockchip RV1108"
 	select CPU_V7A
@@ -278,16 +227,17 @@
           SPL will return to the boot rom, which will then load the U-Boot
           binary to keep going on.
 
+config TPL_ROCKCHIP_COMMON_BOARD
+	bool ""
+	depends on TPL
+	help
+	  Rockchip SoCs have similar boot process, prefer to use TPL for DRAM
+	  init and back to bootrom, and SPL as Trust ATF/U-Boot loader. TPL
+	  common board is a basic TPL board init which can be shared for most
+	  of SoCs to avoid copy-pase for different SoCs.
+
 config ROCKCHIP_BOOT_MODE_REG
 	hex "Rockchip boot mode flag register address"
-	default 0x200081c8 if ROCKCHIP_RK3036
-	default 0x20004040 if ROCKCHIP_RK3188
-	default 0x110005c8 if ROCKCHIP_RK322X
-	default 0xff730094 if ROCKCHIP_RK3288
-	default 0xff738200 if ROCKCHIP_RK3368
-	default 0xff320300 if ROCKCHIP_RK3399
-	default 0x10300580 if ROCKCHIP_RV1108
-	default 0
 	help
 	  The Soc will enter to different boot mode(defined in asm/arch-rockchip/boot_mode.h)
 	  according to the value from this register.
diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile
index 23760a9..a12b8d4 100644
--- a/arch/arm/mach-rockchip/Makefile
+++ b/arch/arm/mach-rockchip/Makefile
@@ -8,16 +8,12 @@
 # the stack-pointer is valid before switching to the U-Boot stack).
 obj-spl-$(CONFIG_ROCKCHIP_BROM_HELPER) += bootrom.o
 obj-tpl-$(CONFIG_ROCKCHIP_BROM_HELPER) += bootrom.o
-
-obj-tpl-$(CONFIG_ROCKCHIP_RK3288) += rk3288-board-tpl.o
-obj-tpl-$(CONFIG_ROCKCHIP_RK3368) += rk3368-board-tpl.o
-obj-tpl-$(CONFIG_ROCKCHIP_RK322X) += rk322x-board-tpl.o
-obj-tpl-$(CONFIG_ROCKCHIP_RK3399) += rk3399-board-tpl.o
+obj-tpl-$(CONFIG_TPL_ROCKCHIP_COMMON_BOARD) += tpl.o
 
 obj-spl-$(CONFIG_ROCKCHIP_RK3036) += rk3036-board-spl.o
 obj-spl-$(CONFIG_ROCKCHIP_RK3188) += rk3188-board-spl.o
 obj-spl-$(CONFIG_ROCKCHIP_RK322X) += rk322x-board-spl.o spl-boot-order.o
-obj-spl-$(CONFIG_ROCKCHIP_RK3288) += rk3288-board-spl.o
+obj-spl-$(CONFIG_ROCKCHIP_RK3288) += rk3288-board-spl.o spl-boot-order.o
 obj-spl-$(CONFIG_ROCKCHIP_RK3328) += rk3328-board-spl.o
 obj-spl-$(CONFIG_ROCKCHIP_RK3368) += rk3368-board-spl.o spl-boot-order.o
 obj-spl-$(CONFIG_ROCKCHIP_RK3399) += rk3399-board-spl.o spl-boot-order.o
@@ -41,12 +37,6 @@
 
 obj-$(CONFIG_$(SPL_TPL_)RAM) += sdram_common.o
 
-ifndef CONFIG_ARM64
-ifndef CONFIG_ROCKCHIP_RK3188
-obj-y += rk_timer.o
-endif
-endif
-
 obj-$(CONFIG_ROCKCHIP_RK3036) += rk3036/
 obj-$(CONFIG_ROCKCHIP_RK3128) += rk3128/
 ifndef CONFIG_TPL_BUILD
diff --git a/arch/arm/mach-rockchip/make_fit_atf.py b/arch/arm/mach-rockchip/make_fit_atf.py
index db0ae96..b9a1988 100755
--- a/arch/arm/mach-rockchip/make_fit_atf.py
+++ b/arch/arm/mach-rockchip/make_fit_atf.py
@@ -13,16 +13,7 @@
 import sys
 import getopt
 import logging
-
-# pip install pyelftools
-from elftools.elf.elffile import ELFFile
-
-ELF_SEG_P_TYPE = 'p_type'
-ELF_SEG_P_PADDR = 'p_paddr'
-ELF_SEG_P_VADDR = 'p_vaddr'
-ELF_SEG_P_OFFSET = 'p_offset'
-ELF_SEG_P_FILESZ = 'p_filesz'
-ELF_SEG_P_MEMSZ = 'p_memsz'
+import struct
 
 DT_HEADER = """
 /*
@@ -118,33 +109,19 @@
     file.write('\n')
 
 def generate_atf_fit_dts_uboot(fit_file, uboot_file_name):
-    num_load_seg = 0
-    p_paddr = 0xFFFFFFFF
-    with open(uboot_file_name, 'rb') as uboot_file:
-        uboot = ELFFile(uboot_file)
-        for i in range(uboot.num_segments()):
-            seg = uboot.get_segment(i)
-            if seg.__getitem__(ELF_SEG_P_TYPE) == 'PT_LOAD':
-                p_paddr = seg.__getitem__(ELF_SEG_P_PADDR)
-                num_load_seg = num_load_seg + 1
-
-    assert (p_paddr != 0xFFFFFFFF and num_load_seg == 1)
-
+    segments = unpack_elf(uboot_file_name)
+    if len(segments) != 1:
+        raise ValueError("Invalid u-boot ELF image '%s'" % uboot_file_name)
+    index, entry, p_paddr, data = segments[0]
     fit_file.write(DT_UBOOT % p_paddr)
 
 def generate_atf_fit_dts_bl31(fit_file, bl31_file_name, dtbs_file_name):
-    with open(bl31_file_name, 'rb') as bl31_file:
-        bl31 = ELFFile(bl31_file)
-        elf_entry = bl31.header['e_entry']
-        segments = bl31.num_segments()
-        for i in range(segments):
-            seg = bl31.get_segment(i)
-            if seg.__getitem__(ELF_SEG_P_TYPE) == 'PT_LOAD':
-                paddr = seg.__getitem__(ELF_SEG_P_PADDR)
-                append_bl31_node(fit_file, i + 1, paddr, elf_entry)
+    segments = unpack_elf(bl31_file_name)
+    for index, entry, paddr, data in segments:
+        append_bl31_node(fit_file, index + 1, paddr, entry)
     append_fdt_node(fit_file, dtbs_file_name)
     fit_file.write(DT_IMAGES_NODE_END)
-    append_conf_node(fit_file, dtbs_file_name, segments)
+    append_conf_node(fit_file, dtbs_file_name, len(segments))
 
 def generate_atf_fit_dts(fit_file_name, bl31_file_name, uboot_file_name, dtbs_file_name):
     # Generate FIT script for ATF image.
@@ -162,17 +139,29 @@
         fit_file.close()
 
 def generate_atf_binary(bl31_file_name):
-    with open(bl31_file_name, 'rb') as bl31_file:
-        bl31 = ELFFile(bl31_file)
+    for index, entry, paddr, data in unpack_elf(bl31_file_name):
+        file_name = 'bl31_0x%08x.bin' % paddr
+        with open(file_name, "wb") as atf:
+            atf.write(data)
 
-        num = bl31.num_segments()
-        for i in range(num):
-            seg = bl31.get_segment(i)
-            if seg.__getitem__(ELF_SEG_P_TYPE) == 'PT_LOAD':
-                paddr = seg.__getitem__(ELF_SEG_P_PADDR)
-                file_name = 'bl31_0x%08x.bin' % paddr
-                with open(file_name, "wb") as atf:
-                    atf.write(seg.data())
+def unpack_elf(filename):
+    with open(filename, 'rb') as file:
+        elf = file.read()
+    if elf[0:7] != b'\x7fELF\x02\x01\x01' or elf[18:20] != b'\xb7\x00':
+        raise ValueError("Invalid arm64 ELF file '%s'" % filename)
+
+    e_entry, e_phoff = struct.unpack_from('<2Q', elf, 0x18)
+    e_phentsize, e_phnum = struct.unpack_from('<2H', elf, 0x36)
+    segments = []
+
+    for index in range(e_phnum):
+        offset = e_phoff + e_phentsize * index
+        p_type, p_flags, p_offset = struct.unpack_from('<LLQ', elf, offset)
+        if p_type == 1: # PT_LOAD
+            p_paddr, p_filesz = struct.unpack_from('<2Q', elf, offset + 0x18)
+            p_data = elf[p_offset:p_offset + p_filesz]
+            segments.append((index, e_entry, p_paddr, p_data))
+    return segments
 
 def main():
     uboot_elf = "./u-boot"
diff --git a/arch/arm/mach-rockchip/rk3036-board-spl.c b/arch/arm/mach-rockchip/rk3036-board-spl.c
index 110d06d..fbc89b6 100644
--- a/arch/arm/mach-rockchip/rk3036-board-spl.c
+++ b/arch/arm/mach-rockchip/rk3036-board-spl.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- * (C) Copyright 2015 Rockchip Electronics Co., Ltd
+ * (C) Copyright 2015-2019 Rockchip Electronics Co., Ltd
  */
 
 #include <common.h>
@@ -8,14 +8,37 @@
 #include <asm/io.h>
 #include <asm/arch-rockchip/bootrom.h>
 #include <asm/arch-rockchip/sdram_rk3036.h>
-#include <asm/arch-rockchip/timer.h>
+
+#define TIMER_LOAD_COUNT_L	0x00
+#define TIMER_LOAD_COUNT_H	0x04
+#define TIMER_CONTROL_REG	0x10
+#define TIMER_EN	0x1
+#define	TIMER_FMODE	(0 << 1)
+#define	TIMER_RMODE	(1 << 1)
+
+void rockchip_stimer_init(void)
+{
+	asm volatile("mcr p15, 0, %0, c14, c0, 0"
+		     : : "r"(COUNTER_FREQUENCY));
+
+	writel(0, CONFIG_ROCKCHIP_STIMER_BASE + TIMER_CONTROL_REG);
+	writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE);
+	writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE + 4);
+	writel(TIMER_EN | TIMER_FMODE, CONFIG_ROCKCHIP_STIMER_BASE +
+	       TIMER_CONTROL_REG);
+}
 
 void board_init_f(ulong dummy)
 {
 #ifdef CONFIG_DEBUG_UART
 	debug_uart_init();
 #endif
-	rockchip_timer_init();
+
+	/* Init secure timer */
+	rockchip_stimer_init();
+	/* Init ARM arch timer in arch/arm/cpu/armv7/arch_timer.c */
+	timer_init();
+
 	sdram_init();
 
 	/* return to maskrom */
diff --git a/arch/arm/mach-rockchip/rk3036-board.c b/arch/arm/mach-rockchip/rk3036-board.c
index e6ea0e9..c594c4d 100644
--- a/arch/arm/mach-rockchip/rk3036-board.c
+++ b/arch/arm/mach-rockchip/rk3036-board.c
@@ -14,7 +14,6 @@
 #include <asm/arch-rockchip/grf_rk3036.h>
 #include <asm/arch-rockchip/boot_mode.h>
 #include <asm/arch-rockchip/sdram_rk3036.h>
-#include <dm/pinctrl.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
diff --git a/arch/arm/mach-rockchip/rk3036/Kconfig b/arch/arm/mach-rockchip/rk3036/Kconfig
index 5e04d20..51cd43b 100644
--- a/arch/arm/mach-rockchip/rk3036/Kconfig
+++ b/arch/arm/mach-rockchip/rk3036/Kconfig
@@ -1,5 +1,8 @@
 if ROCKCHIP_RK3036
 
+choice
+	prompt "RK3036 board select"
+
 config TARGET_EVB_RK3036
 	bool "EVB_RK3036"
 	select BOARD_LATE_INIT
@@ -8,6 +11,11 @@
 	bool "KYLIN_RK3036"
 	select BOARD_LATE_INIT
 
+endchoice
+
+config ROCKCHIP_BOOT_MODE_REG
+	default 0x200081c8
+
 config SYS_SOC
 	default "rk3036"
 
diff --git a/arch/arm/mach-rockchip/rk3036/sdram_rk3036.c b/arch/arm/mach-rockchip/rk3036/sdram_rk3036.c
index 1d940a0..c39cbb8 100644
--- a/arch/arm/mach-rockchip/rk3036/sdram_rk3036.c
+++ b/arch/arm/mach-rockchip/rk3036/sdram_rk3036.c
@@ -9,7 +9,6 @@
 #include <asm/arch-rockchip/grf_rk3036.h>
 #include <asm/arch-rockchip/hardware.h>
 #include <asm/arch-rockchip/sdram_rk3036.h>
-#include <asm/arch-rockchip/timer.h>
 #include <asm/arch-rockchip/uart.h>
 
 /*
@@ -345,7 +344,7 @@
 
 	/* waiting for pll lock */
 	while (readl(&pll->con1) & (1 << PLL_LOCK_STATUS_SHIFT))
-		rockchip_udelay(1);
+		udelay(1);
 
 	/* PLL enter normal-mode */
 	rk_clrsetreg(&priv->cru->cru_mode_con, DPLL_MODE_MASK,
@@ -373,25 +372,25 @@
 			1 << DDRCTRL_PSRST_SHIFT | 1 << DDRCTRL_SRST_SHIFT |
 			1 << DDRPHY_PSRST_SHIFT | 1 << DDRPHY_SRST_SHIFT);
 
-	rockchip_udelay(10);
+	udelay(10);
 
 	rk_clrreg(&priv->cru->cru_softrst_con[5], 1 << DDRPHY_PSRST_SHIFT |
 						  1 << DDRPHY_SRST_SHIFT);
-	rockchip_udelay(10);
+	udelay(10);
 
 	rk_clrreg(&priv->cru->cru_softrst_con[5], 1 << DDRCTRL_PSRST_SHIFT |
 						  1 << DDRCTRL_SRST_SHIFT);
-	rockchip_udelay(10);
+	udelay(10);
 
 	clrsetbits_le32(&ddr_phy->ddrphy_reg1,
 			SOFT_RESET_MASK << SOFT_RESET_SHIFT,
 			0 << SOFT_RESET_SHIFT);
-	rockchip_udelay(10);
+	udelay(10);
 	clrsetbits_le32(&ddr_phy->ddrphy_reg1,
 			SOFT_RESET_MASK << SOFT_RESET_SHIFT,
 			3 << SOFT_RESET_SHIFT);
 
-	rockchip_udelay(1);
+	udelay(1);
 }
 
 void phy_dll_bypass_set(struct rk3036_sdram_priv *priv, unsigned int freq)
@@ -444,7 +443,7 @@
 			 u32 rank, u32 cmd, u32 arg)
 {
 	writel((START_CMD | (rank << 20) | arg | cmd), &pctl->mcmd);
-	rockchip_udelay(1);
+	udelay(1);
 	while (readl(&pctl->mcmd) & START_CMD)
 		;
 }
@@ -454,7 +453,7 @@
 	struct rk3036_ddr_pctl *pctl = priv->pctl;
 
 	send_command(pctl, 3, DESELECT_CMD, 0);
-	rockchip_udelay(1);
+	udelay(1);
 	send_command(pctl, 3, PREA_CMD, 0);
 	send_command(pctl, 3, MRS_CMD,
 		     (0x02 & BANK_ADDR_MASK) << BANK_ADDR_SHIFT |
@@ -492,7 +491,7 @@
 	clrsetbits_le32(&ddr_phy->ddrphy_reg2, 0x03,
 			DQS_SQU_CAL_NORMAL_MODE | DQS_SQU_CAL_START);
 
-	rockchip_udelay(1);
+	udelay(1);
 	while ((readl(&ddr_phy->ddrphy_reg62) & CAL_DONE_MASK) !=
 		(HIGH_8BIT_CAL_DONE | LOW_8BIT_CAL_DONE)) {
 		;
diff --git a/arch/arm/mach-rockchip/rk3128-board.c b/arch/arm/mach-rockchip/rk3128-board.c
index fa71685..0945829 100644
--- a/arch/arm/mach-rockchip/rk3128-board.c
+++ b/arch/arm/mach-rockchip/rk3128-board.c
@@ -12,7 +12,6 @@
 #include <asm/arch-rockchip/periph.h>
 #include <asm/arch-rockchip/grf_rk3128.h>
 #include <asm/arch-rockchip/boot_mode.h>
-#include <asm/arch-rockchip/timer.h>
 #include <power/regulator.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -33,8 +32,6 @@
 {
 	int ret = 0;
 
-	rockchip_timer_init();
-
 	ret = regulators_enable_boot_on(false);
 	if (ret) {
 		debug("%s: Cannot enable boot on regulator\n", __func__);
diff --git a/arch/arm/mach-rockchip/rk3128/Kconfig b/arch/arm/mach-rockchip/rk3128/Kconfig
index a82b7dc..b867401 100644
--- a/arch/arm/mach-rockchip/rk3128/Kconfig
+++ b/arch/arm/mach-rockchip/rk3128/Kconfig
@@ -13,6 +13,9 @@
 
 endchoice
 
+config ROCKCHIP_BOOT_MODE_REG
+	default 0x100a0038
+
 config SYS_SOC
 	default "rk3128"
 
diff --git a/arch/arm/mach-rockchip/rk3188-board-spl.c b/arch/arm/mach-rockchip/rk3188-board-spl.c
index 77b9b36..c3efe0d 100644
--- a/arch/arm/mach-rockchip/rk3188-board-spl.c
+++ b/arch/arm/mach-rockchip/rk3188-board-spl.c
@@ -22,8 +22,6 @@
 #include <asm/arch-rockchip/periph.h>
 #include <asm/arch-rockchip/pmu_rk3188.h>
 #include <asm/arch-rockchip/sdram.h>
-#include <asm/arch-rockchip/timer.h>
-#include <dm/pinctrl.h>
 #include <dm/root.h>
 #include <dm/test.h>
 #include <dm/util.h>
diff --git a/arch/arm/mach-rockchip/rk3188-board.c b/arch/arm/mach-rockchip/rk3188-board.c
index 80d8c42..94fd6c0 100644
--- a/arch/arm/mach-rockchip/rk3188-board.c
+++ b/arch/arm/mach-rockchip/rk3188-board.c
@@ -15,7 +15,6 @@
 #include <asm/arch-rockchip/periph.h>
 #include <asm/arch-rockchip/pmu_rk3288.h>
 #include <asm/arch-rockchip/boot_mode.h>
-#include <dm/pinctrl.h>
 
 __weak int rk_board_late_init(void)
 {
@@ -42,37 +41,7 @@
 
 int board_init(void)
 {
-#if CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM)
-	struct udevice *pinctrl;
-	int ret;
-
-	/*
-	 * We need to implement sdcard iomux here for the further
-	 * initialization, otherwise, it'll hit sdcard command sending
-	 * timeout exception.
-	 */
-	ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl);
-	if (ret) {
-		debug("%s: Cannot find pinctrl device\n", __func__);
-		goto err;
-	}
-	ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_SDCARD);
-	if (ret) {
-		debug("%s: Failed to set up SD card\n", __func__);
-		goto err;
-	}
-
 	return 0;
-err:
-	printf("board_init: Error %d\n", ret);
-
-	/* No way to report error here */
-	hang();
-
-	return -1;
-#else
-	return 0;
-#endif
 }
 
 #if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
diff --git a/arch/arm/mach-rockchip/rk3188/Kconfig b/arch/arm/mach-rockchip/rk3188/Kconfig
index a6fc691..e24e68e 100644
--- a/arch/arm/mach-rockchip/rk3188/Kconfig
+++ b/arch/arm/mach-rockchip/rk3188/Kconfig
@@ -9,6 +9,9 @@
 	  Expansion connectors provide access to display pins, I2C, SPI,
 	  UART and GPIOs.
 
+config ROCKCHIP_BOOT_MODE_REG
+	default 0x20004040
+
 config SYS_SOC
 	default "rk3188"
 
diff --git a/arch/arm/mach-rockchip/rk322x-board-spl.c b/arch/arm/mach-rockchip/rk322x-board-spl.c
index c9b41c6..c825e31 100644
--- a/arch/arm/mach-rockchip/rk322x-board-spl.c
+++ b/arch/arm/mach-rockchip/rk322x-board-spl.c
@@ -19,6 +19,31 @@
 	return MMCSD_MODE_RAW;
 }
 
+#define TIMER_LOAD_COUNT_L	0x00
+#define TIMER_LOAD_COUNT_H	0x04
+#define TIMER_CONTROL_REG	0x10
+#define TIMER_EN	0x1
+#define	TIMER_FMODE	BIT(0)
+#define	TIMER_RMODE	BIT(1)
+
+void rockchip_stimer_init(void)
+{
+	/* If Timer already enabled, don't re-init it */
+	u32 reg = readl(CONFIG_ROCKCHIP_STIMER_BASE + TIMER_CONTROL_REG);
+
+	if (reg & TIMER_EN)
+		return;
+
+	asm volatile("mcr p15, 0, %0, c14, c0, 0"
+		     : : "r"(COUNTER_FREQUENCY));
+
+	writel(0, CONFIG_ROCKCHIP_STIMER_BASE + TIMER_CONTROL_REG);
+	writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE);
+	writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE + 4);
+	writel(TIMER_EN | TIMER_FMODE, CONFIG_ROCKCHIP_STIMER_BASE +
+	       TIMER_CONTROL_REG);
+}
+
 #define SGRF_DDR_CON0 0x10150000
 void board_init_f(ulong dummy)
 {
@@ -31,6 +56,11 @@
 	}
 	preloader_console_init();
 
+	/* Init secure timer */
+	rockchip_stimer_init();
+	/* Init ARM arch timer in arch/arm/cpu/armv7/arch_timer.c */
+	timer_init();
+
 	/* Disable the ddr secure region setting to make it non-secure */
 	rk_clrreg(SGRF_DDR_CON0, 0x4000);
 }
diff --git a/arch/arm/mach-rockchip/rk322x-board-tpl.c b/arch/arm/mach-rockchip/rk322x-board-tpl.c
deleted file mode 100644
index 92d40ee..0000000
--- a/arch/arm/mach-rockchip/rk322x-board-tpl.c
+++ /dev/null
@@ -1,53 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * (C) Copyright 2019 Rockchip Electronics Co., Ltd
- */
-
-#include <common.h>
-#include <debug_uart.h>
-#include <dm.h>
-#include <ram.h>
-#include <spl.h>
-#include <asm/io.h>
-#include <asm/arch-rockchip/bootrom.h>
-#include <asm/arch-rockchip/timer.h>
-
-u32 spl_boot_device(void)
-{
-	return BOOT_DEVICE_MMC1;
-}
-
-void board_init_f(ulong dummy)
-{
-	struct udevice *dev;
-	int ret;
-
-	/*
-	 * Debug UART can be used from here if required:
-	 *
-	 * debug_uart_init();
-	 * printch('a');
-	 * printhex8(0x1234);
-	 * printascii("string");
-	 */
-	debug_uart_init();
-	printascii("TPL Init");
-
-	ret = spl_early_init();
-	if (ret) {
-		debug("spl_early_init() failed: %d\n", ret);
-		hang();
-	}
-
-	rockchip_timer_init();
-	printf("timer init done\n");
-	ret = uclass_get_device(UCLASS_RAM, 0, &dev);
-	if (ret) {
-		printf("DRAM init failed: %d\n", ret);
-		return;
-	}
-
-#if defined(CONFIG_TPL_ROCKCHIP_BACK_TO_BROM) && !defined(CONFIG_TPL_BOARD_INIT)
-	back_to_bootrom(BROM_BOOT_NEXTSTAGE);
-#endif
-}
diff --git a/arch/arm/mach-rockchip/rk322x/Kconfig b/arch/arm/mach-rockchip/rk322x/Kconfig
index 8a1f95f..2fc6f6e 100644
--- a/arch/arm/mach-rockchip/rk322x/Kconfig
+++ b/arch/arm/mach-rockchip/rk322x/Kconfig
@@ -1,18 +1,37 @@
 if ROCKCHIP_RK322X
 
+
 config TARGET_EVB_RK3229
 	bool "EVB_RK3229"
 	select BOARD_LATE_INIT
 
+config ROCKCHIP_BOOT_MODE_REG
+	default 0x110005c8
+
 config SYS_SOC
 	default "rk322x"
 
 config SYS_MALLOC_F_LEN
-	default 0x400
+	default 0x800
+
+config SPL_LIBCOMMON_SUPPORT
+	default y
+
+config SPL_LIBGENERIC_SUPPORT
+	default y
 
 config SPL_SERIAL_SUPPORT
 	default y
 
+config TPL_MAX_SIZE
+        default 28672
+
+config TPL_STACK
+        default 0x10088000
+
+config TPL_TEXT_BASE
+        default 0x10081000
+
 source "board/rockchip/evb_rk3229/Kconfig"
 
 endif
diff --git a/arch/arm/mach-rockchip/rk3288-board-spl.c b/arch/arm/mach-rockchip/rk3288-board-spl.c
index d8d215d..c2e1681 100644
--- a/arch/arm/mach-rockchip/rk3288-board-spl.c
+++ b/arch/arm/mach-rockchip/rk3288-board-spl.c
@@ -22,8 +22,6 @@
 #include <asm/arch-rockchip/sdram.h>
 #include <asm/arch-rockchip/sdram_common.h>
 #include <asm/arch-rockchip/sys_proto.h>
-#include <asm/arch-rockchip/timer.h>
-#include <dm/pinctrl.h>
 #include <dm/root.h>
 #include <dm/test.h>
 #include <dm/util.h>
@@ -104,6 +102,36 @@
 }
 #endif
 
+__weak int arch_cpu_init(void)
+{
+	return 0;
+}
+
+#define TIMER_LOAD_COUNT_L	0x00
+#define TIMER_LOAD_COUNT_H	0x04
+#define TIMER_CONTROL_REG	0x10
+#define TIMER_EN	0x1
+#define	TIMER_FMODE	BIT(0)
+#define	TIMER_RMODE	BIT(1)
+
+void rockchip_stimer_init(void)
+{
+	/* If Timer already enabled, don't re-init it */
+	u32 reg = readl(CONFIG_ROCKCHIP_STIMER_BASE + TIMER_CONTROL_REG);
+
+	if (reg & TIMER_EN)
+		return;
+
+	asm volatile("mcr p15, 0, %0, c14, c0, 0"
+		     : : "r"(COUNTER_FREQUENCY));
+
+	writel(0, CONFIG_ROCKCHIP_STIMER_BASE + TIMER_CONTROL_REG);
+	writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE);
+	writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE + 4);
+	writel(TIMER_EN | TIMER_FMODE, CONFIG_ROCKCHIP_STIMER_BASE +
+	       TIMER_CONTROL_REG);
+}
+
 void board_init_f(ulong dummy)
 {
 	struct udevice *dev;
@@ -127,8 +155,12 @@
 		hang();
 	}
 
-	rockchip_timer_init();
-	configure_l2ctlr();
+	/* Init secure timer */
+	rockchip_stimer_init();
+	/* Init ARM arch timer in arch/arm/cpu/armv7/arch_timer.c */
+	timer_init();
+
+	arch_cpu_init();
 
 	ret = rockchip_get_clk(&dev);
 	if (ret) {
diff --git a/arch/arm/mach-rockchip/rk3288-board-tpl.c b/arch/arm/mach-rockchip/rk3288-board-tpl.c
deleted file mode 100644
index 787129b..0000000
--- a/arch/arm/mach-rockchip/rk3288-board-tpl.c
+++ /dev/null
@@ -1,70 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright (C) 2017 Amarula Solutions
- */
-
-#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/clock.h>
-#include <asm/arch-rockchip/sys_proto.h>
-#include <asm/arch-rockchip/timer.h>
-
-void board_init_f(ulong dummy)
-{
-	struct udevice *dev;
-	int ret;
-
-#ifdef CONFIG_DEBUG_UART
-	/*
-	 * Debug UART can be used from here if required:
-	 *
-	 * debug_uart_init();
-	 * printch('a');
-	 * printhex8(0x1234);
-	 * printascii("string");
-	 */
-	debug_uart_init();
-#endif
-	ret = spl_early_init();
-	if (ret) {
-		debug("spl_early_init() failed: %d\n", ret);
-		hang();
-	}
-
-	rockchip_timer_init();
-	configure_l2ctlr();
-
-	ret = rockchip_get_clk(&dev);
-	if (ret) {
-		debug("CLK init failed: %d\n", ret);
-		return;
-	}
-
-	ret = uclass_get_device(UCLASS_RAM, 0, &dev);
-	if (ret) {
-		debug("DRAM init failed: %d\n", ret);
-		return;
-	}
-}
-
-void board_return_to_bootrom(void)
-{
-	back_to_bootrom(BROM_BOOT_NEXTSTAGE);
-}
-
-u32 spl_boot_device(void)
-{
-	return BOOT_DEVICE_BOOTROM;
-}
-
-void spl_board_init(void)
-{
-	puts("\nU-Boot TPL " PLAIN_VERSION " (" U_BOOT_DATE " - " \
-				U_BOOT_TIME ")\n");
-}
diff --git a/arch/arm/mach-rockchip/rk3288-board.c b/arch/arm/mach-rockchip/rk3288-board.c
index e2de5b2..a250d50 100644
--- a/arch/arm/mach-rockchip/rk3288-board.c
+++ b/arch/arm/mach-rockchip/rk3288-board.c
@@ -16,7 +16,6 @@
 #include <asm/arch-rockchip/qos_rk3288.h>
 #include <asm/arch-rockchip/boot_mode.h>
 #include <asm/gpio.h>
-#include <dm/pinctrl.h>
 #include <dt-bindings/clock/rk3288-cru.h>
 #include <power/regulator.h>
 
@@ -145,33 +144,7 @@
 int board_init(void)
 {
 #if CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM)
-	struct udevice *pinctrl;
-	int ret;
-
-	/*
-	 * We need to implement sdcard iomux here for the further
-	 * initlization, otherwise, it'll hit sdcard command sending
-	 * timeout exception.
-	 */
-	ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl);
-	if (ret) {
-		debug("%s: Cannot find pinctrl device\n", __func__);
-		goto err;
-	}
-	ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_SDCARD);
-	if (ret) {
-		debug("%s: Failed to set up SD card\n", __func__);
-		goto err;
-	}
-
 	return 0;
-err:
-	printf("board_init: Error %d\n", ret);
-
-	/* No way to report error here */
-	hang();
-
-	return -1;
 #else
 	int ret;
 
diff --git a/arch/arm/mach-rockchip/rk3288/Kconfig b/arch/arm/mach-rockchip/rk3288/Kconfig
index c5dcd06..de8d9c2 100644
--- a/arch/arm/mach-rockchip/rk3288/Kconfig
+++ b/arch/arm/mach-rockchip/rk3288/Kconfig
@@ -1,5 +1,8 @@
 if ROCKCHIP_RK3288
 
+choice
+	prompt "RK3288 board select"
+
 config TARGET_CHROMEBOOK_JERRY
 	bool "Google/Rockchip Veyron-Jerry Chromebook"
 	select BOARD_LATE_INIT
@@ -44,6 +47,7 @@
 config TARGET_EVB_RK3288
 	bool "Evb-RK3288"
 	select BOARD_LATE_INIT
+	select TPL
 	help
 	  EVB-RK3288 is a RK3288-based development board with 2 USB ports,
 	  HDMI, VGA, micro-SD card, audio, WiFi  and Gigabit Ethernet, It
@@ -125,6 +129,8 @@
 	  8GB eMMC and 2GB of SDRAM. Expansion connectors provide access to
 	  I2C, SPI, UART, GPIOs.
 
+endchoice
+
 config ROCKCHIP_FAST_SPL
 	bool "Change the CPU to full speed in SPL"
 	depends on TARGET_CHROMEBOOK_JERRY
@@ -134,11 +140,14 @@
 	  voltage. This option is only available on boards which support it
 	  and have the required PMIC code.
 
+config ROCKCHIP_BOOT_MODE_REG
+	default 0xff730094
+
 config SYS_SOC
 	default "rk3288"
 
 config SYS_MALLOC_F_LEN
-	default 0x0800
+	default 0x2000
 
 config SPL_DRIVERS_MISC_SUPPORT
 	default y
@@ -152,6 +161,18 @@
 config SPL_SERIAL_SUPPORT
 	default y
 
+config TPL_LDSCRIPT
+	default "arch/arm/mach-rockchip/u-boot-tpl.lds"
+
+config TPL_MAX_SIZE
+	default 32768
+
+config TPL_STACK
+        default 0xff718000
+
+config TPL_TEXT_BASE
+	default 0xff704000
+
 source "board/amarula/vyasa-rk3288/Kconfig"
 
 source "board/chipspark/popmetal_rk3288/Kconfig"
diff --git a/arch/arm/mach-rockchip/rk3288/rk3288.c b/arch/arm/mach-rockchip/rk3288/rk3288.c
index 7941ca6..7552472 100644
--- a/arch/arm/mach-rockchip/rk3288/rk3288.c
+++ b/arch/arm/mach-rockchip/rk3288/rk3288.c
@@ -2,19 +2,45 @@
 /*
  * Copyright (c) 2016 Rockchip Electronics Co., Ltd
  */
+#include <asm/armv7.h>
 #include <asm/io.h>
 #include <asm/arch-rockchip/hardware.h>
 #include <asm/arch-rockchip/grf_rk3288.h>
 
 #define GRF_BASE	0xff770000
 
+#ifdef CONFIG_SPL_BUILD
+static void configure_l2ctlr(void)
+{
+	u32 l2ctlr;
+
+	l2ctlr = read_l2ctlr();
+	l2ctlr &= 0xfffc0000; /* clear bit0~bit17 */
+
+	/*
+	 * Data RAM write latency: 2 cycles
+	 * Data RAM read latency: 2 cycles
+	 * Data RAM setup latency: 1 cycle
+	 * Tag RAM write latency: 1 cycle
+	 * Tag RAM read latency: 1 cycle
+	 * Tag RAM setup latency: 1 cycle
+	 */
+	l2ctlr |= (1 << 3 | 1 << 0);
+	write_l2ctlr(l2ctlr);
+}
+#endif
+
 int arch_cpu_init(void)
 {
+#ifdef CONFIG_SPL_BUILD
+	configure_l2ctlr();
+#else
 	/* We do some SoC one time setting here. */
 	struct rk3288_grf * const grf = (void *)GRF_BASE;
 
 	/* Use rkpwm by default */
 	rk_setreg(&grf->soc_con2, 1 << 0);
+#endif
 
 	return 0;
 }
diff --git a/arch/arm/mach-rockchip/rk3328-board-spl.c b/arch/arm/mach-rockchip/rk3328-board-spl.c
index 7f49d05..f24fd89 100644
--- a/arch/arm/mach-rockchip/rk3328-board-spl.c
+++ b/arch/arm/mach-rockchip/rk3328-board-spl.c
@@ -7,7 +7,6 @@
 #include <common.h>
 #include <debug_uart.h>
 #include <dm.h>
-#include <dm/pinctrl.h>
 #include <ram.h>
 #include <spl.h>
 #include <asm/io.h>
diff --git a/arch/arm/mach-rockchip/rk3328/Kconfig b/arch/arm/mach-rockchip/rk3328/Kconfig
index 6c5c430..f8e1528 100644
--- a/arch/arm/mach-rockchip/rk3328/Kconfig
+++ b/arch/arm/mach-rockchip/rk3328/Kconfig
@@ -12,11 +12,20 @@
 
 endchoice
 
+config ROCKCHIP_BOOT_MODE_REG
+	default 0xff1005c8
+
 config SYS_SOC
 	default "rk3328"
 
 config SYS_MALLOC_F_LEN
-	default 0x0800
+	default 0x2000
+
+config SPL_LIBCOMMON_SUPPORT
+	default y
+
+config SPL_LIBGENERIC_SUPPORT
+	default y
 
 source "board/rockchip/evb_rk3328/Kconfig"
 
diff --git a/arch/arm/mach-rockchip/rk3368-board-spl.c b/arch/arm/mach-rockchip/rk3368-board-spl.c
index c651193..6ba106c 100644
--- a/arch/arm/mach-rockchip/rk3368-board-spl.c
+++ b/arch/arm/mach-rockchip/rk3368-board-spl.c
@@ -11,6 +11,33 @@
 #include <asm/io.h>
 #include <asm/arch-rockchip/periph.h>
 
+__weak int arch_cpu_init(void)
+{
+	return 0;
+}
+
+#define TIMER_LOAD_COUNT_L	0x00
+#define TIMER_LOAD_COUNT_H	0x04
+#define TIMER_CONTROL_REG	0x10
+#define TIMER_EN	0x1
+#define	TIMER_FMODE	BIT(0)
+#define	TIMER_RMODE	BIT(1)
+
+void rockchip_stimer_init(void)
+{
+	/* If Timer already enabled, don't re-init it */
+	u32 reg = readl(CONFIG_ROCKCHIP_STIMER_BASE + TIMER_CONTROL_REG);
+
+	if (reg & TIMER_EN)
+		return;
+
+	writel(0, CONFIG_ROCKCHIP_STIMER_BASE + TIMER_CONTROL_REG);
+	writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE);
+	writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE + 4);
+	writel(TIMER_EN | TIMER_FMODE, CONFIG_ROCKCHIP_STIMER_BASE +
+	       TIMER_CONTROL_REG);
+}
+
 void board_init_f(ulong dummy)
 {
 	struct udevice *dev;
@@ -22,6 +49,12 @@
 		hang();
 	}
 
+	/* Init secure timer */
+	rockchip_stimer_init();
+	/* Init ARM arch timer in arch/arm/cpu/armv7/arch_timer.c */
+	timer_init();
+
+	arch_cpu_init();
 	preloader_console_init();
 
 	ret = uclass_get_device(UCLASS_RAM, 0, &dev);
diff --git a/arch/arm/mach-rockchip/rk3368-board-tpl.c b/arch/arm/mach-rockchip/rk3368-board-tpl.c
deleted file mode 100644
index dc65a02..0000000
--- a/arch/arm/mach-rockchip/rk3368-board-tpl.c
+++ /dev/null
@@ -1,123 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * (C) Copyright 2017 Theobroma Systems Design und Consulting GmbH
- */
-
-#include <common.h>
-#include <debug_uart.h>
-#include <dm.h>
-#include <ram.h>
-#include <spl.h>
-#include <syscon.h>
-#include <asm/io.h>
-#include <asm/arch-rockchip/bootrom.h>
-#include <asm/arch-rockchip/clock.h>
-#include <asm/arch-rockchip/cru_rk3368.h>
-#include <asm/arch-rockchip/hardware.h>
-#include <asm/arch-rockchip/timer.h>
-
-/*
- * The SPL (and also the full U-Boot stage on the RK3368) will run in
- * secure mode (i.e. EL3) and an ATF will eventually be booted before
- * starting up the operating system... so we can initialize the SGRF
- * here and rely on the ATF installing the final (secure) policy
- * later.
- */
-static inline uintptr_t sgrf_soc_con_addr(unsigned no)
-{
-	const uintptr_t SGRF_BASE =
-		(uintptr_t)syscon_get_first_range(ROCKCHIP_SYSCON_SGRF);
-
-	return SGRF_BASE + sizeof(u32) * no;
-}
-
-static inline uintptr_t sgrf_busdmac_addr(unsigned no)
-{
-	const uintptr_t SGRF_BASE =
-		(uintptr_t)syscon_get_first_range(ROCKCHIP_SYSCON_SGRF);
-	const uintptr_t SGRF_BUSDMAC_OFFSET = 0x100;
-	const uintptr_t SGRF_BUSDMAC_BASE = SGRF_BASE + SGRF_BUSDMAC_OFFSET;
-
-	return SGRF_BUSDMAC_BASE + sizeof(u32) * no;
-}
-
-static void sgrf_init(void)
-{
-	struct rk3368_cru * const cru =
-		(struct rk3368_cru * const)rockchip_get_cru();
-	const u16 SGRF_SOC_CON_SEC = GENMASK(15, 0);
-	const u16 SGRF_BUSDMAC_CON0_SEC = BIT(2);
-	const u16 SGRF_BUSDMAC_CON1_SEC = GENMASK(15, 12);
-
-	/* Set all configurable IP to 'non secure'-mode */
-	rk_setreg(sgrf_soc_con_addr(5), SGRF_SOC_CON_SEC);
-	rk_setreg(sgrf_soc_con_addr(6), SGRF_SOC_CON_SEC);
-	rk_setreg(sgrf_soc_con_addr(7), SGRF_SOC_CON_SEC);
-
-	/*
-	 * From rockchip-uboot/arch/arm/cpu/armv8/rk33xx/cpu.c
-	 * Original comment: "ddr space set no secure mode"
-	 */
-	rk_clrreg(sgrf_soc_con_addr(8), SGRF_SOC_CON_SEC);
-	rk_clrreg(sgrf_soc_con_addr(9), SGRF_SOC_CON_SEC);
-	rk_clrreg(sgrf_soc_con_addr(10), SGRF_SOC_CON_SEC);
-
-	/* Set 'secure dma' to 'non secure'-mode */
-	rk_setreg(sgrf_busdmac_addr(0), SGRF_BUSDMAC_CON0_SEC);
-	rk_setreg(sgrf_busdmac_addr(1), SGRF_BUSDMAC_CON1_SEC);
-
-	dsb();  /* barrier */
-
-	rk_setreg(&cru->softrst_con[1], DMA1_SRST_REQ);
-	rk_setreg(&cru->softrst_con[4], DMA2_SRST_REQ);
-
-	dsb();  /* barrier */
-	udelay(10);
-
-	rk_clrreg(&cru->softrst_con[1], DMA1_SRST_REQ);
-	rk_clrreg(&cru->softrst_con[4], DMA2_SRST_REQ);
-}
-
-void board_init_f(ulong dummy)
-{
-	struct udevice *dev;
-	int ret;
-
-#ifdef CONFIG_DEBUG_UART
-	/*
-	 * Debug UART can be used from here if required:
-	 *
-	 * debug_uart_init();
-	 * printch('a');
-	 * printhex8(0x1234);
-	 * printascii("string");
-	 */
-	debug_uart_init();
-	printascii("U-Boot TPL board init\n");
-#endif
-
-	ret = spl_early_init();
-	if (ret) {
-		debug("spl_early_init() failed: %d\n", ret);
-		hang();
-	}
-
-	/* Reset security, so we can use DMA in the MMC drivers */
-	sgrf_init();
-
-	ret = uclass_get_device(UCLASS_RAM, 0, &dev);
-	if (ret) {
-		debug("DRAM init failed: %d\n", ret);
-		return;
-	}
-}
-
-void board_return_to_bootrom(void)
-{
-	back_to_bootrom(BROM_BOOT_NEXTSTAGE);
-}
-
-u32 spl_boot_device(void)
-{
-	return BOOT_DEVICE_BOOTROM;
-}
diff --git a/arch/arm/mach-rockchip/rk3368/Kconfig b/arch/arm/mach-rockchip/rk3368/Kconfig
index 325572a..d6ca5f1 100644
--- a/arch/arm/mach-rockchip/rk3368/Kconfig
+++ b/arch/arm/mach-rockchip/rk3368/Kconfig
@@ -42,9 +42,21 @@
          sensor STK3410.
 endchoice
 
+config ROCKCHIP_BOOT_MODE_REG
+	default 0xff738200
+
 config SYS_SOC
 	default "rk3368"
 
+config SYS_MALLOC_F_LEN
+	default 0x2000
+
+config SPL_LIBCOMMON_SUPPORT
+	default y
+
+config SPL_LIBGENERIC_SUPPORT
+	default y
+
 source "board/theobroma-systems/lion_rk3368/Kconfig"
 source "board/rockchip/sheep_rk3368/Kconfig"
 source "board/geekbuying/geekbox/Kconfig"
@@ -53,4 +65,13 @@
 config SPL_LDSCRIPT
 	default "arch/arm/cpu/armv8/u-boot-spl.lds"
 
+config TPL_MAX_SIZE
+        default 28672
+
+config TPL_STACK
+        default 0xff8cffff
+
+config TPL_TEXT_BASE
+        default 0xff8c1000
+
 endif
diff --git a/arch/arm/mach-rockchip/rk3368/rk3368.c b/arch/arm/mach-rockchip/rk3368/rk3368.c
index f06d277..47786f5 100644
--- a/arch/arm/mach-rockchip/rk3368/rk3368.c
+++ b/arch/arm/mach-rockchip/rk3368/rk3368.c
@@ -5,12 +5,13 @@
  */
 
 #include <common.h>
+#include <syscon.h>
 #include <asm/armv8/mmu.h>
 #include <asm/io.h>
 #include <asm/arch-rockchip/clock.h>
 #include <asm/arch-rockchip/cru_rk3368.h>
 #include <asm/arch-rockchip/grf_rk3368.h>
-#include <syscon.h>
+#include <asm/arch-rockchip/hardware.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -97,6 +98,78 @@
 }
 #endif
 
+#ifdef CONFIG_SPL_BUILD
+/*
+ * The SPL (and also the full U-Boot stage on the RK3368) will run in
+ * secure mode (i.e. EL3) and an ATF will eventually be booted before
+ * starting up the operating system... so we can initialize the SGRF
+ * here and rely on the ATF installing the final (secure) policy
+ * later.
+ */
+static inline uintptr_t sgrf_soc_con_addr(unsigned int no)
+{
+	const uintptr_t SGRF_BASE =
+		(uintptr_t)syscon_get_first_range(ROCKCHIP_SYSCON_SGRF);
+
+	return SGRF_BASE + sizeof(u32) * no;
+}
+
+static inline uintptr_t sgrf_busdmac_addr(unsigned int no)
+{
+	const uintptr_t SGRF_BASE =
+		(uintptr_t)syscon_get_first_range(ROCKCHIP_SYSCON_SGRF);
+	const uintptr_t SGRF_BUSDMAC_OFFSET = 0x100;
+	const uintptr_t SGRF_BUSDMAC_BASE = SGRF_BASE + SGRF_BUSDMAC_OFFSET;
+
+	return SGRF_BUSDMAC_BASE + sizeof(u32) * no;
+}
+
+static void sgrf_init(void)
+{
+	struct rk3368_cru * const cru =
+		(struct rk3368_cru * const)rockchip_get_cru();
+	const u16 SGRF_SOC_CON_SEC = GENMASK(15, 0);
+	const u16 SGRF_BUSDMAC_CON0_SEC = BIT(2);
+	const u16 SGRF_BUSDMAC_CON1_SEC = GENMASK(15, 12);
+
+	/* Set all configurable IP to 'non secure'-mode */
+	rk_setreg(sgrf_soc_con_addr(5), SGRF_SOC_CON_SEC);
+	rk_setreg(sgrf_soc_con_addr(6), SGRF_SOC_CON_SEC);
+	rk_setreg(sgrf_soc_con_addr(7), SGRF_SOC_CON_SEC);
+
+	/*
+	 * From rockchip-uboot/arch/arm/cpu/armv8/rk33xx/cpu.c
+	 * Original comment: "ddr space set no secure mode"
+	 */
+	rk_clrreg(sgrf_soc_con_addr(8), SGRF_SOC_CON_SEC);
+	rk_clrreg(sgrf_soc_con_addr(9), SGRF_SOC_CON_SEC);
+	rk_clrreg(sgrf_soc_con_addr(10), SGRF_SOC_CON_SEC);
+
+	/* Set 'secure dma' to 'non secure'-mode */
+	rk_setreg(sgrf_busdmac_addr(0), SGRF_BUSDMAC_CON0_SEC);
+	rk_setreg(sgrf_busdmac_addr(1), SGRF_BUSDMAC_CON1_SEC);
+
+	dsb();  /* barrier */
+
+	rk_setreg(&cru->softrst_con[1], DMA1_SRST_REQ);
+	rk_setreg(&cru->softrst_con[4], DMA2_SRST_REQ);
+
+	dsb();  /* barrier */
+	udelay(10);
+
+	rk_clrreg(&cru->softrst_con[1], DMA1_SRST_REQ);
+	rk_clrreg(&cru->softrst_con[4], DMA2_SRST_REQ);
+}
+
+int arch_cpu_init(void)
+{
+	/* Reset security, so we can use DMA in the MMC drivers */
+	sgrf_init();
+
+	return 0;
+}
+#endif
+
 #ifdef CONFIG_DEBUG_UART_BOARD_INIT
 void board_debug_uart_init(void)
 {
diff --git a/arch/arm/mach-rockchip/rk3399-board-spl.c b/arch/arm/mach-rockchip/rk3399-board-spl.c
index 890d800..7154d8e 100644
--- a/arch/arm/mach-rockchip/rk3399-board-spl.c
+++ b/arch/arm/mach-rockchip/rk3399-board-spl.c
@@ -21,7 +21,6 @@
 #include <asm/arch-rockchip/periph.h>
 #include <asm/arch-rockchip/sys_proto.h>
 #include <power/regulator.h>
-#include <dm/pinctrl.h>
 
 void board_return_to_bootrom(void)
 {
@@ -110,30 +109,12 @@
 			   "u-boot,spl-boot-device", boot_ofpath);
 }
 
-#define TIMER_CHN10_BASE	0xff8680a0
-#define TIMER_END_COUNT_L	0x00
-#define TIMER_END_COUNT_H	0x04
-#define TIMER_INIT_COUNT_L	0x10
-#define TIMER_INIT_COUNT_H	0x14
-#define TIMER_CONTROL_REG	0x1c
-
-#define TIMER_EN	0x1
-#define	TIMER_FMODE	(0 << 1)
-#define	TIMER_RMODE	(1 << 1)
-
-void secure_timer_init(void)
+__weak void rockchip_stimer_init(void)
 {
-	writel(0xffffffff, TIMER_CHN10_BASE + TIMER_END_COUNT_L);
-	writel(0xffffffff, TIMER_CHN10_BASE + TIMER_END_COUNT_H);
-	writel(0, TIMER_CHN10_BASE + TIMER_INIT_COUNT_L);
-	writel(0, TIMER_CHN10_BASE + TIMER_INIT_COUNT_H);
-	writel(TIMER_EN | TIMER_FMODE, TIMER_CHN10_BASE + TIMER_CONTROL_REG);
 }
 
-
 void board_init_f(ulong dummy)
 {
-	struct udevice *pinctrl;
 	struct udevice *dev;
 	struct rk3399_pmusgrf_regs *sgrf;
 	struct rk3399_grf_regs *grf;
@@ -190,13 +171,7 @@
 	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
 	rk_clrreg(&grf->emmccore_con[11], 0x0ff);
 
-	secure_timer_init();
-
-	ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl);
-	if (ret) {
-		pr_err("Pinctrl init failed: %d\n", ret);
-		return;
-	}
+	rockchip_stimer_init();
 
 	ret = uclass_get_device(UCLASS_RAM, 0, &dev);
 	if (ret) {
diff --git a/arch/arm/mach-rockchip/rk3399-board-tpl.c b/arch/arm/mach-rockchip/rk3399-board-tpl.c
deleted file mode 100644
index 4a30124..0000000
--- a/arch/arm/mach-rockchip/rk3399-board-tpl.c
+++ /dev/null
@@ -1,91 +0,0 @@
-// 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>
-
-#define TIMER_CHN10_BASE	0xff8680a0
-#define TIMER_END_COUNT_L	0x00
-#define TIMER_END_COUNT_H	0x04
-#define TIMER_INIT_COUNT_L	0x10
-#define TIMER_INIT_COUNT_H	0x14
-#define TIMER_CONTROL_REG	0x1c
-
-#define TIMER_EN	0x1
-#define	TIMER_FMODE	(0 << 1)
-#define	TIMER_RMODE	(1 << 1)
-
-void secure_timer_init(void)
-{
-	writel(0xffffffff, TIMER_CHN10_BASE + TIMER_END_COUNT_L);
-	writel(0xffffffff, TIMER_CHN10_BASE + TIMER_END_COUNT_H);
-	writel(0, TIMER_CHN10_BASE + TIMER_INIT_COUNT_L);
-	writel(0, TIMER_CHN10_BASE + TIMER_INIT_COUNT_H);
-	writel(TIMER_EN | TIMER_FMODE, TIMER_CHN10_BASE + TIMER_CONTROL_REG);
-}
-
-void board_init_f(ulong dummy)
-{
-	struct udevice *dev;
-	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");
-	 */
-	debug("U-Boot TPL board init\n");
-#endif
-	ret = spl_early_init();
-	if (ret) {
-		debug("spl_early_init() failed: %d\n", ret);
-		hang();
-	}
-
-	secure_timer_init();
-
-	ret = uclass_get_device(UCLASS_RAM, 0, &dev);
-	if (ret) {
-		pr_err("DRAM init failed: %d\n", ret);
-		return;
-	}
-}
-
-void board_return_to_bootrom(void)
-{
-	back_to_bootrom(BROM_BOOT_NEXTSTAGE);
-}
-
-u32 spl_boot_device(void)
-{
-	return BOOT_DEVICE_BOOTROM;
-}
-
-void spl_board_init(void)
-{
-	puts("\nU-Boot TPL "  PLAIN_VERSION " (" U_BOOT_DATE " - "
-	     U_BOOT_TIME " " U_BOOT_TZ ")\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
diff --git a/arch/arm/mach-rockchip/rk3399/Kconfig b/arch/arm/mach-rockchip/rk3399/Kconfig
index 2c5c93c..6660d05 100644
--- a/arch/arm/mach-rockchip/rk3399/Kconfig
+++ b/arch/arm/mach-rockchip/rk3399/Kconfig
@@ -64,11 +64,32 @@
 
 endchoice
 
+config ROCKCHIP_BOOT_MODE_REG
+	default 0xff320300
+
 config SYS_SOC
 	default "rk3399"
 
 config SYS_MALLOC_F_LEN
-	default 0x0800
+	default 0x4000
+
+config SPL_LIBCOMMON_SUPPORT
+	default y
+
+config SPL_LIBGENERIC_SUPPORT
+	default y
+
+config TPL_LDSCRIPT
+	default "arch/arm/mach-rockchip/u-boot-tpl-v8.lds"
+
+config TPL_MAX_SIZE
+        default 188416
+
+config TPL_STACK
+        default 0xff8effff
+
+config TPL_TEXT_BASE
+        default 0xff8c2000
 
 source "board/rockchip/evb_rk3399/Kconfig"
 source "board/theobroma-systems/puma_rk3399/Kconfig"
diff --git a/arch/arm/mach-rockchip/rk3399/rk3399.c b/arch/arm/mach-rockchip/rk3399/rk3399.c
index e1f9f8b..0f09ea5 100644
--- a/arch/arm/mach-rockchip/rk3399/rk3399.c
+++ b/arch/arm/mach-rockchip/rk3399/rk3399.c
@@ -38,6 +38,35 @@
 
 struct mm_region *mem_map = rk3399_mem_map;
 
+#ifdef CONFIG_SPL_BUILD
+
+#define TIMER_END_COUNT_L	0x00
+#define TIMER_END_COUNT_H	0x04
+#define TIMER_INIT_COUNT_L	0x10
+#define TIMER_INIT_COUNT_H	0x14
+#define TIMER_CONTROL_REG	0x1c
+
+#define TIMER_EN	0x1
+#define TIMER_FMODE	BIT(0)
+#define TIMER_RMODE	BIT(1)
+
+void rockchip_stimer_init(void)
+{
+	/* If Timer already enabled, don't re-init it */
+	u32 reg = readl(CONFIG_ROCKCHIP_STIMER_BASE + TIMER_CONTROL_REG);
+
+	if (reg & TIMER_EN)
+		return;
+
+	writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE + TIMER_END_COUNT_L);
+	writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE + TIMER_END_COUNT_H);
+	writel(0, CONFIG_ROCKCHIP_STIMER_BASE + TIMER_INIT_COUNT_L);
+	writel(0, CONFIG_ROCKCHIP_STIMER_BASE + TIMER_INIT_COUNT_H);
+	writel(TIMER_EN | TIMER_FMODE, CONFIG_ROCKCHIP_STIMER_BASE + \
+	       TIMER_CONTROL_REG);
+}
+#endif
+
 int dram_init_banksize(void)
 {
 	size_t max_size = min((unsigned long)gd->ram_size, gd->ram_top);
diff --git a/arch/arm/mach-rockchip/rk3399/syscon_rk3399.c b/arch/arm/mach-rockchip/rk3399/syscon_rk3399.c
index a8bb5b1..259ca44 100644
--- a/arch/arm/mach-rockchip/rk3399/syscon_rk3399.c
+++ b/arch/arm/mach-rockchip/rk3399/syscon_rk3399.c
@@ -13,6 +13,7 @@
 	{ .compatible = "rockchip,rk3399-pmugrf", .data = ROCKCHIP_SYSCON_PMUGRF },
 	{ .compatible = "rockchip,rk3399-pmusgrf", .data = ROCKCHIP_SYSCON_PMUSGRF },
 	{ .compatible = "rockchip,rk3399-cic", .data = ROCKCHIP_SYSCON_CIC },
+	{ .compatible = "rockchip,rk3399-pmu", .data = ROCKCHIP_SYSCON_PMU },
 	{ }
 };
 
@@ -58,4 +59,11 @@
 	.of_match = rk3399_syscon_ids + 3,
 	.bind = rk3399_syscon_bind_of_platdata,
 };
+
+U_BOOT_DRIVER(rockchip_rk3399_pmu) = {
+	.name = "rockchip_rk3399_pmu",
+	.id = UCLASS_SYSCON,
+	.of_match = rk3399_syscon_ids + 4,
+	.bind = rk3399_syscon_bind_of_platdata,
+};
 #endif
diff --git a/arch/arm/mach-rockchip/rk_timer.c b/arch/arm/mach-rockchip/rk_timer.c
deleted file mode 100644
index 29d379f..0000000
--- a/arch/arm/mach-rockchip/rk_timer.c
+++ /dev/null
@@ -1,40 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * (C) Copyright 2015 Rockchip Electronics Co., Ltd
- */
-
-#include <common.h>
-#include <asm/arch-rockchip/timer.h>
-#include <asm/io.h>
-#include <linux/types.h>
-
-struct rk_timer * const timer_ptr = (void *)CONFIG_SYS_TIMER_BASE;
-
-static uint64_t rockchip_get_ticks(void)
-{
-	uint64_t timebase_h, timebase_l;
-
-	timebase_l = readl(&timer_ptr->timer_curr_value0);
-	timebase_h = readl(&timer_ptr->timer_curr_value1);
-
-	return timebase_h << 32 | timebase_l;
-}
-
-void rockchip_udelay(unsigned int usec)
-{
-	uint64_t tmp;
-
-	/* get timestamp */
-	tmp = rockchip_get_ticks() + usec_to_tick(usec);
-
-	/* loop till event */
-	while (rockchip_get_ticks() < tmp+1)
-		;
-}
-
-void rockchip_timer_init(void)
-{
-	writel(0xffffffff, &timer_ptr->timer_load_count0);
-	writel(0xffffffff, &timer_ptr->timer_load_count1);
-	writel(1, &timer_ptr->timer_ctrl_reg);
-}
diff --git a/arch/arm/mach-rockchip/rv1108/Kconfig b/arch/arm/mach-rockchip/rv1108/Kconfig
index e3a63b8..a12216d 100644
--- a/arch/arm/mach-rockchip/rv1108/Kconfig
+++ b/arch/arm/mach-rockchip/rv1108/Kconfig
@@ -1,5 +1,8 @@
 if ROCKCHIP_RV1108
 
+choice
+	prompt "RV1108 board select"
+
 config TARGET_EVB_RV1108
 	bool "EVB_RV1108"
 	help
@@ -22,6 +25,11 @@
 	help
 	  RV1108 ELGIN is a board based on the Rockchip RV1108.
 
+endchoice
+
+config ROCKCHIP_BOOT_MODE_REG
+	default 0x10300580
+
 config SYS_SOC
 	default "rv1108"
 
diff --git a/arch/arm/mach-rockchip/spl-boot-order.c b/arch/arm/mach-rockchip/spl-boot-order.c
index 0e485de..c19c285 100644
--- a/arch/arm/mach-rockchip/spl-boot-order.c
+++ b/arch/arm/mach-rockchip/spl-boot-order.c
@@ -8,7 +8,7 @@
 #include <mmc.h>
 #include <spl.h>
 
-#if CONFIG_IS_ENABLED(OF_CONTROL)
+#if CONFIG_IS_ENABLED(OF_LIBFDT)
 /**
  * spl_node_to_boot_device() - maps from a DT-node to a SPL boot device
  * @node:	of_offset of the node
diff --git a/arch/arm/mach-rockchip/tpl.c b/arch/arm/mach-rockchip/tpl.c
new file mode 100644
index 0000000..0ff2a19
--- /dev/null
+++ b/arch/arm/mach-rockchip/tpl.c
@@ -0,0 +1,86 @@
+// 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>
+
+#define TIMER_LOAD_COUNT_L	0x00
+#define TIMER_LOAD_COUNT_H	0x04
+#define TIMER_CONTROL_REG	0x10
+#define TIMER_EN	0x1
+#define	TIMER_FMODE	BIT(0)
+#define	TIMER_RMODE	BIT(1)
+
+__weak void rockchip_stimer_init(void)
+{
+	/* If Timer already enabled, don't re-init it */
+	u32 reg = readl(CONFIG_ROCKCHIP_STIMER_BASE + TIMER_CONTROL_REG);
+
+	if (reg & TIMER_EN)
+		return;
+
+#ifndef CONFIG_ARM64
+	asm volatile("mcr p15, 0, %0, c14, c0, 0"
+		     : : "r"(COUNTER_FREQUENCY));
+#endif
+
+	writel(0, CONFIG_ROCKCHIP_STIMER_BASE + TIMER_CONTROL_REG);
+	writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE);
+	writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE + 4);
+	writel(TIMER_EN | TIMER_FMODE, CONFIG_ROCKCHIP_STIMER_BASE +
+	       TIMER_CONTROL_REG);
+}
+
+void board_init_f(ulong dummy)
+{
+	struct udevice *dev;
+	int ret;
+
+#ifdef CONFIG_DEBUG_UART
+	/*
+	 * Debug UART can be used from here if required:
+	 *
+	 * debug_uart_init();
+	 * printch('a');
+	 * printhex8(0x1234);
+	 * printascii("string");
+	 */
+	debug_uart_init();
+	printascii("\nU-Boot TPL " PLAIN_VERSION " (" U_BOOT_DATE " - " \
+				U_BOOT_TIME ")\n");
+#endif
+	ret = spl_early_init();
+	if (ret) {
+		debug("spl_early_init() failed: %d\n", ret);
+		hang();
+	}
+
+	/* Init secure timer */
+	rockchip_stimer_init();
+	/* Init ARM arch timer in arch/arm/cpu/ */
+	timer_init();
+
+	ret = uclass_get_device(UCLASS_RAM, 0, &dev);
+	if (ret) {
+		printf("DRAM init failed: %d\n", ret);
+		return;
+	}
+}
+
+void board_return_to_bootrom(void)
+{
+	back_to_bootrom(BROM_BOOT_NEXTSTAGE);
+}
+
+u32 spl_boot_device(void)
+{
+	return BOOT_DEVICE_BOOTROM;
+}
diff --git a/board/amarula/vyasa-rk3288/vyasa-rk3288.c b/board/amarula/vyasa-rk3288/vyasa-rk3288.c
index 2b509f5..baf197c 100644
--- a/board/amarula/vyasa-rk3288/vyasa-rk3288.c
+++ b/board/amarula/vyasa-rk3288/vyasa-rk3288.c
@@ -6,14 +6,6 @@
 #include <common.h>
 
 #ifndef CONFIG_TPL_BUILD
-#include <spl.h>
-
-void board_boot_order(u32 *spl_boot_list)
-{
-	/* eMMC prior to sdcard. */
-	spl_boot_list[0] = BOOT_DEVICE_MMC2;
-	spl_boot_list[1] = BOOT_DEVICE_MMC1;
-}
 
 int spl_start_uboot(void)
 {
diff --git a/board/chipspark/popmetal_rk3288/popmetal-rk3288.c b/board/chipspark/popmetal_rk3288/popmetal-rk3288.c
index 355c78b..9ba1fbd 100644
--- a/board/chipspark/popmetal_rk3288/popmetal-rk3288.c
+++ b/board/chipspark/popmetal_rk3288/popmetal-rk3288.c
@@ -4,16 +4,8 @@
  */
 
 #include <common.h>
-#include <spl.h>
 #include <asm/gpio.h>
 
-void board_boot_order(u32 *spl_boot_list)
-{
-	/* eMMC prior to sdcard */
-	spl_boot_list[0] = BOOT_DEVICE_MMC2;
-	spl_boot_list[1] = BOOT_DEVICE_MMC1;
-}
-
 #define GPIO7A3_HUB_RST	227
 
 int rk_board_late_init(void)
diff --git a/board/mqmaker/miqi_rk3288/miqi-rk3288.c b/board/mqmaker/miqi_rk3288/miqi-rk3288.c
index d6992a2..779bc64 100644
--- a/board/mqmaker/miqi_rk3288/miqi-rk3288.c
+++ b/board/mqmaker/miqi_rk3288/miqi-rk3288.c
@@ -3,12 +3,3 @@
  * (C) Copyright 2016 Rockchip Electronics Co., Ltd
  */
 
-#include <common.h>
-#include <spl.h>
-
-void board_boot_order(u32 *spl_boot_list)
-{
-	/* eMMC prior to sdcard. */
-	spl_boot_list[0] = BOOT_DEVICE_MMC2;
-	spl_boot_list[1] = BOOT_DEVICE_MMC1;
-}
diff --git a/board/rockchip/evb_rk3288/evb-rk3288.c b/board/rockchip/evb_rk3288/evb-rk3288.c
index d6992a2..779bc64 100644
--- a/board/rockchip/evb_rk3288/evb-rk3288.c
+++ b/board/rockchip/evb_rk3288/evb-rk3288.c
@@ -3,12 +3,3 @@
  * (C) Copyright 2016 Rockchip Electronics Co., Ltd
  */
 
-#include <common.h>
-#include <spl.h>
-
-void board_boot_order(u32 *spl_boot_list)
-{
-	/* eMMC prior to sdcard. */
-	spl_boot_list[0] = BOOT_DEVICE_MMC2;
-	spl_boot_list[1] = BOOT_DEVICE_MMC1;
-}
diff --git a/board/rockchip/evb_rk3399/README b/board/rockchip/evb_rk3399/README
index 6469821..ea3258c 100644
--- a/board/rockchip/evb_rk3399/README
+++ b/board/rockchip/evb_rk3399/README
@@ -35,12 +35,6 @@
   > git clone https://github.com/rockchip-linux/rkbin.git
   > git clone https://github.com/rockchip-linux/rkdeveloptool.git
 
-Get some prerequisites
-======================
-
-You need the Python elftools.elf.elffile library for make_fit_atf.py to work:
-
-  > sudo apt-get install python-pyelftools
 
 Compile ATF
 ===========
diff --git a/board/rockchip/fennec_rk3288/fennec-rk3288.c b/board/rockchip/fennec_rk3288/fennec-rk3288.c
index ce45544..779bc64 100644
--- a/board/rockchip/fennec_rk3288/fennec-rk3288.c
+++ b/board/rockchip/fennec_rk3288/fennec-rk3288.c
@@ -3,12 +3,3 @@
  * (C) Copyright 2016 Rockchip Electronics Co., Ltd
  */
 
-#include <common.h>
-#include <spl.h>
-
-void board_boot_order(u32 *spl_boot_list)
-{
-	/* eMMC prior to sdcard */
-	spl_boot_list[0] = BOOT_DEVICE_MMC2;
-	spl_boot_list[1] = BOOT_DEVICE_MMC1;
-}
diff --git a/board/vamrs/rock960_rk3399/MAINTAINERS b/board/vamrs/rock960_rk3399/MAINTAINERS
index 22b2db9..5ee5256 100644
--- a/board/vamrs/rock960_rk3399/MAINTAINERS
+++ b/board/vamrs/rock960_rk3399/MAINTAINERS
@@ -1,11 +1,11 @@
 ROCK960-RK3399
-M:      Manivannan Sadhasivam manivannan.sadhasivam@linaro.org
+M:      Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
 S:      Maintained
 F:      board/rockchip/rock960_rk3399
 F:      include/configs/rock960_rk3399.h
 F:      configs/rock960-rk3399_defconfig
 
 FICUS EE
-M:      Manivannan Sadhasivam manivannan.sadhasivam@linaro.org
+M:      Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
 S:      Maintained
 F:	configs/ficus-rk3399_defconfig
diff --git a/configs/chromebit_mickey_defconfig b/configs/chromebit_mickey_defconfig
index 1a34309..cf815dc 100644
--- a/configs/chromebit_mickey_defconfig
+++ b/configs/chromebit_mickey_defconfig
@@ -1,7 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARCH_ROCKCHIP=y
 CONFIG_SYS_TEXT_BASE=0x00100000
-CONFIG_SYS_MALLOC_F_LEN=0x2000
 CONFIG_ROCKCHIP_RK3288=y
 # CONFIG_SPL_MMC_SUPPORT is not set
 CONFIG_TARGET_CHROMEBIT_MICKEY=y
diff --git a/configs/chromebook_bob_defconfig b/configs/chromebook_bob_defconfig
index e61e27c..1c04f0a 100644
--- a/configs/chromebook_bob_defconfig
+++ b/configs/chromebook_bob_defconfig
@@ -2,9 +2,6 @@
 CONFIG_ARCH_ROCKCHIP=y
 CONFIG_SYS_TEXT_BASE=0x00200000
 CONFIG_SPL_GPIO_SUPPORT=y
-CONFIG_SPL_LIBCOMMON_SUPPORT=y
-CONFIG_SPL_LIBGENERIC_SUPPORT=y
-CONFIG_SYS_MALLOC_F_LEN=0x4000
 CONFIG_ROCKCHIP_RK3399=y
 CONFIG_ROCKCHIP_BOOT_MODE_REG=0
 CONFIG_ROCKCHIP_SPL_RESERVE_IRAM=0x4000
diff --git a/configs/chromebook_jerry_defconfig b/configs/chromebook_jerry_defconfig
index 7c7986e..f6056f8 100644
--- a/configs/chromebook_jerry_defconfig
+++ b/configs/chromebook_jerry_defconfig
@@ -1,7 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARCH_ROCKCHIP=y
 CONFIG_SYS_TEXT_BASE=0x00100000
-CONFIG_SYS_MALLOC_F_LEN=0x2000
 CONFIG_ROCKCHIP_RK3288=y
 # CONFIG_SPL_MMC_SUPPORT is not set
 CONFIG_TARGET_CHROMEBOOK_JERRY=y
diff --git a/configs/chromebook_minnie_defconfig b/configs/chromebook_minnie_defconfig
index 17c1ea6..b4bae3b 100644
--- a/configs/chromebook_minnie_defconfig
+++ b/configs/chromebook_minnie_defconfig
@@ -1,7 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARCH_ROCKCHIP=y
 CONFIG_SYS_TEXT_BASE=0x00100000
-CONFIG_SYS_MALLOC_F_LEN=0x2000
 CONFIG_ROCKCHIP_RK3288=y
 # CONFIG_SPL_MMC_SUPPORT is not set
 CONFIG_TARGET_CHROMEBOOK_MINNIE=y
diff --git a/configs/chromebook_speedy_defconfig b/configs/chromebook_speedy_defconfig
index 0cc1eb6..999dc69 100644
--- a/configs/chromebook_speedy_defconfig
+++ b/configs/chromebook_speedy_defconfig
@@ -1,7 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARCH_ROCKCHIP=y
 CONFIG_SYS_TEXT_BASE=0x00100000
-CONFIG_SYS_MALLOC_F_LEN=0x2000
 CONFIG_ROCKCHIP_RK3288=y
 # CONFIG_SPL_MMC_SUPPORT is not set
 CONFIG_TARGET_CHROMEBOOK_SPEEDY=y
diff --git a/configs/evb-px5_defconfig b/configs/evb-px5_defconfig
index 9601b12..a2b72c7 100644
--- a/configs/evb-px5_defconfig
+++ b/configs/evb-px5_defconfig
@@ -1,9 +1,6 @@
 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_RK3368=y
 CONFIG_TPL_LDSCRIPT="arch/arm/mach-rockchip/u-boot-tpl-v8.lds"
 CONFIG_ROCKCHIP_SPL_RESERVE_IRAM=0x40000
@@ -70,10 +67,6 @@
 CONFIG_DEBUG_UART_SHIFT=2
 CONFIG_DEBUG_UART_SKIP_INIT=y
 CONFIG_SYSRESET=y
-CONFIG_TIMER=y
-CONFIG_SPL_TIMER=y
-CONFIG_TPL_TIMER=y
-CONFIG_ROCKCHIP_TIMER=y
 CONFIG_USE_TINY_PRINTF=y
 CONFIG_PANIC_HANG=y
 CONFIG_SPL_TINY_MEMSET=y
diff --git a/configs/evb-rk3229_defconfig b/configs/evb-rk3229_defconfig
index 31c1b17..2032978 100644
--- a/configs/evb-rk3229_defconfig
+++ b/configs/evb-rk3229_defconfig
@@ -1,9 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARCH_ROCKCHIP=y
 CONFIG_SYS_TEXT_BASE=0x61000000
-CONFIG_SPL_LIBCOMMON_SUPPORT=y
-CONFIG_SPL_LIBGENERIC_SUPPORT=y
-CONFIG_SYS_MALLOC_F_LEN=0x800
 CONFIG_ROCKCHIP_RK322X=y
 CONFIG_TPL_LDSCRIPT="arch/arm/mach-rockchip/u-boot-tpl.lds"
 CONFIG_ROCKCHIP_SPL_RESERVE_IRAM=0x0
diff --git a/configs/evb-rk3288_defconfig b/configs/evb-rk3288_defconfig
index 843c59d..a6df143 100644
--- a/configs/evb-rk3288_defconfig
+++ b/configs/evb-rk3288_defconfig
@@ -1,12 +1,10 @@
 CONFIG_ARM=y
 CONFIG_ARCH_ROCKCHIP=y
-CONFIG_SYS_TEXT_BASE=0x00000000
-CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_SYS_TEXT_BASE=0x01000000
 CONFIG_ROCKCHIP_RK3288=y
-CONFIG_SPL_ROCKCHIP_BACK_TO_BROM=y
 CONFIG_TARGET_EVB_RK3288=y
 CONFIG_NR_DRAM_BANKS=1
-CONFIG_SPL_STACK_R_ADDR=0x80000
+CONFIG_SPL_SIZE_LIMIT=307200
 CONFIG_DEBUG_UART_BASE=0xff690000
 CONFIG_DEBUG_UART_CLOCK=24000000
 CONFIG_DEBUG_UART=y
@@ -15,9 +13,7 @@
 CONFIG_DEFAULT_FDT_FILE="rk3288-evb-rk808.dtb"
 # CONFIG_DISPLAY_CPUINFO is not set
 CONFIG_DISPLAY_BOARDINFO_LATE=y
-CONFIG_SPL_TEXT_BASE=0xff704000
-CONFIG_SPL_STACK_R=y
-CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x2000
+CONFIG_SPL_TEXT_BASE=0
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_GPT=y
 CONFIG_CMD_I2C=y
diff --git a/configs/evb-rk3328_defconfig b/configs/evb-rk3328_defconfig
index 92d6817..fcc04f2 100644
--- a/configs/evb-rk3328_defconfig
+++ b/configs/evb-rk3328_defconfig
@@ -1,7 +1,5 @@
 CONFIG_ARM=y
 CONFIG_ARCH_ROCKCHIP=y
-CONFIG_SPL_LIBCOMMON_SUPPORT=y
-CONFIG_SPL_LIBGENERIC_SUPPORT=y
 CONFIG_SYS_TEXT_BASE=0x00200000
 CONFIG_ROCKCHIP_RK3328=y
 CONFIG_SPL_DRIVERS_MISC_SUPPORT=y
diff --git a/configs/evb-rk3399_defconfig b/configs/evb-rk3399_defconfig
index f10502c..764d32f 100644
--- a/configs/evb-rk3399_defconfig
+++ b/configs/evb-rk3399_defconfig
@@ -1,9 +1,6 @@
 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=0x4000
 CONFIG_ROCKCHIP_RK3399=y
 CONFIG_ROCKCHIP_SPL_RESERVE_IRAM=0x50000
 CONFIG_NR_DRAM_BANKS=1
diff --git a/configs/fennec-rk3288_defconfig b/configs/fennec-rk3288_defconfig
index 6dfaff5..16d8fb1 100644
--- a/configs/fennec-rk3288_defconfig
+++ b/configs/fennec-rk3288_defconfig
@@ -1,7 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARCH_ROCKCHIP=y
 CONFIG_SYS_TEXT_BASE=0x00000000
-CONFIG_SYS_MALLOC_F_LEN=0x2000
 CONFIG_ROCKCHIP_RK3288=y
 CONFIG_SPL_ROCKCHIP_BACK_TO_BROM=y
 CONFIG_TARGET_FENNEC_RK3288=y
diff --git a/configs/ficus-rk3399_defconfig b/configs/ficus-rk3399_defconfig
index 6a1b279..d1425dc 100644
--- a/configs/ficus-rk3399_defconfig
+++ b/configs/ficus-rk3399_defconfig
@@ -1,9 +1,6 @@
 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=0x4000
 CONFIG_ROCKCHIP_RK3399=y
 CONFIG_ROCKCHIP_SPL_RESERVE_IRAM=0x4000
 CONFIG_TARGET_ROCK960_RK3399=y
diff --git a/configs/firefly-rk3288_defconfig b/configs/firefly-rk3288_defconfig
index 4cedb28..8abe8a6 100644
--- a/configs/firefly-rk3288_defconfig
+++ b/configs/firefly-rk3288_defconfig
@@ -1,7 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARCH_ROCKCHIP=y
 CONFIG_SYS_TEXT_BASE=0x00000000
-CONFIG_SYS_MALLOC_F_LEN=0x2000
 CONFIG_ROCKCHIP_RK3288=y
 CONFIG_SPL_ROCKCHIP_BACK_TO_BROM=y
 CONFIG_TARGET_FIREFLY_RK3288=y
diff --git a/configs/firefly-rk3399_defconfig b/configs/firefly-rk3399_defconfig
index 61f05b7..9f05f33 100644
--- a/configs/firefly-rk3399_defconfig
+++ b/configs/firefly-rk3399_defconfig
@@ -1,9 +1,6 @@
 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=0x4000
 CONFIG_ROCKCHIP_RK3399=y
 CONFIG_ROCKCHIP_SPL_RESERVE_IRAM=0x50000
 CONFIG_NR_DRAM_BANKS=1
diff --git a/configs/lion-rk3368_defconfig b/configs/lion-rk3368_defconfig
index 75e8583..2c4e11c 100644
--- a/configs/lion-rk3368_defconfig
+++ b/configs/lion-rk3368_defconfig
@@ -1,9 +1,6 @@
 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_RK3368=y
 CONFIG_ROCKCHIP_SPL_RESERVE_IRAM=0x0
 CONFIG_TPL_LIBCOMMON_SUPPORT=y
@@ -91,10 +88,6 @@
 CONFIG_DEBUG_UART_SKIP_INIT=y
 CONFIG_ROCKCHIP_SPI=y
 CONFIG_SYSRESET=y
-CONFIG_TIMER=y
-CONFIG_SPL_TIMER=y
-CONFIG_TPL_TIMER=y
-CONFIG_ROCKCHIP_TIMER=y
 CONFIG_USE_TINY_PRINTF=y
 CONFIG_SPL_TINY_MEMSET=y
 CONFIG_LZO=y
diff --git a/configs/miqi-rk3288_defconfig b/configs/miqi-rk3288_defconfig
index 936192f..c9a3511 100644
--- a/configs/miqi-rk3288_defconfig
+++ b/configs/miqi-rk3288_defconfig
@@ -1,7 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARCH_ROCKCHIP=y
 CONFIG_SYS_TEXT_BASE=0x00000000
-CONFIG_SYS_MALLOC_F_LEN=0x2000
 CONFIG_ROCKCHIP_RK3288=y
 CONFIG_SPL_ROCKCHIP_BACK_TO_BROM=y
 CONFIG_TARGET_MIQI_RK3288=y
diff --git a/configs/nanopc-t4-rk3399_defconfig b/configs/nanopc-t4-rk3399_defconfig
index 7863e45..bca4f08 100644
--- a/configs/nanopc-t4-rk3399_defconfig
+++ b/configs/nanopc-t4-rk3399_defconfig
@@ -1,9 +1,6 @@
 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=0x4000
 CONFIG_ROCKCHIP_RK3399=y
 CONFIG_ROCKCHIP_SPL_RESERVE_IRAM=0x50000
 CONFIG_NR_DRAM_BANKS=1
diff --git a/configs/nanopi-m4-rk3399_defconfig b/configs/nanopi-m4-rk3399_defconfig
index 8b9237c..dd2065d 100644
--- a/configs/nanopi-m4-rk3399_defconfig
+++ b/configs/nanopi-m4-rk3399_defconfig
@@ -1,9 +1,6 @@
 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=0x4000
 CONFIG_ROCKCHIP_RK3399=y
 CONFIG_ROCKCHIP_SPL_RESERVE_IRAM=0x50000
 CONFIG_NR_DRAM_BANKS=1
diff --git a/configs/nanopi-neo4-rk3399_defconfig b/configs/nanopi-neo4-rk3399_defconfig
index 5799ab3..46039d1 100644
--- a/configs/nanopi-neo4-rk3399_defconfig
+++ b/configs/nanopi-neo4-rk3399_defconfig
@@ -1,9 +1,6 @@
 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=0x4000
 CONFIG_ROCKCHIP_RK3399=y
 CONFIG_ROCKCHIP_SPL_RESERVE_IRAM=0x50000
 CONFIG_NR_DRAM_BANKS=1
diff --git a/configs/orangepi-rk3399_defconfig b/configs/orangepi-rk3399_defconfig
index 82ec242..16a0a17 100644
--- a/configs/orangepi-rk3399_defconfig
+++ b/configs/orangepi-rk3399_defconfig
@@ -1,9 +1,6 @@
 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=0x4000
 CONFIG_ROCKCHIP_RK3399=y
 CONFIG_ROCKCHIP_SPL_RESERVE_IRAM=0x50000
 CONFIG_NR_DRAM_BANKS=1
diff --git a/configs/phycore-rk3288_defconfig b/configs/phycore-rk3288_defconfig
index 2e6a4a7..dfddc4a 100644
--- a/configs/phycore-rk3288_defconfig
+++ b/configs/phycore-rk3288_defconfig
@@ -1,7 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARCH_ROCKCHIP=y
 CONFIG_SYS_TEXT_BASE=0x00000000
-CONFIG_SYS_MALLOC_F_LEN=0x2000
 CONFIG_ROCKCHIP_RK3288=y
 CONFIG_SPL_ROCKCHIP_BACK_TO_BROM=y
 CONFIG_TARGET_PHYCORE_RK3288=y
diff --git a/configs/popmetal-rk3288_defconfig b/configs/popmetal-rk3288_defconfig
index 902294b..4c9a7f0 100644
--- a/configs/popmetal-rk3288_defconfig
+++ b/configs/popmetal-rk3288_defconfig
@@ -1,7 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARCH_ROCKCHIP=y
 CONFIG_SYS_TEXT_BASE=0x00000000
-CONFIG_SYS_MALLOC_F_LEN=0x2000
 CONFIG_ROCKCHIP_RK3288=y
 CONFIG_SPL_ROCKCHIP_BACK_TO_BROM=y
 CONFIG_TARGET_POPMETAL_RK3288=y
diff --git a/configs/puma-rk3399_defconfig b/configs/puma-rk3399_defconfig
index 5cb2273..37f845c 100644
--- a/configs/puma-rk3399_defconfig
+++ b/configs/puma-rk3399_defconfig
@@ -2,9 +2,6 @@
 CONFIG_ARCH_ROCKCHIP=y
 CONFIG_SYS_TEXT_BASE=0x00200000
 CONFIG_SPL_GPIO_SUPPORT=y
-CONFIG_SPL_LIBCOMMON_SUPPORT=y
-CONFIG_SPL_LIBGENERIC_SUPPORT=y
-CONFIG_SYS_MALLOC_F_LEN=0x4000
 CONFIG_ROCKCHIP_RK3399=y
 CONFIG_ROCKCHIP_BOOT_MODE_REG=0x0
 CONFIG_TARGET_PUMA_RK3399=y
diff --git a/configs/rock-pi-4-rk3399_defconfig b/configs/rock-pi-4-rk3399_defconfig
index be670df..14ae39a 100644
--- a/configs/rock-pi-4-rk3399_defconfig
+++ b/configs/rock-pi-4-rk3399_defconfig
@@ -1,9 +1,6 @@
 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=0x4000
 CONFIG_ROCKCHIP_RK3399=y
 CONFIG_ROCKCHIP_SPL_RESERVE_IRAM=0x50000
 CONFIG_NR_DRAM_BANKS=1
@@ -28,6 +25,7 @@
 CONFIG_DEFAULT_DEVICE_TREE="rk3399-rock-pi-4"
 CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents"
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_RAM_RK3399_LPDDR4=y
 CONFIG_ROCKCHIP_GPIO=y
 CONFIG_SYS_I2C_ROCKCHIP=y
 CONFIG_MMC_DW=y
diff --git a/configs/rock64-rk3328_defconfig b/configs/rock64-rk3328_defconfig
index 6529ded..ef453e7 100644
--- a/configs/rock64-rk3328_defconfig
+++ b/configs/rock64-rk3328_defconfig
@@ -2,9 +2,6 @@
 CONFIG_SMBIOS_PRODUCT_NAME="rock64_rk3328"
 CONFIG_ARM=y
 CONFIG_ARCH_ROCKCHIP=y
-CONFIG_SPL_LIBCOMMON_SUPPORT=y
-CONFIG_SPL_LIBGENERIC_SUPPORT=y
-CONFIG_SYS_MALLOC_F_LEN=0x2000
 CONFIG_SYS_TEXT_BASE=0x00200000
 CONFIG_ROCKCHIP_RK3328=y
 CONFIG_ROCKCHIP_SPL_RESERVE_IRAM=0x40000
diff --git a/configs/rock960-rk3399_defconfig b/configs/rock960-rk3399_defconfig
index 1958b7e..ed11fef 100644
--- a/configs/rock960-rk3399_defconfig
+++ b/configs/rock960-rk3399_defconfig
@@ -1,9 +1,6 @@
 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=0x4000
 CONFIG_ROCKCHIP_RK3399=y
 CONFIG_ROCKCHIP_SPL_RESERVE_IRAM=0x4000
 CONFIG_TARGET_ROCK960_RK3399=y
@@ -21,7 +18,8 @@
 CONFIG_CMD_BOOTZ=y
 CONFIG_CMD_GPT=y
 CONFIG_CMD_MMC=y
-CONFIG_CMD_SF=y
+CONFIG_CMD_PMIC=y
+CONFIG_CMD_REGULATOR=y
 CONFIG_CMD_USB=y
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_CMD_TIME=y
@@ -34,8 +32,8 @@
 CONFIG_MMC_DW=y
 CONFIG_MMC_DW_ROCKCHIP=y
 CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_SDMA=y
 CONFIG_MMC_SDHCI_ROCKCHIP=y
-CONFIG_SF_DEFAULT_SPEED=20000000
 CONFIG_PMIC_RK8XX=y
 CONFIG_REGULATOR_PWM=y
 CONFIG_REGULATOR_RK8XX=y
@@ -47,5 +45,15 @@
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_GENERIC=y
 CONFIG_ROCKCHIP_USB2_PHY=y
+CONFIG_DM_ETH=y
+CONFIG_USB_HOST_ETHER=y
+CONFIG_USB_ETHER_ASIX88179=y
+CONFIG_USB_ETHER_ASIX=y
+CONFIG_USB_ETHER_MCS7830=y
+CONFIG_USB_ETHER_RTL8152=y
+CONFIG_USB_ETHER_SMSC95XX=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_DWC3=y
+# CONFIG_USB_XHCI_ROCKCHIP is not set
 CONFIG_USE_TINY_PRINTF=y
 CONFIG_ERRNO_STR=y
diff --git a/configs/rockpro64-rk3399_defconfig b/configs/rockpro64-rk3399_defconfig
index e8fc7ae..72bfff2 100644
--- a/configs/rockpro64-rk3399_defconfig
+++ b/configs/rockpro64-rk3399_defconfig
@@ -1,9 +1,6 @@
 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=0x4000
 CONFIG_ROCKCHIP_RK3399=y
 CONFIG_ROCKCHIP_SPL_RESERVE_IRAM=0x50000
 CONFIG_NR_DRAM_BANKS=1
@@ -28,6 +25,7 @@
 CONFIG_DEFAULT_DEVICE_TREE="rk3399-rockpro64"
 CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents"
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_RAM_RK3399_LPDDR4=y
 CONFIG_ROCKCHIP_GPIO=y
 CONFIG_SYS_I2C_ROCKCHIP=y
 CONFIG_MMC_DW=y
diff --git a/configs/sheep-rk3368_defconfig b/configs/sheep-rk3368_defconfig
index cff1905..4883f59 100644
--- a/configs/sheep-rk3368_defconfig
+++ b/configs/sheep-rk3368_defconfig
@@ -1,7 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARCH_ROCKCHIP=y
 CONFIG_SYS_TEXT_BASE=0x00200000
-CONFIG_SYS_MALLOC_F_LEN=0x1000
 CONFIG_ROCKCHIP_RK3368=y
 CONFIG_TARGET_SHEEP=y
 CONFIG_NR_DRAM_BANKS=1
diff --git a/configs/tinker-rk3288_defconfig b/configs/tinker-rk3288_defconfig
index 482ee7d..b234539 100644
--- a/configs/tinker-rk3288_defconfig
+++ b/configs/tinker-rk3288_defconfig
@@ -1,9 +1,7 @@
 CONFIG_ARM=y
 CONFIG_ARCH_ROCKCHIP=y
 CONFIG_SYS_TEXT_BASE=0x01000000
-CONFIG_SYS_MALLOC_F_LEN=0x2000
 CONFIG_ROCKCHIP_RK3288=y
-CONFIG_TPL_LDSCRIPT="arch/arm/mach-rockchip/u-boot-tpl.lds"
 CONFIG_TARGET_TINKER_RK3288=y
 CONFIG_NR_DRAM_BANKS=1
 CONFIG_SPL_SIZE_LIMIT=307200
diff --git a/configs/vyasa-rk3288_defconfig b/configs/vyasa-rk3288_defconfig
index 1108c6a..eaea625 100644
--- a/configs/vyasa-rk3288_defconfig
+++ b/configs/vyasa-rk3288_defconfig
@@ -3,7 +3,6 @@
 # CONFIG_SPL_USE_ARCH_MEMSET is not set
 CONFIG_ARCH_ROCKCHIP=y
 CONFIG_SYS_TEXT_BASE=0x00100000
-CONFIG_SYS_MALLOC_F_LEN=0x2000
 CONFIG_ROCKCHIP_RK3288=y
 CONFIG_TARGET_VYASA_RK3288=y
 CONFIG_NR_DRAM_BANKS=1
diff --git a/doc/README.rockchip b/doc/README.rockchip
index 02e2497..8ccbb87 100644
--- a/doc/README.rockchip
+++ b/doc/README.rockchip
@@ -123,10 +123,6 @@
 
    Option 2: Package the image with SPL:
 
-   - We need the Python elftools.elf.elffile library for make_fit_atf.py to work
-
-     => sudo apt-get install python-pyelftools
-
    - Export cross compiler path for aarch64
 
    - Compile ATF
diff --git a/drivers/clk/rockchip/clk_rk3399.c b/drivers/clk/rockchip/clk_rk3399.c
index aa6a8ad..d9950c1 100644
--- a/drivers/clk/rockchip/clk_rk3399.c
+++ b/drivers/clk/rockchip/clk_rk3399.c
@@ -38,8 +38,8 @@
 };
 
 #define RATE_TO_DIV(input_rate, output_rate) \
-	((input_rate) / (output_rate) - 1);
-#define DIV_TO_RATE(input_rate, div)    ((input_rate) / ((div) + 1))
+	((input_rate) / (output_rate) - 1)
+#define DIV_TO_RATE(input_rate, div)		((input_rate) / ((div) + 1))
 
 #define PLL_DIVISORS(hz, _refdiv, _postdiv1, _postdiv2) {\
 	.refdiv = _refdiv,\
@@ -53,15 +53,15 @@
 static const struct pll_div ppll_init_cfg = PLL_DIVISORS(PPLL_HZ, 2, 2, 1);
 #endif
 
-static const struct pll_div apll_l_1600_cfg = PLL_DIVISORS(1600*MHz, 3, 1, 1);
-static const struct pll_div apll_l_600_cfg = PLL_DIVISORS(600*MHz, 1, 2, 1);
+static const struct pll_div apll_l_1600_cfg = PLL_DIVISORS(1600 * MHz, 3, 1, 1);
+static const struct pll_div apll_l_600_cfg = PLL_DIVISORS(600 * MHz, 1, 2, 1);
 
 static const struct pll_div *apll_l_cfgs[] = {
 	[APLL_L_1600_MHZ] = &apll_l_1600_cfg,
 	[APLL_L_600_MHZ] = &apll_l_600_cfg,
 };
 
-static const struct pll_div apll_b_600_cfg = PLL_DIVISORS(600*MHz, 1, 2, 1);
+static const struct pll_div apll_b_600_cfg = PLL_DIVISORS(600 * MHz, 1, 2, 1);
 static const struct pll_div *apll_b_cfgs[] = {
 	[APLL_B_600_MHZ] = &apll_b_600_cfg,
 };
@@ -393,7 +393,7 @@
 		fref_khz = ref_khz / refdiv;
 
 		fbdiv = vco_khz / fref_khz;
-		if ((fbdiv >= max_fbdiv) || (fbdiv <= min_fbdiv))
+		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) {
@@ -409,7 +409,7 @@
 		div->fbdiv = fbdiv;
 	}
 
-	if (best_diff_khz > 4 * (MHz/KHz)) {
+	if (best_diff_khz > 4 * (MHz / KHz)) {
 		printf("%s: Failed to match output frequency %u, "
 		       "difference is %u Hz,exceed 4MHZ\n", __func__, freq_hz,
 		       best_diff_khz * KHz);
@@ -489,28 +489,21 @@
 }
 
 #define I2C_CLK_REG_MASK(bus) \
-			(I2C_DIV_CON_MASK << \
-			CLK_I2C ##bus## _DIV_CON_SHIFT | \
-			CLK_I2C_PLL_SEL_MASK << \
-			CLK_I2C ##bus## _PLL_SEL_SHIFT)
+	(I2C_DIV_CON_MASK << CLK_I2C ##bus## _DIV_CON_SHIFT | \
+	 CLK_I2C_PLL_SEL_MASK << CLK_I2C ##bus## _PLL_SEL_SHIFT)
 
 #define I2C_CLK_REG_VALUE(bus, clk_div) \
-			      ((clk_div - 1) << \
-					CLK_I2C ##bus## _DIV_CON_SHIFT | \
-			      CLK_I2C_PLL_SEL_GPLL << \
-					CLK_I2C ##bus## _PLL_SEL_SHIFT)
+	((clk_div - 1) << CLK_I2C ##bus## _DIV_CON_SHIFT | \
+	 CLK_I2C_PLL_SEL_GPLL << CLK_I2C ##bus## _PLL_SEL_SHIFT)
 
 #define I2C_CLK_DIV_VALUE(con, bus) \
-			(con >> CLK_I2C ##bus## _DIV_CON_SHIFT) & \
-				I2C_DIV_CON_MASK;
+	((con >> CLK_I2C ##bus## _DIV_CON_SHIFT) & I2C_DIV_CON_MASK)
 
 #define I2C_PMUCLK_REG_MASK(bus) \
-			(I2C_DIV_CON_MASK << \
-			 CLK_I2C ##bus## _DIV_CON_SHIFT)
+	(I2C_DIV_CON_MASK << CLK_I2C ##bus## _DIV_CON_SHIFT)
 
 #define I2C_PMUCLK_REG_VALUE(bus, clk_div) \
-				((clk_div - 1) << \
-				CLK_I2C ##bus## _DIV_CON_SHIFT)
+	((clk_div - 1) << CLK_I2C ##bus## _DIV_CON_SHIFT)
 
 static ulong rk3399_i2c_get_clk(struct rk3399_cru *cru, ulong clk_id)
 {
@@ -597,9 +590,9 @@
  */
 
 struct spi_clkreg {
-	uint8_t reg;  /* CLKSEL_CON[reg] register in CRU */
-	uint8_t div_shift;
-	uint8_t sel_shift;
+	u8 reg;  /* CLKSEL_CON[reg] register in CRU */
+	u8 div_shift;
+	u8 sel_shift;
 };
 
 /*
@@ -678,7 +671,7 @@
 static ulong rk3399_vop_set_clk(struct rk3399_cru *cru, ulong clk_id, u32 hz)
 {
 	struct pll_div vpll_config = {0};
-	int aclk_vop = 198*MHz;
+	int aclk_vop = 198 * MHz;
 	void *aclkreg_addr, *dclkreg_addr;
 	u32 div;
 
@@ -710,7 +703,7 @@
 	rkclk_set_pll(&cru->vpll_con[0], &vpll_config);
 
 	rk_clrsetreg(dclkreg_addr,
-		     DCLK_VOP_DCLK_SEL_MASK | DCLK_VOP_PLL_SEL_MASK|
+		     DCLK_VOP_DCLK_SEL_MASK | DCLK_VOP_PLL_SEL_MASK |
 		     DCLK_VOP_DIV_CON_MASK,
 		     DCLK_VOP_DCLK_SEL_DIVOUT << DCLK_VOP_DCLK_SEL_SHIFT |
 		     DCLK_VOP_PLL_SEL_VPLL << DCLK_VOP_PLL_SEL_SHIFT |
@@ -750,7 +743,7 @@
 				ulong clk_id, ulong set_rate)
 {
 	int src_clk_div;
-	int aclk_emmc = 198*MHz;
+	int aclk_emmc = 198 * MHz;
 
 	switch (clk_id) {
 	case HCLK_SDMMC:
@@ -776,7 +769,7 @@
 		break;
 	case SCLK_EMMC:
 		/* Select aclk_emmc source from GPLL */
-		src_clk_div = DIV_ROUND_UP(GPLL_HZ , aclk_emmc);
+		src_clk_div = DIV_ROUND_UP(GPLL_HZ, aclk_emmc);
 		assert(src_clk_div - 1 < 32);
 
 		rk_clrsetreg(&cru->clksel_con[21],
@@ -834,23 +827,31 @@
 
 	/*  clk_ddrc == DPLL = 24MHz / refdiv * fbdiv / postdiv1 / postdiv2 */
 	switch (set_rate) {
-	case 200*MHz:
+	case 50 * MHz:
+		dpll_cfg = (struct pll_div)
+		{.refdiv = 1, .fbdiv = 12, .postdiv1 = 3, .postdiv2 = 2};
+		break;
+	case 200 * MHz:
 		dpll_cfg = (struct pll_div)
 		{.refdiv = 1, .fbdiv = 50, .postdiv1 = 6, .postdiv2 = 1};
 		break;
-	case 300*MHz:
+	case 300 * MHz:
 		dpll_cfg = (struct pll_div)
 		{.refdiv = 2, .fbdiv = 100, .postdiv1 = 4, .postdiv2 = 1};
 		break;
-	case 666*MHz:
+	case 400 * MHz:
+		dpll_cfg = (struct pll_div)
+		{.refdiv = 1, .fbdiv = 50, .postdiv1 = 3, .postdiv2 = 1};
+		break;
+	case 666 * MHz:
 		dpll_cfg = (struct pll_div)
 		{.refdiv = 2, .fbdiv = 111, .postdiv1 = 2, .postdiv2 = 1};
 		break;
-	case 800*MHz:
+	case 800 * MHz:
 		dpll_cfg = (struct pll_div)
 		{.refdiv = 1, .fbdiv = 100, .postdiv1 = 3, .postdiv2 = 1};
 		break;
-	case 933*MHz:
+	case 933 * MHz:
 		dpll_cfg = (struct pll_div)
 		{.refdiv = 1, .fbdiv = 116, .postdiv1 = 3, .postdiv2 = 1};
 		break;
@@ -916,7 +917,6 @@
 	case SCLK_UART2:
 	case SCLK_UART3:
 		return 24000000;
-		break;
 	case PCLK_HDMI_CTRL:
 		break;
 	case DCLK_VOP0:
@@ -1014,7 +1014,8 @@
 	return ret;
 }
 
-static int __maybe_unused rk3399_gmac_set_parent(struct clk *clk, struct clk *parent)
+static int __maybe_unused rk3399_gmac_set_parent(struct clk *clk,
+						 struct clk *parent)
 {
 	struct rk3399_clk_priv *priv = dev_get_priv(clk->dev);
 	const char *clock_output_name;
@@ -1024,7 +1025,7 @@
 	 * If the requested parent is in the same clock-controller and
 	 * the id is SCLK_MAC ("clk_gmac"), switch to the internal clock.
 	 */
-	if ((parent->dev == clk->dev) && (parent->id == SCLK_MAC)) {
+	if (parent->dev == clk->dev && parent->id == SCLK_MAC) {
 		debug("%s: switching RGMII to SCLK_MAC\n", __func__);
 		rk_clrreg(&priv->cru->clksel_con[19], BIT(4));
 		return 0;
@@ -1049,7 +1050,8 @@
 	return -EINVAL;
 }
 
-static int __maybe_unused rk3399_clk_set_parent(struct clk *clk, struct clk *parent)
+static int __maybe_unused rk3399_clk_set_parent(struct clk *clk,
+						struct clk *parent)
 {
 	switch (clk->id) {
 	case SCLK_RMII_SRC:
@@ -1078,6 +1080,18 @@
 	case PCLK_GMAC:
 		/* Required to successfully probe the Designware GMAC driver */
 		return 0;
+
+	case SCLK_USB3OTG0_REF:
+	case SCLK_USB3OTG1_REF:
+	case SCLK_USB3OTG0_SUSPEND:
+	case SCLK_USB3OTG1_SUSPEND:
+	case ACLK_USB3OTG0:
+	case ACLK_USB3OTG1:
+	case ACLK_USB3_RKSOC_AXI_PERF:
+	case ACLK_USB3:
+	case ACLK_USB3_GRF:
+		/* Required to successfully probe the Designware USB3 driver */
+		return 0;
 	}
 
 	debug("%s: unsupported clk %ld\n", __func__, clk->id);
diff --git a/drivers/ram/Kconfig b/drivers/ram/Kconfig
index fbf7d7b..568d8f2 100644
--- a/drivers/ram/Kconfig
+++ b/drivers/ram/Kconfig
@@ -54,4 +54,5 @@
 	  config add support for the initialization of the external
 	  SDRAM devices connected to DDR subsystem.
 
+source "drivers/ram/rockchip/Kconfig"
 source "drivers/ram/stm32mp1/Kconfig"
diff --git a/drivers/ram/rockchip/Kconfig b/drivers/ram/rockchip/Kconfig
new file mode 100644
index 0000000..4f274e0
--- /dev/null
+++ b/drivers/ram/rockchip/Kconfig
@@ -0,0 +1,33 @@
+config RAM_ROCKCHIP
+	bool "Ram drivers support for Rockchip SoCs"
+	depends on RAM && ARCH_ROCKCHIP
+	default y
+	help
+	  This enables support for ram drivers Rockchip SoCs.
+
+if RAM_ROCKCHIP
+
+config RAM_ROCKCHIP_DEBUG
+	bool "Rockchip ram drivers debugging"
+	help
+	  This enables debugging ram driver API's for the platforms
+	  based on Rockchip SoCs.
+
+	  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
+	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 5df1960..feb1f82 100644
--- a/drivers/ram/rockchip/Makefile
+++ b/drivers/ram/rockchip/Makefile
@@ -3,10 +3,11 @@
 # Copyright (c) 2017 Theobroma Systems Design und Consulting GmbH
 #
 
+obj-$(CONFIG_RAM_ROCKCHIP_DEBUG) += sdram_debug.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_ROCKCHIP_RK3399) = sdram_rk3399.o
+obj-$(CONFIG_RAM_RK3399) += sdram_rk3399.o
diff --git a/drivers/ram/rockchip/sdram-rk3399-lpddr4-400.inc b/drivers/ram/rockchip/sdram-rk3399-lpddr4-400.inc
new file mode 100644
index 0000000..c50a03d
--- /dev/null
+++ b/drivers/ram/rockchip/sdram-rk3399-lpddr4-400.inc
@@ -0,0 +1,1570 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * (C) Copyright 2019 Rockchip Electronics Co., Ltd.
+ * (C) Copyright 2019 Amarula Solutions
+ */
+
+{
+	{
+		{
+			{
+				.rank = 0x2,
+				.col = 0xA,
+				.bk = 0x3,
+				.bw = 0x2,
+				.dbw = 0x1,
+				.row_3_4 = 0x0,
+				.cs0_row = 0xF,
+				.cs1_row = 0xF,
+				.ddrconfig = 1,
+			},
+			{
+				.ddrtiminga0 = 0x80241d22,
+				.ddrtimingb0 = 0x15050f08,
+				.ddrtimingc0 = {
+					0x00000602,
+				},
+				.devtodev0 = 0x00002122,
+				.ddrmode = {
+					0x0000004c,
+				},
+				.agingx0 = 0x00000000,
+			}
+		},
+		{
+			{
+				.rank = 0x2,
+				.col = 0xA,
+				.bk = 0x3,
+				.bw = 0x2,
+				.dbw = 0x1,
+				.row_3_4 = 0x0,
+				.cs0_row = 0xF,
+				.cs1_row = 0xF,
+				.ddrconfig = 1,
+			},
+			{
+				.ddrtiminga0 = 0x80241d22,
+				.ddrtimingb0 = 0x15050f08,
+				.ddrtimingc0 = {
+					0x00000602,
+				},
+				.devtodev0 = 0x00002122,
+				.ddrmode = {
+					0x0000004c,
+				},
+				.agingx0 = 0x00000000,
+			}
+		}
+	},
+	{
+		.ddr_freq = 400 * MHz,
+		.dramtype = LPDDR4,
+		.num_channels = 2,
+		.stride = 13,
+		.odt = 1,
+	},
+	{
+		{
+			0x00000b00,	/* DENALI_CTL_00_DATA */
+			0x00000000,	/* DENALI_CTL_01_DATA */
+			0x00000000,	/* DENALI_CTL_02_DATA */
+			0x00000000,	/* DENALI_CTL_03_DATA */
+			0x00000000,	/* DENALI_CTL_04_DATA */
+			0x00013880,	/* DENALI_CTL_05_DATA */
+			0x000c3500,	/* DENALI_CTL_06_DATA */
+			0x00000005,	/* DENALI_CTL_07_DATA */
+			0x00000320,	/* DENALI_CTL_08_DATA */
+			0x00027100,	/* DENALI_CTL_09_DATA */
+			0x00186a00,	/* DENALI_CTL_10_DATA */
+			0x00000005,	/* DENALI_CTL_11_DATA */
+			0x00000640,	/* DENALI_CTL_12_DATA */
+			0x00002710,	/* DENALI_CTL_13_DATA */
+			0x000186a0,	/* DENALI_CTL_14_DATA */
+			0x00000005,	/* DENALI_CTL_15_DATA */
+			0x01000064,	/* DENALI_CTL_16_DATA */
+			0x00000000,	/* DENALI_CTL_17_DATA */
+			0x02020101,	/* DENALI_CTL_18_DATA */
+			0x00000102,	/* DENALI_CTL_19_DATA */
+			0x00000050,	/* DENALI_CTL_20_DATA */
+			0x000000c8,	/* DENALI_CTL_21_DATA */
+			0x00000000,	/* DENALI_CTL_22_DATA */
+			0x06140000,	/* DENALI_CTL_23_DATA */
+			0x00081c00,	/* DENALI_CTL_24_DATA */
+			0x0400040c,	/* DENALI_CTL_25_DATA */
+			0x19042008,	/* DENALI_CTL_26_DATA */
+			0x10080a11,	/* DENALI_CTL_27_DATA */
+			0x22310800,	/* DENALI_CTL_28_DATA */
+			0x00200f0a,	/* DENALI_CTL_29_DATA */
+			0x0a030704,	/* DENALI_CTL_30_DATA */
+			0x08000204,	/* DENALI_CTL_31_DATA */
+			0x00000a0a,	/* DENALI_CTL_32_DATA */
+			0x04006db0,	/* DENALI_CTL_33_DATA */
+			0x0a0a0804,	/* DENALI_CTL_34_DATA */
+			0x0600db60,	/* DENALI_CTL_35_DATA */
+			0x0a0a0806,	/* DENALI_CTL_36_DATA */
+			0x04000db6,	/* DENALI_CTL_37_DATA */
+			0x02030404,	/* DENALI_CTL_38_DATA */
+			0x0f0a0800,	/* DENALI_CTL_39_DATA */
+			0x08040411,	/* DENALI_CTL_40_DATA */
+			0x1400640a,	/* DENALI_CTL_41_DATA */
+			0x02010a0a,	/* DENALI_CTL_42_DATA */
+			0x00010001,	/* DENALI_CTL_43_DATA */
+			0x04082012,	/* DENALI_CTL_44_DATA */
+			0x00041109,	/* DENALI_CTL_45_DATA */
+			0x00000000,	/* DENALI_CTL_46_DATA */
+			0x03010000,	/* DENALI_CTL_47_DATA */
+			0x06100034,	/* DENALI_CTL_48_DATA */
+			0x0c280068,	/* DENALI_CTL_49_DATA */
+			0x00bb0007,	/* DENALI_CTL_50_DATA */
+			0x00000000,	/* DENALI_CTL_51_DATA */
+			0x00060003,	/* DENALI_CTL_52_DATA */
+			0x000a0003,	/* DENALI_CTL_53_DATA */
+			0x000a0014,	/* DENALI_CTL_54_DATA */
+			0x01000000,	/* DENALI_CTL_55_DATA */
+			0x030a0000,	/* DENALI_CTL_56_DATA */
+			0x0c000002,	/* DENALI_CTL_57_DATA */
+			0x00000103,	/* DENALI_CTL_58_DATA */
+			0x0003030a,	/* DENALI_CTL_59_DATA */
+			0x00060037,	/* DENALI_CTL_60_DATA */
+			0x0003006e,	/* DENALI_CTL_61_DATA */
+			0x05050007,	/* DENALI_CTL_62_DATA */
+			0x03020605,	/* DENALI_CTL_63_DATA */
+			0x06050301,	/* DENALI_CTL_64_DATA */
+			0x06020c05,	/* DENALI_CTL_65_DATA */
+			0x05050302,	/* DENALI_CTL_66_DATA */
+			0x03020305,	/* DENALI_CTL_67_DATA */
+			0x00000301,	/* DENALI_CTL_68_DATA */
+			0x00000301,	/* DENALI_CTL_69_DATA */
+			0x00000001,	/* DENALI_CTL_70_DATA */
+			0x00000000,	/* DENALI_CTL_71_DATA */
+			0x00000000,	/* DENALI_CTL_72_DATA */
+			0x01000000,	/* DENALI_CTL_73_DATA */
+			0x80104002,	/* DENALI_CTL_74_DATA */
+			0x00040003,	/* DENALI_CTL_75_DATA */
+			0x00040005,	/* DENALI_CTL_76_DATA */
+			0x00030000,	/* DENALI_CTL_77_DATA */
+			0x00050004,	/* DENALI_CTL_78_DATA */
+			0x00000004,	/* DENALI_CTL_79_DATA */
+			0x00040003,	/* DENALI_CTL_80_DATA */
+			0x00040005,	/* DENALI_CTL_81_DATA */
+			0x18400000,	/* DENALI_CTL_82_DATA */
+			0x00000c20,	/* DENALI_CTL_83_DATA */
+			0x185030a0,	/* DENALI_CTL_84_DATA */
+			0x02ec0000,	/* DENALI_CTL_85_DATA */
+			0x00000176,	/* DENALI_CTL_86_DATA */
+			0x00000000,	/* DENALI_CTL_87_DATA */
+			0x00000000,	/* DENALI_CTL_88_DATA */
+			0x00000000,	/* DENALI_CTL_89_DATA */
+			0x00000000,	/* DENALI_CTL_90_DATA */
+			0x00000000,	/* DENALI_CTL_91_DATA */
+			0x06030300,	/* DENALI_CTL_92_DATA */
+			0x00030303,	/* DENALI_CTL_93_DATA */
+			0x02030200,	/* DENALI_CTL_94_DATA */
+			0x00040703,	/* DENALI_CTL_95_DATA */
+			0x03020302,	/* DENALI_CTL_96_DATA */
+			0x02000407,	/* DENALI_CTL_97_DATA */
+			0x07030203,	/* DENALI_CTL_98_DATA */
+			0x00030f04,	/* DENALI_CTL_99_DATA */
+			0x00070004,	/* DENALI_CTL_100_DATA */
+			0x00000000,	/* DENALI_CTL_101_DATA */
+			0x00000000,	/* DENALI_CTL_102_DATA */
+			0x00000000,	/* DENALI_CTL_103_DATA */
+			0x00000000,	/* DENALI_CTL_104_DATA */
+			0x00000000,	/* DENALI_CTL_105_DATA */
+			0x00000000,	/* DENALI_CTL_106_DATA */
+			0x00000000,	/* DENALI_CTL_107_DATA */
+			0x00010000,	/* DENALI_CTL_108_DATA */
+			0x20040020,	/* DENALI_CTL_109_DATA */
+			0x00200400,	/* DENALI_CTL_110_DATA */
+			0x01000400,	/* DENALI_CTL_111_DATA */
+			0x00000b80,	/* DENALI_CTL_112_DATA */
+			0x00000000,	/* DENALI_CTL_113_DATA */
+			0x00000001,	/* DENALI_CTL_114_DATA */
+			0x00000002,	/* DENALI_CTL_115_DATA */
+			0x0000000e,	/* DENALI_CTL_116_DATA */
+			0x00000000,	/* DENALI_CTL_117_DATA */
+			0x00000000,	/* DENALI_CTL_118_DATA */
+			0x00000000,	/* DENALI_CTL_119_DATA */
+			0x00000000,	/* DENALI_CTL_120_DATA */
+			0x00000000,	/* DENALI_CTL_121_DATA */
+			0x00500000,	/* DENALI_CTL_122_DATA */
+			0x00640028,	/* DENALI_CTL_123_DATA */
+			0x00640404,	/* DENALI_CTL_124_DATA */
+			0x005000a0,	/* DENALI_CTL_125_DATA */
+			0x060600c8,	/* DENALI_CTL_126_DATA */
+			0x000a00c8,	/* DENALI_CTL_127_DATA */
+			0x000d0005,	/* DENALI_CTL_128_DATA */
+			0x000d0404,	/* DENALI_CTL_129_DATA */
+			0x00000000,	/* DENALI_CTL_130_DATA */
+			0x00000000,	/* DENALI_CTL_131_DATA */
+			0x00000000,	/* DENALI_CTL_132_DATA */
+			0x001400a3,	/* DENALI_CTL_133_DATA */
+			0x00e30009,	/* DENALI_CTL_134_DATA */
+			0x00120024,	/* DENALI_CTL_135_DATA */
+			0x00040063,	/* DENALI_CTL_136_DATA */
+			0x00000000,	/* DENALI_CTL_137_DATA */
+			0x00310031,	/* DENALI_CTL_138_DATA */
+			0x00000031,	/* DENALI_CTL_139_DATA */
+			0x004d0000,	/* DENALI_CTL_140_DATA */
+			0x004d004d,	/* DENALI_CTL_141_DATA */
+			0x004d0000,	/* DENALI_CTL_142_DATA */
+			0x004d004d,	/* DENALI_CTL_143_DATA */
+			0x00010101,	/* DENALI_CTL_144_DATA */
+			0x00000000,	/* DENALI_CTL_145_DATA */
+			0x00000000,	/* DENALI_CTL_146_DATA */
+			0x001400a3,	/* DENALI_CTL_147_DATA */
+			0x00e30009,	/* DENALI_CTL_148_DATA */
+			0x00120024,	/* DENALI_CTL_149_DATA */
+			0x00040063,	/* DENALI_CTL_150_DATA */
+			0x00000000,	/* DENALI_CTL_151_DATA */
+			0x00310031,	/* DENALI_CTL_152_DATA */
+			0x00000031,	/* DENALI_CTL_153_DATA */
+			0x004d0000,	/* DENALI_CTL_154_DATA */
+			0x004d004d,	/* DENALI_CTL_155_DATA */
+			0x004d0000,	/* DENALI_CTL_156_DATA */
+			0x004d004d,	/* DENALI_CTL_157_DATA */
+			0x00010101,	/* DENALI_CTL_158_DATA */
+			0x00000000,	/* DENALI_CTL_159_DATA */
+			0x00000000,	/* DENALI_CTL_160_DATA */
+			0x00000000,	/* DENALI_CTL_161_DATA */
+			0x00000001,	/* DENALI_CTL_162_DATA */
+			0x00000000,	/* DENALI_CTL_163_DATA */
+			0x18151100,	/* DENALI_CTL_164_DATA */
+			0x0000000c,	/* DENALI_CTL_165_DATA */
+			0x00000000,	/* DENALI_CTL_166_DATA */
+			0x00000000,	/* DENALI_CTL_167_DATA */
+			0x00000000,	/* DENALI_CTL_168_DATA */
+			0x00000000,	/* DENALI_CTL_169_DATA */
+			0x00000000,	/* DENALI_CTL_170_DATA */
+			0x00000000,	/* DENALI_CTL_171_DATA */
+			0x00000000,	/* DENALI_CTL_172_DATA */
+			0x00000000,	/* DENALI_CTL_173_DATA */
+			0x00000000,	/* DENALI_CTL_174_DATA */
+			0x00000000,	/* DENALI_CTL_175_DATA */
+			0x00000000,	/* DENALI_CTL_176_DATA */
+			0x00000000,	/* DENALI_CTL_177_DATA */
+			0x00000000,	/* DENALI_CTL_178_DATA */
+			0x00020003,	/* DENALI_CTL_179_DATA */
+			0x00400100,	/* DENALI_CTL_180_DATA */
+			0x000c0190,	/* DENALI_CTL_181_DATA */
+			0x01000200,	/* DENALI_CTL_182_DATA */
+			0x03200040,	/* DENALI_CTL_183_DATA */
+			0x00020018,	/* DENALI_CTL_184_DATA */
+			0x00400100,	/* DENALI_CTL_185_DATA */
+			0x00080032,	/* DENALI_CTL_186_DATA */
+			0x00140000,	/* DENALI_CTL_187_DATA */
+			0x00030028,	/* DENALI_CTL_188_DATA */
+			0x01010100,	/* DENALI_CTL_189_DATA */
+			0x02000202,	/* DENALI_CTL_190_DATA */
+			0x0b000002,	/* DENALI_CTL_191_DATA */
+			0x01000f0f,	/* DENALI_CTL_192_DATA */
+			0x00000000,	/* DENALI_CTL_193_DATA */
+			0x00000000,	/* DENALI_CTL_194_DATA */
+			0x00010003,	/* DENALI_CTL_195_DATA */
+			0x00000c03,	/* DENALI_CTL_196_DATA */
+			0x00040101,	/* DENALI_CTL_197_DATA */
+			0x04010100,	/* DENALI_CTL_198_DATA */
+			0x01000000,	/* DENALI_CTL_199_DATA */
+			0x02010000,	/* DENALI_CTL_200_DATA */
+			0x00000001,	/* DENALI_CTL_201_DATA */
+			0x00000000,	/* DENALI_CTL_202_DATA */
+			0x00000000,	/* DENALI_CTL_203_DATA */
+			0x00000000,	/* DENALI_CTL_204_DATA */
+			0x00000000,	/* DENALI_CTL_205_DATA */
+			0x00000000,	/* DENALI_CTL_206_DATA */
+			0x00000000,	/* DENALI_CTL_207_DATA */
+			0x00000000,	/* DENALI_CTL_208_DATA */
+			0x00000000,	/* DENALI_CTL_209_DATA */
+			0x00000000,	/* DENALI_CTL_210_DATA */
+			0x00010000,	/* DENALI_CTL_211_DATA */
+			0x00000001,	/* DENALI_CTL_212_DATA */
+			0x01010001,	/* DENALI_CTL_213_DATA */
+			0x05040001,	/* DENALI_CTL_214_DATA */
+			0x040a0703,	/* DENALI_CTL_215_DATA */
+			0x02080808,	/* DENALI_CTL_216_DATA */
+			0x020e000a,	/* DENALI_CTL_217_DATA */
+			0x020f010b,	/* DENALI_CTL_218_DATA */
+			0x000d0008,	/* DENALI_CTL_219_DATA */
+			0x00080b0a,	/* DENALI_CTL_220_DATA */
+			0x03000200,	/* DENALI_CTL_221_DATA */
+			0x00000100,	/* DENALI_CTL_222_DATA */
+			0x00000000,	/* DENALI_CTL_223_DATA */
+			0x00000000,	/* DENALI_CTL_224_DATA */
+			0x0d000001,	/* DENALI_CTL_225_DATA */
+			0x00000028,	/* DENALI_CTL_226_DATA */
+			0x00010000,	/* DENALI_CTL_227_DATA */
+			0x00000003,	/* DENALI_CTL_228_DATA */
+			0x00000000,	/* DENALI_CTL_229_DATA */
+			0x00000000,	/* DENALI_CTL_230_DATA */
+			0x00000000,	/* DENALI_CTL_231_DATA */
+			0x00000000,	/* DENALI_CTL_232_DATA */
+			0x00000000,	/* DENALI_CTL_233_DATA */
+			0x00000000,	/* DENALI_CTL_234_DATA */
+			0x00000000,	/* DENALI_CTL_235_DATA */
+			0x00000000,	/* DENALI_CTL_236_DATA */
+			0x00010100,	/* DENALI_CTL_237_DATA */
+			0x01000000,	/* DENALI_CTL_238_DATA */
+			0x00000001,	/* DENALI_CTL_239_DATA */
+			0x00000303,	/* DENALI_CTL_240_DATA */
+			0x00000000,	/* DENALI_CTL_241_DATA */
+			0x00000000,	/* DENALI_CTL_242_DATA */
+			0x00000000,	/* DENALI_CTL_243_DATA */
+			0x00000000,	/* DENALI_CTL_244_DATA */
+			0x00000000,	/* DENALI_CTL_245_DATA */
+			0x00000000,	/* DENALI_CTL_246_DATA */
+			0x00000000,	/* DENALI_CTL_247_DATA */
+			0x00000000,	/* DENALI_CTL_248_DATA */
+			0x00000000,	/* DENALI_CTL_249_DATA */
+			0x00000000,	/* DENALI_CTL_250_DATA */
+			0x00000000,	/* DENALI_CTL_251_DATA */
+			0x00000000,	/* DENALI_CTL_252_DATA */
+			0x00000000,	/* DENALI_CTL_253_DATA */
+			0x00000000,	/* DENALI_CTL_254_DATA */
+			0x00000000,	/* DENALI_CTL_255_DATA */
+			0x000556aa,	/* DENALI_CTL_256_DATA */
+			0x000aaaaa,	/* DENALI_CTL_257_DATA */
+			0x000aa955,	/* DENALI_CTL_258_DATA */
+			0x00055555,	/* DENALI_CTL_259_DATA */
+			0x000b3133,	/* DENALI_CTL_260_DATA */
+			0x0004cd33,	/* DENALI_CTL_261_DATA */
+			0x0004cecc,	/* DENALI_CTL_262_DATA */
+			0x000b32cc,	/* DENALI_CTL_263_DATA */
+			0x00010300,	/* DENALI_CTL_264_DATA */
+			0x03000100,	/* DENALI_CTL_265_DATA */
+			0x00000000,	/* DENALI_CTL_266_DATA */
+			0x00000000,	/* DENALI_CTL_267_DATA */
+			0x00000000,	/* DENALI_CTL_268_DATA */
+			0x00000000,	/* DENALI_CTL_269_DATA */
+			0x00000000,	/* DENALI_CTL_270_DATA */
+			0x00000000,	/* DENALI_CTL_271_DATA */
+			0x00000000,	/* DENALI_CTL_272_DATA */
+			0x00000000,	/* DENALI_CTL_273_DATA */
+			0x00ffff00,	/* DENALI_CTL_274_DATA */
+			0x1a160000,	/* DENALI_CTL_275_DATA */
+			0x08000012,	/* DENALI_CTL_276_DATA */
+			0x00000c20,	/* DENALI_CTL_277_DATA */
+			0x00000200,	/* DENALI_CTL_278_DATA */
+			0x00000200,	/* DENALI_CTL_279_DATA */
+			0x00000200,	/* DENALI_CTL_280_DATA */
+			0x00000200,	/* DENALI_CTL_281_DATA */
+			0x00000c20,	/* DENALI_CTL_282_DATA */
+			0x00007940,	/* DENALI_CTL_283_DATA */
+			0x18500409,	/* DENALI_CTL_284_DATA */
+			0x00000200,	/* DENALI_CTL_285_DATA */
+			0x00000200,	/* DENALI_CTL_286_DATA */
+			0x00000200,	/* DENALI_CTL_287_DATA */
+			0x00000200,	/* DENALI_CTL_288_DATA */
+			0x00001850,	/* DENALI_CTL_289_DATA */
+			0x0000f320,	/* DENALI_CTL_290_DATA */
+			0x0176060c,	/* DENALI_CTL_291_DATA */
+			0x00000200,	/* DENALI_CTL_292_DATA */
+			0x00000200,	/* DENALI_CTL_293_DATA */
+			0x00000200,	/* DENALI_CTL_294_DATA */
+			0x00000200,	/* DENALI_CTL_295_DATA */
+			0x00000176,	/* DENALI_CTL_296_DATA */
+			0x00000e9c,	/* DENALI_CTL_297_DATA */
+			0x02020205,	/* DENALI_CTL_298_DATA */
+			0x03030202,	/* DENALI_CTL_299_DATA */
+			0x00000018,	/* DENALI_CTL_300_DATA */
+			0x00000000,	/* DENALI_CTL_301_DATA */
+			0x00000000,	/* DENALI_CTL_302_DATA */
+			0x00001403,	/* DENALI_CTL_303_DATA */
+			0x00000000,	/* DENALI_CTL_304_DATA */
+			0x00000000,	/* DENALI_CTL_305_DATA */
+			0x00000000,	/* DENALI_CTL_306_DATA */
+			0x00030000,	/* DENALI_CTL_307_DATA */
+			0x000a001c,	/* DENALI_CTL_308_DATA */
+			0x000e0020,	/* DENALI_CTL_309_DATA */
+			0x00060018,	/* DENALI_CTL_310_DATA */
+			0x00000000,	/* DENALI_CTL_311_DATA */
+			0x00000000,	/* DENALI_CTL_312_DATA */
+			0x02000000,	/* DENALI_CTL_313_DATA */
+			0x00090305,	/* DENALI_CTL_314_DATA */
+			0x00050101,	/* DENALI_CTL_315_DATA */
+			0x00000000,	/* DENALI_CTL_316_DATA */
+			0x00000000,	/* DENALI_CTL_317_DATA */
+			0x00000000,	/* DENALI_CTL_318_DATA */
+			0x00000000,	/* DENALI_CTL_319_DATA */
+			0x00000000,	/* DENALI_CTL_320_DATA */
+			0x00000000,	/* DENALI_CTL_321_DATA */
+			0x00000000,	/* DENALI_CTL_322_DATA */
+			0x00000000,	/* DENALI_CTL_323_DATA */
+			0x01000001,	/* DENALI_CTL_324_DATA */
+			0x01010101,	/* DENALI_CTL_325_DATA */
+			0x01000101,	/* DENALI_CTL_326_DATA */
+			0x01000100,	/* DENALI_CTL_327_DATA */
+			0x00010001,	/* DENALI_CTL_328_DATA */
+			0x00010002,	/* DENALI_CTL_329_DATA */
+			0x00020100,	/* DENALI_CTL_330_DATA */
+			0x00000002	/* DENALI_CTL_331_DATA */
+		}
+	},
+	{
+		{
+			0x00000b00,	/* DENALI_PI_00_DATA */
+			0x00000000,	/* DENALI_PI_01_DATA */
+			0x000002ec,	/* DENALI_PI_02_DATA */
+			0x00000176,	/* DENALI_PI_03_DATA */
+			0x000030a0,	/* DENALI_PI_04_DATA */
+			0x00001850,	/* DENALI_PI_05_DATA */
+			0x00001840,	/* DENALI_PI_06_DATA */
+			0x01760c20,	/* DENALI_PI_07_DATA */
+			0x00000200,	/* DENALI_PI_08_DATA */
+			0x00000200,	/* DENALI_PI_09_DATA */
+			0x00000200,	/* DENALI_PI_10_DATA */
+			0x00000200,	/* DENALI_PI_11_DATA */
+			0x00001850,	/* DENALI_PI_12_DATA */
+			0x00000200,	/* DENALI_PI_13_DATA */
+			0x00000200,	/* DENALI_PI_14_DATA */
+			0x00000200,	/* DENALI_PI_15_DATA */
+			0x00000200,	/* DENALI_PI_16_DATA */
+			0x00000c20,	/* DENALI_PI_17_DATA */
+			0x00000200,	/* DENALI_PI_18_DATA */
+			0x00000200,	/* DENALI_PI_19_DATA */
+			0x00000200,	/* DENALI_PI_20_DATA */
+			0x00000200,	/* DENALI_PI_21_DATA */
+			0x00010000,	/* DENALI_PI_22_DATA */
+			0x00000007,	/* DENALI_PI_23_DATA */
+			0x01000001,	/* DENALI_PI_24_DATA */
+			0x00000000,	/* DENALI_PI_25_DATA */
+			0x3fffffff,	/* DENALI_PI_26_DATA */
+			0x00000000,	/* DENALI_PI_27_DATA */
+			0x00000000,	/* DENALI_PI_28_DATA */
+			0x00000000,	/* DENALI_PI_29_DATA */
+			0x00000000,	/* DENALI_PI_30_DATA */
+			0x00000000,	/* DENALI_PI_31_DATA */
+			0x00000000,	/* DENALI_PI_32_DATA */
+			0x00000000,	/* DENALI_PI_33_DATA */
+			0x00000000,	/* DENALI_PI_34_DATA */
+			0x00000000,	/* DENALI_PI_35_DATA */
+			0x00000000,	/* DENALI_PI_36_DATA */
+			0x00000000,	/* DENALI_PI_37_DATA */
+			0x00000000,	/* DENALI_PI_38_DATA */
+			0x00000000,	/* DENALI_PI_39_DATA */
+			0x00000000,	/* DENALI_PI_40_DATA */
+			0x0f000101,	/* DENALI_PI_41_DATA */
+			0x082b3223,	/* DENALI_PI_42_DATA */
+			0x080c0004,	/* DENALI_PI_43_DATA */
+			0x00061c00,	/* DENALI_PI_44_DATA */
+			0x00000214,	/* DENALI_PI_45_DATA */
+			0x00bb0007,	/* DENALI_PI_46_DATA */
+			0x0c280068,	/* DENALI_PI_47_DATA */
+			0x06100034,	/* DENALI_PI_48_DATA */
+			0x00000500,	/* DENALI_PI_49_DATA */
+			0x00000000,	/* DENALI_PI_50_DATA */
+			0x00000000,	/* DENALI_PI_51_DATA */
+			0x00000000,	/* DENALI_PI_52_DATA */
+			0x00000000,	/* DENALI_PI_53_DATA */
+			0x00000000,	/* DENALI_PI_54_DATA */
+			0x00000000,	/* DENALI_PI_55_DATA */
+			0x00000000,	/* DENALI_PI_56_DATA */
+			0x00000000,	/* DENALI_PI_57_DATA */
+			0x04040100,	/* DENALI_PI_58_DATA */
+			0x0a000004,	/* DENALI_PI_59_DATA */
+			0x00000128,	/* DENALI_PI_60_DATA */
+			0x00000000,	/* DENALI_PI_61_DATA */
+			0x0003000f,	/* DENALI_PI_62_DATA */
+			0x00000018,	/* DENALI_PI_63_DATA */
+			0x00000000,	/* DENALI_PI_64_DATA */
+			0x00000000,	/* DENALI_PI_65_DATA */
+			0x00060002,	/* DENALI_PI_66_DATA */
+			0x00010001,	/* DENALI_PI_67_DATA */
+			0x00000101,	/* DENALI_PI_68_DATA */
+			0x00020001,	/* DENALI_PI_69_DATA */
+			0x00080004,	/* DENALI_PI_70_DATA */
+			0x00000000,	/* DENALI_PI_71_DATA */
+			0x05030000,	/* DENALI_PI_72_DATA */
+			0x070a0404,	/* DENALI_PI_73_DATA */
+			0x00000000,	/* DENALI_PI_74_DATA */
+			0x00000000,	/* DENALI_PI_75_DATA */
+			0x00000000,	/* DENALI_PI_76_DATA */
+			0x000f0f00,	/* DENALI_PI_77_DATA */
+			0x0000001e,	/* DENALI_PI_78_DATA */
+			0x00000000,	/* DENALI_PI_79_DATA */
+			0x01010300,	/* DENALI_PI_80_DATA */
+			0x00000000,	/* DENALI_PI_81_DATA */
+			0x00000000,	/* DENALI_PI_82_DATA */
+			0x01000000,	/* DENALI_PI_83_DATA */
+			0x00000101,	/* DENALI_PI_84_DATA */
+			0x55555a5a,	/* DENALI_PI_85_DATA */
+			0x55555a5a,	/* DENALI_PI_86_DATA */
+			0x55555a5a,	/* DENALI_PI_87_DATA */
+			0x55555a5a,	/* DENALI_PI_88_DATA */
+			0x0c050001,	/* DENALI_PI_89_DATA */
+			0x06020009,	/* DENALI_PI_90_DATA */
+			0x00010004,	/* DENALI_PI_91_DATA */
+			0x00000203,	/* DENALI_PI_92_DATA */
+			0x00030000,	/* DENALI_PI_93_DATA */
+			0x170f0000,	/* DENALI_PI_94_DATA */
+			0x00060018,	/* DENALI_PI_95_DATA */
+			0x000e0020,	/* DENALI_PI_96_DATA */
+			0x000a001c,	/* DENALI_PI_97_DATA */
+			0x00000000,	/* DENALI_PI_98_DATA */
+			0x00000000,	/* DENALI_PI_99_DATA */
+			0x00000100,	/* DENALI_PI_100_DATA */
+			0x140a0000,	/* DENALI_PI_101_DATA */
+			0x000d010a,	/* DENALI_PI_102_DATA */
+			0x0100c802,	/* DENALI_PI_103_DATA */
+			0x010a0064,	/* DENALI_PI_104_DATA */
+			0x000e0100,	/* DENALI_PI_105_DATA */
+			0x0100000e,	/* DENALI_PI_106_DATA */
+			0x00c900c9,	/* DENALI_PI_107_DATA */
+			0x00650100,	/* DENALI_PI_108_DATA */
+			0x1e1a0065,	/* DENALI_PI_109_DATA */
+			0x10010204,	/* DENALI_PI_110_DATA */
+			0x06070605,	/* DENALI_PI_111_DATA */
+			0x20000202,	/* DENALI_PI_112_DATA */
+			0x00201000,	/* DENALI_PI_113_DATA */
+			0x00201000,	/* DENALI_PI_114_DATA */
+			0x04041000,	/* DENALI_PI_115_DATA */
+			0x10020100,	/* DENALI_PI_116_DATA */
+			0x0003010c,	/* DENALI_PI_117_DATA */
+			0x004b004a,	/* DENALI_PI_118_DATA */
+			0x1a0f0000,	/* DENALI_PI_119_DATA */
+			0x0102041e,	/* DENALI_PI_120_DATA */
+			0x34000000,	/* DENALI_PI_121_DATA */
+			0x00000000,	/* DENALI_PI_122_DATA */
+			0x00000000,	/* DENALI_PI_123_DATA */
+			0x00010000,	/* DENALI_PI_124_DATA */
+			0x00000400,	/* DENALI_PI_125_DATA */
+			0x00310000,	/* DENALI_PI_126_DATA */
+			0x004d4d00,	/* DENALI_PI_127_DATA */
+			0x00120024,	/* DENALI_PI_128_DATA */
+			0x4d000031,	/* DENALI_PI_129_DATA */
+			0x0000144d,	/* DENALI_PI_130_DATA */
+			0x00310009,	/* DENALI_PI_131_DATA */
+			0x004d4d00,	/* DENALI_PI_132_DATA */
+			0x00000004,	/* DENALI_PI_133_DATA */
+			0x4d000031,	/* DENALI_PI_134_DATA */
+			0x0000244d,	/* DENALI_PI_135_DATA */
+			0x00310012,	/* DENALI_PI_136_DATA */
+			0x004d4d00,	/* DENALI_PI_137_DATA */
+			0x00090014,	/* DENALI_PI_138_DATA */
+			0x4d000031,	/* DENALI_PI_139_DATA */
+			0x0004004d,	/* DENALI_PI_140_DATA */
+			0x00310000,	/* DENALI_PI_141_DATA */
+			0x004d4d00,	/* DENALI_PI_142_DATA */
+			0x00120024,	/* DENALI_PI_143_DATA */
+			0x4d000031,	/* DENALI_PI_144_DATA */
+			0x0000144d,	/* DENALI_PI_145_DATA */
+			0x00310009,	/* DENALI_PI_146_DATA */
+			0x004d4d00,	/* DENALI_PI_147_DATA */
+			0x00000004,	/* DENALI_PI_148_DATA */
+			0x4d000031,	/* DENALI_PI_149_DATA */
+			0x0000244d,	/* DENALI_PI_150_DATA */
+			0x00310012,	/* DENALI_PI_151_DATA */
+			0x004d4d00,	/* DENALI_PI_152_DATA */
+			0x00090014,	/* DENALI_PI_153_DATA */
+			0x4d000031,	/* DENALI_PI_154_DATA */
+			0x0200004d,	/* DENALI_PI_155_DATA */
+			0x00c8000d,	/* DENALI_PI_156_DATA */
+			0x08080064,	/* DENALI_PI_157_DATA */
+			0x040a0404,	/* DENALI_PI_158_DATA */
+			0x03000d92,	/* DENALI_PI_159_DATA */
+			0x010a2001,	/* DENALI_PI_160_DATA */
+			0x0f11080a,	/* DENALI_PI_161_DATA */
+			0x0000110a,	/* DENALI_PI_162_DATA */
+			0x2200d92e,	/* DENALI_PI_163_DATA */
+			0x080c2003,	/* DENALI_PI_164_DATA */
+			0x0809080a,	/* DENALI_PI_165_DATA */
+			0x00000a0a,	/* DENALI_PI_166_DATA */
+			0x11006c97,	/* DENALI_PI_167_DATA */
+			0x040a2002,	/* DENALI_PI_168_DATA */
+			0x0200020a,	/* DENALI_PI_169_DATA */
+			0x02000200,	/* DENALI_PI_170_DATA */
+			0x02000200,	/* DENALI_PI_171_DATA */
+			0x02000200,	/* DENALI_PI_172_DATA */
+			0x02000200,	/* DENALI_PI_173_DATA */
+			0x00000000,	/* DENALI_PI_174_DATA */
+			0x00000000,	/* DENALI_PI_175_DATA */
+			0x00000000,	/* DENALI_PI_176_DATA */
+			0x00000000,	/* DENALI_PI_177_DATA */
+			0x00000000,	/* DENALI_PI_178_DATA */
+			0x00000000,	/* DENALI_PI_179_DATA */
+			0x00000000,	/* DENALI_PI_180_DATA */
+			0x00000000,	/* DENALI_PI_181_DATA */
+			0x00000000,	/* DENALI_PI_182_DATA */
+			0x00000000,	/* DENALI_PI_183_DATA */
+			0x00000000,	/* DENALI_PI_184_DATA */
+			0x00000000,	/* DENALI_PI_185_DATA */
+			0x01000400,	/* DENALI_PI_186_DATA */
+			0x00017600,	/* DENALI_PI_187_DATA */
+			0x00000e9c,	/* DENALI_PI_188_DATA */
+			0x00001850,	/* DENALI_PI_189_DATA */
+			0x0000f320,	/* DENALI_PI_190_DATA */
+			0x00000c20,	/* DENALI_PI_191_DATA */
+			0x00007940,	/* DENALI_PI_192_DATA */
+			0x08000000,	/* DENALI_PI_193_DATA */
+			0x00000100,	/* DENALI_PI_194_DATA */
+			0x00000000,	/* DENALI_PI_195_DATA */
+			0x00000000,	/* DENALI_PI_196_DATA */
+			0x00000000,	/* DENALI_PI_197_DATA */
+			0x00000000,	/* DENALI_PI_198_DATA */
+			0x00000002	/* DENALI_PI_199_DATA */
+		}
+	},
+	{
+		{
+			0x76543210,	/* DENALI_PHY_00_DATA */
+			0x0004f008,	/* DENALI_PHY_01_DATA */
+			0x00020119,	/* DENALI_PHY_02_DATA */
+			0x00000000,	/* DENALI_PHY_03_DATA */
+			0x00000000,	/* DENALI_PHY_04_DATA */
+			0x00010000,	/* DENALI_PHY_05_DATA */
+			0x01665555,	/* DENALI_PHY_06_DATA */
+			0x03665555,	/* DENALI_PHY_07_DATA */
+			0x00010f00,	/* DENALI_PHY_08_DATA */
+			0x04000100,	/* DENALI_PHY_09_DATA */
+			0x00000001,	/* DENALI_PHY_10_DATA */
+			0x00170180,	/* DENALI_PHY_11_DATA */
+			0x00cc0201,	/* DENALI_PHY_12_DATA */
+			0x00030066,	/* DENALI_PHY_13_DATA */
+			0x00000000,	/* DENALI_PHY_14_DATA */
+			0x00000000,	/* DENALI_PHY_15_DATA */
+			0x00000000,	/* DENALI_PHY_16_DATA */
+			0x00000000,	/* DENALI_PHY_17_DATA */
+			0x00000000,	/* DENALI_PHY_18_DATA */
+			0x00000000,	/* DENALI_PHY_19_DATA */
+			0x00000000,	/* DENALI_PHY_20_DATA */
+			0x00000000,	/* DENALI_PHY_21_DATA */
+			0x04080000,	/* DENALI_PHY_22_DATA */
+			0x04080400,	/* DENALI_PHY_23_DATA */
+			0x30000000,	/* DENALI_PHY_24_DATA */
+			0x0c00c007,	/* DENALI_PHY_25_DATA */
+			0x00000100,	/* DENALI_PHY_26_DATA */
+			0x00000000,	/* DENALI_PHY_27_DATA */
+			0xfd02fe01,	/* DENALI_PHY_28_DATA */
+			0xf708fb04,	/* DENALI_PHY_29_DATA */
+			0xdf20ef10,	/* DENALI_PHY_30_DATA */
+			0x7f80bf40,	/* DENALI_PHY_31_DATA */
+			0x0001aaaa,	/* DENALI_PHY_32_DATA */
+			0x00000000,	/* DENALI_PHY_33_DATA */
+			0x00000000,	/* DENALI_PHY_34_DATA */
+			0x00000000,	/* DENALI_PHY_35_DATA */
+			0x00000000,	/* DENALI_PHY_36_DATA */
+			0x00000000,	/* DENALI_PHY_37_DATA */
+			0x00000000,	/* DENALI_PHY_38_DATA */
+			0x00000000,	/* DENALI_PHY_39_DATA */
+			0x00000000,	/* DENALI_PHY_40_DATA */
+			0x00000000,	/* DENALI_PHY_41_DATA */
+			0x00000000,	/* DENALI_PHY_42_DATA */
+			0x00000000,	/* DENALI_PHY_43_DATA */
+			0x00000000,	/* DENALI_PHY_44_DATA */
+			0x00000000,	/* DENALI_PHY_45_DATA */
+			0x00000000,	/* DENALI_PHY_46_DATA */
+			0x00000000,	/* DENALI_PHY_47_DATA */
+			0x00000000,	/* DENALI_PHY_48_DATA */
+			0x00000000,	/* DENALI_PHY_49_DATA */
+			0x00000000,	/* DENALI_PHY_50_DATA */
+			0x00000000,	/* DENALI_PHY_51_DATA */
+			0x00200000,	/* DENALI_PHY_52_DATA */
+			0x00000000,	/* DENALI_PHY_53_DATA */
+			0x00000000,	/* DENALI_PHY_54_DATA */
+			0x00000000,	/* DENALI_PHY_55_DATA */
+			0x00000000,	/* DENALI_PHY_56_DATA */
+			0x00000000,	/* DENALI_PHY_57_DATA */
+			0x00000000,	/* DENALI_PHY_58_DATA */
+			0x02800280,	/* DENALI_PHY_59_DATA */
+			0x02800280,	/* DENALI_PHY_60_DATA */
+			0x02800280,	/* DENALI_PHY_61_DATA */
+			0x02800280,	/* DENALI_PHY_62_DATA */
+			0x00000280,	/* DENALI_PHY_63_DATA */
+			0x00000000,	/* DENALI_PHY_64_DATA */
+			0x00000000,	/* DENALI_PHY_65_DATA */
+			0x00000000,	/* DENALI_PHY_66_DATA */
+			0x00000000,	/* DENALI_PHY_67_DATA */
+			0x00800000,	/* DENALI_PHY_68_DATA */
+			0x00800080,	/* DENALI_PHY_69_DATA */
+			0x00800080,	/* DENALI_PHY_70_DATA */
+			0x00800080,	/* DENALI_PHY_71_DATA */
+			0x00800080,	/* DENALI_PHY_72_DATA */
+			0x00800080,	/* DENALI_PHY_73_DATA */
+			0x00800080,	/* DENALI_PHY_74_DATA */
+			0x00800080,	/* DENALI_PHY_75_DATA */
+			0x00800080,	/* DENALI_PHY_76_DATA */
+			0x01190080,	/* DENALI_PHY_77_DATA */
+			0x00000001,	/* DENALI_PHY_78_DATA */
+			0x00000000,	/* DENALI_PHY_79_DATA */
+			0x00000000,	/* DENALI_PHY_80_DATA */
+			0x00000200,	/* DENALI_PHY_81_DATA */
+			0x00000000,	/* DENALI_PHY_82_DATA */
+			0x51315152,	/* DENALI_PHY_83_DATA */
+			0xc0003150,	/* DENALI_PHY_84_DATA */
+			0x010000c0,	/* DENALI_PHY_85_DATA */
+			0x00100000,	/* DENALI_PHY_86_DATA */
+			0x07044204,	/* DENALI_PHY_87_DATA */
+			0x000f0c18,	/* DENALI_PHY_88_DATA */
+			0x01000140,	/* DENALI_PHY_89_DATA */
+			0x00000c10,	/* DENALI_PHY_90_DATA */
+			0x00000000,	/* DENALI_PHY_91_DATA */
+			0x00000000,	/* DENALI_PHY_92_DATA */
+			0x00000000,	/* DENALI_PHY_93_DATA */
+			0x00000000,	/* DENALI_PHY_94_DATA */
+			0x00000000,	/* DENALI_PHY_95_DATA */
+			0x00000000,	/* DENALI_PHY_96_DATA */
+			0x00000000,	/* DENALI_PHY_97_DATA */
+			0x00000000,	/* DENALI_PHY_98_DATA */
+			0x00000000,	/* DENALI_PHY_99_DATA */
+			0x00000000,	/* DENALI_PHY_100_DATA */
+			0x00000000,	/* DENALI_PHY_101_DATA */
+			0x00000000,	/* DENALI_PHY_102_DATA */
+			0x00000000,	/* DENALI_PHY_103_DATA */
+			0x00000000,	/* DENALI_PHY_104_DATA */
+			0x00000000,	/* DENALI_PHY_105_DATA */
+			0x00000000,	/* DENALI_PHY_106_DATA */
+			0x00000000,	/* DENALI_PHY_107_DATA */
+			0x00000000,	/* DENALI_PHY_108_DATA */
+			0x00000000,	/* DENALI_PHY_109_DATA */
+			0x00000000,	/* DENALI_PHY_110_DATA */
+			0x00000000,	/* DENALI_PHY_111_DATA */
+			0x00000000,	/* DENALI_PHY_112_DATA */
+			0x00000000,	/* DENALI_PHY_113_DATA */
+			0x00000000,	/* DENALI_PHY_114_DATA */
+			0x00000000,	/* DENALI_PHY_115_DATA */
+			0x00000000,	/* DENALI_PHY_116_DATA */
+			0x00000000,	/* DENALI_PHY_117_DATA */
+			0x00000000,	/* DENALI_PHY_118_DATA */
+			0x00000000,	/* DENALI_PHY_119_DATA */
+			0x00000000,	/* DENALI_PHY_120_DATA */
+			0x00000000,	/* DENALI_PHY_121_DATA */
+			0x00000000,	/* DENALI_PHY_122_DATA */
+			0x00000000,	/* DENALI_PHY_123_DATA */
+			0x00000000,	/* DENALI_PHY_124_DATA */
+			0x00000000,	/* DENALI_PHY_125_DATA */
+			0x00000000,	/* DENALI_PHY_126_DATA */
+			0x00000000,	/* DENALI_PHY_127_DATA */
+			0x76543210,	/* DENALI_PHY_128_DATA */
+			0x0004f008,	/* DENALI_PHY_129_DATA */
+			0x00020119,	/* DENALI_PHY_130_DATA */
+			0x00000000,	/* DENALI_PHY_131_DATA */
+			0x00000000,	/* DENALI_PHY_132_DATA */
+			0x00010000,	/* DENALI_PHY_133_DATA */
+			0x01665555,	/* DENALI_PHY_134_DATA */
+			0x03665555,	/* DENALI_PHY_135_DATA */
+			0x00010f00,	/* DENALI_PHY_136_DATA */
+			0x04000100,	/* DENALI_PHY_137_DATA */
+			0x00000001,	/* DENALI_PHY_138_DATA */
+			0x00170180,	/* DENALI_PHY_139_DATA */
+			0x00cc0201,	/* DENALI_PHY_140_DATA */
+			0x00030066,	/* DENALI_PHY_141_DATA */
+			0x00000000,	/* DENALI_PHY_142_DATA */
+			0x00000000,	/* DENALI_PHY_143_DATA */
+			0x00000000,	/* DENALI_PHY_144_DATA */
+			0x00000000,	/* DENALI_PHY_145_DATA */
+			0x00000000,	/* DENALI_PHY_146_DATA */
+			0x00000000,	/* DENALI_PHY_147_DATA */
+			0x00000000,	/* DENALI_PHY_148_DATA */
+			0x00000000,	/* DENALI_PHY_149_DATA */
+			0x04080000,	/* DENALI_PHY_150_DATA */
+			0x04080400,	/* DENALI_PHY_151_DATA */
+			0x30000000,	/* DENALI_PHY_152_DATA */
+			0x0c00c007,	/* DENALI_PHY_153_DATA */
+			0x00000100,	/* DENALI_PHY_154_DATA */
+			0x00000000,	/* DENALI_PHY_155_DATA */
+			0xfd02fe01,	/* DENALI_PHY_156_DATA */
+			0xf708fb04,	/* DENALI_PHY_157_DATA */
+			0xdf20ef10,	/* DENALI_PHY_158_DATA */
+			0x7f80bf40,	/* DENALI_PHY_159_DATA */
+			0x0000aaaa,	/* DENALI_PHY_160_DATA */
+			0x00000000,	/* DENALI_PHY_161_DATA */
+			0x00000000,	/* DENALI_PHY_162_DATA */
+			0x00000000,	/* DENALI_PHY_163_DATA */
+			0x00000000,	/* DENALI_PHY_164_DATA */
+			0x00000000,	/* DENALI_PHY_165_DATA */
+			0x00000000,	/* DENALI_PHY_166_DATA */
+			0x00000000,	/* DENALI_PHY_167_DATA */
+			0x00000000,	/* DENALI_PHY_168_DATA */
+			0x00000000,	/* DENALI_PHY_169_DATA */
+			0x00000000,	/* DENALI_PHY_170_DATA */
+			0x00000000,	/* DENALI_PHY_171_DATA */
+			0x00000000,	/* DENALI_PHY_172_DATA */
+			0x00000000,	/* DENALI_PHY_173_DATA */
+			0x00000000,	/* DENALI_PHY_174_DATA */
+			0x00000000,	/* DENALI_PHY_175_DATA */
+			0x00000000,	/* DENALI_PHY_176_DATA */
+			0x00000000,	/* DENALI_PHY_177_DATA */
+			0x00000000,	/* DENALI_PHY_178_DATA */
+			0x00000000,	/* DENALI_PHY_179_DATA */
+			0x00200000,	/* DENALI_PHY_180_DATA */
+			0x00000000,	/* DENALI_PHY_181_DATA */
+			0x00000000,	/* DENALI_PHY_182_DATA */
+			0x00000000,	/* DENALI_PHY_183_DATA */
+			0x00000000,	/* DENALI_PHY_184_DATA */
+			0x00000000,	/* DENALI_PHY_185_DATA */
+			0x00000000,	/* DENALI_PHY_186_DATA */
+			0x02800280,	/* DENALI_PHY_187_DATA */
+			0x02800280,	/* DENALI_PHY_188_DATA */
+			0x02800280,	/* DENALI_PHY_189_DATA */
+			0x02800280,	/* DENALI_PHY_190_DATA */
+			0x00000280,	/* DENALI_PHY_191_DATA */
+			0x00000000,	/* DENALI_PHY_192_DATA */
+			0x00000000,	/* DENALI_PHY_193_DATA */
+			0x00000000,	/* DENALI_PHY_194_DATA */
+			0x00000000,	/* DENALI_PHY_195_DATA */
+			0x00800000,	/* DENALI_PHY_196_DATA */
+			0x00800080,	/* DENALI_PHY_197_DATA */
+			0x00800080,	/* DENALI_PHY_198_DATA */
+			0x00800080,	/* DENALI_PHY_199_DATA */
+			0x00800080,	/* DENALI_PHY_200_DATA */
+			0x00800080,	/* DENALI_PHY_201_DATA */
+			0x00800080,	/* DENALI_PHY_202_DATA */
+			0x00800080,	/* DENALI_PHY_203_DATA */
+			0x00800080,	/* DENALI_PHY_204_DATA */
+			0x01190080,	/* DENALI_PHY_205_DATA */
+			0x00000001,	/* DENALI_PHY_206_DATA */
+			0x00000000,	/* DENALI_PHY_207_DATA */
+			0x00000000,	/* DENALI_PHY_208_DATA */
+			0x00000200,	/* DENALI_PHY_209_DATA */
+			0x00000000,	/* DENALI_PHY_210_DATA */
+			0x51315152,	/* DENALI_PHY_211_DATA */
+			0xc0003150,	/* DENALI_PHY_212_DATA */
+			0x010000c0,	/* DENALI_PHY_213_DATA */
+			0x00100000,	/* DENALI_PHY_214_DATA */
+			0x07044204,	/* DENALI_PHY_215_DATA */
+			0x000f0c18,	/* DENALI_PHY_216_DATA */
+			0x01000140,	/* DENALI_PHY_217_DATA */
+			0x00000c10,	/* DENALI_PHY_218_DATA */
+			0x00000000,	/* DENALI_PHY_219_DATA */
+			0x00000000,	/* DENALI_PHY_220_DATA */
+			0x00000000,	/* DENALI_PHY_221_DATA */
+			0x00000000,	/* DENALI_PHY_222_DATA */
+			0x00000000,	/* DENALI_PHY_223_DATA */
+			0x00000000,	/* DENALI_PHY_224_DATA */
+			0x00000000,	/* DENALI_PHY_225_DATA */
+			0x00000000,	/* DENALI_PHY_226_DATA */
+			0x00000000,	/* DENALI_PHY_227_DATA */
+			0x00000000,	/* DENALI_PHY_228_DATA */
+			0x00000000,	/* DENALI_PHY_229_DATA */
+			0x00000000,	/* DENALI_PHY_230_DATA */
+			0x00000000,	/* DENALI_PHY_231_DATA */
+			0x00000000,	/* DENALI_PHY_232_DATA */
+			0x00000000,	/* DENALI_PHY_233_DATA */
+			0x00000000,	/* DENALI_PHY_234_DATA */
+			0x00000000,	/* DENALI_PHY_235_DATA */
+			0x00000000,	/* DENALI_PHY_236_DATA */
+			0x00000000,	/* DENALI_PHY_237_DATA */
+			0x00000000,	/* DENALI_PHY_238_DATA */
+			0x00000000,	/* DENALI_PHY_239_DATA */
+			0x00000000,	/* DENALI_PHY_240_DATA */
+			0x00000000,	/* DENALI_PHY_241_DATA */
+			0x00000000,	/* DENALI_PHY_242_DATA */
+			0x00000000,	/* DENALI_PHY_243_DATA */
+			0x00000000,	/* DENALI_PHY_244_DATA */
+			0x00000000,	/* DENALI_PHY_245_DATA */
+			0x00000000,	/* DENALI_PHY_246_DATA */
+			0x00000000,	/* DENALI_PHY_247_DATA */
+			0x00000000,	/* DENALI_PHY_248_DATA */
+			0x00000000,	/* DENALI_PHY_249_DATA */
+			0x00000000,	/* DENALI_PHY_250_DATA */
+			0x00000000,	/* DENALI_PHY_251_DATA */
+			0x00000000,	/* DENALI_PHY_252_DATA */
+			0x00000000,	/* DENALI_PHY_253_DATA */
+			0x00000000,	/* DENALI_PHY_254_DATA */
+			0x00000000,	/* DENALI_PHY_255_DATA */
+			0x76543210,	/* DENALI_PHY_256_DATA */
+			0x0004f008,	/* DENALI_PHY_257_DATA */
+			0x00020119,	/* DENALI_PHY_258_DATA */
+			0x00000000,	/* DENALI_PHY_259_DATA */
+			0x00000000,	/* DENALI_PHY_260_DATA */
+			0x00010000,	/* DENALI_PHY_261_DATA */
+			0x01665555,	/* DENALI_PHY_262_DATA */
+			0x03665555,	/* DENALI_PHY_263_DATA */
+			0x00010f00,	/* DENALI_PHY_264_DATA */
+			0x04000100,	/* DENALI_PHY_265_DATA */
+			0x00000001,	/* DENALI_PHY_266_DATA */
+			0x00170180,	/* DENALI_PHY_267_DATA */
+			0x00cc0201,	/* DENALI_PHY_268_DATA */
+			0x00030066,	/* DENALI_PHY_269_DATA */
+			0x00000000,	/* DENALI_PHY_270_DATA */
+			0x00000000,	/* DENALI_PHY_271_DATA */
+			0x00000000,	/* DENALI_PHY_272_DATA */
+			0x00000000,	/* DENALI_PHY_273_DATA */
+			0x00000000,	/* DENALI_PHY_274_DATA */
+			0x00000000,	/* DENALI_PHY_275_DATA */
+			0x00000000,	/* DENALI_PHY_276_DATA */
+			0x00000000,	/* DENALI_PHY_277_DATA */
+			0x04080000,	/* DENALI_PHY_278_DATA */
+			0x04080400,	/* DENALI_PHY_279_DATA */
+			0x30000000,	/* DENALI_PHY_280_DATA */
+			0x0c00c007,	/* DENALI_PHY_281_DATA */
+			0x00000100,	/* DENALI_PHY_282_DATA */
+			0x00000000,	/* DENALI_PHY_283_DATA */
+			0xfd02fe01,	/* DENALI_PHY_284_DATA */
+			0xf708fb04,	/* DENALI_PHY_285_DATA */
+			0xdf20ef10,	/* DENALI_PHY_286_DATA */
+			0x7f80bf40,	/* DENALI_PHY_287_DATA */
+			0x0001aaaa,	/* DENALI_PHY_288_DATA */
+			0x00000000,	/* DENALI_PHY_289_DATA */
+			0x00000000,	/* DENALI_PHY_290_DATA */
+			0x00000000,	/* DENALI_PHY_291_DATA */
+			0x00000000,	/* DENALI_PHY_292_DATA */
+			0x00000000,	/* DENALI_PHY_293_DATA */
+			0x00000000,	/* DENALI_PHY_294_DATA */
+			0x00000000,	/* DENALI_PHY_295_DATA */
+			0x00000000,	/* DENALI_PHY_296_DATA */
+			0x00000000,	/* DENALI_PHY_297_DATA */
+			0x00000000,	/* DENALI_PHY_298_DATA */
+			0x00000000,	/* DENALI_PHY_299_DATA */
+			0x00000000,	/* DENALI_PHY_300_DATA */
+			0x00000000,	/* DENALI_PHY_301_DATA */
+			0x00000000,	/* DENALI_PHY_302_DATA */
+			0x00000000,	/* DENALI_PHY_303_DATA */
+			0x00000000,	/* DENALI_PHY_304_DATA */
+			0x00000000,	/* DENALI_PHY_305_DATA */
+			0x00000000,	/* DENALI_PHY_306_DATA */
+			0x00000000,	/* DENALI_PHY_307_DATA */
+			0x00200000,	/* DENALI_PHY_308_DATA */
+			0x00000000,	/* DENALI_PHY_309_DATA */
+			0x00000000,	/* DENALI_PHY_310_DATA */
+			0x00000000,	/* DENALI_PHY_311_DATA */
+			0x00000000,	/* DENALI_PHY_312_DATA */
+			0x00000000,	/* DENALI_PHY_313_DATA */
+			0x00000000,	/* DENALI_PHY_314_DATA */
+			0x02800280,	/* DENALI_PHY_315_DATA */
+			0x02800280,	/* DENALI_PHY_316_DATA */
+			0x02800280,	/* DENALI_PHY_317_DATA */
+			0x02800280,	/* DENALI_PHY_318_DATA */
+			0x00000280,	/* DENALI_PHY_319_DATA */
+			0x00000000,	/* DENALI_PHY_320_DATA */
+			0x00000000,	/* DENALI_PHY_321_DATA */
+			0x00000000,	/* DENALI_PHY_322_DATA */
+			0x00000000,	/* DENALI_PHY_323_DATA */
+			0x00800000,	/* DENALI_PHY_324_DATA */
+			0x00800080,	/* DENALI_PHY_325_DATA */
+			0x00800080,	/* DENALI_PHY_326_DATA */
+			0x00800080,	/* DENALI_PHY_327_DATA */
+			0x00800080,	/* DENALI_PHY_328_DATA */
+			0x00800080,	/* DENALI_PHY_329_DATA */
+			0x00800080,	/* DENALI_PHY_330_DATA */
+			0x00800080,	/* DENALI_PHY_331_DATA */
+			0x00800080,	/* DENALI_PHY_332_DATA */
+			0x01190080,	/* DENALI_PHY_333_DATA */
+			0x00000001,	/* DENALI_PHY_334_DATA */
+			0x00000000,	/* DENALI_PHY_335_DATA */
+			0x00000000,	/* DENALI_PHY_336_DATA */
+			0x00000200,	/* DENALI_PHY_337_DATA */
+			0x00000000,	/* DENALI_PHY_338_DATA */
+			0x51315152,	/* DENALI_PHY_339_DATA */
+			0xc0003150,	/* DENALI_PHY_340_DATA */
+			0x010000c0,	/* DENALI_PHY_341_DATA */
+			0x00100000,	/* DENALI_PHY_342_DATA */
+			0x07044204,	/* DENALI_PHY_343_DATA */
+			0x000f0c18,	/* DENALI_PHY_344_DATA */
+			0x01000140,	/* DENALI_PHY_345_DATA */
+			0x00000c10,	/* DENALI_PHY_346_DATA */
+			0x00000000,	/* DENALI_PHY_347_DATA */
+			0x00000000,	/* DENALI_PHY_348_DATA */
+			0x00000000,	/* DENALI_PHY_349_DATA */
+			0x00000000,	/* DENALI_PHY_350_DATA */
+			0x00000000,	/* DENALI_PHY_351_DATA */
+			0x00000000,	/* DENALI_PHY_352_DATA */
+			0x00000000,	/* DENALI_PHY_353_DATA */
+			0x00000000,	/* DENALI_PHY_354_DATA */
+			0x00000000,	/* DENALI_PHY_355_DATA */
+			0x00000000,	/* DENALI_PHY_356_DATA */
+			0x00000000,	/* DENALI_PHY_357_DATA */
+			0x00000000,	/* DENALI_PHY_358_DATA */
+			0x00000000,	/* DENALI_PHY_359_DATA */
+			0x00000000,	/* DENALI_PHY_360_DATA */
+			0x00000000,	/* DENALI_PHY_361_DATA */
+			0x00000000,	/* DENALI_PHY_362_DATA */
+			0x00000000,	/* DENALI_PHY_363_DATA */
+			0x00000000,	/* DENALI_PHY_364_DATA */
+			0x00000000,	/* DENALI_PHY_365_DATA */
+			0x00000000,	/* DENALI_PHY_366_DATA */
+			0x00000000,	/* DENALI_PHY_367_DATA */
+			0x00000000,	/* DENALI_PHY_368_DATA */
+			0x00000000,	/* DENALI_PHY_369_DATA */
+			0x00000000,	/* DENALI_PHY_370_DATA */
+			0x00000000,	/* DENALI_PHY_371_DATA */
+			0x00000000,	/* DENALI_PHY_372_DATA */
+			0x00000000,	/* DENALI_PHY_373_DATA */
+			0x00000000,	/* DENALI_PHY_374_DATA */
+			0x00000000,	/* DENALI_PHY_375_DATA */
+			0x00000000,	/* DENALI_PHY_376_DATA */
+			0x00000000,	/* DENALI_PHY_377_DATA */
+			0x00000000,	/* DENALI_PHY_378_DATA */
+			0x00000000,	/* DENALI_PHY_379_DATA */
+			0x00000000,	/* DENALI_PHY_380_DATA */
+			0x00000000,	/* DENALI_PHY_381_DATA */
+			0x00000000,	/* DENALI_PHY_382_DATA */
+			0x00000000,	/* DENALI_PHY_383_DATA */
+			0x76543210,	/* DENALI_PHY_384_DATA */
+			0x0004f008,	/* DENALI_PHY_385_DATA */
+			0x00020119,	/* DENALI_PHY_386_DATA */
+			0x00000000,	/* DENALI_PHY_387_DATA */
+			0x00000000,	/* DENALI_PHY_388_DATA */
+			0x00010000,	/* DENALI_PHY_389_DATA */
+			0x01665555,	/* DENALI_PHY_390_DATA */
+			0x03665555,	/* DENALI_PHY_391_DATA */
+			0x00010f00,	/* DENALI_PHY_392_DATA */
+			0x04000100,	/* DENALI_PHY_393_DATA */
+			0x00000001,	/* DENALI_PHY_394_DATA */
+			0x00170180,	/* DENALI_PHY_395_DATA */
+			0x00cc0201,	/* DENALI_PHY_396_DATA */
+			0x00030066,	/* DENALI_PHY_397_DATA */
+			0x00000000,	/* DENALI_PHY_398_DATA */
+			0x00000000,	/* DENALI_PHY_399_DATA */
+			0x00000000,	/* DENALI_PHY_400_DATA */
+			0x00000000,	/* DENALI_PHY_401_DATA */
+			0x00000000,	/* DENALI_PHY_402_DATA */
+			0x00000000,	/* DENALI_PHY_403_DATA */
+			0x00000000,	/* DENALI_PHY_404_DATA */
+			0x00000000,	/* DENALI_PHY_405_DATA */
+			0x04080000,	/* DENALI_PHY_406_DATA */
+			0x04080400,	/* DENALI_PHY_407_DATA */
+			0x30000000,	/* DENALI_PHY_408_DATA */
+			0x0c00c007,	/* DENALI_PHY_409_DATA */
+			0x00000100,	/* DENALI_PHY_410_DATA */
+			0x00000000,	/* DENALI_PHY_411_DATA */
+			0xfd02fe01,	/* DENALI_PHY_412_DATA */
+			0xf708fb04,	/* DENALI_PHY_413_DATA */
+			0xdf20ef10,	/* DENALI_PHY_414_DATA */
+			0x7f80bf40,	/* DENALI_PHY_415_DATA */
+			0x0000aaaa,	/* DENALI_PHY_416_DATA */
+			0x00000000,	/* DENALI_PHY_417_DATA */
+			0x00000000,	/* DENALI_PHY_418_DATA */
+			0x00000000,	/* DENALI_PHY_419_DATA */
+			0x00000000,	/* DENALI_PHY_420_DATA */
+			0x00000000,	/* DENALI_PHY_421_DATA */
+			0x00000000,	/* DENALI_PHY_422_DATA */
+			0x00000000,	/* DENALI_PHY_423_DATA */
+			0x00000000,	/* DENALI_PHY_424_DATA */
+			0x00000000,	/* DENALI_PHY_425_DATA */
+			0x00000000,	/* DENALI_PHY_426_DATA */
+			0x00000000,	/* DENALI_PHY_427_DATA */
+			0x00000000,	/* DENALI_PHY_428_DATA */
+			0x00000000,	/* DENALI_PHY_429_DATA */
+			0x00000000,	/* DENALI_PHY_430_DATA */
+			0x00000000,	/* DENALI_PHY_431_DATA */
+			0x00000000,	/* DENALI_PHY_432_DATA */
+			0x00000000,	/* DENALI_PHY_433_DATA */
+			0x00000000,	/* DENALI_PHY_434_DATA */
+			0x00000000,	/* DENALI_PHY_435_DATA */
+			0x00200000,	/* DENALI_PHY_436_DATA */
+			0x00000000,	/* DENALI_PHY_437_DATA */
+			0x00000000,	/* DENALI_PHY_438_DATA */
+			0x00000000,	/* DENALI_PHY_439_DATA */
+			0x00000000,	/* DENALI_PHY_440_DATA */
+			0x00000000,	/* DENALI_PHY_441_DATA */
+			0x00000000,	/* DENALI_PHY_442_DATA */
+			0x02800280,	/* DENALI_PHY_443_DATA */
+			0x02800280,	/* DENALI_PHY_444_DATA */
+			0x02800280,	/* DENALI_PHY_445_DATA */
+			0x02800280,	/* DENALI_PHY_446_DATA */
+			0x00000280,	/* DENALI_PHY_447_DATA */
+			0x00000000,	/* DENALI_PHY_448_DATA */
+			0x00000000,	/* DENALI_PHY_449_DATA */
+			0x00000000,	/* DENALI_PHY_450_DATA */
+			0x00000000,	/* DENALI_PHY_451_DATA */
+			0x00800000,	/* DENALI_PHY_452_DATA */
+			0x00800080,	/* DENALI_PHY_453_DATA */
+			0x00800080,	/* DENALI_PHY_454_DATA */
+			0x00800080,	/* DENALI_PHY_455_DATA */
+			0x00800080,	/* DENALI_PHY_456_DATA */
+			0x00800080,	/* DENALI_PHY_457_DATA */
+			0x00800080,	/* DENALI_PHY_458_DATA */
+			0x00800080,	/* DENALI_PHY_459_DATA */
+			0x00800080,	/* DENALI_PHY_460_DATA */
+			0x01190080,	/* DENALI_PHY_461_DATA */
+			0x00000001,	/* DENALI_PHY_462_DATA */
+			0x00000000,	/* DENALI_PHY_463_DATA */
+			0x00000000,	/* DENALI_PHY_464_DATA */
+			0x00000200,	/* DENALI_PHY_465_DATA */
+			0x00000000,	/* DENALI_PHY_466_DATA */
+			0x51315152,	/* DENALI_PHY_467_DATA */
+			0xc0003150,	/* DENALI_PHY_468_DATA */
+			0x010000c0,	/* DENALI_PHY_469_DATA */
+			0x00100000,	/* DENALI_PHY_470_DATA */
+			0x07044204,	/* DENALI_PHY_471_DATA */
+			0x000f0c18,	/* DENALI_PHY_472_DATA */
+			0x01000140,	/* DENALI_PHY_473_DATA */
+			0x00000c10,	/* DENALI_PHY_474_DATA */
+			0x00000000,	/* DENALI_PHY_475_DATA */
+			0x00000000,	/* DENALI_PHY_476_DATA */
+			0x00000000,	/* DENALI_PHY_477_DATA */
+			0x00000000,	/* DENALI_PHY_478_DATA */
+			0x00000000,	/* DENALI_PHY_479_DATA */
+			0x00000000,	/* DENALI_PHY_480_DATA */
+			0x00000000,	/* DENALI_PHY_481_DATA */
+			0x00000000,	/* DENALI_PHY_482_DATA */
+			0x00000000,	/* DENALI_PHY_483_DATA */
+			0x00000000,	/* DENALI_PHY_484_DATA */
+			0x00000000,	/* DENALI_PHY_485_DATA */
+			0x00000000,	/* DENALI_PHY_486_DATA */
+			0x00000000,	/* DENALI_PHY_487_DATA */
+			0x00000000,	/* DENALI_PHY_488_DATA */
+			0x00000000,	/* DENALI_PHY_489_DATA */
+			0x00000000,	/* DENALI_PHY_490_DATA */
+			0x00000000,	/* DENALI_PHY_491_DATA */
+			0x00000000,	/* DENALI_PHY_492_DATA */
+			0x00000000,	/* DENALI_PHY_493_DATA */
+			0x00000000,	/* DENALI_PHY_494_DATA */
+			0x00000000,	/* DENALI_PHY_495_DATA */
+			0x00000000,	/* DENALI_PHY_496_DATA */
+			0x00000000,	/* DENALI_PHY_497_DATA */
+			0x00000000,	/* DENALI_PHY_498_DATA */
+			0x00000000,	/* DENALI_PHY_499_DATA */
+			0x00000000,	/* DENALI_PHY_500_DATA */
+			0x00000000,	/* DENALI_PHY_501_DATA */
+			0x00000000,	/* DENALI_PHY_502_DATA */
+			0x00000000,	/* DENALI_PHY_503_DATA */
+			0x00000000,	/* DENALI_PHY_504_DATA */
+			0x00000000,	/* DENALI_PHY_505_DATA */
+			0x00000000,	/* DENALI_PHY_506_DATA */
+			0x00000000,	/* DENALI_PHY_507_DATA */
+			0x00000000,	/* DENALI_PHY_508_DATA */
+			0x00000000,	/* DENALI_PHY_509_DATA */
+			0x00000000,	/* DENALI_PHY_510_DATA */
+			0x00000000,	/* DENALI_PHY_511_DATA */
+			0x00000000,	/* DENALI_PHY_512_DATA */
+			0x00000000,	/* DENALI_PHY_513_DATA */
+			0x00000000,	/* DENALI_PHY_514_DATA */
+			0x00000000,	/* DENALI_PHY_515_DATA */
+			0x00000000,	/* DENALI_PHY_516_DATA */
+			0x00000000,	/* DENALI_PHY_517_DATA */
+			0x00000000,	/* DENALI_PHY_518_DATA */
+			0x00000002,	/* DENALI_PHY_519_DATA */
+			0x00000000,	/* DENALI_PHY_520_DATA */
+			0x00000000,	/* DENALI_PHY_521_DATA */
+			0x00000000,	/* DENALI_PHY_522_DATA */
+			0x00400320,	/* DENALI_PHY_523_DATA */
+			0x00000040,	/* DENALI_PHY_524_DATA */
+			0x00dcba98,	/* DENALI_PHY_525_DATA */
+			0x00000000,	/* DENALI_PHY_526_DATA */
+			0x00dcba98,	/* DENALI_PHY_527_DATA */
+			0x01000000,	/* DENALI_PHY_528_DATA */
+			0x00020003,	/* DENALI_PHY_529_DATA */
+			0x00000000,	/* DENALI_PHY_530_DATA */
+			0x00000000,	/* DENALI_PHY_531_DATA */
+			0x00000000,	/* DENALI_PHY_532_DATA */
+			0x0000002a,	/* DENALI_PHY_533_DATA */
+			0x00000015,	/* DENALI_PHY_534_DATA */
+			0x00000015,	/* DENALI_PHY_535_DATA */
+			0x0000002a,	/* DENALI_PHY_536_DATA */
+			0x00000033,	/* DENALI_PHY_537_DATA */
+			0x0000000c,	/* DENALI_PHY_538_DATA */
+			0x0000000c,	/* DENALI_PHY_539_DATA */
+			0x00000033,	/* DENALI_PHY_540_DATA */
+			0x0a418820,	/* DENALI_PHY_541_DATA */
+			0x003f0000,	/* DENALI_PHY_542_DATA */
+			0x0000003f,	/* DENALI_PHY_543_DATA */
+			0x00030055,	/* DENALI_PHY_544_DATA */
+			0x03000300,	/* DENALI_PHY_545_DATA */
+			0x03000300,	/* DENALI_PHY_546_DATA */
+			0x00000300,	/* DENALI_PHY_547_DATA */
+			0x42080010,	/* DENALI_PHY_548_DATA */
+			0x00000003,	/* DENALI_PHY_549_DATA */
+			0x00000000,	/* DENALI_PHY_550_DATA */
+			0x00000000,	/* DENALI_PHY_551_DATA */
+			0x00000000,	/* DENALI_PHY_552_DATA */
+			0x00000000,	/* DENALI_PHY_553_DATA */
+			0x00000000,	/* DENALI_PHY_554_DATA */
+			0x00000000,	/* DENALI_PHY_555_DATA */
+			0x00000000,	/* DENALI_PHY_556_DATA */
+			0x00000000,	/* DENALI_PHY_557_DATA */
+			0x00000000,	/* DENALI_PHY_558_DATA */
+			0x00000000,	/* DENALI_PHY_559_DATA */
+			0x00000000,	/* DENALI_PHY_560_DATA */
+			0x00000000,	/* DENALI_PHY_561_DATA */
+			0x00000000,	/* DENALI_PHY_562_DATA */
+			0x00000000,	/* DENALI_PHY_563_DATA */
+			0x00000000,	/* DENALI_PHY_564_DATA */
+			0x00000000,	/* DENALI_PHY_565_DATA */
+			0x00000000,	/* DENALI_PHY_566_DATA */
+			0x00000000,	/* DENALI_PHY_567_DATA */
+			0x00000000,	/* DENALI_PHY_568_DATA */
+			0x00000000,	/* DENALI_PHY_569_DATA */
+			0x00000000,	/* DENALI_PHY_570_DATA */
+			0x00000000,	/* DENALI_PHY_571_DATA */
+			0x00000000,	/* DENALI_PHY_572_DATA */
+			0x00000000,	/* DENALI_PHY_573_DATA */
+			0x00000000,	/* DENALI_PHY_574_DATA */
+			0x00000000,	/* DENALI_PHY_575_DATA */
+			0x00000000,	/* DENALI_PHY_576_DATA */
+			0x00000000,	/* DENALI_PHY_577_DATA */
+			0x00000000,	/* DENALI_PHY_578_DATA */
+			0x00000000,	/* DENALI_PHY_579_DATA */
+			0x00000000,	/* DENALI_PHY_580_DATA */
+			0x00000000,	/* DENALI_PHY_581_DATA */
+			0x00000000,	/* DENALI_PHY_582_DATA */
+			0x00000000,	/* DENALI_PHY_583_DATA */
+			0x00000000,	/* DENALI_PHY_584_DATA */
+			0x00000000,	/* DENALI_PHY_585_DATA */
+			0x00000000,	/* DENALI_PHY_586_DATA */
+			0x00000000,	/* DENALI_PHY_587_DATA */
+			0x00000000,	/* DENALI_PHY_588_DATA */
+			0x00000000,	/* DENALI_PHY_589_DATA */
+			0x00000000,	/* DENALI_PHY_590_DATA */
+			0x00000000,	/* DENALI_PHY_591_DATA */
+			0x00000000,	/* DENALI_PHY_592_DATA */
+			0x00000000,	/* DENALI_PHY_593_DATA */
+			0x00000000,	/* DENALI_PHY_594_DATA */
+			0x00000000,	/* DENALI_PHY_595_DATA */
+			0x00000000,	/* DENALI_PHY_596_DATA */
+			0x00000000,	/* DENALI_PHY_597_DATA */
+			0x00000000,	/* DENALI_PHY_598_DATA */
+			0x00000000,	/* DENALI_PHY_599_DATA */
+			0x00000000,	/* DENALI_PHY_600_DATA */
+			0x00000000,	/* DENALI_PHY_601_DATA */
+			0x00000000,	/* DENALI_PHY_602_DATA */
+			0x00000000,	/* DENALI_PHY_603_DATA */
+			0x00000000,	/* DENALI_PHY_604_DATA */
+			0x00000000,	/* DENALI_PHY_605_DATA */
+			0x00000000,	/* DENALI_PHY_606_DATA */
+			0x00000000,	/* DENALI_PHY_607_DATA */
+			0x00000000,	/* DENALI_PHY_608_DATA */
+			0x00000000,	/* DENALI_PHY_609_DATA */
+			0x00000000,	/* DENALI_PHY_610_DATA */
+			0x00000000,	/* DENALI_PHY_611_DATA */
+			0x00000000,	/* DENALI_PHY_612_DATA */
+			0x00000000,	/* DENALI_PHY_613_DATA */
+			0x00000000,	/* DENALI_PHY_614_DATA */
+			0x00000000,	/* DENALI_PHY_615_DATA */
+			0x00000000,	/* DENALI_PHY_616_DATA */
+			0x00000000,	/* DENALI_PHY_617_DATA */
+			0x00000000,	/* DENALI_PHY_618_DATA */
+			0x00000000,	/* DENALI_PHY_619_DATA */
+			0x00000000,	/* DENALI_PHY_620_DATA */
+			0x00000000,	/* DENALI_PHY_621_DATA */
+			0x00000000,	/* DENALI_PHY_622_DATA */
+			0x00000000,	/* DENALI_PHY_623_DATA */
+			0x00000000,	/* DENALI_PHY_624_DATA */
+			0x00000000,	/* DENALI_PHY_625_DATA */
+			0x00000000,	/* DENALI_PHY_626_DATA */
+			0x00000000,	/* DENALI_PHY_627_DATA */
+			0x00000000,	/* DENALI_PHY_628_DATA */
+			0x00000000,	/* DENALI_PHY_629_DATA */
+			0x00000000,	/* DENALI_PHY_630_DATA */
+			0x00000000,	/* DENALI_PHY_631_DATA */
+			0x00000000,	/* DENALI_PHY_632_DATA */
+			0x00000000,	/* DENALI_PHY_633_DATA */
+			0x00000000,	/* DENALI_PHY_634_DATA */
+			0x00000000,	/* DENALI_PHY_635_DATA */
+			0x00000000,	/* DENALI_PHY_636_DATA */
+			0x00000000,	/* DENALI_PHY_637_DATA */
+			0x00000000,	/* DENALI_PHY_638_DATA */
+			0x00000000,	/* DENALI_PHY_639_DATA */
+			0x00000000,	/* DENALI_PHY_640_DATA */
+			0x00000000,	/* DENALI_PHY_641_DATA */
+			0x00000000,	/* DENALI_PHY_642_DATA */
+			0x00000000,	/* DENALI_PHY_643_DATA */
+			0x00000000,	/* DENALI_PHY_644_DATA */
+			0x00000000,	/* DENALI_PHY_645_DATA */
+			0x00000000,	/* DENALI_PHY_646_DATA */
+			0x00000002,	/* DENALI_PHY_647_DATA */
+			0x00000000,	/* DENALI_PHY_648_DATA */
+			0x00000000,	/* DENALI_PHY_649_DATA */
+			0x00000000,	/* DENALI_PHY_650_DATA */
+			0x00400320,	/* DENALI_PHY_651_DATA */
+			0x00000040,	/* DENALI_PHY_652_DATA */
+			0x00000000,	/* DENALI_PHY_653_DATA */
+			0x00000000,	/* DENALI_PHY_654_DATA */
+			0x00000000,	/* DENALI_PHY_655_DATA */
+			0x01000000,	/* DENALI_PHY_656_DATA */
+			0x00020003,	/* DENALI_PHY_657_DATA */
+			0x00000000,	/* DENALI_PHY_658_DATA */
+			0x00000000,	/* DENALI_PHY_659_DATA */
+			0x00000000,	/* DENALI_PHY_660_DATA */
+			0x0000002a,	/* DENALI_PHY_661_DATA */
+			0x00000015,	/* DENALI_PHY_662_DATA */
+			0x00000015,	/* DENALI_PHY_663_DATA */
+			0x0000002a,	/* DENALI_PHY_664_DATA */
+			0x00000033,	/* DENALI_PHY_665_DATA */
+			0x0000000c,	/* DENALI_PHY_666_DATA */
+			0x0000000c,	/* DENALI_PHY_667_DATA */
+			0x00000033,	/* DENALI_PHY_668_DATA */
+			0x00000000,	/* DENALI_PHY_669_DATA */
+			0x00000000,	/* DENALI_PHY_670_DATA */
+			0x00000000,	/* DENALI_PHY_671_DATA */
+			0x00030055,	/* DENALI_PHY_672_DATA */
+			0x03000300,	/* DENALI_PHY_673_DATA */
+			0x03000300,	/* DENALI_PHY_674_DATA */
+			0x00000300,	/* DENALI_PHY_675_DATA */
+			0x42080010,	/* DENALI_PHY_676_DATA */
+			0x00000003,	/* DENALI_PHY_677_DATA */
+			0x00000000,	/* DENALI_PHY_678_DATA */
+			0x00000000,	/* DENALI_PHY_679_DATA */
+			0x00000000,	/* DENALI_PHY_680_DATA */
+			0x00000000,	/* DENALI_PHY_681_DATA */
+			0x00000000,	/* DENALI_PHY_682_DATA */
+			0x00000000,	/* DENALI_PHY_683_DATA */
+			0x00000000,	/* DENALI_PHY_684_DATA */
+			0x00000000,	/* DENALI_PHY_685_DATA */
+			0x00000000,	/* DENALI_PHY_686_DATA */
+			0x00000000,	/* DENALI_PHY_687_DATA */
+			0x00000000,	/* DENALI_PHY_688_DATA */
+			0x00000000,	/* DENALI_PHY_689_DATA */
+			0x00000000,	/* DENALI_PHY_690_DATA */
+			0x00000000,	/* DENALI_PHY_691_DATA */
+			0x00000000,	/* DENALI_PHY_692_DATA */
+			0x00000000,	/* DENALI_PHY_693_DATA */
+			0x00000000,	/* DENALI_PHY_694_DATA */
+			0x00000000,	/* DENALI_PHY_695_DATA */
+			0x00000000,	/* DENALI_PHY_696_DATA */
+			0x00000000,	/* DENALI_PHY_697_DATA */
+			0x00000000,	/* DENALI_PHY_698_DATA */
+			0x00000000,	/* DENALI_PHY_699_DATA */
+			0x00000000,	/* DENALI_PHY_700_DATA */
+			0x00000000,	/* DENALI_PHY_701_DATA */
+			0x00000000,	/* DENALI_PHY_702_DATA */
+			0x00000000,	/* DENALI_PHY_703_DATA */
+			0x00000000,	/* DENALI_PHY_704_DATA */
+			0x00000000,	/* DENALI_PHY_705_DATA */
+			0x00000000,	/* DENALI_PHY_706_DATA */
+			0x00000000,	/* DENALI_PHY_707_DATA */
+			0x00000000,	/* DENALI_PHY_708_DATA */
+			0x00000000,	/* DENALI_PHY_709_DATA */
+			0x00000000,	/* DENALI_PHY_710_DATA */
+			0x00000000,	/* DENALI_PHY_711_DATA */
+			0x00000000,	/* DENALI_PHY_712_DATA */
+			0x00000000,	/* DENALI_PHY_713_DATA */
+			0x00000000,	/* DENALI_PHY_714_DATA */
+			0x00000000,	/* DENALI_PHY_715_DATA */
+			0x00000000,	/* DENALI_PHY_716_DATA */
+			0x00000000,	/* DENALI_PHY_717_DATA */
+			0x00000000,	/* DENALI_PHY_718_DATA */
+			0x00000000,	/* DENALI_PHY_719_DATA */
+			0x00000000,	/* DENALI_PHY_720_DATA */
+			0x00000000,	/* DENALI_PHY_721_DATA */
+			0x00000000,	/* DENALI_PHY_722_DATA */
+			0x00000000,	/* DENALI_PHY_723_DATA */
+			0x00000000,	/* DENALI_PHY_724_DATA */
+			0x00000000,	/* DENALI_PHY_725_DATA */
+			0x00000000,	/* DENALI_PHY_726_DATA */
+			0x00000000,	/* DENALI_PHY_727_DATA */
+			0x00000000,	/* DENALI_PHY_728_DATA */
+			0x00000000,	/* DENALI_PHY_729_DATA */
+			0x00000000,	/* DENALI_PHY_730_DATA */
+			0x00000000,	/* DENALI_PHY_731_DATA */
+			0x00000000,	/* DENALI_PHY_732_DATA */
+			0x00000000,	/* DENALI_PHY_733_DATA */
+			0x00000000,	/* DENALI_PHY_734_DATA */
+			0x00000000,	/* DENALI_PHY_735_DATA */
+			0x00000000,	/* DENALI_PHY_736_DATA */
+			0x00000000,	/* DENALI_PHY_737_DATA */
+			0x00000000,	/* DENALI_PHY_738_DATA */
+			0x00000000,	/* DENALI_PHY_739_DATA */
+			0x00000000,	/* DENALI_PHY_740_DATA */
+			0x00000000,	/* DENALI_PHY_741_DATA */
+			0x00000000,	/* DENALI_PHY_742_DATA */
+			0x00000000,	/* DENALI_PHY_743_DATA */
+			0x00000000,	/* DENALI_PHY_744_DATA */
+			0x00000000,	/* DENALI_PHY_745_DATA */
+			0x00000000,	/* DENALI_PHY_746_DATA */
+			0x00000000,	/* DENALI_PHY_747_DATA */
+			0x00000000,	/* DENALI_PHY_748_DATA */
+			0x00000000,	/* DENALI_PHY_749_DATA */
+			0x00000000,	/* DENALI_PHY_750_DATA */
+			0x00000000,	/* DENALI_PHY_751_DATA */
+			0x00000000,	/* DENALI_PHY_752_DATA */
+			0x00000000,	/* DENALI_PHY_753_DATA */
+			0x00000000,	/* DENALI_PHY_754_DATA */
+			0x00000000,	/* DENALI_PHY_755_DATA */
+			0x00000000,	/* DENALI_PHY_756_DATA */
+			0x00000000,	/* DENALI_PHY_757_DATA */
+			0x00000000,	/* DENALI_PHY_758_DATA */
+			0x00000000,	/* DENALI_PHY_759_DATA */
+			0x00000000,	/* DENALI_PHY_760_DATA */
+			0x00000000,	/* DENALI_PHY_761_DATA */
+			0x00000000,	/* DENALI_PHY_762_DATA */
+			0x00000000,	/* DENALI_PHY_763_DATA */
+			0x00000000,	/* DENALI_PHY_764_DATA */
+			0x00000000,	/* DENALI_PHY_765_DATA */
+			0x00000000,	/* DENALI_PHY_766_DATA */
+			0x00000000,	/* DENALI_PHY_767_DATA */
+			0x00000000,	/* DENALI_PHY_768_DATA */
+			0x00000000,	/* DENALI_PHY_769_DATA */
+			0x00000000,	/* DENALI_PHY_770_DATA */
+			0x00000000,	/* DENALI_PHY_771_DATA */
+			0x00000000,	/* DENALI_PHY_772_DATA */
+			0x00000000,	/* DENALI_PHY_773_DATA */
+			0x00000000,	/* DENALI_PHY_774_DATA */
+			0x00000002,	/* DENALI_PHY_775_DATA */
+			0x00000000,	/* DENALI_PHY_776_DATA */
+			0x00000000,	/* DENALI_PHY_777_DATA */
+			0x00000000,	/* DENALI_PHY_778_DATA */
+			0x00400320,	/* DENALI_PHY_779_DATA */
+			0x00000040,	/* DENALI_PHY_780_DATA */
+			0x00000000,	/* DENALI_PHY_781_DATA */
+			0x00000000,	/* DENALI_PHY_782_DATA */
+			0x00000000,	/* DENALI_PHY_783_DATA */
+			0x01000000,	/* DENALI_PHY_784_DATA */
+			0x00020003,	/* DENALI_PHY_785_DATA */
+			0x00000000,	/* DENALI_PHY_786_DATA */
+			0x00000000,	/* DENALI_PHY_787_DATA */
+			0x00000000,	/* DENALI_PHY_788_DATA */
+			0x0000002a,	/* DENALI_PHY_789_DATA */
+			0x00000015,	/* DENALI_PHY_790_DATA */
+			0x00000015,	/* DENALI_PHY_791_DATA */
+			0x0000002a,	/* DENALI_PHY_792_DATA */
+			0x00000033,	/* DENALI_PHY_793_DATA */
+			0x0000000c,	/* DENALI_PHY_794_DATA */
+			0x0000000c,	/* DENALI_PHY_795_DATA */
+			0x00000033,	/* DENALI_PHY_796_DATA */
+			0x1ee6b16a,	/* DENALI_PHY_797_DATA */
+			0x10000000,	/* DENALI_PHY_798_DATA */
+			0x00000000,	/* DENALI_PHY_799_DATA */
+			0x00030055,	/* DENALI_PHY_800_DATA */
+			0x03000300,	/* DENALI_PHY_801_DATA */
+			0x03000300,	/* DENALI_PHY_802_DATA */
+			0x00000300,	/* DENALI_PHY_803_DATA */
+			0x42080010,	/* DENALI_PHY_804_DATA */
+			0x00000003,	/* DENALI_PHY_805_DATA */
+			0x00000000,	/* DENALI_PHY_806_DATA */
+			0x00000000,	/* DENALI_PHY_807_DATA */
+			0x00000000,	/* DENALI_PHY_808_DATA */
+			0x00000000,	/* DENALI_PHY_809_DATA */
+			0x00000000,	/* DENALI_PHY_810_DATA */
+			0x00000000,	/* DENALI_PHY_811_DATA */
+			0x00000000,	/* DENALI_PHY_812_DATA */
+			0x00000000,	/* DENALI_PHY_813_DATA */
+			0x00000000,	/* DENALI_PHY_814_DATA */
+			0x00000000,	/* DENALI_PHY_815_DATA */
+			0x00000000,	/* DENALI_PHY_816_DATA */
+			0x00000000,	/* DENALI_PHY_817_DATA */
+			0x00000000,	/* DENALI_PHY_818_DATA */
+			0x00000000,	/* DENALI_PHY_819_DATA */
+			0x00000000,	/* DENALI_PHY_820_DATA */
+			0x00000000,	/* DENALI_PHY_821_DATA */
+			0x00000000,	/* DENALI_PHY_822_DATA */
+			0x00000000,	/* DENALI_PHY_823_DATA */
+			0x00000000,	/* DENALI_PHY_824_DATA */
+			0x00000000,	/* DENALI_PHY_825_DATA */
+			0x00000000,	/* DENALI_PHY_826_DATA */
+			0x00000000,	/* DENALI_PHY_827_DATA */
+			0x00000000,	/* DENALI_PHY_828_DATA */
+			0x00000000,	/* DENALI_PHY_829_DATA */
+			0x00000000,	/* DENALI_PHY_830_DATA */
+			0x00000000,	/* DENALI_PHY_831_DATA */
+			0x00000000,	/* DENALI_PHY_832_DATA */
+			0x00000000,	/* DENALI_PHY_833_DATA */
+			0x00000000,	/* DENALI_PHY_834_DATA */
+			0x00000000,	/* DENALI_PHY_835_DATA */
+			0x00000000,	/* DENALI_PHY_836_DATA */
+			0x00000000,	/* DENALI_PHY_837_DATA */
+			0x00000000,	/* DENALI_PHY_838_DATA */
+			0x00000000,	/* DENALI_PHY_839_DATA */
+			0x00000000,	/* DENALI_PHY_840_DATA */
+			0x00000000,	/* DENALI_PHY_841_DATA */
+			0x00000000,	/* DENALI_PHY_842_DATA */
+			0x00000000,	/* DENALI_PHY_843_DATA */
+			0x00000000,	/* DENALI_PHY_844_DATA */
+			0x00000000,	/* DENALI_PHY_845_DATA */
+			0x00000000,	/* DENALI_PHY_846_DATA */
+			0x00000000,	/* DENALI_PHY_847_DATA */
+			0x00000000,	/* DENALI_PHY_848_DATA */
+			0x00000000,	/* DENALI_PHY_849_DATA */
+			0x00000000,	/* DENALI_PHY_850_DATA */
+			0x00000000,	/* DENALI_PHY_851_DATA */
+			0x00000000,	/* DENALI_PHY_852_DATA */
+			0x00000000,	/* DENALI_PHY_853_DATA */
+			0x00000000,	/* DENALI_PHY_854_DATA */
+			0x00000000,	/* DENALI_PHY_855_DATA */
+			0x00000000,	/* DENALI_PHY_856_DATA */
+			0x00000000,	/* DENALI_PHY_857_DATA */
+			0x00000000,	/* DENALI_PHY_858_DATA */
+			0x00000000,	/* DENALI_PHY_859_DATA */
+			0x00000000,	/* DENALI_PHY_860_DATA */
+			0x00000000,	/* DENALI_PHY_861_DATA */
+			0x00000000,	/* DENALI_PHY_862_DATA */
+			0x00000000,	/* DENALI_PHY_863_DATA */
+			0x00000000,	/* DENALI_PHY_864_DATA */
+			0x00000000,	/* DENALI_PHY_865_DATA */
+			0x00000000,	/* DENALI_PHY_866_DATA */
+			0x00000000,	/* DENALI_PHY_867_DATA */
+			0x00000000,	/* DENALI_PHY_868_DATA */
+			0x00000000,	/* DENALI_PHY_869_DATA */
+			0x00000000,	/* DENALI_PHY_870_DATA */
+			0x00000000,	/* DENALI_PHY_871_DATA */
+			0x00000000,	/* DENALI_PHY_872_DATA */
+			0x00000000,	/* DENALI_PHY_873_DATA */
+			0x00000000,	/* DENALI_PHY_874_DATA */
+			0x00000000,	/* DENALI_PHY_875_DATA */
+			0x00000000,	/* DENALI_PHY_876_DATA */
+			0x00000000,	/* DENALI_PHY_877_DATA */
+			0x00000000,	/* DENALI_PHY_878_DATA */
+			0x00000000,	/* DENALI_PHY_879_DATA */
+			0x00000000,	/* DENALI_PHY_880_DATA */
+			0x00000000,	/* DENALI_PHY_881_DATA */
+			0x00000000,	/* DENALI_PHY_882_DATA */
+			0x00000000,	/* DENALI_PHY_883_DATA */
+			0x00000000,	/* DENALI_PHY_884_DATA */
+			0x00000000,	/* DENALI_PHY_885_DATA */
+			0x00000000,	/* DENALI_PHY_886_DATA */
+			0x00000000,	/* DENALI_PHY_887_DATA */
+			0x00000000,	/* DENALI_PHY_888_DATA */
+			0x00000000,	/* DENALI_PHY_889_DATA */
+			0x00000000,	/* DENALI_PHY_890_DATA */
+			0x00000000,	/* DENALI_PHY_891_DATA */
+			0x00000000,	/* DENALI_PHY_892_DATA */
+			0x00000000,	/* DENALI_PHY_893_DATA */
+			0x00000000,	/* DENALI_PHY_894_DATA */
+			0x00000000,	/* DENALI_PHY_895_DATA */
+			0x00000000,	/* DENALI_PHY_896_DATA */
+			0x00000000,	/* DENALI_PHY_897_DATA */
+			0x00000005,	/* DENALI_PHY_898_DATA */
+			0x04000f01,	/* DENALI_PHY_899_DATA */
+			0x00020040,	/* DENALI_PHY_900_DATA */
+			0x00020055,	/* DENALI_PHY_901_DATA */
+			0x00000000,	/* DENALI_PHY_902_DATA */
+			0x00000000,	/* DENALI_PHY_903_DATA */
+			0x00000000,	/* DENALI_PHY_904_DATA */
+			0x00000050,	/* DENALI_PHY_905_DATA */
+			0x00000000,	/* DENALI_PHY_906_DATA */
+			0x01010100,	/* DENALI_PHY_907_DATA */
+			0x00000600,	/* DENALI_PHY_908_DATA */
+			0x00000000,	/* DENALI_PHY_909_DATA */
+			0x00006400,	/* DENALI_PHY_910_DATA */
+			0x03221302,	/* DENALI_PHY_911_DATA */
+			0x00000000,	/* DENALI_PHY_912_DATA */
+			0x000d1f01,	/* DENALI_PHY_913_DATA */
+			0x0d1f0d1f,	/* DENALI_PHY_914_DATA */
+			0x0d1f0d1f,	/* DENALI_PHY_915_DATA */
+			0x00030003,	/* DENALI_PHY_916_DATA */
+			0x03000300,	/* DENALI_PHY_917_DATA */
+			0x00000300,	/* DENALI_PHY_918_DATA */
+			0x03221302,	/* DENALI_PHY_919_DATA */
+			0x00000000,	/* DENALI_PHY_920_DATA */
+			0x00000000,	/* DENALI_PHY_921_DATA */
+			0x01020000,	/* DENALI_PHY_922_DATA */
+			0x00000001,	/* DENALI_PHY_923_DATA */
+			0x00000411,	/* DENALI_PHY_924_DATA */
+			0x00000411,	/* DENALI_PHY_925_DATA */
+			0x00000040,	/* DENALI_PHY_926_DATA */
+			0x00000040,	/* DENALI_PHY_927_DATA */
+			0x00000411,	/* DENALI_PHY_928_DATA */
+			0x00000411,	/* DENALI_PHY_929_DATA */
+			0x00004410,	/* DENALI_PHY_930_DATA */
+			0x00004410,	/* DENALI_PHY_931_DATA */
+			0x00004410,	/* DENALI_PHY_932_DATA */
+			0x00004410,	/* DENALI_PHY_933_DATA */
+			0x00004410,	/* DENALI_PHY_934_DATA */
+			0x00000411,	/* DENALI_PHY_935_DATA */
+			0x00004410,	/* DENALI_PHY_936_DATA */
+			0x00000411,	/* DENALI_PHY_937_DATA */
+			0x00004410,	/* DENALI_PHY_938_DATA */
+			0x00000411,	/* DENALI_PHY_939_DATA */
+			0x00004410,	/* DENALI_PHY_940_DATA */
+			0x00000000,	/* DENALI_PHY_941_DATA */
+			0x00000000,	/* DENALI_PHY_942_DATA */
+			0x00000000,	/* DENALI_PHY_943_DATA */
+			0x64000000,	/* DENALI_PHY_944_DATA */
+			0x00000000,	/* DENALI_PHY_945_DATA */
+			0x00000000,	/* DENALI_PHY_946_DATA */
+			0x00000408,	/* DENALI_PHY_947_DATA */
+			0x00000000,	/* DENALI_PHY_948_DATA */
+			0x00000000,	/* DENALI_PHY_949_DATA */
+			0x00000000,	/* DENALI_PHY_950_DATA */
+			0x00000000,	/* DENALI_PHY_951_DATA */
+			0x00000000,	/* DENALI_PHY_952_DATA */
+			0x00000000,	/* DENALI_PHY_953_DATA */
+			0xe4000000,	/* DENALI_PHY_954_DATA */
+			0x00000000,	/* DENALI_PHY_955_DATA */
+			0x00000000,	/* DENALI_PHY_956_DATA */
+			0x01010000,	/* DENALI_PHY_957_DATA */
+			0x00000000	/* DENALI_PHY_958_DATA */
+		}
+	},
+},
diff --git a/drivers/ram/rockchip/sdram-rk3399-lpddr4-800.inc b/drivers/ram/rockchip/sdram-rk3399-lpddr4-800.inc
new file mode 100644
index 0000000..d8ae335
--- /dev/null
+++ b/drivers/ram/rockchip/sdram-rk3399-lpddr4-800.inc
@@ -0,0 +1,1570 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * (C) Copyright 2019 Rockchip Electronics Co., Ltd.
+ * (C) Copyright 2019 Amarula Solutions
+ */
+
+{
+	{
+		{
+			{
+				.rank = 0x2,
+				.col = 0xA,
+				.bk = 0x3,
+				.bw = 0x2,
+				.dbw = 0x1,
+				.row_3_4 = 0x0,
+				.cs0_row = 0xF,
+				.cs1_row = 0xF,
+				.ddrconfig = 1,
+			},
+			{
+				.ddrtiminga0 = 0x80241d22,
+				.ddrtimingb0 = 0x15050f08,
+				.ddrtimingc0 = {
+					0x00000602,
+				},
+				.devtodev0 = 0x00002122,
+				.ddrmode = {
+					0x0000004c,
+				},
+				.agingx0 = 0x00000000,
+			}
+		},
+		{
+			{
+				.rank = 0x2,
+				.col = 0xA,
+				.bk = 0x3,
+				.bw = 0x2,
+				.dbw = 0x1,
+				.row_3_4 = 0x0,
+				.cs0_row = 0xF,
+				.cs1_row = 0xF,
+				.ddrconfig = 1,
+			},
+			{
+				.ddrtiminga0 = 0x80241d22,
+				.ddrtimingb0 = 0x15050f08,
+				.ddrtimingc0 = {
+					0x00000602,
+				},
+				.devtodev0 = 0x00002122,
+				.ddrmode = {
+					0x0000004c,
+				},
+				.agingx0 = 0x00000000,
+			}
+		}
+	},
+	{
+		.ddr_freq = 800 * MHz,
+		.dramtype = LPDDR4,
+		.num_channels = 2,
+		.stride = 13,
+		.odt = 1,
+	},
+	{
+		{
+			0x00000b00,	/* DENALI_CTL_00_DATA */
+			0x00000000,	/* DENALI_CTL_01_DATA */
+			0x00000000,	/* DENALI_CTL_02_DATA */
+			0x00000000,	/* DENALI_CTL_03_DATA */
+			0x00000000,	/* DENALI_CTL_04_DATA */
+			0x00013880,	/* DENALI_CTL_05_DATA */
+			0x000c3500,	/* DENALI_CTL_06_DATA */
+			0x00000005,	/* DENALI_CTL_07_DATA */
+			0x00000320,	/* DENALI_CTL_08_DATA */
+			0x00027100,	/* DENALI_CTL_09_DATA */
+			0x00186a00,	/* DENALI_CTL_10_DATA */
+			0x00000005,	/* DENALI_CTL_11_DATA */
+			0x00000640,	/* DENALI_CTL_12_DATA */
+			0x00002710,	/* DENALI_CTL_13_DATA */
+			0x000186a0,	/* DENALI_CTL_14_DATA */
+			0x00000005,	/* DENALI_CTL_15_DATA */
+			0x01000064,	/* DENALI_CTL_16_DATA */
+			0x00000000,	/* DENALI_CTL_17_DATA */
+			0x02020101,	/* DENALI_CTL_18_DATA */
+			0x00000102,	/* DENALI_CTL_19_DATA */
+			0x00000050,	/* DENALI_CTL_20_DATA */
+			0x000000c8,	/* DENALI_CTL_21_DATA */
+			0x00000000,	/* DENALI_CTL_22_DATA */
+			0x06140000,	/* DENALI_CTL_23_DATA */
+			0x00081c00,	/* DENALI_CTL_24_DATA */
+			0x0400040c,	/* DENALI_CTL_25_DATA */
+			0x19042008,	/* DENALI_CTL_26_DATA */
+			0x10080a11,	/* DENALI_CTL_27_DATA */
+			0x22310800,	/* DENALI_CTL_28_DATA */
+			0x00200f0a,	/* DENALI_CTL_29_DATA */
+			0x0a030704,	/* DENALI_CTL_30_DATA */
+			0x08000204,	/* DENALI_CTL_31_DATA */
+			0x00000a0a,	/* DENALI_CTL_32_DATA */
+			0x04006db0,	/* DENALI_CTL_33_DATA */
+			0x0a0a0804,	/* DENALI_CTL_34_DATA */
+			0x0600db60,	/* DENALI_CTL_35_DATA */
+			0x0a0a0806,	/* DENALI_CTL_36_DATA */
+			0x04000db6,	/* DENALI_CTL_37_DATA */
+			0x02030404,	/* DENALI_CTL_38_DATA */
+			0x0f0a0800,	/* DENALI_CTL_39_DATA */
+			0x08040411,	/* DENALI_CTL_40_DATA */
+			0x1400640a,	/* DENALI_CTL_41_DATA */
+			0x02010a0a,	/* DENALI_CTL_42_DATA */
+			0x00010001,	/* DENALI_CTL_43_DATA */
+			0x04082012,	/* DENALI_CTL_44_DATA */
+			0x00041109,	/* DENALI_CTL_45_DATA */
+			0x00000000,	/* DENALI_CTL_46_DATA */
+			0x03010000,	/* DENALI_CTL_47_DATA */
+			0x06100034,	/* DENALI_CTL_48_DATA */
+			0x0c280068,	/* DENALI_CTL_49_DATA */
+			0x00bb0007,	/* DENALI_CTL_50_DATA */
+			0x00000000,	/* DENALI_CTL_51_DATA */
+			0x00060003,	/* DENALI_CTL_52_DATA */
+			0x000a0003,	/* DENALI_CTL_53_DATA */
+			0x000a0014,	/* DENALI_CTL_54_DATA */
+			0x01000000,	/* DENALI_CTL_55_DATA */
+			0x030a0000,	/* DENALI_CTL_56_DATA */
+			0x0c000002,	/* DENALI_CTL_57_DATA */
+			0x00000103,	/* DENALI_CTL_58_DATA */
+			0x0003030a,	/* DENALI_CTL_59_DATA */
+			0x00060037,	/* DENALI_CTL_60_DATA */
+			0x0003006e,	/* DENALI_CTL_61_DATA */
+			0x05050007,	/* DENALI_CTL_62_DATA */
+			0x03020605,	/* DENALI_CTL_63_DATA */
+			0x06050301,	/* DENALI_CTL_64_DATA */
+			0x06020c05,	/* DENALI_CTL_65_DATA */
+			0x05050302,	/* DENALI_CTL_66_DATA */
+			0x03020305,	/* DENALI_CTL_67_DATA */
+			0x00000301,	/* DENALI_CTL_68_DATA */
+			0x00000301,	/* DENALI_CTL_69_DATA */
+			0x00000001,	/* DENALI_CTL_70_DATA */
+			0x00000000,	/* DENALI_CTL_71_DATA */
+			0x00000000,	/* DENALI_CTL_72_DATA */
+			0x01000000,	/* DENALI_CTL_73_DATA */
+			0x80104002,	/* DENALI_CTL_74_DATA */
+			0x00040003,	/* DENALI_CTL_75_DATA */
+			0x00040005,	/* DENALI_CTL_76_DATA */
+			0x00030000,	/* DENALI_CTL_77_DATA */
+			0x00050004,	/* DENALI_CTL_78_DATA */
+			0x00000004,	/* DENALI_CTL_79_DATA */
+			0x00040003,	/* DENALI_CTL_80_DATA */
+			0x00040005,	/* DENALI_CTL_81_DATA */
+			0x18400000,	/* DENALI_CTL_82_DATA */
+			0x00000c20,	/* DENALI_CTL_83_DATA */
+			0x185030a0,	/* DENALI_CTL_84_DATA */
+			0x02ec0000,	/* DENALI_CTL_85_DATA */
+			0x00000176,	/* DENALI_CTL_86_DATA */
+			0x00000000,	/* DENALI_CTL_87_DATA */
+			0x00000000,	/* DENALI_CTL_88_DATA */
+			0x00000000,	/* DENALI_CTL_89_DATA */
+			0x00000000,	/* DENALI_CTL_90_DATA */
+			0x00000000,	/* DENALI_CTL_91_DATA */
+			0x06030300,	/* DENALI_CTL_92_DATA */
+			0x00030303,	/* DENALI_CTL_93_DATA */
+			0x02030200,	/* DENALI_CTL_94_DATA */
+			0x00040703,	/* DENALI_CTL_95_DATA */
+			0x03020302,	/* DENALI_CTL_96_DATA */
+			0x02000407,	/* DENALI_CTL_97_DATA */
+			0x07030203,	/* DENALI_CTL_98_DATA */
+			0x00030f04,	/* DENALI_CTL_99_DATA */
+			0x00070004,	/* DENALI_CTL_100_DATA */
+			0x00000000,	/* DENALI_CTL_101_DATA */
+			0x00000000,	/* DENALI_CTL_102_DATA */
+			0x00000000,	/* DENALI_CTL_103_DATA */
+			0x00000000,	/* DENALI_CTL_104_DATA */
+			0x00000000,	/* DENALI_CTL_105_DATA */
+			0x00000000,	/* DENALI_CTL_106_DATA */
+			0x00000000,	/* DENALI_CTL_107_DATA */
+			0x00010000,	/* DENALI_CTL_108_DATA */
+			0x20040020,	/* DENALI_CTL_109_DATA */
+			0x00200400,	/* DENALI_CTL_110_DATA */
+			0x01000400,	/* DENALI_CTL_111_DATA */
+			0x00000b80,	/* DENALI_CTL_112_DATA */
+			0x00000000,	/* DENALI_CTL_113_DATA */
+			0x00000001,	/* DENALI_CTL_114_DATA */
+			0x00000002,	/* DENALI_CTL_115_DATA */
+			0x0000000e,	/* DENALI_CTL_116_DATA */
+			0x00000000,	/* DENALI_CTL_117_DATA */
+			0x00000000,	/* DENALI_CTL_118_DATA */
+			0x00000000,	/* DENALI_CTL_119_DATA */
+			0x00000000,	/* DENALI_CTL_120_DATA */
+			0x00000000,	/* DENALI_CTL_121_DATA */
+			0x00500000,	/* DENALI_CTL_122_DATA */
+			0x00640028,	/* DENALI_CTL_123_DATA */
+			0x00640404,	/* DENALI_CTL_124_DATA */
+			0x005000a0,	/* DENALI_CTL_125_DATA */
+			0x060600c8,	/* DENALI_CTL_126_DATA */
+			0x000a00c8,	/* DENALI_CTL_127_DATA */
+			0x000d0005,	/* DENALI_CTL_128_DATA */
+			0x000d0404,	/* DENALI_CTL_129_DATA */
+			0x00000000,	/* DENALI_CTL_130_DATA */
+			0x00000000,	/* DENALI_CTL_131_DATA */
+			0x00000000,	/* DENALI_CTL_132_DATA */
+			0x001400a3,	/* DENALI_CTL_133_DATA */
+			0x00e30009,	/* DENALI_CTL_134_DATA */
+			0x00120024,	/* DENALI_CTL_135_DATA */
+			0x00040063,	/* DENALI_CTL_136_DATA */
+			0x00000000,	/* DENALI_CTL_137_DATA */
+			0x00310031,	/* DENALI_CTL_138_DATA */
+			0x00000031,	/* DENALI_CTL_139_DATA */
+			0x004d0000,	/* DENALI_CTL_140_DATA */
+			0x004d004d,	/* DENALI_CTL_141_DATA */
+			0x004d0000,	/* DENALI_CTL_142_DATA */
+			0x004d004d,	/* DENALI_CTL_143_DATA */
+			0x00010101,	/* DENALI_CTL_144_DATA */
+			0x00000000,	/* DENALI_CTL_145_DATA */
+			0x00000000,	/* DENALI_CTL_146_DATA */
+			0x001400a3,	/* DENALI_CTL_147_DATA */
+			0x00e30009,	/* DENALI_CTL_148_DATA */
+			0x00120024,	/* DENALI_CTL_149_DATA */
+			0x00040063,	/* DENALI_CTL_150_DATA */
+			0x00000000,	/* DENALI_CTL_151_DATA */
+			0x00310031,	/* DENALI_CTL_152_DATA */
+			0x00000031,	/* DENALI_CTL_153_DATA */
+			0x004d0000,	/* DENALI_CTL_154_DATA */
+			0x004d004d,	/* DENALI_CTL_155_DATA */
+			0x004d0000,	/* DENALI_CTL_156_DATA */
+			0x004d004d,	/* DENALI_CTL_157_DATA */
+			0x00010101,	/* DENALI_CTL_158_DATA */
+			0x00000000,	/* DENALI_CTL_159_DATA */
+			0x00000000,	/* DENALI_CTL_160_DATA */
+			0x00000000,	/* DENALI_CTL_161_DATA */
+			0x00000001,	/* DENALI_CTL_162_DATA */
+			0x00000000,	/* DENALI_CTL_163_DATA */
+			0x18151100,	/* DENALI_CTL_164_DATA */
+			0x0000000c,	/* DENALI_CTL_165_DATA */
+			0x00000000,	/* DENALI_CTL_166_DATA */
+			0x00000000,	/* DENALI_CTL_167_DATA */
+			0x00000000,	/* DENALI_CTL_168_DATA */
+			0x00000000,	/* DENALI_CTL_169_DATA */
+			0x00000000,	/* DENALI_CTL_170_DATA */
+			0x00000000,	/* DENALI_CTL_171_DATA */
+			0x00000000,	/* DENALI_CTL_172_DATA */
+			0x00000000,	/* DENALI_CTL_173_DATA */
+			0x00000000,	/* DENALI_CTL_174_DATA */
+			0x00000000,	/* DENALI_CTL_175_DATA */
+			0x00000000,	/* DENALI_CTL_176_DATA */
+			0x00000000,	/* DENALI_CTL_177_DATA */
+			0x00000000,	/* DENALI_CTL_178_DATA */
+			0x00020003,	/* DENALI_CTL_179_DATA */
+			0x00400100,	/* DENALI_CTL_180_DATA */
+			0x000c0190,	/* DENALI_CTL_181_DATA */
+			0x01000200,	/* DENALI_CTL_182_DATA */
+			0x03200040,	/* DENALI_CTL_183_DATA */
+			0x00020018,	/* DENALI_CTL_184_DATA */
+			0x00400100,	/* DENALI_CTL_185_DATA */
+			0x00080032,	/* DENALI_CTL_186_DATA */
+			0x00140000,	/* DENALI_CTL_187_DATA */
+			0x00030028,	/* DENALI_CTL_188_DATA */
+			0x01010100,	/* DENALI_CTL_189_DATA */
+			0x02000202,	/* DENALI_CTL_190_DATA */
+			0x0b000002,	/* DENALI_CTL_191_DATA */
+			0x01000f0f,	/* DENALI_CTL_192_DATA */
+			0x00000000,	/* DENALI_CTL_193_DATA */
+			0x00000000,	/* DENALI_CTL_194_DATA */
+			0x00010003,	/* DENALI_CTL_195_DATA */
+			0x00000c03,	/* DENALI_CTL_196_DATA */
+			0x00040101,	/* DENALI_CTL_197_DATA */
+			0x04010100,	/* DENALI_CTL_198_DATA */
+			0x01000000,	/* DENALI_CTL_199_DATA */
+			0x02010000,	/* DENALI_CTL_200_DATA */
+			0x00000001,	/* DENALI_CTL_201_DATA */
+			0x00000000,	/* DENALI_CTL_202_DATA */
+			0x00000000,	/* DENALI_CTL_203_DATA */
+			0x00000000,	/* DENALI_CTL_204_DATA */
+			0x00000000,	/* DENALI_CTL_205_DATA */
+			0x00000000,	/* DENALI_CTL_206_DATA */
+			0x00000000,	/* DENALI_CTL_207_DATA */
+			0x00000000,	/* DENALI_CTL_208_DATA */
+			0x00000000,	/* DENALI_CTL_209_DATA */
+			0x00000000,	/* DENALI_CTL_210_DATA */
+			0x00010000,	/* DENALI_CTL_211_DATA */
+			0x00000001,	/* DENALI_CTL_212_DATA */
+			0x01010001,	/* DENALI_CTL_213_DATA */
+			0x05040001,	/* DENALI_CTL_214_DATA */
+			0x040a0703,	/* DENALI_CTL_215_DATA */
+			0x02080808,	/* DENALI_CTL_216_DATA */
+			0x020e000a,	/* DENALI_CTL_217_DATA */
+			0x020f010b,	/* DENALI_CTL_218_DATA */
+			0x000d0008,	/* DENALI_CTL_219_DATA */
+			0x00080b0a,	/* DENALI_CTL_220_DATA */
+			0x03000200,	/* DENALI_CTL_221_DATA */
+			0x00000100,	/* DENALI_CTL_222_DATA */
+			0x00000000,	/* DENALI_CTL_223_DATA */
+			0x00000000,	/* DENALI_CTL_224_DATA */
+			0x0d000001,	/* DENALI_CTL_225_DATA */
+			0x00000028,	/* DENALI_CTL_226_DATA */
+			0x00010000,	/* DENALI_CTL_227_DATA */
+			0x00000003,	/* DENALI_CTL_228_DATA */
+			0x00000000,	/* DENALI_CTL_229_DATA */
+			0x00000000,	/* DENALI_CTL_230_DATA */
+			0x00000000,	/* DENALI_CTL_231_DATA */
+			0x00000000,	/* DENALI_CTL_232_DATA */
+			0x00000000,	/* DENALI_CTL_233_DATA */
+			0x00000000,	/* DENALI_CTL_234_DATA */
+			0x00000000,	/* DENALI_CTL_235_DATA */
+			0x00000000,	/* DENALI_CTL_236_DATA */
+			0x00010100,	/* DENALI_CTL_237_DATA */
+			0x01000000,	/* DENALI_CTL_238_DATA */
+			0x00000001,	/* DENALI_CTL_239_DATA */
+			0x00000303,	/* DENALI_CTL_240_DATA */
+			0x00000000,	/* DENALI_CTL_241_DATA */
+			0x00000000,	/* DENALI_CTL_242_DATA */
+			0x00000000,	/* DENALI_CTL_243_DATA */
+			0x00000000,	/* DENALI_CTL_244_DATA */
+			0x00000000,	/* DENALI_CTL_245_DATA */
+			0x00000000,	/* DENALI_CTL_246_DATA */
+			0x00000000,	/* DENALI_CTL_247_DATA */
+			0x00000000,	/* DENALI_CTL_248_DATA */
+			0x00000000,	/* DENALI_CTL_249_DATA */
+			0x00000000,	/* DENALI_CTL_250_DATA */
+			0x00000000,	/* DENALI_CTL_251_DATA */
+			0x00000000,	/* DENALI_CTL_252_DATA */
+			0x00000000,	/* DENALI_CTL_253_DATA */
+			0x00000000,	/* DENALI_CTL_254_DATA */
+			0x00000000,	/* DENALI_CTL_255_DATA */
+			0x000556aa,	/* DENALI_CTL_256_DATA */
+			0x000aaaaa,	/* DENALI_CTL_257_DATA */
+			0x000aa955,	/* DENALI_CTL_258_DATA */
+			0x00055555,	/* DENALI_CTL_259_DATA */
+			0x000b3133,	/* DENALI_CTL_260_DATA */
+			0x0004cd33,	/* DENALI_CTL_261_DATA */
+			0x0004cecc,	/* DENALI_CTL_262_DATA */
+			0x000b32cc,	/* DENALI_CTL_263_DATA */
+			0x00010300,	/* DENALI_CTL_264_DATA */
+			0x03000100,	/* DENALI_CTL_265_DATA */
+			0x00000000,	/* DENALI_CTL_266_DATA */
+			0x00000000,	/* DENALI_CTL_267_DATA */
+			0x00000000,	/* DENALI_CTL_268_DATA */
+			0x00000000,	/* DENALI_CTL_269_DATA */
+			0x00000000,	/* DENALI_CTL_270_DATA */
+			0x00000000,	/* DENALI_CTL_271_DATA */
+			0x00000000,	/* DENALI_CTL_272_DATA */
+			0x00000000,	/* DENALI_CTL_273_DATA */
+			0x00ffff00,	/* DENALI_CTL_274_DATA */
+			0x1a160000,	/* DENALI_CTL_275_DATA */
+			0x08000012,	/* DENALI_CTL_276_DATA */
+			0x00000c20,	/* DENALI_CTL_277_DATA */
+			0x00000200,	/* DENALI_CTL_278_DATA */
+			0x00000200,	/* DENALI_CTL_279_DATA */
+			0x00000200,	/* DENALI_CTL_280_DATA */
+			0x00000200,	/* DENALI_CTL_281_DATA */
+			0x00000c20,	/* DENALI_CTL_282_DATA */
+			0x00007940,	/* DENALI_CTL_283_DATA */
+			0x18500409,	/* DENALI_CTL_284_DATA */
+			0x00000200,	/* DENALI_CTL_285_DATA */
+			0x00000200,	/* DENALI_CTL_286_DATA */
+			0x00000200,	/* DENALI_CTL_287_DATA */
+			0x00000200,	/* DENALI_CTL_288_DATA */
+			0x00001850,	/* DENALI_CTL_289_DATA */
+			0x0000f320,	/* DENALI_CTL_290_DATA */
+			0x0176060c,	/* DENALI_CTL_291_DATA */
+			0x00000200,	/* DENALI_CTL_292_DATA */
+			0x00000200,	/* DENALI_CTL_293_DATA */
+			0x00000200,	/* DENALI_CTL_294_DATA */
+			0x00000200,	/* DENALI_CTL_295_DATA */
+			0x00000176,	/* DENALI_CTL_296_DATA */
+			0x00000e9c,	/* DENALI_CTL_297_DATA */
+			0x02020205,	/* DENALI_CTL_298_DATA */
+			0x03030202,	/* DENALI_CTL_299_DATA */
+			0x00000018,	/* DENALI_CTL_300_DATA */
+			0x00000000,	/* DENALI_CTL_301_DATA */
+			0x00000000,	/* DENALI_CTL_302_DATA */
+			0x00001403,	/* DENALI_CTL_303_DATA */
+			0x00000000,	/* DENALI_CTL_304_DATA */
+			0x00000000,	/* DENALI_CTL_305_DATA */
+			0x00000000,	/* DENALI_CTL_306_DATA */
+			0x00030000,	/* DENALI_CTL_307_DATA */
+			0x000a001c,	/* DENALI_CTL_308_DATA */
+			0x000e0020,	/* DENALI_CTL_309_DATA */
+			0x00060018,	/* DENALI_CTL_310_DATA */
+			0x00000000,	/* DENALI_CTL_311_DATA */
+			0x00000000,	/* DENALI_CTL_312_DATA */
+			0x02000000,	/* DENALI_CTL_313_DATA */
+			0x00090305,	/* DENALI_CTL_314_DATA */
+			0x00050101,	/* DENALI_CTL_315_DATA */
+			0x00000000,	/* DENALI_CTL_316_DATA */
+			0x00000000,	/* DENALI_CTL_317_DATA */
+			0x00000000,	/* DENALI_CTL_318_DATA */
+			0x00000000,	/* DENALI_CTL_319_DATA */
+			0x00000000,	/* DENALI_CTL_320_DATA */
+			0x00000000,	/* DENALI_CTL_321_DATA */
+			0x00000000,	/* DENALI_CTL_322_DATA */
+			0x00000000,	/* DENALI_CTL_323_DATA */
+			0x01000001,	/* DENALI_CTL_324_DATA */
+			0x01010101,	/* DENALI_CTL_325_DATA */
+			0x01000101,	/* DENALI_CTL_326_DATA */
+			0x01000100,	/* DENALI_CTL_327_DATA */
+			0x00010001,	/* DENALI_CTL_328_DATA */
+			0x00010002,	/* DENALI_CTL_329_DATA */
+			0x00020100,	/* DENALI_CTL_330_DATA */
+			0x00000002	/* DENALI_CTL_331_DATA */
+		}
+	},
+	{
+		{
+			0x00000b00,	/* DENALI_PI_00_DATA */
+			0x00000000,	/* DENALI_PI_01_DATA */
+			0x000002ec,	/* DENALI_PI_02_DATA */
+			0x00000176,	/* DENALI_PI_03_DATA */
+			0x000030a0,	/* DENALI_PI_04_DATA */
+			0x00001850,	/* DENALI_PI_05_DATA */
+			0x00001840,	/* DENALI_PI_06_DATA */
+			0x01760c20,	/* DENALI_PI_07_DATA */
+			0x00000200,	/* DENALI_PI_08_DATA */
+			0x00000200,	/* DENALI_PI_09_DATA */
+			0x00000200,	/* DENALI_PI_10_DATA */
+			0x00000200,	/* DENALI_PI_11_DATA */
+			0x00001850,	/* DENALI_PI_12_DATA */
+			0x00000200,	/* DENALI_PI_13_DATA */
+			0x00000200,	/* DENALI_PI_14_DATA */
+			0x00000200,	/* DENALI_PI_15_DATA */
+			0x00000200,	/* DENALI_PI_16_DATA */
+			0x00000c20,	/* DENALI_PI_17_DATA */
+			0x00000200,	/* DENALI_PI_18_DATA */
+			0x00000200,	/* DENALI_PI_19_DATA */
+			0x00000200,	/* DENALI_PI_20_DATA */
+			0x00000200,	/* DENALI_PI_21_DATA */
+			0x00010000,	/* DENALI_PI_22_DATA */
+			0x00000007,	/* DENALI_PI_23_DATA */
+			0x01000001,	/* DENALI_PI_24_DATA */
+			0x00000000,	/* DENALI_PI_25_DATA */
+			0x3fffffff,	/* DENALI_PI_26_DATA */
+			0x00000000,	/* DENALI_PI_27_DATA */
+			0x00000000,	/* DENALI_PI_28_DATA */
+			0x00000000,	/* DENALI_PI_29_DATA */
+			0x00000000,	/* DENALI_PI_30_DATA */
+			0x00000000,	/* DENALI_PI_31_DATA */
+			0x00000000,	/* DENALI_PI_32_DATA */
+			0x00000000,	/* DENALI_PI_33_DATA */
+			0x00000000,	/* DENALI_PI_34_DATA */
+			0x00000000,	/* DENALI_PI_35_DATA */
+			0x00000000,	/* DENALI_PI_36_DATA */
+			0x00000000,	/* DENALI_PI_37_DATA */
+			0x00000000,	/* DENALI_PI_38_DATA */
+			0x00000000,	/* DENALI_PI_39_DATA */
+			0x00000000,	/* DENALI_PI_40_DATA */
+			0x0f000101,	/* DENALI_PI_41_DATA */
+			0x082b3223,	/* DENALI_PI_42_DATA */
+			0x080c0004,	/* DENALI_PI_43_DATA */
+			0x00061c00,	/* DENALI_PI_44_DATA */
+			0x00000214,	/* DENALI_PI_45_DATA */
+			0x00bb0007,	/* DENALI_PI_46_DATA */
+			0x0c280068,	/* DENALI_PI_47_DATA */
+			0x06100034,	/* DENALI_PI_48_DATA */
+			0x00000500,	/* DENALI_PI_49_DATA */
+			0x00000000,	/* DENALI_PI_50_DATA */
+			0x00000000,	/* DENALI_PI_51_DATA */
+			0x00000000,	/* DENALI_PI_52_DATA */
+			0x00000000,	/* DENALI_PI_53_DATA */
+			0x00000000,	/* DENALI_PI_54_DATA */
+			0x00000000,	/* DENALI_PI_55_DATA */
+			0x00000000,	/* DENALI_PI_56_DATA */
+			0x00000000,	/* DENALI_PI_57_DATA */
+			0x04040100,	/* DENALI_PI_58_DATA */
+			0x0a000004,	/* DENALI_PI_59_DATA */
+			0x00000128,	/* DENALI_PI_60_DATA */
+			0x00000000,	/* DENALI_PI_61_DATA */
+			0x0003000f,	/* DENALI_PI_62_DATA */
+			0x00000018,	/* DENALI_PI_63_DATA */
+			0x00000000,	/* DENALI_PI_64_DATA */
+			0x00000000,	/* DENALI_PI_65_DATA */
+			0x00060002,	/* DENALI_PI_66_DATA */
+			0x00010001,	/* DENALI_PI_67_DATA */
+			0x00000101,	/* DENALI_PI_68_DATA */
+			0x00020001,	/* DENALI_PI_69_DATA */
+			0x00080004,	/* DENALI_PI_70_DATA */
+			0x00000000,	/* DENALI_PI_71_DATA */
+			0x05030000,	/* DENALI_PI_72_DATA */
+			0x070a0404,	/* DENALI_PI_73_DATA */
+			0x00000000,	/* DENALI_PI_74_DATA */
+			0x00000000,	/* DENALI_PI_75_DATA */
+			0x00000000,	/* DENALI_PI_76_DATA */
+			0x000f0f00,	/* DENALI_PI_77_DATA */
+			0x0000001e,	/* DENALI_PI_78_DATA */
+			0x00000000,	/* DENALI_PI_79_DATA */
+			0x01010300,	/* DENALI_PI_80_DATA */
+			0x00000000,	/* DENALI_PI_81_DATA */
+			0x00000000,	/* DENALI_PI_82_DATA */
+			0x01000000,	/* DENALI_PI_83_DATA */
+			0x00000101,	/* DENALI_PI_84_DATA */
+			0x55555a5a,	/* DENALI_PI_85_DATA */
+			0x55555a5a,	/* DENALI_PI_86_DATA */
+			0x55555a5a,	/* DENALI_PI_87_DATA */
+			0x55555a5a,	/* DENALI_PI_88_DATA */
+			0x0c050001,	/* DENALI_PI_89_DATA */
+			0x06020009,	/* DENALI_PI_90_DATA */
+			0x00010004,	/* DENALI_PI_91_DATA */
+			0x00000203,	/* DENALI_PI_92_DATA */
+			0x00030000,	/* DENALI_PI_93_DATA */
+			0x170f0000,	/* DENALI_PI_94_DATA */
+			0x00060018,	/* DENALI_PI_95_DATA */
+			0x000e0020,	/* DENALI_PI_96_DATA */
+			0x000a001c,	/* DENALI_PI_97_DATA */
+			0x00000000,	/* DENALI_PI_98_DATA */
+			0x00000000,	/* DENALI_PI_99_DATA */
+			0x00000100,	/* DENALI_PI_100_DATA */
+			0x140a0000,	/* DENALI_PI_101_DATA */
+			0x000d010a,	/* DENALI_PI_102_DATA */
+			0x0100c802,	/* DENALI_PI_103_DATA */
+			0x010a0064,	/* DENALI_PI_104_DATA */
+			0x000e0100,	/* DENALI_PI_105_DATA */
+			0x0100000e,	/* DENALI_PI_106_DATA */
+			0x00c900c9,	/* DENALI_PI_107_DATA */
+			0x00650100,	/* DENALI_PI_108_DATA */
+			0x1e1a0065,	/* DENALI_PI_109_DATA */
+			0x10010204,	/* DENALI_PI_110_DATA */
+			0x06070605,	/* DENALI_PI_111_DATA */
+			0x20000202,	/* DENALI_PI_112_DATA */
+			0x00201000,	/* DENALI_PI_113_DATA */
+			0x00201000,	/* DENALI_PI_114_DATA */
+			0x04041000,	/* DENALI_PI_115_DATA */
+			0x10020100,	/* DENALI_PI_116_DATA */
+			0x0003010c,	/* DENALI_PI_117_DATA */
+			0x004b004a,	/* DENALI_PI_118_DATA */
+			0x1a0f0000,	/* DENALI_PI_119_DATA */
+			0x0102041e,	/* DENALI_PI_120_DATA */
+			0x34000000,	/* DENALI_PI_121_DATA */
+			0x00000000,	/* DENALI_PI_122_DATA */
+			0x00000000,	/* DENALI_PI_123_DATA */
+			0x00010000,	/* DENALI_PI_124_DATA */
+			0x00000400,	/* DENALI_PI_125_DATA */
+			0x00310000,	/* DENALI_PI_126_DATA */
+			0x004d4d00,	/* DENALI_PI_127_DATA */
+			0x00120024,	/* DENALI_PI_128_DATA */
+			0x4d000031,	/* DENALI_PI_129_DATA */
+			0x0000144d,	/* DENALI_PI_130_DATA */
+			0x00310009,	/* DENALI_PI_131_DATA */
+			0x004d4d00,	/* DENALI_PI_132_DATA */
+			0x00000004,	/* DENALI_PI_133_DATA */
+			0x4d000031,	/* DENALI_PI_134_DATA */
+			0x0000244d,	/* DENALI_PI_135_DATA */
+			0x00310012,	/* DENALI_PI_136_DATA */
+			0x004d4d00,	/* DENALI_PI_137_DATA */
+			0x00090014,	/* DENALI_PI_138_DATA */
+			0x4d000031,	/* DENALI_PI_139_DATA */
+			0x0004004d,	/* DENALI_PI_140_DATA */
+			0x00310000,	/* DENALI_PI_141_DATA */
+			0x004d4d00,	/* DENALI_PI_142_DATA */
+			0x00120024,	/* DENALI_PI_143_DATA */
+			0x4d000031,	/* DENALI_PI_144_DATA */
+			0x0000144d,	/* DENALI_PI_145_DATA */
+			0x00310009,	/* DENALI_PI_146_DATA */
+			0x004d4d00,	/* DENALI_PI_147_DATA */
+			0x00000004,	/* DENALI_PI_148_DATA */
+			0x4d000031,	/* DENALI_PI_149_DATA */
+			0x0000244d,	/* DENALI_PI_150_DATA */
+			0x00310012,	/* DENALI_PI_151_DATA */
+			0x004d4d00,	/* DENALI_PI_152_DATA */
+			0x00090014,	/* DENALI_PI_153_DATA */
+			0x4d000031,	/* DENALI_PI_154_DATA */
+			0x0200004d,	/* DENALI_PI_155_DATA */
+			0x00c8000d,	/* DENALI_PI_156_DATA */
+			0x08080064,	/* DENALI_PI_157_DATA */
+			0x040a0404,	/* DENALI_PI_158_DATA */
+			0x03000d92,	/* DENALI_PI_159_DATA */
+			0x010a2001,	/* DENALI_PI_160_DATA */
+			0x0f11080a,	/* DENALI_PI_161_DATA */
+			0x0000110a,	/* DENALI_PI_162_DATA */
+			0x2200d92e,	/* DENALI_PI_163_DATA */
+			0x080c2003,	/* DENALI_PI_164_DATA */
+			0x0809080a,	/* DENALI_PI_165_DATA */
+			0x00000a0a,	/* DENALI_PI_166_DATA */
+			0x11006c97,	/* DENALI_PI_167_DATA */
+			0x040a2002,	/* DENALI_PI_168_DATA */
+			0x0200020a,	/* DENALI_PI_169_DATA */
+			0x02000200,	/* DENALI_PI_170_DATA */
+			0x02000200,	/* DENALI_PI_171_DATA */
+			0x02000200,	/* DENALI_PI_172_DATA */
+			0x02000200,	/* DENALI_PI_173_DATA */
+			0x00000000,	/* DENALI_PI_174_DATA */
+			0x00000000,	/* DENALI_PI_175_DATA */
+			0x00000000,	/* DENALI_PI_176_DATA */
+			0x00000000,	/* DENALI_PI_177_DATA */
+			0x00000000,	/* DENALI_PI_178_DATA */
+			0x00000000,	/* DENALI_PI_179_DATA */
+			0x00000000,	/* DENALI_PI_180_DATA */
+			0x00000000,	/* DENALI_PI_181_DATA */
+			0x00000000,	/* DENALI_PI_182_DATA */
+			0x00000000,	/* DENALI_PI_183_DATA */
+			0x00000000,	/* DENALI_PI_184_DATA */
+			0x00000000,	/* DENALI_PI_185_DATA */
+			0x01000400,	/* DENALI_PI_186_DATA */
+			0x00017600,	/* DENALI_PI_187_DATA */
+			0x00000e9c,	/* DENALI_PI_188_DATA */
+			0x00001850,	/* DENALI_PI_189_DATA */
+			0x0000f320,	/* DENALI_PI_190_DATA */
+			0x00000c20,	/* DENALI_PI_191_DATA */
+			0x00007940,	/* DENALI_PI_192_DATA */
+			0x08000000,	/* DENALI_PI_193_DATA */
+			0x00000100,	/* DENALI_PI_194_DATA */
+			0x00000000,	/* DENALI_PI_195_DATA */
+			0x00000000,	/* DENALI_PI_196_DATA */
+			0x00000000,	/* DENALI_PI_197_DATA */
+			0x00000000,	/* DENALI_PI_198_DATA */
+			0x00000002	/* DENALI_PI_199_DATA */
+		}
+	},
+	{
+		{
+			0x76543210,	/* DENALI_PHY_00_DATA */
+			0x0004f008,	/* DENALI_PHY_01_DATA */
+			0x00020119,	/* DENALI_PHY_02_DATA */
+			0x00000000,	/* DENALI_PHY_03_DATA */
+			0x00000000,	/* DENALI_PHY_04_DATA */
+			0x00010000,	/* DENALI_PHY_05_DATA */
+			0x01665555,	/* DENALI_PHY_06_DATA */
+			0x03665555,	/* DENALI_PHY_07_DATA */
+			0x00010f00,	/* DENALI_PHY_08_DATA */
+			0x05010200,	/* DENALI_PHY_09_DATA */
+			0x00000002,	/* DENALI_PHY_10_DATA */
+			0x00170180,	/* DENALI_PHY_11_DATA */
+			0x00cc0201,	/* DENALI_PHY_12_DATA */
+			0x00030066,	/* DENALI_PHY_13_DATA */
+			0x00000000,	/* DENALI_PHY_14_DATA */
+			0x00000000,	/* DENALI_PHY_15_DATA */
+			0x00000000,	/* DENALI_PHY_16_DATA */
+			0x00000000,	/* DENALI_PHY_17_DATA */
+			0x00000000,	/* DENALI_PHY_18_DATA */
+			0x00000000,	/* DENALI_PHY_19_DATA */
+			0x00000000,	/* DENALI_PHY_20_DATA */
+			0x00000000,	/* DENALI_PHY_21_DATA */
+			0x04080000,	/* DENALI_PHY_22_DATA */
+			0x04080400,	/* DENALI_PHY_23_DATA */
+			0x30000000,	/* DENALI_PHY_24_DATA */
+			0x0c00c007,	/* DENALI_PHY_25_DATA */
+			0x00000100,	/* DENALI_PHY_26_DATA */
+			0x00000000,	/* DENALI_PHY_27_DATA */
+			0xfd02fe01,	/* DENALI_PHY_28_DATA */
+			0xf708fb04,	/* DENALI_PHY_29_DATA */
+			0xdf20ef10,	/* DENALI_PHY_30_DATA */
+			0x7f80bf40,	/* DENALI_PHY_31_DATA */
+			0x0001aaaa,	/* DENALI_PHY_32_DATA */
+			0x00000000,	/* DENALI_PHY_33_DATA */
+			0x00000000,	/* DENALI_PHY_34_DATA */
+			0x00000000,	/* DENALI_PHY_35_DATA */
+			0x00000000,	/* DENALI_PHY_36_DATA */
+			0x00000000,	/* DENALI_PHY_37_DATA */
+			0x00000000,	/* DENALI_PHY_38_DATA */
+			0x00000000,	/* DENALI_PHY_39_DATA */
+			0x00000000,	/* DENALI_PHY_40_DATA */
+			0x00000000,	/* DENALI_PHY_41_DATA */
+			0x00000000,	/* DENALI_PHY_42_DATA */
+			0x00000000,	/* DENALI_PHY_43_DATA */
+			0x00000000,	/* DENALI_PHY_44_DATA */
+			0x00000000,	/* DENALI_PHY_45_DATA */
+			0x00000000,	/* DENALI_PHY_46_DATA */
+			0x00000000,	/* DENALI_PHY_47_DATA */
+			0x00000000,	/* DENALI_PHY_48_DATA */
+			0x00000000,	/* DENALI_PHY_49_DATA */
+			0x00000000,	/* DENALI_PHY_50_DATA */
+			0x00000000,	/* DENALI_PHY_51_DATA */
+			0x00200000,	/* DENALI_PHY_52_DATA */
+			0x00000000,	/* DENALI_PHY_53_DATA */
+			0x00000000,	/* DENALI_PHY_54_DATA */
+			0x00000000,	/* DENALI_PHY_55_DATA */
+			0x00000000,	/* DENALI_PHY_56_DATA */
+			0x00000000,	/* DENALI_PHY_57_DATA */
+			0x00000000,	/* DENALI_PHY_58_DATA */
+			0x02800280,	/* DENALI_PHY_59_DATA */
+			0x02800280,	/* DENALI_PHY_60_DATA */
+			0x02800280,	/* DENALI_PHY_61_DATA */
+			0x02800280,	/* DENALI_PHY_62_DATA */
+			0x00000280,	/* DENALI_PHY_63_DATA */
+			0x00000000,	/* DENALI_PHY_64_DATA */
+			0x00000000,	/* DENALI_PHY_65_DATA */
+			0x00000000,	/* DENALI_PHY_66_DATA */
+			0x00000000,	/* DENALI_PHY_67_DATA */
+			0x00800000,	/* DENALI_PHY_68_DATA */
+			0x00800080,	/* DENALI_PHY_69_DATA */
+			0x00800080,	/* DENALI_PHY_70_DATA */
+			0x00800080,	/* DENALI_PHY_71_DATA */
+			0x00800080,	/* DENALI_PHY_72_DATA */
+			0x00800080,	/* DENALI_PHY_73_DATA */
+			0x00800080,	/* DENALI_PHY_74_DATA */
+			0x00800080,	/* DENALI_PHY_75_DATA */
+			0x00800080,	/* DENALI_PHY_76_DATA */
+			0x01190080,	/* DENALI_PHY_77_DATA */
+			0x00000002,	/* DENALI_PHY_78_DATA */
+			0x00000000,	/* DENALI_PHY_79_DATA */
+			0x00000000,	/* DENALI_PHY_80_DATA */
+			0x00000200,	/* DENALI_PHY_81_DATA */
+			0x00000000,	/* DENALI_PHY_82_DATA */
+			0x51315152,	/* DENALI_PHY_83_DATA */
+			0xc0013150,	/* DENALI_PHY_84_DATA */
+			0x020000c0,	/* DENALI_PHY_85_DATA */
+			0x00100001,	/* DENALI_PHY_86_DATA */
+			0x07054204,	/* DENALI_PHY_87_DATA */
+			0x000f0c18,	/* DENALI_PHY_88_DATA */
+			0x01000140,	/* DENALI_PHY_89_DATA */
+			0x00000c10,	/* DENALI_PHY_90_DATA */
+			0x00000000,	/* DENALI_PHY_91_DATA */
+			0x00000000,	/* DENALI_PHY_92_DATA */
+			0x00000000,	/* DENALI_PHY_93_DATA */
+			0x00000000,	/* DENALI_PHY_94_DATA */
+			0x00000000,	/* DENALI_PHY_95_DATA */
+			0x00000000,	/* DENALI_PHY_96_DATA */
+			0x00000000,	/* DENALI_PHY_97_DATA */
+			0x00000000,	/* DENALI_PHY_98_DATA */
+			0x00000000,	/* DENALI_PHY_99_DATA */
+			0x00000000,	/* DENALI_PHY_100_DATA */
+			0x00000000,	/* DENALI_PHY_101_DATA */
+			0x00000000,	/* DENALI_PHY_102_DATA */
+			0x00000000,	/* DENALI_PHY_103_DATA */
+			0x00000000,	/* DENALI_PHY_104_DATA */
+			0x00000000,	/* DENALI_PHY_105_DATA */
+			0x00000000,	/* DENALI_PHY_106_DATA */
+			0x00000000,	/* DENALI_PHY_107_DATA */
+			0x00000000,	/* DENALI_PHY_108_DATA */
+			0x00000000,	/* DENALI_PHY_109_DATA */
+			0x00000000,	/* DENALI_PHY_110_DATA */
+			0x00000000,	/* DENALI_PHY_111_DATA */
+			0x00000000,	/* DENALI_PHY_112_DATA */
+			0x00000000,	/* DENALI_PHY_113_DATA */
+			0x00000000,	/* DENALI_PHY_114_DATA */
+			0x00000000,	/* DENALI_PHY_115_DATA */
+			0x00000000,	/* DENALI_PHY_116_DATA */
+			0x00000000,	/* DENALI_PHY_117_DATA */
+			0x00000000,	/* DENALI_PHY_118_DATA */
+			0x00000000,	/* DENALI_PHY_119_DATA */
+			0x00000000,	/* DENALI_PHY_120_DATA */
+			0x00000000,	/* DENALI_PHY_121_DATA */
+			0x00000000,	/* DENALI_PHY_122_DATA */
+			0x00000000,	/* DENALI_PHY_123_DATA */
+			0x00000000,	/* DENALI_PHY_124_DATA */
+			0x00000000,	/* DENALI_PHY_125_DATA */
+			0x00000000,	/* DENALI_PHY_126_DATA */
+			0x00000000,	/* DENALI_PHY_127_DATA */
+			0x76543210,	/* DENALI_PHY_128_DATA */
+			0x0004f008,	/* DENALI_PHY_129_DATA */
+			0x00020119,	/* DENALI_PHY_130_DATA */
+			0x00000000,	/* DENALI_PHY_131_DATA */
+			0x00000000,	/* DENALI_PHY_132_DATA */
+			0x00010000,	/* DENALI_PHY_133_DATA */
+			0x01665555,	/* DENALI_PHY_134_DATA */
+			0x03665555,	/* DENALI_PHY_135_DATA */
+			0x00010f00,	/* DENALI_PHY_136_DATA */
+			0x05010200,	/* DENALI_PHY_137_DATA */
+			0x00000002,	/* DENALI_PHY_138_DATA */
+			0x00170180,	/* DENALI_PHY_139_DATA */
+			0x00cc0201,	/* DENALI_PHY_140_DATA */
+			0x00030066,	/* DENALI_PHY_141_DATA */
+			0x00000000,	/* DENALI_PHY_142_DATA */
+			0x00000000,	/* DENALI_PHY_143_DATA */
+			0x00000000,	/* DENALI_PHY_144_DATA */
+			0x00000000,	/* DENALI_PHY_145_DATA */
+			0x00000000,	/* DENALI_PHY_146_DATA */
+			0x00000000,	/* DENALI_PHY_147_DATA */
+			0x00000000,	/* DENALI_PHY_148_DATA */
+			0x00000000,	/* DENALI_PHY_149_DATA */
+			0x04080000,	/* DENALI_PHY_150_DATA */
+			0x04080400,	/* DENALI_PHY_151_DATA */
+			0x30000000,	/* DENALI_PHY_152_DATA */
+			0x0c00c007,	/* DENALI_PHY_153_DATA */
+			0x00000100,	/* DENALI_PHY_154_DATA */
+			0x00000000,	/* DENALI_PHY_155_DATA */
+			0xfd02fe01,	/* DENALI_PHY_156_DATA */
+			0xf708fb04,	/* DENALI_PHY_157_DATA */
+			0xdf20ef10,	/* DENALI_PHY_158_DATA */
+			0x7f80bf40,	/* DENALI_PHY_159_DATA */
+			0x0000aaaa,	/* DENALI_PHY_160_DATA */
+			0x00000000,	/* DENALI_PHY_161_DATA */
+			0x00000000,	/* DENALI_PHY_162_DATA */
+			0x00000000,	/* DENALI_PHY_163_DATA */
+			0x00000000,	/* DENALI_PHY_164_DATA */
+			0x00000000,	/* DENALI_PHY_165_DATA */
+			0x00000000,	/* DENALI_PHY_166_DATA */
+			0x00000000,	/* DENALI_PHY_167_DATA */
+			0x00000000,	/* DENALI_PHY_168_DATA */
+			0x00000000,	/* DENALI_PHY_169_DATA */
+			0x00000000,	/* DENALI_PHY_170_DATA */
+			0x00000000,	/* DENALI_PHY_171_DATA */
+			0x00000000,	/* DENALI_PHY_172_DATA */
+			0x00000000,	/* DENALI_PHY_173_DATA */
+			0x00000000,	/* DENALI_PHY_174_DATA */
+			0x00000000,	/* DENALI_PHY_175_DATA */
+			0x00000000,	/* DENALI_PHY_176_DATA */
+			0x00000000,	/* DENALI_PHY_177_DATA */
+			0x00000000,	/* DENALI_PHY_178_DATA */
+			0x00000000,	/* DENALI_PHY_179_DATA */
+			0x00200000,	/* DENALI_PHY_180_DATA */
+			0x00000000,	/* DENALI_PHY_181_DATA */
+			0x00000000,	/* DENALI_PHY_182_DATA */
+			0x00000000,	/* DENALI_PHY_183_DATA */
+			0x00000000,	/* DENALI_PHY_184_DATA */
+			0x00000000,	/* DENALI_PHY_185_DATA */
+			0x00000000,	/* DENALI_PHY_186_DATA */
+			0x02800280,	/* DENALI_PHY_187_DATA */
+			0x02800280,	/* DENALI_PHY_188_DATA */
+			0x02800280,	/* DENALI_PHY_189_DATA */
+			0x02800280,	/* DENALI_PHY_190_DATA */
+			0x00000280,	/* DENALI_PHY_191_DATA */
+			0x00000000,	/* DENALI_PHY_192_DATA */
+			0x00000000,	/* DENALI_PHY_193_DATA */
+			0x00000000,	/* DENALI_PHY_194_DATA */
+			0x00000000,	/* DENALI_PHY_195_DATA */
+			0x00800000,	/* DENALI_PHY_196_DATA */
+			0x00800080,	/* DENALI_PHY_197_DATA */
+			0x00800080,	/* DENALI_PHY_198_DATA */
+			0x00800080,	/* DENALI_PHY_199_DATA */
+			0x00800080,	/* DENALI_PHY_200_DATA */
+			0x00800080,	/* DENALI_PHY_201_DATA */
+			0x00800080,	/* DENALI_PHY_202_DATA */
+			0x00800080,	/* DENALI_PHY_203_DATA */
+			0x00800080,	/* DENALI_PHY_204_DATA */
+			0x01190080,	/* DENALI_PHY_205_DATA */
+			0x00000002,	/* DENALI_PHY_206_DATA */
+			0x00000000,	/* DENALI_PHY_207_DATA */
+			0x00000000,	/* DENALI_PHY_208_DATA */
+			0x00000200,	/* DENALI_PHY_209_DATA */
+			0x00000000,	/* DENALI_PHY_210_DATA */
+			0x51315152,	/* DENALI_PHY_211_DATA */
+			0xc0013150,	/* DENALI_PHY_212_DATA */
+			0x020000c0,	/* DENALI_PHY_213_DATA */
+			0x00100001,	/* DENALI_PHY_214_DATA */
+			0x07054204,	/* DENALI_PHY_215_DATA */
+			0x000f0c18,	/* DENALI_PHY_216_DATA */
+			0x01000140,	/* DENALI_PHY_217_DATA */
+			0x00000c10,	/* DENALI_PHY_218_DATA */
+			0x00000000,	/* DENALI_PHY_219_DATA */
+			0x00000000,	/* DENALI_PHY_220_DATA */
+			0x00000000,	/* DENALI_PHY_221_DATA */
+			0x00000000,	/* DENALI_PHY_222_DATA */
+			0x00000000,	/* DENALI_PHY_223_DATA */
+			0x00000000,	/* DENALI_PHY_224_DATA */
+			0x00000000,	/* DENALI_PHY_225_DATA */
+			0x00000000,	/* DENALI_PHY_226_DATA */
+			0x00000000,	/* DENALI_PHY_227_DATA */
+			0x00000000,	/* DENALI_PHY_228_DATA */
+			0x00000000,	/* DENALI_PHY_229_DATA */
+			0x00000000,	/* DENALI_PHY_230_DATA */
+			0x00000000,	/* DENALI_PHY_231_DATA */
+			0x00000000,	/* DENALI_PHY_232_DATA */
+			0x00000000,	/* DENALI_PHY_233_DATA */
+			0x00000000,	/* DENALI_PHY_234_DATA */
+			0x00000000,	/* DENALI_PHY_235_DATA */
+			0x00000000,	/* DENALI_PHY_236_DATA */
+			0x00000000,	/* DENALI_PHY_237_DATA */
+			0x00000000,	/* DENALI_PHY_238_DATA */
+			0x00000000,	/* DENALI_PHY_239_DATA */
+			0x00000000,	/* DENALI_PHY_240_DATA */
+			0x00000000,	/* DENALI_PHY_241_DATA */
+			0x00000000,	/* DENALI_PHY_242_DATA */
+			0x00000000,	/* DENALI_PHY_243_DATA */
+			0x00000000,	/* DENALI_PHY_244_DATA */
+			0x00000000,	/* DENALI_PHY_245_DATA */
+			0x00000000,	/* DENALI_PHY_246_DATA */
+			0x00000000,	/* DENALI_PHY_247_DATA */
+			0x00000000,	/* DENALI_PHY_248_DATA */
+			0x00000000,	/* DENALI_PHY_249_DATA */
+			0x00000000,	/* DENALI_PHY_250_DATA */
+			0x00000000,	/* DENALI_PHY_251_DATA */
+			0x00000000,	/* DENALI_PHY_252_DATA */
+			0x00000000,	/* DENALI_PHY_253_DATA */
+			0x00000000,	/* DENALI_PHY_254_DATA */
+			0x00000000,	/* DENALI_PHY_255_DATA */
+			0x76543210,	/* DENALI_PHY_256_DATA */
+			0x0004f008,	/* DENALI_PHY_257_DATA */
+			0x00020119,	/* DENALI_PHY_258_DATA */
+			0x00000000,	/* DENALI_PHY_259_DATA */
+			0x00000000,	/* DENALI_PHY_260_DATA */
+			0x00010000,	/* DENALI_PHY_261_DATA */
+			0x01665555,	/* DENALI_PHY_262_DATA */
+			0x03665555,	/* DENALI_PHY_263_DATA */
+			0x00010f00,	/* DENALI_PHY_264_DATA */
+			0x05010200,	/* DENALI_PHY_265_DATA */
+			0x00000002,	/* DENALI_PHY_266_DATA */
+			0x00170180,	/* DENALI_PHY_267_DATA */
+			0x00cc0201,	/* DENALI_PHY_268_DATA */
+			0x00030066,	/* DENALI_PHY_269_DATA */
+			0x00000000,	/* DENALI_PHY_270_DATA */
+			0x00000000,	/* DENALI_PHY_271_DATA */
+			0x00000000,	/* DENALI_PHY_272_DATA */
+			0x00000000,	/* DENALI_PHY_273_DATA */
+			0x00000000,	/* DENALI_PHY_274_DATA */
+			0x00000000,	/* DENALI_PHY_275_DATA */
+			0x00000000,	/* DENALI_PHY_276_DATA */
+			0x00000000,	/* DENALI_PHY_277_DATA */
+			0x04080000,	/* DENALI_PHY_278_DATA */
+			0x04080400,	/* DENALI_PHY_279_DATA */
+			0x30000000,	/* DENALI_PHY_280_DATA */
+			0x0c00c007,	/* DENALI_PHY_281_DATA */
+			0x00000100,	/* DENALI_PHY_282_DATA */
+			0x00000000,	/* DENALI_PHY_283_DATA */
+			0xfd02fe01,	/* DENALI_PHY_284_DATA */
+			0xf708fb04,	/* DENALI_PHY_285_DATA */
+			0xdf20ef10,	/* DENALI_PHY_286_DATA */
+			0x7f80bf40,	/* DENALI_PHY_287_DATA */
+			0x0001aaaa,	/* DENALI_PHY_288_DATA */
+			0x00000000,	/* DENALI_PHY_289_DATA */
+			0x00000000,	/* DENALI_PHY_290_DATA */
+			0x00000000,	/* DENALI_PHY_291_DATA */
+			0x00000000,	/* DENALI_PHY_292_DATA */
+			0x00000000,	/* DENALI_PHY_293_DATA */
+			0x00000000,	/* DENALI_PHY_294_DATA */
+			0x00000000,	/* DENALI_PHY_295_DATA */
+			0x00000000,	/* DENALI_PHY_296_DATA */
+			0x00000000,	/* DENALI_PHY_297_DATA */
+			0x00000000,	/* DENALI_PHY_298_DATA */
+			0x00000000,	/* DENALI_PHY_299_DATA */
+			0x00000000,	/* DENALI_PHY_300_DATA */
+			0x00000000,	/* DENALI_PHY_301_DATA */
+			0x00000000,	/* DENALI_PHY_302_DATA */
+			0x00000000,	/* DENALI_PHY_303_DATA */
+			0x00000000,	/* DENALI_PHY_304_DATA */
+			0x00000000,	/* DENALI_PHY_305_DATA */
+			0x00000000,	/* DENALI_PHY_306_DATA */
+			0x00000000,	/* DENALI_PHY_307_DATA */
+			0x00200000,	/* DENALI_PHY_308_DATA */
+			0x00000000,	/* DENALI_PHY_309_DATA */
+			0x00000000,	/* DENALI_PHY_310_DATA */
+			0x00000000,	/* DENALI_PHY_311_DATA */
+			0x00000000,	/* DENALI_PHY_312_DATA */
+			0x00000000,	/* DENALI_PHY_313_DATA */
+			0x00000000,	/* DENALI_PHY_314_DATA */
+			0x02800280,	/* DENALI_PHY_315_DATA */
+			0x02800280,	/* DENALI_PHY_316_DATA */
+			0x02800280,	/* DENALI_PHY_317_DATA */
+			0x02800280,	/* DENALI_PHY_318_DATA */
+			0x00000280,	/* DENALI_PHY_319_DATA */
+			0x00000000,	/* DENALI_PHY_320_DATA */
+			0x00000000,	/* DENALI_PHY_321_DATA */
+			0x00000000,	/* DENALI_PHY_322_DATA */
+			0x00000000,	/* DENALI_PHY_323_DATA */
+			0x00800000,	/* DENALI_PHY_324_DATA */
+			0x00800080,	/* DENALI_PHY_325_DATA */
+			0x00800080,	/* DENALI_PHY_326_DATA */
+			0x00800080,	/* DENALI_PHY_327_DATA */
+			0x00800080,	/* DENALI_PHY_328_DATA */
+			0x00800080,	/* DENALI_PHY_329_DATA */
+			0x00800080,	/* DENALI_PHY_330_DATA */
+			0x00800080,	/* DENALI_PHY_331_DATA */
+			0x00800080,	/* DENALI_PHY_332_DATA */
+			0x01190080,	/* DENALI_PHY_333_DATA */
+			0x00000002,	/* DENALI_PHY_334_DATA */
+			0x00000000,	/* DENALI_PHY_335_DATA */
+			0x00000000,	/* DENALI_PHY_336_DATA */
+			0x00000200,	/* DENALI_PHY_337_DATA */
+			0x00000000,	/* DENALI_PHY_338_DATA */
+			0x51315152,	/* DENALI_PHY_339_DATA */
+			0xc0013150,	/* DENALI_PHY_340_DATA */
+			0x020000c0,	/* DENALI_PHY_341_DATA */
+			0x00100001,	/* DENALI_PHY_342_DATA */
+			0x07054204,	/* DENALI_PHY_343_DATA */
+			0x000f0c18,	/* DENALI_PHY_344_DATA */
+			0x01000140,	/* DENALI_PHY_345_DATA */
+			0x00000c10,	/* DENALI_PHY_346_DATA */
+			0x00000000,	/* DENALI_PHY_347_DATA */
+			0x00000000,	/* DENALI_PHY_348_DATA */
+			0x00000000,	/* DENALI_PHY_349_DATA */
+			0x00000000,	/* DENALI_PHY_350_DATA */
+			0x00000000,	/* DENALI_PHY_351_DATA */
+			0x00000000,	/* DENALI_PHY_352_DATA */
+			0x00000000,	/* DENALI_PHY_353_DATA */
+			0x00000000,	/* DENALI_PHY_354_DATA */
+			0x00000000,	/* DENALI_PHY_355_DATA */
+			0x00000000,	/* DENALI_PHY_356_DATA */
+			0x00000000,	/* DENALI_PHY_357_DATA */
+			0x00000000,	/* DENALI_PHY_358_DATA */
+			0x00000000,	/* DENALI_PHY_359_DATA */
+			0x00000000,	/* DENALI_PHY_360_DATA */
+			0x00000000,	/* DENALI_PHY_361_DATA */
+			0x00000000,	/* DENALI_PHY_362_DATA */
+			0x00000000,	/* DENALI_PHY_363_DATA */
+			0x00000000,	/* DENALI_PHY_364_DATA */
+			0x00000000,	/* DENALI_PHY_365_DATA */
+			0x00000000,	/* DENALI_PHY_366_DATA */
+			0x00000000,	/* DENALI_PHY_367_DATA */
+			0x00000000,	/* DENALI_PHY_368_DATA */
+			0x00000000,	/* DENALI_PHY_369_DATA */
+			0x00000000,	/* DENALI_PHY_370_DATA */
+			0x00000000,	/* DENALI_PHY_371_DATA */
+			0x00000000,	/* DENALI_PHY_372_DATA */
+			0x00000000,	/* DENALI_PHY_373_DATA */
+			0x00000000,	/* DENALI_PHY_374_DATA */
+			0x00000000,	/* DENALI_PHY_375_DATA */
+			0x00000000,	/* DENALI_PHY_376_DATA */
+			0x00000000,	/* DENALI_PHY_377_DATA */
+			0x00000000,	/* DENALI_PHY_378_DATA */
+			0x00000000,	/* DENALI_PHY_379_DATA */
+			0x00000000,	/* DENALI_PHY_380_DATA */
+			0x00000000,	/* DENALI_PHY_381_DATA */
+			0x00000000,	/* DENALI_PHY_382_DATA */
+			0x00000000,	/* DENALI_PHY_383_DATA */
+			0x76543210,	/* DENALI_PHY_384_DATA */
+			0x0004f008,	/* DENALI_PHY_385_DATA */
+			0x00020119,	/* DENALI_PHY_386_DATA */
+			0x00000000,	/* DENALI_PHY_387_DATA */
+			0x00000000,	/* DENALI_PHY_388_DATA */
+			0x00010000,	/* DENALI_PHY_389_DATA */
+			0x01665555,	/* DENALI_PHY_390_DATA */
+			0x03665555,	/* DENALI_PHY_391_DATA */
+			0x00010f00,	/* DENALI_PHY_392_DATA */
+			0x05010200,	/* DENALI_PHY_393_DATA */
+			0x00000002,	/* DENALI_PHY_394_DATA */
+			0x00170180,	/* DENALI_PHY_395_DATA */
+			0x00cc0201,	/* DENALI_PHY_396_DATA */
+			0x00030066,	/* DENALI_PHY_397_DATA */
+			0x00000000,	/* DENALI_PHY_398_DATA */
+			0x00000000,	/* DENALI_PHY_399_DATA */
+			0x00000000,	/* DENALI_PHY_400_DATA */
+			0x00000000,	/* DENALI_PHY_401_DATA */
+			0x00000000,	/* DENALI_PHY_402_DATA */
+			0x00000000,	/* DENALI_PHY_403_DATA */
+			0x00000000,	/* DENALI_PHY_404_DATA */
+			0x00000000,	/* DENALI_PHY_405_DATA */
+			0x04080000,	/* DENALI_PHY_406_DATA */
+			0x04080400,	/* DENALI_PHY_407_DATA */
+			0x30000000,	/* DENALI_PHY_408_DATA */
+			0x0c00c007,	/* DENALI_PHY_409_DATA */
+			0x00000100,	/* DENALI_PHY_410_DATA */
+			0x00000000,	/* DENALI_PHY_411_DATA */
+			0xfd02fe01,	/* DENALI_PHY_412_DATA */
+			0xf708fb04,	/* DENALI_PHY_413_DATA */
+			0xdf20ef10,	/* DENALI_PHY_414_DATA */
+			0x7f80bf40,	/* DENALI_PHY_415_DATA */
+			0x0000aaaa,	/* DENALI_PHY_416_DATA */
+			0x00000000,	/* DENALI_PHY_417_DATA */
+			0x00000000,	/* DENALI_PHY_418_DATA */
+			0x00000000,	/* DENALI_PHY_419_DATA */
+			0x00000000,	/* DENALI_PHY_420_DATA */
+			0x00000000,	/* DENALI_PHY_421_DATA */
+			0x00000000,	/* DENALI_PHY_422_DATA */
+			0x00000000,	/* DENALI_PHY_423_DATA */
+			0x00000000,	/* DENALI_PHY_424_DATA */
+			0x00000000,	/* DENALI_PHY_425_DATA */
+			0x00000000,	/* DENALI_PHY_426_DATA */
+			0x00000000,	/* DENALI_PHY_427_DATA */
+			0x00000000,	/* DENALI_PHY_428_DATA */
+			0x00000000,	/* DENALI_PHY_429_DATA */
+			0x00000000,	/* DENALI_PHY_430_DATA */
+			0x00000000,	/* DENALI_PHY_431_DATA */
+			0x00000000,	/* DENALI_PHY_432_DATA */
+			0x00000000,	/* DENALI_PHY_433_DATA */
+			0x00000000,	/* DENALI_PHY_434_DATA */
+			0x00000000,	/* DENALI_PHY_435_DATA */
+			0x00200000,	/* DENALI_PHY_436_DATA */
+			0x00000000,	/* DENALI_PHY_437_DATA */
+			0x00000000,	/* DENALI_PHY_438_DATA */
+			0x00000000,	/* DENALI_PHY_439_DATA */
+			0x00000000,	/* DENALI_PHY_440_DATA */
+			0x00000000,	/* DENALI_PHY_441_DATA */
+			0x00000000,	/* DENALI_PHY_442_DATA */
+			0x02800280,	/* DENALI_PHY_443_DATA */
+			0x02800280,	/* DENALI_PHY_444_DATA */
+			0x02800280,	/* DENALI_PHY_445_DATA */
+			0x02800280,	/* DENALI_PHY_446_DATA */
+			0x00000280,	/* DENALI_PHY_447_DATA */
+			0x00000000,	/* DENALI_PHY_448_DATA */
+			0x00000000,	/* DENALI_PHY_449_DATA */
+			0x00000000,	/* DENALI_PHY_450_DATA */
+			0x00000000,	/* DENALI_PHY_451_DATA */
+			0x00800000,	/* DENALI_PHY_452_DATA */
+			0x00800080,	/* DENALI_PHY_453_DATA */
+			0x00800080,	/* DENALI_PHY_454_DATA */
+			0x00800080,	/* DENALI_PHY_455_DATA */
+			0x00800080,	/* DENALI_PHY_456_DATA */
+			0x00800080,	/* DENALI_PHY_457_DATA */
+			0x00800080,	/* DENALI_PHY_458_DATA */
+			0x00800080,	/* DENALI_PHY_459_DATA */
+			0x00800080,	/* DENALI_PHY_460_DATA */
+			0x01190080,	/* DENALI_PHY_461_DATA */
+			0x00000002,	/* DENALI_PHY_462_DATA */
+			0x00000000,	/* DENALI_PHY_463_DATA */
+			0x00000000,	/* DENALI_PHY_464_DATA */
+			0x00000200,	/* DENALI_PHY_465_DATA */
+			0x00000000,	/* DENALI_PHY_466_DATA */
+			0x51315152,	/* DENALI_PHY_467_DATA */
+			0xc0013150,	/* DENALI_PHY_468_DATA */
+			0x020000c0,	/* DENALI_PHY_469_DATA */
+			0x00100001,	/* DENALI_PHY_470_DATA */
+			0x07054204,	/* DENALI_PHY_471_DATA */
+			0x000f0c18,	/* DENALI_PHY_472_DATA */
+			0x01000140,	/* DENALI_PHY_473_DATA */
+			0x00000c10,	/* DENALI_PHY_474_DATA */
+			0x00000000,	/* DENALI_PHY_475_DATA */
+			0x00000000,	/* DENALI_PHY_476_DATA */
+			0x00000000,	/* DENALI_PHY_477_DATA */
+			0x00000000,	/* DENALI_PHY_478_DATA */
+			0x00000000,	/* DENALI_PHY_479_DATA */
+			0x00000000,	/* DENALI_PHY_480_DATA */
+			0x00000000,	/* DENALI_PHY_481_DATA */
+			0x00000000,	/* DENALI_PHY_482_DATA */
+			0x00000000,	/* DENALI_PHY_483_DATA */
+			0x00000000,	/* DENALI_PHY_484_DATA */
+			0x00000000,	/* DENALI_PHY_485_DATA */
+			0x00000000,	/* DENALI_PHY_486_DATA */
+			0x00000000,	/* DENALI_PHY_487_DATA */
+			0x00000000,	/* DENALI_PHY_488_DATA */
+			0x00000000,	/* DENALI_PHY_489_DATA */
+			0x00000000,	/* DENALI_PHY_490_DATA */
+			0x00000000,	/* DENALI_PHY_491_DATA */
+			0x00000000,	/* DENALI_PHY_492_DATA */
+			0x00000000,	/* DENALI_PHY_493_DATA */
+			0x00000000,	/* DENALI_PHY_494_DATA */
+			0x00000000,	/* DENALI_PHY_495_DATA */
+			0x00000000,	/* DENALI_PHY_496_DATA */
+			0x00000000,	/* DENALI_PHY_497_DATA */
+			0x00000000,	/* DENALI_PHY_498_DATA */
+			0x00000000,	/* DENALI_PHY_499_DATA */
+			0x00000000,	/* DENALI_PHY_500_DATA */
+			0x00000000,	/* DENALI_PHY_501_DATA */
+			0x00000000,	/* DENALI_PHY_502_DATA */
+			0x00000000,	/* DENALI_PHY_503_DATA */
+			0x00000000,	/* DENALI_PHY_504_DATA */
+			0x00000000,	/* DENALI_PHY_505_DATA */
+			0x00000000,	/* DENALI_PHY_506_DATA */
+			0x00000000,	/* DENALI_PHY_507_DATA */
+			0x00000000,	/* DENALI_PHY_508_DATA */
+			0x00000000,	/* DENALI_PHY_509_DATA */
+			0x00000000,	/* DENALI_PHY_510_DATA */
+			0x00000000,	/* DENALI_PHY_511_DATA */
+			0x00000000,	/* DENALI_PHY_512_DATA */
+			0x00000000,	/* DENALI_PHY_513_DATA */
+			0x00000000,	/* DENALI_PHY_514_DATA */
+			0x00000000,	/* DENALI_PHY_515_DATA */
+			0x00000000,	/* DENALI_PHY_516_DATA */
+			0x00000000,	/* DENALI_PHY_517_DATA */
+			0x00000000,	/* DENALI_PHY_518_DATA */
+			0x00000002,	/* DENALI_PHY_519_DATA */
+			0x00000000,	/* DENALI_PHY_520_DATA */
+			0x00000000,	/* DENALI_PHY_521_DATA */
+			0x00000000,	/* DENALI_PHY_522_DATA */
+			0x00400320,	/* DENALI_PHY_523_DATA */
+			0x00000040,	/* DENALI_PHY_524_DATA */
+			0x00dcba98,	/* DENALI_PHY_525_DATA */
+			0x00000000,	/* DENALI_PHY_526_DATA */
+			0x00dcba98,	/* DENALI_PHY_527_DATA */
+			0x01000000,	/* DENALI_PHY_528_DATA */
+			0x00020003,	/* DENALI_PHY_529_DATA */
+			0x00000000,	/* DENALI_PHY_530_DATA */
+			0x00000000,	/* DENALI_PHY_531_DATA */
+			0x00000000,	/* DENALI_PHY_532_DATA */
+			0x0000002a,	/* DENALI_PHY_533_DATA */
+			0x00000015,	/* DENALI_PHY_534_DATA */
+			0x00000015,	/* DENALI_PHY_535_DATA */
+			0x0000002a,	/* DENALI_PHY_536_DATA */
+			0x00000033,	/* DENALI_PHY_537_DATA */
+			0x0000000c,	/* DENALI_PHY_538_DATA */
+			0x0000000c,	/* DENALI_PHY_539_DATA */
+			0x00000033,	/* DENALI_PHY_540_DATA */
+			0x0a418820,	/* DENALI_PHY_541_DATA */
+			0x003f0000,	/* DENALI_PHY_542_DATA */
+			0x0000003f,	/* DENALI_PHY_543_DATA */
+			0x00030055,	/* DENALI_PHY_544_DATA */
+			0x03000300,	/* DENALI_PHY_545_DATA */
+			0x03000300,	/* DENALI_PHY_546_DATA */
+			0x00000300,	/* DENALI_PHY_547_DATA */
+			0x42080010,	/* DENALI_PHY_548_DATA */
+			0x00000003,	/* DENALI_PHY_549_DATA */
+			0x00000000,	/* DENALI_PHY_550_DATA */
+			0x00000000,	/* DENALI_PHY_551_DATA */
+			0x00000000,	/* DENALI_PHY_552_DATA */
+			0x00000000,	/* DENALI_PHY_553_DATA */
+			0x00000000,	/* DENALI_PHY_554_DATA */
+			0x00000000,	/* DENALI_PHY_555_DATA */
+			0x00000000,	/* DENALI_PHY_556_DATA */
+			0x00000000,	/* DENALI_PHY_557_DATA */
+			0x00000000,	/* DENALI_PHY_558_DATA */
+			0x00000000,	/* DENALI_PHY_559_DATA */
+			0x00000000,	/* DENALI_PHY_560_DATA */
+			0x00000000,	/* DENALI_PHY_561_DATA */
+			0x00000000,	/* DENALI_PHY_562_DATA */
+			0x00000000,	/* DENALI_PHY_563_DATA */
+			0x00000000,	/* DENALI_PHY_564_DATA */
+			0x00000000,	/* DENALI_PHY_565_DATA */
+			0x00000000,	/* DENALI_PHY_566_DATA */
+			0x00000000,	/* DENALI_PHY_567_DATA */
+			0x00000000,	/* DENALI_PHY_568_DATA */
+			0x00000000,	/* DENALI_PHY_569_DATA */
+			0x00000000,	/* DENALI_PHY_570_DATA */
+			0x00000000,	/* DENALI_PHY_571_DATA */
+			0x00000000,	/* DENALI_PHY_572_DATA */
+			0x00000000,	/* DENALI_PHY_573_DATA */
+			0x00000000,	/* DENALI_PHY_574_DATA */
+			0x00000000,	/* DENALI_PHY_575_DATA */
+			0x00000000,	/* DENALI_PHY_576_DATA */
+			0x00000000,	/* DENALI_PHY_577_DATA */
+			0x00000000,	/* DENALI_PHY_578_DATA */
+			0x00000000,	/* DENALI_PHY_579_DATA */
+			0x00000000,	/* DENALI_PHY_580_DATA */
+			0x00000000,	/* DENALI_PHY_581_DATA */
+			0x00000000,	/* DENALI_PHY_582_DATA */
+			0x00000000,	/* DENALI_PHY_583_DATA */
+			0x00000000,	/* DENALI_PHY_584_DATA */
+			0x00000000,	/* DENALI_PHY_585_DATA */
+			0x00000000,	/* DENALI_PHY_586_DATA */
+			0x00000000,	/* DENALI_PHY_587_DATA */
+			0x00000000,	/* DENALI_PHY_588_DATA */
+			0x00000000,	/* DENALI_PHY_589_DATA */
+			0x00000000,	/* DENALI_PHY_590_DATA */
+			0x00000000,	/* DENALI_PHY_591_DATA */
+			0x00000000,	/* DENALI_PHY_592_DATA */
+			0x00000000,	/* DENALI_PHY_593_DATA */
+			0x00000000,	/* DENALI_PHY_594_DATA */
+			0x00000000,	/* DENALI_PHY_595_DATA */
+			0x00000000,	/* DENALI_PHY_596_DATA */
+			0x00000000,	/* DENALI_PHY_597_DATA */
+			0x00000000,	/* DENALI_PHY_598_DATA */
+			0x00000000,	/* DENALI_PHY_599_DATA */
+			0x00000000,	/* DENALI_PHY_600_DATA */
+			0x00000000,	/* DENALI_PHY_601_DATA */
+			0x00000000,	/* DENALI_PHY_602_DATA */
+			0x00000000,	/* DENALI_PHY_603_DATA */
+			0x00000000,	/* DENALI_PHY_604_DATA */
+			0x00000000,	/* DENALI_PHY_605_DATA */
+			0x00000000,	/* DENALI_PHY_606_DATA */
+			0x00000000,	/* DENALI_PHY_607_DATA */
+			0x00000000,	/* DENALI_PHY_608_DATA */
+			0x00000000,	/* DENALI_PHY_609_DATA */
+			0x00000000,	/* DENALI_PHY_610_DATA */
+			0x00000000,	/* DENALI_PHY_611_DATA */
+			0x00000000,	/* DENALI_PHY_612_DATA */
+			0x00000000,	/* DENALI_PHY_613_DATA */
+			0x00000000,	/* DENALI_PHY_614_DATA */
+			0x00000000,	/* DENALI_PHY_615_DATA */
+			0x00000000,	/* DENALI_PHY_616_DATA */
+			0x00000000,	/* DENALI_PHY_617_DATA */
+			0x00000000,	/* DENALI_PHY_618_DATA */
+			0x00000000,	/* DENALI_PHY_619_DATA */
+			0x00000000,	/* DENALI_PHY_620_DATA */
+			0x00000000,	/* DENALI_PHY_621_DATA */
+			0x00000000,	/* DENALI_PHY_622_DATA */
+			0x00000000,	/* DENALI_PHY_623_DATA */
+			0x00000000,	/* DENALI_PHY_624_DATA */
+			0x00000000,	/* DENALI_PHY_625_DATA */
+			0x00000000,	/* DENALI_PHY_626_DATA */
+			0x00000000,	/* DENALI_PHY_627_DATA */
+			0x00000000,	/* DENALI_PHY_628_DATA */
+			0x00000000,	/* DENALI_PHY_629_DATA */
+			0x00000000,	/* DENALI_PHY_630_DATA */
+			0x00000000,	/* DENALI_PHY_631_DATA */
+			0x00000000,	/* DENALI_PHY_632_DATA */
+			0x00000000,	/* DENALI_PHY_633_DATA */
+			0x00000000,	/* DENALI_PHY_634_DATA */
+			0x00000000,	/* DENALI_PHY_635_DATA */
+			0x00000000,	/* DENALI_PHY_636_DATA */
+			0x00000000,	/* DENALI_PHY_637_DATA */
+			0x00000000,	/* DENALI_PHY_638_DATA */
+			0x00000000,	/* DENALI_PHY_639_DATA */
+			0x00000000,	/* DENALI_PHY_640_DATA */
+			0x00000000,	/* DENALI_PHY_641_DATA */
+			0x00000000,	/* DENALI_PHY_642_DATA */
+			0x00000000,	/* DENALI_PHY_643_DATA */
+			0x00000000,	/* DENALI_PHY_644_DATA */
+			0x00000000,	/* DENALI_PHY_645_DATA */
+			0x00000000,	/* DENALI_PHY_646_DATA */
+			0x00000002,	/* DENALI_PHY_647_DATA */
+			0x00000000,	/* DENALI_PHY_648_DATA */
+			0x00000000,	/* DENALI_PHY_649_DATA */
+			0x00000000,	/* DENALI_PHY_650_DATA */
+			0x00400320,	/* DENALI_PHY_651_DATA */
+			0x00000040,	/* DENALI_PHY_652_DATA */
+			0x00000000,	/* DENALI_PHY_653_DATA */
+			0x00000000,	/* DENALI_PHY_654_DATA */
+			0x00000000,	/* DENALI_PHY_655_DATA */
+			0x01000000,	/* DENALI_PHY_656_DATA */
+			0x00020003,	/* DENALI_PHY_657_DATA */
+			0x00000000,	/* DENALI_PHY_658_DATA */
+			0x00000000,	/* DENALI_PHY_659_DATA */
+			0x00000000,	/* DENALI_PHY_660_DATA */
+			0x0000002a,	/* DENALI_PHY_661_DATA */
+			0x00000015,	/* DENALI_PHY_662_DATA */
+			0x00000015,	/* DENALI_PHY_663_DATA */
+			0x0000002a,	/* DENALI_PHY_664_DATA */
+			0x00000033,	/* DENALI_PHY_665_DATA */
+			0x0000000c,	/* DENALI_PHY_666_DATA */
+			0x0000000c,	/* DENALI_PHY_667_DATA */
+			0x00000033,	/* DENALI_PHY_668_DATA */
+			0x00000000,	/* DENALI_PHY_669_DATA */
+			0x00000000,	/* DENALI_PHY_670_DATA */
+			0x00000000,	/* DENALI_PHY_671_DATA */
+			0x00030055,	/* DENALI_PHY_672_DATA */
+			0x03000300,	/* DENALI_PHY_673_DATA */
+			0x03000300,	/* DENALI_PHY_674_DATA */
+			0x00000300,	/* DENALI_PHY_675_DATA */
+			0x42080010,	/* DENALI_PHY_676_DATA */
+			0x00000003,	/* DENALI_PHY_677_DATA */
+			0x00000000,	/* DENALI_PHY_678_DATA */
+			0x00000000,	/* DENALI_PHY_679_DATA */
+			0x00000000,	/* DENALI_PHY_680_DATA */
+			0x00000000,	/* DENALI_PHY_681_DATA */
+			0x00000000,	/* DENALI_PHY_682_DATA */
+			0x00000000,	/* DENALI_PHY_683_DATA */
+			0x00000000,	/* DENALI_PHY_684_DATA */
+			0x00000000,	/* DENALI_PHY_685_DATA */
+			0x00000000,	/* DENALI_PHY_686_DATA */
+			0x00000000,	/* DENALI_PHY_687_DATA */
+			0x00000000,	/* DENALI_PHY_688_DATA */
+			0x00000000,	/* DENALI_PHY_689_DATA */
+			0x00000000,	/* DENALI_PHY_690_DATA */
+			0x00000000,	/* DENALI_PHY_691_DATA */
+			0x00000000,	/* DENALI_PHY_692_DATA */
+			0x00000000,	/* DENALI_PHY_693_DATA */
+			0x00000000,	/* DENALI_PHY_694_DATA */
+			0x00000000,	/* DENALI_PHY_695_DATA */
+			0x00000000,	/* DENALI_PHY_696_DATA */
+			0x00000000,	/* DENALI_PHY_697_DATA */
+			0x00000000,	/* DENALI_PHY_698_DATA */
+			0x00000000,	/* DENALI_PHY_699_DATA */
+			0x00000000,	/* DENALI_PHY_700_DATA */
+			0x00000000,	/* DENALI_PHY_701_DATA */
+			0x00000000,	/* DENALI_PHY_702_DATA */
+			0x00000000,	/* DENALI_PHY_703_DATA */
+			0x00000000,	/* DENALI_PHY_704_DATA */
+			0x00000000,	/* DENALI_PHY_705_DATA */
+			0x00000000,	/* DENALI_PHY_706_DATA */
+			0x00000000,	/* DENALI_PHY_707_DATA */
+			0x00000000,	/* DENALI_PHY_708_DATA */
+			0x00000000,	/* DENALI_PHY_709_DATA */
+			0x00000000,	/* DENALI_PHY_710_DATA */
+			0x00000000,	/* DENALI_PHY_711_DATA */
+			0x00000000,	/* DENALI_PHY_712_DATA */
+			0x00000000,	/* DENALI_PHY_713_DATA */
+			0x00000000,	/* DENALI_PHY_714_DATA */
+			0x00000000,	/* DENALI_PHY_715_DATA */
+			0x00000000,	/* DENALI_PHY_716_DATA */
+			0x00000000,	/* DENALI_PHY_717_DATA */
+			0x00000000,	/* DENALI_PHY_718_DATA */
+			0x00000000,	/* DENALI_PHY_719_DATA */
+			0x00000000,	/* DENALI_PHY_720_DATA */
+			0x00000000,	/* DENALI_PHY_721_DATA */
+			0x00000000,	/* DENALI_PHY_722_DATA */
+			0x00000000,	/* DENALI_PHY_723_DATA */
+			0x00000000,	/* DENALI_PHY_724_DATA */
+			0x00000000,	/* DENALI_PHY_725_DATA */
+			0x00000000,	/* DENALI_PHY_726_DATA */
+			0x00000000,	/* DENALI_PHY_727_DATA */
+			0x00000000,	/* DENALI_PHY_728_DATA */
+			0x00000000,	/* DENALI_PHY_729_DATA */
+			0x00000000,	/* DENALI_PHY_730_DATA */
+			0x00000000,	/* DENALI_PHY_731_DATA */
+			0x00000000,	/* DENALI_PHY_732_DATA */
+			0x00000000,	/* DENALI_PHY_733_DATA */
+			0x00000000,	/* DENALI_PHY_734_DATA */
+			0x00000000,	/* DENALI_PHY_735_DATA */
+			0x00000000,	/* DENALI_PHY_736_DATA */
+			0x00000000,	/* DENALI_PHY_737_DATA */
+			0x00000000,	/* DENALI_PHY_738_DATA */
+			0x00000000,	/* DENALI_PHY_739_DATA */
+			0x00000000,	/* DENALI_PHY_740_DATA */
+			0x00000000,	/* DENALI_PHY_741_DATA */
+			0x00000000,	/* DENALI_PHY_742_DATA */
+			0x00000000,	/* DENALI_PHY_743_DATA */
+			0x00000000,	/* DENALI_PHY_744_DATA */
+			0x00000000,	/* DENALI_PHY_745_DATA */
+			0x00000000,	/* DENALI_PHY_746_DATA */
+			0x00000000,	/* DENALI_PHY_747_DATA */
+			0x00000000,	/* DENALI_PHY_748_DATA */
+			0x00000000,	/* DENALI_PHY_749_DATA */
+			0x00000000,	/* DENALI_PHY_750_DATA */
+			0x00000000,	/* DENALI_PHY_751_DATA */
+			0x00000000,	/* DENALI_PHY_752_DATA */
+			0x00000000,	/* DENALI_PHY_753_DATA */
+			0x00000000,	/* DENALI_PHY_754_DATA */
+			0x00000000,	/* DENALI_PHY_755_DATA */
+			0x00000000,	/* DENALI_PHY_756_DATA */
+			0x00000000,	/* DENALI_PHY_757_DATA */
+			0x00000000,	/* DENALI_PHY_758_DATA */
+			0x00000000,	/* DENALI_PHY_759_DATA */
+			0x00000000,	/* DENALI_PHY_760_DATA */
+			0x00000000,	/* DENALI_PHY_761_DATA */
+			0x00000000,	/* DENALI_PHY_762_DATA */
+			0x00000000,	/* DENALI_PHY_763_DATA */
+			0x00000000,	/* DENALI_PHY_764_DATA */
+			0x00000000,	/* DENALI_PHY_765_DATA */
+			0x00000000,	/* DENALI_PHY_766_DATA */
+			0x00000000,	/* DENALI_PHY_767_DATA */
+			0x00000000,	/* DENALI_PHY_768_DATA */
+			0x00000000,	/* DENALI_PHY_769_DATA */
+			0x00000000,	/* DENALI_PHY_770_DATA */
+			0x00000000,	/* DENALI_PHY_771_DATA */
+			0x00000000,	/* DENALI_PHY_772_DATA */
+			0x00000000,	/* DENALI_PHY_773_DATA */
+			0x00000000,	/* DENALI_PHY_774_DATA */
+			0x00000002,	/* DENALI_PHY_775_DATA */
+			0x00000000,	/* DENALI_PHY_776_DATA */
+			0x00000000,	/* DENALI_PHY_777_DATA */
+			0x00000000,	/* DENALI_PHY_778_DATA */
+			0x00400320,	/* DENALI_PHY_779_DATA */
+			0x00000040,	/* DENALI_PHY_780_DATA */
+			0x00000000,	/* DENALI_PHY_781_DATA */
+			0x00000000,	/* DENALI_PHY_782_DATA */
+			0x00000000,	/* DENALI_PHY_783_DATA */
+			0x01000000,	/* DENALI_PHY_784_DATA */
+			0x00020003,	/* DENALI_PHY_785_DATA */
+			0x00000000,	/* DENALI_PHY_786_DATA */
+			0x00000000,	/* DENALI_PHY_787_DATA */
+			0x00000000,	/* DENALI_PHY_788_DATA */
+			0x0000002a,	/* DENALI_PHY_789_DATA */
+			0x00000015,	/* DENALI_PHY_790_DATA */
+			0x00000015,	/* DENALI_PHY_791_DATA */
+			0x0000002a,	/* DENALI_PHY_792_DATA */
+			0x00000033,	/* DENALI_PHY_793_DATA */
+			0x0000000c,	/* DENALI_PHY_794_DATA */
+			0x0000000c,	/* DENALI_PHY_795_DATA */
+			0x00000033,	/* DENALI_PHY_796_DATA */
+			0x1ee6b16a,	/* DENALI_PHY_797_DATA */
+			0x10000000,	/* DENALI_PHY_798_DATA */
+			0x00000000,	/* DENALI_PHY_799_DATA */
+			0x00030055,	/* DENALI_PHY_800_DATA */
+			0x03000300,	/* DENALI_PHY_801_DATA */
+			0x03000300,	/* DENALI_PHY_802_DATA */
+			0x00000300,	/* DENALI_PHY_803_DATA */
+			0x42080010,	/* DENALI_PHY_804_DATA */
+			0x00000003,	/* DENALI_PHY_805_DATA */
+			0x00000000,	/* DENALI_PHY_806_DATA */
+			0x00000000,	/* DENALI_PHY_807_DATA */
+			0x00000000,	/* DENALI_PHY_808_DATA */
+			0x00000000,	/* DENALI_PHY_809_DATA */
+			0x00000000,	/* DENALI_PHY_810_DATA */
+			0x00000000,	/* DENALI_PHY_811_DATA */
+			0x00000000,	/* DENALI_PHY_812_DATA */
+			0x00000000,	/* DENALI_PHY_813_DATA */
+			0x00000000,	/* DENALI_PHY_814_DATA */
+			0x00000000,	/* DENALI_PHY_815_DATA */
+			0x00000000,	/* DENALI_PHY_816_DATA */
+			0x00000000,	/* DENALI_PHY_817_DATA */
+			0x00000000,	/* DENALI_PHY_818_DATA */
+			0x00000000,	/* DENALI_PHY_819_DATA */
+			0x00000000,	/* DENALI_PHY_820_DATA */
+			0x00000000,	/* DENALI_PHY_821_DATA */
+			0x00000000,	/* DENALI_PHY_822_DATA */
+			0x00000000,	/* DENALI_PHY_823_DATA */
+			0x00000000,	/* DENALI_PHY_824_DATA */
+			0x00000000,	/* DENALI_PHY_825_DATA */
+			0x00000000,	/* DENALI_PHY_826_DATA */
+			0x00000000,	/* DENALI_PHY_827_DATA */
+			0x00000000,	/* DENALI_PHY_828_DATA */
+			0x00000000,	/* DENALI_PHY_829_DATA */
+			0x00000000,	/* DENALI_PHY_830_DATA */
+			0x00000000,	/* DENALI_PHY_831_DATA */
+			0x00000000,	/* DENALI_PHY_832_DATA */
+			0x00000000,	/* DENALI_PHY_833_DATA */
+			0x00000000,	/* DENALI_PHY_834_DATA */
+			0x00000000,	/* DENALI_PHY_835_DATA */
+			0x00000000,	/* DENALI_PHY_836_DATA */
+			0x00000000,	/* DENALI_PHY_837_DATA */
+			0x00000000,	/* DENALI_PHY_838_DATA */
+			0x00000000,	/* DENALI_PHY_839_DATA */
+			0x00000000,	/* DENALI_PHY_840_DATA */
+			0x00000000,	/* DENALI_PHY_841_DATA */
+			0x00000000,	/* DENALI_PHY_842_DATA */
+			0x00000000,	/* DENALI_PHY_843_DATA */
+			0x00000000,	/* DENALI_PHY_844_DATA */
+			0x00000000,	/* DENALI_PHY_845_DATA */
+			0x00000000,	/* DENALI_PHY_846_DATA */
+			0x00000000,	/* DENALI_PHY_847_DATA */
+			0x00000000,	/* DENALI_PHY_848_DATA */
+			0x00000000,	/* DENALI_PHY_849_DATA */
+			0x00000000,	/* DENALI_PHY_850_DATA */
+			0x00000000,	/* DENALI_PHY_851_DATA */
+			0x00000000,	/* DENALI_PHY_852_DATA */
+			0x00000000,	/* DENALI_PHY_853_DATA */
+			0x00000000,	/* DENALI_PHY_854_DATA */
+			0x00000000,	/* DENALI_PHY_855_DATA */
+			0x00000000,	/* DENALI_PHY_856_DATA */
+			0x00000000,	/* DENALI_PHY_857_DATA */
+			0x00000000,	/* DENALI_PHY_858_DATA */
+			0x00000000,	/* DENALI_PHY_859_DATA */
+			0x00000000,	/* DENALI_PHY_860_DATA */
+			0x00000000,	/* DENALI_PHY_861_DATA */
+			0x00000000,	/* DENALI_PHY_862_DATA */
+			0x00000000,	/* DENALI_PHY_863_DATA */
+			0x00000000,	/* DENALI_PHY_864_DATA */
+			0x00000000,	/* DENALI_PHY_865_DATA */
+			0x00000000,	/* DENALI_PHY_866_DATA */
+			0x00000000,	/* DENALI_PHY_867_DATA */
+			0x00000000,	/* DENALI_PHY_868_DATA */
+			0x00000000,	/* DENALI_PHY_869_DATA */
+			0x00000000,	/* DENALI_PHY_870_DATA */
+			0x00000000,	/* DENALI_PHY_871_DATA */
+			0x00000000,	/* DENALI_PHY_872_DATA */
+			0x00000000,	/* DENALI_PHY_873_DATA */
+			0x00000000,	/* DENALI_PHY_874_DATA */
+			0x00000000,	/* DENALI_PHY_875_DATA */
+			0x00000000,	/* DENALI_PHY_876_DATA */
+			0x00000000,	/* DENALI_PHY_877_DATA */
+			0x00000000,	/* DENALI_PHY_878_DATA */
+			0x00000000,	/* DENALI_PHY_879_DATA */
+			0x00000000,	/* DENALI_PHY_880_DATA */
+			0x00000000,	/* DENALI_PHY_881_DATA */
+			0x00000000,	/* DENALI_PHY_882_DATA */
+			0x00000000,	/* DENALI_PHY_883_DATA */
+			0x00000000,	/* DENALI_PHY_884_DATA */
+			0x00000000,	/* DENALI_PHY_885_DATA */
+			0x00000000,	/* DENALI_PHY_886_DATA */
+			0x00000000,	/* DENALI_PHY_887_DATA */
+			0x00000000,	/* DENALI_PHY_888_DATA */
+			0x00000000,	/* DENALI_PHY_889_DATA */
+			0x00000000,	/* DENALI_PHY_890_DATA */
+			0x00000000,	/* DENALI_PHY_891_DATA */
+			0x00000000,	/* DENALI_PHY_892_DATA */
+			0x00000000,	/* DENALI_PHY_893_DATA */
+			0x00000000,	/* DENALI_PHY_894_DATA */
+			0x00000000,	/* DENALI_PHY_895_DATA */
+			0x00000000,	/* DENALI_PHY_896_DATA */
+			0x00000000,	/* DENALI_PHY_897_DATA */
+			0x00000005,	/* DENALI_PHY_898_DATA */
+			0x04000f01,	/* DENALI_PHY_899_DATA */
+			0x00020040,	/* DENALI_PHY_900_DATA */
+			0x00020055,	/* DENALI_PHY_901_DATA */
+			0x00000000,	/* DENALI_PHY_902_DATA */
+			0x00000000,	/* DENALI_PHY_903_DATA */
+			0x00000000,	/* DENALI_PHY_904_DATA */
+			0x00000050,	/* DENALI_PHY_905_DATA */
+			0x00000000,	/* DENALI_PHY_906_DATA */
+			0x01010100,	/* DENALI_PHY_907_DATA */
+			0x00000600,	/* DENALI_PHY_908_DATA */
+			0x00000000,	/* DENALI_PHY_909_DATA */
+			0x00006400,	/* DENALI_PHY_910_DATA */
+			0x01221102,	/* DENALI_PHY_911_DATA */
+			0x00000000,	/* DENALI_PHY_912_DATA */
+			0x000d1f00,	/* DENALI_PHY_913_DATA */
+			0x0d1f0d1f,	/* DENALI_PHY_914_DATA */
+			0x0d1f0d1f,	/* DENALI_PHY_915_DATA */
+			0x00030003,	/* DENALI_PHY_916_DATA */
+			0x03000300,	/* DENALI_PHY_917_DATA */
+			0x00000300,	/* DENALI_PHY_918_DATA */
+			0x01221102,	/* DENALI_PHY_919_DATA */
+			0x00000000,	/* DENALI_PHY_920_DATA */
+			0x00000000,	/* DENALI_PHY_921_DATA */
+			0x03020000,	/* DENALI_PHY_922_DATA */
+			0x00000001,	/* DENALI_PHY_923_DATA */
+			0x00000411,	/* DENALI_PHY_924_DATA */
+			0x00000411,	/* DENALI_PHY_925_DATA */
+			0x00000040,	/* DENALI_PHY_926_DATA */
+			0x00000040,	/* DENALI_PHY_927_DATA */
+			0x00000411,	/* DENALI_PHY_928_DATA */
+			0x00000411,	/* DENALI_PHY_929_DATA */
+			0x00004410,	/* DENALI_PHY_930_DATA */
+			0x00004410,	/* DENALI_PHY_931_DATA */
+			0x00004410,	/* DENALI_PHY_932_DATA */
+			0x00004410,	/* DENALI_PHY_933_DATA */
+			0x00004410,	/* DENALI_PHY_934_DATA */
+			0x00000411,	/* DENALI_PHY_935_DATA */
+			0x00004410,	/* DENALI_PHY_936_DATA */
+			0x00000411,	/* DENALI_PHY_937_DATA */
+			0x00004410,	/* DENALI_PHY_938_DATA */
+			0x00000411,	/* DENALI_PHY_939_DATA */
+			0x00004410,	/* DENALI_PHY_940_DATA */
+			0x00000000,	/* DENALI_PHY_941_DATA */
+			0x00000000,	/* DENALI_PHY_942_DATA */
+			0x00000000,	/* DENALI_PHY_943_DATA */
+			0x64000000,	/* DENALI_PHY_944_DATA */
+			0x00000000,	/* DENALI_PHY_945_DATA */
+			0x00000000,	/* DENALI_PHY_946_DATA */
+			0x00000508,	/* DENALI_PHY_947_DATA */
+			0x00000000,	/* DENALI_PHY_948_DATA */
+			0x00000000,	/* DENALI_PHY_949_DATA */
+			0x00000000,	/* DENALI_PHY_950_DATA */
+			0x00000000,	/* DENALI_PHY_951_DATA */
+			0x00000000,	/* DENALI_PHY_952_DATA */
+			0x00000000,	/* DENALI_PHY_953_DATA */
+			0xe4000000,	/* DENALI_PHY_954_DATA */
+			0x00000000,	/* DENALI_PHY_955_DATA */
+			0x00000000,	/* DENALI_PHY_956_DATA */
+			0x01010000,	/* DENALI_PHY_957_DATA */
+			0x00000000	/* DENALI_PHY_958_DATA */
+		}
+	},
+},
diff --git a/drivers/ram/rockchip/sdram_debug.c b/drivers/ram/rockchip/sdram_debug.c
new file mode 100644
index 0000000..9cf6626
--- /dev/null
+++ b/drivers/ram/rockchip/sdram_debug.c
@@ -0,0 +1,147 @@
+// 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_rk322x.c b/drivers/ram/rockchip/sdram_rk322x.c
index e96ac54..94893e1 100644
--- a/drivers/ram/rockchip/sdram_rk322x.c
+++ b/drivers/ram/rockchip/sdram_rk322x.c
@@ -16,7 +16,6 @@
 #include <asm/arch-rockchip/grf_rk322x.h>
 #include <asm/arch-rockchip/hardware.h>
 #include <asm/arch-rockchip/sdram_rk322x.h>
-#include <asm/arch-rockchip/timer.h>
 #include <asm/arch-rockchip/uart.h>
 #include <asm/arch-rockchip/sdram_common.h>
 #include <asm/types.h>
@@ -96,26 +95,26 @@
 			1 << DDRCTRL_PSRST_SHIFT | 1 << DDRCTRL_SRST_SHIFT |
 			1 << DDRPHY_PSRST_SHIFT | 1 << DDRPHY_SRST_SHIFT);
 
-	rockchip_udelay(10);
+	udelay(10);
 
 	rk_clrreg(&cru->cru_softrst_con[5], 1 << DDRPHY_PSRST_SHIFT |
 						  1 << DDRPHY_SRST_SHIFT);
-	rockchip_udelay(10);
+	udelay(10);
 
 	rk_clrreg(&cru->cru_softrst_con[5], 1 << DDRCTRL_PSRST_SHIFT |
 						  1 << DDRCTRL_SRST_SHIFT);
-	rockchip_udelay(10);
+	udelay(10);
 
 	clrbits_le32(&ddr_phy->ddrphy_reg[0],
 		     SOFT_RESET_MASK << SOFT_RESET_SHIFT);
-	rockchip_udelay(10);
+	udelay(10);
 	setbits_le32(&ddr_phy->ddrphy_reg[0],
 		     SOFT_DERESET_ANALOG);
-	rockchip_udelay(5);
+	udelay(5);
 	setbits_le32(&ddr_phy->ddrphy_reg[0],
 		     SOFT_DERESET_DIGITAL);
 
-	rockchip_udelay(1);
+	udelay(1);
 }
 
 void phy_dll_bypass_set(struct rk322x_ddr_phy *ddr_phy, u32 freq)
@@ -154,7 +153,7 @@
 			 u32 rank, u32 cmd, u32 arg)
 {
 	writel((START_CMD | (rank << 20) | arg | cmd), &pctl->mcmd);
-	rockchip_udelay(1);
+	udelay(1);
 	while (readl(&pctl->mcmd) & START_CMD)
 		;
 }
@@ -167,7 +166,7 @@
 
 	if (dramtype == DDR3) {
 		send_command(pctl, 3, DESELECT_CMD, 0);
-		rockchip_udelay(1);
+		udelay(1);
 		send_command(pctl, 3, PREA_CMD, 0);
 		send_command(pctl, 3, MRS_CMD,
 			     (0x02 & BANK_ADDR_MASK) << BANK_ADDR_SHIFT |
@@ -196,17 +195,17 @@
 			     (0x63 & LPDDR23_MA_MASK) << LPDDR23_MA_SHIFT |
 			     (0 & LPDDR23_OP_MASK) <<
 			     LPDDR23_OP_SHIFT);
-		rockchip_udelay(10);
+		udelay(10);
 		send_command(pctl, 3, MRS_CMD,
 			     (0x10 & LPDDR23_MA_MASK) << LPDDR23_MA_SHIFT |
 			     (0xff & LPDDR23_OP_MASK) <<
 			     LPDDR23_OP_SHIFT);
-		rockchip_udelay(1);
+		udelay(1);
 		send_command(pctl, 3, MRS_CMD,
 			     (0x10 & LPDDR23_MA_MASK) << LPDDR23_MA_SHIFT |
 			     (0xff & LPDDR23_OP_MASK) <<
 			     LPDDR23_OP_SHIFT);
-		rockchip_udelay(1);
+		udelay(1);
 		send_command(pctl, 3, MRS_CMD,
 			     (1 & LPDDR23_MA_MASK) << LPDDR23_MA_SHIFT |
 			     (sdram_params->phy_timing.mr[1] &
@@ -243,7 +242,7 @@
 			DQS_SQU_CAL_SEL_CS0);
 	setbits_le32(&ddr_phy->ddrphy_reg[2], DQS_SQU_CAL_START);
 
-	rockchip_udelay(30);
+	udelay(30);
 	ret = readl(&ddr_phy->ddrphy_reg[0xff]);
 
 	clrbits_le32(&ddr_phy->ddrphy_reg[2],
@@ -367,9 +366,9 @@
 
 	writel(GRF_DDRPHY_BUFFEREN_CORE_EN, &grf->soc_con[0]);
 	clrbits_le32(&ddr_phy->ddrphy_reg[0], 0x3 << 2);
-	rockchip_udelay(1);
+	udelay(1);
 	setbits_le32(&ddr_phy->ddrphy_reg[0], 1 << 2);
-	rockchip_udelay(5);
+	udelay(5);
 	setbits_le32(&ddr_phy->ddrphy_reg[0], 1 << 3);
 	writel(GRF_DDRPHY_BUFFEREN_CORE_DIS, &grf->soc_con[0]);
 }
diff --git a/drivers/ram/rockchip/sdram_rk3399.c b/drivers/ram/rockchip/sdram_rk3399.c
index 5251865..81fc71c 100644
--- a/drivers/ram/rockchip/sdram_rk3399.c
+++ b/drivers/ram/rockchip/sdram_rk3399.c
@@ -14,14 +14,40 @@
 #include <syscon.h>
 #include <asm/io.h>
 #include <asm/arch-rockchip/clock.h>
-#include <asm/arch-rockchip/sdram_common.h>
-#include <asm/arch-rockchip/sdram_rk3399.h>
 #include <asm/arch-rockchip/cru_rk3399.h>
 #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_rk3399.h>
 #include <linux/err.h>
 #include <time.h>
 
+#define PRESET_SGRF_HOLD(n)	((0x1 << (6 + 16)) | ((n) << 6))
+#define PRESET_GPIO0_HOLD(n)	((0x1 << (7 + 16)) | ((n) << 7))
+#define PRESET_GPIO1_HOLD(n)	((0x1 << (8 + 16)) | ((n) << 8))
+
+#define PHY_DRV_ODT_HI_Z	0x0
+#define PHY_DRV_ODT_240		0x1
+#define PHY_DRV_ODT_120		0x8
+#define PHY_DRV_ODT_80		0x9
+#define PHY_DRV_ODT_60		0xc
+#define PHY_DRV_ODT_48		0xd
+#define PHY_DRV_ODT_40		0xe
+#define PHY_DRV_ODT_34_3	0xf
+
+#define PHY_BOOSTP_EN		0x1
+#define PHY_BOOSTN_EN		0x1
+#define PHY_SLEWP_EN		0x1
+#define PHY_SLEWN_EN		0x1
+#define PHY_RX_CM_INPUT		0x1
+#define CS0_MR22_VAL		0
+#define CS1_MR22_VAL		3
+
+#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)) | \
+					((n) << (9 + (ch) * 4)))
 struct chan_info {
 	struct rk3399_ddr_pctl_regs *pctl;
 	struct rk3399_ddr_pi_regs *pi;
@@ -32,29 +58,27 @@
 struct dram_info {
 #if defined(CONFIG_TPL_BUILD) || \
 	(!defined(CONFIG_TPL) && defined(CONFIG_SPL_BUILD))
+	u32 pwrup_srefresh_exit[2];
 	struct chan_info chan[2];
 	struct clk ddr_clk;
 	struct rk3399_cru *cru;
+	struct rk3399_grf_regs *grf;
+	struct rk3399_pmu_regs *pmu;
 	struct rk3399_pmucru *pmucru;
 	struct rk3399_pmusgrf_regs *pmusgrf;
 	struct rk3399_ddr_cic_regs *cic;
+	const struct sdram_rk3399_ops *ops;
 #endif
 	struct ram_info info;
 	struct rk3399_pmugrf_regs *pmugrf;
 };
 
-#define PRESET_SGRF_HOLD(n)	((0x1 << (6 + 16)) | ((n) << 6))
-#define PRESET_GPIO0_HOLD(n)	((0x1 << (7 + 16)) | ((n) << 7))
-#define PRESET_GPIO1_HOLD(n)	((0x1 << (8 + 16)) | ((n) << 8))
-
-#define PHY_DRV_ODT_Hi_Z	0x0
-#define PHY_DRV_ODT_240		0x1
-#define PHY_DRV_ODT_120		0x8
-#define PHY_DRV_ODT_80		0x9
-#define PHY_DRV_ODT_60		0xc
-#define PHY_DRV_ODT_48		0xd
-#define PHY_DRV_ODT_40		0xe
-#define PHY_DRV_ODT_34_3	0xf
+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);
+};
 
 #if defined(CONFIG_TPL_BUILD) || \
 	(!defined(CONFIG_TPL) && defined(CONFIG_SPL_BUILD))
@@ -68,6 +92,154 @@
 	struct regmap *map;
 };
 
+struct io_setting {
+	u32 mhz;
+	u32 mr5;
+	/* dram side */
+	u32 dq_odt;
+	u32 ca_odt;
+	u32 pdds;
+	u32 dq_vref;
+	u32 ca_vref;
+	/* phy side */
+	u32 rd_odt;
+	u32 wr_dq_drv;
+	u32 wr_ca_drv;
+	u32 wr_ckcs_drv;
+	u32 rd_odt_en;
+	u32 rd_vref;
+} lpddr4_io_setting[] = {
+	{
+		50 * MHz,
+		0,
+		/* dram side */
+		0,	/* dq_odt; */
+		0,	/* ca_odt; */
+		6,	/* pdds; */
+		0x72,	/* dq_vref; */
+		0x72,	/* ca_vref; */
+		/* phy side */
+		PHY_DRV_ODT_HI_Z,	/* rd_odt; */
+		PHY_DRV_ODT_40,	/* wr_dq_drv; */
+		PHY_DRV_ODT_40,	/* wr_ca_drv; */
+		PHY_DRV_ODT_40,	/* wr_ckcs_drv; */
+		0,	/* rd_odt_en;*/
+		41,	/* rd_vref; (unit %, range 3.3% - 48.7%) */
+	},
+	{
+		600 * MHz,
+		0,
+		/* dram side */
+		1,	/* dq_odt; */
+		0,	/* ca_odt; */
+		6,	/* pdds; */
+		0x72,	/* dq_vref; */
+		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%) */
+	},
+	{
+		800 * MHz,
+		0,
+		/* dram side */
+		1,	/* dq_odt; */
+		0,	/* ca_odt; */
+		1,	/* 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_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%) */
+	},
+	{
+		1066 * MHz,
+		0,
+		/* dram side */
+		6,	/* dq_odt; */
+		0,	/* ca_odt; */
+		1,	/* pdds; */
+		0x10,	/* dq_vref; */
+		0x72,	/* ca_vref; */
+		/* phy side */
+		PHY_DRV_ODT_40,	/* 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%) */
+	},
+};
+
+/**
+ * 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)
+{
+	struct io_setting *io = NULL;
+	u32 n;
+
+	for (n = 0; n < ARRAY_SIZE(lpddr4_io_setting); n++) {
+		io = &lpddr4_io_setting[n];
+
+		if (io->mr5 != 0) {
+			if (io->mhz >= params->base.ddr_freq &&
+			    io->mr5 == mr5)
+				break;
+		} else {
+			if (io->mhz >= params->base.ddr_freq)
+				break;
+		}
+	}
+
+	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)
+{
+	return (channel == 0) ? &dram->grf->ddrc0_con0 : &dram->grf->ddrc0_con1;
+}
+
 static void copy_to_reg(u32 *dest, const u32 *src, u32 n)
 {
 	int i;
@@ -79,6 +251,29 @@
 	}
 }
 
+static void rkclk_ddr_reset(struct rk3399_cru *cru, u32 channel, u32 ctl,
+			    u32 phy)
+{
+	channel &= 0x1;
+	ctl &= 0x1;
+	phy &= 0x1;
+	writel(CRU_SFTRST_DDR_CTRL(channel, ctl) |
+				   CRU_SFTRST_DDR_PHY(channel, phy),
+				   &cru->softrst_con[4]);
+}
+
+static void phy_pctrl_reset(struct rk3399_cru *cru,  u32 channel)
+{
+	rkclk_ddr_reset(cru, channel, 1, 1);
+	udelay(10);
+
+	rkclk_ddr_reset(cru, channel, 1, 0);
+	udelay(10);
+
+	rkclk_ddr_reset(cru, channel, 0, 0);
+	udelay(10);
+}
+
 static void phy_dll_bypass_set(struct rk3399_ddr_publ_regs *ddr_publ_regs,
 			       u32 freq)
 {
@@ -111,10 +306,9 @@
 }
 
 static void set_memory_map(const struct chan_info *chan, u32 channel,
-			   const struct rk3399_sdram_params *sdram_params)
+			   const struct rk3399_sdram_params *params)
 {
-	const struct rk3399_sdram_channel *sdram_ch =
-		&sdram_params->ch[channel];
+	const struct rk3399_sdram_channel *sdram_ch = &params->ch[channel];
 	u32 *denali_ctl = chan->pctl->denali_ctl;
 	u32 *denali_pi = chan->pi->denali_pi;
 	u32 cs_map;
@@ -122,179 +316,51 @@
 	u32 row;
 
 	/* Get row number from ddrconfig setting */
-	if (sdram_ch->ddrconfig < 2 || sdram_ch->ddrconfig == 4)
+	if (sdram_ch->cap_info.ddrconfig < 2 ||
+	    sdram_ch->cap_info.ddrconfig == 4)
 		row = 16;
-	else if (sdram_ch->ddrconfig == 3)
+	else if (sdram_ch->cap_info.ddrconfig == 3)
 		row = 14;
 	else
 		row = 15;
 
-	cs_map = (sdram_ch->rank > 1) ? 3 : 1;
-	reduc = (sdram_ch->bw == 2) ? 0 : 1;
+	cs_map = (sdram_ch->cap_info.rank > 1) ? 3 : 1;
+	reduc = (sdram_ch->cap_info.bw == 2) ? 0 : 1;
 
 	/* Set the dram configuration to ctrl */
-	clrsetbits_le32(&denali_ctl[191], 0xF, (12 - sdram_ch->col));
+	clrsetbits_le32(&denali_ctl[191], 0xF, (12 - sdram_ch->cap_info.col));
 	clrsetbits_le32(&denali_ctl[190], (0x3 << 16) | (0x7 << 24),
-			((3 - sdram_ch->bk) << 16) |
+			((3 - sdram_ch->cap_info.bk) << 16) |
 			((16 - row) << 24));
 
 	clrsetbits_le32(&denali_ctl[196], 0x3 | (1 << 16),
 			cs_map | (reduc << 16));
 
 	/* PI_199 PI_COL_DIFF:RW:0:4 */
-	clrsetbits_le32(&denali_pi[199], 0xF, (12 - sdram_ch->col));
+	clrsetbits_le32(&denali_pi[199], 0xF, (12 - sdram_ch->cap_info.col));
 
 	/* PI_155 PI_ROW_DIFF:RW:24:3 PI_BANK_DIFF:RW:16:2 */
 	clrsetbits_le32(&denali_pi[155], (0x3 << 16) | (0x7 << 24),
-			((3 - sdram_ch->bk) << 16) |
+			((3 - sdram_ch->cap_info.bk) << 16) |
 			((16 - row) << 24));
+
+	if (IS_ENABLED(CONFIG_RAM_RK3399_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 ((sdram_ch->rank == 1) && (sdram_params->base.dramtype == DDR3))
+	if (sdram_ch->cap_info.rank == 1 && params->base.dramtype == DDR3)
 		writel(0x2EC7FFFF, &denali_pi[34]);
 }
 
-static void set_ds_odt(const struct chan_info *chan,
-		       const struct rk3399_sdram_params *sdram_params)
-{
-	u32 *denali_phy = chan->publ->denali_phy;
-
-	u32 tsel_idle_en, tsel_wr_en, tsel_rd_en;
-	u32 tsel_idle_select_p, tsel_wr_select_p, tsel_rd_select_p;
-	u32 ca_tsel_wr_select_p, ca_tsel_wr_select_n;
-	u32 tsel_idle_select_n, tsel_wr_select_n, tsel_rd_select_n;
-	u32 reg_value;
-
-	if (sdram_params->base.dramtype == LPDDR4) {
-		tsel_rd_select_p = PHY_DRV_ODT_Hi_Z;
-		tsel_wr_select_p = PHY_DRV_ODT_40;
-		ca_tsel_wr_select_p = PHY_DRV_ODT_40;
-		tsel_idle_select_p = PHY_DRV_ODT_Hi_Z;
-
-		tsel_rd_select_n = PHY_DRV_ODT_240;
-		tsel_wr_select_n = PHY_DRV_ODT_40;
-		ca_tsel_wr_select_n = PHY_DRV_ODT_40;
-		tsel_idle_select_n = PHY_DRV_ODT_240;
-	} else if (sdram_params->base.dramtype == LPDDR3) {
-		tsel_rd_select_p = PHY_DRV_ODT_240;
-		tsel_wr_select_p = PHY_DRV_ODT_34_3;
-		ca_tsel_wr_select_p = PHY_DRV_ODT_48;
-		tsel_idle_select_p = PHY_DRV_ODT_240;
-
-		tsel_rd_select_n = PHY_DRV_ODT_Hi_Z;
-		tsel_wr_select_n = PHY_DRV_ODT_34_3;
-		ca_tsel_wr_select_n = PHY_DRV_ODT_48;
-		tsel_idle_select_n = PHY_DRV_ODT_Hi_Z;
-	} else {
-		tsel_rd_select_p = PHY_DRV_ODT_240;
-		tsel_wr_select_p = PHY_DRV_ODT_34_3;
-		ca_tsel_wr_select_p = PHY_DRV_ODT_34_3;
-		tsel_idle_select_p = PHY_DRV_ODT_240;
-
-		tsel_rd_select_n = PHY_DRV_ODT_240;
-		tsel_wr_select_n = PHY_DRV_ODT_34_3;
-		ca_tsel_wr_select_n = PHY_DRV_ODT_34_3;
-		tsel_idle_select_n = PHY_DRV_ODT_240;
-	}
-
-	if (sdram_params->base.odt == 1)
-		tsel_rd_en = 1;
-	else
-		tsel_rd_en = 0;
-
-	tsel_wr_en = 0;
-	tsel_idle_en = 0;
-
-	/*
-	 * phy_dq_tsel_select_X 24bits DENALI_PHY_6/134/262/390 offset_0
-	 * sets termination values for read/idle cycles and drive strength
-	 * for write cycles for DQ/DM
-	 */
-	reg_value = tsel_rd_select_n | (tsel_rd_select_p << 0x4) |
-		    (tsel_wr_select_n << 8) | (tsel_wr_select_p << 12) |
-		    (tsel_idle_select_n << 16) | (tsel_idle_select_p << 20);
-	clrsetbits_le32(&denali_phy[6], 0xffffff, reg_value);
-	clrsetbits_le32(&denali_phy[134], 0xffffff, reg_value);
-	clrsetbits_le32(&denali_phy[262], 0xffffff, reg_value);
-	clrsetbits_le32(&denali_phy[390], 0xffffff, reg_value);
-
-	/*
-	 * phy_dqs_tsel_select_X 24bits DENALI_PHY_7/135/263/391 offset_0
-	 * sets termination values for read/idle cycles and drive strength
-	 * for write cycles for DQS
-	 */
-	clrsetbits_le32(&denali_phy[7], 0xffffff, reg_value);
-	clrsetbits_le32(&denali_phy[135], 0xffffff, reg_value);
-	clrsetbits_le32(&denali_phy[263], 0xffffff, reg_value);
-	clrsetbits_le32(&denali_phy[391], 0xffffff, reg_value);
-
-	/* phy_adr_tsel_select_ 8bits DENALI_PHY_544/672/800 offset_0 */
-	reg_value = ca_tsel_wr_select_n | (ca_tsel_wr_select_p << 0x4);
-	clrsetbits_le32(&denali_phy[544], 0xff, reg_value);
-	clrsetbits_le32(&denali_phy[672], 0xff, reg_value);
-	clrsetbits_le32(&denali_phy[800], 0xff, reg_value);
-
-	/* phy_pad_addr_drive 8bits DENALI_PHY_928 offset_0 */
-	clrsetbits_le32(&denali_phy[928], 0xff, reg_value);
-
-	/* phy_pad_rst_drive 8bits DENALI_PHY_937 offset_0 */
-	clrsetbits_le32(&denali_phy[937], 0xff, reg_value);
-
-	/* phy_pad_cke_drive 8bits DENALI_PHY_935 offset_0 */
-	clrsetbits_le32(&denali_phy[935], 0xff, reg_value);
-
-	/* phy_pad_cs_drive 8bits DENALI_PHY_939 offset_0 */
-	clrsetbits_le32(&denali_phy[939], 0xff, reg_value);
-
-	/* phy_pad_clk_drive 8bits DENALI_PHY_929 offset_0 */
-	clrsetbits_le32(&denali_phy[929], 0xff, reg_value);
-
-	/* phy_pad_fdbk_drive 23bit DENALI_PHY_924/925 */
-	clrsetbits_le32(&denali_phy[924], 0xff,
-			tsel_wr_select_n | (tsel_wr_select_p << 4));
-	clrsetbits_le32(&denali_phy[925], 0xff,
-			tsel_rd_select_n | (tsel_rd_select_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))
-		<< 16;
-	clrsetbits_le32(&denali_phy[5], 0x7 << 16, reg_value);
-	clrsetbits_le32(&denali_phy[133], 0x7 << 16, reg_value);
-	clrsetbits_le32(&denali_phy[261], 0x7 << 16, reg_value);
-	clrsetbits_le32(&denali_phy[389], 0x7 << 16, reg_value);
-
-	/* phy_dqs_tsel_enable_X 3bits DENALI_PHY_6/134/262/390 offset_24 */
-	reg_value = (tsel_rd_en | (tsel_wr_en << 1) | (tsel_idle_en << 2))
-		<< 24;
-	clrsetbits_le32(&denali_phy[6], 0x7 << 24, reg_value);
-	clrsetbits_le32(&denali_phy[134], 0x7 << 24, reg_value);
-	clrsetbits_le32(&denali_phy[262], 0x7 << 24, reg_value);
-	clrsetbits_le32(&denali_phy[390], 0x7 << 24, reg_value);
-
-	/* phy_adr_tsel_enable_ 1bit DENALI_PHY_518/646/774 offset_8 */
-	reg_value = tsel_wr_en << 8;
-	clrsetbits_le32(&denali_phy[518], 0x1 << 8, reg_value);
-	clrsetbits_le32(&denali_phy[646], 0x1 << 8, reg_value);
-	clrsetbits_le32(&denali_phy[774], 0x1 << 8, reg_value);
-
-	/* phy_pad_addr_term tsel 1bit DENALI_PHY_933 offset_17 */
-	reg_value = tsel_wr_en << 17;
-	clrsetbits_le32(&denali_phy[933], 0x1 << 17, reg_value);
-	/*
-	 * pad_rst/cke/cs/clk_term tsel 1bits
-	 * DENALI_PHY_938/936/940/934 offset_17
-	 */
-	clrsetbits_le32(&denali_phy[938], 0x1 << 17, reg_value);
-	clrsetbits_le32(&denali_phy[936], 0x1 << 17, reg_value);
-	clrsetbits_le32(&denali_phy[940], 0x1 << 17, reg_value);
-	clrsetbits_le32(&denali_phy[934], 0x1 << 17, reg_value);
-
-	/* phy_pad_fdbk_term 1bit DENALI_PHY_930 offset_17 */
-	clrsetbits_le32(&denali_phy[930], 0x1 << 17, reg_value);
-}
-
 static int phy_io_config(const struct chan_info *chan,
-			  const struct rk3399_sdram_params *sdram_params)
+			 const struct rk3399_sdram_params *params, u32 mr5)
 {
 	u32 *denali_phy = chan->publ->denali_phy;
 	u32 vref_mode_dq, vref_value_dq, vref_mode_ac, vref_value_ac;
@@ -303,15 +369,29 @@
 	u32 drv_value, odt_value;
 	u32 speed;
 
-	/* vref setting */
-	if (sdram_params->base.dramtype == LPDDR4) {
-		/* LPDDR4 */
-		vref_mode_dq = 0x6;
-		vref_value_dq = 0x1f;
+	/* vref setting & mode setting */
+	if (params->base.dramtype == LPDDR4) {
+		struct io_setting *io = lpddr4_get_io_settings(params, mr5);
+		u32 rd_vref = io->rd_vref * 1000;
+
+		if (rd_vref < 36700) {
+			/* MODE_LV[2:0] = LPDDR4 (Range 2)*/
+			vref_mode_dq = 0x7;
+			/* MODE[2:0]= LPDDR4 Range 2(0.4*VDDQ) */
+			mode_sel = 0x5;
+			vref_value_dq = (rd_vref - 3300) / 521;
+		} else {
+			/* MODE_LV[2:0] = LPDDR4 (Range 1)*/
+			vref_mode_dq = 0x6;
+			/* MODE[2:0]= LPDDR4 Range 1(0.33*VDDQ) */
+			mode_sel = 0x4;
+			vref_value_dq = (rd_vref - 15300) / 521;
+		}
 		vref_mode_ac = 0x6;
-		vref_value_ac = 0x1f;
-	} else if (sdram_params->base.dramtype == LPDDR3) {
-		if (sdram_params->base.odt == 1) {
+		/* VDDQ/3/2=16.8% */
+		vref_value_ac = 0x3;
+	} 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;
 			odt_value = (readl(&denali_phy[6]) >> 4) & 0xf;
@@ -370,12 +450,14 @@
 		}
 		vref_mode_ac = 0x2;
 		vref_value_ac = 0x1f;
-	} else if (sdram_params->base.dramtype == DDR3) {
+		mode_sel = 0x0;
+	} else if (params->base.dramtype == DDR3) {
 		/* DDR3L */
 		vref_mode_dq = 0x1;
 		vref_value_dq = 0x1f;
 		vref_mode_ac = 0x1;
 		vref_value_ac = 0x1f;
+		mode_sel = 0x1;
 	} else {
 		debug("Unknown DRAM type.\n");
 		return -EINVAL;
@@ -397,15 +479,6 @@
 	/* PHY_915 PHY_PAD_VREF_CTRL_AC 12bits offset_16 */
 	clrsetbits_le32(&denali_phy[915], 0xfff << 16, reg_value << 16);
 
-	if (sdram_params->base.dramtype == LPDDR4)
-		mode_sel = 0x6;
-	else if (sdram_params->base.dramtype == LPDDR3)
-		mode_sel = 0x0;
-	else if (sdram_params->base.dramtype == DDR3)
-		mode_sel = 0x1;
-	else
-		return -EINVAL;
-
 	/* PHY_924 PHY_PAD_FDBK_DRIVE */
 	clrsetbits_le32(&denali_phy[924], 0x7 << 15, mode_sel << 15);
 	/* PHY_926 PHY_PAD_DATA_DRIVE */
@@ -423,13 +496,52 @@
 	/* PHY_939 PHY_PAD_CS_DRIVE */
 	clrsetbits_le32(&denali_phy[939], 0x7 << 14, mode_sel << 14);
 
+	if (IS_ENABLED(CONFIG_RAM_RK3399_LPDDR4)) {
+		/* BOOSTP_EN & BOOSTN_EN */
+		reg_value = ((PHY_BOOSTP_EN << 4) | PHY_BOOSTN_EN);
+		/* PHY_925 PHY_PAD_FDBK_DRIVE2 */
+		clrsetbits_le32(&denali_phy[925], 0xff << 8, reg_value << 8);
+		/* PHY_926 PHY_PAD_DATA_DRIVE */
+		clrsetbits_le32(&denali_phy[926], 0xff << 12, reg_value << 12);
+		/* PHY_927 PHY_PAD_DQS_DRIVE */
+		clrsetbits_le32(&denali_phy[927], 0xff << 14, reg_value << 14);
+		/* PHY_928 PHY_PAD_ADDR_DRIVE */
+		clrsetbits_le32(&denali_phy[928], 0xff << 20, reg_value << 20);
+		/* PHY_929 PHY_PAD_CLK_DRIVE */
+		clrsetbits_le32(&denali_phy[929], 0xff << 22, reg_value << 22);
+		/* PHY_935 PHY_PAD_CKE_DRIVE */
+		clrsetbits_le32(&denali_phy[935], 0xff << 20, reg_value << 20);
+		/* PHY_937 PHY_PAD_RST_DRIVE */
+		clrsetbits_le32(&denali_phy[937], 0xff << 20, reg_value << 20);
+		/* PHY_939 PHY_PAD_CS_DRIVE */
+		clrsetbits_le32(&denali_phy[939], 0xff << 20, reg_value << 20);
+
+		/* SLEWP_EN & SLEWN_EN */
+		reg_value = ((PHY_SLEWP_EN << 3) | PHY_SLEWN_EN);
+		/* PHY_924 PHY_PAD_FDBK_DRIVE */
+		clrsetbits_le32(&denali_phy[924], 0x3f << 8, reg_value << 8);
+		/* PHY_926 PHY_PAD_DATA_DRIVE */
+		clrsetbits_le32(&denali_phy[926], 0x3f, reg_value);
+		/* PHY_927 PHY_PAD_DQS_DRIVE */
+		clrsetbits_le32(&denali_phy[927], 0x3f, reg_value);
+		/* PHY_928 PHY_PAD_ADDR_DRIVE */
+		clrsetbits_le32(&denali_phy[928], 0x3f << 8, reg_value << 8);
+		/* PHY_929 PHY_PAD_CLK_DRIVE */
+		clrsetbits_le32(&denali_phy[929], 0x3f << 8, reg_value << 8);
+		/* PHY_935 PHY_PAD_CKE_DRIVE */
+		clrsetbits_le32(&denali_phy[935], 0x3f << 8, reg_value << 8);
+		/* PHY_937 PHY_PAD_RST_DRIVE */
+		clrsetbits_le32(&denali_phy[937], 0x3f << 8, reg_value << 8);
+		/* PHY_939 PHY_PAD_CS_DRIVE */
+		clrsetbits_le32(&denali_phy[939], 0x3f << 8, reg_value << 8);
+	}
 
 	/* speed setting */
-	if (sdram_params->base.ddr_freq < 400)
+	if (params->base.ddr_freq < 400)
 		speed = 0x0;
-	else if (sdram_params->base.ddr_freq < 800)
+	else if (params->base.ddr_freq < 800)
 		speed = 0x1;
-	else if (sdram_params->base.ddr_freq < 1200)
+	else if (params->base.ddr_freq < 1200)
 		speed = 0x2;
 	else
 		speed = 0x3;
@@ -451,21 +563,304 @@
 	/* PHY_939 PHY_PAD_CS_DRIVE */
 	clrsetbits_le32(&denali_phy[939], 0x3 << 17, speed << 17);
 
+	if (IS_ENABLED(CONFIG_RAM_RK3399_LPDDR4)) {
+		/* RX_CM_INPUT */
+		reg_value = PHY_RX_CM_INPUT;
+		/* PHY_924 PHY_PAD_FDBK_DRIVE */
+		clrsetbits_le32(&denali_phy[924], 0x1 << 14, reg_value << 14);
+		/* PHY_926 PHY_PAD_DATA_DRIVE */
+		clrsetbits_le32(&denali_phy[926], 0x1 << 11, reg_value << 11);
+		/* PHY_927 PHY_PAD_DQS_DRIVE */
+		clrsetbits_le32(&denali_phy[927], 0x1 << 13, reg_value << 13);
+		/* PHY_928 PHY_PAD_ADDR_DRIVE */
+		clrsetbits_le32(&denali_phy[928], 0x1 << 19, reg_value << 19);
+		/* PHY_929 PHY_PAD_CLK_DRIVE */
+		clrsetbits_le32(&denali_phy[929], 0x1 << 21, reg_value << 21);
+		/* PHY_935 PHY_PAD_CKE_DRIVE */
+		clrsetbits_le32(&denali_phy[935], 0x1 << 19, reg_value << 19);
+		/* PHY_937 PHY_PAD_RST_DRIVE */
+		clrsetbits_le32(&denali_phy[937], 0x1 << 19, reg_value << 19);
+		/* PHY_939 PHY_PAD_CS_DRIVE */
+		clrsetbits_le32(&denali_phy[939], 0x1 << 19, reg_value << 19);
+	}
+
 	return 0;
 }
 
-static int pctl_cfg(const struct chan_info *chan, u32 channel,
-		    const struct rk3399_sdram_params *sdram_params)
+static void set_ds_odt(const struct chan_info *chan,
+		       struct rk3399_sdram_params *params,
+		       bool ctl_phy_reg, u32 mr5)
+{
+	u32 *denali_phy = get_denali_phy(chan, params, ctl_phy_reg);
+	u32 *denali_ctl = get_denali_ctl(chan, params, ctl_phy_reg);
+	u32 tsel_idle_en, tsel_wr_en, tsel_rd_en;
+	u32 tsel_idle_select_p, tsel_rd_select_p;
+	u32 tsel_idle_select_n, tsel_rd_select_n;
+	u32 tsel_wr_select_dq_p, tsel_wr_select_ca_p;
+	u32 tsel_wr_select_dq_n, tsel_wr_select_ca_n;
+	u32 tsel_ckcs_select_p, tsel_ckcs_select_n;
+	struct io_setting *io = NULL;
+	u32 soc_odt = 0;
+	u32 reg_value;
+
+	if (params->base.dramtype == LPDDR4) {
+		io = lpddr4_get_io_settings(params, mr5);
+
+		tsel_rd_select_p = PHY_DRV_ODT_HI_Z;
+		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_wr_select_dq_p = io->wr_dq_drv;
+		tsel_wr_select_dq_n = PHY_DRV_ODT_40;
+
+		tsel_wr_select_ca_p = io->wr_ca_drv;
+		tsel_wr_select_ca_n = PHY_DRV_ODT_40;
+
+		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;
+			break;
+		case PHY_DRV_ODT_120:
+			soc_odt = 2;
+			break;
+		case PHY_DRV_ODT_80:
+			soc_odt = 3;
+			break;
+		case PHY_DRV_ODT_60:
+			soc_odt = 4;
+			break;
+		case PHY_DRV_ODT_48:
+			soc_odt = 5;
+			break;
+		case PHY_DRV_ODT_40:
+			soc_odt = 6;
+			break;
+		case PHY_DRV_ODT_34_3:
+			soc_odt = 6;
+			printf("%s: Unable to support LPDDR4 MR22 Soc ODT\n",
+			       __func__);
+			break;
+		case PHY_DRV_ODT_HI_Z:
+		default:
+			soc_odt = 0;
+			break;
+		}
+	} else if (params->base.dramtype == LPDDR3) {
+		tsel_rd_select_p = PHY_DRV_ODT_240;
+		tsel_rd_select_n = PHY_DRV_ODT_HI_Z;
+
+		tsel_idle_select_p = PHY_DRV_ODT_240;
+		tsel_idle_select_n = PHY_DRV_ODT_HI_Z;
+
+		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_ckcs_select_p = PHY_DRV_ODT_34_3;
+		tsel_ckcs_select_n = PHY_DRV_ODT_34_3;
+	} else {
+		tsel_rd_select_p = PHY_DRV_ODT_240;
+		tsel_rd_select_n = PHY_DRV_ODT_240;
+
+		tsel_idle_select_p = PHY_DRV_ODT_240;
+		tsel_idle_select_n = PHY_DRV_ODT_240;
+
+		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_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;
+	}
+
+	if (params->base.odt == 1) {
+		tsel_rd_en = 1;
+
+		if (params->base.dramtype == LPDDR4)
+			tsel_rd_en = io->rd_odt_en;
+	} else {
+		tsel_rd_en = 0;
+	}
+
+	tsel_wr_en = 0;
+	tsel_idle_en = 0;
+
+	/* F0_0 */
+	clrsetbits_le32(&denali_ctl[145], 0xFF << 16,
+			(soc_odt | (CS0_MR22_VAL << 3)) << 16);
+	/* F2_0, F1_0 */
+	clrsetbits_le32(&denali_ctl[146], 0xFF00FF,
+			((soc_odt | (CS0_MR22_VAL << 3)) << 16) |
+			(soc_odt | (CS0_MR22_VAL << 3)));
+	/* F0_1 */
+	clrsetbits_le32(&denali_ctl[159], 0xFF << 16,
+			(soc_odt | (CS1_MR22_VAL << 3)) << 16);
+	/* F2_1, F1_1 */
+	clrsetbits_le32(&denali_ctl[160], 0xFF00FF,
+			((soc_odt | (CS1_MR22_VAL << 3)) << 16) |
+			(soc_odt | (CS1_MR22_VAL << 3)));
+
+	/*
+	 * phy_dq_tsel_select_X 24bits DENALI_PHY_6/134/262/390 offset_0
+	 * sets termination values for read/idle cycles and drive strength
+	 * for write cycles for DQ/DM
+	 */
+	reg_value = tsel_rd_select_n | (tsel_rd_select_p << 0x4) |
+		    (tsel_wr_select_dq_n << 8) | (tsel_wr_select_dq_p << 12) |
+		    (tsel_idle_select_n << 16) | (tsel_idle_select_p << 20);
+	clrsetbits_le32(&denali_phy[6], 0xffffff, reg_value);
+	clrsetbits_le32(&denali_phy[134], 0xffffff, reg_value);
+	clrsetbits_le32(&denali_phy[262], 0xffffff, reg_value);
+	clrsetbits_le32(&denali_phy[390], 0xffffff, reg_value);
+
+	/*
+	 * phy_dqs_tsel_select_X 24bits DENALI_PHY_7/135/263/391 offset_0
+	 * sets termination values for read/idle cycles and drive strength
+	 * for write cycles for DQS
+	 */
+	clrsetbits_le32(&denali_phy[7], 0xffffff, reg_value);
+	clrsetbits_le32(&denali_phy[135], 0xffffff, reg_value);
+	clrsetbits_le32(&denali_phy[263], 0xffffff, reg_value);
+	clrsetbits_le32(&denali_phy[391], 0xffffff, reg_value);
+
+	/* 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)) {
+		/* LPDDR4 these register read always return 0, so
+		 * can not use clrsetbits_le32(), need to write32
+		 */
+		writel((0x300 << 8) | reg_value, &denali_phy[544]);
+		writel((0x300 << 8) | reg_value, &denali_phy[672]);
+		writel((0x300 << 8) | reg_value, &denali_phy[800]);
+	} else {
+		clrsetbits_le32(&denali_phy[544], 0xff, reg_value);
+		clrsetbits_le32(&denali_phy[672], 0xff, reg_value);
+		clrsetbits_le32(&denali_phy[800], 0xff, reg_value);
+	}
+
+	/* phy_pad_addr_drive 8bits DENALI_PHY_928 offset_0 */
+	clrsetbits_le32(&denali_phy[928], 0xff, reg_value);
+
+	/* phy_pad_rst_drive 8bits DENALI_PHY_937 offset_0 */
+	if (!ctl_phy_reg)
+		clrsetbits_le32(&denali_phy[937], 0xff, reg_value);
+
+	/* phy_pad_cke_drive 8bits DENALI_PHY_935 offset_0 */
+	clrsetbits_le32(&denali_phy[935], 0xff, reg_value);
+
+	/* phy_pad_cs_drive 8bits DENALI_PHY_939 offset_0 */
+	clrsetbits_le32(&denali_phy[939], 0xff,
+			tsel_ckcs_select_n | (tsel_ckcs_select_p << 0x4));
+
+	/* phy_pad_clk_drive 8bits DENALI_PHY_929 offset_0 */
+	clrsetbits_le32(&denali_phy[929], 0xff,
+			tsel_ckcs_select_n | (tsel_ckcs_select_p << 0x4));
+
+	/* 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));
+	clrsetbits_le32(&denali_phy[925], 0xff,
+			tsel_rd_select_n | (tsel_rd_select_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))
+		<< 16;
+	clrsetbits_le32(&denali_phy[5], 0x7 << 16, reg_value);
+	clrsetbits_le32(&denali_phy[133], 0x7 << 16, reg_value);
+	clrsetbits_le32(&denali_phy[261], 0x7 << 16, reg_value);
+	clrsetbits_le32(&denali_phy[389], 0x7 << 16, reg_value);
+
+	/* phy_dqs_tsel_enable_X 3bits DENALI_PHY_6/134/262/390 offset_24 */
+	reg_value = (tsel_rd_en | (tsel_wr_en << 1) | (tsel_idle_en << 2))
+		<< 24;
+	clrsetbits_le32(&denali_phy[6], 0x7 << 24, reg_value);
+	clrsetbits_le32(&denali_phy[134], 0x7 << 24, reg_value);
+	clrsetbits_le32(&denali_phy[262], 0x7 << 24, reg_value);
+	clrsetbits_le32(&denali_phy[390], 0x7 << 24, reg_value);
+
+	/* phy_adr_tsel_enable_ 1bit DENALI_PHY_518/646/774 offset_8 */
+	reg_value = tsel_wr_en << 8;
+	clrsetbits_le32(&denali_phy[518], 0x1 << 8, reg_value);
+	clrsetbits_le32(&denali_phy[646], 0x1 << 8, reg_value);
+	clrsetbits_le32(&denali_phy[774], 0x1 << 8, reg_value);
+
+	/* phy_pad_addr_term tsel 1bit DENALI_PHY_933 offset_17 */
+	reg_value = tsel_wr_en << 17;
+	clrsetbits_le32(&denali_phy[933], 0x1 << 17, reg_value);
+	/*
+	 * pad_rst/cke/cs/clk_term tsel 1bits
+	 * DENALI_PHY_938/936/940/934 offset_17
+	 */
+	clrsetbits_le32(&denali_phy[938], 0x1 << 17, reg_value);
+	clrsetbits_le32(&denali_phy[936], 0x1 << 17, reg_value);
+	clrsetbits_le32(&denali_phy[940], 0x1 << 17, reg_value);
+	clrsetbits_le32(&denali_phy[934], 0x1 << 17, reg_value);
+
+	/* phy_pad_fdbk_term 1bit DENALI_PHY_930 offset_17 */
+	clrsetbits_le32(&denali_phy[930], 0x1 << 17, reg_value);
+
+	phy_io_config(chan, params, mr5);
+}
+
+static void pctl_start(struct dram_info *dram, u8 channel)
+{
+	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);
+	u32 count = 0;
+	u32 byte, tmp;
+
+	writel(0x01000000, &ddrc0_con);
+
+	clrsetbits_le32(&denali_phy[957], 0x3 << 24, 0x2 << 24);
+
+	while (!(readl(&denali_ctl[203]) & (1 << 3))) {
+		if (count > 1000) {
+			printf("%s: Failed to init pctl for channel %d\n",
+			       __func__, channel);
+			while (1)
+				;
+		}
+
+		udelay(1);
+		count++;
+	}
+
+	writel(0x01000100, &ddrc0_con);
+
+	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_phy[58 + (128 * byte)], 0xffff, tmp);
+	}
+
+	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,
+		    u32 channel, struct rk3399_sdram_params *params)
 {
 	u32 *denali_ctl = chan->pctl->denali_ctl;
 	u32 *denali_pi = chan->pi->denali_pi;
 	u32 *denali_phy = chan->publ->denali_phy;
-	const u32 *params_ctl = sdram_params->pctl_regs.denali_ctl;
-	const u32 *params_phy = sdram_params->phy_regs.denali_phy;
+	const u32 *params_ctl = params->pctl_regs.denali_ctl;
+	const u32 *params_phy = params->phy_regs.denali_phy;
 	u32 tmp, tmp1, tmp2;
-	u32 pwrup_srefresh_exit;
-	int ret;
-	const ulong timeout_ms = 200;
 
 	/*
 	 * work around controller bug:
@@ -474,16 +869,38 @@
 	copy_to_reg(&denali_ctl[1], &params_ctl[1],
 		    sizeof(struct rk3399_ddr_pctl_regs) - 4);
 	writel(params_ctl[0], &denali_ctl[0]);
-	copy_to_reg(denali_pi, &sdram_params->pi_regs.denali_pi[0],
+
+	/*
+	 * two channel init at the same time, then ZQ Cal Start
+	 * at the same time, it will use the same RZQ, but cannot
+	 * start at the same time.
+	 *
+	 * So, increase tINIT3 for channel 1, will avoid two
+	 * channel ZQ Cal Start at the same time
+	 */
+	if (params->base.dramtype == LPDDR4 && channel == 1) {
+		tmp = ((params->base.ddr_freq * MHz + 999) / 1000);
+		tmp1 = readl(&denali_ctl[14]);
+		writel(tmp + tmp1, &denali_ctl[14]);
+	}
+
+	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, sdram_params);
+	set_memory_map(chan, channel, params);
 
-	writel(sdram_params->phy_regs.denali_phy[910], &denali_phy[910]);
-	writel(sdram_params->phy_regs.denali_phy[911], &denali_phy[911]);
-	writel(sdram_params->phy_regs.denali_phy[912], &denali_phy[912]);
+	writel(params->phy_regs.denali_phy[910], &denali_phy[910]);
+	writel(params->phy_regs.denali_phy[911], &denali_phy[911]);
+	writel(params->phy_regs.denali_phy[912], &denali_phy[912]);
 
-	pwrup_srefresh_exit = readl(&denali_ctl[68]) & PWRUP_SREFRESH_EXIT;
+	if (IS_ENABLED(CONFIG_RAM_RK3399_LPDDR4)) {
+		writel(params->phy_regs.denali_phy[898], &denali_phy[898]);
+		writel(params->phy_regs.denali_phy[919], &denali_phy[919]);
+	}
+
+	dram->pwrup_srefresh_exit[channel] = readl(&denali_ctl[68]) &
+					     PWRUP_SREFRESH_EXIT;
 	clrbits_le32(&denali_ctl[68], PWRUP_SREFRESH_EXIT);
 
 	/* PHY_DLL_RST_EN */
@@ -492,16 +909,22 @@
 	setbits_le32(&denali_pi[0], START);
 	setbits_le32(&denali_ctl[0], START);
 
-	/* Wating for phy DLL lock */
-	while (1) {
-		tmp = readl(&denali_phy[920]);
-		tmp1 = readl(&denali_phy[921]);
-		tmp2 = readl(&denali_phy[922]);
-		if ((((tmp >> 16) & 0x1) == 0x1) &&
-		    (((tmp1 >> 16) & 0x1) == 0x1) &&
-		    (((tmp1 >> 0) & 0x1) == 0x1) &&
-		    (((tmp2 >> 0) & 0x1) == 0x1))
-			break;
+	/**
+	 * LPDDR4 use PLL bypass mode for init
+	 * not need to wait for the PLL to lock
+	 */
+	if (params->base.dramtype != LPDDR4) {
+		/* Waiting for phy DLL lock */
+		while (1) {
+			tmp = readl(&denali_phy[920]);
+			tmp1 = readl(&denali_phy[921]);
+			tmp2 = readl(&denali_phy[922]);
+			if ((((tmp >> 16) & 0x1) == 0x1) &&
+			    (((tmp1 >> 16) & 0x1) == 0x1) &&
+			    (((tmp1 >> 0) & 0x1) == 0x1) &&
+			    (((tmp2 >> 0) & 0x1) == 0x1))
+				break;
+		}
 	}
 
 	copy_to_reg(&denali_phy[896], &params_phy[896], (958 - 895) * 4);
@@ -512,7 +935,7 @@
 	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, sdram_params);
+	set_ds_odt(chan, params, true, 0);
 
 	/*
 	 * phy_dqs_tsel_wr_timing_X 8bits DENALI_PHY_84/212/340/468 offset_8
@@ -540,26 +963,6 @@
 	tmp = (readl(&denali_phy[467]) >> 16) & 0xff;
 	clrsetbits_le32(&denali_phy[467], 0xff << 16, (tmp + 0x10) << 16);
 
-	ret = phy_io_config(chan, sdram_params);
-	if (ret)
-		return ret;
-
-	/* PHY_DLL_RST_EN */
-	clrsetbits_le32(&denali_phy[957], 0x3 << 24, 0x2 << 24);
-
-	/* Wating for PHY and DRAM init complete */
-	tmp = get_timer(0);
-	do {
-		if (get_timer(tmp) > timeout_ms) {
-			pr_err("DRAM (%s): phy failed to lock within  %ld ms\n",
-			      __func__, timeout_ms);
-			return -ETIME;
-		}
-	} while (!(readl(&denali_ctl[203]) & (1 << 3)));
-	debug("DRAM (%s): phy locked after %ld ms\n", __func__, get_timer(tmp));
-
-	clrsetbits_le32(&denali_ctl[68], PWRUP_SREFRESH_EXIT,
-			pwrup_srefresh_exit);
 	return 0;
 }
 
@@ -569,7 +972,7 @@
 	u32 *denali_phy = chan->publ->denali_phy;
 
 	/* PHY_84 PHY_PER_CS_TRAINING_EN_0 1bit offset_16 */
-	if ((readl(&denali_phy[84])>>16) & 1) {
+	if ((readl(&denali_phy[84]) >> 16) & 1) {
 		/*
 		 * PHY_8/136/264/392
 		 * phy_per_cs_training_index_X 1bit offset_24
@@ -611,18 +1014,32 @@
 }
 
 static int data_training_ca(const struct chan_info *chan, u32 channel,
-			    const struct rk3399_sdram_params *sdram_params)
+			    const struct rk3399_sdram_params *params)
 {
 	u32 *denali_pi = chan->pi->denali_pi;
 	u32 *denali_phy = chan->publ->denali_phy;
 	u32 i, tmp;
 	u32 obs_0, obs_1, obs_2, obs_err = 0;
-	u32 rank = sdram_params->ch[channel].rank;
+	u32 rank = params->ch[channel].cap_info.rank;
+	u32 rank_mask;
 
-	for (i = 0; i < rank; i++) {
+	/* clear interrupt,PI_175 PI_INT_ACK:WR:0:17 */
+	writel(0x00003f7c, (&denali_pi[175]));
+
+	if (params->base.dramtype == LPDDR4)
+		rank_mask = (rank == 1) ? 0x5 : 0xf;
+	else
+		rank_mask = (rank == 1) ? 0x1 : 0x3;
+
+	for (i = 0; i < 4; i++) {
+		if (!(rank_mask & (1 << i)))
+			continue;
+
 		select_per_cs_training_index(chan, i);
+
 		/* PI_100 PI_CALVL_EN:RW:8:2 */
 		clrsetbits_le32(&denali_pi[100], 0x3 << 8, 0x2 << 8);
+
 		/* PI_92 PI_CALVL_REQ:WR:16:1,PI_CALVL_CS:RW:24:2 */
 		clrsetbits_le32(&denali_pi[92],
 				(0x1 << 16) | (0x3 << 24),
@@ -646,33 +1063,40 @@
 			if ((((tmp >> 11) & 0x1) == 0x1) &&
 			    (((tmp >> 13) & 0x1) == 0x1) &&
 			    (((tmp >> 5) & 0x1) == 0x0) &&
-			    (obs_err == 0))
+			    obs_err == 0)
 				break;
 			else if ((((tmp >> 5) & 0x1) == 0x1) ||
 				 (obs_err == 1))
 				return -EIO;
 		}
+
 		/* clear interrupt,PI_175 PI_INT_ACK:WR:0:17 */
 		writel(0x00003f7c, (&denali_pi[175]));
 	}
+
 	clrbits_le32(&denali_pi[100], 0x3 << 8);
 
 	return 0;
 }
 
 static int data_training_wl(const struct chan_info *chan, u32 channel,
-			    const struct rk3399_sdram_params *sdram_params)
+			    const struct rk3399_sdram_params *params)
 {
 	u32 *denali_pi = chan->pi->denali_pi;
 	u32 *denali_phy = chan->publ->denali_phy;
 	u32 i, tmp;
 	u32 obs_0, obs_1, obs_2, obs_3, obs_err = 0;
-	u32 rank = sdram_params->ch[channel].rank;
+	u32 rank = params->ch[channel].cap_info.rank;
+
+	/* clear interrupt,PI_175 PI_INT_ACK:WR:0:17 */
+	writel(0x00003f7c, (&denali_pi[175]));
 
 	for (i = 0; i < rank; i++) {
 		select_per_cs_training_index(chan, i);
+
 		/* PI_60 PI_WRLVL_EN:RW:8:2 */
 		clrsetbits_le32(&denali_pi[60], 0x3 << 8, 0x2 << 8);
+
 		/* PI_59 PI_WRLVL_REQ:WR:8:1,PI_WRLVL_CS:RW:16:2 */
 		clrsetbits_le32(&denali_pi[59],
 				(0x1 << 8) | (0x3 << 16),
@@ -700,12 +1124,13 @@
 			if ((((tmp >> 10) & 0x1) == 0x1) &&
 			    (((tmp >> 13) & 0x1) == 0x1) &&
 			    (((tmp >> 4) & 0x1) == 0x0) &&
-			    (obs_err == 0))
+			    obs_err == 0)
 				break;
 			else if ((((tmp >> 4) & 0x1) == 0x1) ||
 				 (obs_err == 1))
 				return -EIO;
 		}
+
 		/* clear interrupt,PI_175 PI_INT_ACK:WR:0:17 */
 		writel(0x00003f7c, (&denali_pi[175]));
 	}
@@ -717,18 +1142,23 @@
 }
 
 static int data_training_rg(const struct chan_info *chan, u32 channel,
-			    const struct rk3399_sdram_params *sdram_params)
+			    const struct rk3399_sdram_params *params)
 {
 	u32 *denali_pi = chan->pi->denali_pi;
 	u32 *denali_phy = chan->publ->denali_phy;
 	u32 i, tmp;
 	u32 obs_0, obs_1, obs_2, obs_3, obs_err = 0;
-	u32 rank = sdram_params->ch[channel].rank;
+	u32 rank = params->ch[channel].cap_info.rank;
+
+	/* clear interrupt,PI_175 PI_INT_ACK:WR:0:17 */
+	writel(0x00003f7c, (&denali_pi[175]));
 
 	for (i = 0; i < rank; i++) {
 		select_per_cs_training_index(chan, i);
+
 		/* PI_80 PI_RDLVL_GATE_EN:RW:24:2 */
 		clrsetbits_le32(&denali_pi[80], 0x3 << 24, 0x2 << 24);
+
 		/*
 		 * PI_74 PI_RDLVL_GATE_REQ:WR:16:1
 		 * PI_RDLVL_CS:RW:24:2
@@ -759,31 +1189,38 @@
 			if ((((tmp >> 9) & 0x1) == 0x1) &&
 			    (((tmp >> 13) & 0x1) == 0x1) &&
 			    (((tmp >> 3) & 0x1) == 0x0) &&
-			    (obs_err == 0))
+			    obs_err == 0)
 				break;
 			else if ((((tmp >> 3) & 0x1) == 0x1) ||
 				 (obs_err == 1))
 				return -EIO;
 		}
+
 		/* clear interrupt,PI_175 PI_INT_ACK:WR:0:17 */
 		writel(0x00003f7c, (&denali_pi[175]));
 	}
+
 	clrbits_le32(&denali_pi[80], 0x3 << 24);
 
 	return 0;
 }
 
 static int data_training_rl(const struct chan_info *chan, u32 channel,
-			    const struct rk3399_sdram_params *sdram_params)
+			    const struct rk3399_sdram_params *params)
 {
 	u32 *denali_pi = chan->pi->denali_pi;
 	u32 i, tmp;
-	u32 rank = sdram_params->ch[channel].rank;
+	u32 rank = params->ch[channel].cap_info.rank;
+
+	/* clear interrupt,PI_175 PI_INT_ACK:WR:0:17 */
+	writel(0x00003f7c, (&denali_pi[175]));
 
 	for (i = 0; i < rank; i++) {
 		select_per_cs_training_index(chan, i);
+
 		/* PI_80 PI_RDLVL_EN:RW:16:2 */
 		clrsetbits_le32(&denali_pi[80], 0x3 << 16, 0x2 << 16);
+
 		/* PI_74 PI_RDLVL_REQ:WR:8:1,PI_RDLVL_CS:RW:24:2 */
 		clrsetbits_le32(&denali_pi[74],
 				(0x1 << 8) | (0x3 << 24),
@@ -806,30 +1243,47 @@
 			else if (((tmp >> 2) & 0x1) == 0x1)
 				return -EIO;
 		}
+
 		/* clear interrupt,PI_175 PI_INT_ACK:WR:0:17 */
 		writel(0x00003f7c, (&denali_pi[175]));
 	}
+
 	clrbits_le32(&denali_pi[80], 0x3 << 16);
 
 	return 0;
 }
 
 static int data_training_wdql(const struct chan_info *chan, u32 channel,
-			      const struct rk3399_sdram_params *sdram_params)
+			      const struct rk3399_sdram_params *params)
 {
 	u32 *denali_pi = chan->pi->denali_pi;
 	u32 i, tmp;
-	u32 rank = sdram_params->ch[channel].rank;
+	u32 rank = params->ch[channel].cap_info.rank;
+	u32 rank_mask;
 
-	for (i = 0; i < rank; i++) {
+	/* clear interrupt,PI_175 PI_INT_ACK:WR:0:17 */
+	writel(0x00003f7c, (&denali_pi[175]));
+
+	if (params->base.dramtype == LPDDR4)
+		rank_mask = (rank == 1) ? 0x5 : 0xf;
+	else
+		rank_mask = (rank == 1) ? 0x1 : 0x3;
+
+	for (i = 0; i < 4; i++) {
+		if (!(rank_mask & (1 << i)))
+			continue;
+
 		select_per_cs_training_index(chan, i);
+
 		/*
 		 * disable PI_WDQLVL_VREF_EN before wdq leveling?
 		 * PI_181 PI_WDQLVL_VREF_EN:RW:8:1
 		 */
 		clrbits_le32(&denali_pi[181], 0x1 << 8);
+
 		/* PI_124 PI_WDQLVL_EN:RW:16:2 */
 		clrsetbits_le32(&denali_pi[124], 0x3 << 16, 0x2 << 16);
+
 		/* PI_121 PI_WDQLVL_REQ:WR:8:1,PI_WDQLVL_CS:RW:16:2 */
 		clrsetbits_le32(&denali_pi[121],
 				(0x1 << 8) | (0x3 << 16),
@@ -846,32 +1300,36 @@
 			else if (((tmp >> 6) & 0x1) == 0x1)
 				return -EIO;
 		}
+
 		/* clear interrupt,PI_175 PI_INT_ACK:WR:0:17 */
 		writel(0x00003f7c, (&denali_pi[175]));
 	}
+
 	clrbits_le32(&denali_pi[124], 0x3 << 16);
 
 	return 0;
 }
 
-static int data_training(const struct chan_info *chan, u32 channel,
-			 const struct rk3399_sdram_params *sdram_params,
+static int data_training(struct dram_info *dram, u32 channel,
+			 const struct rk3399_sdram_params *params,
 			 u32 training_flag)
 {
+	struct chan_info *chan = &dram->chan[channel];
 	u32 *denali_phy = chan->publ->denali_phy;
+	int ret;
 
 	/* PHY_927 PHY_PAD_DQS_DRIVE  RPULL offset_22 */
 	setbits_le32(&denali_phy[927], (1 << 22));
 
 	if (training_flag == PI_FULL_TRAINING) {
-		if (sdram_params->base.dramtype == LPDDR4) {
-			training_flag = PI_CA_TRAINING | PI_WRITE_LEVELING |
+		if (params->base.dramtype == LPDDR4) {
+			training_flag = PI_WRITE_LEVELING |
 					PI_READ_GATE_TRAINING |
 					PI_READ_LEVELING | PI_WDQ_LEVELING;
-		} else if (sdram_params->base.dramtype == LPDDR3) {
+		} else if (params->base.dramtype == LPDDR3) {
 			training_flag = PI_CA_TRAINING | PI_WRITE_LEVELING |
 					PI_READ_GATE_TRAINING;
-		} else if (sdram_params->base.dramtype == DDR3) {
+		} else if (params->base.dramtype == DDR3) {
 			training_flag = PI_WRITE_LEVELING |
 					PI_READ_GATE_TRAINING |
 					PI_READ_LEVELING;
@@ -879,24 +1337,49 @@
 	}
 
 	/* ca training(LPDDR4,LPDDR3 support) */
-	if ((training_flag & PI_CA_TRAINING) == PI_CA_TRAINING)
-		data_training_ca(chan, channel, sdram_params);
+	if ((training_flag & PI_CA_TRAINING) == PI_CA_TRAINING) {
+		ret = data_training_ca(chan, channel, params);
+		if (ret < 0) {
+			debug("%s: data training ca failed\n", __func__);
+			return ret;
+		}
+	}
 
 	/* write leveling(LPDDR4,LPDDR3,DDR3 support) */
-	if ((training_flag & PI_WRITE_LEVELING) == PI_WRITE_LEVELING)
-		data_training_wl(chan, channel, sdram_params);
+	if ((training_flag & PI_WRITE_LEVELING) == PI_WRITE_LEVELING) {
+		ret = data_training_wl(chan, channel, params);
+		if (ret < 0) {
+			debug("%s: data training wl failed\n", __func__);
+			return ret;
+		}
+	}
 
 	/* read gate training(LPDDR4,LPDDR3,DDR3 support) */
-	if ((training_flag & PI_READ_GATE_TRAINING) == PI_READ_GATE_TRAINING)
-		data_training_rg(chan, channel, sdram_params);
+	if ((training_flag & PI_READ_GATE_TRAINING) == PI_READ_GATE_TRAINING) {
+		ret = data_training_rg(chan, channel, params);
+		if (ret < 0) {
+			debug("%s: data training rg failed\n", __func__);
+			return ret;
+		}
+	}
 
 	/* read leveling(LPDDR4,LPDDR3,DDR3 support) */
-	if ((training_flag & PI_READ_LEVELING) == PI_READ_LEVELING)
-		data_training_rl(chan, channel, sdram_params);
+	if ((training_flag & PI_READ_LEVELING) == PI_READ_LEVELING) {
+		ret = data_training_rl(chan, channel, params);
+		if (ret < 0) {
+			debug("%s: data training rl failed\n", __func__);
+			return ret;
+		}
+	}
 
 	/* wdq leveling(LPDDR4 support) */
-	if ((training_flag & PI_WDQ_LEVELING) == PI_WDQ_LEVELING)
-		data_training_wdql(chan, channel, sdram_params);
+	if ((training_flag & PI_WDQ_LEVELING) == PI_WDQ_LEVELING) {
+		ret = data_training_wdql(chan, channel, params);
+		if (ret < 0) {
+			debug("%s: data training wdql failed\n", __func__);
+			return ret;
+		}
+	}
 
 	/* PHY_927 PHY_PAD_DQS_DRIVE  RPULL offset_22 */
 	clrbits_le32(&denali_phy[927], (1 << 22));
@@ -905,7 +1388,7 @@
 }
 
 static void set_ddrconfig(const struct chan_info *chan,
-			  const struct rk3399_sdram_params *sdram_params,
+			  const struct rk3399_sdram_params *params,
 			  unsigned char channel, u32 ddrconfig)
 {
 	/* only need to set ddrconfig */
@@ -913,14 +1396,14 @@
 	unsigned int cs0_cap = 0;
 	unsigned int cs1_cap = 0;
 
-	cs0_cap = (1 << (sdram_params->ch[channel].cs0_row
-			+ sdram_params->ch[channel].col
-			+ sdram_params->ch[channel].bk
-			+ sdram_params->ch[channel].bw - 20));
-	if (sdram_params->ch[channel].rank > 1)
-		cs1_cap = cs0_cap >> (sdram_params->ch[channel].cs0_row
-				- sdram_params->ch[channel].cs1_row);
-	if (sdram_params->ch[channel].row_3_4) {
+	cs0_cap = (1 << (params->ch[channel].cap_info.cs0_row
+			+ params->ch[channel].cap_info.col
+			+ params->ch[channel].cap_info.bk
+			+ params->ch[channel].cap_info.bw - 20));
+	if (params->ch[channel].cap_info.rank > 1)
+		cs1_cap = cs0_cap >> (params->ch[channel].cap_info.cs0_row
+				- params->ch[channel].cap_info.cs1_row);
+	if (params->ch[channel].cap_info.row_3_4) {
 		cs0_cap = cs0_cap * 3 / 4;
 		cs1_cap = cs1_cap * 3 / 4;
 	}
@@ -931,57 +1414,72 @@
 }
 
 static void dram_all_config(struct dram_info *dram,
-			    const struct rk3399_sdram_params *sdram_params)
+			    const struct rk3399_sdram_params *params)
 {
-	u32 sys_reg = 0;
+	u32 sys_reg2 = 0;
+	u32 sys_reg3 = 0;
 	unsigned int channel, idx;
 
-	sys_reg |= sdram_params->base.dramtype << SYS_REG_DDRTYPE_SHIFT;
-	sys_reg |= (sdram_params->base.num_channels - 1)
-		    << SYS_REG_NUM_CH_SHIFT;
+	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 < sdram_params->base.num_channels) && (channel < 2);
+	     (idx < params->base.num_channels) && (channel < 2);
 	     channel++) {
-		const struct rk3399_sdram_channel *info =
-			&sdram_params->ch[channel];
+		const struct rk3399_sdram_channel *info = &params->ch[channel];
 		struct rk3399_msch_regs *ddr_msch_regs;
 		const struct rk3399_msch_timings *noc_timing;
 
-		if (sdram_params->ch[channel].col == 0)
+		if (params->ch[channel].cap_info.col == 0)
 			continue;
 		idx++;
-		sys_reg |= info->row_3_4 << SYS_REG_ROW_3_4_SHIFT(channel);
-		sys_reg |= 1 << SYS_REG_CHINFO_SHIFT(channel);
-		sys_reg |= (info->rank - 1) << SYS_REG_RANK_SHIFT(channel);
-		sys_reg |= (info->col - 9) << SYS_REG_COL_SHIFT(channel);
-		sys_reg |= info->bk == 3 ? 0 : 1 << SYS_REG_BK_SHIFT(channel);
-		sys_reg |= (info->cs0_row - 13) << SYS_REG_CS0_ROW_SHIFT(channel);
-		sys_reg |= (info->cs1_row - 13) << SYS_REG_CS1_ROW_SHIFT(channel);
-		sys_reg |= (2 >> info->bw) << SYS_REG_BW_SHIFT(channel);
-		sys_reg |= (2 >> info->dbw) << SYS_REG_DBW_SHIFT(channel);
+		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);
 
 		ddr_msch_regs = dram->chan[channel].msch;
-		noc_timing = &sdram_params->ch[channel].noc_timings;
+		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,
+		writel(noc_timing->ddrtimingc0.d32,
 		       &ddr_msch_regs->ddrtimingc0);
 		writel(noc_timing->devtodev0,
 		       &ddr_msch_regs->devtodev0);
-		writel(noc_timing->ddrmode,
+		writel(noc_timing->ddrmode.d32,
 		       &ddr_msch_regs->ddrmode);
 
-		/* rank 1 memory clock disable (dfi_dram_clk_disable = 1) */
-		if (sdram_params->ch[channel].rank == 1)
+		/**
+		 * rank 1 memory clock disable (dfi_dram_clk_disable = 1)
+		 *
+		 * The hardware for LPDDR4 with
+		 * - CLK0P/N connect to lower 16-bits
+		 * - CLK1P/N connect to higher 16-bits
+		 *
+		 * dfi dram clk is configured via CLK1P/N, so disabling
+		 * dfi dram clk will disable the CLK1P/N as well for lpddr4.
+		 */
+		if (params->ch[channel].cap_info.rank == 1 &&
+		    params->base.dramtype != LPDDR4)
 			setbits_le32(&dram->chan[channel].pctl->denali_ctl[276],
 				     1 << 17);
 	}
 
-	writel(sys_reg, &dram->pmugrf->os_reg2);
+	writel(sys_reg2, &dram->pmugrf->os_reg2);
+	writel(sys_reg3, &dram->pmugrf->os_reg3);
 	rk_clrsetreg(&dram->pmusgrf->soc_con4, 0x1f << 10,
-		     sdram_params->base.stride << 10);
+		     params->base.stride << 10);
 
 	/* reboot hold register set */
 	writel(PRESET_SGRF_HOLD(0) | PRESET_GPIO0_HOLD(1) |
@@ -990,12 +1488,30 @@
 	clrsetbits_le32(&dram->cru->glb_rst_con, 0x3, 0x3);
 }
 
+#if !defined(CONFIG_RAM_RK3399_LPDDR4)
+static int default_data_training(struct dram_info *dram, u32 channel, u8 rank,
+				 struct rk3399_sdram_params *params)
+{
+	u8 training_flag = PI_READ_GATE_TRAINING;
+
+	/*
+	 * LPDDR3 CA training msut be trigger before
+	 * other training.
+	 * DDR3 is not have CA training.
+	 */
+
+	if (params->base.dramtype == LPDDR3)
+		training_flag |= PI_CA_TRAINING;
+
+	return data_training(dram, channel, params, training_flag);
+}
+
 static int switch_to_phy_index1(struct dram_info *dram,
-				 const struct rk3399_sdram_params *sdram_params)
+				struct rk3399_sdram_params *params)
 {
 	u32 channel;
 	u32 *denali_phy;
-	u32 ch_count = sdram_params->base.num_channels;
+	u32 ch_count = params->base.num_channels;
 	int ret;
 	int i = 0;
 
@@ -1025,9 +1541,8 @@
 	for (channel = 0; channel < ch_count; channel++) {
 		denali_phy = dram->chan[channel].publ->denali_phy;
 		clrsetbits_le32(&denali_phy[896], (0x3 << 8) | 1, 1 << 8);
-		ret = data_training(&dram->chan[channel], channel,
-				  sdram_params, PI_FULL_TRAINING);
-		if (ret) {
+		ret = data_training(dram, channel, params, PI_FULL_TRAINING);
+		if (ret < 0) {
 			debug("index1 training failed\n");
 			return ret;
 		}
@@ -1036,12 +1551,979 @@
 	return 0;
 }
 
-static int sdram_init(struct dram_info *dram,
-		      const struct rk3399_sdram_params *sdram_params)
+#else
+
+struct rk3399_sdram_params lpddr4_timings[] = {
+	#include "sdram-rk3399-lpddr4-400.inc"
+	#include "sdram-rk3399-lpddr4-800.inc"
+};
+
+static void *get_denali_pi(const struct chan_info *chan,
+			   struct rk3399_sdram_params *params, bool reg)
 {
-	unsigned char dramtype = sdram_params->base.dramtype;
-	unsigned int ddr_freq = sdram_params->base.ddr_freq;
+	return reg ? &chan->pi->denali_pi : &params->pi_regs.denali_pi;
+}
+
+static u32 lpddr4_get_phy(struct rk3399_sdram_params *params, u32 ctl)
+{
+	u32 lpddr4_phy[] = {1, 0, 0xb};
+
+	return lpddr4_phy[ctl];
+}
+
+static u32 lpddr4_get_ctl(struct rk3399_sdram_params *params, u32 phy)
+{
+	u32 lpddr4_ctl[] = {1, 0, 2};
+
+	return lpddr4_ctl[phy];
+}
+
+static u32 get_ddr_stride(struct rk3399_pmusgrf_regs *pmusgrf)
+{
+	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);
+}
+
+static void set_cap_relate_config(const struct chan_info *chan,
+				  struct rk3399_sdram_params *params,
+				  unsigned int channel)
+{
+	u32 *denali_ctl = chan->pctl->denali_ctl;
+	u32 tmp;
+	struct rk3399_msch_timings *noc_timing;
+
+	if (params->base.dramtype == LPDDR3) {
+		tmp = (8 << params->ch[channel].cap_info.bw) /
+			(8 << params->ch[channel].cap_info.dbw);
+
+		/**
+		 * memdata_ratio
+		 * 1 -> 0, 2 -> 1, 4 -> 2
+		 */
+		clrsetbits_le32(&denali_ctl[197], 0x7,
+				(tmp >> 1));
+		clrsetbits_le32(&denali_ctl[198], 0x7 << 8,
+				(tmp >> 1) << 8);
+	}
+
+	noc_timing = &params->ch[channel].noc_timings;
+
+	/*
+	 * noc timing bw relate timing is 32 bit, and real bw is 16bit
+	 * actually noc reg is setting at function dram_all_config
+	 */
+	if (params->ch[channel].cap_info.bw == 16 &&
+	    noc_timing->ddrmode.b.mwrsize == 2) {
+		if (noc_timing->ddrmode.b.burstsize)
+			noc_timing->ddrmode.b.burstsize -= 1;
+		noc_timing->ddrmode.b.mwrsize -= 1;
+		noc_timing->ddrtimingc0.b.burstpenalty *= 2;
+		noc_timing->ddrtimingc0.b.wrtomwr *= 2;
+	}
+}
+
+static u32 calculate_ddrconfig(struct rk3399_sdram_params *params, u32 channel)
+{
+	unsigned int cs0_row = params->ch[channel].cap_info.cs0_row;
+	unsigned int col = params->ch[channel].cap_info.col;
+	unsigned int bw = params->ch[channel].cap_info.bw;
+	u16  ddr_cfg_2_rbc[] = {
+		/*
+		 * [6]	  highest bit col
+		 * [5:3]  max row(14+n)
+		 * [2]    insertion row
+		 * [1:0]  col(9+n),col, data bus 32bit
+		 *
+		 * highbitcol, max_row, insertion_row,  col
+		 */
+		((0 << 6) | (2 << 3) | (0 << 2) | 0), /* 0 */
+		((0 << 6) | (2 << 3) | (0 << 2) | 1), /* 1 */
+		((0 << 6) | (1 << 3) | (0 << 2) | 2), /* 2 */
+		((0 << 6) | (0 << 3) | (0 << 2) | 3), /* 3 */
+		((0 << 6) | (2 << 3) | (1 << 2) | 1), /* 4 */
+		((0 << 6) | (1 << 3) | (1 << 2) | 2), /* 5 */
+		((1 << 6) | (0 << 3) | (0 << 2) | 2), /* 6 */
+		((1 << 6) | (1 << 3) | (0 << 2) | 2), /* 7 */
+	};
+	u32 i;
+
+	col -= (bw == 2) ? 0 : 1;
+	col -= 9;
+
+	for (i = 0; i < 4; i++) {
+		if ((col == (ddr_cfg_2_rbc[i] & 0x3)) &&
+		    (cs0_row <= (((ddr_cfg_2_rbc[i] >> 3) & 0x7) + 14)))
+			break;
+	}
+
+	if (i >= 4)
+		i = -EINVAL;
+
+	return i;
+}
+
+/**
+ * read mr_num mode register
+ * rank = 1: cs0
+ * rank = 2: cs1
+ */
+static int read_mr(struct rk3399_ddr_pctl_regs *ddr_pctl_regs, u32 rank,
+		   u32 mr_num, u32 *buf)
+{
+	s32 timeout = 100;
+
+	writel(((1 << 16) | (((rank == 2) ? 1 : 0) << 8) | mr_num) << 8,
+	       &ddr_pctl_regs->denali_ctl[118]);
+
+	while (0 == (readl(&ddr_pctl_regs->denali_ctl[203]) &
+			((1 << 21) | (1 << 12)))) {
+		udelay(1);
+
+		if (timeout <= 0) {
+			printf("%s: pctl timeout!\n", __func__);
+			return -ETIMEDOUT;
+		}
+
+		timeout--;
+	}
+
+	if (!(readl(&ddr_pctl_regs->denali_ctl[203]) & (1 << 12))) {
+		*buf = readl(&ddr_pctl_regs->denali_ctl[119]) & 0xFF;
+	} else {
+		printf("%s: read mr failed with 0x%x status\n", __func__,
+		       readl(&ddr_pctl_regs->denali_ctl[17]) & 0x3);
+		*buf = 0;
+	}
+
+	setbits_le32(&ddr_pctl_regs->denali_ctl[205], (1 << 21) | (1 << 12));
+
+	return 0;
+}
+
+static int lpddr4_mr_detect(struct dram_info *dram, u32 channel, u8 rank,
+			    struct rk3399_sdram_params *params)
+{
+	u64 cs0_cap;
+	u32 stride;
+	u32 cs = 0, col = 0, bk = 0, bw = 0, row_3_4 = 0;
+	u32 cs0_row = 0, cs1_row = 0, ddrconfig = 0;
+	u32 mr5, mr12, mr14;
+	struct chan_info *chan = &dram->chan[channel];
+	struct rk3399_ddr_pctl_regs *ddr_pctl_regs = chan->pctl;
+	void __iomem *addr = NULL;
+	int ret = 0;
+	u32 val;
+
+	stride = get_ddr_stride(dram->pmusgrf);
+
+	if (params->ch[channel].cap_info.col == 0) {
+		ret = -EPERM;
+		goto end;
+	}
+
+	cs = params->ch[channel].cap_info.rank;
+	col = params->ch[channel].cap_info.col;
+	bk = params->ch[channel].cap_info.bk;
+	bw = params->ch[channel].cap_info.bw;
+	row_3_4 = params->ch[channel].cap_info.row_3_4;
+	cs0_row = params->ch[channel].cap_info.cs0_row;
+	cs1_row = params->ch[channel].cap_info.cs1_row;
+	ddrconfig = params->ch[channel].cap_info.ddrconfig;
+
+	/* 2GB */
+	params->ch[channel].cap_info.rank = 2;
+	params->ch[channel].cap_info.col = 10;
+	params->ch[channel].cap_info.bk = 3;
+	params->ch[channel].cap_info.bw = 2;
+	params->ch[channel].cap_info.row_3_4 = 0;
+	params->ch[channel].cap_info.cs0_row = 15;
+	params->ch[channel].cap_info.cs1_row = 15;
+	params->ch[channel].cap_info.ddrconfig = 1;
+
+	set_memory_map(chan, channel, params);
+	params->ch[channel].cap_info.ddrconfig =
+			calculate_ddrconfig(params, channel);
+	set_ddrconfig(chan, params, channel,
+		      params->ch[channel].cap_info.ddrconfig);
+	set_cap_relate_config(chan, params, channel);
+
+	cs0_cap = (1 << (params->ch[channel].cap_info.bw
+			+ params->ch[channel].cap_info.col
+			+ params->ch[channel].cap_info.bk
+			+ params->ch[channel].cap_info.cs0_row));
+
+	if (params->ch[channel].cap_info.row_3_4)
+		cs0_cap = cs0_cap * 3 / 4;
+
+	if (channel == 0)
+		set_ddr_stride(dram->pmusgrf, 0x17);
+	else
+		set_ddr_stride(dram->pmusgrf, 0x18);
+
+	/* read and write data to DRAM, avoid be optimized by compiler. */
+	if (rank == 1)
+		addr = (void __iomem *)0x100;
+	else if (rank == 2)
+		addr = (void __iomem *)(cs0_cap + 0x100);
+
+	val = readl(addr);
+	writel(val + 1, addr);
+
+	read_mr(ddr_pctl_regs, rank, 5, &mr5);
+	read_mr(ddr_pctl_regs, rank, 12, &mr12);
+	read_mr(ddr_pctl_regs, rank, 14, &mr14);
+
+	if (mr5 == 0 || mr12 != 0x4d || mr14 != 0x4d) {
+		ret = -EINVAL;
+		goto end;
+	}
+end:
+	params->ch[channel].cap_info.rank = cs;
+	params->ch[channel].cap_info.col = col;
+	params->ch[channel].cap_info.bk = bk;
+	params->ch[channel].cap_info.bw = bw;
+	params->ch[channel].cap_info.row_3_4 = row_3_4;
+	params->ch[channel].cap_info.cs0_row = cs0_row;
+	params->ch[channel].cap_info.cs1_row = cs1_row;
+	params->ch[channel].cap_info.ddrconfig = ddrconfig;
+
+	set_ddr_stride(dram->pmusgrf, stride);
+
+	return ret;
+}
+
+static void set_lpddr4_dq_odt(const struct chan_info *chan,
+			      struct rk3399_sdram_params *params, u32 ctl,
+			      bool en, bool ctl_phy_reg, u32 mr5)
+{
+	u32 *denali_ctl = get_denali_ctl(chan, params, ctl_phy_reg);
+	u32 *denali_pi = get_denali_pi(chan, params, ctl_phy_reg);
+	struct io_setting *io;
+	u32 reg_value;
+
+	if (!en)
+		return;
+
+	io = lpddr4_get_io_settings(params, mr5);
+
+	reg_value = io->dq_odt;
+
+	switch (ctl) {
+	case 0:
+		clrsetbits_le32(&denali_ctl[139], 0x7 << 24, reg_value << 24);
+		clrsetbits_le32(&denali_ctl[153], 0x7 << 24, reg_value << 24);
+
+		clrsetbits_le32(&denali_pi[132], 0x7 << 0, (reg_value << 0));
+		clrsetbits_le32(&denali_pi[139], 0x7 << 16, (reg_value << 16));
+		clrsetbits_le32(&denali_pi[147], 0x7 << 0, (reg_value << 0));
+		clrsetbits_le32(&denali_pi[154], 0x7 << 16, (reg_value << 16));
+		break;
+	case 1:
+		clrsetbits_le32(&denali_ctl[140], 0x7 << 0, reg_value << 0);
+		clrsetbits_le32(&denali_ctl[154], 0x7 << 0, reg_value << 0);
+
+		clrsetbits_le32(&denali_pi[129], 0x7 << 16, (reg_value << 16));
+		clrsetbits_le32(&denali_pi[137], 0x7 << 0, (reg_value << 0));
+		clrsetbits_le32(&denali_pi[144], 0x7 << 16, (reg_value << 16));
+		clrsetbits_le32(&denali_pi[152], 0x7 << 0, (reg_value << 0));
+		break;
+	case 2:
+	default:
+		clrsetbits_le32(&denali_ctl[140], 0x7 << 8, (reg_value << 8));
+		clrsetbits_le32(&denali_ctl[154], 0x7 << 8, (reg_value << 8));
+
+		clrsetbits_le32(&denali_pi[127], 0x7 << 0, (reg_value << 0));
+		clrsetbits_le32(&denali_pi[134], 0x7 << 16, (reg_value << 16));
+		clrsetbits_le32(&denali_pi[142], 0x7 << 0, (reg_value << 0));
+		clrsetbits_le32(&denali_pi[149], 0x7 << 16, (reg_value << 16));
+		break;
+	}
+}
+
+static void set_lpddr4_ca_odt(const struct chan_info *chan,
+			      struct rk3399_sdram_params *params, u32 ctl,
+			      bool en, bool ctl_phy_reg, u32 mr5)
+{
+	u32 *denali_ctl = get_denali_ctl(chan, params, ctl_phy_reg);
+	u32 *denali_pi = get_denali_pi(chan, params, ctl_phy_reg);
+	struct io_setting *io;
+	u32 reg_value;
+
+	if (!en)
+		return;
+
+	io = lpddr4_get_io_settings(params, mr5);
+
+	reg_value = io->ca_odt;
+
+	switch (ctl) {
+	case 0:
+		clrsetbits_le32(&denali_ctl[139], 0x7 << 28, reg_value << 28);
+		clrsetbits_le32(&denali_ctl[153], 0x7 << 28, reg_value << 28);
+
+		clrsetbits_le32(&denali_pi[132], 0x7 << 4, reg_value << 4);
+		clrsetbits_le32(&denali_pi[139], 0x7 << 20, reg_value << 20);
+		clrsetbits_le32(&denali_pi[147], 0x7 << 4, reg_value << 4);
+		clrsetbits_le32(&denali_pi[154], 0x7 << 20, reg_value << 20);
+		break;
+	case 1:
+		clrsetbits_le32(&denali_ctl[140], 0x7 << 4, reg_value << 4);
+		clrsetbits_le32(&denali_ctl[154], 0x7 << 4, reg_value << 4);
+
+		clrsetbits_le32(&denali_pi[129], 0x7 << 20, reg_value << 20);
+		clrsetbits_le32(&denali_pi[137], 0x7 << 4, reg_value << 4);
+		clrsetbits_le32(&denali_pi[144], 0x7 << 20, reg_value << 20);
+		clrsetbits_le32(&denali_pi[152], 0x7 << 4, reg_value << 4);
+		break;
+	case 2:
+	default:
+		clrsetbits_le32(&denali_ctl[140], 0x7 << 12, (reg_value << 12));
+		clrsetbits_le32(&denali_ctl[154], 0x7 << 12, (reg_value << 12));
+
+		clrsetbits_le32(&denali_pi[127], 0x7 << 4, reg_value << 4);
+		clrsetbits_le32(&denali_pi[134], 0x7 << 20, reg_value << 20);
+		clrsetbits_le32(&denali_pi[142], 0x7 << 4, reg_value << 4);
+		clrsetbits_le32(&denali_pi[149], 0x7 << 20, reg_value << 20);
+		break;
+	}
+}
+
+static void set_lpddr4_MR3(const struct chan_info *chan,
+			   struct rk3399_sdram_params *params, u32 ctl,
+			   bool ctl_phy_reg, u32 mr5)
+{
+	u32 *denali_ctl = get_denali_ctl(chan, params, ctl_phy_reg);
+	u32 *denali_pi = get_denali_pi(chan, params, ctl_phy_reg);
+	struct io_setting *io;
+	u32 reg_value;
+
+	io = lpddr4_get_io_settings(params, mr5);
+
+	reg_value = ((io->pdds << 3) | 1);
+
+	switch (ctl) {
+	case 0:
+		clrsetbits_le32(&denali_ctl[138], 0xFFFF, reg_value);
+		clrsetbits_le32(&denali_ctl[152], 0xFFFF, reg_value);
+
+		clrsetbits_le32(&denali_pi[131], 0xFFFF << 16, reg_value << 16);
+		clrsetbits_le32(&denali_pi[139], 0xFFFF, reg_value);
+		clrsetbits_le32(&denali_pi[146], 0xFFFF << 16, reg_value << 16);
+		clrsetbits_le32(&denali_pi[154], 0xFFFF, reg_value);
+		break;
+	case 1:
+		clrsetbits_le32(&denali_ctl[138], 0xFFFF << 16,
+				reg_value << 16);
+		clrsetbits_le32(&denali_ctl[152], 0xFFFF << 16,
+				reg_value << 16);
+
+		clrsetbits_le32(&denali_pi[129], 0xFFFF, reg_value);
+		clrsetbits_le32(&denali_pi[136], 0xFFFF << 16, reg_value << 16);
+		clrsetbits_le32(&denali_pi[144], 0xFFFF, reg_value);
+		clrsetbits_le32(&denali_pi[151], 0xFFFF << 16, reg_value << 16);
+		break;
+	case 2:
+	default:
+		clrsetbits_le32(&denali_ctl[139], 0xFFFF, reg_value);
+		clrsetbits_le32(&denali_ctl[153], 0xFFFF, reg_value);
+
+		clrsetbits_le32(&denali_pi[126], 0xFFFF << 16, reg_value << 16);
+		clrsetbits_le32(&denali_pi[134], 0xFFFF, reg_value);
+		clrsetbits_le32(&denali_pi[141], 0xFFFF << 16, reg_value << 16);
+		clrsetbits_le32(&denali_pi[149], 0xFFFF, reg_value);
+		break;
+	}
+}
+
+static void set_lpddr4_MR12(const struct chan_info *chan,
+			    struct rk3399_sdram_params *params, u32 ctl,
+			    bool ctl_phy_reg, u32 mr5)
+{
+	u32 *denali_ctl = get_denali_ctl(chan, params, ctl_phy_reg);
+	u32 *denali_pi = get_denali_pi(chan, params, ctl_phy_reg);
+	struct io_setting *io;
+	u32 reg_value;
+
+	io = lpddr4_get_io_settings(params, mr5);
+
+	reg_value = io->ca_vref;
+
+	switch (ctl) {
+	case 0:
+		clrsetbits_le32(&denali_ctl[140], 0xFFFF << 16,
+				reg_value << 16);
+		clrsetbits_le32(&denali_ctl[154], 0xFFFF << 16,
+				reg_value << 16);
+
+		clrsetbits_le32(&denali_pi[132], 0xFF << 8, reg_value << 8);
+		clrsetbits_le32(&denali_pi[139], 0xFF << 24, reg_value << 24);
+		clrsetbits_le32(&denali_pi[147], 0xFF << 8, reg_value << 8);
+		clrsetbits_le32(&denali_pi[154], 0xFF << 24, reg_value << 24);
+		break;
+	case 1:
+		clrsetbits_le32(&denali_ctl[141], 0xFFFF, reg_value);
+		clrsetbits_le32(&denali_ctl[155], 0xFFFF, reg_value);
+
+		clrsetbits_le32(&denali_pi[129], 0xFF << 24, reg_value << 24);
+		clrsetbits_le32(&denali_pi[137], 0xFF << 8, reg_value << 8);
+		clrsetbits_le32(&denali_pi[144], 0xFF << 24, reg_value << 24);
+		clrsetbits_le32(&denali_pi[152], 0xFF << 8, reg_value << 8);
+		break;
+	case 2:
+	default:
+		clrsetbits_le32(&denali_ctl[141], 0xFFFF << 16,
+				reg_value << 16);
+		clrsetbits_le32(&denali_ctl[155], 0xFFFF << 16,
+				reg_value << 16);
+
+		clrsetbits_le32(&denali_pi[127], 0xFF << 8, reg_value << 8);
+		clrsetbits_le32(&denali_pi[134], 0xFF << 24, reg_value << 24);
+		clrsetbits_le32(&denali_pi[142], 0xFF << 8, reg_value << 8);
+		clrsetbits_le32(&denali_pi[149], 0xFF << 24, reg_value << 24);
+		break;
+	}
+}
+
+static void set_lpddr4_MR14(const struct chan_info *chan,
+			    struct rk3399_sdram_params *params, u32 ctl,
+			    bool ctl_phy_reg, u32 mr5)
+{
+	u32 *denali_ctl = get_denali_ctl(chan, params, ctl_phy_reg);
+	u32 *denali_pi = get_denali_pi(chan, params, ctl_phy_reg);
+	struct io_setting *io;
+	u32 reg_value;
+
+	io = lpddr4_get_io_settings(params, mr5);
+
+	reg_value = io->dq_vref;
+
+	switch (ctl) {
+	case 0:
+		clrsetbits_le32(&denali_ctl[142], 0xFFFF << 16,
+				reg_value << 16);
+		clrsetbits_le32(&denali_ctl[156], 0xFFFF << 16,
+				reg_value << 16);
+
+		clrsetbits_le32(&denali_pi[132], 0xFF << 16, reg_value << 16);
+		clrsetbits_le32(&denali_pi[140], 0xFF << 0, reg_value << 0);
+		clrsetbits_le32(&denali_pi[147], 0xFF << 16, reg_value << 16);
+		clrsetbits_le32(&denali_pi[155], 0xFF << 0, reg_value << 0);
+		break;
+	case 1:
+		clrsetbits_le32(&denali_ctl[143], 0xFFFF, reg_value);
+		clrsetbits_le32(&denali_ctl[157], 0xFFFF, reg_value);
+
+		clrsetbits_le32(&denali_pi[130], 0xFF << 0, reg_value << 0);
+		clrsetbits_le32(&denali_pi[137], 0xFF << 16, reg_value << 16);
+		clrsetbits_le32(&denali_pi[145], 0xFF << 0, reg_value << 0);
+		clrsetbits_le32(&denali_pi[152], 0xFF << 16, reg_value << 16);
+		break;
+	case 2:
+	default:
+		clrsetbits_le32(&denali_ctl[143], 0xFFFF << 16,
+				reg_value << 16);
+		clrsetbits_le32(&denali_ctl[157], 0xFFFF << 16,
+				reg_value << 16);
+
+		clrsetbits_le32(&denali_pi[127], 0xFF << 16, reg_value << 16);
+		clrsetbits_le32(&denali_pi[135], 0xFF << 0, reg_value << 0);
+		clrsetbits_le32(&denali_pi[142], 0xFF << 16, reg_value << 16);
+		clrsetbits_le32(&denali_pi[150], 0xFF << 0, reg_value << 0);
+		break;
+	}
+}
+
+static void lpddr4_copy_phy(struct dram_info *dram,
+			    struct rk3399_sdram_params *params, u32 phy,
+			    struct rk3399_sdram_params *timings,
+			    u32 channel)
+{
+	u32 *denali_ctl, *denali_phy;
+	u32 *denali_phy_params;
+	u32 speed = 0;
+	u32 ctl, 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;
+
+	/* switch index */
+	clrsetbits_le32(&denali_phy_params[896], 0x3 << 8, phy << 8);
+	writel(denali_phy_params[896], &denali_phy[896]);
+
+	/* phy_pll_ctrl_ca, phy_pll_ctrl */
+	writel(denali_phy_params[911], &denali_phy[911]);
+
+	/* phy_low_freq_sel */
+	clrsetbits_le32(&denali_phy[913], 0x1,
+			denali_phy_params[913] & 0x1);
+
+	/* phy_grp_slave_delay_x, phy_cslvl_dly_step */
+	writel(denali_phy_params[916], &denali_phy[916]);
+	writel(denali_phy_params[917], &denali_phy[917]);
+	writel(denali_phy_params[918], &denali_phy[918]);
+
+	/* phy_adrz_sw_wraddr_shift_x  */
+	writel(denali_phy_params[512], &denali_phy[512]);
+	clrsetbits_le32(&denali_phy[513], 0xffff,
+			denali_phy_params[513] & 0xffff);
+	writel(denali_phy_params[640], &denali_phy[640]);
+	clrsetbits_le32(&denali_phy[641], 0xffff,
+			denali_phy_params[641] & 0xffff);
+	writel(denali_phy_params[768], &denali_phy[768]);
+	clrsetbits_le32(&denali_phy[769], 0xffff,
+			denali_phy_params[769] & 0xffff);
+
+	writel(denali_phy_params[544], &denali_phy[544]);
+	writel(denali_phy_params[545], &denali_phy[545]);
+	writel(denali_phy_params[546], &denali_phy[546]);
+	writel(denali_phy_params[547], &denali_phy[547]);
+
+	writel(denali_phy_params[672], &denali_phy[672]);
+	writel(denali_phy_params[673], &denali_phy[673]);
+	writel(denali_phy_params[674], &denali_phy[674]);
+	writel(denali_phy_params[675], &denali_phy[675]);
+
+	writel(denali_phy_params[800], &denali_phy[800]);
+	writel(denali_phy_params[801], &denali_phy[801]);
+	writel(denali_phy_params[802], &denali_phy[802]);
+	writel(denali_phy_params[803], &denali_phy[803]);
+
+	/*
+	 * phy_adr_master_delay_start_x
+	 * phy_adr_master_delay_step_x
+	 * phy_adr_master_delay_wait_x
+	 */
+	writel(denali_phy_params[548], &denali_phy[548]);
+	writel(denali_phy_params[676], &denali_phy[676]);
+	writel(denali_phy_params[804], &denali_phy[804]);
+
+	/* phy_adr_calvl_dly_step_x */
+	writel(denali_phy_params[549], &denali_phy[549]);
+	writel(denali_phy_params[677], &denali_phy[677]);
+	writel(denali_phy_params[805], &denali_phy[805]);
+
+	/*
+	 * phy_clk_wrdm_slave_delay_x
+	 * 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);
+
+	/*
+	 * phy_dqs_tsel_wr_timing_x 8bits denali_phy_84/212/340/468 offset_8
+	 * dqs_tsel_wr_end[7:4] add half cycle
+	 * phy_dq_tsel_wr_timing_x 8bits denali_phy_83/211/339/467 offset_8
+	 * dq_tsel_wr_end[7:4] add half cycle
+	 */
+	writel(denali_phy_params[83] + (0x10 << 16), &denali_phy[83]);
+	writel(denali_phy_params[84] + (0x10 << 8), &denali_phy[84]);
+	writel(denali_phy_params[85], &denali_phy[85]);
+
+	writel(denali_phy_params[211] + (0x10 << 16), &denali_phy[211]);
+	writel(denali_phy_params[212] + (0x10 << 8), &denali_phy[212]);
+	writel(denali_phy_params[213], &denali_phy[213]);
+
+	writel(denali_phy_params[339] + (0x10 << 16), &denali_phy[339]);
+	writel(denali_phy_params[340] + (0x10 << 8), &denali_phy[340]);
+	writel(denali_phy_params[341], &denali_phy[341]);
+
+	writel(denali_phy_params[467] + (0x10 << 16), &denali_phy[467]);
+	writel(denali_phy_params[468] + (0x10 << 8), &denali_phy[468]);
+	writel(denali_phy_params[469], &denali_phy[469]);
+
+	/*
+	 * phy_gtlvl_resp_wait_cnt_x
+	 * phy_gtlvl_dly_step_x
+	 * phy_wrlvl_resp_wait_cnt_x
+	 * phy_gtlvl_final_step_x
+	 * phy_gtlvl_back_step_x
+	 * phy_rdlvl_dly_step_x
+	 *
+	 * phy_master_delay_step_x
+	 * phy_master_delay_wait_x
+	 * phy_wrlvl_dly_step_x
+	 * phy_rptr_update_x
+	 * phy_wdqlvl_dly_step_x
+	 */
+	writel(denali_phy_params[87], &denali_phy[87]);
+	writel(denali_phy_params[88], &denali_phy[88]);
+	writel(denali_phy_params[89], &denali_phy[89]);
+	writel(denali_phy_params[90], &denali_phy[90]);
+
+	writel(denali_phy_params[215], &denali_phy[215]);
+	writel(denali_phy_params[216], &denali_phy[216]);
+	writel(denali_phy_params[217], &denali_phy[217]);
+	writel(denali_phy_params[218], &denali_phy[218]);
+
+	writel(denali_phy_params[343], &denali_phy[343]);
+	writel(denali_phy_params[344], &denali_phy[344]);
+	writel(denali_phy_params[345], &denali_phy[345]);
+	writel(denali_phy_params[346], &denali_phy[346]);
+
+	writel(denali_phy_params[471], &denali_phy[471]);
+	writel(denali_phy_params[472], &denali_phy[472]);
+	writel(denali_phy_params[473], &denali_phy[473]);
+	writel(denali_phy_params[474], &denali_phy[474]);
+
+	/*
+	 * phy_gtlvl_lat_adj_start_x
+	 * phy_gtlvl_rddqs_slv_dly_start_x
+	 * phy_rdlvl_rddqs_dq_slv_dly_start_x
+	 * phy_wdqlvl_dqdm_slv_dly_start_x
+	 */
+	writel(denali_phy_params[80], &denali_phy[80]);
+	writel(denali_phy_params[81], &denali_phy[81]);
+
+	writel(denali_phy_params[208], &denali_phy[208]);
+	writel(denali_phy_params[209], &denali_phy[209]);
+
+	writel(denali_phy_params[336], &denali_phy[336]);
+	writel(denali_phy_params[337], &denali_phy[337]);
+
+	writel(denali_phy_params[464], &denali_phy[464]);
+	writel(denali_phy_params[465], &denali_phy[465]);
+
+	/*
+	 * phy_master_delay_start_x
+	 * phy_sw_master_mode_x
+	 * phy_rddata_en_tsel_dly_x
+	 */
+	writel(denali_phy_params[86], &denali_phy[86]);
+	writel(denali_phy_params[214], &denali_phy[214]);
+	writel(denali_phy_params[342], &denali_phy[342]);
+	writel(denali_phy_params[470], &denali_phy[470]);
+
+	/*
+	 * phy_rddqz_slave_delay_x
+	 * phy_rddqs_dqz_fall_slave_delay_x
+	 * phy_rddqs_dqz_rise_slave_delay_x
+	 * phy_rddqs_dm_fall_slave_delay_x
+	 * phy_rddqs_dm_rise_slave_delay_x
+	 * phy_rddqs_gate_slave_delay_x
+	 * phy_wrlvl_delay_early_threshold_x
+	 * phy_write_path_lat_add_x
+	 * phy_rddqs_latency_adjust_x
+	 * 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);
+	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);
+	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);
+	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);
+	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);
+
+	/* phy_two_cyc_preamble_x */
+	clrsetbits_le32(&denali_phy[7], 0x3 << 24,
+			denali_phy_params[7] & (0x3 << 24));
+	clrsetbits_le32(&denali_phy[135], 0x3 << 24,
+			denali_phy_params[135] & (0x3 << 24));
+	clrsetbits_le32(&denali_phy[263], 0x3 << 24,
+			denali_phy_params[263] & (0x3 << 24));
+	clrsetbits_le32(&denali_phy[391], 0x3 << 24,
+			denali_phy_params[391] & (0x3 << 24));
+
+	/* speed */
+	if (timings->base.ddr_freq < 400 * MHz)
+		speed = 0x0;
+	else if (timings->base.ddr_freq < 800 * MHz)
+		speed = 0x1;
+	else if (timings->base.ddr_freq < 1200 * MHz)
+		speed = 0x2;
+
+	/* phy_924 phy_pad_fdbk_drive */
+	clrsetbits_le32(&denali_phy[924], 0x3 << 21, speed << 21);
+	/* phy_926 phy_pad_data_drive */
+	clrsetbits_le32(&denali_phy[926], 0x3 << 9, speed << 9);
+	/* phy_927 phy_pad_dqs_drive */
+	clrsetbits_le32(&denali_phy[927], 0x3 << 9, speed << 9);
+	/* phy_928 phy_pad_addr_drive */
+	clrsetbits_le32(&denali_phy[928], 0x3 << 17, speed << 17);
+	/* phy_929 phy_pad_clk_drive */
+	clrsetbits_le32(&denali_phy[929], 0x3 << 17, speed << 17);
+	/* phy_935 phy_pad_cke_drive */
+	clrsetbits_le32(&denali_phy[935], 0x3 << 17, speed << 17);
+	/* phy_937 phy_pad_rst_drive */
+	clrsetbits_le32(&denali_phy[937], 0x3 << 17, speed << 17);
+	/* 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);
+
+	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);
+
+	/*
+	 * 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);
+	}
+}
+
+static void lpddr4_set_phy(struct dram_info *dram,
+			   struct rk3399_sdram_params *params, u32 phy,
+			   struct rk3399_sdram_params *timings)
+{
+	u32 channel;
+
+	for (channel = 0; channel < 2; channel++)
+		lpddr4_copy_phy(dram, params, phy, timings, channel);
+}
+
+static int lpddr4_set_ctl(struct dram_info *dram,
+			  struct rk3399_sdram_params *params, u32 ctl, u32 hz)
+{
+	u32 channel;
+	int ret_clk, ret;
+
+	/* cci idle req stall */
+	writel(0x70007, &dram->grf->soc_con0);
+
+	/* enable all clk */
+	setbits_le32(&dram->pmu->pmu_noc_auto_ena, (0x3 << 7));
+
+	/* idle */
+	setbits_le32(&dram->pmu->pmu_bus_idle_req, (0x3 << 18));
+	while ((readl(&dram->pmu->pmu_bus_idle_st) & (0x3 << 18))
+	       != (0x3 << 18))
+		;
+
+	/* change freq */
+	writel((((0x3 << 4) | (1 << 2) | 1) << 16) |
+		(ctl << 4) | (1 << 2) | 1, &dram->cic->cic_ctrl0);
+	while (!(readl(&dram->cic->cic_status0) & (1 << 2)))
+		;
+
+	ret_clk = clk_set_rate(&dram->ddr_clk, hz);
+	if (ret_clk < 0) {
+		printf("%s clk set failed %d\n", __func__, ret_clk);
+		return ret_clk;
+	}
+
+	writel(0x20002, &dram->cic->cic_ctrl0);
+	while (!(readl(&dram->cic->cic_status0) & (1 << 0)))
+		;
+
+	/* deidle */
+	clrbits_le32(&dram->pmu->pmu_bus_idle_req, (0x3 << 18));
+	while (readl(&dram->pmu->pmu_bus_idle_st) & (0x3 << 18))
+		;
+
+	/* clear enable all clk */
+	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)) {
+		for (channel = 0; channel < 2; channel++) {
+			if (!(params->ch[channel].cap_info.col))
+				continue;
+			ret = data_training(dram, channel, params,
+						     PI_FULL_TRAINING);
+			if (ret)
+				printf("%s: channel %d training failed!\n",
+				       __func__, channel);
+			else
+				debug("%s: channel %d training pass\n",
+				      __func__, channel);
+		}
+	}
+
+	return 0;
+}
+
+static int lpddr4_set_rate(struct dram_info *dram,
+			   struct rk3399_sdram_params *params)
+{
+	u32 ctl;
+	u32 phy;
+
+	for (ctl = 0; ctl < 2; ctl++) {
+		phy = lpddr4_get_phy(params, ctl);
+
+		lpddr4_set_phy(dram, params, phy, &lpddr4_timings[ctl]);
+		lpddr4_set_ctl(dram, params, ctl,
+			       lpddr4_timings[ctl].base.ddr_freq);
+
+		debug("%s: change freq to %d mhz %d, %d\n", __func__,
+		      lpddr4_timings[ctl].base.ddr_freq / MHz, ctl, phy);
+	}
+
+	return 0;
+}
+#endif /* CONFIG_RAM_RK3399_LPDDR4 */
+
+static unsigned char calculate_stride(struct rk3399_sdram_params *params)
+{
+	unsigned int stride = params->base.stride;
+	unsigned int channel, chinfo = 0;
+	unsigned int ch_cap[2] = {0, 0};
+	u64 cap;
+
+	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;
+
+		if (cap_info->col == 0)
+			continue;
+
+		cs0_cap = (1 << (cap_info->cs0_row + cap_info->col +
+				 cap_info->bk + cap_info->bw - 20));
+		if (cap_info->rank > 1)
+			cs1_cap = cs0_cap >> (cap_info->cs0_row
+					      - cap_info->cs1_row);
+		if (cap_info->row_3_4) {
+			cs0_cap = cs0_cap * 3 / 4;
+			cs1_cap = cs1_cap * 3 / 4;
+		}
+		ch_cap[channel] = cs0_cap + cs1_cap;
+		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;
+		/*
+		 * 768MB + 768MB same as total 2GB memory
+		 * useful space: 0-768MB 1GB-1792MB
+		 */
+		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;
+		}
+	}
+
+	sdram_print_stride(stride);
+
+	return stride;
+}
+
+static void clear_channel_params(struct rk3399_sdram_params *params, u8 channel)
+{
+	params->ch[channel].cap_info.rank = 0;
+	params->ch[channel].cap_info.col = 0;
+	params->ch[channel].cap_info.bk = 0;
+	params->ch[channel].cap_info.bw = 32;
+	params->ch[channel].cap_info.dbw = 32;
+	params->ch[channel].cap_info.row_3_4 = 0;
+	params->ch[channel].cap_info.cs0_row = 0;
+	params->ch[channel].cap_info.cs1_row = 0;
+	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;
 
 	debug("Starting SDRAM initialization...\n");
 
@@ -1052,35 +2534,78 @@
 		return -E2BIG;
 	}
 
+	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;
+			}
+
+			/* LPDDR2/LPDDR3 need to wait DAI complete, max 10us */
+			if (dramtype == LPDDR3)
+				udelay(10);
+
+			params->ch[ch].cap_info.rank = rank;
+
+			ret = dram->ops->data_training(dram, ch, rank, params);
+			if (!ret) {
+				debug("%s: data trained for rank %d, ch %d\n",
+				      __func__, rank, ch);
+				break;
+			}
+		}
+		/* Computed rank with associated channel number */
+		params->ch[ch].cap_info.rank = rank;
+	}
+
+	params->base.num_channels = 0;
 	for (channel = 0; channel < 2; channel++) {
 		const struct chan_info *chan = &dram->chan[channel];
-		struct rk3399_ddr_publ_regs *publ = chan->publ;
+		struct sdram_cap_info *cap_info = &params->ch[channel].cap_info;
+		u8 training_flag = PI_FULL_TRAINING;
 
-		phy_dll_bypass_set(publ, ddr_freq);
-
-		if (channel >= sdram_params->base.num_channels)
+		if (cap_info->rank == 0) {
+			clear_channel_params(params, channel);
 			continue;
-
-		if (pctl_cfg(chan, channel, sdram_params) != 0) {
-			printf("pctl_cfg fail, reset\n");
-			return -EIO;
+		} else {
+			params->base.num_channels++;
 		}
 
-		/* LPDDR2/LPDDR3 need to wait DAI complete, max 10us */
-		if (dramtype == LPDDR3)
-			udelay(10);
+		debug("Channel ");
+		debug(channel ? "1: " : "0: ");
 
-		if (data_training(chan, channel,
-				  sdram_params, PI_FULL_TRAINING)) {
-			printf("SDRAM initialization failed, reset\n");
-			return -EIO;
+		/* LPDDR3 should have write and read gate training */
+		if (params->base.dramtype == LPDDR3)
+			training_flag = PI_WRITE_LEVELING |
+					PI_READ_GATE_TRAINING;
+
+		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;
+			}
 		}
 
-		set_ddrconfig(chan, sdram_params, channel,
-			      sdram_params->ch[channel].ddrconfig);
+		sdram_print_ddr_info(cap_info, &params->base);
+
+		set_ddrconfig(chan, params, channel, cap_info->ddrconfig);
 	}
-	dram_all_config(dram, sdram_params);
-	switch_to_phy_index1(dram, sdram_params);
+
+	if (params->base.num_channels == 0) {
+		printf("%s: ", __func__);
+		sdram_print_dram_type(params->base.dramtype);
+		printf(" - %dMHz failed!\n", params->base.ddr_freq);
+		return -EINVAL;
+	}
+
+	params->base.stride = calculate_stride(params);
+	dram_all_config(dram, params);
+	dram->ops->set_rate(dram, params);
 
 	debug("Finish SDRAM initialization...\n");
 	return 0;
@@ -1116,8 +2641,8 @@
 	int ret;
 
 	ret = regmap_init_mem_platdata(dev, dtplat->reg,
-			ARRAY_SIZE(dtplat->reg) / 2,
-			&plat->map);
+				       ARRAY_SIZE(dtplat->reg) / 2,
+				       &plat->map);
 	if (ret)
 		return ret;
 
@@ -1125,6 +2650,16 @@
 }
 #endif
 
+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,
+#else
+	.data_training = lpddr4_mr_detect,
+	.set_rate = lpddr4_set_rate,
+#endif
+};
+
 static int rk3399_dmc_init(struct udevice *dev)
 {
 	struct dram_info *priv = dev_get_priv(dev);
@@ -1142,7 +2677,10 @@
 		return ret;
 #endif
 
+	priv->ops = &rk3399_ops;
 	priv->cic = syscon_get_first_range(ROCKCHIP_SYSCON_CIC);
+	priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+	priv->pmu = syscon_get_first_range(ROCKCHIP_SYSCON_PMU);
 	priv->pmugrf = syscon_get_first_range(ROCKCHIP_SYSCON_PMUGRF);
 	priv->pmusgrf = syscon_get_first_range(ROCKCHIP_SYSCON_PMUSGRF);
 	priv->pmucru = rockchip_get_pmucru();
@@ -1161,8 +2699,9 @@
 	      priv->chan[0].publ, priv->chan[0].msch,
 	      priv->chan[1].pctl, priv->chan[1].pi,
 	      priv->chan[1].publ, priv->chan[1].msch);
-	debug("cru %p, cic %p, grf %p, sgrf %p, pmucru %p\n", priv->cru,
-	      priv->cic, priv->pmugrf, priv->pmusgrf, priv->pmucru);
+	debug("cru %p, cic %p, grf %p, sgrf %p, pmucru %p, pmu %p\n", priv->cru,
+	      priv->cic, priv->pmugrf, priv->pmusgrf, priv->pmucru, priv->pmu);
+
 #if CONFIG_IS_ENABLED(OF_PLATDATA)
 	ret = clk_get_by_index_platdata(dev, 0, dtplat->clocks, &priv->ddr_clk);
 #else
@@ -1172,14 +2711,16 @@
 		printf("%s clk get failed %d\n", __func__, ret);
 		return ret;
 	}
+
 	ret = clk_set_rate(&priv->ddr_clk, params->base.ddr_freq * MHz);
 	if (ret < 0) {
 		printf("%s clk set failed %d\n", __func__, ret);
 		return ret;
 	}
+
 	ret = sdram_init(priv, params);
 	if (ret < 0) {
-		printf("%s DRAM init failed%d\n", __func__, ret);
+		printf("%s DRAM init failed %d\n", __func__, ret);
 		return ret;
 	}
 
@@ -1197,10 +2738,10 @@
 	struct dram_info *priv = dev_get_priv(dev);
 
 	priv->pmugrf = syscon_get_first_range(ROCKCHIP_SYSCON_PMUGRF);
-	debug("%s: pmugrf=%p\n", __func__, priv->pmugrf);
+	debug("%s: pmugrf = %p\n", __func__, priv->pmugrf);
 	priv->info.base = CONFIG_SYS_SDRAM_BASE;
-	priv->info.size = rockchip_sdram_size(
-			(phys_addr_t)&priv->pmugrf->os_reg2);
+	priv->info.size =
+		rockchip_sdram_size((phys_addr_t)&priv->pmugrf->os_reg2);
 #endif
 	return 0;
 }
@@ -1218,7 +2759,6 @@
 	.get_info = rk3399_dmc_get_info,
 };
 
-
 static const struct udevice_id rk3399_dmc_ids[] = {
 	{ .compatible = "rockchip,rk3399-dmc" },
 	{ }
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index b1188bc..ac68aa2 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -24,6 +24,7 @@
 config USB_XHCI_DWC3_OF_SIMPLE
 	bool "DesignWare USB3 DRD Generic OF Simple Glue Layer"
 	depends on DM_USB
+	default y if ARCH_ROCKCHIP
 	default y if DRA7XX
 	help
 	  Support USB2/3 functionality in simple SoC integrations with
diff --git a/drivers/usb/host/dwc3-of-simple.c b/drivers/usb/host/dwc3-of-simple.c
index b118997..45df614 100644
--- a/drivers/usb/host/dwc3-of-simple.c
+++ b/drivers/usb/host/dwc3-of-simple.c
@@ -92,6 +92,7 @@
 
 static const struct udevice_id dwc3_of_simple_ids[] = {
 	{ .compatible = "amlogic,meson-gxl-dwc3" },
+	{ .compatible = "rockchip,rk3399-dwc3" },
 	{ .compatible = "ti,dwc3" },
 	{ }
 };
diff --git a/drivers/usb/host/xhci-dwc3.c b/drivers/usb/host/xhci-dwc3.c
index 83b9f11..9e8cae7 100644
--- a/drivers/usb/host/xhci-dwc3.c
+++ b/drivers/usb/host/xhci-dwc3.c
@@ -118,6 +118,8 @@
 	struct dwc3 *dwc3_reg;
 	enum usb_dr_mode dr_mode;
 	struct xhci_dwc3_platdata *plat = dev_get_platdata(dev);
+	const char *phy;
+	u32 reg;
 	int ret;
 
 	hccr = (struct xhci_hccr *)((uintptr_t)dev_read_addr(dev));
@@ -132,6 +134,24 @@
 
 	dwc3_core_init(dwc3_reg);
 
+	/* Set dwc3 usb2 phy config */
+	reg = readl(&dwc3_reg->g_usb2phycfg[0]);
+
+	phy = dev_read_string(dev, "phy_type");
+	if (phy && strcmp(phy, "utmi_wide") == 0) {
+		reg |= DWC3_GUSB2PHYCFG_PHYIF;
+		reg &= ~DWC3_GUSB2PHYCFG_USBTRDTIM_MASK;
+		reg |= DWC3_GUSB2PHYCFG_USBTRDTIM_16BIT;
+	}
+
+	if (dev_read_bool(dev, "snps,dis_enblslpm-quirk"))
+		reg &= ~DWC3_GUSB2PHYCFG_ENBLSLPM;
+
+	if (dev_read_bool(dev, "snps,dis-u2-freeclk-exists-quirk"))
+		reg &= ~DWC3_GUSB2PHYCFG_U2_FREECLK_EXISTS;
+
+	writel(reg, &dwc3_reg->g_usb2phycfg[0]);
+
 	dr_mode = usb_get_dr_mode(dev_of_offset(dev));
 	if (dr_mode == USB_DR_MODE_UNKNOWN)
 		/* by default set dual role mode to HOST */
diff --git a/drivers/usb/host/xhci-rockchip.c b/drivers/usb/host/xhci-rockchip.c
index f19bea3..e7b0dbc 100644
--- a/drivers/usb/host/xhci-rockchip.c
+++ b/drivers/usb/host/xhci-rockchip.c
@@ -167,7 +167,6 @@
 }
 
 static const struct udevice_id xhci_usb_ids[] = {
-	{ .compatible = "rockchip,rk3399-xhci" },
 	{ .compatible = "rockchip,rk3328-xhci" },
 	{ }
 };
@@ -187,7 +186,6 @@
 };
 
 static const struct udevice_id usb_phy_ids[] = {
-	{ .compatible = "rockchip,rk3399-usb3-phy" },
 	{ .compatible = "rockchip,rk3328-usb3-phy" },
 	{ }
 };
diff --git a/drivers/video/rockchip/rk3288_hdmi.c b/drivers/video/rockchip/rk3288_hdmi.c
index 315d3ad..3d25ce9 100644
--- a/drivers/video/rockchip/rk3288_hdmi.c
+++ b/drivers/video/rockchip/rk3288_hdmi.c
@@ -33,7 +33,7 @@
 	/* hdmi data from vop id */
 	rk_clrsetreg(&grf->soc_con6, 1 << 4, (vop_id == 1) ? (1 << 4) : 0);
 
-	return 0;
+	return dw_hdmi_enable(&priv->hdmi, edid);
 }
 
 static int rk3288_hdmi_ofdata_to_platdata(struct udevice *dev)
diff --git a/include/configs/rk3036_common.h b/include/configs/rk3036_common.h
index f5d09d1..73be079 100644
--- a/include/configs/rk3036_common.h
+++ b/include/configs/rk3036_common.h
@@ -12,9 +12,10 @@
 #define CONFIG_SYS_CBSIZE		1024
 #define CONFIG_SKIP_LOWLEVEL_INIT
 
-#define CONFIG_SYS_TIMER_RATE		(24 * 1000 * 1000)
-#define CONFIG_SYS_TIMER_BASE		0x200440a0 /* TIMER5 */
-#define CONFIG_SYS_TIMER_COUNTER	(CONFIG_SYS_TIMER_BASE + 8)
+#define CONFIG_ROCKCHIP_STIMER_BASE	0x200440a0
+#define COUNTER_FREQUENCY		24000000
+#define CONFIG_SYS_ARCH_TIMER
+#define CONFIG_SYS_HZ_CLOCK		24000000
 
 #define CONFIG_SYS_INIT_SP_ADDR		0x60100000
 #define CONFIG_SYS_LOAD_ADDR		0x60800800
diff --git a/include/configs/rk3128_common.h b/include/configs/rk3128_common.h
index 0c08d7a..20d6243 100644
--- a/include/configs/rk3128_common.h
+++ b/include/configs/rk3128_common.h
@@ -14,9 +14,10 @@
 #define CONFIG_SYS_CBSIZE		1024
 #define CONFIG_SKIP_LOWLEVEL_INIT
 
-#define CONFIG_SYS_TIMER_RATE		(24 * 1000 * 1000)
-#define CONFIG_SYS_TIMER_BASE		0x200440a0 /* TIMER5 */
-#define CONFIG_SYS_TIMER_COUNTER	(CONFIG_SYS_TIMER_BASE + 8)
+#define CONFIG_ROCKCHIP_STIMER_BASE	0x200440a0
+#define COUNTER_FREQUENCY		24000000
+#define CONFIG_SYS_ARCH_TIMER
+#define CONFIG_SYS_HZ_CLOCK		24000000
 
 #define CONFIG_SYS_INIT_SP_ADDR		0x60100000
 #define CONFIG_SYS_LOAD_ADDR		0x60800800
diff --git a/include/configs/rk322x_common.h b/include/configs/rk322x_common.h
index 15bb8d6..cc08699 100644
--- a/include/configs/rk322x_common.h
+++ b/include/configs/rk322x_common.h
@@ -13,9 +13,10 @@
 #define CONFIG_SYS_CBSIZE		1024
 #define CONFIG_SYS_BOOTM_LEN	(64 << 20)	/*  64M */
 
-#define CONFIG_SYS_TIMER_RATE		(24 * 1000 * 1000)
-#define CONFIG_SYS_TIMER_BASE		0x110c00a0 /* TIMER5 */
-#define CONFIG_SYS_TIMER_COUNTER	(CONFIG_SYS_TIMER_BASE + 8)
+#define CONFIG_ROCKCHIP_STIMER_BASE	0x110d0020
+#define COUNTER_FREQUENCY		24000000
+#define CONFIG_SYS_ARCH_TIMER
+#define CONFIG_SYS_HZ_CLOCK		24000000
 
 #define CONFIG_SYS_INIT_SP_ADDR		0x61100000
 #define CONFIG_SYS_LOAD_ADDR		0x61800800
diff --git a/include/configs/rk3288_common.h b/include/configs/rk3288_common.h
index 7c79ed6..5472a90 100644
--- a/include/configs/rk3288_common.h
+++ b/include/configs/rk3288_common.h
@@ -13,9 +13,10 @@
 #define CONFIG_SYS_MALLOC_LEN		(32 << 20)
 #define CONFIG_SYS_CBSIZE		1024
 
-#define CONFIG_SYS_TIMER_RATE		(24 * 1000 * 1000)
-#define	CONFIG_SYS_TIMER_BASE		0xff810020 /* TIMER7 */
-#define CONFIG_SYS_TIMER_COUNTER	(CONFIG_SYS_TIMER_BASE + 8)
+#define CONFIG_ROCKCHIP_STIMER_BASE	0xff810020
+#define COUNTER_FREQUENCY		24000000
+#define CONFIG_SYS_ARCH_TIMER
+#define CONFIG_SYS_HZ_CLOCK		24000000
 
 #ifdef CONFIG_SPL_ROCKCHIP_BACK_TO_BROM
 /* Bootrom will load u-boot binary to 0x0 once return from SPL */
@@ -35,6 +36,8 @@
 #define SDRAM_BANK_SIZE			(2UL << 30)
 #define SDRAM_MAX_SIZE			0xfe000000
 
+#define CONFIG_SYS_MONITOR_LEN (600 * 1024)
+
 #ifndef CONFIG_SPL_BUILD
 /* usb otg */
 
diff --git a/include/configs/rk3368_common.h b/include/configs/rk3368_common.h
index 13630ba..8a1e311 100644
--- a/include/configs/rk3368_common.h
+++ b/include/configs/rk3368_common.h
@@ -20,7 +20,8 @@
 #define CONFIG_SYS_CBSIZE		1024
 #define CONFIG_SKIP_LOWLEVEL_INIT
 
-#define COUNTER_FREQUENCY               24000000
+#define CONFIG_ROCKCHIP_STIMER_BASE	0xff830020
+#define COUNTER_FREQUENCY		24000000
 
 #define CONFIG_SYS_NS16550_MEM32
 
diff --git a/include/configs/rk3399_common.h b/include/configs/rk3399_common.h
index f31f265..8df0180 100644
--- a/include/configs/rk3399_common.h
+++ b/include/configs/rk3399_common.h
@@ -13,6 +13,7 @@
 #define CONFIG_SKIP_LOWLEVEL_INIT
 
 #define COUNTER_FREQUENCY               24000000
+#define CONFIG_ROCKCHIP_STIMER_BASE	0xff8680a0
 
 #define CONFIG_SYS_NS16550_MEM32
 
diff --git a/include/configs/tinker_rk3288.h b/include/configs/tinker_rk3288.h
index 32057b3..5adae68 100644
--- a/include/configs/tinker_rk3288.h
+++ b/include/configs/tinker_rk3288.h
@@ -18,6 +18,5 @@
 	func(DHCP, dchp, na)
 
 #define CONFIG_SYS_MMC_ENV_DEV 1
-#define CONFIG_SYS_MONITOR_LEN (600 * 1024)
 
 #endif
diff --git a/include/debug_uart.h b/include/debug_uart.h
index 34e8b2f..cd70ae1 100644
--- a/include/debug_uart.h
+++ b/include/debug_uart.h
@@ -104,6 +104,13 @@
  */
 void printhex8(uint value);
 
+/**
+ * printdec() - Output a decimalism value
+ *
+ * @value:	Value to output
+ */
+void printdec(uint value);
+
 #ifdef CONFIG_DEBUG_UART_ANNOUNCE
 #define _DEBUG_UART_ANNOUNCE	printascii("<debug_uart> ");
 #else
@@ -171,6 +178,18 @@
 		printhex(value, 8); \
 	} \
 \
+	void printdec(uint value) \
+	{ \
+		if (value > 10) { \
+			printdec(value / 10); \
+			value %= 10; \
+		} else if (value == 10) { \
+			_debug_uart_putc('1'); \
+			value = 0; \
+		} \
+		_debug_uart_putc('0' + value); \
+	} \
+\
 	void debug_uart_init(void) \
 	{ \
 		board_debug_uart_init(); \
diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt
index bd16795..e616f72 100644
--- a/scripts/config_whitelist.txt
+++ b/scripts/config_whitelist.txt
@@ -1532,6 +1532,7 @@
 CONFIG_ROCKCHIP_CHIP_TAG
 CONFIG_ROCKCHIP_MAX_INIT_SIZE
 CONFIG_ROCKCHIP_SDHCI_MAX_FREQ
+CONFIG_ROCKCHIP_STIMER_BASE
 CONFIG_ROM_STUBS
 CONFIG_ROOTFS_OFFSET
 CONFIG_ROOTPATH