Merge git://git.denx.de/u-boot-rockchip

Here is additional rk3368 and rk3399 support, rv1108 support,
refactoring HDMI video (brought in from Anatolij's tree to resolve
conflicts), some mkimage fixes and a few other things.
diff --git a/MAINTAINERS b/MAINTAINERS
index 0962b47..56dd1f3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -135,6 +135,7 @@
 S:	Maintained
 T:	git git://git.denx.de/u-boot-rockchip.git
 F:	arch/arm/mach-rockchip/
+F:	board/rockchip/
 
 ARM SAMSUNG
 M:	Minkyu Kang <mk7.kang@samsung.com>
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index aceb29e..8b8f5e9 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -41,9 +41,15 @@
 	rk3288-veyron-mickey.dtb \
 	rk3288-veyron-minnie.dtb \
 	rk3328-evb.dtb \
+	rk3368-sheep.dtb \
+	rk3368-geekbox.dtb \
+	rk3368-px5-evb.dtb \
 	rk3399-evb.dtb \
 	rk3399-firefly.dtb \
-	rk3399-puma.dtb
+	rk3399-puma-ddr1333.dtb \
+	rk3399-puma-ddr1600.dtb \
+	rk3399-puma-ddr1866.dtb \
+	rv1108-evb.dtb
 dtb-$(CONFIG_ARCH_MESON) += \
 	meson-gxbb-odroidc2.dtb
 dtb-$(CONFIG_TEGRA) += tegra20-harmony.dtb \
diff --git a/arch/arm/dts/rk3328-evb.dts b/arch/arm/dts/rk3328-evb.dts
index 01794ed..b807bc5 100644
--- a/arch/arm/dts/rk3328-evb.dts
+++ b/arch/arm/dts/rk3328-evb.dts
@@ -43,3 +43,16 @@
 	pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>;
 	status = "okay";
 };
+
+&usb_host0_ehci {
+	status = "okay";
+};
+
+&usb_host0_ohci {
+	status = "okay";
+};
+
+&usb_host0_xhci {
+	rockchip,vbus-gpio = <&gpio0 0 GPIO_ACTIVE_HIGH>;
+	status = "okay";
+};
diff --git a/arch/arm/dts/rk3328.dtsi b/arch/arm/dts/rk3328.dtsi
index 8a98ee3..f18cfc2 100644
--- a/arch/arm/dts/rk3328.dtsi
+++ b/arch/arm/dts/rk3328.dtsi
@@ -446,6 +446,20 @@
 		status = "disabled";
 	};
 
+	usb_host0_ehci: usb@ff5c0000 {
+		compatible = "generic-ehci";
+		reg = <0x0 0xff5c0000 0x0 0x10000>;
+		interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+		status = "disabled";
+	};
+
+	usb_host0_ohci: usb@ff5d0000 {
+		compatible = "generic-ohci";
+		reg = <0x0 0xff5d0000 0x0 0x10000>;
+		interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+		status = "disabled";
+	};
+
 	sdmmc_ext: rksdmmc@ff5f0000 {
 		compatible = "rockchip,rk3328-dw-mshc", "rockchip,rk3288-dw-mshc";
 		reg = <0x0 0xff5f0000 0x0 0x4000>;
@@ -457,6 +471,17 @@
 		status = "disabled";
 	};
 
+	usb_host0_xhci: usb@ff600000 {
+		compatible = "rockchip,rk3328-xhci";
+		reg = <0x0 0xff600000 0x0 0x100000>;
+		interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
+		snps,dis-enblslpm-quirk;
+		snps,phyif-utmi-bits = <16>;
+		snps,dis-u2-freeclk-exists-quirk;
+		snps,dis-u2-susphy-quirk;
+		status = "disabled";
+	};
+
 	gic: interrupt-controller@ffb70000 {
 		compatible = "arm,gic-400";
 		#interrupt-cells = <3>;
diff --git a/arch/arm/dts/rk3368-geekbox.dts b/arch/arm/dts/rk3368-geekbox.dts
new file mode 100644
index 0000000..46cdddf
--- /dev/null
+++ b/arch/arm/dts/rk3368-geekbox.dts
@@ -0,0 +1,319 @@
+/*
+ * Copyright (c) 2016 Andreas Färber
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "rk3368.dtsi"
+#include <dt-bindings/input/input.h>
+
+/ {
+	model = "GeekBox";
+	compatible = "geekbuying,geekbox", "rockchip,rk3368";
+
+	chosen {
+		stdout-path = "serial2:115200n8";
+	};
+
+	memory@0 {
+		device_type = "memory";
+		reg = <0x0 0x0 0x0 0x80000000>;
+	};
+
+	ext_gmac: gmac-clk {
+		compatible = "fixed-clock";
+		clock-frequency = <125000000>;
+		clock-output-names = "ext_gmac";
+		#clock-cells = <0>;
+	};
+
+	ir: ir-receiver {
+		compatible = "gpio-ir-receiver";
+		gpios = <&gpio3 30 GPIO_ACTIVE_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&ir_int>;
+	};
+
+	keys: gpio-keys {
+		compatible = "gpio-keys";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pwr_key>;
+
+		power {
+			gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+			label = "GPIO Power";
+			linux,code = <KEY_POWER>;
+			wakeup-source;
+		};
+	};
+
+	leds: gpio-leds {
+		compatible = "gpio-leds";
+
+		blue {
+			gpios = <&gpio2 2 GPIO_ACTIVE_HIGH>;
+			label = "geekbox:blue:led";
+			default-state = "on";
+		};
+
+		red {
+			gpios = <&gpio2 3 GPIO_ACTIVE_HIGH>;
+			label = "geekbox:red:led";
+			default-state = "off";
+		};
+	};
+
+	vcc_sys: vcc-sys-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_sys";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-always-on;
+		regulator-boot-on;
+	};
+};
+
+&emmc {
+	status = "okay";
+	bus-width = <8>;
+	cap-mmc-highspeed;
+	clock-frequency = <150000000>;
+	disable-wp;
+	keep-power-in-suspend;
+	non-removable;
+	num-slots = <1>;
+	vmmc-supply = <&vcc_io>;
+	vqmmc-supply = <&vcc18_flash>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&emmc_clk>, <&emmc_cmd>, <&emmc_bus8>;
+};
+
+&gmac {
+	status = "okay";
+	phy-supply = <&vcc_lan>;
+	phy-mode = "rgmii";
+	clock_in_out = "input";
+	assigned-clocks = <&cru SCLK_MAC>;
+	assigned-clock-parents = <&ext_gmac>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii_pins>;
+	tx_delay = <0x30>;
+	rx_delay = <0x10>;
+};
+
+&i2c0 {
+	status = "okay";
+
+	rk808: pmic@1b {
+		compatible = "rockchip,rk808";
+		reg = <0x1b>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pmic_int>, <&pmic_sleep>;
+		interrupt-parent = <&gpio0>;
+		interrupts = <5 IRQ_TYPE_LEVEL_LOW>;
+		rockchip,system-power-controller;
+		vcc1-supply = <&vcc_sys>;
+		vcc2-supply = <&vcc_sys>;
+		vcc3-supply = <&vcc_sys>;
+		vcc4-supply = <&vcc_sys>;
+		vcc6-supply = <&vcc_sys>;
+		vcc7-supply = <&vcc_sys>;
+		vcc8-supply = <&vcc_io>;
+		vcc9-supply = <&vcc_sys>;
+		vcc10-supply = <&vcc_sys>;
+		vcc11-supply = <&vcc_sys>;
+		vcc12-supply = <&vcc_io>;
+		clock-output-names = "xin32k", "rk808-clkout2";
+		#clock-cells = <1>;
+
+		regulators {
+			vdd_cpu: DCDC_REG1 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <700000>;
+				regulator-max-microvolt = <1500000>;
+				regulator-name = "vdd_cpu";
+			};
+
+			vdd_log: DCDC_REG2 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <700000>;
+				regulator-max-microvolt = <1500000>;
+				regulator-name = "vdd_log";
+			};
+
+			vcc_ddr: DCDC_REG3 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-name = "vcc_ddr";
+			};
+
+			vcc_io: DCDC_REG4 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-name = "vcc_io";
+			};
+
+			vcc18_flash: LDO_REG1 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vcc18_flash";
+			};
+
+			vcc33_lcd: LDO_REG2 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-name = "vcc33_lcd";
+			};
+
+			vdd_10: LDO_REG3 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <1000000>;
+				regulator-name = "vdd_10";
+			};
+
+			vcca_18: LDO_REG4 {
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vcca_18";
+			};
+
+			vccio_sd: LDO_REG5 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-name = "vccio_sd";
+			};
+
+			vdd10_lcd: LDO_REG6 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <1000000>;
+				regulator-name = "vdd10_lcd";
+			};
+
+			vcc_18: LDO_REG7 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vcc_18";
+			};
+
+			vcc18_lcd: LDO_REG8 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vcc18_lcd";
+			};
+
+			vcc_sd: SWITCH_REG1 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-name = "vcc_sd";
+			};
+
+			vcc_lan: SWITCH_REG2 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-name = "vcc_lan";
+			};
+		};
+	};
+};
+
+&pinctrl {
+	ir {
+		ir_int: ir-int {
+			rockchip,pins = <3 30 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	keys {
+		pwr_key: pwr-key {
+			rockchip,pins = <0 2 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	pmic {
+		pmic_sleep: pmic-sleep {
+			rockchip,pins = <0 0 RK_FUNC_2 &pcfg_pull_none>;
+		};
+
+		pmic_int: pmic-int {
+			rockchip,pins = <0 5 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+};
+
+&tsadc {
+	status = "okay";
+	rockchip,hw-tshut-mode = <0>; /* CRU */
+	rockchip,hw-tshut-polarity = <1>; /* high */
+};
+
+&uart2 {
+	status = "okay";
+};
+
+&usb_host0_ehci {
+	status = "okay";
+};
+
+&usb_otg {
+	status = "okay";
+};
+
+&wdt {
+	status = "okay";
+};
diff --git a/arch/arm/dts/rk3368-px5-evb.dts b/arch/arm/dts/rk3368-px5-evb.dts
new file mode 100644
index 0000000..c7478f7
--- /dev/null
+++ b/arch/arm/dts/rk3368-px5-evb.dts
@@ -0,0 +1,319 @@
+/*
+ * Copyright (c) 2017 Rockchip Electronics Co., Ltd
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "rk3368.dtsi"
+#include <dt-bindings/input/input.h>
+
+/ {
+	model = "PX5 EVB";
+	compatible = "rockchip,px5-evb", "rockchip,px5", "rockchip,rk3368";
+
+	chosen {
+		stdout-path = "serial4:115200n8";
+	};
+
+	memory@0 {
+		device_type = "memory";
+		reg = <0x0 0x0 0x0 0x40000000>;
+	};
+
+	ext_gmac: gmac-clk {
+		compatible = "fixed-clock";
+		clock-frequency = <125000000>;
+		clock-output-names = "ext_gmac";
+		#clock-cells = <0>;
+	};
+
+	ir: ir-receiver {
+		compatible = "gpio-ir-receiver";
+		gpios = <&gpio3 30 GPIO_ACTIVE_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&ir_int>;
+	};
+
+	keys: gpio-keys {
+		compatible = "gpio-keys";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pwr_key>;
+
+		power {
+			gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+			label = "GPIO Power";
+			linux,code = <KEY_POWER>;
+			wakeup-source;
+		};
+	};
+
+	leds: gpio-leds {
+		compatible = "gpio-leds";
+
+		blue {
+			gpios = <&gpio2 2 GPIO_ACTIVE_HIGH>;
+			label = "geekbox:blue:led";
+			default-state = "on";
+		};
+
+		red {
+			gpios = <&gpio2 3 GPIO_ACTIVE_HIGH>;
+			label = "geekbox:red:led";
+			default-state = "off";
+		};
+	};
+
+	vcc_sys: vcc-sys-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_sys";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-always-on;
+		regulator-boot-on;
+	};
+};
+
+&emmc {
+	status = "okay";
+	bus-width = <8>;
+	cap-mmc-highspeed;
+	clock-frequency = <150000000>;
+	disable-wp;
+	keep-power-in-suspend;
+	non-removable;
+	num-slots = <1>;
+	vmmc-supply = <&vcc_io>;
+	vqmmc-supply = <&vcc18_flash>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&emmc_clk>, <&emmc_cmd>, <&emmc_bus8>;
+};
+
+&gmac {
+	status = "okay";
+	phy-supply = <&vcc_lan>;
+	phy-mode = "rgmii";
+	clock_in_out = "input";
+	assigned-clocks = <&cru SCLK_MAC>;
+	assigned-clock-parents = <&ext_gmac>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii_pins>;
+	tx_delay = <0x30>;
+	rx_delay = <0x10>;
+};
+
+&i2c0 {
+	status = "okay";
+
+	rk808: pmic@1b {
+		compatible = "rockchip,rk808";
+		reg = <0x1b>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pmic_int>, <&pmic_sleep>;
+		interrupt-parent = <&gpio0>;
+		interrupts = <5 IRQ_TYPE_LEVEL_LOW>;
+		rockchip,system-power-controller;
+		vcc1-supply = <&vcc_sys>;
+		vcc2-supply = <&vcc_sys>;
+		vcc3-supply = <&vcc_sys>;
+		vcc4-supply = <&vcc_sys>;
+		vcc6-supply = <&vcc_sys>;
+		vcc7-supply = <&vcc_sys>;
+		vcc8-supply = <&vcc_io>;
+		vcc9-supply = <&vcc_sys>;
+		vcc10-supply = <&vcc_sys>;
+		vcc11-supply = <&vcc_sys>;
+		vcc12-supply = <&vcc_io>;
+		clock-output-names = "xin32k", "rk808-clkout2";
+		#clock-cells = <1>;
+
+		regulators {
+			vdd_cpu: DCDC_REG1 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <700000>;
+				regulator-max-microvolt = <1500000>;
+				regulator-name = "vdd_cpu";
+			};
+
+			vdd_log: DCDC_REG2 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <700000>;
+				regulator-max-microvolt = <1500000>;
+				regulator-name = "vdd_log";
+			};
+
+			vcc_ddr: DCDC_REG3 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-name = "vcc_ddr";
+			};
+
+			vcc_io: DCDC_REG4 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-name = "vcc_io";
+			};
+
+			vcc18_flash: LDO_REG1 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vcc18_flash";
+			};
+
+			vcc33_lcd: LDO_REG2 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-name = "vcc33_lcd";
+			};
+
+			vdd_10: LDO_REG3 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <1000000>;
+				regulator-name = "vdd_10";
+			};
+
+			vcca_18: LDO_REG4 {
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vcca_18";
+			};
+
+			vccio_sd: LDO_REG5 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-name = "vccio_sd";
+			};
+
+			vdd10_lcd: LDO_REG6 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <1000000>;
+				regulator-name = "vdd10_lcd";
+			};
+
+			vcc_18: LDO_REG7 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vcc_18";
+			};
+
+			vcc18_lcd: LDO_REG8 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vcc18_lcd";
+			};
+
+			vcc_sd: SWITCH_REG1 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-name = "vcc_sd";
+			};
+
+			vcc_lan: SWITCH_REG2 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-name = "vcc_lan";
+			};
+		};
+	};
+};
+
+&pinctrl {
+	ir {
+		ir_int: ir-int {
+			rockchip,pins = <3 30 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	keys {
+		pwr_key: pwr-key {
+			rockchip,pins = <0 2 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	pmic {
+		pmic_sleep: pmic-sleep {
+			rockchip,pins = <0 0 RK_FUNC_2 &pcfg_pull_none>;
+		};
+
+		pmic_int: pmic-int {
+			rockchip,pins = <0 5 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+};
+
+&tsadc {
+	status = "okay";
+	rockchip,hw-tshut-mode = <0>; /* CRU */
+	rockchip,hw-tshut-polarity = <1>; /* high */
+};
+
+&uart4 {
+	status = "okay";
+};
+
+&usb_host0_ehci {
+	status = "okay";
+};
+
+&usb_otg {
+	status = "okay";
+};
+
+&wdt {
+	status = "okay";
+};
diff --git a/arch/arm/dts/rk3368-sheep.dts b/arch/arm/dts/rk3368-sheep.dts
new file mode 100644
index 0000000..7c190f7
--- /dev/null
+++ b/arch/arm/dts/rk3368-sheep.dts
@@ -0,0 +1,283 @@
+/*
+ * (C) Copyright 2017 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+/dts-v1/;
+#include "rk3368.dtsi"
+#include <dt-bindings/input/input.h>
+
+/ {
+	model = "Rockchip sheep board";
+	compatible = "rockchip,sheep", "rockchip,rk3368";
+
+	chosen {
+		stdout-path = "serial2:115200n8";
+	};
+
+	memory@0 {
+		device_type = "memory";
+		reg = <0x0 0x0 0x0 0x80000000>;
+	};
+
+	ext_gmac: gmac-clk {
+		compatible = "fixed-clock";
+		clock-frequency = <125000000>;
+		clock-output-names = "ext_gmac";
+		#clock-cells = <0>;
+	};
+
+	ir: ir-receiver {
+		compatible = "gpio-ir-receiver";
+		gpios = <&gpio3 30 GPIO_ACTIVE_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&ir_int>;
+	};
+
+	keys: gpio-keys {
+		compatible = "gpio-keys";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pwr_key>;
+
+		power {
+			gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+			label = "GPIO Power";
+			linux,code = <KEY_POWER>;
+			wakeup-source;
+		};
+	};
+
+	leds: gpio-leds {
+		compatible = "gpio-leds";
+
+		blue {
+			gpios = <&gpio2 2 GPIO_ACTIVE_HIGH>;
+			label = "geekbox:blue:led";
+			default-state = "on";
+		};
+
+		red {
+			gpios = <&gpio2 3 GPIO_ACTIVE_HIGH>;
+			label = "geekbox:red:led";
+			default-state = "off";
+		};
+	};
+
+	vcc_sys: vcc-sys-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_sys";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-always-on;
+		regulator-boot-on;
+	};
+};
+
+&emmc {
+	status = "okay";
+	bus-width = <8>;
+	cap-mmc-highspeed;
+	clock-frequency = <150000000>;
+	disable-wp;
+	keep-power-in-suspend;
+	non-removable;
+	num-slots = <1>;
+	vmmc-supply = <&vcc_io>;
+	vqmmc-supply = <&vcc18_flash>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&emmc_clk>, <&emmc_cmd>, <&emmc_bus8>;
+};
+
+&gmac {
+	status = "okay";
+	phy-supply = <&vcc_lan>;
+	phy-mode = "rgmii";
+	clock_in_out = "input";
+	assigned-clocks = <&cru SCLK_MAC>;
+	assigned-clock-parents = <&ext_gmac>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii_pins>;
+	tx_delay = <0x30>;
+	rx_delay = <0x10>;
+};
+
+&i2c0 {
+	status = "okay";
+
+	rk808: pmic@1b {
+		compatible = "rockchip,rk808";
+		reg = <0x1b>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pmic_int>, <&pmic_sleep>;
+		interrupt-parent = <&gpio0>;
+		interrupts = <5 IRQ_TYPE_LEVEL_LOW>;
+		rockchip,system-power-controller;
+		vcc1-supply = <&vcc_sys>;
+		vcc2-supply = <&vcc_sys>;
+		vcc3-supply = <&vcc_sys>;
+		vcc4-supply = <&vcc_sys>;
+		vcc6-supply = <&vcc_sys>;
+		vcc7-supply = <&vcc_sys>;
+		vcc8-supply = <&vcc_io>;
+		vcc9-supply = <&vcc_sys>;
+		vcc10-supply = <&vcc_sys>;
+		vcc11-supply = <&vcc_sys>;
+		vcc12-supply = <&vcc_io>;
+		clock-output-names = "xin32k", "rk808-clkout2";
+		#clock-cells = <1>;
+
+		regulators {
+			vdd_cpu: DCDC_REG1 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <700000>;
+				regulator-max-microvolt = <1500000>;
+				regulator-name = "vdd_cpu";
+			};
+
+			vdd_log: DCDC_REG2 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <700000>;
+				regulator-max-microvolt = <1500000>;
+				regulator-name = "vdd_log";
+			};
+
+			vcc_ddr: DCDC_REG3 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-name = "vcc_ddr";
+			};
+
+			vcc_io: DCDC_REG4 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-name = "vcc_io";
+			};
+
+			vcc18_flash: LDO_REG1 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vcc18_flash";
+			};
+
+			vcc33_lcd: LDO_REG2 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-name = "vcc33_lcd";
+			};
+
+			vdd_10: LDO_REG3 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <1000000>;
+				regulator-name = "vdd_10";
+			};
+
+			vcca_18: LDO_REG4 {
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vcca_18";
+			};
+
+			vccio_sd: LDO_REG5 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-name = "vccio_sd";
+			};
+
+			vdd10_lcd: LDO_REG6 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <1000000>;
+				regulator-name = "vdd10_lcd";
+			};
+
+			vcc_18: LDO_REG7 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vcc_18";
+			};
+
+			vcc18_lcd: LDO_REG8 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vcc18_lcd";
+			};
+
+			vcc_sd: SWITCH_REG1 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-name = "vcc_sd";
+			};
+
+			vcc_lan: SWITCH_REG2 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-name = "vcc_lan";
+			};
+		};
+	};
+};
+
+&pinctrl {
+	ir {
+		ir_int: ir-int {
+			rockchip,pins = <3 30 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	keys {
+		pwr_key: pwr-key {
+			rockchip,pins = <0 2 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	pmic {
+		pmic_sleep: pmic-sleep {
+			rockchip,pins = <0 0 RK_FUNC_2 &pcfg_pull_none>;
+		};
+
+		pmic_int: pmic-int {
+			rockchip,pins = <0 5 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+};
+
+&tsadc {
+	status = "okay";
+	rockchip,hw-tshut-mode = <0>; /* CRU */
+	rockchip,hw-tshut-polarity = <1>; /* high */
+};
+
+&uart4 {
+	status = "okay";
+};
+
+&usb_host0_ehci {
+	status = "okay";
+};
+
+&usb_otg {
+	status = "okay";
+};
+
+&wdt {
+	status = "okay";
+};
diff --git a/arch/arm/dts/rk3368.dtsi b/arch/arm/dts/rk3368.dtsi
new file mode 100644
index 0000000..025dc32
--- /dev/null
+++ b/arch/arm/dts/rk3368.dtsi
@@ -0,0 +1,1090 @@
+/*
+ * Copyright (c) 2015 Heiko Stuebner <heiko@sntech.de>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This library is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This library is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <dt-bindings/clock/rk3368-cru.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/thermal/thermal.h>
+
+/ {
+	compatible = "rockchip,rk3368";
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	aliases {
+		ethernet0 = &gmac;
+		i2c0 = &i2c0;
+		i2c1 = &i2c1;
+		i2c2 = &i2c2;
+		i2c3 = &i2c3;
+		i2c4 = &i2c4;
+		i2c5 = &i2c5;
+		serial0 = &uart0;
+		serial1 = &uart1;
+		serial2 = &uart2;
+		serial3 = &uart3;
+		serial4 = &uart4;
+		spi0 = &spi0;
+		spi1 = &spi1;
+		spi2 = &spi2;
+	};
+
+	cpus {
+		#address-cells = <0x2>;
+		#size-cells = <0x0>;
+
+		cpu-map {
+			cluster0 {
+				core0 {
+					cpu = <&cpu_b0>;
+				};
+				core1 {
+					cpu = <&cpu_b1>;
+				};
+				core2 {
+					cpu = <&cpu_b2>;
+				};
+				core3 {
+					cpu = <&cpu_b3>;
+				};
+			};
+
+			cluster1 {
+				core0 {
+					cpu = <&cpu_l0>;
+				};
+				core1 {
+					cpu = <&cpu_l1>;
+				};
+				core2 {
+					cpu = <&cpu_l2>;
+				};
+				core3 {
+					cpu = <&cpu_l3>;
+				};
+			};
+		};
+
+		idle-states {
+			entry-method = "psci";
+
+			cpu_sleep: cpu-sleep-0 {
+				compatible = "arm,idle-state";
+				arm,psci-suspend-param = <0x1010000>;
+				entry-latency-us = <0x3fffffff>;
+				exit-latency-us = <0x40000000>;
+				min-residency-us = <0xffffffff>;
+			};
+		};
+
+		cpu_l0: cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53", "arm,armv8";
+			reg = <0x0 0x0>;
+			cpu-idle-states = <&cpu_sleep>;
+			enable-method = "psci";
+
+			#cooling-cells = <2>; /* min followed by max */
+		};
+
+		cpu_l1: cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53", "arm,armv8";
+			reg = <0x0 0x1>;
+			cpu-idle-states = <&cpu_sleep>;
+			enable-method = "psci";
+		};
+
+		cpu_l2: cpu@2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53", "arm,armv8";
+			reg = <0x0 0x2>;
+			cpu-idle-states = <&cpu_sleep>;
+			enable-method = "psci";
+		};
+
+		cpu_l3: cpu@3 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53", "arm,armv8";
+			reg = <0x0 0x3>;
+			cpu-idle-states = <&cpu_sleep>;
+			enable-method = "psci";
+		};
+
+		cpu_b0: cpu@100 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53", "arm,armv8";
+			reg = <0x0 0x100>;
+			cpu-idle-states = <&cpu_sleep>;
+			enable-method = "psci";
+
+			#cooling-cells = <2>; /* min followed by max */
+		};
+
+		cpu_b1: cpu@101 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53", "arm,armv8";
+			reg = <0x0 0x101>;
+			cpu-idle-states = <&cpu_sleep>;
+			enable-method = "psci";
+		};
+
+		cpu_b2: cpu@102 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53", "arm,armv8";
+			reg = <0x0 0x102>;
+			cpu-idle-states = <&cpu_sleep>;
+			enable-method = "psci";
+		};
+
+		cpu_b3: cpu@103 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53", "arm,armv8";
+			reg = <0x0 0x103>;
+			cpu-idle-states = <&cpu_sleep>;
+			enable-method = "psci";
+		};
+	};
+
+	arm-pmu {
+		compatible = "arm,armv8-pmuv3";
+		interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-affinity = <&cpu_l0>, <&cpu_l1>, <&cpu_l2>,
+				     <&cpu_l3>, <&cpu_b0>, <&cpu_b1>,
+				     <&cpu_b2>, <&cpu_b3>;
+	};
+
+	psci {
+		compatible = "arm,psci-0.2";
+		method = "smc";
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <GIC_PPI 13
+			(GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_HIGH)>,
+			     <GIC_PPI 14
+			(GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_HIGH)>,
+			     <GIC_PPI 11
+			(GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_HIGH)>,
+			     <GIC_PPI 10
+			(GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_HIGH)>;
+	};
+
+	xin24m: oscillator {
+		compatible = "fixed-clock";
+		clock-frequency = <24000000>;
+		clock-output-names = "xin24m";
+		#clock-cells = <0>;
+	};
+
+	sdmmc: dwmmc@ff0c0000 {
+		compatible = "rockchip,rk3368-dw-mshc", "rockchip,rk3288-dw-mshc";
+		reg = <0x0 0xff0c0000 0x0 0x4000>;
+		clock-freq-min-max = <400000 150000000>;
+		clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>,
+			 <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>;
+		clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
+		fifo-depth = <0x100>;
+		interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+		status = "disabled";
+	};
+
+	sdio0: dwmmc@ff0d0000 {
+		compatible = "rockchip,rk3368-dw-mshc", "rockchip,rk3288-dw-mshc";
+		reg = <0x0 0xff0d0000 0x0 0x4000>;
+		clock-freq-min-max = <400000 150000000>;
+		clocks = <&cru HCLK_SDIO0>, <&cru SCLK_SDIO0>,
+			 <&cru SCLK_SDIO0_DRV>, <&cru SCLK_SDIO0_SAMPLE>;
+		clock-names = "biu", "ciu", "ciu_drv", "ciu_sample";
+		fifo-depth = <0x100>;
+		interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+		status = "disabled";
+	};
+
+	emmc: dwmmc@ff0f0000 {
+		compatible = "rockchip,rk3368-dw-mshc", "rockchip,rk3288-dw-mshc";
+		reg = <0x0 0xff0f0000 0x0 0x4000>;
+		clock-freq-min-max = <400000 150000000>;
+		clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>,
+			 <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>;
+		clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
+		fifo-depth = <0x100>;
+		interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
+		status = "disabled";
+	};
+
+	saradc: saradc@ff100000 {
+		compatible = "rockchip,saradc";
+		reg = <0x0 0xff100000 0x0 0x100>;
+		interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+		#io-channel-cells = <1>;
+		clocks = <&cru SCLK_SARADC>, <&cru PCLK_SARADC>;
+		clock-names = "saradc", "apb_pclk";
+		status = "disabled";
+	};
+
+	spi0: spi@ff110000 {
+		compatible = "rockchip,rk3368-spi", "rockchip,rk3066-spi";
+		reg = <0x0 0xff110000 0x0 0x1000>;
+		clocks = <&cru SCLK_SPI0>, <&cru PCLK_SPI0>;
+		clock-names = "spiclk", "apb_pclk";
+		interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&spi0_clk &spi0_tx &spi0_rx &spi0_cs0>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	spi1: spi@ff120000 {
+		compatible = "rockchip,rk3368-spi", "rockchip,rk3066-spi";
+		reg = <0x0 0xff120000 0x0 0x1000>;
+		clocks = <&cru SCLK_SPI1>, <&cru PCLK_SPI1>;
+		clock-names = "spiclk", "apb_pclk";
+		interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&spi1_clk &spi1_tx &spi1_rx &spi1_cs0>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	spi2: spi@ff130000 {
+		compatible = "rockchip,rk3368-spi", "rockchip,rk3066-spi";
+		reg = <0x0 0xff130000 0x0 0x1000>;
+		clocks = <&cru SCLK_SPI2>, <&cru PCLK_SPI2>;
+		clock-names = "spiclk", "apb_pclk";
+		interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&spi2_clk &spi2_tx &spi2_rx &spi2_cs0>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	i2c1: i2c@ff140000 {
+		compatible = "rockchip,rk3368-i2c", "rockchip,rk3288-i2c";
+		reg = <0x0 0xff140000 0x0 0x1000>;
+		interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		clock-names = "i2c";
+		clocks = <&cru PCLK_I2C1>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&i2c1_xfer>;
+		status = "disabled";
+	};
+
+	i2c3: i2c@ff150000 {
+		compatible = "rockchip,rk3368-i2c", "rockchip,rk3288-i2c";
+		reg = <0x0 0xff150000 0x0 0x1000>;
+		interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		clock-names = "i2c";
+		clocks = <&cru PCLK_I2C3>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&i2c3_xfer>;
+		status = "disabled";
+	};
+
+	i2c4: i2c@ff160000 {
+		compatible = "rockchip,rk3368-i2c", "rockchip,rk3288-i2c";
+		reg = <0x0 0xff160000 0x0 0x1000>;
+		interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		clock-names = "i2c";
+		clocks = <&cru PCLK_I2C4>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&i2c4_xfer>;
+		status = "disabled";
+	};
+
+	i2c5: i2c@ff170000 {
+		compatible = "rockchip,rk3368-i2c", "rockchip,rk3288-i2c";
+		reg = <0x0 0xff170000 0x0 0x1000>;
+		interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		clock-names = "i2c";
+		clocks = <&cru PCLK_I2C5>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&i2c5_xfer>;
+		status = "disabled";
+	};
+
+	uart0: serial@ff180000 {
+		compatible = "rockchip,rk3368-uart", "snps,dw-apb-uart";
+		reg = <0x0 0xff180000 0x0 0x100>;
+		clock-frequency = <24000000>;
+		clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>;
+		clock-names = "baudclk", "apb_pclk";
+		interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
+		reg-shift = <2>;
+		reg-io-width = <4>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&uart0_xfer>;
+		status = "disabled";
+	};
+
+	uart1: serial@ff190000 {
+		compatible = "rockchip,rk3368-uart", "snps,dw-apb-uart";
+		reg = <0x0 0xff190000 0x0 0x100>;
+		clock-frequency = <24000000>;
+		clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>;
+		clock-names = "baudclk", "apb_pclk";
+		interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
+		reg-shift = <2>;
+		reg-io-width = <4>;
+		pinctrl-names = "default";
+		pinctrl-1 = <&uart0_xfer>;
+		status = "disabled";
+	};
+
+	uart3: serial@ff1b0000 {
+		compatible = "rockchip,rk3368-uart", "snps,dw-apb-uart";
+		reg = <0x0 0xff1b0000 0x0 0x100>;
+		clock-frequency = <24000000>;
+		clocks = <&cru SCLK_UART3>, <&cru PCLK_UART3>;
+		clock-names = "baudclk", "apb_pclk";
+		interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>;
+		reg-shift = <2>;
+		reg-io-width = <4>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&uart3_xfer>;
+		status = "disabled";
+	};
+
+	uart4: serial@ff1c0000 {
+		compatible = "rockchip,rk3368-uart", "snps,dw-apb-uart";
+		reg = <0x0 0xff1c0000 0x0 0x100>;
+		clock-frequency = <24000000>;
+		clocks = <&cru SCLK_UART4>, <&cru PCLK_UART4>;
+		clock-names = "baudclk", "apb_pclk";
+		interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>;
+		reg-shift = <2>;
+		reg-io-width = <4>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&uart4_xfer>;
+		status = "disabled";
+	};
+
+	thermal-zones {
+		cpu {
+			polling-delay-passive = <100>; /* milliseconds */
+			polling-delay = <5000>; /* milliseconds */
+
+			thermal-sensors = <&tsadc 0>;
+
+			trips {
+				cpu_alert0: cpu_alert0 {
+					temperature = <75000>; /* millicelsius */
+					hysteresis = <2000>; /* millicelsius */
+					type = "passive";
+				};
+				cpu_alert1: cpu_alert1 {
+					temperature = <80000>; /* millicelsius */
+					hysteresis = <2000>; /* millicelsius */
+					type = "passive";
+				};
+				cpu_crit: cpu_crit {
+					temperature = <95000>; /* millicelsius */
+					hysteresis = <2000>; /* millicelsius */
+					type = "critical";
+				};
+			};
+
+			cooling-maps {
+				map0 {
+					trip = <&cpu_alert0>;
+					cooling-device =
+					<&cpu_b0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+				};
+				map1 {
+					trip = <&cpu_alert1>;
+					cooling-device =
+					<&cpu_l0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+				};
+			};
+		};
+
+		gpu {
+			polling-delay-passive = <100>; /* milliseconds */
+			polling-delay = <5000>; /* milliseconds */
+
+			thermal-sensors = <&tsadc 1>;
+
+			trips {
+				gpu_alert0: gpu_alert0 {
+					temperature = <80000>; /* millicelsius */
+					hysteresis = <2000>; /* millicelsius */
+					type = "passive";
+				};
+				gpu_crit: gpu_crit {
+					temperature = <115000>; /* millicelsius */
+					hysteresis = <2000>; /* millicelsius */
+					type = "critical";
+				};
+			};
+
+			cooling-maps {
+				map0 {
+					trip = <&gpu_alert0>;
+					cooling-device =
+					<&cpu_b0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+				};
+			};
+		};
+	};
+
+	tsadc: tsadc@ff280000 {
+		compatible = "rockchip,rk3368-tsadc";
+		reg = <0x0 0xff280000 0x0 0x100>;
+		interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru SCLK_TSADC>, <&cru PCLK_TSADC>;
+		clock-names = "tsadc", "apb_pclk";
+		resets = <&cru SRST_TSADC>;
+		reset-names = "tsadc-apb";
+		pinctrl-names = "init", "default", "sleep";
+		pinctrl-0 = <&otp_gpio>;
+		pinctrl-1 = <&otp_out>;
+		pinctrl-2 = <&otp_gpio>;
+		#thermal-sensor-cells = <1>;
+		rockchip,hw-tshut-temp = <95000>;
+		status = "disabled";
+	};
+
+	gmac: ethernet@ff290000 {
+		compatible = "rockchip,rk3368-gmac";
+		reg = <0x0 0xff290000 0x0 0x10000>;
+		interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "macirq";
+		rockchip,grf = <&grf>;
+		clocks = <&cru SCLK_MAC>,
+			<&cru SCLK_MAC_RX>, <&cru SCLK_MAC_TX>,
+			<&cru SCLK_MACREF>, <&cru SCLK_MACREF_OUT>,
+			<&cru ACLK_GMAC>, <&cru PCLK_GMAC>;
+		clock-names = "stmmaceth",
+			"mac_clk_rx", "mac_clk_tx",
+			"clk_mac_ref", "clk_mac_refout",
+			"aclk_mac", "pclk_mac";
+		status = "disabled";
+	};
+
+	usb_host0_ehci: usb@ff500000 {
+		compatible = "generic-ehci";
+		reg = <0x0 0xff500000 0x0 0x100>;
+		interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru HCLK_HOST0>;
+		clock-names = "usbhost";
+		status = "disabled";
+	};
+
+	usb_otg: usb@ff580000 {
+		compatible = "rockchip,rk3368-usb", "rockchip,rk3066-usb",
+				"snps,dwc2";
+		reg = <0x0 0xff580000 0x0 0x40000>;
+		interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru HCLK_OTG0>;
+		clock-names = "otg";
+		dr_mode = "otg";
+		g-np-tx-fifo-size = <16>;
+		g-rx-fifo-size = <275>;
+		g-tx-fifo-size = <256 128 128 64 64 32>;
+		g-use-dma;
+		status = "disabled";
+	};
+
+	i2c0: i2c@ff650000 {
+		compatible = "rockchip,rk3368-i2c", "rockchip,rk3288-i2c";
+		reg = <0x0 0xff650000 0x0 0x1000>;
+		clocks = <&cru PCLK_I2C0>;
+		clock-names = "i2c";
+		interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&i2c0_xfer>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	i2c2: i2c@ff660000 {
+		compatible = "rockchip,rk3368-i2c", "rockchip,rk3288-i2c";
+		reg = <0x0 0xff660000 0x0 0x1000>;
+		interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		clock-names = "i2c";
+		clocks = <&cru PCLK_I2C2>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&i2c2_xfer>;
+		status = "disabled";
+	};
+
+	pwm0: pwm@ff680000 {
+		compatible = "rockchip,rk3368-pwm", "rockchip,rk3288-pwm";
+		reg = <0x0 0xff680000 0x0 0x10>;
+		#pwm-cells = <3>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pwm0_pin>;
+		clocks = <&cru PCLK_PWM1>;
+		clock-names = "pwm";
+		status = "disabled";
+	};
+
+	pwm1: pwm@ff680010 {
+		compatible = "rockchip,rk3368-pwm", "rockchip,rk3288-pwm";
+		reg = <0x0 0xff680010 0x0 0x10>;
+		#pwm-cells = <3>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pwm1_pin>;
+		clocks = <&cru PCLK_PWM1>;
+		clock-names = "pwm";
+		status = "disabled";
+	};
+
+	pwm2: pwm@ff680020 {
+		compatible = "rockchip,rk3368-pwm", "rockchip,rk3288-pwm";
+		reg = <0x0 0xff680020 0x0 0x10>;
+		#pwm-cells = <3>;
+		clocks = <&cru PCLK_PWM1>;
+		clock-names = "pwm";
+		status = "disabled";
+	};
+
+	pwm3: pwm@ff680030 {
+		compatible = "rockchip,rk3368-pwm", "rockchip,rk3288-pwm";
+		reg = <0x0 0xff680030 0x0 0x10>;
+		#pwm-cells = <3>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pwm3_pin>;
+		clocks = <&cru PCLK_PWM1>;
+		clock-names = "pwm";
+		status = "disabled";
+	};
+
+	uart2: serial@ff690000 {
+		compatible = "rockchip,rk3368-uart", "snps,dw-apb-uart";
+		reg = <0x0 0xff690000 0x0 0x100>;
+		clock-frequency = <24000000>;
+		clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>;
+		clock-names = "baudclk", "apb_pclk";
+		interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&uart2_xfer>;
+		reg-shift = <2>;
+		reg-io-width = <4>;
+		status = "disabled";
+	};
+
+	mbox: mbox@ff6b0000 {
+		compatible = "rockchip,rk3368-mailbox";
+		reg = <0x0 0xff6b0000 0x0 0x1000>;
+		interrupts = <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru PCLK_MAILBOX>;
+		clock-names = "pclk_mailbox";
+		#mbox-cells = <1>;
+	};
+
+	pmugrf: syscon@ff738000 {
+		compatible = "rockchip,rk3368-pmugrf", "syscon";
+		reg = <0x0 0xff738000 0x0 0x1000>;
+	};
+
+	cru: clock-controller@ff760000 {
+		compatible = "rockchip,rk3368-cru";
+		reg = <0x0 0xff760000 0x0 0x1000>;
+		rockchip,grf = <&grf>;
+		#clock-cells = <1>;
+		#reset-cells = <1>;
+	};
+
+	grf: syscon@ff770000 {
+		compatible = "rockchip,rk3368-grf", "syscon";
+		reg = <0x0 0xff770000 0x0 0x1000>;
+	};
+
+	wdt: watchdog@ff800000 {
+		compatible = "rockchip,rk3368-wdt", "snps,dw-wdt";
+		reg = <0x0 0xff800000 0x0 0x100>;
+		clocks = <&cru PCLK_WDT>;
+		interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
+		status = "disabled";
+	};
+
+	timer@ff810000 {
+		compatible = "rockchip,rk3368-timer", "rockchip,rk3288-timer";
+		reg = <0x0 0xff810000 0x0 0x20>;
+		interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gic: interrupt-controller@ffb71000 {
+		compatible = "arm,gic-400";
+		interrupt-controller;
+		#interrupt-cells = <3>;
+		#address-cells = <0>;
+
+		reg = <0x0 0xffb71000 0x0 0x1000>,
+		      <0x0 0xffb72000 0x0 0x1000>,
+		      <0x0 0xffb74000 0x0 0x2000>,
+		      <0x0 0xffb76000 0x0 0x2000>;
+		interrupts = <GIC_PPI 9
+		      (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_HIGH)>;
+	};
+
+	pinctrl: pinctrl {
+		compatible = "rockchip,rk3368-pinctrl";
+		rockchip,grf = <&grf>;
+		rockchip,pmu = <&pmugrf>;
+		#address-cells = <0x2>;
+		#size-cells = <0x2>;
+		ranges;
+
+		gpio0: gpio0@ff750000 {
+			compatible = "rockchip,gpio-bank";
+			reg = <0x0 0xff750000 0x0 0x100>;
+			clocks = <&cru PCLK_GPIO0>;
+			interrupts = <GIC_SPI 0x51 IRQ_TYPE_LEVEL_HIGH>;
+
+			gpio-controller;
+			#gpio-cells = <0x2>;
+
+			interrupt-controller;
+			#interrupt-cells = <0x2>;
+		};
+
+		gpio1: gpio1@ff780000 {
+			compatible = "rockchip,gpio-bank";
+			reg = <0x0 0xff780000 0x0 0x100>;
+			clocks = <&cru PCLK_GPIO1>;
+			interrupts = <GIC_SPI 0x52 IRQ_TYPE_LEVEL_HIGH>;
+
+			gpio-controller;
+			#gpio-cells = <0x2>;
+
+			interrupt-controller;
+			#interrupt-cells = <0x2>;
+		};
+
+		gpio2: gpio2@ff790000 {
+			compatible = "rockchip,gpio-bank";
+			reg = <0x0 0xff790000 0x0 0x100>;
+			clocks = <&cru PCLK_GPIO2>;
+			interrupts = <GIC_SPI 0x53 IRQ_TYPE_LEVEL_HIGH>;
+
+			gpio-controller;
+			#gpio-cells = <0x2>;
+
+			interrupt-controller;
+			#interrupt-cells = <0x2>;
+		};
+
+		gpio3: gpio3@ff7a0000 {
+			compatible = "rockchip,gpio-bank";
+			reg = <0x0 0xff7a0000 0x0 0x100>;
+			clocks = <&cru PCLK_GPIO3>;
+			interrupts = <GIC_SPI 0x54 IRQ_TYPE_LEVEL_HIGH>;
+
+			gpio-controller;
+			#gpio-cells = <0x2>;
+
+			interrupt-controller;
+			#interrupt-cells = <0x2>;
+		};
+
+		pcfg_pull_up: pcfg-pull-up {
+			bias-pull-up;
+		};
+
+		pcfg_pull_down: pcfg-pull-down {
+			bias-pull-down;
+		};
+
+		pcfg_pull_none: pcfg-pull-none {
+			bias-disable;
+		};
+
+		pcfg_pull_none_12ma: pcfg-pull-none-12ma {
+			bias-disable;
+			drive-strength = <12>;
+		};
+
+		emmc {
+			emmc_clk: emmc-clk {
+				rockchip,pins = <2 4 RK_FUNC_2 &pcfg_pull_none>;
+			};
+
+			emmc_cmd: emmc-cmd {
+				rockchip,pins = <1 26 RK_FUNC_2 &pcfg_pull_up>;
+			};
+
+			emmc_pwr: emmc-pwr {
+				rockchip,pins = <1 27 RK_FUNC_2 &pcfg_pull_up>;
+			};
+
+			emmc_bus1: emmc-bus1 {
+				rockchip,pins = <1 18 RK_FUNC_2 &pcfg_pull_up>;
+			};
+
+			emmc_bus4: emmc-bus4 {
+				rockchip,pins = <1 18 RK_FUNC_2 &pcfg_pull_up>,
+						<1 19 RK_FUNC_2 &pcfg_pull_up>,
+						<1 20 RK_FUNC_2 &pcfg_pull_up>,
+						<1 21 RK_FUNC_2 &pcfg_pull_up>;
+			};
+
+			emmc_bus8: emmc-bus8 {
+				rockchip,pins = <1 18 RK_FUNC_2 &pcfg_pull_up>,
+						<1 19 RK_FUNC_2 &pcfg_pull_up>,
+						<1 20 RK_FUNC_2 &pcfg_pull_up>,
+						<1 21 RK_FUNC_2 &pcfg_pull_up>,
+						<1 22 RK_FUNC_2 &pcfg_pull_up>,
+						<1 23 RK_FUNC_2 &pcfg_pull_up>,
+						<1 24 RK_FUNC_2 &pcfg_pull_up>,
+						<1 25 RK_FUNC_2 &pcfg_pull_up>;
+			};
+		};
+
+		gmac {
+			rgmii_pins: rgmii-pins {
+				rockchip,pins =	<3 22 RK_FUNC_1 &pcfg_pull_none>,
+						<3 24 RK_FUNC_1 &pcfg_pull_none>,
+						<3 19 RK_FUNC_1 &pcfg_pull_none>,
+						<3 8 RK_FUNC_1 &pcfg_pull_none_12ma>,
+						<3 9 RK_FUNC_1 &pcfg_pull_none_12ma>,
+						<3 10 RK_FUNC_1 &pcfg_pull_none_12ma>,
+						<3 14 RK_FUNC_1 &pcfg_pull_none_12ma>,
+						<3 28 RK_FUNC_1 &pcfg_pull_none_12ma>,
+						<3 13 RK_FUNC_1 &pcfg_pull_none_12ma>,
+						<3 15 RK_FUNC_1 &pcfg_pull_none>,
+						<3 16 RK_FUNC_1 &pcfg_pull_none>,
+						<3 17 RK_FUNC_1 &pcfg_pull_none>,
+						<3 18 RK_FUNC_1 &pcfg_pull_none>,
+						<3 25 RK_FUNC_1 &pcfg_pull_none>,
+						<3 20 RK_FUNC_1 &pcfg_pull_none>;
+			};
+
+			rmii_pins: rmii-pins {
+				rockchip,pins =	<3 22 RK_FUNC_1 &pcfg_pull_none>,
+						<3 24 RK_FUNC_1 &pcfg_pull_none>,
+						<3 19 RK_FUNC_1 &pcfg_pull_none>,
+						<3 8 RK_FUNC_1 &pcfg_pull_none_12ma>,
+						<3 9 RK_FUNC_1 &pcfg_pull_none_12ma>,
+						<3 13 RK_FUNC_1 &pcfg_pull_none_12ma>,
+						<3 15 RK_FUNC_1 &pcfg_pull_none>,
+						<3 16 RK_FUNC_1 &pcfg_pull_none>,
+						<3 20 RK_FUNC_1 &pcfg_pull_none>,
+						<3 21 RK_FUNC_1 &pcfg_pull_none>;
+			};
+		};
+
+		i2c0 {
+			i2c0_xfer: i2c0-xfer {
+				rockchip,pins = <0 6 RK_FUNC_1 &pcfg_pull_none>,
+						<0 7 RK_FUNC_1 &pcfg_pull_none>;
+			};
+		};
+
+		i2c1 {
+			i2c1_xfer: i2c1-xfer {
+				rockchip,pins = <2 21 RK_FUNC_1 &pcfg_pull_none>,
+						<2 22 RK_FUNC_1 &pcfg_pull_none>;
+			};
+		};
+
+		i2c2 {
+			i2c2_xfer: i2c2-xfer {
+				rockchip,pins = <0 9 RK_FUNC_2 &pcfg_pull_none>,
+						<3 31 RK_FUNC_2 &pcfg_pull_none>;
+			};
+		};
+
+		i2c3 {
+			i2c3_xfer: i2c3-xfer {
+				rockchip,pins = <1 16 RK_FUNC_1 &pcfg_pull_none>,
+						<1 17 RK_FUNC_1 &pcfg_pull_none>;
+			};
+		};
+
+		i2c4 {
+			i2c4_xfer: i2c4-xfer {
+				rockchip,pins = <3 24 RK_FUNC_2 &pcfg_pull_none>,
+						<3 25 RK_FUNC_2 &pcfg_pull_none>;
+			};
+		};
+
+		i2c5 {
+			i2c5_xfer: i2c5-xfer {
+				rockchip,pins = <3 26 RK_FUNC_2 &pcfg_pull_none>,
+						<3 27 RK_FUNC_2 &pcfg_pull_none>;
+			};
+		};
+
+		pwm0 {
+			pwm0_pin: pwm0-pin {
+				rockchip,pins = <3 8 RK_FUNC_2 &pcfg_pull_none>;
+			};
+		};
+
+		pwm1 {
+			pwm1_pin: pwm1-pin {
+				rockchip,pins = <0 8 RK_FUNC_2 &pcfg_pull_none>;
+			};
+		};
+
+		pwm3 {
+			pwm3_pin: pwm3-pin {
+				rockchip,pins = <3 29 RK_FUNC_3 &pcfg_pull_none>;
+			};
+		};
+
+		sdio0 {
+			sdio0_bus1: sdio0-bus1 {
+				rockchip,pins = <2 28 RK_FUNC_1 &pcfg_pull_up>;
+			};
+
+			sdio0_bus4: sdio0-bus4 {
+				rockchip,pins = <2 28 RK_FUNC_1 &pcfg_pull_up>,
+						<2 29 RK_FUNC_1 &pcfg_pull_up>,
+						<2 30 RK_FUNC_1 &pcfg_pull_up>,
+						<2 31 RK_FUNC_1 &pcfg_pull_up>;
+			};
+
+			sdio0_cmd: sdio0-cmd {
+				rockchip,pins = <3 0 RK_FUNC_1 &pcfg_pull_up>;
+			};
+
+			sdio0_clk: sdio0-clk {
+				rockchip,pins = <3 1 RK_FUNC_1 &pcfg_pull_none>;
+			};
+
+			sdio0_cd: sdio0-cd {
+				rockchip,pins = <3 2 RK_FUNC_1 &pcfg_pull_up>;
+			};
+
+			sdio0_wp: sdio0-wp {
+				rockchip,pins = <3 3 RK_FUNC_1 &pcfg_pull_up>;
+			};
+
+			sdio0_pwr: sdio0-pwr {
+				rockchip,pins = <3 4 RK_FUNC_1 &pcfg_pull_up>;
+			};
+
+			sdio0_bkpwr: sdio0-bkpwr {
+				rockchip,pins = <3 5 RK_FUNC_1 &pcfg_pull_up>;
+			};
+
+			sdio0_int: sdio0-int {
+				rockchip,pins = <3 6 RK_FUNC_1 &pcfg_pull_up>;
+			};
+		};
+
+		sdmmc {
+			sdmmc_clk: sdmmc-clk {
+				rockchip,pins = <2 9 RK_FUNC_1 &pcfg_pull_none>;
+			};
+
+			sdmmc_cmd: sdmmc-cmd {
+				rockchip,pins = <2 10 RK_FUNC_1 &pcfg_pull_up>;
+			};
+
+			sdmmc_cd: sdmmc-cd {
+				rockchip,pins = <2 11 RK_FUNC_1 &pcfg_pull_up>;
+			};
+
+			sdmmc_bus1: sdmmc-bus1 {
+				rockchip,pins = <2 5 RK_FUNC_1 &pcfg_pull_up>;
+			};
+
+			sdmmc_bus4: sdmmc-bus4 {
+				rockchip,pins = <2 5 RK_FUNC_1 &pcfg_pull_up>,
+						<2 6 RK_FUNC_1 &pcfg_pull_up>,
+						<2 7 RK_FUNC_1 &pcfg_pull_up>,
+						<2 8 RK_FUNC_1 &pcfg_pull_up>;
+			};
+		};
+
+		spi0 {
+			spi0_clk: spi0-clk {
+				rockchip,pins = <1 29 RK_FUNC_2 &pcfg_pull_up>;
+			};
+			spi0_cs0: spi0-cs0 {
+				rockchip,pins = <1 24 RK_FUNC_3 &pcfg_pull_up>;
+			};
+			spi0_cs1: spi0-cs1 {
+				rockchip,pins = <1 25 RK_FUNC_3 &pcfg_pull_up>;
+			};
+			spi0_tx: spi0-tx {
+				rockchip,pins = <1 23 RK_FUNC_3 &pcfg_pull_up>;
+			};
+			spi0_rx: spi0-rx {
+				rockchip,pins = <1 22 RK_FUNC_3 &pcfg_pull_up>;
+			};
+		};
+
+		spi1 {
+			spi1_clk: spi1-clk {
+				rockchip,pins = <1 14 RK_FUNC_2 &pcfg_pull_up>;
+			};
+			spi1_cs0: spi1-cs0 {
+				rockchip,pins = <1 15 RK_FUNC_2 &pcfg_pull_up>;
+			};
+			spi1_cs1: spi1-cs1 {
+				rockchip,pins = <3 28 RK_FUNC_2 &pcfg_pull_up>;
+			};
+			spi1_rx: spi1-rx {
+				rockchip,pins = <1 16 RK_FUNC_2 &pcfg_pull_up>;
+			};
+			spi1_tx: spi1-tx {
+				rockchip,pins = <1 17 RK_FUNC_2 &pcfg_pull_up>;
+			};
+		};
+
+		spi2 {
+			spi2_clk: spi2-clk {
+				rockchip,pins = <0 12 RK_FUNC_2 &pcfg_pull_up>;
+			};
+			spi2_cs0: spi2-cs0 {
+				rockchip,pins = <0 13 RK_FUNC_2 &pcfg_pull_up>;
+			};
+			spi2_rx: spi2-rx {
+				rockchip,pins = <0 10 RK_FUNC_2 &pcfg_pull_up>;
+			};
+			spi2_tx: spi2-tx {
+				rockchip,pins = <0 11 RK_FUNC_2 &pcfg_pull_up>;
+			};
+		};
+
+		tsadc {
+			otp_gpio: otp-gpio {
+				rockchip,pins = <0 3 RK_FUNC_GPIO &pcfg_pull_none>;
+			};
+
+			otp_out: otp-out {
+				rockchip,pins = <0 3 RK_FUNC_1 &pcfg_pull_none>;
+			};
+		};
+
+		uart0 {
+			uart0_xfer: uart0-xfer {
+				rockchip,pins = <2 24 RK_FUNC_1 &pcfg_pull_up>,
+						<2 25 RK_FUNC_1 &pcfg_pull_none>;
+			};
+
+			uart0_cts: uart0-cts {
+				rockchip,pins = <2 26 RK_FUNC_1 &pcfg_pull_none>;
+			};
+
+			uart0_rts: uart0-rts {
+				rockchip,pins = <2 27 RK_FUNC_1 &pcfg_pull_none>;
+			};
+		};
+
+		uart1 {
+			uart1_xfer: uart1-xfer {
+				rockchip,pins = <0 20 RK_FUNC_3 &pcfg_pull_up>,
+						<0 21 RK_FUNC_3 &pcfg_pull_none>;
+			};
+
+			uart1_cts: uart1-cts {
+				rockchip,pins = <0 22 RK_FUNC_3 &pcfg_pull_none>;
+			};
+
+			uart1_rts: uart1-rts {
+				rockchip,pins = <0 23 RK_FUNC_3 &pcfg_pull_none>;
+			};
+		};
+
+		uart2 {
+			uart2_xfer: uart2-xfer {
+				rockchip,pins = <2 6 RK_FUNC_2 &pcfg_pull_up>,
+						<2 5 RK_FUNC_2 &pcfg_pull_none>;
+			};
+			/* no rts / cts for uart2 */
+		};
+
+		uart3 {
+			uart3_xfer: uart3-xfer {
+				rockchip,pins = <3 29 RK_FUNC_2 &pcfg_pull_up>,
+						<3 30 RK_FUNC_3 &pcfg_pull_none>;
+			};
+
+			uart3_cts: uart3-cts {
+				rockchip,pins = <3 16 RK_FUNC_2 &pcfg_pull_none>;
+			};
+
+			uart3_rts: uart3-rts {
+				rockchip,pins = <3 17 RK_FUNC_2 &pcfg_pull_none>;
+			};
+		};
+
+		uart4 {
+			uart4_xfer: uart4-xfer {
+				rockchip,pins = <0 27 RK_FUNC_3 &pcfg_pull_up>,
+						<0 26 RK_FUNC_3 &pcfg_pull_none>;
+			};
+
+			uart4_cts: uart4-cts {
+				rockchip,pins = <0 24 RK_FUNC_3 &pcfg_pull_none>;
+			};
+
+			uart4_rts: uart4-rts {
+				rockchip,pins = <0 25 RK_FUNC_3 &pcfg_pull_none>;
+			};
+		};
+	};
+};
diff --git a/arch/arm/dts/rk3399-puma-ddr1333.dts b/arch/arm/dts/rk3399-puma-ddr1333.dts
new file mode 100644
index 0000000..564de91
--- /dev/null
+++ b/arch/arm/dts/rk3399-puma-ddr1333.dts
@@ -0,0 +1,11 @@
+/*
+ * (C) Copyright 2017 Theobroma Systems Design und Consulting GmbH
+ *
+ * SPDX-License-Identifier:     GPL-2.0+	X11
+ */
+
+/dts-v1/;
+
+#include "rk3399-puma.dtsi"
+#include "rk3399-sdram-ddr3-1333.dtsi"
+
diff --git a/arch/arm/dts/rk3399-puma-ddr1600.dts b/arch/arm/dts/rk3399-puma-ddr1600.dts
new file mode 100644
index 0000000..31aaf70
--- /dev/null
+++ b/arch/arm/dts/rk3399-puma-ddr1600.dts
@@ -0,0 +1,11 @@
+/*
+ * (C) Copyright 2017 Theobroma Systems Design und Consulting GmbH
+ *
+ * SPDX-License-Identifier:     GPL-2.0+	X11
+ */
+
+/dts-v1/;
+
+#include "rk3399-puma.dtsi"
+#include "rk3399-sdram-ddr3-1600.dtsi"
+
diff --git a/arch/arm/dts/rk3399-puma-ddr1866.dts b/arch/arm/dts/rk3399-puma-ddr1866.dts
new file mode 100644
index 0000000..4eec8e7
--- /dev/null
+++ b/arch/arm/dts/rk3399-puma-ddr1866.dts
@@ -0,0 +1,11 @@
+/*
+ * (C) Copyright 2017 Theobroma Systems Design und Consulting GmbH
+ *
+ * SPDX-License-Identifier:     GPL-2.0+	X11
+ */
+
+/dts-v1/;
+
+#include "rk3399-puma.dtsi"
+#include "rk3399-sdram-ddr3-1866.dtsi"
+
diff --git a/arch/arm/dts/rk3399-puma.dts b/arch/arm/dts/rk3399-puma.dts
deleted file mode 100644
index a234db8..0000000
--- a/arch/arm/dts/rk3399-puma.dts
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * (C) Copyright 2017 Theobroma Systems Design und Consulting GmbH
- *
- * SPDX-License-Identifier:     GPL-2.0+	X11
- */
-
-/dts-v1/;
-#include <dt-bindings/pwm/pwm.h>
-#include "rk3399.dtsi"
-#include "rk3399-sdram-ddr3-1600.dtsi"
-
-/ {
-	model = "Theobroma Systems RK3399-Q7 SoM";
-	compatible = "tsd,puma", "rockchip,rk3399";
-
-	config {
-	        u-boot,spl-payload-offset = <204800>;
-	};
-
-	chosen {
-		stdout-path = "serial0:115200n8";
-		u-boot,spl-boot-order = &spiflash, &sdhci, &sdmmc;
-	};
-
-	aliases {
-		spi0 = &spi1;
-		spi1 = &spi5;
-	};
-
-	vdd_center: vdd-center {
-		compatible = "pwm-regulator";
-		pwms = <&pwm3 0 25000 0>;
-		regulator-name = "vdd_center";
-		regulator-min-microvolt = <800000>;
-		regulator-max-microvolt = <1400000>;
-		regulator-init-microvolt = <950000>;
-		regulator-always-on;
-		regulator-boot-on;
-		status = "okay";
-	};
-
-	vcc3v3_sys: vcc3v3-sys {
-		compatible = "regulator-fixed";
-		regulator-name = "vcc3v3_sys";
-		regulator-always-on;
-		regulator-boot-on;
-		regulator-min-microvolt = <3300000>;
-		regulator-max-microvolt = <3300000>;
-	};
-
-	vcc_phy: vcc-phy-regulator {
-		compatible = "regulator-fixed";
-		regulator-name = "vcc_phy";
-		regulator-always-on;
-		regulator-boot-on;
-	};
-
-	vcc5v0_host: vcc5v0-host-en {
-		compatible = "regulator-fixed";
-		regulator-name = "vcc5v0_host";
-		gpio = <&gpio4 25 GPIO_ACTIVE_HIGH>;
-	};
-
-	clkin_gmac: external-gmac-clock {
-		compatible = "fixed-clock";
-		clock-frequency = <125000000>;
-		clock-output-names = "clkin_gmac";
-		#clock-cells = <0>;
-	};
-
-	vcc_phy: vcc-phy-regulator {
-		compatible = "regulator-fixed";
-		regulator-name = "vcc_phy";
-		regulator-always-on;
-		regulator-boot-on;
-	};
-};
-
-&emmc_phy {
-	status = "okay";
-};
-
-&pwm0 {
-	status = "okay";
-};
-
-&pwm2 {
-	status = "okay";
-};
-
-&pwm3 {
-	status = "okay";
-};
-
-&sdmmc {
-        u-boot,dm-pre-reloc;
-	bus-width = <4>;
-	status = "okay";
-};
-
-&sdhci {
-	bus-width = <8>;
-	mmc-hs400-1_8v;
-	mmc-hs400-enhanced-strobe;
-	non-removable;
-	status = "okay";
-};
-
-&uart0 {
-	status = "okay";
-};
-
-&uart2 {
-	status = "okay";
-};
-
-&usb_host0_ehci {
-	status = "okay";
-};
-
-&usb_host0_ohci {
-	status = "okay";
-};
-
-&dwc3_typec0 {
-	status = "okay";
-};
-
-&usb_host1_ehci {
-	status = "okay";
-};
-
-&usb_host1_ohci {
-	status = "okay";
-};
-
-&dwc3_typec1 {
-	status = "okay";
-};
-
-&pinctrl {
-	pmic {
-		pmic_int_l: pmic-int-l {
-			rockchip,pins =
-				<1 21 RK_FUNC_GPIO &pcfg_pull_up>;
-		};
-
-		pmic_dvs2: pmic-dvs2 {
-			rockchip,pins =
-				<1 18 RK_FUNC_GPIO &pcfg_pull_down>;
-		};
-	};
-};
-
-&gmac {
-        phy-supply = <&vcc_phy>;
-	phy-mode = "rgmii";
-	clock_in_out = "input";
-	snps,reset-gpio = <&gpio3 16 GPIO_ACTIVE_LOW>;
-	snps,reset-active-low;
-	snps,reset-delays-us = <0 10000 50000>;
-	assigned-clocks = <&cru SCLK_RMII_SRC>;
-	assigned-clock-parents = <&clkin_gmac>;
-	pinctrl-names = "default";
-	pinctrl-0 = <&rgmii_pins>;
-	tx_delay = <0x10>;
-	rx_delay = <0x10>;
-	status = "okay";
-};
-
-&spi1 {
-	u-boot,dm-pre-reloc;
-
-	status = "okay";
-
-	#address-cells = <1>;
-	#size-cells = <0>;
-
-	spiflash: w25q32dw@0 {
-		u-boot,dm-pre-reloc;
-
-		compatible = "spi-flash";
-		reg = <0>;
-		spi-max-frequency = <5000000>;
-		spi-cpol;
-		spi-cpha;
-	};
-};
-
-&spi5 {
-	status = "okay";
-};
diff --git a/arch/arm/dts/rk3399-puma.dtsi b/arch/arm/dts/rk3399-puma.dtsi
new file mode 100644
index 0000000..1aad6c5
--- /dev/null
+++ b/arch/arm/dts/rk3399-puma.dtsi
@@ -0,0 +1,642 @@
+/*
+ * (C) Copyright 2017 Theobroma Systems Design und Consulting GmbH
+ *
+ * SPDX-License-Identifier:     GPL-2.0+	X11
+ */
+
+#include <dt-bindings/pwm/pwm.h>
+#include "rk3399.dtsi"
+
+/ {
+	model = "Theobroma Systems RK3399-Q7 SoM";
+	compatible = "tsd,rk3399-q7", "tsd,puma", "rockchip,rk3399";
+
+	config {
+		u-boot,spl-payload-offset = <0x40000>; /* 256kbyte */
+		u-boot,boot-led = "module_led";
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+		u-boot,spl-boot-order = &spiflash, &sdhci, &sdmmc;
+	};
+
+	aliases {
+		spi0 = &spi1;
+		spi1 = &spi5;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&leds_pins_puma>;
+
+		module_led {
+			label = "module_led";
+			gpios = <&gpio2 25 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "heartbeat";
+		};
+
+		sd_card_led {
+			label = "sd_card_led";
+			gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "mmc0";
+		};
+	};
+
+	clkin_gmac: external-gmac-clock {
+		compatible = "fixed-clock";
+		clock-frequency = <125000000>;
+		clock-output-names = "clkin_gmac";
+		#clock-cells = <0>;
+	};
+
+	dw_hdmi_audio: dw-hdmi-audio {
+		status = "enabled";
+		compatible = "rockchip,dw-hdmi-audio";
+		#sound-dai-cells = <0>;
+	};
+
+	hdmi_codec: hdmi-codec {
+		compatible = "simple-audio-card";
+		simple-audio-card,format = "i2s";
+		simple-audio-card,mclk-fs = <256>;
+		simple-audio-card,name = "HDMI-CODEC";
+
+		simple-audio-card,cpu {
+			sound-dai = <&i2s2>;
+		};
+
+		simple-audio-card,codec {
+			sound-dai = <&hdmi>;
+		};
+	};
+
+	hdmi_sound: hdmi-sound {
+		status = "disabled";
+		compatible = "simple-audio-card";
+		simple-audio-card,format = "i2s";
+		simple-audio-card,mclk-fs = <256>;
+		simple-audio-card,name = "rockchip,hdmi";
+
+		simple-audio-card,cpu {
+			sound-dai = <&i2s2>;
+		};
+		simple-audio-card,codec {
+			sound-dai = <&hdmi>;
+		};
+	};
+
+	vccadc_ref: vccadc-ref {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc1v8_sys";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+	};
+
+	vcc3v3_sys: vcc3v3-sys {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc3v3_sys";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
+
+	vcc5v0_otg: vcc5v0-otg-regulator {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio0 2 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&otg_vbus_drv>;
+		regulator-name = "vcc5v0_otg";
+		regulator-always-on;
+	};
+
+	vcc5v0_host: vcc5v0-host-regulator {
+		compatible = "regulator-fixed";
+		enable-active-low;
+		gpio = <&gpio4 3 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&host_vbus_drv>;
+		regulator-name = "vcc5v0_host";
+		regulator-always-on;
+	};
+
+	vcc5v0_sys: vcc5v0-sys {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc5v0_sys";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+	};
+
+	vcc_phy: vcc-phy-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_phy";
+		regulator-always-on;
+		regulator-boot-on;
+	};
+
+	vdd_log: vdd-log {
+		compatible = "pwm-regulator";
+		pwms = <&pwm2 0 25000 1>;
+		regulator-name = "vdd_log";
+		regulator-min-microvolt = <800000>;
+		regulator-max-microvolt = <1400000>;
+		regulator-always-on;
+		regulator-boot-on;
+
+		/* for rockchip boot on */
+		rockchip,pwm_id= <2>;
+		rockchip,pwm_voltage = <1000000>;
+	};
+};
+
+&emmc_phy {
+	status = "okay";
+};
+
+&gmac {
+	phy-supply = <&vcc_phy>;
+	phy-mode = "rgmii";
+	clock_in_out = "input";
+	snps,reset-gpio = <&gpio3 16 GPIO_ACTIVE_LOW>;
+	snps,reset-active-low;
+	snps,reset-delays-us = <2 10000 50000>;
+	assigned-clocks = <&cru SCLK_RMII_SRC>;
+	assigned-clock-parents = <&clkin_gmac>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii_pins>;
+	tx_delay = <0x10>;
+	rx_delay = <0x10>;
+	status = "okay";
+};
+
+&hdmi {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	#sound-dai-cells = <0>;
+	status = "okay";
+};
+
+&i2c0 {
+	status = "okay";
+	i2c-scl-rising-time-ns = <168>;
+	i2c-scl-falling-time-ns = <4>;
+	clock-frequency = <400000>;
+
+	vdd_gpu: fan535555@60 {
+		compatible = "fcs,fan53555";
+		reg = <0x60>;
+		vsel-gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>;
+		vin-supply = <&vcc5v0_sys>;
+		regulator-compatible = "fan53555-reg";
+		regulator-name = "vdd_gpu";
+		regulator-min-microvolt = <600000>;
+		regulator-max-microvolt = <1230000>;
+		regulator-ramp-delay = <1000>;
+		fcs,suspend-voltage-selector = <1>;
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-initial-state = <3>;
+			regulator-state-mem {
+			regulator-off-in-suspend;
+		};
+	};
+
+	rk808: pmic@1b {
+		compatible = "rockchip,rk808";
+		reg = <0x1b>;
+		interrupt-parent = <&gpio1>;
+		interrupts = <22 IRQ_TYPE_LEVEL_LOW>;  // TODO check interrupt?
+		pinctrl-names = "default";
+		pinctrl-0 = <&pmic_int_l>;
+		rockchip,system-power-controller;
+		wakeup-source;
+		#clock-cells = <1>;
+		clock-output-names = "xin32k", "rk808-clkout2";
+
+		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 = <&vcc5v0_sys>;
+		vcc10-supply = <&vcc5v0_sys>;
+		vcc11-supply = <&vcc5v0_sys>;
+		vcc12-supply = <&vcc3v3_sys>;
+		vddio-supply = <&vcc1v8_pmu>;
+
+		regulators {
+			vdd_center: DCDC_REG1 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <750000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-ramp-delay = <6001>;
+				regulator-name = "vdd_center";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdd_cpu_l: DCDC_REG2 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <750000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-ramp-delay = <6001>;
+				regulator-name = "vdd_cpu_l";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_ddr: DCDC_REG3 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-name = "vcc_ddr";
+				regulator-state-mem {
+					regulator-on-in-suspend;
+				};
+			};
+
+			vcc_1v8: DCDC_REG4 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vcc_1v8";
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <1800000>;
+				};
+			};
+
+			vcc_ldo1: LDO_REG1 {
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vcc_ldo1";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc1v8_hdmi: LDO_REG2 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vcc1v8_hdmi";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc1v8_pmu: LDO_REG3 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vcc1v8_pmu";
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <1800000>;
+				};
+			};
+
+			vcc_sd: LDO_REG4 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-name = "vcc_sd";
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <3300000>;
+				};
+			};
+
+			vcc_ldo5: LDO_REG5 {
+				regulator-boot-on;
+				regulator-min-microvolt = <3000000>;
+				regulator-max-microvolt = <3000000>;
+				regulator-name = "vcc_ldo5";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_ldo6: LDO_REG6 {
+				regulator-boot-on;
+				regulator-min-microvolt = <1500000>;
+				regulator-max-microvolt = <1500000>;
+				regulator-name = "vcc_ldo6";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc0v9_hdmi: LDO_REG7 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <900000>;
+				regulator-max-microvolt = <900000>;
+				regulator-name = "vcc0v9_hdmi";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_efuse: LDO_REG8 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vcc_efuse";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc3v3_s3: SWITCH_REG1 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-name = "vcc3v3_s3";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc3v3_s0: SWITCH_REG2 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-name = "vcc3v3_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+		};
+	};
+};
+
+&i2c8 {
+	status = "okay";
+	clock-frequency = <400000>;
+
+	vdd_cpu_b: fan53555@60 {
+		compatible = "fcs,fan53555";
+		reg = <0x60>;
+		vsel-gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
+		vin-supply = <&vcc5v0_sys>;
+		regulator-compatible = "fan53555-reg";
+		regulator-name = "vdd_cpu_b";
+		regulator-min-microvolt = <600000>;
+		regulator-max-microvolt = <1230000>;
+		regulator-ramp-delay = <1000>;
+		fcs,suspend-voltage-selector = <1>;
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-initial-state = <3>;
+			regulator-state-mem {
+			regulator-off-in-suspend;
+		};
+	};
+};
+
+&i2s0 {
+	status = "okay";
+	rockchip,i2s-broken-burst-len;
+	rockchip,playback-channels = <8>;
+	rockchip,capture-channels = <8>;
+	#sound-dai-cells = <0>;
+};
+
+&i2s2 {
+	#sound-dai-cells = <0>;
+	status = "okay";
+};
+
+&io_domains {
+	status = "okay";
+
+	bt656-supply = <&vcc_1v8>;	/* bt656_gpio2ab_ms */
+	audio-supply = <&vcc_1v8>;	/* audio_gpio3d4a_ms */
+	sdmmc-supply = <&vcc_sd>;	/* sdmmc_gpio4b_ms */
+	gpio1830-supply = <&vcc_1v8>;	/* gpio1833_gpio4cd_ms */
+};
+
+&pcie0 {
+	assigned-clocks = <&cru SCLK_PCIEPHY_REF>;
+	assigned-clock-parents = <&cru SCLK_PCIEPHY_REF100M>;
+	assigned-clock-rates = <100000000>;
+	ep-gpios = <&gpio4 22 GPIO_ACTIVE_HIGH>;
+	num-lanes = <4>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie_clkreqn>;
+	status = "okay";
+};
+
+&pcie_phy {
+	        status = "okay";
+};
+
+&pmu_io_domains {
+	status = "okay";
+	pmu1830-supply = <&vcc_1v8>;
+};
+
+&pwm0 {
+	status = "okay";
+};
+
+&pwm2 {
+	status = "okay";
+};
+
+&sdhci {
+	bus-width = <8>;
+	mmc-hs400-1_8v;
+	supports-emmc;
+	non-removable;
+	keep-power-in-suspend;
+	mmc-hs400-enhanced-strobe;
+	status = "okay";
+};
+
+&sdmmc {
+        u-boot,dm-pre-reloc;
+	clock-frequency = <150000000>;
+	clock-freq-min-max = <100000 150000000>;
+	supports-sd;
+	bus-width = <4>;
+	cap-mmc-highspeed;
+	cap-sd-highspeed;
+	disable-wp;
+	num-slots = <1>;
+	vqmmc-supply = <&vcc_sd>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>;
+	status = "okay";
+};
+
+&uart2 {
+	status = "okay";
+};
+
+&usb_host0_ehci {
+	status = "okay";
+};
+
+&usb_host0_ohci {
+	status = "okay";
+};
+
+&dwc3_typec0 {
+	status = "disabled";
+};
+
+&usb_host1_ehci {
+	status = "okay";
+};
+
+&usb_host1_ohci {
+	status = "okay";
+};
+
+&dwc3_typec1 {
+	rockchip,vbus-gpio = <&gpio4 3 GPIO_ACTIVE_LOW>;
+	status = "okay";
+};
+
+&vopb {
+	status = "okay";
+};
+
+&pinctrl {
+	/* Pins that are not explicitely used by any devices */
+	pinctrl-names = "default";
+	pinctrl-0 = <&puma_pin_hog>;
+	hog {
+		puma_pin_hog: puma_pin_hog {
+			rockchip,pins =
+				/* We need pull-ups on Q7 buttons */
+				<0  4 RK_FUNC_GPIO &pcfg_pull_up>, /* LID_BTN# */
+				<0 10 RK_FUNC_GPIO &pcfg_pull_up>, /* BATLOW# */
+				<0 11 RK_FUNC_GPIO &pcfg_pull_up>, /* SLP_BTN# */
+				<0  9 RK_FUNC_GPIO &pcfg_pull_up>; /* BIOS_DISABLE# */
+		};
+	};
+
+	pmic {
+		pmic_int_l: pmic-int-l {
+			rockchip,pins =
+				<1 22 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+
+	leds_pins_puma: led_pins@0 {
+			rockchip,pins =
+				<2 25 RK_FUNC_GPIO &pcfg_pull_none>,
+				<1 2 RK_FUNC_GPIO &pcfg_pull_none>;
+	};
+
+	usb2 {
+		otg_vbus_drv: otg-vbus-drv {
+			rockchip,pins =
+				<0 2 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		host_vbus_drv: host-vbus-drv {
+			rockchip,pins =
+				<0 2 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	i2c8 {
+		i2c8_xfer_a: i2c8-xfer {
+			rockchip,pins = <1 21 RK_FUNC_1 &pcfg_pull_up>,
+			                <1 20 RK_FUNC_1 &pcfg_pull_up>;
+		};
+	};
+};
+
+&i2c1 {
+	status = "okay";
+	clock-frequency = <400000>;
+};
+&i2c2 {
+	status = "okay";
+	clock-frequency = <400000>;
+};
+&i2c4 {
+	status = "okay";
+	clock-frequency = <400000>;
+};
+&i2c6 {
+	status = "okay";
+	clock-frequency = <400000>;
+};
+
+&i2c6_xfer {
+	/* Enable pull-ups, the pins would float otherwise. */
+	rockchip,pins =
+		<2 10 RK_FUNC_2 &pcfg_pull_up>,
+		<2 9 RK_FUNC_2 &pcfg_pull_up>;
+};
+
+&i2c7 {
+	status = "okay";
+	clock-frequency = <400000>;
+
+	rtc_twi: rtc@6f {
+		compatible = "isil,isl1208";
+		reg = <0x6f>;
+	};
+	fan: fan@18 {
+		compatible = "ti,amc6821";
+		reg = <0x18>;
+		cooling-min-state = <0>;
+		cooling-max-state = <9>;
+		#cooling-cells = <2>;
+	};
+};
+
+&uart0 {
+	u-boot,dm-pre-reloc;
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_xfer &uart0_cts>;
+	status = "okay";
+};
+
+
+&spi1 {
+	u-boot,dm-pre-reloc;
+
+	status = "okay";
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	spiflash: w25q32dw@0 {
+		u-boot,dm-pre-reloc;
+
+		compatible = "spi-flash";
+		reg = <0>;
+		spi-max-frequency = <49500000>;
+		spi-cpol;
+		spi-cpha;
+	};
+};
+
+&spi5 {
+	status = "okay";
+};
+
diff --git a/arch/arm/dts/rk3399-sdram-ddr3-1866.dtsi b/arch/arm/dts/rk3399-sdram-ddr3-1866.dtsi
new file mode 100644
index 0000000..80e946e
--- /dev/null
+++ b/arch/arm/dts/rk3399-sdram-ddr3-1866.dtsi
@@ -0,0 +1,1537 @@
+/*
+ * (C) 2017 Theobroma Systems Design und Consulting GmbH
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+&dmc {
+        rockchip,sdram-params = <
+		0x1
+		0xa
+		0x3
+		0x2
+		0x1
+		0x0
+		0xf
+		0xf
+		1
+		0x80181219
+		0x17050a03
+		0x00000002
+		0x00006456
+		0x0000004c
+		0x00000000
+		0x1
+		0xa
+		0x3
+		0x2
+		0x1
+		0x0
+		0xf
+		0xf
+		1
+		0x80181219
+		0x17050a03
+		0x00000002
+		0x00006456
+		0x0000004c
+		0x00000000
+		933
+		3
+		2
+		9
+		1
+		0x00000600
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x0000000a
+		0x00000000
+		0x00000000
+		0x00000000
+		0x0000000a
+		0x00000000
+		0x00000000
+		0x00000000
+		0x0000000a
+		0x00000000
+		0x00000000
+		0x01000000
+		0x00000000
+		0x00000101
+		0x00020100
+		0x0002d976
+		0x00071fa6
+		0x02000200
+		0x091a0200
+		0x00091a00
+		0x0400091a
+		0x2c060004
+		0x210c0820
+		0x202c0600
+		0x00210c08
+		0x08202c06
+		0x0800210c
+		0x00000f04
+		0x0501000a
+		0x0f040805
+		0x0501000a
+		0x0f040805
+		0x0501000a
+		0x02030005
+		0x0c0f0c00
+		0x000f0c0f
+		0x14000a0a
+		0x00000a0a
+		0x00010000
+		0x031c1c1c
+		0x000c0c0c
+		0x00000000
+		0x03010000
+		0x1c6a0147
+		0x1c6a0147
+		0x1c6a0147
+		0x00000000
+		0x00060006
+		0x00170006
+		0x00170017
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x02000000
+		0x02000151
+		0x02000151
+		0x00000151
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000301
+		0x00000001
+		0x00000000
+		0x00000000
+		0x01000000
+		0x80104002
+		0x00040003
+		0x00040005
+		0x00030000
+		0x00050004
+		0x00000004
+		0x00040003
+		0x00040005
+		0x71a80000
+		0x000038d4
+		0x38d471a8
+		0x71a80000
+		0x000038d4
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x0a0a0a00
+		0x000a0a0a
+		0x00030200
+		0x00040700
+		0x00000302
+		0x02000407
+		0x00000003
+		0x00030f04
+		0x00070004
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00010000
+		0x00010000
+		0x20040020
+		0x00200400
+		0x01000400
+		0x00000b80
+		0x00000000
+		0x00000001
+		0x00000002
+		0x0000000e
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00bb0000
+		0x00ea005e
+		0x00ea0000
+		0x005e00bb
+		0x000000ea
+		0x00bb00ea
+		0x00ea005e
+		0x00ea0000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00420014
+		0x00140020
+		0x00200042
+		0x00420014
+		0x00000020
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00420014
+		0x00140020
+		0x00200042
+		0x00420014
+		0x00000020
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x01000000
+		0x00000000
+		0x00000000
+		0x18151100
+		0x0000000c
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00025603
+		0x004b012b
+		0x00000000
+		0x012b0256
+		0x0000004b
+		0x00025600
+		0x004b012b
+		0x00000000
+		0x00000000
+		0x00000000
+		0x01010100
+		0x00000202
+		0x0a000001
+		0x01000f0f
+		0x00000000
+		0x00000000
+		0x00010003
+		0x00000c03
+		0x00000000
+		0x00000000
+		0x01000000
+		0x00010000
+		0x00000001
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00010000
+		0x08080802
+		0x01010606
+		0x00000001
+		0x04040400
+		0x03080808
+		0x03050303
+		0x03050303
+		0x00050303
+		0x00020202
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x0d000001
+		0x00010028
+		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
+		0x15150000
+		0x08000015
+		0x000038d4
+		0x00000200
+		0x00000200
+		0x00000200
+		0x00000200
+		0x000038d4
+		0x00023848
+		0x38d4080b
+		0x00000200
+		0x00000200
+		0x00000200
+		0x00000200
+		0x000038d4
+		0x00023848
+		0x38d4080b
+		0x00000200
+		0x00000200
+		0x00000200
+		0x00000200
+		0x000038d4
+		0x00023848
+		0x0202080b
+		0x03030202
+		0x00000014
+		0x00000000
+		0x00000000
+		0x00001403
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00030000
+		0x00060018
+		0x00060018
+		0x00060018
+		0x00000000
+		0x00000000
+		0x01000000
+		0x03080308
+		0x00050308
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x01000100
+		0x01010101
+		0x01000101
+		0x01000100
+		0x00010001
+		0x00010002
+		0x00020100
+		0x00000002
+		0x00000600
+		0x00000000
+		0x000071a8
+		0x000038d4
+		0x000071a8
+		0x000038d4
+		0x000071a8
+		0x38d438d4
+		0x00000200
+		0x00000200
+		0x00000200
+		0x00000200
+		0x000038d4
+		0x00000200
+		0x00000200
+		0x00000200
+		0x00000200
+		0x000038d4
+		0x00000200
+		0x00000200
+		0x00000200
+		0x00000200
+		0x00010000
+		0x00000007
+		0x110f0001
+		0x3c020000
+		0x3fffffff
+		0x3c030000
+		0x1dc0ffff
+		0x3c010000
+		0x1dc0ffff
+		0x3c000000
+		0x1dc0ffff
+		0x3c300400
+		0x1dc7ffff
+		0x3c000000
+		0x00000000
+		0x3c000000
+		0x00000000
+		0x3c000000
+		0x00000000
+		0x03000101
+		0x00262626
+		0x091a0009
+		0x00091a00
+		0x0000001a
+		0x1c6a0147
+		0x1c6a0147
+		0x1c6a0147
+		0x00000500
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x04040000
+		0x0d000004
+		0x00000128
+		0x00000000
+		0x00030003
+		0x00000014
+		0x00000000
+		0x00000000
+		0x08060002
+		0x08010801
+		0x00060601
+		0x00020001
+		0x00080004
+		0x00000000
+		0x00000000
+		0x04040400
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00030300
+		0x00000014
+		0x00000000
+		0x01010300
+		0x00000000
+		0x00000000
+		0x01000000
+		0x00000101
+		0x55555a5a
+		0x55555a5a
+		0x55555a5a
+		0x55555a5a
+		0x0b0b0001
+		0x0808000b
+		0x03030008
+		0x00000103
+		0x00030000
+		0x17030000
+		0x00060018
+		0x00060018
+		0x00060018
+		0x00000000
+		0x00000000
+		0x00000000
+		0x140a0000
+		0x000a000a
+		0x00000a00
+		0x010a000a
+		0x00000100
+		0x01000000
+		0x00000000
+		0x00000100
+		0x1e1a0000
+		0x10010204
+		0x07070705
+		0x20000202
+		0x00201000
+		0x00201000
+		0x04041000
+		0x12120100
+		0x00010112
+		0x004b004a
+		0x1a030000
+		0x0102041e
+		0x34000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00004200
+		0x00000020
+		0x004d4d00
+		0x00200042
+		0x4d000000
+		0x0000424d
+		0x00000020
+		0x004d4d00
+		0x00200042
+		0x4d000000
+		0x0000424d
+		0x00000020
+		0x004d4d00
+		0x00200042
+		0x4d000000
+		0x0042004d
+		0x00000020
+		0x004d4d00
+		0x00200042
+		0x4d000000
+		0x0000424d
+		0x00000020
+		0x004d4d00
+		0x00200042
+		0x4d000000
+		0x0000424d
+		0x00000020
+		0x004d4d00
+		0x00200042
+		0x4d000000
+		0x0000004d
+		0x00ea00ea
+		0x080400ea
+		0x0f080c0c
+		0x2000fd7a
+		0x0a042000
+		0x0c0c080f
+		0x00000f08
+		0x2000fd7a
+		0x0a042000
+		0x0c0c080f
+		0x00000f08
+		0x2000fd7a
+		0x0a042000
+		0x0200020f
+		0x02000200
+		0x02000200
+		0x02000200
+		0x02000200
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x01000300
+		0x0038d400
+		0x00023848
+		0x000038d4
+		0x00023848
+		0x000038d4
+		0x00023848
+		0x08000000
+		0x00000100
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000001
+		0x76543210
+		0x0004c008
+		0x000000de
+		0x00000000
+		0x00000000
+		0x00010000
+		0x01665555
+		0x00665555
+		0x00010f00
+		0x06010200
+		0x00000001
+		0x001700c0
+		0x00cc0001
+		0x00000066
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x04080000
+		0x04080400
+		0x08000000
+		0x0c00c007
+		0x00000100
+		0x00000100
+		0x55555555
+		0xaaaaaaaa
+		0x55555555
+		0xaaaaaaaa
+		0x00005555
+		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
+		0x00de0080
+		0x00000001
+		0x00000000
+		0x00000000
+		0x00000200
+		0x00000000
+		0x51313152
+		0x80013130
+		0x02000080
+		0x00100001
+		0x07064208
+		0x000f0c0f
+		0x01000140
+		0x00000c20
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		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
+		0x0004c008
+		0x000000de
+		0x00000000
+		0x00000000
+		0x00010000
+		0x01665555
+		0x00665555
+		0x00010f00
+		0x06010200
+		0x00000001
+		0x001700c0
+		0x00cc0001
+		0x00000066
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x04080000
+		0x04080400
+		0x08000000
+		0x0c00c007
+		0x00000100
+		0x00000100
+		0x55555555
+		0xaaaaaaaa
+		0x55555555
+		0xaaaaaaaa
+		0x00005555
+		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
+		0x00de0080
+		0x00000001
+		0x00000000
+		0x00000000
+		0x00000200
+		0x00000000
+		0x51313152
+		0x80013130
+		0x02000080
+		0x00100001
+		0x07064208
+		0x000f0c0f
+		0x01000140
+		0x00000c20
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		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
+		0x0004c008
+		0x000000de
+		0x00000000
+		0x00000000
+		0x00010000
+		0x01665555
+		0x00665555
+		0x00010f00
+		0x06010200
+		0x00000001
+		0x001700c0
+		0x00cc0001
+		0x00000066
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x04080000
+		0x04080400
+		0x08000000
+		0x0c00c007
+		0x00000100
+		0x00000100
+		0x55555555
+		0xaaaaaaaa
+		0x55555555
+		0xaaaaaaaa
+		0x00005555
+		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
+		0x00de0080
+		0x00000001
+		0x00000000
+		0x00000000
+		0x00000200
+		0x00000000
+		0x51313152
+		0x80013130
+		0x02000080
+		0x00100001
+		0x07064208
+		0x000f0c0f
+		0x01000140
+		0x00000c20
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		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
+		0x0004c008
+		0x000000de
+		0x00000000
+		0x00000000
+		0x00010000
+		0x01665555
+		0x00665555
+		0x00010f00
+		0x06010200
+		0x00000001
+		0x001700c0
+		0x00cc0001
+		0x00000066
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x04080000
+		0x04080400
+		0x08000000
+		0x0c00c007
+		0x00000100
+		0x00000100
+		0x55555555
+		0xaaaaaaaa
+		0x55555555
+		0xaaaaaaaa
+		0x00005555
+		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
+		0x00de0080
+		0x00000001
+		0x00000000
+		0x00000000
+		0x00000200
+		0x00000000
+		0x51313152
+		0x80013130
+		0x02000080
+		0x00100001
+		0x07064208
+		0x000f0c0f
+		0x01000140
+		0x00000c20
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00800000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00400320
+		0x00000040
+		0x00dcba98
+		0x00000000
+		0x00dcba98
+		0x01000000
+		0x00020003
+		0x00000000
+		0x00000000
+		0x00000000
+		0x0000002a
+		0x00000015
+		0x00000015
+		0x0000002a
+		0x00000033
+		0x0000000c
+		0x0000000c
+		0x00000033
+		0x0a418820
+		0x103f0000
+		0x0000003f
+		0x00030055
+		0x03000300
+		0x03000300
+		0x00000300
+		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
+		0x00800000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00400320
+		0x00000040
+		0x00000000
+		0x00000000
+		0x00000000
+		0x01000000
+		0x00020003
+		0x00000000
+		0x00000000
+		0x00000000
+		0x0000002a
+		0x00000015
+		0x00000015
+		0x0000002a
+		0x00000033
+		0x0000000c
+		0x0000000c
+		0x00000033
+		0x16a4a0e6
+		0x103f0000
+		0x0000003f
+		0x00030055
+		0x03000300
+		0x03000300
+		0x00000300
+		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
+		0x00800000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00400320
+		0x00000040
+		0x00000000
+		0x00000000
+		0x00000000
+		0x01000000
+		0x00020003
+		0x00000000
+		0x00000000
+		0x00000000
+		0x0000002a
+		0x00000015
+		0x00000015
+		0x0000002a
+		0x00000033
+		0x0000000c
+		0x0000000c
+		0x00000033
+		0x1ee6b16a
+		0x103f0000
+		0x0000003f
+		0x00030055
+		0x03000300
+		0x03000300
+		0x00000300
+		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
+		0x00000001
+		0x00000000
+		0x01000005
+		0x04000f00
+		0x00020040
+		0x00020055
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00010100
+		0x00000601
+		0x00000000
+		0x00006400
+		0x01221102
+		0x00000000
+		0x00031f00
+		0x031f031f
+		0x031f031f
+		0x00030003
+		0x03000300
+		0x00000300
+		0x01221102
+		0x00000000
+		0x00000000
+		0x04020000
+		0x00000001
+		0x00008011
+		0x00000011
+		0x00000440
+		0x00000040
+		0x00004011
+		0x00004011
+		0x00004410
+		0x00004410
+		0x00004410
+		0x00004410
+		0x00004410
+		0x00004011
+		0x00004410
+		0x00004011
+		0x00004410
+		0x00004011
+		0x00004410
+		0x00000000
+		0x00000000
+		0x00000000
+		0x04000000
+		0x00000000
+		0x00000000
+		0x00000508
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0xe4000000
+		0x00000000
+		0x00000000
+		0x01010000
+		0x00000000
+	>;
+};
+
diff --git a/arch/arm/dts/rk3399.dtsi b/arch/arm/dts/rk3399.dtsi
index f3d3f53..7f1fc50 100644
--- a/arch/arm/dts/rk3399.dtsi
+++ b/arch/arm/dts/rk3399.dtsi
@@ -1419,6 +1419,11 @@
 				reg = <3>;
 				remote-endpoint = <&mipi_in_vopl>;
 			};
+
+			vopl_out_hdmi: endpoint@1 {
+				reg = <1>;
+				remote-endpoint = <&hdmi_in_vopl>;
+			};
 		};
 	};
 
@@ -1440,6 +1445,40 @@
 				reg = <3>;
 				remote-endpoint = <&mipi_in_vopb>;
 			};
+
+			vopb_out_hdmi: endpoint@1 {
+				reg = <1>;
+				remote-endpoint = <&hdmi_in_vopb>;
+			};
+		};
+	};
+
+	hdmi: hdmi@ff940000 {
+		compatible = "rockchip,rk3399-dw-hdmi";
+		reg = <0x0 0xff940000 0x0 0x20000>;
+		reg-io-width = <4>;
+		rockchip,grf = <&grf>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&hdmi_i2c_xfer>;
+		power-domains = <&power RK3399_PD_HDCP>;
+		interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH 0>;
+		clocks = <&cru PCLK_HDMI_CTRL>, <&cru SCLK_HDMI_SFR>, <&cru PLL_VPLL>, <&cru PCLK_VIO_GRF>;
+		clock-names = "iahb", "isfr", "vpll", "grf";
+		status = "disabled";
+
+		ports {
+			hdmi_in: port {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				hdmi_in_vopb: endpoint@0 {
+					reg = <0>;
+					remote-endpoint = <&vopb_out_hdmi>;
+				};
+				hdmi_in_vopl: endpoint@1 {
+					reg = <1>;
+					remote-endpoint = <&vopl_out_hdmi>;
+				};
+			};
 		};
 	};
 
diff --git a/arch/arm/dts/rv1108-evb.dts b/arch/arm/dts/rv1108-evb.dts
new file mode 100644
index 0000000..0128dd8
--- /dev/null
+++ b/arch/arm/dts/rv1108-evb.dts
@@ -0,0 +1,54 @@
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+/dts-v1/;
+
+#include "rv1108.dtsi"
+
+/ {
+	model = "Rockchip RV1108 Evaluation board";
+	compatible = "rockchip,rv1108-evb", "rockchip,rv1108";
+
+	memory@60000000 {
+		device_type = "memory";
+		reg = <0x60000000 0x08000000>;
+	};
+
+	chosen {
+		stdout-path = "serial2:1500000n8";
+	};
+};
+
+&gmac {
+	status = "okay";
+	clock_in_out = <0>;
+	snps,reset-active-low;
+	snps,reset-delays-us = <0 10000 1000000>;
+	snps,reset-gpio = <&gpio1 RK_PC1 GPIO_ACTIVE_LOW>;
+};
+
+&sfc {
+	status = "okay";
+	flash@0 {
+		compatible = "gd25q256","spi-flash";
+		reg = <0>;
+		spi-tx-bus-width = <1>;
+		spi-rx-bus-width = <1>;
+		spi-max-frequency = <96000000>;
+	};
+};
+
+&uart0 {
+	status = "okay";
+};
+
+&uart1 {
+	status = "okay";
+};
+
+&uart2 {
+	status = "okay";
+};
diff --git a/arch/arm/dts/rv1108.dtsi b/arch/arm/dts/rv1108.dtsi
new file mode 100644
index 0000000..77ca24e
--- /dev/null
+++ b/arch/arm/dts/rv1108.dtsi
@@ -0,0 +1,479 @@
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/rv1108-cru.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	compatible = "rockchip,rv1108";
+
+	interrupt-parent = <&gic>;
+
+	aliases {
+		serial0 = &uart0;
+		serial1 = &uart1;
+		serial2 = &uart2;
+		spi0	= &sfc;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu0: cpu@f00 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0xf00>;
+		};
+	};
+
+	arm-pmu {
+		compatible = "arm,cortex-a7-pmu";
+		interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	timer {
+		compatible = "arm,armv7-timer";
+		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_HIGH)>,
+			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_HIGH)>;
+		clock-frequency = <24000000>;
+	};
+
+	xin24m: oscillator {
+		compatible = "fixed-clock";
+		clock-frequency = <24000000>;
+		clock-output-names = "xin24m";
+		#clock-cells = <0>;
+	};
+
+	amba {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		pdma: pdma@102a0000 {
+			compatible = "arm,pl330", "arm,primecell";
+			reg = <0x102a0000 0x4000>;
+			interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
+			#dma-cells = <1>;
+			arm,pl330-broken-no-flushp;
+			clocks = <&cru ACLK_DMAC>;
+			clock-names = "apb_pclk";
+		};
+	};
+
+	bus_intmem@10080000 {
+		compatible = "mmio-sram";
+		reg = <0x10080000 0x2000>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0 0x10080000 0x2000>;
+	};
+
+	uart2: serial@10210000 {
+		compatible = "rockchip,rv1108-uart", "snps,dw-apb-uart";
+		reg = <0x10210000 0x100>;
+		interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
+		reg-shift = <2>;
+		reg-io-width = <4>;
+		clock-frequency = <24000000>;
+		clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>;
+		clock-names = "baudclk", "apb_pclk";
+		pinctrl-names = "default";
+		pinctrl-0 = <&uart2m0_xfer>;
+		status = "disabled";
+	};
+
+	uart1: serial@10220000 {
+		compatible = "rockchip,rv1108-uart", "snps,dw-apb-uart";
+		reg = <0x10220000 0x100>;
+		interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
+		reg-shift = <2>;
+		reg-io-width = <4>;
+		clock-frequency = <24000000>;
+		clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>;
+		clock-names = "baudclk", "apb_pclk";
+		pinctrl-names = "default";
+		pinctrl-0 = <&uart1_xfer>;
+		status = "disabled";
+	};
+
+	uart0: serial@10230000 {
+		compatible = "rockchip,rv1108-uart", "snps,dw-apb-uart";
+		reg = <0x10230000 0x100>;
+		interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
+		reg-shift = <2>;
+		reg-io-width = <4>;
+		clock-frequency = <24000000>;
+		clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>;
+		clock-names = "baudclk", "apb_pclk";
+		pinctrl-names = "default";
+		pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>;
+		status = "disabled";
+	};
+
+	grf: syscon@10300000 {
+		compatible = "rockchip,rv1108-grf", "syscon";
+		reg = <0x10300000 0x1000>;
+	};
+
+	pmugrf: syscon@20060000 {
+		compatible = "rockchip,rv1108-pmugrf", "syscon";
+		reg = <0x20060000 0x1000>;
+	};
+
+	cru: clock-controller@20200000 {
+		compatible = "rockchip,rv1108-cru";
+		reg = <0x20200000 0x1000>;
+		rockchip,grf = <&grf>;
+		#clock-cells = <1>;
+		#reset-cells = <1>;
+	};
+
+	emmc: dwmmc@30110000 {
+		compatible = "rockchip,rv1108-dw-mshc", "rockchip,rk3288-dw-mshc";
+		clock-freq-min-max = <400000 150000000>;
+		clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>,
+			 <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>;
+		clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
+		fifo-depth = <0x100>;
+		interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+		reg = <0x30110000 0x4000>;
+		status = "disabled";
+	};
+
+	sdio: dwmmc@30120000 {
+		compatible = "rockchip,rv1108-dw-mshc", "rockchip,rk3288-dw-mshc";
+		clock-freq-min-max = <400000 150000000>;
+		clocks = <&cru HCLK_SDIO>, <&cru SCLK_SDIO>,
+			 <&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>;
+		clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
+		fifo-depth = <0x100>;
+		interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+		reg = <0x30120000 0x4000>;
+		status = "disabled";
+	};
+
+	sdmmc: dwmmc@30130000 {
+		compatible = "rockchip,rv1108-dw-mshc", "rockchip,rk3288-dw-mshc";
+		clock-freq-min-max = <400000 100000000>;
+		clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>,
+			 <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>;
+		clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
+		fifo-depth = <0x100>;
+		interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+		reg = <0x30130000 0x4000>;
+		status = "disabled";
+	};
+
+	sfc: sfc@301c0000 {
+		compatible = "rockchip,sfc";
+		reg = <0x301c0000 0x200>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru SCLK_SFC>, <&cru HCLK_SFC>;
+		clock-names = "clk_sfc", "hclk_sfc";
+		pinctrl-0 = <&sfc_pins>;
+		pinctrl-names = "default";
+		status = "disabled";
+        };
+
+	gmac: ethernet@30200000 {
+		compatible = "rockchip,rv1108-gmac";
+		reg = <0x30200000 0x10000>;
+		interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "macirq";
+		rockchip,grf = <&grf>;
+		clocks = <&cru SCLK_MAC>,
+			<&cru SCLK_MAC_RX>, <&cru SCLK_MAC_TX>,
+			<&cru SCLK_MACREF>, <&cru SCLK_MACREF_OUT>,
+			<&cru ACLK_GMAC>, <&cru PCLK_GMAC>;
+                clock-names = "stmmaceth",
+                        "mac_clk_rx", "mac_clk_tx",
+                        "clk_mac_ref", "clk_mac_refout",
+                        "aclk_mac", "pclk_mac";
+		pinctrl-names = "default";
+		pinctrl-0 = <&rmii_pins>;
+		phy-mode = "rmii";
+		max-speed = <100>;
+		status = "disabled";
+	};
+
+	gic: interrupt-controller@32010000 {
+		compatible = "arm,gic-400";
+		interrupt-controller;
+		#interrupt-cells = <3>;
+		#address-cells = <0>;
+
+		reg = <0x32011000 0x1000>,
+		      <0x32012000 0x1000>,
+		      <0x32014000 0x2000>,
+		      <0x32016000 0x2000>;
+		interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_HIGH)>;
+	};
+
+	pinctrl: pinctrl {
+		compatible = "rockchip,rv1108-pinctrl";
+		rockchip,grf = <&grf>;
+		rockchip,pmu = <&pmugrf>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		gpio0: gpio0@20030000 {
+			compatible = "rockchip,gpio-bank";
+			reg = <0x20030000 0x100>;
+			interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&xin24m>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpio1: gpio1@10310000 {
+			compatible = "rockchip,gpio-bank";
+			reg = <0x10310000 0x100>;
+			interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&xin24m>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpio2: gpio2@10320000 {
+			compatible = "rockchip,gpio-bank";
+			reg = <0x10320000 0x100>;
+			interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&xin24m>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpio3: gpio3@10330000 {
+			compatible = "rockchip,gpio-bank";
+			reg = <0x10330000 0x100>;
+			interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&xin24m>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		pcfg_pull_up: pcfg-pull-up {
+			bias-pull-up;
+		};
+
+		pcfg_pull_down: pcfg-pull-down {
+			bias-pull-down;
+		};
+
+		pcfg_pull_none: pcfg-pull-none {
+			bias-disable;
+		};
+
+		pcfg_pull_none_drv_8ma: pcfg-pull-none-drv-8ma {
+			drive-strength = <8>;
+		};
+
+		pcfg_pull_none_drv_12ma: pcfg-pull-none-drv-12ma {
+			drive-strength = <12>;
+		};
+
+		pcfg_pull_up_drv_8ma: pcfg-pull-up-drv-8ma {
+			bias-pull-up;
+			drive-strength = <8>;
+		};
+
+		pcfg_pull_none_drv_4ma: pcfg-pull-none-drv-4ma {
+			drive-strength = <4>;
+		};
+
+		pcfg_pull_up_drv_4ma: pcfg-pull-up-drv-4ma {
+			bias-pull-up;
+			drive-strength = <4>;
+		};
+
+		pcfg_output_high: pcfg-output-high {
+			output-high;
+		};
+
+		pcfg_output_low: pcfg-output-low {
+			output-low;
+		};
+
+		pcfg_input_high: pcfg-input-high {
+			bias-pull-up;
+			input-enable;
+		};
+
+		gmac {
+			rmii_pins: rmii-pins {
+				rockchip,pins = <1 RK_PC5 RK_FUNC_2 &pcfg_pull_none>,
+						<1 RK_PC3 RK_FUNC_2 &pcfg_pull_none>,
+						<1 RK_PC4 RK_FUNC_2 &pcfg_pull_none>,
+						<1 RK_PB2 RK_FUNC_3 &pcfg_pull_none_drv_12ma>,
+						<1 RK_PB3 RK_FUNC_3 &pcfg_pull_none_drv_12ma>,
+						<1 RK_PB4 RK_FUNC_3 &pcfg_pull_none_drv_12ma>,
+						<1 RK_PB5 RK_FUNC_3 &pcfg_pull_none>,
+						<1 RK_PB6 RK_FUNC_3 &pcfg_pull_none>,
+						<1 RK_PB7 RK_FUNC_3 &pcfg_pull_none>,
+						<1 RK_PC2 RK_FUNC_3 &pcfg_pull_none>;
+			};
+		};
+
+		i2c1 {
+			i2c1_xfer: i2c1-xfer {
+				rockchip,pins = <2 RK_PD3 RK_FUNC_1 &pcfg_pull_up>,
+						<2 RK_PD4 RK_FUNC_1 &pcfg_pull_up>;
+			};
+		};
+
+		i2c2m1 {
+			i2c2m1_xfer: i2c2m1-xfer {
+				rockchip,pins = <0 RK_PC2 RK_FUNC_2 &pcfg_pull_none>,
+						<0 RK_PC6 RK_FUNC_3 &pcfg_pull_none>;
+			};
+
+			i2c2m1_gpio: i2c2m1-gpio {
+				rockchip,pins = <0 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>,
+						<0 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>;
+			};
+		};
+
+		i2c2m05v {
+			i2c2m05v_xfer: i2c2m05v-xfer {
+				rockchip,pins = <1 RK_PD5 RK_FUNC_2 &pcfg_pull_none>,
+						<1 RK_PD4 RK_FUNC_2 &pcfg_pull_none>;
+			};
+
+			i2c2m05v_gpio: i2c2m05v-gpio {
+				rockchip,pins = <1 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>,
+						<1 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>;
+			};
+		};
+
+		i2c3 {
+			i2c3_xfer: i2c3-xfer {
+				rockchip,pins = <0 RK_PB6 RK_FUNC_1 &pcfg_pull_none>,
+						<0 RK_PC4 RK_FUNC_2 &pcfg_pull_none>;
+			};
+		};
+
+		sfc {
+			sfc_pins: sfc-pins {
+				rockchip,pins = <2 RK_PA3 RK_FUNC_3 &pcfg_pull_none>,
+						<2 RK_PA2 RK_FUNC_3 &pcfg_pull_none>,
+						<2 RK_PA1 RK_FUNC_3 &pcfg_pull_none>,
+						<2 RK_PA0 RK_FUNC_3 &pcfg_pull_none>,
+						<2 RK_PB7 RK_FUNC_2 &pcfg_pull_none>,
+						<2 RK_PB4 RK_FUNC_3 &pcfg_pull_none>;
+			};
+		};
+
+		sdmmc {
+			sdmmc_clk: sdmmc-clk {
+				rockchip,pins = <3 RK_PC4 RK_FUNC_1 &pcfg_pull_none_drv_4ma>;
+			};
+
+			sdmmc_cmd: sdmmc-cmd {
+				rockchip,pins = <3 RK_PC5 RK_FUNC_1 &pcfg_pull_up_drv_4ma>;
+			};
+
+			sdmmc_cd: sdmmc-cd {
+				rockchip,pins = <0 RK_PA1 RK_FUNC_1 &pcfg_pull_up_drv_4ma>;
+			};
+
+			sdmmc_bus1: sdmmc-bus1 {
+				rockchip,pins = <3 RK_PC3 RK_FUNC_1 &pcfg_pull_up_drv_4ma>;
+			};
+
+			sdmmc_bus4: sdmmc-bus4 {
+				rockchip,pins = <3 RK_PC3 RK_FUNC_1 &pcfg_pull_up_drv_4ma>,
+						<3 RK_PC2 RK_FUNC_1 &pcfg_pull_up_drv_4ma>,
+						<3 RK_PC1 RK_FUNC_1 &pcfg_pull_up_drv_4ma>,
+						<3 RK_PC0 RK_FUNC_1 &pcfg_pull_up_drv_4ma>;
+			};
+		};
+
+		uart0 {
+			uart0_xfer: uart0-xfer {
+				rockchip,pins = <3 RK_PA6 RK_FUNC_1 &pcfg_pull_up>,
+						<3 RK_PA5 RK_FUNC_1 &pcfg_pull_none>;
+			};
+
+			uart0_cts: uart0-cts {
+				rockchip,pins = <3 RK_PA4 RK_FUNC_1 &pcfg_pull_none>;
+			};
+
+			uart0_rts: uart0-rts {
+				rockchip,pins = <3 RK_PA3 RK_FUNC_1 &pcfg_pull_none>;
+			};
+
+			uart0_rts_gpio: uart0-rts-gpio {
+				rockchip,pins = <3 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none>;
+			};
+		};
+
+		uart1 {
+			uart1_xfer: uart1-xfer {
+				rockchip,pins = <1 RK_PD3 RK_FUNC_1 &pcfg_pull_up>,
+						<1 RK_PD2 RK_FUNC_1 &pcfg_pull_none>;
+			};
+
+			uart1_cts: uart1-cts {
+				rockchip,pins = <1 RK_PD0 RK_FUNC_1 &pcfg_pull_none>;
+			};
+
+			uart01rts: uart1-rts {
+				rockchip,pins = <1 RK_PD1 RK_FUNC_1 &pcfg_pull_none>;
+			};
+		};
+
+		uart2m0 {
+			uart2m0_xfer: uart2m0-xfer {
+				rockchip,pins = <2 RK_PD2 RK_FUNC_1 &pcfg_pull_up>,
+						<2 RK_PD1 RK_FUNC_1 &pcfg_pull_none>;
+			};
+		};
+
+		uart2m1 {
+			uart2m1_xfer: uart2m1-xfer {
+				rockchip,pins = <3 RK_PC3 RK_FUNC_2 &pcfg_pull_up>,
+						<3 RK_PC2 RK_FUNC_2 &pcfg_pull_none>;
+			};
+		};
+
+		uart2_5v {
+			uart2_5v_cts: uart2_5v-cts {
+				rockchip,pins = <1 RK_PD4 RK_FUNC_1 &pcfg_pull_none>;
+			};
+
+			uart2_5v_rts: uart2_5v-rts {
+				rockchip,pins = <1 RK_PD5 RK_FUNC_1 &pcfg_pull_none>;
+			};
+		};
+	};
+};
diff --git a/arch/arm/include/asm/arch-rockchip/cru_rk3036.h b/arch/arm/include/asm/arch-rockchip/cru_rk3036.h
index aaef4b9..22278e1 100644
--- a/arch/arm/include/asm/arch-rockchip/cru_rk3036.h
+++ b/arch/arm/include/asm/arch-rockchip/cru_rk3036.h
@@ -16,9 +16,9 @@
 #define CORE_PERI_HZ	150000000
 #define CORE_ACLK_HZ	300000000
 
-#define CPU_ACLK_HZ	150000000
-#define CPU_HCLK_HZ	300000000
-#define CPU_PCLK_HZ	300000000
+#define BUS_ACLK_HZ	148500000
+#define BUS_HCLK_HZ	148500000
+#define BUS_PCLK_HZ	74250000
 
 #define PERI_ACLK_HZ	148500000
 #define PERI_HCLK_HZ	148500000
@@ -68,102 +68,102 @@
 
 enum {
 	/* PLLCON0*/
-	PLL_POSTDIV1_MASK	= 7,
 	PLL_POSTDIV1_SHIFT	= 12,
-	PLL_FBDIV_MASK		= 0xfff,
+	PLL_POSTDIV1_MASK	= 7 << PLL_POSTDIV1_SHIFT,
 	PLL_FBDIV_SHIFT		= 0,
+	PLL_FBDIV_MASK		= 0xfff,
 
 	/* PLLCON1 */
-	PLL_DSMPD_MASK		= 1,
-	PLL_DSMPD_SHIFT		= 12,
-	PLL_LOCK_STATUS_MASK	= 1,
-	PLL_LOCK_STATUS_SHIFT	= 10,
-	PLL_POSTDIV2_MASK	= 7,
-	PLL_POSTDIV2_SHIFT	= 6,
-	PLL_REFDIV_MASK		= 0x3f,
-	PLL_REFDIV_SHIFT	= 0,
 	PLL_RST_SHIFT		= 14,
+	PLL_DSMPD_SHIFT		= 12,
+	PLL_DSMPD_MASK		= 1 << PLL_DSMPD_SHIFT,
+	PLL_LOCK_STATUS_SHIFT	= 10,
+	PLL_LOCK_STATUS_MASK	= 1 << PLL_LOCK_STATUS_SHIFT,
+	PLL_POSTDIV2_SHIFT	= 6,
+	PLL_POSTDIV2_MASK	= 7 << PLL_POSTDIV2_SHIFT,
+	PLL_REFDIV_SHIFT	= 0,
+	PLL_REFDIV_MASK		= 0x3f,
 
 	/* CRU_MODE */
-	GPLL_MODE_MASK		= 3,
 	GPLL_MODE_SHIFT		= 12,
+	GPLL_MODE_MASK		= 3 << GPLL_MODE_SHIFT,
 	GPLL_MODE_SLOW		= 0,
 	GPLL_MODE_NORM,
 	GPLL_MODE_DEEP,
-	DPLL_MODE_MASK		= 1,
 	DPLL_MODE_SHIFT		= 4,
+	DPLL_MODE_MASK		= 1 << DPLL_MODE_SHIFT,
 	DPLL_MODE_SLOW		= 0,
 	DPLL_MODE_NORM,
-	APLL_MODE_MASK		= 1,
 	APLL_MODE_SHIFT		= 0,
+	APLL_MODE_MASK		= 1 << APLL_MODE_SHIFT,
 	APLL_MODE_SLOW		= 0,
 	APLL_MODE_NORM,
 
 	/* CRU_CLK_SEL0_CON */
-	CPU_CLK_PLL_SEL_MASK	= 3,
-	CPU_CLK_PLL_SEL_SHIFT	= 14,
-	CPU_CLK_PLL_SEL_APLL	= 0,
-	CPU_CLK_PLL_SEL_DPLL,
-	CPU_CLK_PLL_SEL_GPLL,
-	ACLK_CPU_DIV_MASK	= 0x1f,
-	ACLK_CPU_DIV_SHIFT	= 8,
-	CORE_CLK_PLL_SEL_MASK	= 1,
+	BUS_ACLK_PLL_SEL_SHIFT	= 14,
+	BUS_ACLK_PLL_SEL_MASK	= 3 << BUS_ACLK_PLL_SEL_SHIFT,
+	BUS_ACLK_PLL_SEL_APLL	= 0,
+	BUS_ACLK_PLL_SEL_DPLL,
+	BUS_ACLK_PLL_SEL_GPLL,
+	BUS_ACLK_DIV_SHIFT	= 8,
+	BUS_ACLK_DIV_MASK	= 0x1f << BUS_ACLK_DIV_SHIFT,
 	CORE_CLK_PLL_SEL_SHIFT	= 7,
+	CORE_CLK_PLL_SEL_MASK	= 1 << CORE_CLK_PLL_SEL_SHIFT,
 	CORE_CLK_PLL_SEL_APLL	= 0,
 	CORE_CLK_PLL_SEL_GPLL,
-	CORE_DIV_CON_MASK	= 0x1f,
 	CORE_DIV_CON_SHIFT	= 0,
+	CORE_DIV_CON_MASK	= 0x1f << CORE_DIV_CON_SHIFT,
 
 	/* CRU_CLK_SEL1_CON */
-	CPU_PCLK_DIV_MASK	= 7,
-	CPU_PCLK_DIV_SHIFT	= 12,
-	CPU_HCLK_DIV_MASK	= 3,
-	CPU_HCLK_DIV_SHIFT	= 8,
-	CORE_ACLK_DIV_MASK	= 7,
+	BUS_PCLK_DIV_SHIFT	= 12,
+	BUS_PCLK_DIV_MASK	= 7 << BUS_PCLK_DIV_SHIFT,
+	BUS_HCLK_DIV_SHIFT	= 8,
+	BUS_HCLK_DIV_MASK	= 3 << BUS_HCLK_DIV_SHIFT,
 	CORE_ACLK_DIV_SHIFT	= 4,
-	CORE_PERI_DIV_MASK	= 0xf,
+	CORE_ACLK_DIV_MASK	= 7 << CORE_ACLK_DIV_SHIFT,
 	CORE_PERI_DIV_SHIFT	= 0,
+	CORE_PERI_DIV_MASK	= 0xf << CORE_PERI_DIV_SHIFT,
 
 	/* CRU_CLKSEL10_CON */
-	PERI_PLL_SEL_MASK	= 3,
 	PERI_PLL_SEL_SHIFT	= 14,
+	PERI_PLL_SEL_MASK	= 3 << PERI_PLL_SEL_SHIFT,
 	PERI_PLL_APLL		= 0,
 	PERI_PLL_DPLL,
 	PERI_PLL_GPLL,
-	PERI_PCLK_DIV_MASK	= 3,
 	PERI_PCLK_DIV_SHIFT	= 12,
-	PERI_HCLK_DIV_MASK	= 3,
+	PERI_PCLK_DIV_MASK	= 3 << PERI_PCLK_DIV_SHIFT,
 	PERI_HCLK_DIV_SHIFT	= 8,
-	PERI_ACLK_DIV_MASK	= 0x1f,
+	PERI_HCLK_DIV_MASK	= 3 << PERI_HCLK_DIV_SHIFT,
 	PERI_ACLK_DIV_SHIFT	= 0,
+	PERI_ACLK_DIV_MASK	= 0x1f << PERI_ACLK_DIV_SHIFT,
 
 	/* CRU_CLKSEL11_CON */
-	SDIO_DIV_MASK		= 0x7f,
 	SDIO_DIV_SHIFT		= 8,
-	MMC0_DIV_MASK		= 0x7f,
+	SDIO_DIV_MASK		= 0x7f << SDIO_DIV_SHIFT,
 	MMC0_DIV_SHIFT		= 0,
+	MMC0_DIV_MASK		= 0x7f << MMC0_DIV_SHIFT,
 
 	/* CRU_CLKSEL12_CON */
-	EMMC_PLL_MASK		= 3,
 	EMMC_PLL_SHIFT		= 12,
+	EMMC_PLL_MASK		= 3 << EMMC_PLL_SHIFT,
 	EMMC_SEL_APLL		= 0,
 	EMMC_SEL_DPLL,
 	EMMC_SEL_GPLL,
 	EMMC_SEL_24M,
-	SDIO_PLL_MASK		= 3,
 	SDIO_PLL_SHIFT		= 10,
+	SDIO_PLL_MASK		= 3 << SDIO_PLL_SHIFT,
 	SDIO_SEL_APLL		= 0,
 	SDIO_SEL_DPLL,
 	SDIO_SEL_GPLL,
 	SDIO_SEL_24M,
-	MMC0_PLL_MASK		= 3,
 	MMC0_PLL_SHIFT		= 8,
+	MMC0_PLL_MASK		= 3 << MMC0_PLL_SHIFT,
 	MMC0_SEL_APLL		= 0,
 	MMC0_SEL_DPLL,
 	MMC0_SEL_GPLL,
 	MMC0_SEL_24M,
-	EMMC_DIV_MASK		= 0x7f,
 	EMMC_DIV_SHIFT		= 0,
+	EMMC_DIV_MASK		= 0x7f << EMMC_DIV_SHIFT,
 
 	/* CRU_SOFTRST5_CON */
 	DDRCTRL_PSRST_SHIFT	= 11,
diff --git a/arch/arm/include/asm/arch-rockchip/cru_rk3368.h b/arch/arm/include/asm/arch-rockchip/cru_rk3368.h
new file mode 100644
index 0000000..4910ee7
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/cru_rk3368.h
@@ -0,0 +1,124 @@
+/*
+ * (C) Copyright 2017 Rockchip Electronics Co., Ltd
+ * Author: Andy Yan <andy.yan@rock-chips.com>
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+#ifndef _ASM_ARCH_CRU_RK3368_H
+#define _ASM_ARCH_CRU_RK3368_H
+
+#include <common.h>
+
+
+/* RK3368 clock numbers */
+enum rk3368_pll_id {
+	APLLB,
+	APLLL,
+	DPLL,
+	CPLL,
+	GPLL,
+	NPLL,
+	PLL_COUNT,
+};
+
+struct rk3368_cru {
+	struct rk3368_pll {
+		unsigned int con0;
+		unsigned int con1;
+		unsigned int con2;
+		unsigned int con3;
+	} pll[6];
+	unsigned int reserved[0x28];
+	unsigned int clksel_con[56];
+	unsigned int reserved1[8];
+	unsigned int clkgate_con[25];
+	unsigned int reserved2[7];
+	unsigned int glb_srst_fst_val;
+	unsigned int glb_srst_snd_val;
+	unsigned int reserved3[0x1e];
+	unsigned int softrst_con[15];
+	unsigned int reserved4[0x11];
+	unsigned int misc_con;
+	unsigned int glb_cnt_th;
+	unsigned int glb_rst_con;
+	unsigned int glb_rst_st;
+	unsigned int reserved5[0x1c];
+	unsigned int sdmmc_con[2];
+	unsigned int sdio0_con[2];
+	unsigned int sdio1_con[2];
+	unsigned int emmc_con[2];
+};
+check_member(rk3368_cru, emmc_con[1], 0x41c);
+
+struct rk3368_clk_priv {
+	struct rk3368_cru *cru;
+	ulong rate;
+	bool has_bwadj;
+};
+
+enum {
+	/* PLL CON0 */
+	PLL_NR_SHIFT			= 8,
+	PLL_NR_MASK			= GENMASK(13, 8),
+	PLL_OD_SHIFT			= 0,
+	PLL_OD_MASK			= GENMASK(3, 0),
+
+	/* PLL CON1 */
+	PLL_LOCK_STA			= BIT(31),
+	PLL_NF_SHIFT			= 0,
+	PLL_NF_MASK			= GENMASK(12, 0),
+
+	/* PLL CON2 */
+	PLL_BWADJ_SHIFT			= 0,
+	PLL_BWADJ_MASK			= GENMASK(11, 0),
+
+	/* PLL CON3 */
+	PLL_MODE_SHIFT			= 8,
+	PLL_MODE_MASK			= GENMASK(9, 8),
+	PLL_MODE_SLOW			= 0,
+	PLL_MODE_NORMAL			= 1,
+	PLL_MODE_DEEP_SLOW		= 3,
+	PLL_RESET_SHIFT			= 5,
+	PLL_RESET			= 1,
+	PLL_RESET_MASK			= GENMASK(5, 5),
+
+	/* CLKSEL12_CON */
+	MCU_STCLK_DIV_SHIFT		= 8,
+	MCU_STCLK_DIV_MASK		= GENMASK(10, 8),
+	MCU_PLL_SEL_SHIFT		= 7,
+	MCU_PLL_SEL_MASK		= BIT(7),
+	MCU_PLL_SEL_CPLL		= 0,
+	MCU_PLL_SEL_GPLL		= 1,
+	MCU_CLK_DIV_SHIFT		= 0,
+	MCU_CLK_DIV_MASK		= GENMASK(4, 0),
+
+	/* CLKSEL51_CON */
+	MMC_PLL_SEL_SHIFT		= 8,
+	MMC_PLL_SEL_MASK		= GENMASK(9, 8),
+	MMC_PLL_SEL_CPLL		= 0,
+	MMC_PLL_SEL_GPLL,
+	MMC_PLL_SEL_USBPHY_480M,
+	MMC_PLL_SEL_24M,
+	MMC_CLK_DIV_SHIFT		= 0,
+	MMC_CLK_DIV_MASK		= GENMASK(6, 0),
+
+	/* SOFTRST1_CON */
+	MCU_PO_SRST_MASK		= BIT(13),
+	MCU_SYS_SRST_MASK		= BIT(12),
+
+	/* GLB_RST_CON */
+	PMU_GLB_SRST_CTRL_SHIFT		= 2,
+	PMU_GLB_SRST_CTRL_MASK		= GENMASK(3, 2),
+	PMU_RST_BY_FST_GLB_SRST 	= 0,
+	PMU_RST_BY_SND_GLB_SRST 	= 1,
+	PMU_RST_DISABLE			= 2,
+	WDT_GLB_SRST_CTRL_SHIFT		= 1,
+	WDT_GLB_SRST_CTRL_MASK		= BIT(1),
+	WDT_TRIGGER_SND_GLB_SRST 	= 0,
+	WDT_TRIGGER_FST_GLB_SRST 	= 1,
+	TSADC_GLB_SRST_CTRL_SHIFT 	= 0,
+	TSADC_GLB_SRST_CTRL_MASK  	= BIT(0),
+	TSADC_TRIGGER_SND_GLB_SRST 	= 0,
+	TSADC_TRIGGER_FST_GLB_SRST 	= 1,
+
+};
+#endif
diff --git a/arch/arm/include/asm/arch-rockchip/cru_rv1108.h b/arch/arm/include/asm/arch-rockchip/cru_rv1108.h
new file mode 100644
index 0000000..2a1ae69
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/cru_rv1108.h
@@ -0,0 +1,111 @@
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ * Author: Andy Yan <andy.yan@rock-chips.com>
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+#ifndef _ASM_ARCH_CRU_RV1108_H
+#define _ASM_ARCH_CRU_RV1108_H
+
+#include <common.h>
+
+#define OSC_HZ		(24 * 1000 * 1000)
+
+#define APLL_HZ		(600 * 1000000)
+#define GPLL_HZ		(594 * 1000000)
+
+struct rv1108_clk_priv {
+	struct rv1108_cru *cru;
+	ulong rate;
+};
+
+struct rv1108_cru {
+	struct rv1108_pll {
+		unsigned int con0;
+		unsigned int con1;
+		unsigned int con2;
+		unsigned int con3;
+		unsigned int con4;
+		unsigned int con5;
+		unsigned int reserved[2];
+	} pll[3];
+	unsigned int clksel_con[46];
+	unsigned int reserved1[2];
+	unsigned int clkgate_con[20];
+	unsigned int reserved2[4];
+	unsigned int softrst_con[13];
+	unsigned int reserved3[3];
+	unsigned int glb_srst_fst_val;
+	unsigned int glb_srst_snd_val;
+	unsigned int glb_cnt_th;
+	unsigned int misc_con;
+	unsigned int glb_rst_con;
+	unsigned int glb_rst_st;
+	unsigned int sdmmc_con[2];
+	unsigned int sdio_con[2];
+	unsigned int emmc_con[2];
+};
+check_member(rv1108_cru, emmc_con[1], 0x01ec);
+
+struct pll_div {
+	u32 refdiv;
+	u32 fbdiv;
+	u32 postdiv1;
+	u32 postdiv2;
+	u32 frac;
+};
+
+enum {
+	/* PLL CON0 */
+	FBDIV_MASK		= 0xfff,
+	FBDIV_SHIFT		= 0,
+
+	/* PLL CON1 */
+	POSTDIV2_SHIFT          = 12,
+	POSTDIV2_MASK		= 7 << POSTDIV2_SHIFT,
+	POSTDIV1_SHIFT          = 8,
+	POSTDIV1_MASK		= 7 << POSTDIV1_SHIFT,
+	REFDIV_MASK		= 0x3f,
+	REFDIV_SHIFT		= 0,
+
+	/* PLL CON2 */
+	LOCK_STA_SHIFT          = 31,
+	LOCK_STA_MASK		= 1 << LOCK_STA_SHIFT,
+	FRACDIV_MASK		= 0xffffff,
+	FRACDIV_SHIFT		= 0,
+
+	/* PLL CON3 */
+	WORK_MODE_SHIFT         = 8,
+	WORK_MODE_MASK		= 1 << WORK_MODE_SHIFT,
+	WORK_MODE_SLOW		= 0,
+	WORK_MODE_NORMAL	= 1,
+	DSMPD_SHIFT             = 3,
+	DSMPD_MASK		= 1 << DSMPD_SHIFT,
+
+	/* CLKSEL0_CON */
+	CORE_PLL_SEL_SHIFT	= 8,
+	CORE_PLL_SEL_MASK	= 3 << CORE_PLL_SEL_SHIFT,
+	CORE_PLL_SEL_APLL	= 0,
+	CORE_PLL_SEL_GPLL	= 1,
+	CORE_PLL_SEL_DPLL	= 2,
+	CORE_CLK_DIV_SHIFT	= 0,
+	CORE_CLK_DIV_MASK	= 0x1f << CORE_CLK_DIV_SHIFT,
+
+	/* CLKSEL24_CON */
+	MAC_PLL_SEL_SHIFT	= 12,
+	MAC_PLL_SEL_MASK	= 1 << MAC_PLL_SEL_SHIFT,
+	MAC_PLL_SEL_APLL	= 0,
+	MAC_PLL_SEL_GPLL	= 1,
+	RMII_EXTCLK_SEL_SHIFT   = 8,
+	RMII_EXTCLK_SEL_MASK	= 1 << RMII_EXTCLK_SEL_SHIFT,
+	MAC_CLK_DIV_MASK	= 0x1f,
+	MAC_CLK_DIV_SHIFT	= 0,
+
+	/* CLKSEL27_CON */
+	SFC_PLL_SEL_SHIFT	= 7,
+	SFC_PLL_SEL_MASK	= 1 << SFC_PLL_SEL_SHIFT,
+	SFC_PLL_SEL_DPLL	= 0,
+	SFC_PLL_SEL_GPLL	= 1,
+	SFC_CLK_DIV_SHIFT	= 0,
+	SFC_CLK_DIV_MASK	= 0x3f << SFC_CLK_DIV_SHIFT,
+};
+#endif
diff --git a/arch/arm/include/asm/arch-rockchip/grf_rk3036.h b/arch/arm/include/asm/arch-rockchip/grf_rk3036.h
index 72d133c..7625f24 100644
--- a/arch/arm/include/asm/arch-rockchip/grf_rk3036.h
+++ b/arch/arm/include/asm/arch-rockchip/grf_rk3036.h
@@ -83,57 +83,56 @@
 /* GRF_GPIO0A_IOMUX */
 enum {
 	GPIO0A3_SHIFT		= 6,
-	GPIO0A3_MASK		= 1,
+	GPIO0A3_MASK		= 1 << GPIO0A3_SHIFT,
 	GPIO0A3_GPIO		= 0,
 	GPIO0A3_I2C1_SDA,
 
 	GPIO0A2_SHIFT		= 4,
-	GPIO0A2_MASK		= 1,
+	GPIO0A2_MASK		= 1 << GPIO0A2_SHIFT,
 	GPIO0A2_GPIO		= 0,
 	GPIO0A2_I2C1_SCL,
 
 	GPIO0A1_SHIFT		= 2,
-	GPIO0A1_MASK		= 3,
+	GPIO0A1_MASK		= 3 << GPIO0A1_SHIFT,
 	GPIO0A1_GPIO		= 0,
 	GPIO0A1_I2C0_SDA,
 	GPIO0A1_PWM2,
 
 	GPIO0A0_SHIFT		= 0,
-	GPIO0A0_MASK		= 3,
+	GPIO0A0_MASK		= 3 << GPIO0A0_SHIFT,
 	GPIO0A0_GPIO		= 0,
 	GPIO0A0_I2C0_SCL,
 	GPIO0A0_PWM1,
-
 };
 
 /* GRF_GPIO0B_IOMUX */
 enum {
 	GPIO0B6_SHIFT		= 12,
-	GPIO0B6_MASK		= 3,
+	GPIO0B6_MASK		= 3 << GPIO0B6_SHIFT,
 	GPIO0B6_GPIO		= 0,
 	GPIO0B6_MMC1_D3,
 	GPIO0B6_I2S1_SCLK,
 
 	GPIO0B5_SHIFT		= 10,
-	GPIO0B5_MASK		= 3,
+	GPIO0B5_MASK		= 3 << GPIO0B5_SHIFT,
 	GPIO0B5_GPIO		= 0,
 	GPIO0B5_MMC1_D2,
 	GPIO0B5_I2S1_SDI,
 
 	GPIO0B4_SHIFT		= 8,
-	GPIO0B4_MASK		= 3,
+	GPIO0B4_MASK		= 3 << GPIO0B4_SHIFT,
 	GPIO0B4_GPIO		= 0,
 	GPIO0B4_MMC1_D1,
 	GPIO0B4_I2S1_LRCKTX,
 
 	GPIO0B3_SHIFT		= 6,
-	GPIO0B3_MASK		= 3,
+	GPIO0B3_MASK		= 3 << GPIO0B3_SHIFT,
 	GPIO0B3_GPIO		= 0,
 	GPIO0B3_MMC1_D0,
 	GPIO0B3_I2S1_LRCKRX,
 
 	GPIO0B1_SHIFT		= 2,
-	GPIO0B1_MASK		= 3,
+	GPIO0B1_MASK		= 3 << GPIO0B1_SHIFT,
 	GPIO0B1_GPIO		= 0,
 	GPIO0B1_MMC1_CLKOUT,
 	GPIO0B1_I2S1_MCLK,
@@ -148,28 +147,28 @@
 /* GRF_GPIO0C_IOMUX */
 enum {
 	GPIO0C4_SHIFT		= 8,
-	GPIO0C4_MASK		= 1,
+	GPIO0C4_MASK		= 1 << GPIO0C4_SHIFT,
 	GPIO0C4_GPIO		= 0,
 	GPIO0C4_DRIVE_VBUS,
 
 	GPIO0C3_SHIFT		= 6,
-	GPIO0C3_MASK		= 1,
+	GPIO0C3_MASK		= 1 << GPIO0C3_SHIFT,
 	GPIO0C3_GPIO		= 0,
 	GPIO0C3_UART0_CTSN,
 
 	GPIO0C2_SHIFT		= 4,
-	GPIO0C2_MASK		= 1,
+	GPIO0C2_MASK		= 1 << GPIO0C2_SHIFT,
 	GPIO0C2_GPIO		= 0,
 	GPIO0C2_UART0_RTSN,
 
 	GPIO0C1_SHIFT		= 2,
-	GPIO0C1_MASK		= 1,
+	GPIO0C1_MASK		= 1 << GPIO0C1_SHIFT,
 	GPIO0C1_GPIO		= 0,
 	GPIO0C1_UART0_SIN,
 
 
 	GPIO0C0_SHIFT		= 0,
-	GPIO0C0_MASK		= 1,
+	GPIO0C0_MASK		= 1 << GPIO0C0_SHIFT,
 	GPIO0C0_GPIO		= 0,
 	GPIO0C0_UART0_SOUT,
 };
@@ -177,17 +176,17 @@
 /* GRF_GPIO0D_IOMUX */
 enum {
 	GPIO0D4_SHIFT		= 8,
-	GPIO0D4_MASK		= 1,
+	GPIO0D4_MASK		= 1 << GPIO0D4_SHIFT,
 	GPIO0D4_GPIO		= 0,
 	GPIO0D4_SPDIF,
 
 	GPIO0D3_SHIFT		= 6,
-	GPIO0D3_MASK		= 1,
+	GPIO0D3_MASK		= 1 << GPIO0D3_SHIFT,
 	GPIO0D3_GPIO		= 0,
 	GPIO0D3_PWM3,
 
 	GPIO0D2_SHIFT		= 4,
-	GPIO0D2_MASK		= 1,
+	GPIO0D2_MASK		= 1 << GPIO0D2_SHIFT,
 	GPIO0D2_GPIO		= 0,
 	GPIO0D2_PWM0,
 };
@@ -195,33 +194,33 @@
 /* GRF_GPIO1A_IOMUX */
 enum {
 	GPIO1A5_SHIFT		= 10,
-	GPIO1A5_MASK		= 1,
+	GPIO1A5_MASK		= 1 << GPIO1A5_SHIFT,
 	GPIO1A5_GPIO		= 0,
 	GPIO1A5_I2S_SDI,
 
 	GPIO1A4_SHIFT		= 8,
-	GPIO1A4_MASK		= 1,
+	GPIO1A4_MASK		= 1 << GPIO1A4_SHIFT,
 	GPIO1A4_GPIO		= 0,
 	GPIO1A4_I2S_SD0,
 
 	GPIO1A3_SHIFT		= 6,
-	GPIO1A3_MASK		= 1,
+	GPIO1A3_MASK		= 1 << GPIO1A3_SHIFT,
 	GPIO1A3_GPIO		= 0,
 	GPIO1A3_I2S_LRCKTX,
 
 	GPIO1A2_SHIFT		= 4,
-	GPIO1A2_MASK		= 6,
+	GPIO1A2_MASK		= 6 << GPIO1A2_SHIFT,
 	GPIO1A2_GPIO		= 0,
 	GPIO1A2_I2S_LRCKRX,
 	GPIO1A2_I2S_PWM1_0,
 
 	GPIO1A1_SHIFT		= 2,
-	GPIO1A1_MASK		= 1,
+	GPIO1A1_MASK		= 1 << GPIO1A1_SHIFT,
 	GPIO1A1_GPIO		= 0,
 	GPIO1A1_I2S_SCLK,
 
 	GPIO1A0_SHIFT		= 0,
-	GPIO1A0_MASK		= 1,
+	GPIO1A0_MASK		= 1 << GPIO1A0_SHIFT,
 	GPIO1A0_GPIO		= 0,
 	GPIO1A0_I2S_MCLK,
 
@@ -230,27 +229,27 @@
 /* GRF_GPIO1B_IOMUX */
 enum {
 	GPIO1B7_SHIFT		= 14,
-	GPIO1B7_MASK		= 1,
+	GPIO1B7_MASK		= 1 << GPIO1B7_SHIFT,
 	GPIO1B7_GPIO		= 0,
 	GPIO1B7_MMC0_CMD,
 
 	GPIO1B3_SHIFT		= 6,
-	GPIO1B3_MASK		= 1,
+	GPIO1B3_MASK		= 1 << GPIO1B3_SHIFT,
 	GPIO1B3_GPIO		= 0,
 	GPIO1B3_HDMI_HPD,
 
 	GPIO1B2_SHIFT		= 4,
-	GPIO1B2_MASK		= 1,
+	GPIO1B2_MASK		= 1 << GPIO1B2_SHIFT,
 	GPIO1B2_GPIO		= 0,
 	GPIO1B2_HDMI_SCL,
 
 	GPIO1B1_SHIFT		= 2,
-	GPIO1B1_MASK		= 1,
+	GPIO1B1_MASK		= 1 << GPIO1B1_SHIFT,
 	GPIO1B1_GPIO		= 0,
 	GPIO1B1_HDMI_SDA,
 
 	GPIO1B0_SHIFT		= 0,
-	GPIO1B0_MASK		= 1,
+	GPIO1B0_MASK		= 1 << GPIO1B0_SHIFT,
 	GPIO1B0_GPIO		= 0,
 	GPIO1B0_HDMI_CEC,
 };
@@ -258,36 +257,36 @@
 /* GRF_GPIO1C_IOMUX */
 enum {
 	GPIO1C5_SHIFT		= 10,
-	GPIO1C5_MASK		= 3,
+	GPIO1C5_MASK		= 3 << GPIO1C5_SHIFT,
 	GPIO1C5_GPIO		= 0,
 	GPIO1C5_MMC0_D3,
 	GPIO1C5_JTAG_TMS,
 
 	GPIO1C4_SHIFT		= 8,
-	GPIO1C4_MASK		= 3,
+	GPIO1C4_MASK		= 3 << GPIO1C4_SHIFT,
 	GPIO1C4_GPIO		= 0,
 	GPIO1C4_MMC0_D2,
 	GPIO1C4_JTAG_TCK,
 
 	GPIO1C3_SHIFT		= 6,
-	GPIO1C3_MASK		= 3,
+	GPIO1C3_MASK		= 3 << GPIO1C3_SHIFT,
 	GPIO1C3_GPIO		= 0,
 	GPIO1C3_MMC0_D1,
 	GPIO1C3_UART2_SOUT,
 
 	GPIO1C2_SHIFT		= 4,
-	GPIO1C2_MASK		= 3,
+	GPIO1C2_MASK		= 3 << GPIO1C2_SHIFT ,
 	GPIO1C2_GPIO		= 0,
 	GPIO1C2_MMC0_D0,
 	GPIO1C2_UART2_SIN,
 
 	GPIO1C1_SHIFT		= 2,
-	GPIO1C1_MASK		= 1,
+	GPIO1C1_MASK		= 1 << GPIO1C1_SHIFT,
 	GPIO1C1_GPIO		= 0,
 	GPIO1C1_MMC0_DETN,
 
 	GPIO1C0_SHIFT		= 0,
-	GPIO1C0_MASK		= 1,
+	GPIO1C0_MASK		= 1 << GPIO1C0_SHIFT,
 	GPIO1C0_GPIO		= 0,
 	GPIO1C0_MMC0_CLKOUT,
 };
@@ -295,56 +294,56 @@
 /* GRF_GPIO1D_IOMUX */
 enum {
 	GPIO1D7_SHIFT		= 14,
-	GPIO1D7_MASK		= 3,
+	GPIO1D7_MASK		= 3 << GPIO1D7_SHIFT,
 	GPIO1D7_GPIO		= 0,
 	GPIO1D7_NAND_D7,
 	GPIO1D7_EMMC_D7,
 	GPIO1D7_SPI_CSN1,
 
 	GPIO1D6_SHIFT		= 12,
-	GPIO1D6_MASK		= 3,
+	GPIO1D6_MASK		= 3 << GPIO1D6_SHIFT,
 	GPIO1D6_GPIO		= 0,
 	GPIO1D6_NAND_D6,
 	GPIO1D6_EMMC_D6,
 	GPIO1D6_SPI_CSN0,
 
 	GPIO1D5_SHIFT		= 10,
-	GPIO1D5_MASK		= 3,
+	GPIO1D5_MASK		= 3 << GPIO1D5_SHIFT,
 	GPIO1D5_GPIO		= 0,
 	GPIO1D5_NAND_D5,
 	GPIO1D5_EMMC_D5,
 	GPIO1D5_SPI_TXD,
 
 	GPIO1D4_SHIFT		= 8,
-	GPIO1D4_MASK		= 3,
+	GPIO1D4_MASK		= 3 << GPIO1D4_SHIFT,
 	GPIO1D4_GPIO		= 0,
 	GPIO1D4_NAND_D4,
 	GPIO1D4_EMMC_D4,
 	GPIO1D4_SPI_RXD,
 
 	GPIO1D3_SHIFT		= 6,
-	GPIO1D3_MASK		= 3,
+	GPIO1D3_MASK		= 3 << GPIO1D3_SHIFT,
 	GPIO1D3_GPIO		= 0,
 	GPIO1D3_NAND_D3,
 	GPIO1D3_EMMC_D3,
 	GPIO1D3_SFC_SIO3,
 
 	GPIO1D2_SHIFT		= 4,
-	GPIO1D2_MASK		= 3,
+	GPIO1D2_MASK		= 3 << GPIO1D2_SHIFT,
 	GPIO1D2_GPIO		= 0,
 	GPIO1D2_NAND_D2,
 	GPIO1D2_EMMC_D2,
 	GPIO1D2_SFC_SIO2,
 
 	GPIO1D1_SHIFT		= 2,
-	GPIO1D1_MASK		= 3,
+	GPIO1D1_MASK		= 3 << GPIO1D1_SHIFT,
 	GPIO1D1_GPIO		= 0,
 	GPIO1D1_NAND_D1,
 	GPIO1D1_EMMC_D1,
 	GPIO1D1_SFC_SIO1,
 
 	GPIO1D0_SHIFT		= 0,
-	GPIO1D0_MASK		= 3,
+	GPIO1D0_MASK		= 3 << GPIO1D0_SHIFT,
 	GPIO1D0_GPIO		= 0,
 	GPIO1D0_NAND_D0,
 	GPIO1D0_EMMC_D0,
@@ -354,42 +353,42 @@
 /* GRF_GPIO2A_IOMUX */
 enum {
 	GPIO2A7_SHIFT		= 14,
-	GPIO2A7_MASK		= 1,
+	GPIO2A7_MASK		= 1 << GPIO2A7_SHIFT,
 	GPIO2A7_GPIO		= 0,
 	GPIO2A7_TESTCLK_OUT,
 
 	GPIO2A6_SHIFT		= 12,
-	GPIO2A6_MASK		= 1,
+	GPIO2A6_MASK		= 1 << GPIO2A6_SHIFT,
 	GPIO2A6_GPIO		= 0,
 	GPIO2A6_NAND_CS0,
 
 	GPIO2A4_SHIFT		= 8,
-	GPIO2A4_MASK		= 3,
+	GPIO2A4_MASK		= 3 << GPIO2A4_SHIFT,
 	GPIO2A4_GPIO		= 0,
 	GPIO2A4_NAND_RDY,
 	GPIO2A4_EMMC_CMD,
 	GPIO2A3_SFC_CLK,
 
 	GPIO2A3_SHIFT		= 6,
-	GPIO2A3_MASK		= 3,
+	GPIO2A3_MASK		= 3 << GPIO2A3_SHIFT,
 	GPIO2A3_GPIO		= 0,
 	GPIO2A3_NAND_RDN,
 	GPIO2A4_SFC_CSN1,
 
 	GPIO2A2_SHIFT		= 4,
-	GPIO2A2_MASK		= 3,
+	GPIO2A2_MASK		= 3 << GPIO2A2_SHIFT,
 	GPIO2A2_GPIO		= 0,
 	GPIO2A2_NAND_WRN,
 	GPIO2A4_SFC_CSN0,
 
 	GPIO2A1_SHIFT		= 2,
-	GPIO2A1_MASK		= 3,
+	GPIO2A1_MASK		= 3 << GPIO2A1_SHIFT,
 	GPIO2A1_GPIO		= 0,
 	GPIO2A1_NAND_CLE,
 	GPIO2A1_EMMC_CLKOUT,
 
 	GPIO2A0_SHIFT		= 0,
-	GPIO2A0_MASK		= 3,
+	GPIO2A0_MASK		= 3 << GPIO2A0_SHIFT,
 	GPIO2A0_GPIO		= 0,
 	GPIO2A0_NAND_ALE,
 	GPIO2A0_SPI_CLK,
@@ -398,28 +397,28 @@
 /* GRF_GPIO2B_IOMUX */
 enum {
 	GPIO2B7_SHIFT		= 14,
-	GPIO2B7_MASK		= 1,
+	GPIO2B7_MASK		= 1 << GPIO2B7_SHIFT,
 	GPIO2B7_GPIO		= 0,
 	GPIO2B7_MAC_RXER,
 
 	GPIO2B6_SHIFT		= 12,
-	GPIO2B6_MASK		= 3,
+	GPIO2B6_MASK		= 3 << GPIO2B6_SHIFT,
 	GPIO2B6_GPIO		= 0,
 	GPIO2B6_MAC_CLKOUT,
 	GPIO2B6_MAC_CLKIN,
 
 	GPIO2B5_SHIFT		= 10,
-	GPIO2B5_MASK		= 1,
+	GPIO2B5_MASK		= 1 << GPIO2B5_SHIFT,
 	GPIO2B5_GPIO		= 0,
 	GPIO2B5_MAC_TXEN,
 
 	GPIO2B4_SHIFT		= 8,
-	GPIO2B4_MASK		= 1,
+	GPIO2B4_MASK		= 1 << GPIO2B4_SHIFT,
 	GPIO2B4_GPIO		= 0,
 	GPIO2B4_MAC_MDIO,
 
 	GPIO2B2_SHIFT		= 4,
-	GPIO2B2_MASK		= 1,
+	GPIO2B2_MASK		= 1 << GPIO2B2_SHIFT,
 	GPIO2B2_GPIO		= 0,
 	GPIO2B2_MAC_CRS,
 };
@@ -427,43 +426,43 @@
 /* GRF_GPIO2C_IOMUX */
 enum {
 	GPIO2C7_SHIFT		= 14,
-	GPIO2C7_MASK		= 3,
+	GPIO2C7_MASK		= 3 << GPIO2C7_SHIFT,
 	GPIO2C7_GPIO		= 0,
 	GPIO2C7_UART1_SOUT,
 	GPIO2C7_TESTCLK_OUT1,
 
 	GPIO2C6_SHIFT		= 12,
-	GPIO2C6_MASK		= 1,
+	GPIO2C6_MASK		= 1 << GPIO2C6_SHIFT,
 	GPIO2C6_GPIO		= 0,
 	GPIO2C6_UART1_SIN,
 
 	GPIO2C5_SHIFT		= 10,
-	GPIO2C5_MASK		= 1,
+	GPIO2C5_MASK		= 1 << GPIO2C5_SHIFT,
 	GPIO2C5_GPIO		= 0,
 	GPIO2C5_I2C2_SCL,
 
 	GPIO2C4_SHIFT		= 8,
-	GPIO2C4_MASK		= 1,
+	GPIO2C4_MASK		= 1 << GPIO2C4_SHIFT,
 	GPIO2C4_GPIO		= 0,
 	GPIO2C4_I2C2_SDA,
 
 	GPIO2C3_SHIFT		= 6,
-	GPIO2C3_MASK		= 1,
+	GPIO2C3_MASK		= 1 << GPIO2C3_SHIFT,
 	GPIO2C3_GPIO		= 0,
 	GPIO2C3_MAC_TXD0,
 
 	GPIO2C2_SHIFT		= 4,
-	GPIO2C2_MASK		= 1,
+	GPIO2C2_MASK		= 1 << GPIO2C2_SHIFT,
 	GPIO2C2_GPIO		= 0,
 	GPIO2C2_MAC_TXD1,
 
 	GPIO2C1_SHIFT		= 2,
-	GPIO2C1_MASK		= 1,
+	GPIO2C1_MASK		= 1 << GPIO2C1_SHIFT,
 	GPIO2C1_GPIO		= 0,
 	GPIO2C1_MAC_RXD0,
 
 	GPIO2C0_SHIFT		= 0,
-	GPIO2C0_MASK		= 1,
+	GPIO2C0_MASK		= 1 << GPIO2C0_SHIFT,
 	GPIO2C0_GPIO		= 0,
 	GPIO2C0_MAC_RXD1,
 };
@@ -471,22 +470,22 @@
 /* GRF_GPIO2D_IOMUX */
 enum {
 	GPIO2D6_SHIFT		= 12,
-	GPIO2D6_MASK		= 1,
+	GPIO2D6_MASK		= 1 << GPIO2D6_SHIFT,
 	GPIO2D6_GPIO		= 0,
 	GPIO2D6_I2S_SDO1,
 
 	GPIO2D5_SHIFT		= 10,
-	GPIO2D5_MASK		= 1,
+	GPIO2D5_MASK		= 1 << GPIO2D5_SHIFT,
 	GPIO2D5_GPIO		= 0,
 	GPIO2D5_I2S_SDO2,
 
 	GPIO2D4_SHIFT		= 8,
-	GPIO2D4_MASK		= 1,
+	GPIO2D4_MASK		= 1 << GPIO2D4_SHIFT,
 	GPIO2D4_GPIO		= 0,
 	GPIO2D4_I2S_SDO3,
 
 	GPIO2D1_SHIFT		= 2,
-	GPIO2D1_MASK		= 1,
+	GPIO2D1_MASK		= 1 << GPIO2D1_SHIFT,
 	GPIO2D1_GPIO		= 0,
 	GPIO2D1_MAC_MDC,
 };
diff --git a/arch/arm/include/asm/arch-rockchip/grf_rk3288.h b/arch/arm/include/asm/arch-rockchip/grf_rk3288.h
index 7d56b8c..fbc4a0d 100644
--- a/arch/arm/include/asm/arch-rockchip/grf_rk3288.h
+++ b/arch/arm/include/asm/arch-rockchip/grf_rk3288.h
@@ -813,7 +813,7 @@
 		(1 << RK3288_TXCLK_DLY_ENA_GMAC_SHIFT),
 	RK3288_TXCLK_DLY_ENA_GMAC_DISABLE = 0,
 	RK3288_TXCLK_DLY_ENA_GMAC_ENABLE =
-		(1 << RK3288_RXCLK_DLY_ENA_GMAC_SHIFT),
+		(1 << RK3288_TXCLK_DLY_ENA_GMAC_SHIFT),
 
 	RK3288_CLK_RX_DL_CFG_GMAC_SHIFT = 0x7,
 	RK3288_CLK_RX_DL_CFG_GMAC_MASK =
diff --git a/arch/arm/include/asm/arch-rockchip/grf_rk3328.h b/arch/arm/include/asm/arch-rockchip/grf_rk3328.h
index 2776cef..f0a0781 100644
--- a/arch/arm/include/asm/arch-rockchip/grf_rk3328.h
+++ b/arch/arm/include/asm/arch-rockchip/grf_rk3328.h
@@ -131,4 +131,118 @@
 };
 check_member(rk3328_sgrf_regs, hdcp_key_access_mask, 0x2a0);
 
+enum {
+	/* GPIO0A_IOMUX */
+	GPIO0A5_SEL_SHIFT	= 10,
+	GPIO0A5_SEL_MASK	= 3 << GPIO0A5_SEL_SHIFT,
+	GPIO0A5_I2C3_SCL	= 2,
+
+	GPIO0A6_SEL_SHIFT	= 12,
+	GPIO0A6_SEL_MASK	= 3 << GPIO0A6_SEL_SHIFT,
+	GPIO0A6_I2C3_SDA	= 2,
+
+	GPIO0A7_SEL_SHIFT	= 14,
+	GPIO0A7_SEL_MASK	= 3 << GPIO0A7_SEL_SHIFT,
+	GPIO0A7_EMMC_DATA0	= 2,
+
+	/* GPIO0D_IOMUX*/
+	GPIO0D6_SEL_SHIFT	= 12,
+	GPIO0D6_SEL_MASK	= 3 << GPIO0D6_SEL_SHIFT,
+	GPIO0D6_GPIO		= 0,
+	GPIO0D6_SDMMC0_PWRENM1	= 3,
+
+	/* GPIO1A_IOMUX */
+	GPIO1A0_SEL_SHIFT	= 0,
+	GPIO1A0_SEL_MASK	= 0x3fff << GPIO1A0_SEL_SHIFT,
+	GPIO1A0_CARD_DATA_CLK_CMD_DETN	= 0x1555,
+
+	/* GPIO2A_IOMUX */
+	GPIO2A0_SEL_SHIFT	= 0,
+	GPIO2A0_SEL_MASK	= 3 << GPIO2A0_SEL_SHIFT,
+	GPIO2A0_UART2_TX_M1	= 1,
+
+	GPIO2A1_SEL_SHIFT	= 2,
+	GPIO2A1_SEL_MASK	= 3 << GPIO2A1_SEL_SHIFT,
+	GPIO2A1_UART2_RX_M1	= 1,
+
+	GPIO2A2_SEL_SHIFT	= 4,
+	GPIO2A2_SEL_MASK	= 3 << GPIO2A2_SEL_SHIFT,
+	GPIO2A2_PWM_IR		= 1,
+
+	GPIO2A4_SEL_SHIFT	= 8,
+	GPIO2A4_SEL_MASK	= 3 << GPIO2A4_SEL_SHIFT,
+	GPIO2A4_PWM_0		= 1,
+	GPIO2A4_I2C1_SDA,
+
+	GPIO2A5_SEL_SHIFT	= 10,
+	GPIO2A5_SEL_MASK	= 3 << GPIO2A5_SEL_SHIFT,
+	GPIO2A5_PWM_1		= 1,
+	GPIO2A5_I2C1_SCL,
+
+	GPIO2A6_SEL_SHIFT	= 12,
+	GPIO2A6_SEL_MASK	= 3 << GPIO2A6_SEL_SHIFT,
+	GPIO2A6_PWM_2		= 1,
+
+	GPIO2A7_SEL_SHIFT	= 14,
+	GPIO2A7_SEL_MASK	= 3 << GPIO2A7_SEL_SHIFT,
+	GPIO2A7_GPIO		= 0,
+	GPIO2A7_SDMMC0_PWRENM0,
+
+	/* GPIO2BL_IOMUX */
+	GPIO2BL0_SEL_SHIFT	= 0,
+	GPIO2BL0_SEL_MASK	= 0x3f << GPIO2BL0_SEL_SHIFT,
+	GPIO2BL0_SPI_CLK_TX_RX_M0	= 0x15,
+
+	GPIO2BL3_SEL_SHIFT	= 6,
+	GPIO2BL3_SEL_MASK	= 3 << GPIO2BL3_SEL_SHIFT,
+	GPIO2BL3_SPI_CSN0_M0	= 1,
+
+	GPIO2BL4_SEL_SHIFT	= 8,
+	GPIO2BL4_SEL_MASK	= 3 << GPIO2BL4_SEL_SHIFT,
+	GPIO2BL4_SPI_CSN1_M0	= 1,
+
+	GPIO2BL5_SEL_SHIFT	= 10,
+	GPIO2BL5_SEL_MASK	= 3 << GPIO2BL5_SEL_SHIFT,
+	GPIO2BL5_I2C2_SDA	= 1,
+
+	GPIO2BL6_SEL_SHIFT	= 12,
+	GPIO2BL6_SEL_MASK	= 3 << GPIO2BL6_SEL_SHIFT,
+	GPIO2BL6_I2C2_SCL	= 1,
+
+	/* GPIO2D_IOMUX */
+	GPIO2D0_SEL_SHIFT	= 0,
+	GPIO2D0_SEL_MASK	= 3 << GPIO2D0_SEL_SHIFT,
+	GPIO2D0_I2C0_SCL	= 1,
+
+	GPIO2D1_SEL_SHIFT	= 2,
+	GPIO2D1_SEL_MASK	= 3 << GPIO2D1_SEL_SHIFT,
+	GPIO2D1_I2C0_SDA	= 1,
+
+	GPIO2D4_SEL_SHIFT	= 8,
+	GPIO2D4_SEL_MASK	= 0xff << GPIO2D4_SEL_SHIFT,
+	GPIO2D4_EMMC_DATA1234	= 0xaa,
+
+	/* GPIO3C_IOMUX */
+	GPIO3C0_SEL_SHIFT	= 0,
+	GPIO3C0_SEL_MASK	= 0x3fff << GPIO3C0_SEL_SHIFT,
+	GPIO3C0_EMMC_DATA567_PWR_CLK_RSTN_CMD	= 0x2aaa,
+
+	/* COM_IOMUX */
+	IOMUX_SEL_UART2_SHIFT	= 0,
+	IOMUX_SEL_UART2_MASK	= 3 << IOMUX_SEL_UART2_SHIFT,
+	IOMUX_SEL_UART2_M0	= 0,
+	IOMUX_SEL_UART2_M1,
+
+	IOMUX_SEL_SPI_SHIFT	= 4,
+	IOMUX_SEL_SPI_MASK	= 3 << IOMUX_SEL_SPI_SHIFT,
+	IOMUX_SEL_SPI_M0	= 0,
+	IOMUX_SEL_SPI_M1,
+	IOMUX_SEL_SPI_M2,
+
+	IOMUX_SEL_SDMMC_SHIFT	= 7,
+	IOMUX_SEL_SDMMC_MASK	= 1 << IOMUX_SEL_SDMMC_SHIFT,
+	IOMUX_SEL_SDMMC_M0	= 0,
+	IOMUX_SEL_SDMMC_M1,
+};
+
 #endif	/* __SOC_ROCKCHIP_RK3328_GRF_H__ */
diff --git a/arch/arm/include/asm/arch-rockchip/grf_rk3368.h b/arch/arm/include/asm/arch-rockchip/grf_rk3368.h
new file mode 100644
index 0000000..3233dc3
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/grf_rk3368.h
@@ -0,0 +1,440 @@
+/* (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+#ifndef _ASM_ARCH_GRF_RK3368_H
+#define _ASM_ARCH_GRF_RK3368_H
+
+#include <common.h>
+
+struct rk3368_grf {
+	u32 gpio1a_iomux;
+	u32 gpio1b_iomux;
+	u32 gpio1c_iomux;
+	u32 gpio1d_iomux;
+	u32 gpio2a_iomux;
+	u32 gpio2b_iomux;
+	u32 gpio2c_iomux;
+	u32 gpio2d_iomux;
+	u32 gpio3a_iomux;
+	u32 gpio3b_iomux;
+	u32 gpio3c_iomux;
+	u32 gpio3d_iomux;
+	u32 reserved[0x34];
+	u32 gpio1a_pull;
+	u32 gpio1b_pull;
+	u32 gpio1c_pull;
+	u32 gpio1d_pull;
+	u32 gpio2a_pull;
+	u32 gpio2b_pull;
+	u32 gpio2c_pull;
+	u32 gpio2d_pull;
+	u32 gpio3a_pull;
+	u32 gpio3b_pull;
+	u32 gpio3c_pull;
+	u32 gpio3d_pull;
+	u32 reserved1[0x34];
+	u32 gpio1a_drv;
+	u32 gpio1b_drv;
+	u32 gpio1c_drv;
+	u32 gpio1d_drv;
+	u32 gpio2a_drv;
+	u32 gpio2b_drv;
+	u32 gpio2c_drv;
+	u32 gpio2d_drv;
+	u32 gpio3a_drv;
+	u32 gpio3b_drv;
+	u32 gpio3c_drv;
+	u32 gpio3d_drv;
+	u32 reserved2[0x34];
+	u32 gpio1l_sr;
+	u32 gpio1h_sr;
+	u32 gpio2l_sr;
+	u32 gpio2h_sr;
+	u32 gpio3l_sr;
+	u32 gpio3h_sr;
+	u32 reserved3[0x1a];
+	u32 gpio_smt;
+	u32 reserved4[0x1f];
+	u32 soc_con0;
+	u32 soc_con1;
+	u32 soc_con2;
+	u32 soc_con3;
+	u32 soc_con4;
+	u32 soc_con5;
+	u32 soc_con6;
+	u32 soc_con7;
+	u32 soc_con8;
+	u32 soc_con9;
+	u32 soc_con10;
+	u32 soc_con11;
+	u32 soc_con12;
+	u32 soc_con13;
+	u32 soc_con14;
+	u32 soc_con15;
+	u32 soc_con16;
+	u32 soc_con17;
+};
+check_member(rk3368_grf, soc_con17, 0x444);
+
+struct rk3368_pmu_grf {
+	u32 gpio0a_iomux;
+	u32 gpio0b_iomux;
+	u32 gpio0c_iomux;
+	u32 gpio0d_iomux;
+	u32 gpio0a_pull;
+	u32 gpio0b_pull;
+	u32 gpio0c_pull;
+	u32 gpio0d_pull;
+	u32 gpio0a_drv;
+	u32 gpio0b_drv;
+	u32 gpio0c_drv;
+	u32 gpio0d_drv;
+	u32 gpio0l_sr;
+	u32 gpio0h_sr;
+};
+check_member(rk3368_pmu_grf, gpio0h_sr, 0x34);
+
+/*GRF_GPIO0C_IOMUX*/
+enum {
+	GPIO0C7_SHIFT		= 14,
+	GPIO0C7_MASK		= 3 << GPIO0C7_SHIFT,
+	GPIO0C7_GPIO		= 0,
+	GPIO0C7_LCDC_D19,
+	GPIO0C7_TRACE_D9,
+	GPIO0C7_UART1_RTSN,
+
+	GPIO0C6_SHIFT           = 12,
+	GPIO0C6_MASK            = 3 << GPIO0C6_SHIFT,
+	GPIO0C6_GPIO            = 0,
+	GPIO0C6_LCDC_D18,
+	GPIO0C6_TRACE_D8,
+	GPIO0C6_UART1_CTSN,
+
+	GPIO0C5_SHIFT           = 10,
+	GPIO0C5_MASK            = 3 << GPIO0C5_SHIFT,
+	GPIO0C5_GPIO            = 0,
+	GPIO0C5_LCDC_D17,
+	GPIO0C5_TRACE_D7,
+	GPIO0C5_UART1_SOUT,
+
+	GPIO0C4_SHIFT           = 8,
+	GPIO0C4_MASK            = 3 << GPIO0C4_SHIFT,
+	GPIO0C4_GPIO            = 0,
+	GPIO0C4_LCDC_D16,
+	GPIO0C4_TRACE_D6,
+	GPIO0C4_UART1_SIN,
+
+	GPIO0C3_SHIFT           = 6,
+	GPIO0C3_MASK            = 3 << GPIO0C3_SHIFT,
+	GPIO0C3_GPIO            = 0,
+	GPIO0C3_LCDC_D15,
+	GPIO0C3_TRACE_D5,
+	GPIO0C3_MCU_JTAG_TDO,
+
+	GPIO0C2_SHIFT           = 4,
+	GPIO0C2_MASK            = 3 << GPIO0C2_SHIFT,
+	GPIO0C2_GPIO            = 0,
+	GPIO0C2_LCDC_D14,
+	GPIO0C2_TRACE_D4,
+	GPIO0C2_MCU_JTAG_TDI,
+
+	GPIO0C1_SHIFT           = 2,
+	GPIO0C1_MASK            = 3 << GPIO0C1_SHIFT,
+	GPIO0C1_GPIO            = 0,
+	GPIO0C1_LCDC_D13,
+	GPIO0C1_TRACE_D3,
+	GPIO0C1_MCU_JTAG_TRTSN,
+
+	GPIO0C0_SHIFT           = 0,
+	GPIO0C0_MASK            = 3 << GPIO0C0_SHIFT,
+	GPIO0C0_GPIO            = 0,
+	GPIO0C0_LCDC_D12,
+	GPIO0C0_TRACE_D2,
+	GPIO0C0_MCU_JTAG_TDO,
+};
+
+/*GRF_GPIO0D_IOMUX*/
+enum {
+	GPIO0D7_SHIFT           = 14,
+	GPIO0D7_MASK            = 3 << GPIO0D7_SHIFT,
+	GPIO0D7_GPIO            = 0,
+	GPIO0D7_LCDC_DCLK,
+	GPIO0D7_TRACE_CTL,
+	GPIO0D7_PMU_DEBUG5,
+
+	GPIO0D6_SHIFT           = 12,
+	GPIO0D6_MASK            = 3 << GPIO0D6_SHIFT,
+	GPIO0D6_GPIO            = 0,
+	GPIO0D6_LCDC_DEN,
+	GPIO0D6_TRACE_CLK,
+	GPIO0D6_PMU_DEBUG4,
+
+	GPIO0D5_SHIFT           = 10,
+	GPIO0D5_MASK            = 3 << GPIO0D5_SHIFT,
+	GPIO0D5_GPIO            = 0,
+	GPIO0D5_LCDC_VSYNC,
+	GPIO0D5_TRACE_D15,
+	GPIO0D5_PMU_DEBUG3,
+
+	GPIO0D4_SHIFT           = 8,
+	GPIO0D4_MASK            = 3 << GPIO0D4_SHIFT,
+	GPIO0D4_GPIO            = 0,
+	GPIO0D4_LCDC_HSYNC,
+	GPIO0D4_TRACE_D14,
+	GPIO0D4_PMU_DEBUG2,
+
+	GPIO0D3_SHIFT           = 6,
+	GPIO0D3_MASK            = 3 << GPIO0D3_SHIFT,
+	GPIO0D3_GPIO            = 0,
+	GPIO0D3_LCDC_D23,
+	GPIO0D3_TRACE_D13,
+	GPIO0D3_UART4_SIN,
+
+	GPIO0D2_SHIFT           = 4,
+	GPIO0D2_MASK            = 3 << GPIO0D2_SHIFT,
+	GPIO0D2_GPIO            = 0,
+	GPIO0D2_LCDC_D22,
+	GPIO0D2_TRACE_D12,
+	GPIO0D2_UART4_SOUT,
+
+	GPIO0D1_SHIFT           = 2,
+	GPIO0D1_MASK            = 3 << GPIO0D1_SHIFT,
+	GPIO0D1_GPIO            = 0,
+	GPIO0D1_LCDC_D21,
+	GPIO0D1_TRACE_D11,
+	GPIO0D1_UART4_RTSN,
+
+	GPIO0D0_SHIFT           = 0,
+	GPIO0D0_MASK            = 3 << GPIO0D0_SHIFT,
+	GPIO0D0_GPIO            = 0,
+	GPIO0D0_LCDC_D20,
+	GPIO0D0_TRACE_D10,
+	GPIO0D0_UART4_CTSN,
+};
+
+/*GRF_GPIO2A_IOMUX*/
+enum {
+	GPIO2A7_SHIFT           = 14,
+	GPIO2A7_MASK            = 3 << GPIO2A7_SHIFT,
+	GPIO2A7_GPIO            = 0,
+	GPIO2A7_SDMMC0_D2,
+	GPIO2A7_JTAG_TCK,
+
+	GPIO2A6_SHIFT           = 12,
+	GPIO2A6_MASK            = 3 << GPIO2A6_SHIFT,
+	GPIO2A6_GPIO            = 0,
+	GPIO2A6_SDMMC0_D1,
+	GPIO2A6_UART2_SIN,
+
+	GPIO2A5_SHIFT           = 10,
+	GPIO2A5_MASK            = 3 << GPIO2A5_SHIFT,
+	GPIO2A5_GPIO            = 0,
+	GPIO2A5_SDMMC0_D0,
+	GPIO2A5_UART2_SOUT,
+
+	GPIO2A4_SHIFT           = 8,
+	GPIO2A4_MASK            = 3 << GPIO2A4_SHIFT,
+	GPIO2A4_GPIO            = 0,
+	GPIO2A4_FLASH_DQS,
+	GPIO2A4_EMMC_CLKO,
+
+	GPIO2A3_SHIFT           = 6,
+	GPIO2A3_MASK            = 3 << GPIO2A3_SHIFT,
+	GPIO2A3_GPIO            = 0,
+	GPIO2A3_FLASH_CSN3,
+	GPIO2A3_EMMC_RSTNO,
+
+	GPIO2A2_SHIFT           = 4,
+	GPIO2A2_MASK            = 3 << GPIO2A2_SHIFT,
+	GPIO2A2_GPIO           = 0,
+	GPIO2A2_FLASH_CSN2,
+
+	GPIO2A1_SHIFT           = 2,
+	GPIO2A1_MASK            = 3 << GPIO2A1_SHIFT,
+	GPIO2A1_GPIO            = 0,
+	GPIO2A1_FLASH_CSN1,
+
+	GPIO2A0_SHIFT           = 0,
+	GPIO2A0_MASK            = 3 << GPIO2A0_SHIFT,
+	GPIO2A0_GPIO            = 0,
+	GPIO2A0_FLASH_CSN0,
+};
+
+/*GRF_GPIO2D_IOMUX*/
+enum {
+	GPIO2D7_SHIFT           = 14,
+	GPIO2D7_MASK            = 3 << GPIO2D7_SHIFT,
+	GPIO2D7_GPIO            = 0,
+	GPIO2D7_SDIO0_D3,
+
+	GPIO2D6_SHIFT           = 12,
+	GPIO2D6_MASK            = 3 << GPIO2D6_SHIFT,
+	GPIO2D6_GPIO            = 0,
+	GPIO2D6_SDIO0_D2,
+
+	GPIO2D5_SHIFT           = 10,
+	GPIO2D5_MASK            = 3 << GPIO2D5_SHIFT,
+	GPIO2D5_GPIO            = 0,
+	GPIO2D5_SDIO0_D1,
+
+	GPIO2D4_SHIFT           = 8,
+	GPIO2D4_MASK            = 3 << GPIO2D4_SHIFT,
+	GPIO2D4_GPIO            = 0,
+	GPIO2D4_SDIO0_D0,
+
+	GPIO2D3_SHIFT           = 6,
+	GPIO2D3_MASK            = 3 << GPIO2D3_SHIFT,
+	GPIO2D3_GPIO            = 0,
+	GPIO2D3_UART0_RTS0,
+
+	GPIO2D2_SHIFT           = 4,
+	GPIO2D2_MASK            = 3 << GPIO2D2_SHIFT,
+	GPIO2D2_GPIO            = 0,
+	GPIO2D2_UART0_CTS0,
+
+	GPIO2D1_SHIFT           = 2,
+	GPIO2D1_MASK            = 3 << GPIO2D1_SHIFT,
+	GPIO2D1_GPIO            = 0,
+	GPIO2D1_UART0_SOUT,
+
+	GPIO2D0_SHIFT           = 0,
+	GPIO2D0_MASK            = 3 << GPIO2D0_SHIFT,
+	GPIO2D0_GPIO            = 0,
+	GPIO2D0_UART0_SIN,
+};
+
+/*GRF_GPIO3C_IOMUX*/
+enum {
+	GPIO3C7_SHIFT           = 14,
+	GPIO3C7_MASK            = 3 << GPIO3C7_SHIFT,
+	GPIO3C7_GPIO            = 0,
+	GPIO3C7_EDPHDMI_CECINOUT,
+	GPIO3C7_ISP_FLASHTRIGIN,
+
+	GPIO3C6_SHIFT           = 12,
+	GPIO3C6_MASK            = 3 << GPIO3C6_SHIFT,
+	GPIO3C6_GPIO            = 0,
+	GPIO3C6_MAC_CLK,
+	GPIO3C6_ISP_SHUTTERTRIG,
+
+	GPIO3C5_SHIFT           = 10,
+	GPIO3C5_MASK            = 3 << GPIO3C5_SHIFT,
+	GPIO3C5_GPIO            = 0,
+	GPIO3C5_MAC_RXER,
+	GPIO3C5_ISP_PRELIGHTTRIG,
+
+	GPIO3C4_SHIFT           = 8,
+	GPIO3C4_MASK            = 3 << GPIO3C4_SHIFT,
+	GPIO3C4_GPIO            = 0,
+	GPIO3C4_MAC_RXDV,
+	GPIO3C4_ISP_FLASHTRIGOUT,
+
+	GPIO3C3_SHIFT           = 6,
+	GPIO3C3_MASK            = 3 << GPIO3C3_SHIFT,
+	GPIO3C3_GPIO            = 0,
+	GPIO3C3_MAC_RXDV,
+	GPIO3C3_EMMC_RSTNO,
+
+	GPIO3C2_SHIFT           = 4,
+	GPIO3C2_MASK            = 3 << GPIO3C2_SHIFT,
+	GPIO3C2_MAC_MDC            = 0,
+	GPIO3C2_ISP_SHUTTEREN,
+
+	GPIO3C1_SHIFT           = 2,
+	GPIO3C1_MASK            = 3 << GPIO3C1_SHIFT,
+	GPIO3C1_GPIO            = 0,
+	GPIO3C1_MAC_RXD2,
+	GPIO3C1_UART3_RTSN,
+
+	GPIO3C0_SHIFT           = 0,
+	GPIO3C0_MASK            = 3 << GPIO3C0_SHIFT,
+	GPIO3C0_GPIO            = 0,
+	GPIO3C0_MAC_RXD1,
+	GPIO3C0_UART3_CTSN,
+	GPIO3C0_GPS_RFCLK,
+};
+
+/*GRF_GPIO3D_IOMUX*/
+enum {
+	GPIO3D7_SHIFT           = 14,
+	GPIO3D7_MASK            = 3 << GPIO3D7_SHIFT,
+	GPIO3D7_GPIO            = 0,
+	GPIO3D7_SC_VCC18V,
+	GPIO3D7_I2C2_SDA,
+	GPIO3D7_GPUJTAG_TCK,
+
+	GPIO3D6_SHIFT           = 12,
+	GPIO3D6_MASK            = 3 << GPIO3D6_SHIFT,
+	GPIO3D6_GPIO            = 0,
+	GPIO3D6_IR_TX,
+	GPIO3D6_UART3_SOUT,
+	GPIO3D6_PWM3,
+
+	GPIO3D5_SHIFT           = 10,
+	GPIO3D5_MASK            = 3 << GPIO3D5_SHIFT,
+	GPIO3D5_GPIO            = 0,
+	GPIO3D5_IR_RX,
+	GPIO3D5_UART3_SIN,
+
+	GPIO3D4_SHIFT           = 8,
+	GPIO3D4_MASK            = 3 << GPIO3D4_SHIFT,
+	GPIO3D4_GPIO            = 0,
+	GPIO3D4_MAC_TXCLKOUT,
+	GPIO3D4_SPI1_CSN1,
+
+	GPIO3D3_SHIFT           = 6,
+	GPIO3D3_MASK            = 3 << GPIO3D3_SHIFT,
+	GPIO3D3_GPIO            = 0,
+	GPIO3D3_HDMII2C_SCL,
+	GPIO3D3_I2C5_SCL,
+
+	GPIO3D2_SHIFT           = 4,
+	GPIO3D2_MASK            = 3 << GPIO3D2_SHIFT,
+	GPIO3D2_GPIO            = 0,
+	GPIO3D2_HDMII2C_SDA,
+	GPIO3D2_I2C5_SDA,
+
+	GPIO3D1_SHIFT           = 2,
+	GPIO3D1_MASK            = 3 << GPIO3D1_SHIFT,
+	GPIO3D1_GPIO            = 0,
+	GPIO3D1_MAC_RXCLKIN,
+	GPIO3D1_I2C4_SCL,
+
+	GPIO3D0_SHIFT           = 0,
+	GPIO3D0_MASK            = 3 << GPIO3D0_SHIFT,
+	GPIO3D0_GPIO            = 0,
+	GPIO3D0_MAC_MDIO,
+	GPIO3D0_I2C4_SDA,
+};
+
+/*GRF_SOC_CON11/12/13*/
+enum {
+	MCU_SRAM_BASE_BIT27_BIT12_SHIFT	= 0,
+	MCU_SRAM_BASE_BIT27_BIT12_MASK	= GENMASK(15, 0),
+};
+
+/*GRF_SOC_CON12*/
+enum {
+	MCU_EXSRAM_BASE_BIT27_BIT12_SHIFT  = 0,
+	MCU_EXSRAM_BASE_BIT27_BIT12_MASK   = GENMASK(15, 0),
+};
+
+/*GRF_SOC_CON13*/
+enum {
+	MCU_EXPERI_BASE_BIT27_BIT12_SHIFT  = 0,
+	MCU_EXPERI_BASE_BIT27_BIT12_MASK   = GENMASK(15, 0),
+};
+
+/*GRF_SOC_CON14*/
+enum {
+	MCU_EXPERI_BASE_BIT31_BIT28_SHIFT	= 12,
+	MCU_EXPERI_BASE_BIT31_BIT28_MASK	= GENMASK(15, 12),
+	MCU_EXSRAM_BASE_BIT31_BIT28_SHIFT	= 8,
+	MCU_EXSRAM_BASE_BIT31_BIT28_MASK	= GENMASK(11, 8),
+	MCU_SRAM_BASE_BIT31_BIT28_SHIFT		= 4,
+	MCU_SRAM_BASE_BIT31_BIT28_MASK		= GENMASK(7, 4),
+	MCU_CODE_BASE_BIT31_BIT28_SHIFT		= 0,
+	MCU_CODE_BASE_BIT31_BIT28_MASK		= GENMASK(3, 0),
+};
+#endif
diff --git a/arch/arm/include/asm/arch-rockchip/grf_rk3399.h b/arch/arm/include/asm/arch-rockchip/grf_rk3399.h
index eda9956..8d21eb7 100644
--- a/arch/arm/include/asm/arch-rockchip/grf_rk3399.h
+++ b/arch/arm/include/asm/arch-rockchip/grf_rk3399.h
@@ -534,6 +534,9 @@
 	GRF_DSI0_VOP_SEL_MASK   = 1 << GRF_DSI0_VOP_SEL_SHIFT,
 	GRF_DSI0_VOP_SEL_B      = 0,
 	GRF_DSI0_VOP_SEL_L      = 1,
+	GRF_RK3399_HDMI_VOP_SEL_MASK = 1 << 6,
+	GRF_RK3399_HDMI_VOP_SEL_B = 0 << 6,
+	GRF_RK3399_HDMI_VOP_SEL_L = 1 << 6,
 
 	/* GRF_SOC_CON22 */
 	GRF_DPHY_TX0_RXMODE_SHIFT = 0,
diff --git a/arch/arm/include/asm/arch-rockchip/grf_rv1108.h b/arch/arm/include/asm/arch-rockchip/grf_rv1108.h
new file mode 100644
index 0000000..c816a5b
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/grf_rv1108.h
@@ -0,0 +1,509 @@
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+#ifndef _ASM_ARCH_GRF_RV1108_H
+#define _ASM_ARCH_GRF_RV1108_H
+
+#include <common.h>
+
+struct rv1108_grf {
+	u32 reserved[4];
+	u32 gpio1a_iomux;
+	u32 gpio1b_iomux;
+	u32 gpio1c_iomux;
+	u32 gpio1d_iomux;
+	u32 gpio2a_iomux;
+	u32 gpio2b_iomux;
+	u32 gpio2c_iomux;
+	u32 gpio2d_iomux;
+	u32 gpio3a_iomux;
+	u32 gpio3b_iomux;
+	u32 gpio3c_iomux;
+	u32 gpio3d_iomux;
+	u32 reserved1[52];
+	u32 gpio1a_pull;
+	u32 gpio1b_pull;
+	u32 gpio1c_pull;
+	u32 gpio1d_pull;
+	u32 gpio2a_pull;
+	u32 gpio2b_pull;
+	u32 gpio2c_pull;
+	u32 gpio2d_pull;
+	u32 gpio3a_pull;
+	u32 gpio3b_pull;
+	u32 gpio3c_pull;
+	u32 gpio3d_pull;
+	u32 reserved2[52];
+	u32 gpio1a_drv;
+	u32 gpio1b_drv;
+	u32 gpio1c_drv;
+	u32 gpio1d_drv;
+	u32 gpio2a_drv;
+	u32 gpio2b_drv;
+	u32 gpio2c_drv;
+	u32 gpio2d_drv;
+	u32 gpio3a_drv;
+	u32 gpio3b_drv;
+	u32 gpio3c_drv;
+	u32 gpio3d_drv;
+	u32 reserved3[50];
+	u32 gpio1l_sr;
+	u32 gpio1h_sr;
+	u32 gpio2l_sr;
+	u32 gpio2h_sr;
+	u32 gpio3l_sr;
+	u32 gpio3h_sr;
+	u32 reserved4[26];
+	u32 gpio1l_smt;
+	u32 gpio1h_smt;
+	u32 gpio2l_smt;
+	u32 gpio2h_smt;
+	u32 gpio3l_smt;
+	u32 gpio3h_smt;
+	u32 reserved5[24];
+	u32 soc_con0;
+	u32 soc_con1;
+	u32 soc_con2;
+	u32 soc_con3;
+	u32 soc_con4;
+	u32 soc_con5;
+	u32 soc_con6;
+	u32 soc_con7;
+	u32 soc_con8;
+	u32 soc_con9;
+	u32 soc_con10;
+	u32 soc_con11;
+	u32 reserved6[20];
+	u32 soc_status0;
+	u32 soc_status1;
+	u32 reserved7[30];
+	u32 cpu_con0;
+	u32 cpu_con1;
+	u32 reserved8[30];
+	u32 os_reg0;
+	u32 os_reg1;
+	u32 os_reg2;
+	u32 os_reg3;
+	u32 reserved9[29];
+	u32 ddr_status;
+	u32 reserved10[30];
+	u32 sig_det_con;
+	u32 reserved11[3];
+	u32 sig_det_status;
+	u32 reserved12[3];
+	u32 sig_det_clr;
+	u32 reserved13[23];
+	u32 host_con0;
+	u32 host_con1;
+	u32 reserved14[2];
+	u32 dma_con0;
+	u32 dma_con1;
+	u32 reserved15[539];
+	u32 uoc_status;
+	u32 host_status;
+	u32 gmac_con0;
+	u32 chip_id;
+};
+check_member(rv1108_grf, chip_id, 0xf90);
+
+/* GRF_GPIO1B_IOMUX */
+enum {
+	GPIO1B7_SHIFT		= 14,
+	GPIO1B7_MASK		= 3 << GPIO1B7_SHIFT,
+	GPIO1B7_GPIO		= 0,
+	GPIO1B7_LCDC_D12,
+	GPIO1B7_I2S_SDIO2_M0,
+	GPIO1B7_GMAC_RXDV,
+
+	GPIO1B6_SHIFT		= 12,
+	GPIO1B6_MASK		= 3 << GPIO1B6_SHIFT,
+	GPIO1B6_GPIO		= 0,
+	GPIO1B6_LCDC_D13,
+	GPIO1B6_I2S_LRCLKTX_M0,
+	GPIO1B6_GMAC_RXD1,
+
+	GPIO1B5_SHIFT		= 10,
+	GPIO1B5_MASK		= 3 << GPIO1B5_SHIFT,
+	GPIO1B5_GPIO		= 0,
+	GPIO1B5_LCDC_D14,
+	GPIO1B5_I2S_SDIO1_M0,
+	GPIO1B5_GMAC_RXD0,
+
+	GPIO1B4_SHIFT		= 8,
+	GPIO1B4_MASK		= 3 << GPIO1B4_SHIFT,
+	GPIO1B4_GPIO		= 0,
+	GPIO1B4_LCDC_D15,
+	GPIO1B4_I2S_MCLK_M0,
+	GPIO1B4_GMAC_TXEN,
+
+	GPIO1B3_SHIFT		= 6,
+	GPIO1B3_MASK		= 3 << GPIO1B3_SHIFT,
+	GPIO1B3_GPIO		= 0,
+	GPIO1B3_LCDC_D16,
+	GPIO1B3_I2S_SCLK_M0,
+	GPIO1B3_GMAC_TXD1,
+
+	GPIO1B2_SHIFT		= 4,
+	GPIO1B2_MASK		= 3 << GPIO1B2_SHIFT,
+	GPIO1B2_GPIO		= 0,
+	GPIO1B2_LCDC_D17,
+	GPIO1B2_I2S_SDIO_M0,
+	GPIO1B2_GMAC_TXD0,
+
+	GPIO1B1_SHIFT		= 2,
+	GPIO1B1_MASK		= 3 << GPIO1B1_SHIFT,
+	GPIO1B1_GPIO		= 0,
+	GPIO1B1_LCDC_D9,
+	GPIO1B1_PWM7,
+
+	GPIO1B0_SHIFT		= 0,
+	GPIO1B0_MASK		= 3,
+	GPIO1B0_GPIO		= 0,
+	GPIO1B0_LCDC_D8,
+	GPIO1B0_PWM6,
+};
+
+/* GRF_GPIO1C_IOMUX */
+enum {
+	GPIO1C7_SHIFT		= 14,
+	GPIO1C7_MASK		= 3 << GPIO1C7_SHIFT,
+	GPIO1C7_GPIO		= 0,
+	GPIO1C7_CIF_D5,
+	GPIO1C7_I2S_SDIO2_M1,
+
+	GPIO1C6_SHIFT		= 12,
+	GPIO1C6_MASK		= 3 << GPIO1C6_SHIFT,
+	GPIO1C6_GPIO		= 0,
+	GPIO1C6_CIF_D4,
+	GPIO1C6_I2S_LRCLKTX_M1,
+
+	GPIO1C5_SHIFT		= 10,
+	GPIO1C5_MASK		= 3 << GPIO1C5_SHIFT,
+	GPIO1C5_GPIO		= 0,
+	GPIO1C5_LCDC_CLK,
+	GPIO1C5_GMAC_CLK,
+
+	GPIO1C4_SHIFT		= 8,
+	GPIO1C4_MASK		= 3 << GPIO1C4_SHIFT,
+	GPIO1C4_GPIO		= 0,
+	GPIO1C4_LCDC_HSYNC,
+	GPIO1C4_GMAC_MDC,
+
+	GPIO1C3_SHIFT		= 6,
+	GPIO1C3_MASK		= 3 << GPIO1C3_SHIFT,
+	GPIO1C3_GPIO		= 0,
+	GPIO1C3_LCDC_VSYNC,
+	GPIO1C3_GMAC_MDIO,
+
+	GPIO1C2_SHIFT		= 4,
+	GPIO1C2_MASK		= 3 << GPIO1C2_SHIFT,
+	GPIO1C2_GPIO		= 0,
+	GPIO1C2_LCDC_EN,
+	GPIO1C2_I2S_SDIO3_M0,
+	GPIO1C2_GMAC_RXER,
+
+	GPIO1C1_SHIFT		= 2,
+	GPIO1C1_MASK		= 3 << GPIO1C1_SHIFT,
+	GPIO1C1_GPIO		= 0,
+	GPIO1C1_LCDC_D10,
+	GPIO1C1_I2S_SDI_M0,
+	GPIO1C1_PWM4,
+
+	GPIO1C0_SHIFT           = 0,
+	GPIO1C0_MASK		= 3,
+	GPIO1C0_GPIO		= 0,
+	GPIO1C0_LCDC_D11,
+	GPIO1C0_I2S_LRCLKRX_M0,
+};
+
+/* GRF_GPIO1D_OIMUX */
+enum {
+	GPIO1D7_SHIFT		= 14,
+	GPIO1D7_MASK		= 3 << GPIO1D7_SHIFT,
+	GPIO1D7_GPIO		= 0,
+	GPIO1D7_HDMI_CEC,
+	GPIO1D7_DSP_RTCK,
+
+	GPIO1D6_SHIFT		= 12,
+	GPIO1D6_MASK		= 1 << GPIO1D6_SHIFT,
+	GPIO1D6_GPIO		= 0,
+	GPIO1D6_HDMI_HPD_M0,
+
+	GPIO1D5_SHIFT		= 10,
+	GPIO1D5_MASK		= 3 << GPIO1D5_SHIFT,
+	GPIO1D5_GPIO		= 0,
+	GPIO1D5_UART2_RTSN,
+	GPIO1D5_HDMI_SDA_M0,
+
+	GPIO1D4_SHIFT		= 8,
+	GPIO1D4_MASK		= 3 << GPIO1D4_SHIFT,
+	GPIO1D4_GPIO		= 0,
+	GPIO1D4_UART2_CTSN,
+	GPIO1D4_HDMI_SCL_M0,
+
+	GPIO1D3_SHIFT		= 6,
+	GPIO1D3_MASK		= 3 << GPIO1D3_SHIFT,
+	GPIO1D3_GPIO		= 0,
+	GPIO1D3_UART0_SOUT,
+	GPIO1D3_SPI_TXD_M0,
+
+	GPIO1D2_SHIFT		= 4,
+	GPIO1D2_MASK		= 3 << GPIO1D2_SHIFT,
+	GPIO1D2_GPIO		= 0,
+	GPIO1D2_UART0_SIN,
+	GPIO1D2_SPI_RXD_M0,
+	GPIO1D2_DSP_TDI,
+
+	GPIO1D1_SHIFT		= 2,
+	GPIO1D1_MASK		= 3 << GPIO1D1_SHIFT,
+	GPIO1D1_GPIO		= 0,
+	GPIO1D1_UART0_RTSN,
+	GPIO1D1_SPI_CSN0_M0,
+	GPIO1D1_DSP_TMS,
+
+	GPIO1D0_SHIFT		= 0,
+	GPIO1D0_MASK		= 3,
+	GPIO1D0_GPIO		= 0,
+	GPIO1D0_UART0_CTSN,
+	GPIO1D0_SPI_CLK_M0,
+	GPIO1D0_DSP_TCK,
+};
+
+/* GRF_GPIO2A_IOMUX */
+enum {
+	GPIO2A7_SHIFT		= 14,
+	GPIO2A7_MASK		= 3 << GPIO2A7_SHIFT,
+	GPIO2A7_GPIO		= 0,
+	GPIO2A7_FLASH_D7,
+	GPIO2A7_EMMC_D7,
+
+	GPIO2A6_SHIFT		= 12,
+	GPIO2A6_MASK		= 3 << GPIO2A6_SHIFT,
+	GPIO2A6_GPIO		= 0,
+	GPIO2A6_FLASH_D6,
+	GPIO2A6_EMMC_D6,
+
+	GPIO2A5_SHIFT           = 10,
+	GPIO2A5_MASK            = 3 << GPIO2A5_SHIFT,
+	GPIO2A5_GPIO            = 0,
+	GPIO2A5_FLASH_D5,
+	GPIO2A5_EMMC_D5,
+
+	GPIO2A4_SHIFT           = 8,
+	GPIO2A4_MASK            = 3 << GPIO2A4_SHIFT,
+	GPIO2A4_GPIO            = 0,
+	GPIO2A4_FLASH_D4,
+	GPIO2A4_EMMC_D4,
+
+	GPIO2A3_SHIFT           = 6,
+	GPIO2A3_MASK            = 3 << GPIO2A3_SHIFT,
+	GPIO2A3_GPIO            = 0,
+	GPIO2A3_FLASH_D3,
+	GPIO2A3_EMMC_D3,
+	GPIO2A3_SFC_HOLD_IO3,
+
+	GPIO2A2_SHIFT           = 4,
+	GPIO2A2_MASK            = 3 << GPIO2A2_SHIFT,
+	GPIO2A2_GPIO            = 0,
+	GPIO2A2_FLASH_D2,
+	GPIO2A2_EMMC_D2,
+	GPIO2A2_SFC_WP_IO2,
+
+	GPIO2A1_SHIFT           = 2,
+	GPIO2A1_MASK            = 3 << GPIO2A1_SHIFT,
+	GPIO2A1_GPIO            = 0,
+	GPIO2A1_FLASH_D1,
+	GPIO2A1_EMMC_D1,
+	GPIO2A1_SFC_SO_IO1,
+
+	GPIO2A0_SHIFT           = 0,
+	GPIO2A0_MASK            = 3 << GPIO2A0_SHIFT,
+	GPIO2A0_GPIO            = 0,
+	GPIO2A0_FLASH_D0,
+	GPIO2A0_EMMC_D0,
+	GPIO2A0_SFC_SI_IO0,
+};
+
+/* GRF_GPIO2D_IOMUX */
+enum {
+	GPIO2B7_SHIFT		= 14,
+	GPIO2B7_MASK		= 3 << GPIO2B7_SHIFT,
+	GPIO2B7_GPIO		= 0,
+	GPIO2B7_FLASH_CS1,
+	GPIO2B7_SFC_CLK,
+
+	GPIO2B6_SHIFT           = 12,
+	GPIO2B6_MASK            = 1 << GPIO2B6_SHIFT,
+	GPIO2B6_GPIO            = 0,
+	GPIO2B6_EMMC_CLKO,
+
+	GPIO2B5_SHIFT           = 10,
+	GPIO2B5_MASK            = 1 << GPIO2B5_SHIFT,
+	GPIO2B5_GPIO            = 0,
+	GPIO2B5_FLASH_CS0,
+
+	GPIO2B4_SHIFT           = 8,
+	GPIO2B4_MASK            = 3 << GPIO2B4_SHIFT,
+	GPIO2B4_GPIO            = 0,
+	GPIO2B4_FLASH_RDY,
+	GPIO2B4_EMMC_CMD,
+	GPIO2B4_SFC_CSN0,
+
+	GPIO2B3_SHIFT           = 6,
+	GPIO2B3_MASK            = 1 << GPIO2B3_SHIFT,
+	GPIO2B3_GPIO            = 0,
+	GPIO2B3_FLASH_RDN,
+
+	GPIO2B2_SHIFT           = 4,
+	GPIO2B2_MASK            = 1 << GPIO2B2_SHIFT,
+	GPIO2B2_GPIO            = 0,
+	GPIO2B2_FLASH_WRN,
+
+	GPIO2B1_SHIFT           = 2,
+	GPIO2B1_MASK            = 1 << GPIO2B1_SHIFT,
+	GPIO2B1_GPIO            = 0,
+	GPIO2B1_FLASH_CLE,
+
+	GPIO2B0_SHIFT           = 0,
+	GPIO2B0_MASK            = 1 << GPIO2B0_SHIFT,
+	GPIO2B0_GPIO            = 0,
+	GPIO2B0_FLASH_ALE,
+};
+
+/* GRF_GPIO2D_IOMUX */
+enum {
+	GPIO2D7_SHIFT		= 14,
+	GPIO2D7_MASK		= 1 << GPIO2D7_SHIFT,
+	GPIO2D7_GPIO		= 0,
+	GPIO2D7_SDIO_D0,
+
+	GPIO2D6_SHIFT		= 12,
+	GPIO2D6_MASK		= 1 << GPIO2D6_SHIFT,
+	GPIO2D6_GPIO		= 0,
+	GPIO2D6_SDIO_CMD,
+
+	GPIO2D5_SHIFT		= 10,
+	GPIO2D5_MASK		= 1 << GPIO2D5_SHIFT,
+	GPIO2D5_GPIO		= 0,
+	GPIO2D5_SDIO_CLKO,
+
+	GPIO2D4_SHIFT		= 8,
+	GPIO2D4_MASK		= 1 << GPIO2D4_SHIFT,
+	GPIO2D4_GPIO		= 0,
+	GPIO2D4_I2C1_SCL,
+
+	GPIO2D3_SHIFT		= 6,
+	GPIO2D3_MASK		= 1 << GPIO2D3_SHIFT,
+	GPIO2D3_GPIO		= 0,
+	GPIO2D3_I2C1_SDA,
+
+	GPIO2D2_SHIFT		= 4,
+	GPIO2D2_MASK		= 3 << GPIO2D2_SHIFT,
+	GPIO2D2_GPIO		= 0,
+	GPIO2D2_UART2_SOUT_M0,
+	GPIO2D2_JTAG_TCK,
+
+	GPIO2D1_SHIFT		= 2,
+	GPIO2D1_MASK		= 3 << GPIO2D1_SHIFT,
+	GPIO2D1_GPIO		= 0,
+	GPIO2D1_UART2_SIN_M0,
+	GPIO2D1_JTAG_TMS,
+	GPIO2D1_DSP_TMS,
+
+	GPIO2D0_SHIFT		= 0,
+	GPIO2D0_MASK		= 3,
+	GPIO2D0_GPIO		= 0,
+	GPIO2D0_UART0_CTSN,
+	GPIO2D0_SPI_CLK_M0,
+	GPIO2D0_DSP_TCK,
+};
+
+/* GRF_GPIO3A_IOMUX */
+enum {
+	GPIO3A7_SHIFT		= 14,
+	GPIO3A7_MASK		= 1 << GPIO3A7_SHIFT,
+	GPIO3A7_GPIO		= 0,
+
+	GPIO3A6_SHIFT		= 12,
+	GPIO3A6_MASK		= 1 << GPIO3A6_SHIFT,
+	GPIO3A6_GPIO		= 0,
+	GPIO3A6_UART1_SOUT,
+
+	GPIO3A5_SHIFT		= 10,
+	GPIO3A5_MASK		= 1 << GPIO3A5_SHIFT,
+	GPIO3A5_GPIO		= 0,
+	GPIO3A5_UART1_SIN,
+
+	GPIO3A4_SHIFT		= 8,
+	GPIO3A4_MASK		= 1 << GPIO3A4_SHIFT,
+	GPIO3A4_GPIO		= 0,
+	GPIO3A4_UART1_CTSN,
+
+	GPIO3A3_SHIFT		= 6,
+	GPIO3A3_MASK		= 1 << GPIO3A3_SHIFT,
+	GPIO3A3_GPIO		= 0,
+	GPIO3A3_UART1_RTSN,
+
+	GPIO3A2_SHIFT		= 4,
+	GPIO3A2_MASK		= 1 << GPIO3A2_SHIFT,
+	GPIO3A2_GPIO		= 0,
+	GPIO3A2_SDIO_D3,
+
+	GPIO3A1_SHIFT		= 2,
+	GPIO3A1_MASK		= 1 << GPIO3A1_SHIFT,
+	GPIO3A1_GPIO		= 0,
+	GPIO3A1_SDIO_D2,
+
+	GPIO3A0_SHIFT		= 0,
+	GPIO3A0_MASK		= 1,
+	GPIO3A0_GPIO		= 0,
+	GPIO3A0_SDIO_D1,
+};
+
+/* GRF_GPIO3C_IOMUX */
+enum {
+	GPIO3C7_SHIFT		= 14,
+	GPIO3C7_MASK		= 1 << GPIO3C7_SHIFT,
+	GPIO3C7_GPIO		= 0,
+	GPIO3C7_CIF_CLKI,
+
+	GPIO3C6_SHIFT		= 12,
+	GPIO3C6_MASK		= 1 << GPIO3C6_SHIFT,
+	GPIO3C6_GPIO		= 0,
+	GPIO3C6_CIF_VSYNC,
+
+	GPIO3C5_SHIFT		= 10,
+	GPIO3C5_MASK		= 1 << GPIO3C5_SHIFT,
+	GPIO3C5_GPIO		= 0,
+	GPIO3C5_SDMMC_CMD,
+
+	GPIO3C4_SHIFT		= 8,
+	GPIO3C4_MASK		= 1 << GPIO3C4_SHIFT,
+	GPIO3C4_GPIO		= 0,
+	GPIO3C4_SDMMC_CLKO,
+
+	GPIO3C3_SHIFT		= 6,
+	GPIO3C3_MASK		= 3 << GPIO3C3_SHIFT,
+	GPIO3C3_GPIO		= 0,
+	GPIO3C3_SDMMC_D0,
+	GPIO3C3_UART2_SOUT_M1,
+
+	GPIO3C2_SHIFT		= 4,
+	GPIO3C2_MASK		= 3 << GPIO3C2_SHIFT,
+	GPIO3C2_GPIO		= 0,
+	GPIO3C2_SDMMC_D1,
+	GPIO3C2_UART2_SIN_M1,
+
+	GPIOC1_SHIFT		= 2,
+	GPIOC1_MASK		= 1 << GPIOC1_SHIFT,
+	GPIOC1_GPIO		= 0,
+	GPIOC1_SDMMC_D2,
+
+	GPIOC0_SHIFT		= 0,
+	GPIOC0_MASK		= 1,
+	GPIO3C0_GPIO		= 0,
+	GPIO3C0_SDMMC_D3,
+};
+#endif
diff --git a/arch/arm/include/asm/arch-rockchip/periph.h b/arch/arm/include/asm/arch-rockchip/periph.h
index 8018d47..9f4bc2e 100644
--- a/arch/arm/include/asm/arch-rockchip/periph.h
+++ b/arch/arm/include/asm/arch-rockchip/periph.h
@@ -42,6 +42,7 @@
 	PERIPH_ID_SDMMC2,
 	PERIPH_ID_HDMI,
 	PERIPH_ID_GMAC,
+	PERIPH_ID_SFC,
 
 	PERIPH_ID_COUNT,
 
diff --git a/arch/arm/include/asm/arch-rockchip/vop_rk3288.h b/arch/arm/include/asm/arch-rockchip/vop_rk3288.h
index d5599ec..21e59be 100644
--- a/arch/arm/include/asm/arch-rockchip/vop_rk3288.h
+++ b/arch/arm/include/asm/arch-rockchip/vop_rk3288.h
@@ -197,9 +197,20 @@
 #define V_DSP_DEN_POL(x)               (((x) & 1) << 6)
 #define V_DSP_VSYNC_POL(x)             (((x) & 1) << 5)
 #define V_DSP_HSYNC_POL(x)             (((x) & 1) << 4)
+#define V_DSP_PIN_POL(x)               (((x) & 0xf) << 4)
 #define V_DSP_OUT_MODE(x)              ((x) & 0xf)
 
 /* VOP_DSP_CTRL1 */
+#define V_RK3399_DSP_MIPI_POL(x)       ((x) << 28)
+#define V_RK3399_DSP_EDP_POL(x)        ((x) << 24)
+#define V_RK3399_DSP_HDMI_POL(x)       ((x) << 20)
+#define V_RK3399_DSP_LVDS_POL(x)       ((x) << 16)
+
+#define M_RK3399_DSP_MIPI_POL          (V_RK3399_DSP_MIPI_POL(0xf))
+#define M_RK3399_DSP_EDP_POL           (V_RK3399_DSP_EDP_POL(0xf))
+#define M_RK3399_DSP_HDMI_POL          (V_RK3399_DSP_HDMI_POL(0xf))
+#define M_RK3399_DSP_LVDS_POL          (V_RK3399_DSP_LVDS_POL(0xf))
+
 #define M_DSP_LAYER3_SEL               (3 << 14)
 #define M_DSP_LAYER2_SEL               (3 << 12)
 #define M_DSP_LAYER1_SEL               (3 << 10)
diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig
index 6be2ab5..9b2ef29 100644
--- a/arch/arm/mach-rockchip/Kconfig
+++ b/arch/arm/mach-rockchip/Kconfig
@@ -51,6 +51,18 @@
 	  and video codec support. Peripherals include Gigabit Ethernet,
 	  USB2 host and OTG, SDIO, I2S, UARTs, SPI, I2C and PWMs.
 
+config ROCKCHIP_RK3368
+	bool "Support Rockchip RK3368"
+	select ARM64
+	select SYS_NS16550
+	help
+	  The Rockchip RK3328 is a ARM-based SoC with a octa-core Cortex-A53.
+	  including NEON and GPU, 512KB L2 cache for big cluster and 256 KB
+	  L2 cache for little cluser, PowerVR G6110 based graphics, one video
+	  output processor supporting LVDS、HDMI、eDP, several DDR3 options
+	  and video codec support. Peripherals include Gigabit Ethernet,
+	  USB2 host and OTG, SDIO, I2S, UARTs, SPI, I2C and PWMs.
+
 config ROCKCHIP_RK3399
 	bool "Support Rockchip RK3399"
 	select ARM64
@@ -67,6 +79,13 @@
 	  and video codec support. Peripherals include Gigabit Ethernet,
 	  USB2 host and OTG, SDIO, I2S, UARTs, SPI, I2C and PWMs.
 
+config ROCKCHIP_RV1108
+	bool "Support Rockchip RV1108"
+	select CPU_V7
+	help
+	  The Rockchip RV1108 is a ARM-based SoC with a single-core Cortex-A7
+	  and a DSP.
+
 config ROCKCHIP_SPL_BACK_TO_BROM
 	bool "SPL returns to bootrom"
 	default y if ROCKCHIP_RK3036
@@ -94,5 +113,7 @@
 source "arch/arm/mach-rockchip/rk3188/Kconfig"
 source "arch/arm/mach-rockchip/rk3288/Kconfig"
 source "arch/arm/mach-rockchip/rk3328/Kconfig"
+source "arch/arm/mach-rockchip/rk3368/Kconfig"
 source "arch/arm/mach-rockchip/rk3399/Kconfig"
+source "arch/arm/mach-rockchip/rv1108/Kconfig"
 endif
diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile
index 327b267..87d2019 100644
--- a/arch/arm/mach-rockchip/Makefile
+++ b/arch/arm/mach-rockchip/Makefile
@@ -31,4 +31,6 @@
 
 obj-$(CONFIG_ROCKCHIP_RK3288) += rk3288/
 obj-$(CONFIG_ROCKCHIP_RK3328) += rk3328/
+obj-$(CONFIG_ROCKCHIP_RK3368) += rk3368/
 obj-$(CONFIG_ROCKCHIP_RK3399) += rk3399/
+obj-$(CONFIG_ROCKCHIP_RV1108) += rv1108/
diff --git a/arch/arm/mach-rockchip/rk3368/Kconfig b/arch/arm/mach-rockchip/rk3368/Kconfig
new file mode 100644
index 0000000..6d32068
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3368/Kconfig
@@ -0,0 +1,32 @@
+if ROCKCHIP_RK3368
+
+choice
+	prompt "RK3368 board"
+
+config TARGET_SHEEP
+	bool "Sheep board"
+	help
+	  Sheep board is designed by Rockchip as a EVB board
+	  for rk3368.
+
+config TARGET_GEEKBOX
+	bool "GeekBox"
+
+config TARGET_EVB_PX5
+        bool "Evb-PX5"
+        help
+	 PX5 EVB is designed by Rockchip for automotive field
+         with integrated CVBS (TP2825) / MIPI DSI / CSI / LVDS
+         HDMI video input/output interface, audio codec ES8396,
+         WIFI/BT (on RTL8723BS), Gsensor BMA250E and light&proximity
+         sensor STK3410.
+endchoice
+
+config SYS_SOC
+	default "rockchip"
+
+source "board/rockchip/sheep_rk3368/Kconfig"
+source "board/geekbuying/geekbox/Kconfig"
+source "board/rockchip/evb_px5/Kconfig"
+
+endif
diff --git a/arch/arm/mach-rockchip/rk3368/Makefile b/arch/arm/mach-rockchip/rk3368/Makefile
new file mode 100644
index 0000000..46798c2
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3368/Makefile
@@ -0,0 +1,8 @@
+#
+# Copyright (c) 2016 Andreas Färber
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+obj-y		+= clk_rk3368.o
+obj-y		+= rk3368.o
+obj-y 		+= syscon_rk3368.o
diff --git a/arch/arm/mach-rockchip/rk3368/clk_rk3368.c b/arch/arm/mach-rockchip/rk3368/clk_rk3368.c
new file mode 100644
index 0000000..2f98165
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3368/clk_rk3368.c
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2017 Rockchip Electronics Co., Ltd
+ * Author: Andy Yan <andy.yan@rock-chips.org>
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <syscon.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/cru_rk3368.h>
+
+int rockchip_get_clk(struct udevice **devp)
+{
+	return uclass_get_device_by_driver(UCLASS_CLK,
+			DM_GET_DRIVER(rockchip_rk3368_cru), devp);
+}
+
+void *rockchip_get_cru(void)
+{
+	struct rk3368_clk_priv *priv;
+	struct udevice *dev;
+	int ret;
+
+	ret = rockchip_get_clk(&dev);
+	if (ret)
+		return ERR_PTR(ret);
+
+	priv = dev_get_priv(dev);
+
+	return priv->cru;
+}
diff --git a/arch/arm/mach-rockchip/rk3368/rk3368.c b/arch/arm/mach-rockchip/rk3368/rk3368.c
new file mode 100644
index 0000000..fb829a4
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3368/rk3368.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2016 Rockchip Electronics Co., Ltd
+ * Copyright (c) 2016 Andreas Färber
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/armv8/mmu.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/cru_rk3368.h>
+#include <asm/arch/grf_rk3368.h>
+#include <syscon.h>
+
+#define IMEM_BASE                  0xFF8C0000
+
+/* Max MCU's SRAM value is 8K, begin at (IMEM_BASE + 4K) */
+#define MCU_SRAM_BASE			(IMEM_BASE + 1024 * 4)
+#define MCU_SRAM_BASE_BIT31_BIT28	((MCU_SRAM_BASE & GENMASK(31, 28)) >> 28)
+#define MCU_SRAM_BASE_BIT27_BIT12	((MCU_SRAM_BASE & GENMASK(27, 12)) >> 12)
+/* exsram may using by mcu to accessing dram(0x0-0x20000000) */
+#define MCU_EXSRAM_BASE    (0)
+#define MCU_EXSRAM_BASE_BIT31_BIT28       ((MCU_EXSRAM_BASE & GENMASK(31, 28)) >> 28)
+#define MCU_EXSRAM_BASE_BIT27_BIT12       ((MCU_EXSRAM_BASE & GENMASK(27, 12)) >> 12)
+/* experi no used, reserved value = 0 */
+#define MCU_EXPERI_BASE    (0)
+#define MCU_EXPERI_BASE_BIT31_BIT28       ((MCU_EXPERI_BASE & GENMASK(31, 28)) >> 28)
+#define MCU_EXPERI_BASE_BIT27_BIT12       ((MCU_EXPERI_BASE & GENMASK(27, 12)) >> 12)
+
+static struct mm_region rk3368_mem_map[] = {
+	{
+		.virt = 0x0UL,
+		.phys = 0x0UL,
+		.size = 0x80000000UL,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+			 PTE_BLOCK_INNER_SHARE
+	}, {
+		.virt = 0xf0000000UL,
+		.phys = 0xf0000000UL,
+		.size = 0x10000000UL,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+			 PTE_BLOCK_NON_SHARE |
+			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
+	}, {
+		/* List terminator */
+		0,
+	}
+};
+
+struct mm_region *mem_map = rk3368_mem_map;
+
+#ifdef CONFIG_ARCH_EARLY_INIT_R
+static int mcu_init(void)
+{
+	struct rk3368_grf *grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+	struct rk3368_cru *cru = rockchip_get_cru();
+
+	rk_clrsetreg(&grf->soc_con14, MCU_SRAM_BASE_BIT31_BIT28_MASK,
+		     MCU_SRAM_BASE_BIT31_BIT28 << MCU_SRAM_BASE_BIT31_BIT28_SHIFT);
+	rk_clrsetreg(&grf->soc_con11, MCU_SRAM_BASE_BIT27_BIT12_MASK,
+		     MCU_SRAM_BASE_BIT27_BIT12 << MCU_SRAM_BASE_BIT27_BIT12_SHIFT);
+	rk_clrsetreg(&grf->soc_con14, MCU_EXSRAM_BASE_BIT31_BIT28_MASK,
+		     MCU_EXSRAM_BASE_BIT31_BIT28 << MCU_EXSRAM_BASE_BIT31_BIT28_SHIFT);
+	rk_clrsetreg(&grf->soc_con12, MCU_EXSRAM_BASE_BIT27_BIT12_MASK,
+		     MCU_EXSRAM_BASE_BIT27_BIT12 << MCU_EXSRAM_BASE_BIT27_BIT12_SHIFT);
+	rk_clrsetreg(&grf->soc_con14, MCU_EXPERI_BASE_BIT31_BIT28_MASK,
+		     MCU_EXPERI_BASE_BIT31_BIT28 << MCU_EXPERI_BASE_BIT31_BIT28_SHIFT);
+	rk_clrsetreg(&grf->soc_con13, MCU_EXPERI_BASE_BIT27_BIT12_MASK,
+		     MCU_EXPERI_BASE_BIT27_BIT12 << MCU_EXPERI_BASE_BIT27_BIT12_SHIFT);
+
+	rk_clrsetreg(&cru->clksel_con[12], MCU_PLL_SEL_MASK | MCU_CLK_DIV_MASK,
+		     (MCU_PLL_SEL_GPLL << MCU_PLL_SEL_SHIFT) |
+		     (5 << MCU_CLK_DIV_SHIFT));
+
+	 /* mcu dereset, for start running */
+	rk_clrreg(&cru->softrst_con[1], MCU_PO_SRST_MASK | MCU_SYS_SRST_MASK);
+
+	return 0;
+}
+
+int arch_early_init_r(void)
+{
+	return mcu_init();
+}
+#endif
diff --git a/arch/arm/mach-rockchip/rk3368/syscon_rk3368.c b/arch/arm/mach-rockchip/rk3368/syscon_rk3368.c
new file mode 100644
index 0000000..03e97eb
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3368/syscon_rk3368.c
@@ -0,0 +1,24 @@
+/*
+ * (C) Copyright 2017 Rockchip Electronics Co., Ltd
+ * Author: Andy Yan <andy.yan@rock-chips.com>
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <syscon.h>
+#include <asm/arch/clock.h>
+
+static const struct udevice_id rk3368_syscon_ids[] = {
+	{ .compatible = "rockchip,rk3368-grf",
+	  .data = ROCKCHIP_SYSCON_GRF },
+	{ .compatible = "rockchip,rk3368-pmugrf",
+	  .data = ROCKCHIP_SYSCON_PMUGRF },
+	{ }
+};
+
+U_BOOT_DRIVER(syscon_rk3368) = {
+	.name = "rk3368_syscon",
+	.id = UCLASS_SYSCON,
+	.of_match = rk3368_syscon_ids,
+};
diff --git a/arch/arm/mach-rockchip/rk3399-board-spl.c b/arch/arm/mach-rockchip/rk3399-board-spl.c
index 050f5e1..e050aff 100644
--- a/arch/arm/mach-rockchip/rk3399-board-spl.c
+++ b/arch/arm/mach-rockchip/rk3399-board-spl.c
@@ -156,8 +156,6 @@
 	writel(TIMER_EN | TIMER_FMODE, TIMER_CHN10_BASE + TIMER_CONTROL_REG);
 }
 
-#define SGRF_DDR_RGN_CON16 0xff330040
-
 void board_debug_uart_init(void)
 {
 #include <asm/arch/grf_rk3399.h>
@@ -188,6 +186,8 @@
 }
 
 #define GRF_EMMCCORE_CON11 0xff77f02c
+#define SGRF_DDR_RGN_CON16 0xff330040
+#define SGRF_SLV_SECURE_CON4 0xff33e3d0
 void board_init_f(ulong dummy)
 {
 	struct udevice *pinctrl;
@@ -207,6 +207,7 @@
 	debug_uart_init();
 	printascii("U-Boot SPL board init");
 #endif
+
 	/*  Emmc clock generator: disable the clock multipilier */
 	rk_clrreg(GRF_EMMCCORE_CON11, 0x0ff);
 
@@ -217,7 +218,7 @@
 	}
 
 	/*
-	 * Disable DDR security regions.
+	 * Disable DDR and SRAM security regions.
 	 *
 	 * As we are entered from the BootROM, the region from
 	 * 0x0 through 0xfffff (i.e. the first MB of memory) will
@@ -226,6 +227,7 @@
 	 * located in this range.
 	 */
 	rk_clrsetreg(SGRF_DDR_RGN_CON16, 0x1FF, 0);
+	rk_clrreg(SGRF_SLV_SECURE_CON4, 0x2000);
 
 	secure_timer_init();
 
diff --git a/arch/arm/mach-rockchip/rk3399/sdram_rk3399.c b/arch/arm/mach-rockchip/rk3399/sdram_rk3399.c
index a3ae8bd..1b91bb1 100644
--- a/arch/arm/mach-rockchip/rk3399/sdram_rk3399.c
+++ b/arch/arm/mach-rockchip/rk3399/sdram_rk3399.c
@@ -5,6 +5,7 @@
  *
  * Adapted from coreboot.
  */
+
 #include <common.h>
 #include <clk.h>
 #include <dm.h>
@@ -19,6 +20,7 @@
 #include <asm/arch/grf_rk3399.h>
 #include <asm/arch/hardware.h>
 #include <linux/err.h>
+#include <time.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 struct chan_info {
@@ -506,6 +508,7 @@
 	u32 tmp, tmp1, tmp2;
 	u32 pwrup_srefresh_exit;
 	int ret;
+	const ulong timeout_ms = 200;
 
 	/*
 	 * work around controller bug:
@@ -588,13 +591,15 @@
 	clrsetbits_le32(&denali_phy[957], 0x3 << 24, 0x2 << 24);
 
 	/* Wating for PHY and DRAM init complete */
-	tmp = 0;
-	while (!(readl(&denali_ctl[203]) & (1 << 3))) {
-		mdelay(10);
-		tmp++;
-		if (tmp > 10)
+	tmp = get_timer(0);
+	do {
+		if (get_timer(tmp) > timeout_ms) {
+			error("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);
@@ -1082,7 +1087,7 @@
 
 	debug("Starting SDRAM initialization...\n");
 
-	if ((dramtype == DDR3 && ddr_freq > 800) ||
+	if ((dramtype == DDR3 && ddr_freq > 933) ||
 	    (dramtype == LPDDR3 && ddr_freq > 933) ||
 	    (dramtype == LPDDR4 && ddr_freq > 800)) {
 		debug("SDRAM frequency is to high!");
diff --git a/arch/arm/mach-rockchip/rv1108/Kconfig b/arch/arm/mach-rockchip/rv1108/Kconfig
new file mode 100644
index 0000000..e6cba66
--- /dev/null
+++ b/arch/arm/mach-rockchip/rv1108/Kconfig
@@ -0,0 +1,28 @@
+if ROCKCHIP_RV1108
+
+config TARGET_EVB_RV1108
+	bool "EVB_RV1108"
+	help
+	  RV1108 EVB is a evaluation board for Rockchp RV1108.
+
+	  Key features of the board include:
+	   * one macro USB OTG port
+	   * one USB HOST port
+	   * one RS232 to USB port route to UART2 as debug port
+	   * MIPI screen with resolution 720 x 1280
+	   * 128M DDR3
+	   * 64M SPI Nor Flash
+	   * macro SD card interface
+	   * HDMI output
+	   * 10/100 Mbps Ethernet
+	   * camera interface compatible with imx323 / ov2710 / ov4689
+
+config SYS_SOC
+	default "rockchip"
+
+config SYS_MALLOC_F_LEN
+	default 0x400
+
+source board/rockchip/evb_rv1108/Kconfig
+
+endif
diff --git a/arch/arm/mach-rockchip/rv1108/Makefile b/arch/arm/mach-rockchip/rv1108/Makefile
new file mode 100644
index 0000000..9035a1a
--- /dev/null
+++ b/arch/arm/mach-rockchip/rv1108/Makefile
@@ -0,0 +1,11 @@
+#
+# (C) Copyright 2016 Rockchip Electronics Co., Ltd
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+ifndef CONFIG_SPL_BUILD
+obj-y += syscon_rv1108.o
+endif
+obj-y += rv1108.o
+obj-y += clk_rv1108.o
diff --git a/arch/arm/mach-rockchip/rv1108/clk_rv1108.c b/arch/arm/mach-rockchip/rv1108/clk_rv1108.c
new file mode 100644
index 0000000..968c356
--- /dev/null
+++ b/arch/arm/mach-rockchip/rv1108/clk_rv1108.c
@@ -0,0 +1,32 @@
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ * Author: Andy Yan <andy.yan@rock-chips.com>
+ * SPDX-License-Identifier:     GPL-2.0
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <syscon.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/cru_rv1108.h>
+
+int rockchip_get_clk(struct udevice **devp)
+{
+	return uclass_get_device_by_driver(UCLASS_CLK,
+			DM_GET_DRIVER(clk_rv1108), devp);
+}
+
+void *rockchip_get_cru(void)
+{
+	struct rv1108_clk_priv *priv;
+	struct udevice *dev;
+	int ret;
+
+	ret = rockchip_get_clk(&dev);
+	if (ret)
+		return ERR_PTR(ret);
+
+	priv = dev_get_priv(dev);
+
+	return priv->cru;
+}
diff --git a/arch/arm/mach-rockchip/rv1108/rv1108.c b/arch/arm/mach-rockchip/rv1108/rv1108.c
new file mode 100644
index 0000000..868cdd5
--- /dev/null
+++ b/arch/arm/mach-rockchip/rv1108/rv1108.c
@@ -0,0 +1,15 @@
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ * Author: Andy Yan <andy.yan@rock-chips.com>
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+
+#ifndef CONFIG_SYS_DCACHE_OFF
+void enable_caches(void)
+{
+	/* Enable D-cache. I-cache is already enabled in start.S */
+	dcache_enable();
+}
+#endif
diff --git a/arch/arm/mach-rockchip/rv1108/syscon_rv1108.c b/arch/arm/mach-rockchip/rv1108/syscon_rv1108.c
new file mode 100644
index 0000000..8bb0ab8
--- /dev/null
+++ b/arch/arm/mach-rockchip/rv1108/syscon_rv1108.c
@@ -0,0 +1,21 @@
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <syscon.h>
+#include <asm/arch/clock.h>
+
+static const struct udevice_id rv1108_syscon_ids[] = {
+	{ .compatible = "rockchip,rv1108-grf", .data = ROCKCHIP_SYSCON_GRF },
+	{ }
+};
+
+U_BOOT_DRIVER(syscon_rv1108) = {
+	.name = "rv1108_syscon",
+	.id = UCLASS_SYSCON,
+	.of_match = rv1108_syscon_ids,
+};
diff --git a/board/geekbuying/geekbox/Kconfig b/board/geekbuying/geekbox/Kconfig
new file mode 100644
index 0000000..41aa8fb
--- /dev/null
+++ b/board/geekbuying/geekbox/Kconfig
@@ -0,0 +1,15 @@
+if TARGET_GEEKBOX
+
+config SYS_BOARD
+	default "geekbox"
+
+config SYS_VENDOR
+	default "geekbuying"
+
+config SYS_CONFIG_NAME
+	default "geekbox"
+
+config BOARD_SPECIFIC_OPTIONS # dummy
+	def_bool y
+
+endif
diff --git a/board/geekbuying/geekbox/MAINTAINERS b/board/geekbuying/geekbox/MAINTAINERS
new file mode 100644
index 0000000..7a4989f
--- /dev/null
+++ b/board/geekbuying/geekbox/MAINTAINERS
@@ -0,0 +1,6 @@
+GEEKBOX
+M:	Andreas Färber <afaerber@suse.de>
+S:	Maintained
+F:	board/geekbuying/geekbox
+F:	include/configs/geekbox.h
+F:	configs/geekbox_defconfig
diff --git a/board/geekbuying/geekbox/Makefile b/board/geekbuying/geekbox/Makefile
new file mode 100644
index 0000000..5c1d66c
--- /dev/null
+++ b/board/geekbuying/geekbox/Makefile
@@ -0,0 +1,7 @@
+#
+# Copyright (c) 2016 Andreas Färber
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-y	+= geekbox.o
diff --git a/board/geekbuying/geekbox/README b/board/geekbuying/geekbox/README
new file mode 100644
index 0000000..de980f2
--- /dev/null
+++ b/board/geekbuying/geekbox/README
@@ -0,0 +1 @@
+see board/rockchip/sheep_rk3368/README
diff --git a/board/geekbuying/geekbox/geekbox.c b/board/geekbuying/geekbox/geekbox.c
new file mode 100644
index 0000000..75d121d
--- /dev/null
+++ b/board/geekbuying/geekbox/geekbox.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2016 Andreas Färber
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int board_init(void)
+{
+	return 0;
+}
+
+int dram_init(void)
+{
+	gd->ram_size = 0x80000000;
+	return 0;
+}
+
+int dram_init_banksize(void)
+{
+	gd->bd->bi_dram[0].start = 0;
+	gd->bd->bi_dram[0].size = 0x80000000;
+
+	return 0;
+}
diff --git a/board/rockchip/evb_px5/Kconfig b/board/rockchip/evb_px5/Kconfig
new file mode 100644
index 0000000..9a04ee7
--- /dev/null
+++ b/board/rockchip/evb_px5/Kconfig
@@ -0,0 +1,15 @@
+if TARGET_EVB_PX5
+
+config SYS_BOARD
+	default "evb_px5"
+
+config SYS_VENDOR
+	default "rockchip"
+
+config SYS_CONFIG_NAME
+	default "evb_px5"
+
+config BOARD_SPECIFIC_OPTIONS # dummy
+	def_bool y
+
+endif
diff --git a/board/rockchip/evb_px5/MAINTAINERS b/board/rockchip/evb_px5/MAINTAINERS
new file mode 100644
index 0000000..5d09fbf
--- /dev/null
+++ b/board/rockchip/evb_px5/MAINTAINERS
@@ -0,0 +1,6 @@
+PX5 EVB
+M:	Andy Yan <andy.yan@rock-chips.com>
+S:	Maintained
+F:	board/rockchip/evb_px5
+F:	include/configs/evb_px5.h
+F:	configs/evb-px5_defconfig
diff --git a/board/rockchip/evb_px5/Makefile b/board/rockchip/evb_px5/Makefile
new file mode 100644
index 0000000..f5aa5a9
--- /dev/null
+++ b/board/rockchip/evb_px5/Makefile
@@ -0,0 +1,7 @@
+#
+# Copyright (c) 2017 Rockchip Electronics Co., Ltd
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-y	+= evb-px5.o
diff --git a/board/rockchip/evb_px5/README b/board/rockchip/evb_px5/README
new file mode 100644
index 0000000..de980f2
--- /dev/null
+++ b/board/rockchip/evb_px5/README
@@ -0,0 +1 @@
+see board/rockchip/sheep_rk3368/README
diff --git a/board/rockchip/evb_px5/evb-px5.c b/board/rockchip/evb_px5/evb-px5.c
new file mode 100644
index 0000000..54e62db
--- /dev/null
+++ b/board/rockchip/evb_px5/evb-px5.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2017 Andy Yan
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+#include <common.h>
+#include <asm/io.h>
+#include <fdtdec.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/grf_rk3368.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int mach_cpu_init(void)
+{
+	struct rk3368_pmu_grf *pmugrf;
+	int node;
+
+	node = fdt_node_offset_by_compatible(gd->fdt_blob, -1, "rockchip,rk3368-pmugrf");
+	pmugrf = (struct rk3368_pmu_grf *)fdtdec_get_addr(gd->fdt_blob, node, "reg");
+
+	rk_clrsetreg(&pmugrf->gpio0d_iomux,
+		     GPIO0D0_MASK | GPIO0D1_MASK |
+		     GPIO0D2_MASK | GPIO0D3_MASK,
+		     GPIO0D0_GPIO << GPIO0D0_SHIFT |
+		     GPIO0D1_GPIO << GPIO0D1_SHIFT |
+		     GPIO0D2_UART4_SOUT << GPIO0D2_SHIFT |
+		     GPIO0D3_UART4_SIN << GPIO0D3_SHIFT);
+	return 0;
+}
+
+int board_init(void)
+{
+	return 0;
+}
+
+int dram_init(void)
+{
+	gd->ram_size = 0x40000000;
+
+	return 0;
+}
+
+int dram_init_banksize(void)
+{
+	 /* Reserve 0x200000 for ATF bl31 */
+	gd->bd->bi_dram[0].start = 0x200000;
+	gd->bd->bi_dram[0].size = 0x3fe00000;
+
+	return 0;
+}
diff --git a/board/rockchip/evb_rk3328/MAINTAINERS b/board/rockchip/evb_rk3328/MAINTAINERS
index 9db604f..2ee6e46 100644
--- a/board/rockchip/evb_rk3328/MAINTAINERS
+++ b/board/rockchip/evb_rk3328/MAINTAINERS
@@ -1,5 +1,5 @@
 EVB-RK3328
-M:      William Zhang <william.zhang@rock-chips.com>
+M:      Kever Yang <kever.yang@rock-chips.com>
 S:      Maintained
 F:      board/rockchip/evb_rk3328
 F:      include/configs/evb_rk3328.h
diff --git a/board/rockchip/evb_rk3328/evb-rk3328.c b/board/rockchip/evb_rk3328/evb-rk3328.c
index a7895cb..0a26ed5 100644
--- a/board/rockchip/evb_rk3328/evb-rk3328.c
+++ b/board/rockchip/evb_rk3328/evb-rk3328.c
@@ -31,11 +31,6 @@
 	return 0;
 }
 
-int usb_gadget_handle_interrupts(void)
-{
-	return 0;
-}
-
 int board_usb_init(int index, enum usb_init_type init)
 {
 	return 0;
diff --git a/board/rockchip/evb_rv1108/Kconfig b/board/rockchip/evb_rv1108/Kconfig
new file mode 100644
index 0000000..4a76e0b
--- /dev/null
+++ b/board/rockchip/evb_rv1108/Kconfig
@@ -0,0 +1,15 @@
+if TARGET_EVB_RV1108
+
+config SYS_BOARD
+	default "evb_rv1108"
+
+config SYS_VENDOR
+	default "rockchip"
+
+config SYS_CONFIG_NAME
+	default "evb_rv1108"
+
+config BOARD_SPECIFIC_OPTIONS # dummy
+	def_bool y
+
+endif
diff --git a/board/rockchip/evb_rv1108/MAINTAINERS b/board/rockchip/evb_rv1108/MAINTAINERS
new file mode 100644
index 0000000..94def32
--- /dev/null
+++ b/board/rockchip/evb_rv1108/MAINTAINERS
@@ -0,0 +1,6 @@
+EVB-RV1108
+M:      Andy Yan <andy.yan@rock-chips.com>
+S:      Maintained
+F:      board/rockchip/evb_rv1108
+F:      include/configs/evb_rv1108.h
+F:      configs/evb-rv1108_defconfig
diff --git a/board/rockchip/evb_rv1108/Makefile b/board/rockchip/evb_rv1108/Makefile
new file mode 100644
index 0000000..dd99054
--- /dev/null
+++ b/board/rockchip/evb_rv1108/Makefile
@@ -0,0 +1,7 @@
+#
+# (C) Copyright 2016 Rockchip Electronics Co., Ltd
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-y	+= evb_rv1108.o
diff --git a/board/rockchip/evb_rv1108/README b/board/rockchip/evb_rv1108/README
new file mode 100644
index 0000000..5889596
--- /dev/null
+++ b/board/rockchip/evb_rv1108/README
@@ -0,0 +1,47 @@
+Here is the step-by-step to boot U-Boot on rv1108 evb.
+
+Get ddr init binary
+==============================================================================
+  > git clone  https://github.com/rockchip-linux/rkbin.git
+  > dd if=./rkbin/rv1x/rv1108ddr.bin of=ddr.bin bs=4 skip=1
+
+Compile  U-Boot
+===========================
+  > make CROSS_COMPILE=arm-linux-gnueabi- evb-rv1108_defconfig  all
+  > ./tools/mkimage  -n rv1108 -T rksd -d ddr.bin spl.bin
+  > cat spl.bin u-boot.bin > u-boot.img
+
+Flash the image by rkdeveloptool
+================================
+rkdeveloptool can get from https://github.com/rockchip-linux/rkdeveloptool.git
+
+Power on(or reset with RESET KEY) with MASKROM KEY preesed, and then:
+  > rkdeveloptool db ./rkbin/rv1x/RV1108_usb_boot.bin
+  > rkdeveloptool wl 0x40 u-boot.img
+  > rkdeveloptool RD
+
+You should be able to get U-Boot log message from boot console:
+
+DDR Version V1.02 20170220
+In
+400MHz
+DDR3
+Bus Width=16 Col=10 Bank=8 Row=15 CS=1 Die Bus-Width=16 Size=512MB
+mach:2
+OUT
+
+
+U-Boot 2017.05-00693-g3a5b171 (Jun 01 2017 - 17:37:53 +0800)
+
+Model: Rockchip RV1108 Evaluation board
+DRAM:  128 MiB
+APLL: 600000000 DPLL:792000000 GPLL:384000000
+MMC:
+Using default environment
+
+In:    serial@10210000
+Out:   serial@10210000
+Err:   serial@10210000
+Net:   No ethernet found.
+Hit any key to stop autoboot:  0
+=>
diff --git a/board/rockchip/evb_rv1108/evb_rv1108.c b/board/rockchip/evb_rv1108/evb_rv1108.c
new file mode 100644
index 0000000..fe37eac
--- /dev/null
+++ b/board/rockchip/evb_rv1108/evb_rv1108.c
@@ -0,0 +1,52 @@
+/*
+ * (C)Copyright 2016 Rockchip Electronics Co., Ltd
+ * Authors: Andy Yan <andy.yan@rock-chips.com>
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <fdtdec.h>
+#include <asm/arch/grf_rv1108.h>
+#include <asm/arch/hardware.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int mach_cpu_init(void)
+{
+	int node;
+	struct rv1108_grf *grf;
+
+	node = fdt_node_offset_by_compatible(gd->fdt_blob, -1, "rockchip,rv1108-grf");
+	grf = (struct rv1108_grf *)fdtdec_get_addr(gd->fdt_blob, node, "reg");
+
+	/*evb board use UART2 m0 for debug*/
+	rk_clrsetreg(&grf->gpio2d_iomux,
+		     GPIO2D2_MASK | GPIO2D1_MASK,
+		     GPIO2D2_UART2_SOUT_M0 << GPIO2D2_SHIFT |
+		     GPIO2D1_UART2_SIN_M0 << GPIO2D1_SHIFT);
+	rk_clrreg(&grf->gpio3c_iomux, GPIO3C3_MASK | GPIO3C2_MASK);
+
+	return 0;
+}
+
+
+int board_init(void)
+{
+	return 0;
+}
+
+int dram_init(void)
+{
+	gd->ram_size = 0x8000000;
+
+	return 0;
+}
+
+int dram_init_banksize(void)
+{
+	gd->bd->bi_dram[0].start = 0x60000000;
+	gd->bd->bi_dram[0].size = 0x8000000;
+
+	return 0;
+}
diff --git a/board/rockchip/sheep_rk3368/Kconfig b/board/rockchip/sheep_rk3368/Kconfig
new file mode 100644
index 0000000..d39b5e8
--- /dev/null
+++ b/board/rockchip/sheep_rk3368/Kconfig
@@ -0,0 +1,15 @@
+if TARGET_SHEEP
+
+config SYS_BOARD
+	default "sheep_rk3368"
+
+config SYS_VENDOR
+	default "rockchip"
+
+config SYS_CONFIG_NAME
+	default "sheep_rk3368"
+
+config BOARD_SPECIFIC_OPTIONS # dummy
+	def_bool y
+
+endif
diff --git a/board/rockchip/sheep_rk3368/MAINTAINERS b/board/rockchip/sheep_rk3368/MAINTAINERS
new file mode 100644
index 0000000..cd5de99
--- /dev/null
+++ b/board/rockchip/sheep_rk3368/MAINTAINERS
@@ -0,0 +1,6 @@
+RK3368 Sheep Board
+M:	Andy Yan <andy.yan@rock-chips.com>
+S:	Maintained
+F:	board/rockchip/sheep_rk3368
+F:	include/configs/sheep_rk3368.h
+F:	configs/sheep-rk3368_defconfig
diff --git a/board/rockchip/sheep_rk3368/Makefile b/board/rockchip/sheep_rk3368/Makefile
new file mode 100644
index 0000000..a38b9ce
--- /dev/null
+++ b/board/rockchip/sheep_rk3368/Makefile
@@ -0,0 +1,7 @@
+#
+# Copyright (c) 2017 Rockchip Electronics Co., Ltd
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-y	+= sheep_rk3368.o
diff --git a/board/rockchip/sheep_rk3368/README b/board/rockchip/sheep_rk3368/README
new file mode 100644
index 0000000..2d078cb
--- /dev/null
+++ b/board/rockchip/sheep_rk3368/README
@@ -0,0 +1,44 @@
+Here is the step-by-step to boot to U-Boot on rk3368.
+
+Get miniloader and trust.img form rockchip vendor u-boot source code
+==============================================================================
+  > git clone  https://github.com/rockchip-linux/u-boot.git rockchip-uboot
+  > cd rockchip-uboot
+  > make rk3368_defconfig /*chose px5_defconfig if you run a px5 platform here*/
+  > ./mkv8.sh
+
+Compile the upstream U-Boot
+===========================
+  > cd u-boot
+  > make CROSS_COMPILE=aarch64-linux-gnu- sheep-rk3368_defconfig  all
+
+Package u-boot for miniloader
+================================
+  > ../rockchip-uboot/tools/loaderimage --pack --uboot u-boot.bin u-boot.img
+
+Flash the image by rkdeveloptool
+================================
+rkdeveloptool can get from https://github.com/rockchip-linux/rkdeveloptool.git
+
+Power on(or reset with RESET KEY) with MASKROM KEY preesed, and then:
+  > rkdeveloptool db ./rockchip-uboot/rk3368_loader_v2.00.256.bin
+  > rkdeveloptool wl 0x6000 ./rockchip-uboot/trust.img
+  > rkdeveloptool wl 0x4000 ./u-boot/u-boot.img
+  > rkdeveloptool RD
+
+You should be able to get U-Boot log message from boot console:
+
+U-Boot 2017.05-rc3-01094-g9ddd1e8-dirty (May 15 2017 - 15:57:23 +0800)
+
+Model: Rockchip sheep board
+DRAM:  2 GiB
+MMC:   dwmmc@ff0f0000: 0
+Using default environment
+
+In:    serial@ff690000
+Out:   serial@ff690000
+Err:   serial@ff690000
+Net:   Net Initialization Skipped
+No ethernet found.
+Hit any key to stop autoboot:  0
+=>
diff --git a/board/rockchip/sheep_rk3368/sheep_rk3368.c b/board/rockchip/sheep_rk3368/sheep_rk3368.c
new file mode 100644
index 0000000..df1fd9d
--- /dev/null
+++ b/board/rockchip/sheep_rk3368/sheep_rk3368.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2017 Andy Yan
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/grf_rk3368.h>
+#include <syscon.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int mach_cpu_init(void)
+{
+	return 0;
+}
+
+int board_init(void)
+{
+	return 0;
+}
+
+int dram_init(void)
+{
+	gd->ram_size = 0x80000000;
+
+	return 0;
+}
+
+int dram_init_banksize(void)
+{
+	gd->bd->bi_dram[0].start = 0x200000;
+	gd->bd->bi_dram[0].size = 0x7fe00000;
+
+	return 0;
+}
diff --git a/board/theobroma-systems/puma_rk3399/README b/board/theobroma-systems/puma_rk3399/README
index 1a8d02b..250e345 100644
--- a/board/theobroma-systems/puma_rk3399/README
+++ b/board/theobroma-systems/puma_rk3399/README
@@ -56,8 +56,7 @@
 =================
 
 	> tools/mkimage -n rk3399 -T rksd -d spl/u-boot-spl.bin spl.img
-	> tools/mkimage -f board/theobroma/puma_rk3399/fit_spl_atf.its \
-		-E rk3399_bl3x.itb
+	> make CROSS_COMPILE=aarch64-linux-gnu- u-boot.itb
 
 Flash the image
 ===============
@@ -67,7 +66,7 @@
 card.
 
   > dd if=spl.img of=/dev/sdb seek=64
-  > dd if=rk3399_bl3x.itb of=/dev/sdb seek=512
+  > dd if=u-boot.itb of=/dev/sdb seek=512
 
 After powering up the board (with the inserted SD card), you should see
 a U-Boot console on UART0 (115200n8).
diff --git a/board/theobroma-systems/puma_rk3399/puma-rk3399.c b/board/theobroma-systems/puma_rk3399/puma-rk3399.c
index 0a8861a..6fff3e1 100644
--- a/board/theobroma-systems/puma_rk3399/puma-rk3399.c
+++ b/board/theobroma-systems/puma_rk3399/puma-rk3399.c
@@ -9,10 +9,15 @@
 #include <ram.h>
 #include <dm/pinctrl.h>
 #include <dm/uclass-internal.h>
+#include <misc.h>
+#include <asm/setup.h>
 #include <asm/arch/periph.h>
 #include <power/regulator.h>
 #include <u-boot/sha256.h>
 
+#define RK3399_CPUID_OFF  0x7
+#define RK3399_CPUID_LEN  0x10
+
 DECLARE_GLOBAL_DATA_PTR;
 
 #define RK3399_CPUID_OFF  0x7
@@ -63,6 +68,119 @@
 	return 0;
 }
 
+static void setup_macaddr(void)
+{
+#if CONFIG_IS_ENABLED(CMD_NET)
+	int ret;
+	const char *cpuid = getenv("cpuid#");
+	u8 hash[SHA256_SUM_LEN];
+	int size = sizeof(hash);
+	u8 mac_addr[6];
+
+	/* Only generate a MAC address, if none is set in the environment */
+	if (getenv("ethaddr"))
+		return;
+
+	if (!cpuid) {
+		debug("%s: could not retrieve 'cpuid#'\n", __func__);
+		return;
+	}
+
+	ret = hash_block("sha256", (void *)cpuid, strlen(cpuid), hash, &size);
+	if (ret) {
+		debug("%s: failed to calculate SHA256\n", __func__);
+		return;
+	}
+
+	/* Copy 6 bytes of the hash to base the MAC address on */
+	memcpy(mac_addr, hash, 6);
+
+	/* Make this a valid MAC address and set it */
+	mac_addr[0] &= 0xfe;  /* clear multicast bit */
+	mac_addr[0] |= 0x02;  /* set local assignment bit (IEEE802) */
+	eth_setenv_enetaddr("ethaddr", mac_addr);
+#endif
+
+	return;
+}
+
+static void setup_serial(void)
+{
+#if CONFIG_IS_ENABLED(ROCKCHIP_EFUSE)
+	struct udevice *dev;
+	int ret, i;
+	u8 cpuid[RK3399_CPUID_LEN];
+	u8 low[RK3399_CPUID_LEN/2], high[RK3399_CPUID_LEN/2];
+	char cpuid_str[RK3399_CPUID_LEN * 2 + 1];
+	u64 serialno;
+	char serialno_str[16];
+
+	/* retrieve the device */
+	ret = uclass_get_device_by_driver(UCLASS_MISC,
+					  DM_GET_DRIVER(rockchip_efuse), &dev);
+	if (ret) {
+		debug("%s: could not find efuse device\n", __func__);
+		return;
+	}
+
+	/* read the cpu_id range from the efuses */
+	ret = misc_read(dev, RK3399_CPUID_OFF, &cpuid, sizeof(cpuid));
+	if (ret) {
+		debug("%s: reading cpuid from the efuses failed\n",
+		      __func__);
+		return;
+	}
+
+	memset(cpuid_str, 0, sizeof(cpuid_str));
+	for (i = 0; i < 16; i++)
+		sprintf(&cpuid_str[i * 2], "%02x", cpuid[i]);
+
+	debug("cpuid: %s\n", cpuid_str);
+
+	/*
+	 * Mix the cpuid bytes using the same rules as in
+	 *   ${linux}/drivers/soc/rockchip/rockchip-cpuinfo.c
+	 */
+	for (i = 0; i < 8; i++) {
+		low[i] = cpuid[1 + (i << 1)];
+		high[i] = cpuid[i << 1];
+	}
+
+	serialno = crc32_no_comp(0, low, 8);
+	serialno |= (u64)crc32_no_comp(serialno, high, 8) << 32;
+	snprintf(serialno_str, sizeof(serialno_str), "%llx", serialno);
+
+	setenv("cpuid#", cpuid_str);
+	setenv("serial#", serialno_str);
+#endif
+
+	return;
+}
+
+int misc_init_r(void)
+{
+	setup_serial();
+	setup_macaddr();
+
+	return 0;
+}
+
+#ifdef CONFIG_SERIAL_TAG
+void get_board_serial(struct tag_serialnr *serialnr)
+{
+	char *serial_string;
+	u64 serial = 0;
+
+	serial_string = getenv("serial#");
+
+	if (serial_string)
+		serial = simple_strtoull(serial_string, NULL, 16);
+
+	serialnr->high = (u32)(serial >> 32);
+	serialnr->low = (u32)(serial & 0xffffffff);
+}
+#endif
+
 int dram_init(void)
 {
 	struct ram_info ram;
diff --git a/configs/evb-px5_defconfig b/configs/evb-px5_defconfig
new file mode 100644
index 0000000..8926f89
--- /dev/null
+++ b/configs/evb-px5_defconfig
@@ -0,0 +1,30 @@
+CONFIG_ARM=y
+CONFIG_ARCH_ROCKCHIP=y
+CONFIG_ROCKCHIP_RK3368=y
+CONFIG_TARGET_EVB_PX5=y
+CONFIG_DEFAULT_DEVICE_TREE="rk3368-px5-evb"
+CONFIG_HUSH_PARSER=y
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_ARCH_EARLY_INIT_R=y
+CONFIG_FASTBOOT=y
+CONFIG_ANDROID_BOOT_IMAGE=y
+CONFIG_CMD_BOOTRK=y
+# CONFIG_CMD_IMLS is not set
+CONFIG_CMD_MMC=y
+CONFIG_CMD_CACHE=y
+CONFIG_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_CLK=y
+CONFIG_MMC_DW=y
+CONFIG_MMC_DW_ROCKCHIP=y
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_ROCKCHIP_RK3368=y
+CONFIG_RAM=y
+CONFIG_DEBUG_UART=y
+CONFIG_DEBUG_UART_BASE=0xFF1c0000
+CONFIG_DEBUG_UART_CLOCK=24000000
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_DEBUG_UART_ANNOUNCE=y
+CONFIG_DEBUG_UART_SKIP_INIT=y
+CONFIG_SYSRESET=y
+CONFIG_ERRNO_STR=y
diff --git a/configs/evb-rk3328_defconfig b/configs/evb-rk3328_defconfig
index 96241f6..57aee02 100644
--- a/configs/evb-rk3328_defconfig
+++ b/configs/evb-rk3328_defconfig
@@ -31,3 +31,14 @@
 CONFIG_SYSRESET=y
 CONFIG_USE_TINY_PRINTF=y
 CONFIG_ERRNO_STR=y
+CONFIG_USB=y
+CONFIG_DM_USB=y
+CONFIG_CMD_USB=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_GENERIC=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_GENERIC=y
+CONFIG_USB_XHCI_DWC3=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_RK=y
diff --git a/configs/evb-rv1108_defconfig b/configs/evb-rv1108_defconfig
new file mode 100644
index 0000000..3fa1ae8
--- /dev/null
+++ b/configs/evb-rv1108_defconfig
@@ -0,0 +1,40 @@
+CONFIG_ARM=y
+CONFIG_ARCH_ROCKCHIP=y
+CONFIG_ROCKCHIP_RV1108=y
+CONFIG_TARGET_EVB_RV1108=y
+CONFIG_DEFAULT_DEVICE_TREE="rv1108-evb"
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_HUSH_PARSER=y
+# CONFIG_CMD_IMLS is not set
+CONFIG_CMD_SF=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_CACHE=y
+CONFIG_CMD_TIME=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_CLK=y
+CONFIG_ROCKCHIP_GPIO=y
+CONFIG_SYS_I2C_ROCKCHIP=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_BAR=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_SPI_FLASH_MTD=y
+CONFIG_DM_ETH=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_GMAC_ROCKCHIP=y
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_ROCKCHIP_RV1108=y
+CONFIG_RAM=y
+CONFIG_BAUDRATE=1500000
+# CONFIG_SPL_SERIAL_PRESENT is not set
+CONFIG_DEBUG_UART=y
+CONFIG_DEBUG_UART_BASE=0x10210000
+CONFIG_DEBUG_UART_CLOCK=24000000
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_SYSRESET=y
+CONFIG_ERRNO_STR=y
diff --git a/configs/firefly-rk3399_defconfig b/configs/firefly-rk3399_defconfig
index f30f131..0a4d005 100644
--- a/configs/firefly-rk3399_defconfig
+++ b/configs/firefly-rk3399_defconfig
@@ -39,7 +39,7 @@
 CONFIG_GMAC_ROCKCHIP=y
 CONFIG_PINCTRL=y
 CONFIG_SPL_PINCTRL=y
-CONFIG_ROCKCHIP_RK3399_PINCTRL=y
+CONFIG_PINCTRL_ROCKCHIP_RK3399=y
 CONFIG_DM_PMIC=y
 CONFIG_PMIC_RK8XX=y
 CONFIG_REGULATOR_PWM=y
diff --git a/configs/geekbox_defconfig b/configs/geekbox_defconfig
new file mode 100644
index 0000000..0a50bbf
--- /dev/null
+++ b/configs/geekbox_defconfig
@@ -0,0 +1,22 @@
+CONFIG_ARM=y
+CONFIG_ARCH_ROCKCHIP=y
+CONFIG_ROCKCHIP_RK3368=y
+CONFIG_TARGET_GEEKBOX=y
+CONFIG_DEFAULT_DEVICE_TREE="rk3368-geekbox"
+CONFIG_HUSH_PARSER=y
+# CONFIG_DISPLAY_CPUINFO is not set
+# CONFIG_CMD_IMLS is not set
+CONFIG_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_CLK=y
+CONFIG_SYSRESET=y
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_ROCKCHIP_RK3368=y
+CONFIG_RAM=y
+CONFIG_DEBUG_UART=y
+CONFIG_DEBUG_UART_BASE=0xFF690000
+CONFIG_DEBUG_UART_CLOCK=24000000
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_DEBUG_UART_ANNOUNCE=y
+CONFIG_DEBUG_UART_SKIP_INIT=y
+CONFIG_ERRNO_STR=y
diff --git a/configs/puma-rk3399_defconfig b/configs/puma-rk3399_defconfig
index 6245360..89f1620 100644
--- a/configs/puma-rk3399_defconfig
+++ b/configs/puma-rk3399_defconfig
@@ -8,11 +8,13 @@
 CONFIG_SPL_SPI_FLASH_SUPPORT=y
 CONFIG_SPL_SPI_SUPPORT=y
 CONFIG_SPL_STACK_R_ADDR=0x80000
-CONFIG_DEFAULT_DEVICE_TREE="rk3399-puma"
+CONFIG_DEFAULT_DEVICE_TREE="rk3399-puma-ddr1600"
+CONFIG_DEBUG_UART=y
 CONFIG_FIT=y
-CONFIG_SPL_FIT=y
 CONFIG_SPL_LOAD_FIT=y
+CONFIG_SPL_FIT_SOURCE="board/theobroma-systems/puma_rk3399/fit_spl_atf.its"
 # CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_SPL_BOARD_INIT=y
 # CONFIG_SPL_RAW_IMAGE_SUPPORT is not set
 # CONFIG_SPL_LEGACY_IMAGE_SUPPORT is not set
 CONFIG_SPL_STACK_R=y
@@ -24,11 +26,16 @@
 CONFIG_CMD_MMC=y
 CONFIG_CMD_SF=y
 CONFIG_CMD_SPI=y
+CONFIG_CMD_I2C=y
 CONFIG_CMD_USB=y
 # CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_BMP=y
+CONFIG_CMD_CACHE=y
 CONFIG_CMD_TIME=y
+CONFIG_CMD_PMIC=y
+CONFIG_CMD_REGULATOR=y
 CONFIG_SPL_OF_CONTROL=y
-CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents"
+CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents"
 CONFIG_REGMAP=y
 CONFIG_SPL_REGMAP=y
 CONFIG_SYSCON=y
@@ -36,6 +43,9 @@
 CONFIG_CLK=y
 CONFIG_SPL_CLK=y
 CONFIG_ROCKCHIP_GPIO=y
+CONFIG_SYS_I2C_ROCKCHIP=y
+CONFIG_MISC=y
+CONFIG_ROCKCHIP_EFUSE=y
 CONFIG_MMC_DW=y
 CONFIG_MMC_DW_ROCKCHIP=y
 CONFIG_MMC_SDHCI=y
@@ -43,18 +53,21 @@
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_PHY_MICREL=y
+CONFIG_PHY_MICREL_KSZ9031=y
 CONFIG_DM_ETH=y
 CONFIG_ETH_DESIGNWARE=y
 CONFIG_GMAC_ROCKCHIP=y
 CONFIG_PINCTRL=y
 CONFIG_SPL_PINCTRL=y
 CONFIG_PINCTRL_ROCKCHIP_RK3399=y
+CONFIG_DM_PMIC=y
+CONFIG_PMIC_RK8XX=y
 CONFIG_REGULATOR_PWM=y
 CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_REGULATOR_RK8XX=y
 CONFIG_PWM_ROCKCHIP=y
 CONFIG_RAM=y
 CONFIG_SPL_RAM=y
-CONFIG_DEBUG_UART=y
 CONFIG_DEBUG_UART_BASE=0xFF180000
 CONFIG_DEBUG_UART_CLOCK=24000000
 CONFIG_DEBUG_UART_SHIFT=2
@@ -67,4 +80,8 @@
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_GENERIC=y
 CONFIG_USB_STORAGE=y
+CONFIG_DM_VIDEO=y
+CONFIG_DISPLAY=y
+CONFIG_VIDEO_ROCKCHIP=y
+CONFIG_DISPLAY_ROCKCHIP_HDMI=y
 CONFIG_ERRNO_STR=y
diff --git a/configs/sheep-rk3368_defconfig b/configs/sheep-rk3368_defconfig
new file mode 100644
index 0000000..73c59b7
--- /dev/null
+++ b/configs/sheep-rk3368_defconfig
@@ -0,0 +1,28 @@
+CONFIG_ARM=y
+CONFIG_ARCH_ROCKCHIP=y
+CONFIG_ROCKCHIP_RK3368=y
+CONFIG_TARGET_SHEEP=y
+CONFIG_DEFAULT_DEVICE_TREE="rk3368-sheep"
+CONFIG_HUSH_PARSER=y
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_FASTBOOT=y
+CONFIG_ANDROID_BOOT_IMAGE=y
+# CONFIG_CMD_IMLS is not set
+CONFIG_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_CLK=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_BOOTRK=y
+CONFIG_MMC_DW=y
+CONFIG_MMC_DW_ROCKCHIP=y
+CONFIG_SYSRESET=y
+CONFIG_PINCTRL=y
+CONFIG_ROCKCHIP_RK3368_PINCTRL=y
+CONFIG_RAM=y
+CONFIG_DEBUG_UART=y
+CONFIG_DEBUG_UART_BASE=0xFF1b0000
+CONFIG_DEBUG_UART_CLOCK=24000000
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_DEBUG_UART_ANNOUNCE=y
+CONFIG_DEBUG_UART_SKIP_INIT=y
+CONFIG_ERRNO_STR=y
diff --git a/doc/git-mailrc b/doc/git-mailrc
index b9b5929..33317d1 100644
--- a/doc/git-mailrc
+++ b/doc/git-mailrc
@@ -77,7 +77,7 @@
 alias ti             uboot, trini
 alias uniphier       uboot, masahiro
 alias zynq           uboot, monstr
-alias rockchip       uboot, sjg, Lin huang <hl@rock-chips.com>
+alias rockchip       uboot, sjg, Kever Yang <kever.yang@rock-chips.com>
 alias avr32          uboot, abiessmann
 
 alias bfin           uboot, vapier, sonic
diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
index 1091a76..e404c0c 100644
--- a/drivers/clk/rockchip/Makefile
+++ b/drivers/clk/rockchip/Makefile
@@ -8,4 +8,6 @@
 obj-$(CONFIG_ROCKCHIP_RK3188) += clk_rk3188.o
 obj-$(CONFIG_ROCKCHIP_RK3288) += clk_rk3288.o
 obj-$(CONFIG_ROCKCHIP_RK3328) += clk_rk3328.o
+obj-$(CONFIG_ROCKCHIP_RK3368) += clk_rk3368.o
 obj-$(CONFIG_ROCKCHIP_RK3399) += clk_rk3399.o
+obj-$(CONFIG_ROCKCHIP_RV1108) += clk_rv1108.o
diff --git a/drivers/clk/rockchip/clk_rk3036.c b/drivers/clk/rockchip/clk_rk3036.c
index 0bee5db..28652df 100644
--- a/drivers/clk/rockchip/clk_rk3036.c
+++ b/drivers/clk/rockchip/clk_rk3036.c
@@ -65,12 +65,11 @@
 	rk_clrreg(&pll->con1, 1 << PLL_DSMPD_SHIFT);
 
 	rk_clrsetreg(&pll->con0,
-		     PLL_POSTDIV1_MASK << PLL_POSTDIV1_SHIFT | PLL_FBDIV_MASK,
+		     PLL_POSTDIV1_MASK | PLL_FBDIV_MASK,
 		     (div->postdiv1 << PLL_POSTDIV1_SHIFT) | div->fbdiv);
-	rk_clrsetreg(&pll->con1, PLL_POSTDIV2_MASK << PLL_POSTDIV2_SHIFT |
-			PLL_REFDIV_MASK << PLL_REFDIV_SHIFT,
-			(div->postdiv2 << PLL_POSTDIV2_SHIFT |
-			 div->refdiv << PLL_REFDIV_SHIFT));
+	rk_clrsetreg(&pll->con1, PLL_POSTDIV2_MASK | PLL_REFDIV_MASK,
+		     (div->postdiv2 << PLL_POSTDIV2_SHIFT |
+		     div->refdiv << PLL_REFDIV_SHIFT));
 
 	/* waiting for pll lock */
 	while (readl(&pll->con1) & (1 << PLL_LOCK_STATUS_SHIFT))
@@ -87,8 +86,7 @@
 
 	/* pll enter slow-mode */
 	rk_clrsetreg(&cru->cru_mode_con,
-		     GPLL_MODE_MASK << GPLL_MODE_SHIFT |
-		     APLL_MODE_MASK << APLL_MODE_SHIFT,
+		     GPLL_MODE_MASK | APLL_MODE_MASK,
 		     GPLL_MODE_SLOW << GPLL_MODE_SHIFT |
 		     APLL_MODE_SLOW << APLL_MODE_SHIFT);
 
@@ -97,8 +95,8 @@
 	rkclk_set_pll(cru, CLK_GENERAL, &gpll_init_cfg);
 
 	/*
-	 * select apll as core clock pll source and
-	 * set up dependent divisors for PCLK/HCLK and ACLK clocks.
+	 * select apll as cpu/core clock pll source and
+	 * set up dependent divisors for PERI and ACLK clocks.
 	 * core hz : apll = 1:1
 	 */
 	aclk_div = APLL_HZ / CORE_ACLK_HZ - 1;
@@ -108,44 +106,40 @@
 	assert((pclk_div + 1) * CORE_PERI_HZ == APLL_HZ && pclk_div < 0xf);
 
 	rk_clrsetreg(&cru->cru_clksel_con[0],
-		     CORE_CLK_PLL_SEL_MASK << CORE_CLK_PLL_SEL_SHIFT |
-		     CORE_DIV_CON_MASK << CORE_DIV_CON_SHIFT,
+		     CORE_CLK_PLL_SEL_MASK | CORE_DIV_CON_MASK,
 		     CORE_CLK_PLL_SEL_APLL << CORE_CLK_PLL_SEL_SHIFT |
 		     0 << CORE_DIV_CON_SHIFT);
 
 	rk_clrsetreg(&cru->cru_clksel_con[1],
-		     CORE_ACLK_DIV_MASK << CORE_ACLK_DIV_SHIFT |
-		     CORE_PERI_DIV_MASK << CORE_PERI_DIV_SHIFT,
+		     CORE_ACLK_DIV_MASK | CORE_PERI_DIV_MASK,
 		     aclk_div << CORE_ACLK_DIV_SHIFT |
 		     pclk_div << CORE_PERI_DIV_SHIFT);
 
 	/*
-	 * select apll as cpu clock pll source and
+	 * select apll as pd_bus bus clock source and
 	 * set up dependent divisors for PCLK/HCLK and ACLK clocks.
 	 */
-	aclk_div = APLL_HZ / CPU_ACLK_HZ - 1;
-	assert((aclk_div + 1) * CPU_ACLK_HZ == APLL_HZ && aclk_div < 0x1f);
+	aclk_div = GPLL_HZ / BUS_ACLK_HZ - 1;
+	assert((aclk_div + 1) * BUS_ACLK_HZ == GPLL_HZ && aclk_div <= 0x1f);
 
-	pclk_div = APLL_HZ / CPU_PCLK_HZ - 1;
-	assert((pclk_div + 1) * CPU_PCLK_HZ == APLL_HZ && pclk_div < 0x7);
+	pclk_div = GPLL_HZ / BUS_PCLK_HZ - 1;
+	assert((pclk_div + 1) * BUS_PCLK_HZ == GPLL_HZ && pclk_div <= 0x7);
 
-	hclk_div = APLL_HZ / CPU_HCLK_HZ - 1;
-	assert((hclk_div + 1) * CPU_HCLK_HZ == APLL_HZ && hclk_div < 0x3);
+	hclk_div = GPLL_HZ / BUS_HCLK_HZ - 1;
+	assert((hclk_div + 1) * BUS_HCLK_HZ == GPLL_HZ && hclk_div <= 0x3);
 
 	rk_clrsetreg(&cru->cru_clksel_con[0],
-		     CPU_CLK_PLL_SEL_MASK << CPU_CLK_PLL_SEL_SHIFT |
-		     ACLK_CPU_DIV_MASK << ACLK_CPU_DIV_SHIFT,
-		     CPU_CLK_PLL_SEL_APLL << CPU_CLK_PLL_SEL_SHIFT |
-		     aclk_div << ACLK_CPU_DIV_SHIFT);
+		     BUS_ACLK_PLL_SEL_MASK | BUS_ACLK_DIV_MASK,
+		     BUS_ACLK_PLL_SEL_GPLL << BUS_ACLK_PLL_SEL_SHIFT |
+		     aclk_div << BUS_ACLK_DIV_SHIFT);
 
 	rk_clrsetreg(&cru->cru_clksel_con[1],
-		     CPU_PCLK_DIV_MASK << CPU_PCLK_DIV_SHIFT |
-		     CPU_HCLK_DIV_MASK << CPU_HCLK_DIV_SHIFT,
-		     pclk_div << CPU_PCLK_DIV_SHIFT |
-		     hclk_div << CPU_HCLK_DIV_SHIFT);
+		     BUS_PCLK_DIV_MASK | BUS_HCLK_DIV_MASK,
+		     pclk_div << BUS_PCLK_DIV_SHIFT |
+		     hclk_div << BUS_HCLK_DIV_SHIFT);
 
 	/*
-	 * select gpll as peri clock pll source and
+	 * select gpll as pd_peri bus clock source and
 	 * set up dependent divisors for PCLK/HCLK and ACLK clocks.
 	 */
 	aclk_div = GPLL_HZ / PERI_ACLK_HZ - 1;
@@ -153,17 +147,15 @@
 
 	hclk_div = ilog2(PERI_ACLK_HZ / PERI_HCLK_HZ);
 	assert((1 << hclk_div) * PERI_HCLK_HZ ==
-		PERI_ACLK_HZ && (pclk_div < 0x4));
+		PERI_ACLK_HZ && (hclk_div < 0x4));
 
 	pclk_div = ilog2(PERI_ACLK_HZ / PERI_PCLK_HZ);
 	assert((1 << pclk_div) * PERI_PCLK_HZ ==
 		PERI_ACLK_HZ && pclk_div < 0x8);
 
 	rk_clrsetreg(&cru->cru_clksel_con[10],
-		     PERI_PLL_SEL_MASK << PERI_PLL_SEL_SHIFT |
-		     PERI_PCLK_DIV_MASK << PERI_PCLK_DIV_SHIFT |
-		     PERI_HCLK_DIV_MASK << PERI_HCLK_DIV_SHIFT |
-		     PERI_ACLK_DIV_MASK << PERI_ACLK_DIV_SHIFT,
+		     PERI_PLL_SEL_MASK | PERI_PCLK_DIV_MASK |
+		     PERI_HCLK_DIV_MASK | PERI_ACLK_DIV_MASK,
 		     PERI_PLL_GPLL << PERI_PLL_SEL_SHIFT |
 		     pclk_div << PERI_PCLK_DIV_SHIFT |
 		     hclk_div << PERI_HCLK_DIV_SHIFT |
@@ -171,8 +163,7 @@
 
 	/* PLL enter normal-mode */
 	rk_clrsetreg(&cru->cru_mode_con,
-		     GPLL_MODE_MASK << GPLL_MODE_SHIFT |
-		     APLL_MODE_MASK << APLL_MODE_SHIFT,
+		     GPLL_MODE_MASK | APLL_MODE_MASK,
 		     GPLL_MODE_NORM << GPLL_MODE_SHIFT |
 		     APLL_MODE_NORM << APLL_MODE_SHIFT);
 }
@@ -189,9 +180,9 @@
 		0xff, APLL_MODE_SHIFT, DPLL_MODE_SHIFT, 0xff,
 		GPLL_MODE_SHIFT, 0xff
 	};
-	static u8 clk_mask[CLK_COUNT] = {
-		0xff, APLL_MODE_MASK, DPLL_MODE_MASK, 0xff,
-		GPLL_MODE_MASK, 0xff
+	static u32 clk_mask[CLK_COUNT] = {
+		0xffffffff, APLL_MODE_MASK, DPLL_MODE_MASK, 0xffffffff,
+		GPLL_MODE_MASK, 0xffffffff
 	};
 	uint shift;
 	uint mask;
@@ -200,18 +191,18 @@
 	shift = clk_shift[clk_id];
 	mask = clk_mask[clk_id];
 
-	switch ((con >> shift) & mask) {
+	switch ((con & mask) >> shift) {
 	case GPLL_MODE_SLOW:
 		return OSC_HZ;
 	case GPLL_MODE_NORM:
 
 		/* normal mode */
 		con = readl(&pll->con0);
-		postdiv1 = (con >> PLL_POSTDIV1_SHIFT) & PLL_POSTDIV1_MASK;
-		fbdiv = (con >> PLL_FBDIV_SHIFT) & PLL_FBDIV_MASK;
+		postdiv1 = (con & PLL_POSTDIV1_MASK) >> PLL_POSTDIV1_SHIFT;
+		fbdiv = (con & PLL_FBDIV_MASK) >> PLL_FBDIV_SHIFT;
 		con = readl(&pll->con1);
-		postdiv2 = (con >> PLL_POSTDIV2_SHIFT) & PLL_POSTDIV2_MASK;
-		refdiv = (con >> PLL_REFDIV_SHIFT) & PLL_REFDIV_MASK;
+		postdiv2 = (con & PLL_POSTDIV2_MASK) >> PLL_POSTDIV2_SHIFT;
+		refdiv = (con & PLL_REFDIV_MASK) >> PLL_REFDIV_SHIFT;
 		return (24 * fbdiv / (refdiv * postdiv1 * postdiv2)) * 1000000;
 	case GPLL_MODE_DEEP:
 	default:
@@ -230,14 +221,14 @@
 	case HCLK_EMMC:
 	case SCLK_EMMC:
 		con = readl(&cru->cru_clksel_con[12]);
-		mux = (con >> EMMC_PLL_SHIFT) & EMMC_PLL_MASK;
-		div = (con >> EMMC_DIV_SHIFT) & EMMC_DIV_MASK;
+		mux = (con & EMMC_PLL_MASK) >> EMMC_PLL_SHIFT;
+		div = (con & EMMC_DIV_MASK) >> EMMC_DIV_SHIFT;
 		break;
 	case HCLK_SDIO:
 	case SCLK_SDIO:
 		con = readl(&cru->cru_clksel_con[12]);
-		mux = (con >> MMC0_PLL_SHIFT) & MMC0_PLL_MASK;
-		div = (con >> MMC0_DIV_SHIFT) & MMC0_DIV_MASK;
+		mux = (con & MMC0_PLL_MASK) >> MMC0_PLL_SHIFT;
+		div = (con & MMC0_DIV_MASK) >> MMC0_DIV_SHIFT;
 		break;
 	default:
 		return -EINVAL;
@@ -269,16 +260,14 @@
 	case HCLK_EMMC:
 	case SCLK_EMMC:
 		rk_clrsetreg(&cru->cru_clksel_con[12],
-			     EMMC_PLL_MASK << EMMC_PLL_SHIFT |
-			     EMMC_DIV_MASK << EMMC_DIV_SHIFT,
+			     EMMC_PLL_MASK | EMMC_DIV_MASK,
 			     mux << EMMC_PLL_SHIFT |
 			     (src_clk_div - 1) << EMMC_DIV_SHIFT);
 		break;
 	case HCLK_SDIO:
 	case SCLK_SDIO:
 		rk_clrsetreg(&cru->cru_clksel_con[11],
-			     MMC0_PLL_MASK << MMC0_PLL_SHIFT |
-			     MMC0_DIV_MASK << MMC0_DIV_SHIFT,
+			     MMC0_PLL_MASK | MMC0_DIV_MASK,
 			     mux << MMC0_PLL_SHIFT |
 			     (src_clk_div - 1) << MMC0_DIV_SHIFT);
 		break;
diff --git a/drivers/clk/rockchip/clk_rk3368.c b/drivers/clk/rockchip/clk_rk3368.c
new file mode 100644
index 0000000..52cad38
--- /dev/null
+++ b/drivers/clk/rockchip/clk_rk3368.c
@@ -0,0 +1,291 @@
+/*
+ * (C) Copyright 2017 Rockchip Electronics Co., Ltd
+ * Author: Andy Yan <andy.yan@rock-chips.com>
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <errno.h>
+#include <syscon.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/cru_rk3368.h>
+#include <asm/arch/hardware.h>
+#include <asm/io.h>
+#include <dm/lists.h>
+#include <dt-bindings/clock/rk3368-cru.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct pll_div {
+	u32 nr;
+	u32 nf;
+	u32 no;
+};
+
+#define OSC_HZ		(24 * 1000 * 1000)
+#define APLL_L_HZ	(800 * 1000 * 1000)
+#define APLL_B_HZ	(816 * 1000 * 1000)
+#define GPLL_HZ		(576 * 1000 * 1000)
+#define CPLL_HZ		(400 * 1000 * 1000)
+
+#define RATE_TO_DIV(input_rate, output_rate) \
+		((input_rate) / (output_rate) - 1);
+
+#define DIV_TO_RATE(input_rate, div)    ((input_rate) / ((div) + 1))
+
+#define PLL_DIVISORS(hz, _nr, _no) { \
+	.nr = _nr, .nf = (u32)((u64)hz * _nr * _no / OSC_HZ), .no = _no}; \
+	_Static_assert(((u64)hz * _nr * _no / OSC_HZ) * OSC_HZ /\
+		       (_nr * _no) == hz, #hz "Hz cannot be hit with PLL " \
+		       "divisors on line " __stringify(__LINE__));
+
+static const struct pll_div apll_l_init_cfg = PLL_DIVISORS(APLL_L_HZ, 12, 2);
+static const struct pll_div apll_b_init_cfg = PLL_DIVISORS(APLL_B_HZ, 1, 2);
+static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 1, 2);
+static const struct pll_div cpll_init_cfg = PLL_DIVISORS(CPLL_HZ, 1, 6);
+
+/* Get pll rate by id */
+static uint32_t rkclk_pll_get_rate(struct rk3368_cru *cru,
+				   enum rk3368_pll_id pll_id)
+{
+	uint32_t nr, no, nf;
+	uint32_t con;
+	struct rk3368_pll *pll = &cru->pll[pll_id];
+
+	con = readl(&pll->con3);
+
+	switch ((con & PLL_MODE_MASK) >> PLL_MODE_SHIFT) {
+	case PLL_MODE_SLOW:
+		return OSC_HZ;
+	case PLL_MODE_NORMAL:
+		con = readl(&pll->con0);
+		no = ((con & PLL_OD_MASK) >> PLL_OD_SHIFT) + 1;
+		nr = ((con & PLL_NR_MASK) >> PLL_NR_SHIFT) + 1;
+		con = readl(&pll->con1);
+		nf = ((con & PLL_NF_MASK) >> PLL_NF_SHIFT) + 1;
+
+		return (24 * nf / (nr * no)) * 1000000;
+	case PLL_MODE_DEEP_SLOW:
+	default:
+		return 32768;
+	}
+}
+
+static int rkclk_set_pll(struct rk3368_cru *cru, enum rk3368_pll_id pll_id,
+			 const struct pll_div *div, bool has_bwadj)
+{
+	struct rk3368_pll *pll = &cru->pll[pll_id];
+	/* All PLLs have same VCO and output frequency range restrictions*/
+	uint vco_hz = OSC_HZ / 1000 * div->nf / div->nr * 1000;
+	uint output_hz = vco_hz / div->no;
+
+	debug("PLL at %p: nf=%d, nr=%d, no=%d, vco=%u Hz, output=%u Hz\n",
+	      pll, div->nf, div->nr, div->no, vco_hz, output_hz);
+
+	/* enter slow mode and reset pll */
+	rk_clrsetreg(&pll->con3, PLL_MODE_MASK | PLL_RESET_MASK,
+		     PLL_RESET << PLL_RESET_SHIFT);
+
+	rk_clrsetreg(&pll->con0, PLL_NR_MASK | PLL_OD_MASK,
+		     ((div->nr - 1) << PLL_NR_SHIFT) |
+		     ((div->no - 1) << PLL_OD_SHIFT));
+	writel((div->nf - 1) << PLL_NF_SHIFT, &pll->con1);
+	udelay(10);
+
+	/* return from reset */
+	rk_clrreg(&pll->con3, PLL_RESET_MASK);
+
+	/* waiting for pll lock */
+	while (!(readl(&pll->con1) & PLL_LOCK_STA))
+		udelay(1);
+
+	rk_clrsetreg(&pll->con3, PLL_MODE_MASK,
+		     PLL_MODE_NORMAL << PLL_MODE_SHIFT);
+
+	return 0;
+}
+
+static void rkclk_init(struct rk3368_cru *cru)
+{
+	u32 apllb, aplll, dpll, cpll, gpll;
+
+	rkclk_set_pll(cru, APLLB, &apll_b_init_cfg, false);
+	rkclk_set_pll(cru, APLLL, &apll_l_init_cfg, false);
+	rkclk_set_pll(cru, GPLL, &gpll_init_cfg, false);
+	rkclk_set_pll(cru, CPLL, &cpll_init_cfg, false);
+
+	apllb = rkclk_pll_get_rate(cru, APLLB);
+	aplll = rkclk_pll_get_rate(cru, APLLL);
+	dpll = rkclk_pll_get_rate(cru, DPLL);
+	cpll = rkclk_pll_get_rate(cru, CPLL);
+	gpll = rkclk_pll_get_rate(cru, GPLL);
+
+	debug("%s apllb(%d) apll(%d) dpll(%d) cpll(%d) gpll(%d)\n",
+	       __func__, apllb, aplll, dpll, cpll, gpll);
+}
+
+static ulong rk3368_mmc_get_clk(struct rk3368_cru *cru, uint clk_id)
+{
+	u32 div, con, con_id, rate;
+	u32 pll_rate;
+
+	switch (clk_id) {
+	case SCLK_SDMMC:
+		con_id = 50;
+		break;
+	case SCLK_EMMC:
+		con_id = 51;
+		break;
+	case SCLK_SDIO0:
+		con_id = 48;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	con = readl(&cru->clksel_con[con_id]);
+	switch ((con & MMC_PLL_SEL_MASK) >> MMC_PLL_SEL_SHIFT) {
+	case MMC_PLL_SEL_GPLL:
+		pll_rate = rkclk_pll_get_rate(cru, GPLL);
+		break;
+	case MMC_PLL_SEL_24M:
+		pll_rate = OSC_HZ;
+		break;
+	case MMC_PLL_SEL_CPLL:
+	case MMC_PLL_SEL_USBPHY_480M:
+	default:
+		return -EINVAL;
+	}
+	div = (con & MMC_CLK_DIV_MASK) >> MMC_CLK_DIV_SHIFT;
+	rate = DIV_TO_RATE(pll_rate, div);
+
+	return rate >> 1;
+}
+
+static ulong rk3368_mmc_set_clk(struct rk3368_cru *cru,
+				ulong clk_id, ulong rate)
+{
+	u32 div;
+	u32 con_id;
+	u32 gpll_rate = rkclk_pll_get_rate(cru, GPLL);
+
+	div = RATE_TO_DIV(gpll_rate, rate << 1);
+
+	switch (clk_id) {
+	case SCLK_SDMMC:
+		con_id = 50;
+		break;
+	case SCLK_EMMC:
+		con_id = 51;
+		break;
+	case SCLK_SDIO0:
+		con_id = 48;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (div > 0x3f) {
+		div = RATE_TO_DIV(OSC_HZ, rate);
+		rk_clrsetreg(&cru->clksel_con[con_id],
+			     MMC_PLL_SEL_MASK | MMC_CLK_DIV_MASK,
+			     (MMC_PLL_SEL_24M << MMC_PLL_SEL_SHIFT) |
+			     (div << MMC_CLK_DIV_SHIFT));
+	} else {
+		rk_clrsetreg(&cru->clksel_con[con_id],
+			     MMC_PLL_SEL_MASK | MMC_CLK_DIV_MASK,
+			     (MMC_PLL_SEL_GPLL << MMC_PLL_SEL_SHIFT) |
+			     div << MMC_CLK_DIV_SHIFT);
+	}
+
+	return rk3368_mmc_get_clk(cru, clk_id);
+}
+
+static ulong rk3368_clk_get_rate(struct clk *clk)
+{
+	struct rk3368_clk_priv *priv = dev_get_priv(clk->dev);
+	ulong rate = 0;
+
+	debug("%s id:%ld\n", __func__, clk->id);
+	switch (clk->id) {
+	case HCLK_SDMMC:
+	case HCLK_EMMC:
+		rate = rk3368_mmc_get_clk(priv->cru, clk->id);
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	return rate;
+}
+
+static ulong rk3368_clk_set_rate(struct clk *clk, ulong rate)
+{
+	struct rk3368_clk_priv *priv = dev_get_priv(clk->dev);
+	ulong ret = 0;
+
+	debug("%s id:%ld rate:%ld\n", __func__, clk->id, rate);
+	switch (clk->id) {
+	case SCLK_SDMMC:
+	case SCLK_EMMC:
+		ret = rk3368_mmc_set_clk(priv->cru, clk->id, rate);
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	return ret;
+}
+
+static struct clk_ops rk3368_clk_ops = {
+	.get_rate = rk3368_clk_get_rate,
+	.set_rate = rk3368_clk_set_rate,
+};
+
+static int rk3368_clk_probe(struct udevice *dev)
+{
+	struct rk3368_clk_priv *priv = dev_get_priv(dev);
+
+	rkclk_init(priv->cru);
+
+	return 0;
+}
+
+static int rk3368_clk_ofdata_to_platdata(struct udevice *dev)
+{
+	struct rk3368_clk_priv *priv = dev_get_priv(dev);
+
+	priv->cru = (struct rk3368_cru *)devfdt_get_addr(dev);
+
+	return 0;
+}
+
+static int rk3368_clk_bind(struct udevice *dev)
+{
+	int ret;
+
+	/* The reset driver does not have a device node, so bind it here */
+	ret = device_bind_driver(gd->dm_root, "rk3368_sysreset", "reset", &dev);
+	if (ret)
+		error("bind RK3368 reset driver failed: ret=%d\n", ret);
+
+	return ret;
+}
+
+static const struct udevice_id rk3368_clk_ids[] = {
+	{ .compatible = "rockchip,rk3368-cru" },
+	{ }
+};
+
+U_BOOT_DRIVER(rockchip_rk3368_cru) = {
+	.name		= "rockchip_rk3368_cru",
+	.id		= UCLASS_CLK,
+	.of_match	= rk3368_clk_ids,
+	.priv_auto_alloc_size = sizeof(struct rk3368_cru),
+	.ofdata_to_platdata = rk3368_clk_ofdata_to_platdata,
+	.ops		= &rk3368_clk_ops,
+	.bind		= rk3368_clk_bind,
+	.probe		= rk3368_clk_probe,
+};
diff --git a/drivers/clk/rockchip/clk_rv1108.c b/drivers/clk/rockchip/clk_rv1108.c
new file mode 100644
index 0000000..0a3ba3b
--- /dev/null
+++ b/drivers/clk/rockchip/clk_rv1108.c
@@ -0,0 +1,223 @@
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ * Author: Andy Yan <andy.yan@rock-chips.com>
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <errno.h>
+#include <syscon.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/cru_rv1108.h>
+#include <asm/arch/hardware.h>
+#include <dm/lists.h>
+#include <dt-bindings/clock/rv1108-cru.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+enum {
+	VCO_MAX_HZ	= 2400U * 1000000,
+	VCO_MIN_HZ	= 600 * 1000000,
+	OUTPUT_MAX_HZ	= 2400U * 1000000,
+	OUTPUT_MIN_HZ	= 24 * 1000000,
+};
+
+#define RATE_TO_DIV(input_rate, output_rate) \
+	((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,\
+	.fbdiv = (u32)((u64)hz * _refdiv * _postdiv1 * _postdiv2 / OSC_HZ),\
+	.postdiv1 = _postdiv1, .postdiv2 = _postdiv2};\
+	_Static_assert(((u64)hz * _refdiv * _postdiv1 * _postdiv2 / OSC_HZ) *\
+			 OSC_HZ / (_refdiv * _postdiv1 * _postdiv2) == hz,\
+			 #hz "Hz cannot be hit with PLL "\
+			 "divisors on line " __stringify(__LINE__));
+
+/* use interge mode*/
+static const struct pll_div apll_init_cfg = PLL_DIVISORS(APLL_HZ, 1, 3, 1);
+static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 2, 2, 1);
+
+static inline int rv1108_pll_id(enum rk_clk_id clk_id)
+{
+	int id = 0;
+
+	switch (clk_id) {
+	case CLK_ARM:
+	case CLK_DDR:
+		id = clk_id - 1;
+		break;
+	case CLK_GENERAL:
+		id = 2;
+		break;
+	default:
+		printf("invalid pll id:%d\n", clk_id);
+		id = -1;
+		break;
+	}
+
+	return id;
+}
+
+static uint32_t rkclk_pll_get_rate(struct rv1108_cru *cru,
+				   enum rk_clk_id clk_id)
+{
+	uint32_t refdiv, fbdiv, postdiv1, postdiv2;
+	uint32_t con0, con1, con3;
+	int pll_id = rv1108_pll_id(clk_id);
+	struct rv1108_pll *pll = &cru->pll[pll_id];
+	uint32_t freq;
+
+	con3 = readl(&pll->con3);
+
+	if (con3 & WORK_MODE_MASK) {
+		con0 = readl(&pll->con0);
+		con1 = readl(&pll->con1);
+		fbdiv = (con0 >> FBDIV_SHIFT) & FBDIV_MASK;
+		postdiv1 = (con1 & POSTDIV1_MASK) >> POSTDIV1_SHIFT;
+		postdiv2 = (con1 & POSTDIV2_MASK) >> POSTDIV2_SHIFT;
+		refdiv = (con1 & REFDIV_MASK) >> REFDIV_SHIFT;
+		freq = (24 * fbdiv / (refdiv * postdiv1 * postdiv2)) * 1000000;
+	} else {
+		freq = OSC_HZ;
+	}
+
+	return freq;
+}
+
+static int rv1108_mac_set_clk(struct rv1108_cru *cru, ulong rate)
+{
+	uint32_t con = readl(&cru->clksel_con[24]);
+	ulong pll_rate;
+	uint8_t div;
+
+	if ((con >> MAC_PLL_SEL_SHIFT) & MAC_PLL_SEL_GPLL)
+		pll_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
+	else
+		pll_rate = rkclk_pll_get_rate(cru, CLK_ARM);
+
+	/*default set 50MHZ for gmac*/
+	if (!rate)
+		rate = 50000000;
+
+	div = DIV_ROUND_UP(pll_rate, rate) - 1;
+	if (div <= 0x1f)
+		rk_clrsetreg(&cru->clksel_con[24], MAC_CLK_DIV_MASK,
+			     div << MAC_CLK_DIV_SHIFT);
+	else
+		debug("Unsupported div for gmac:%d\n", div);
+
+	return DIV_TO_RATE(pll_rate, div);
+}
+
+static int rv1108_sfc_set_clk(struct rv1108_cru *cru, uint rate)
+{
+	u32 con = readl(&cru->clksel_con[27]);
+	u32 pll_rate;
+	u32 div;
+
+	if ((con >> SFC_PLL_SEL_SHIFT) && SFC_PLL_SEL_GPLL)
+		pll_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
+	else
+		pll_rate = rkclk_pll_get_rate(cru, CLK_DDR);
+
+	div = DIV_ROUND_UP(pll_rate, rate) - 1;
+	if (div <= 0x3f)
+		rk_clrsetreg(&cru->clksel_con[27], SFC_CLK_DIV_MASK,
+			     div << SFC_CLK_DIV_SHIFT);
+	else
+		debug("Unsupported sfc clk rate:%d\n", rate);
+
+	return DIV_TO_RATE(pll_rate, div);
+}
+
+static ulong rv1108_clk_get_rate(struct clk *clk)
+{
+	struct rv1108_clk_priv *priv = dev_get_priv(clk->dev);
+
+	switch (clk->id) {
+	case 0 ... 63:
+		return rkclk_pll_get_rate(priv->cru, clk->id);
+	default:
+		return -ENOENT;
+	}
+}
+
+static ulong rv1108_clk_set_rate(struct clk *clk, ulong rate)
+{
+	struct rv1108_clk_priv *priv = dev_get_priv(clk->dev);
+	ulong new_rate;
+
+	switch (clk->id) {
+	case SCLK_MAC:
+		new_rate = rv1108_mac_set_clk(priv->cru, rate);
+		break;
+	case SCLK_SFC:
+		new_rate = rv1108_sfc_set_clk(priv->cru, rate);
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	return new_rate;
+}
+
+static const struct clk_ops rv1108_clk_ops = {
+	.get_rate	= rv1108_clk_get_rate,
+	.set_rate	= rv1108_clk_set_rate,
+};
+
+static void rkclk_init(struct rv1108_cru *cru)
+{
+	unsigned int apll = rkclk_pll_get_rate(cru, CLK_ARM);
+	unsigned int dpll = rkclk_pll_get_rate(cru, CLK_DDR);
+	unsigned int gpll = rkclk_pll_get_rate(cru, CLK_GENERAL);
+
+	rk_clrsetreg(&cru->clksel_con[0], CORE_CLK_DIV_MASK,
+		     0 << MAC_CLK_DIV_SHIFT);
+
+	printf("APLL: %d DPLL:%d GPLL:%d\n", apll, dpll, gpll);
+}
+
+static int rv1108_clk_probe(struct udevice *dev)
+{
+	struct rv1108_clk_priv *priv = dev_get_priv(dev);
+
+	priv->cru = (struct rv1108_cru *)devfdt_get_addr(dev);
+
+	rkclk_init(priv->cru);
+
+	return 0;
+}
+
+static int rv1108_clk_bind(struct udevice *dev)
+{
+	int ret;
+
+	/* The reset driver does not have a device node, so bind it here */
+	ret = device_bind_driver(gd->dm_root, "rv1108_sysreset", "reset", &dev);
+	if (ret)
+		error("No Rv1108 reset driver: ret=%d\n", ret);
+
+	return 0;
+}
+
+static const struct udevice_id rv1108_clk_ids[] = {
+	{ .compatible = "rockchip,rv1108-cru" },
+	{ }
+};
+
+U_BOOT_DRIVER(clk_rv1108) = {
+	.name		= "clk_rv1108",
+	.id		= UCLASS_CLK,
+	.of_match	= rv1108_clk_ids,
+	.priv_auto_alloc_size = sizeof(struct rv1108_clk_priv),
+	.ops		= &rv1108_clk_ops,
+	.bind		= rv1108_clk_bind,
+	.probe		= rv1108_clk_probe,
+};
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index ecca159..92f348f 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -20,6 +20,19 @@
 	  Select this to enable a sysid for Altera devices. Please find
 	  details on the "Embedded Peripherals IP User Guide" of Altera.
 
+config ROCKCHIP_EFUSE
+        bool "Rockchip e-fuse support"
+	depends on MISC
+	help
+	  Enable (read-only) access for the e-fuse block found in Rockchip
+	  SoCs: accesses can either be made using byte addressing and a length
+	  or through child-nodes that are generated based on the e-fuse map
+	  retrieved from the DTS.
+
+	  This driver currently supports the RK3399 only, but can easily be
+	  extended (by porting the read function from the Linux kernel sources)
+	  to support other recent Rockchip devices.
+
 config CMD_CROS_EC
 	bool "Enable crosec command"
 	depends on CROS_EC
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 4543cd6..ea64677 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -50,3 +50,4 @@
 obj-$(CONFIG_FSL_DEVICE_DISABLE) += fsl_devdis.o
 obj-$(CONFIG_WINBOND_W83627) += winbond_w83627.o
 obj-$(CONFIG_QFW) += qfw.o
+obj-$(CONFIG_ROCKCHIP_EFUSE) += rockchip-efuse.o
diff --git a/drivers/misc/rockchip-efuse.c b/drivers/misc/rockchip-efuse.c
new file mode 100644
index 0000000..423d24c
--- /dev/null
+++ b/drivers/misc/rockchip-efuse.c
@@ -0,0 +1,161 @@
+/*
+ * eFuse driver for Rockchip devices
+ *
+ * Copyright 2017, Theobroma Systems Design und Consulting GmbH
+ * Written by Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <command.h>
+#include <display_options.h>
+#include <dm.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <misc.h>
+
+#define RK3399_A_SHIFT          16
+#define RK3399_A_MASK           0x3ff
+#define RK3399_NFUSES           32
+#define RK3399_BYTES_PER_FUSE   4
+#define RK3399_STROBSFTSEL      BIT(9)
+#define RK3399_RSB              BIT(7)
+#define RK3399_PD               BIT(5)
+#define RK3399_PGENB            BIT(3)
+#define RK3399_LOAD             BIT(2)
+#define RK3399_STROBE           BIT(1)
+#define RK3399_CSB              BIT(0)
+
+struct rockchip_efuse_regs {
+	u32 ctrl;      /* 0x00  efuse control register */
+	u32 dout;      /* 0x04  efuse data out register */
+	u32 rf;        /* 0x08  efuse redundancy bit used register */
+	u32 _rsvd0;
+	u32 jtag_pass; /* 0x10  JTAG password */
+	u32 strobe_finish_ctrl;
+		       /* 0x14	efuse strobe finish control register */
+};
+
+struct rockchip_efuse_platdata {
+	void __iomem *base;
+	struct clk *clk;
+};
+
+#if defined(DEBUG)
+static int dump_efuses(cmd_tbl_t *cmdtp, int flag,
+		       int argc, char * const argv[])
+{
+	/*
+	 * N.B.: This function is tailored towards the RK3399 and assumes that
+	 *       there's always 32 fuses x 32 bits (i.e. 128 bytes of data) to
+	 *       be read.
+	 */
+
+	struct udevice *dev;
+	u8 fuses[128];
+	int ret;
+
+	/* retrieve the device */
+	ret = uclass_get_device_by_driver(UCLASS_MISC,
+					  DM_GET_DRIVER(rockchip_efuse), &dev);
+	if (ret) {
+		printf("%s: no misc-device found\n", __func__);
+		return 0;
+	}
+
+	ret = misc_read(dev, 0, &fuses, sizeof(fuses));
+	if (ret) {
+		printf("%s: misc_read failed\n", __func__);
+		return 0;
+	}
+
+	printf("efuse-contents:\n");
+	print_buffer(0, fuses, 1, 128, 16);
+
+	return 0;
+}
+
+U_BOOT_CMD(
+	rk3399_dump_efuses, 1, 1, dump_efuses,
+	"Dump the content of the efuses",
+	""
+);
+#endif
+
+static int rockchip_rk3399_efuse_read(struct udevice *dev, int offset,
+				      void *buf, int size)
+{
+	struct rockchip_efuse_platdata *plat = dev_get_platdata(dev);
+	struct rockchip_efuse_regs *efuse =
+		(struct rockchip_efuse_regs *)plat->base;
+
+	unsigned int addr_start, addr_end, addr_offset;
+	u32 out_value;
+	u8  bytes[RK3399_NFUSES * RK3399_BYTES_PER_FUSE];
+	int i = 0;
+	u32 addr;
+
+	addr_start = offset / RK3399_BYTES_PER_FUSE;
+	addr_offset = offset % RK3399_BYTES_PER_FUSE;
+	addr_end = DIV_ROUND_UP(offset + size, RK3399_BYTES_PER_FUSE);
+
+	/* cap to the size of the efuse block */
+	if (addr_end > RK3399_NFUSES)
+		addr_end = RK3399_NFUSES;
+
+	writel(RK3399_LOAD | RK3399_PGENB | RK3399_STROBSFTSEL | RK3399_RSB,
+	       &efuse->ctrl);
+	udelay(1);
+	for (addr = addr_start; addr < addr_end; addr++) {
+		setbits_le32(&efuse->ctrl,
+			     RK3399_STROBE | (addr << RK3399_A_SHIFT));
+		udelay(1);
+		out_value = readl(&efuse->dout);
+		clrbits_le32(&efuse->ctrl, RK3399_STROBE);
+		udelay(1);
+
+		memcpy(&bytes[i], &out_value, RK3399_BYTES_PER_FUSE);
+		i += RK3399_BYTES_PER_FUSE;
+	}
+
+	/* Switch to standby mode */
+	writel(RK3399_PD | RK3399_CSB, &efuse->ctrl);
+
+	memcpy(buf, bytes + addr_offset, size);
+
+	return 0;
+}
+
+static int rockchip_efuse_read(struct udevice *dev, int offset,
+			       void *buf, int size)
+{
+	return rockchip_rk3399_efuse_read(dev, offset, buf, size);
+}
+
+static const struct misc_ops rockchip_efuse_ops = {
+	.read = rockchip_efuse_read,
+};
+
+static int rockchip_efuse_ofdata_to_platdata(struct udevice *dev)
+{
+	struct rockchip_efuse_platdata *plat = dev_get_platdata(dev);
+
+	plat->base = (void *)devfdt_get_addr(dev);
+	return 0;
+}
+
+static const struct udevice_id rockchip_efuse_ids[] = {
+	{ .compatible = "rockchip,rk3399-efuse" },
+	{}
+};
+
+U_BOOT_DRIVER(rockchip_efuse) = {
+	.name = "rockchip_efuse",
+	.id = UCLASS_MISC,
+	.of_match = rockchip_efuse_ids,
+	.ofdata_to_platdata = rockchip_efuse_ofdata_to_platdata,
+	.platdata_auto_alloc_size = sizeof(struct rockchip_efuse_platdata),
+	.ops = &rockchip_efuse_ops,
+};
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index f6616c5..150c68d 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -197,6 +197,16 @@
 	  the GPIO definitions and pin control functions for each available
 	  multiplex function.
 
+config PINCTRL_ROCKCHIP_RK3368
+	bool "Rockchip RK3368 pin control driver"
+	depends on DM
+	help
+	  Support pin multiplexing control on Rockchip rk3368 SoCs.
+
+	  The driver is controlled by a device tree node which contains both
+	  the GPIO definitions and pin control functions for each available
+	  multiplex function.
+
 config PINCTRL_ROCKCHIP_RK3399
 	bool "Rockchip rk3399 pin control driver"
 	depends on DM
@@ -207,6 +217,16 @@
 	  the GPIO definitions and pin control functions for each available
 	  multiplex function.
 
+config PINCTRL_ROCKCHIP_RV1108
+	bool "Rockchip rv1108 pin control driver"
+	depends on DM
+	help
+	  Support pin multiplexing control on Rockchip rv1108 SoC.
+
+	  The driver is controlled by a device tree node which contains
+	  both the GPIO definitions and pin control functions for each
+	  available multiplex function.
+
 config PINCTRL_SANDBOX
 	bool "Sandbox pinctrl driver"
 	depends on SANDBOX
diff --git a/drivers/pinctrl/rockchip/Makefile b/drivers/pinctrl/rockchip/Makefile
index 69eef4c..a1c655d 100644
--- a/drivers/pinctrl/rockchip/Makefile
+++ b/drivers/pinctrl/rockchip/Makefile
@@ -9,4 +9,6 @@
 obj-$(CONFIG_PINCTRL_ROCKCHIP_RK3188) += pinctrl_rk3188.o
 obj-$(CONFIG_PINCTRL_ROCKCHIP_RK3288) += pinctrl_rk3288.o
 obj-$(CONFIG_PINCTRL_ROCKCHIP_RK3328) += pinctrl_rk3328.o
+obj-$(CONFIG_PINCTRL_ROCKCHIP_RK3368) += pinctrl_rk3368.o
 obj-$(CONFIG_PINCTRL_ROCKCHIP_RK3399) += pinctrl_rk3399.o
+obj-$(CONFIG_PINCTRL_ROCKCHIP_RV1108) += pinctrl_rv1108.o
diff --git a/drivers/pinctrl/rockchip/pinctrl_rk3036.c b/drivers/pinctrl/rockchip/pinctrl_rk3036.c
index 8d42584..9215d6c 100644
--- a/drivers/pinctrl/rockchip/pinctrl_rk3036.c
+++ b/drivers/pinctrl/rockchip/pinctrl_rk3036.c
@@ -26,19 +26,19 @@
 {
 	switch (pwm_id) {
 	case PERIPH_ID_PWM0:
-		rk_clrsetreg(&grf->gpio0d_iomux, GPIO0D2_MASK << GPIO0D2_SHIFT,
+		rk_clrsetreg(&grf->gpio0d_iomux, GPIO0D2_MASK,
 			     GPIO0D2_PWM0 << GPIO0D2_SHIFT);
 		break;
 	case PERIPH_ID_PWM1:
-		rk_clrsetreg(&grf->gpio0a_iomux, GPIO0A0_MASK << GPIO0A0_SHIFT,
+		rk_clrsetreg(&grf->gpio0a_iomux, GPIO0A0_MASK,
 			     GPIO0A0_PWM1 << GPIO0A0_SHIFT);
 		break;
 	case PERIPH_ID_PWM2:
-		rk_clrsetreg(&grf->gpio0a_iomux, GPIO0A1_MASK << GPIO0A1_SHIFT,
+		rk_clrsetreg(&grf->gpio0a_iomux, GPIO0A1_MASK,
 			     GPIO0A1_PWM2 << GPIO0A1_SHIFT);
 		break;
 	case PERIPH_ID_PWM3:
-		rk_clrsetreg(&grf->gpio0a_iomux, GPIO0D3_MASK << GPIO0D3_SHIFT,
+		rk_clrsetreg(&grf->gpio0a_iomux, GPIO0D3_MASK,
 			     GPIO0D3_PWM3 << GPIO0D3_SHIFT);
 		break;
 	default:
@@ -52,23 +52,20 @@
 	switch (i2c_id) {
 	case PERIPH_ID_I2C0:
 		rk_clrsetreg(&grf->gpio0a_iomux,
-			     GPIO0A1_MASK << GPIO0A1_SHIFT |
-			     GPIO0A0_MASK << GPIO0A0_SHIFT,
+			     GPIO0A1_MASK | GPIO0A0_MASK,
 			     GPIO0A1_I2C0_SDA << GPIO0A1_SHIFT |
 			     GPIO0A0_I2C0_SCL << GPIO0A0_SHIFT);
 
 		break;
 	case PERIPH_ID_I2C1:
 		rk_clrsetreg(&grf->gpio0a_iomux,
-			     GPIO0A3_MASK << GPIO0A3_SHIFT |
-			     GPIO0A2_MASK << GPIO0A2_SHIFT,
+			     GPIO0A3_MASK | GPIO0A2_MASK,
 			     GPIO0A3_I2C1_SDA << GPIO0A3_SHIFT |
 			     GPIO0A2_I2C1_SCL << GPIO0A2_SHIFT);
 		break;
 	case PERIPH_ID_I2C2:
 		rk_clrsetreg(&grf->gpio2c_iomux,
-			     GPIO2C5_MASK << GPIO2C5_SHIFT |
-			     GPIO2C4_MASK << GPIO2C4_SHIFT,
+			     GPIO2C5_MASK | GPIO2C4_MASK,
 			     GPIO2C5_I2C2_SCL << GPIO2C5_SHIFT |
 			     GPIO2C4_I2C2_SDA << GPIO2C4_SHIFT);
 
@@ -80,24 +77,20 @@
 {
 	switch (cs) {
 	case 0:
-		rk_clrsetreg(&grf->gpio1d_iomux,
-			     GPIO1D6_MASK << GPIO1D6_SHIFT,
+		rk_clrsetreg(&grf->gpio1d_iomux, GPIO1D6_MASK,
 			     GPIO1D6_SPI_CSN0 << GPIO1D6_SHIFT);
 		break;
 	case 1:
-		rk_clrsetreg(&grf->gpio1d_iomux,
-			     GPIO1D7_MASK << GPIO1D7_SHIFT,
+		rk_clrsetreg(&grf->gpio1d_iomux, GPIO1D7_MASK,
 			     GPIO1D7_SPI_CSN1 << GPIO1D7_SHIFT);
 		break;
 	}
 	rk_clrsetreg(&grf->gpio1d_iomux,
-		     GPIO1D5_MASK << GPIO1D5_SHIFT |
-		     GPIO1D4_MASK << GPIO1D4_SHIFT,
+		     GPIO1D5_MASK | GPIO1D4_MASK,
 		     GPIO1D5_SPI_TXD << GPIO1D5_SHIFT |
 		     GPIO1D4_SPI_RXD << GPIO1D4_SHIFT);
 
-	rk_clrsetreg(&grf->gpio2a_iomux,
-		     GPIO2A0_MASK << GPIO2A0_SHIFT,
+	rk_clrsetreg(&grf->gpio2a_iomux, GPIO2A0_MASK,
 		     GPIO2A0_SPI_CLK << GPIO2A0_SHIFT);
 }
 
@@ -106,10 +99,8 @@
 	switch (uart_id) {
 	case PERIPH_ID_UART0:
 		rk_clrsetreg(&grf->gpio0c_iomux,
-			     GPIO0C3_MASK << GPIO0C3_SHIFT |
-			     GPIO0C2_MASK << GPIO0C2_SHIFT |
-			     GPIO0C1_MASK << GPIO0C1_SHIFT |
-			     GPIO0C0_MASK << GPIO0C0_SHIFT,
+			     GPIO0C3_MASK | GPIO0C2_MASK |
+			     GPIO0C1_MASK |  GPIO0C0_MASK,
 			     GPIO0C3_UART0_CTSN << GPIO0C3_SHIFT |
 			     GPIO0C2_UART0_RTSN << GPIO0C2_SHIFT |
 			     GPIO0C1_UART0_SIN << GPIO0C1_SHIFT |
@@ -117,15 +108,13 @@
 		break;
 	case PERIPH_ID_UART1:
 		rk_clrsetreg(&grf->gpio2c_iomux,
-			     GPIO2C7_MASK << GPIO2C7_SHIFT |
-			     GPIO2C6_MASK << GPIO2C6_SHIFT,
+			     GPIO2C7_MASK | GPIO2C6_MASK,
 			     GPIO2C7_UART1_SOUT << GPIO2C7_SHIFT |
 			     GPIO2C6_UART1_SIN << GPIO2C6_SHIFT);
 		break;
 	case PERIPH_ID_UART2:
 		rk_clrsetreg(&grf->gpio1c_iomux,
-			     GPIO1C3_MASK << GPIO1C3_SHIFT |
-			     GPIO1C2_MASK << GPIO1C2_SHIFT,
+			     GPIO1C3_MASK | GPIO1C2_MASK,
 			     GPIO1C3_UART2_SOUT << GPIO1C3_SHIFT |
 			     GPIO1C2_UART2_SIN << GPIO1C2_SHIFT);
 		break;
@@ -146,8 +135,7 @@
 			     GPIO1D1_EMMC_D1 << GPIO1D1_SHIFT |
 			     GPIO1D0_EMMC_D0 << GPIO1D0_SHIFT);
 		rk_clrsetreg(&grf->gpio2a_iomux,
-			     GPIO2A4_MASK << GPIO2A4_SHIFT |
-			     GPIO2A1_MASK << GPIO2A1_SHIFT,
+			     GPIO2A4_MASK | GPIO2A1_MASK,
 			     GPIO2A4_EMMC_CMD << GPIO2A4_SHIFT |
 			     GPIO2A1_EMMC_CLKOUT << GPIO2A1_SHIFT);
 		break;
diff --git a/drivers/pinctrl/rockchip/pinctrl_rk3328.c b/drivers/pinctrl/rockchip/pinctrl_rk3328.c
index b6beec5..d0ffeb1 100644
--- a/drivers/pinctrl/rockchip/pinctrl_rk3328.c
+++ b/drivers/pinctrl/rockchip/pinctrl_rk3328.c
@@ -21,135 +21,28 @@
 	struct rk3328_grf_regs *grf;
 };
 
-enum {
-	/* GRF_GPIO0A_IOMUX */
-	GRF_GPIO0A5_SEL_SHIFT	= 10,
-	GRF_GPIO0A5_SEL_MASK	= 3 << GRF_GPIO0A5_SEL_SHIFT,
-	GRF_I2C3_SCL		= 2,
-
-	GRF_GPIO0A6_SEL_SHIFT	= 12,
-	GRF_GPIO0A6_SEL_MASK	= 3 << GRF_GPIO0A6_SEL_SHIFT,
-	GRF_I2C3_SDA		= 2,
-
-	GRF_GPIO0A7_SEL_SHIFT	= 14,
-	GRF_GPIO0A7_SEL_MASK	= 3 << GRF_GPIO0A7_SEL_SHIFT,
-	GRF_EMMC_DATA0		= 2,
-
-	/* GRF_GPIO1A_IOMUX */
-	GRF_GPIO1A0_SEL_SHIFT	= 0,
-	GRF_GPIO1A0_SEL_MASK	= 0x3fff << GRF_GPIO1A0_SEL_SHIFT,
-	GRF_CARD_DATA_CLK_CMD_DETN	= 0x1555,
-
-	/* GRF_GPIO2A_IOMUX */
-	GRF_GPIO2A0_SEL_SHIFT	= 0,
-	GRF_GPIO2A0_SEL_MASK	= 3 << GRF_GPIO2A0_SEL_SHIFT,
-	GRF_UART2_TX_M1		= 1,
-
-	GRF_GPIO2A1_SEL_SHIFT	= 2,
-	GRF_GPIO2A1_SEL_MASK	= 3 << GRF_GPIO2A1_SEL_SHIFT,
-	GRF_UART2_RX_M1		= 1,
-
-	GRF_GPIO2A2_SEL_SHIFT	= 4,
-	GRF_GPIO2A2_SEL_MASK	= 3 << GRF_GPIO2A2_SEL_SHIFT,
-	GRF_PWM_IR		= 1,
-
-	GRF_GPIO2A4_SEL_SHIFT	= 8,
-	GRF_GPIO2A4_SEL_MASK	= 3 << GRF_GPIO2A4_SEL_SHIFT,
-	GRF_PWM_0		= 1,
-	GRF_I2C1_SDA,
-
-	GRF_GPIO2A5_SEL_SHIFT	= 10,
-	GRF_GPIO2A5_SEL_MASK	= 3 << GRF_GPIO2A5_SEL_SHIFT,
-	GRF_PWM_1		= 1,
-	GRF_I2C1_SCL,
-
-	GRF_GPIO2A6_SEL_SHIFT	= 12,
-	GRF_GPIO2A6_SEL_MASK	= 3 << GRF_GPIO2A6_SEL_SHIFT,
-	GRF_PWM_2		= 1,
-
-	GRF_GPIO2A7_SEL_SHIFT	= 14,
-	GRF_GPIO2A7_SEL_MASK	= 3 << GRF_GPIO2A7_SEL_SHIFT,
-	GRF_CARD_PWR_EN_M0	= 1,
-
-	/* GRF_GPIO2BL_IOMUX */
-	GRF_GPIO2BL0_SEL_SHIFT	= 0,
-	GRF_GPIO2BL0_SEL_MASK	= 0x3f << GRF_GPIO2BL0_SEL_SHIFT,
-	GRF_SPI_CLK_TX_RX_M0	= 0x15,
-
-	GRF_GPIO2BL3_SEL_SHIFT	= 6,
-	GRF_GPIO2BL3_SEL_MASK	= 3 << GRF_GPIO2BL3_SEL_SHIFT,
-	GRF_SPI_CSN0_M0		= 1,
-
-	GRF_GPIO2BL4_SEL_SHIFT	= 8,
-	GRF_GPIO2BL4_SEL_MASK	= 3 << GRF_GPIO2BL4_SEL_SHIFT,
-	GRF_SPI_CSN1_M0		= 1,
-
-	GRF_GPIO2BL5_SEL_SHIFT	= 10,
-	GRF_GPIO2BL5_SEL_MASK	= 3 << GRF_GPIO2BL5_SEL_SHIFT,
-	GRF_I2C2_SDA		= 1,
-
-	GRF_GPIO2BL6_SEL_SHIFT	= 12,
-	GRF_GPIO2BL6_SEL_MASK	= 3 << GRF_GPIO2BL6_SEL_SHIFT,
-	GRF_I2C2_SCL		= 1,
-
-	/* GRF_GPIO2D_IOMUX */
-	GRF_GPIO2D0_SEL_SHIFT	= 0,
-	GRF_GPIO2D0_SEL_MASK	= 3 << GRF_GPIO2D0_SEL_SHIFT,
-	GRF_I2C0_SCL		= 1,
-
-	GRF_GPIO2D1_SEL_SHIFT	= 2,
-	GRF_GPIO2D1_SEL_MASK	= 3 << GRF_GPIO2D1_SEL_SHIFT,
-	GRF_I2C0_SDA		= 1,
-
-	GRF_GPIO2D4_SEL_SHIFT	= 8,
-	GRF_GPIO2D4_SEL_MASK	= 0xff << GRF_GPIO2D4_SEL_SHIFT,
-	GRF_EMMC_DATA123	= 0xaa,
-
-	/* GRF_GPIO3C_IOMUX */
-	GRF_GPIO3C0_SEL_SHIFT	= 0,
-	GRF_GPIO3C0_SEL_MASK	= 0x3fff << GRF_GPIO3C0_SEL_SHIFT,
-	GRF_EMMC_DATA567_PWR_CLK_RSTN_CMD	= 0x2aaa,
-
-	/* GRF_COM_IOMUX */
-	GRF_UART2_IOMUX_SEL_SHIFT	= 0,
-	GRF_UART2_IOMUX_SEL_MASK	= 3 << GRF_UART2_IOMUX_SEL_SHIFT,
-	GRF_UART2_IOMUX_SEL_M0		= 0,
-	GRF_UART2_IOMUX_SEL_M1,
-
-	GRF_SPI_IOMUX_SEL_SHIFT = 4,
-	GRF_SPI_IOMUX_SEL_MASK	= 3 << GRF_SPI_IOMUX_SEL_SHIFT,
-	GRF_SPI_IOMUX_SEL_M0	= 0,
-	GRF_SPI_IOMUX_SEL_M1,
-	GRF_SPI_IOMUX_SEL_M2,
-
-	GRF_CARD_IOMUX_SEL_SHIFT	= 7,
-	GRF_CARD_IOMUX_SEL_MASK		= 1 << GRF_CARD_IOMUX_SEL_SHIFT,
-	GRF_CARD_IOMUX_SEL_M0		= 0,
-	GRF_CARD_IOMUX_SEL_M1,
-};
-
 static void pinctrl_rk3328_pwm_config(struct rk3328_grf_regs *grf, int pwm_id)
 {
 	switch (pwm_id) {
 	case PERIPH_ID_PWM0:
 		rk_clrsetreg(&grf->gpio2a_iomux,
-			     GRF_GPIO2A4_SEL_MASK,
-			     GRF_PWM_0 << GRF_GPIO2A4_SEL_SHIFT);
+			     GPIO2A4_SEL_MASK,
+			     GPIO2A4_PWM_0 << GPIO2A4_SEL_SHIFT);
 		break;
 	case PERIPH_ID_PWM1:
 		rk_clrsetreg(&grf->gpio2a_iomux,
-			     GRF_GPIO2A5_SEL_MASK,
-			     GRF_PWM_1 << GRF_GPIO2A5_SEL_SHIFT);
+			     GPIO2A5_SEL_MASK,
+			     GPIO2A5_PWM_1 << GPIO2A5_SEL_SHIFT);
 		break;
 	case PERIPH_ID_PWM2:
 		rk_clrsetreg(&grf->gpio2a_iomux,
-			     GRF_GPIO2A6_SEL_MASK,
-			     GRF_PWM_2 << GRF_GPIO2A6_SEL_SHIFT);
+			     GPIO2A6_SEL_MASK,
+			     GPIO2A6_PWM_2 << GPIO2A6_SEL_SHIFT);
 		break;
 	case PERIPH_ID_PWM3:
 		rk_clrsetreg(&grf->gpio2a_iomux,
-			     GRF_GPIO2A2_SEL_MASK,
-			     GRF_PWM_IR << GRF_GPIO2A2_SEL_SHIFT);
+			     GPIO2A2_SEL_MASK,
+			     GPIO2A2_PWM_IR << GPIO2A2_SEL_SHIFT);
 		break;
 	default:
 		debug("pwm id = %d iomux error!\n", pwm_id);
@@ -162,27 +55,27 @@
 	switch (i2c_id) {
 	case PERIPH_ID_I2C0:
 		rk_clrsetreg(&grf->gpio2d_iomux,
-			     GRF_GPIO2D0_SEL_MASK | GRF_GPIO2D1_SEL_MASK,
-			     GRF_I2C0_SCL << GRF_GPIO2D0_SEL_SHIFT
-			     | GRF_I2C0_SDA << GRF_GPIO2D1_SEL_SHIFT);
+			     GPIO2D0_SEL_MASK | GPIO2D1_SEL_MASK,
+			     GPIO2D0_I2C0_SCL << GPIO2D0_SEL_SHIFT |
+			     GPIO2D1_I2C0_SDA << GPIO2D1_SEL_SHIFT);
 		break;
 	case PERIPH_ID_I2C1:
 		rk_clrsetreg(&grf->gpio2a_iomux,
-			     GRF_GPIO2A4_SEL_MASK | GRF_GPIO2A5_SEL_MASK,
-			     GRF_I2C1_SCL << GRF_GPIO2A5_SEL_SHIFT
-			     | GRF_I2C1_SDA << GRF_GPIO2A4_SEL_SHIFT);
+			     GPIO2A4_SEL_MASK | GPIO2A5_SEL_MASK,
+			     GPIO2A5_I2C1_SCL << GPIO2A5_SEL_SHIFT |
+			     GPIO2A4_I2C1_SDA << GPIO2A4_SEL_SHIFT);
 		break;
 	case PERIPH_ID_I2C2:
 		rk_clrsetreg(&grf->gpio2bl_iomux,
-			     GRF_GPIO2BL5_SEL_MASK | GRF_GPIO2BL6_SEL_MASK,
-			     GRF_I2C2_SCL << GRF_GPIO2BL6_SEL_SHIFT
-			     | GRF_I2C2_SDA << GRF_GPIO2BL6_SEL_SHIFT);
+			     GPIO2BL5_SEL_MASK | GPIO2BL6_SEL_MASK,
+			     GPIO2BL6_I2C2_SCL << GPIO2BL6_SEL_SHIFT |
+			     GPIO2BL5_I2C2_SDA << GPIO2BL5_SEL_SHIFT);
 		break;
 	case PERIPH_ID_I2C3:
 		rk_clrsetreg(&grf->gpio0a_iomux,
-			     GRF_GPIO0A5_SEL_MASK | GRF_GPIO0A6_SEL_MASK,
-			     GRF_I2C3_SCL << GRF_GPIO0A5_SEL_SHIFT
-			     | GRF_I2C3_SDA << GRF_GPIO0A6_SEL_SHIFT);
+			     GPIO0A5_SEL_MASK | GPIO0A6_SEL_MASK,
+			     GPIO0A5_I2C3_SCL << GPIO0A5_SEL_SHIFT |
+			     GPIO0A6_I2C3_SDA << GPIO0A6_SEL_SHIFT);
 		break;
 	default:
 		debug("i2c id = %d iomux error!\n", i2c_id);
@@ -204,29 +97,35 @@
 static int pinctrl_rk3328_spi_config(struct rk3328_grf_regs *grf,
 				     enum periph_id spi_id, int cs)
 {
-	rk_clrsetreg(&grf->com_iomux,
-		     GRF_SPI_IOMUX_SEL_MASK,
-		     GRF_SPI_IOMUX_SEL_M0 << GRF_SPI_IOMUX_SEL_SHIFT);
+	u32 com_iomux = readl(&grf->com_iomux);
+
+	if ((com_iomux & IOMUX_SEL_SPI_MASK) !=
+		IOMUX_SEL_SPI_M0 << IOMUX_SEL_SPI_SHIFT) {
+		debug("driver do not support iomux other than m0\n");
+		goto err;
+	}
 
 	switch (spi_id) {
 	case PERIPH_ID_SPI0:
 		switch (cs) {
 		case 0:
 			rk_clrsetreg(&grf->gpio2bl_iomux,
-				     GRF_GPIO2BL3_SEL_MASK,
-				     GRF_SPI_CSN0_M0 << GRF_GPIO2BL3_SEL_SHIFT);
+				     GPIO2BL3_SEL_MASK,
+				     GPIO2BL3_SPI_CSN0_M0
+				     << GPIO2BL3_SEL_SHIFT);
 			break;
 		case 1:
 			rk_clrsetreg(&grf->gpio2bl_iomux,
-				     GRF_GPIO2BL4_SEL_MASK,
-				     GRF_SPI_CSN1_M0 << GRF_GPIO2BL4_SEL_SHIFT);
+				     GPIO2BL4_SEL_MASK,
+				     GPIO2BL4_SPI_CSN1_M0
+				     << GPIO2BL4_SEL_SHIFT);
 			break;
 		default:
 			goto err;
 		}
 		rk_clrsetreg(&grf->gpio2bl_iomux,
-			     GRF_GPIO2BL0_SEL_MASK,
-			     GRF_SPI_CLK_TX_RX_M0 << GRF_GPIO2BL0_SEL_SHIFT);
+			     GPIO2BL0_SEL_MASK,
+			     GPIO2BL0_SPI_CLK_TX_RX_M0 << GPIO2BL0_SEL_SHIFT);
 		break;
 	default:
 		goto err;
@@ -240,18 +139,17 @@
 
 static void pinctrl_rk3328_uart_config(struct rk3328_grf_regs *grf, int uart_id)
 {
+	u32 com_iomux = readl(&grf->com_iomux);
+
 	switch (uart_id) {
 	case PERIPH_ID_UART2:
 		break;
-		/* uart2 iomux select m1 */
-		rk_clrsetreg(&grf->com_iomux,
-			     GRF_UART2_IOMUX_SEL_MASK,
-			     GRF_UART2_IOMUX_SEL_M1
-			     << GRF_UART2_IOMUX_SEL_SHIFT);
-		rk_clrsetreg(&grf->gpio2a_iomux,
-			     GRF_GPIO2A0_SEL_MASK | GRF_GPIO2A1_SEL_MASK,
-			     GRF_UART2_TX_M1 << GRF_GPIO2A0_SEL_SHIFT |
-			     GRF_UART2_RX_M1 << GRF_GPIO2A1_SEL_SHIFT);
+		if (com_iomux & IOMUX_SEL_UART2_MASK)
+			rk_clrsetreg(&grf->gpio2a_iomux,
+				     GPIO2A0_SEL_MASK | GPIO2A1_SEL_MASK,
+				     GPIO2A0_UART2_TX_M1 << GPIO2A0_SEL_SHIFT |
+				     GPIO2A1_UART2_RX_M1 << GPIO2A1_SEL_SHIFT);
+
 		break;
 	case PERIPH_ID_UART0:
 	case PERIPH_ID_UART1:
@@ -266,31 +164,37 @@
 static void pinctrl_rk3328_sdmmc_config(struct rk3328_grf_regs *grf,
 					int mmc_id)
 {
+	u32 com_iomux = readl(&grf->com_iomux);
+
 	switch (mmc_id) {
 	case PERIPH_ID_EMMC:
 		rk_clrsetreg(&grf->gpio0a_iomux,
-			     GRF_GPIO0A7_SEL_MASK,
-			     GRF_EMMC_DATA0 << GRF_GPIO0A7_SEL_SHIFT);
+			     GPIO0A7_SEL_MASK,
+			     GPIO0A7_EMMC_DATA0 << GPIO0A7_SEL_SHIFT);
 		rk_clrsetreg(&grf->gpio2d_iomux,
-			     GRF_GPIO2D4_SEL_MASK,
-			     GRF_EMMC_DATA123 << GRF_GPIO2D4_SEL_SHIFT);
+			     GPIO2D4_SEL_MASK,
+			     GPIO2D4_EMMC_DATA1234 << GPIO2D4_SEL_SHIFT);
 		rk_clrsetreg(&grf->gpio3c_iomux,
-			     GRF_GPIO3C0_SEL_MASK,
-			     GRF_EMMC_DATA567_PWR_CLK_RSTN_CMD
-			     << GRF_GPIO3C0_SEL_SHIFT);
+			     GPIO3C0_SEL_MASK,
+			     GPIO3C0_EMMC_DATA567_PWR_CLK_RSTN_CMD
+			     << GPIO3C0_SEL_SHIFT);
 		break;
 	case PERIPH_ID_SDCARD:
-		/* sdcard iomux select m0 */
-		rk_clrsetreg(&grf->com_iomux,
-			     GRF_CARD_IOMUX_SEL_MASK,
-			     GRF_CARD_IOMUX_SEL_M0 << GRF_CARD_IOMUX_SEL_SHIFT);
-		rk_clrsetreg(&grf->gpio2a_iomux,
-			     GRF_GPIO2A7_SEL_MASK,
-			     GRF_CARD_PWR_EN_M0 << GRF_GPIO2A7_SEL_SHIFT);
+		/* SDMMC_PWREN use GPIO and init as regulator-fiexed  */
+		if (com_iomux & IOMUX_SEL_SDMMC_MASK)
+			rk_clrsetreg(&grf->gpio0d_iomux,
+				     GPIO0D6_SEL_MASK,
+				     GPIO0D6_SDMMC0_PWRENM1
+				     << GPIO0D6_SEL_SHIFT);
+		else
+			rk_clrsetreg(&grf->gpio2a_iomux,
+				     GPIO2A7_SEL_MASK,
+				     GPIO2A7_SDMMC0_PWRENM0
+				     << GPIO2A7_SEL_SHIFT);
 		rk_clrsetreg(&grf->gpio1a_iomux,
-			     GRF_GPIO1A0_SEL_MASK,
-			     GRF_CARD_DATA_CLK_CMD_DETN
-			     << GRF_GPIO1A0_SEL_SHIFT);
+			     GPIO1A0_SEL_MASK,
+			     GPIO1A0_CARD_DATA_CLK_CMD_DETN
+			     << GPIO1A0_SEL_SHIFT);
 		break;
 	default:
 		debug("mmc id = %d iomux error!\n", mmc_id);
diff --git a/drivers/pinctrl/rockchip/pinctrl_rk3368.c b/drivers/pinctrl/rockchip/pinctrl_rk3368.c
new file mode 100644
index 0000000..bdf0758
--- /dev/null
+++ b/drivers/pinctrl/rockchip/pinctrl_rk3368.c
@@ -0,0 +1,149 @@
+/*
+ * (C) Copyright 2017 Rockchip Electronics Co., Ltd
+ * Author: Andy Yan <andy.yan@rock-chips.com>
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <syscon.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/grf_rk3368.h>
+#include <asm/arch/periph.h>
+#include <dm/pinctrl.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct rk3368_pinctrl_priv {
+	struct rk3368_grf *grf;
+	struct rk3368_pmu_grf *pmugrf;
+};
+
+static void pinctrl_rk3368_uart_config(struct rk3368_pinctrl_priv *priv,
+				       int uart_id)
+{
+	struct rk3368_grf *grf = priv->grf;
+	struct rk3368_pmu_grf *pmugrf = priv->pmugrf;
+
+	switch (uart_id) {
+	case PERIPH_ID_UART2:
+		rk_clrsetreg(&grf->gpio2a_iomux,
+			     GPIO2A6_MASK | GPIO2A5_MASK,
+			     GPIO2A6_UART2_SIN << GPIO2A6_SHIFT |
+			     GPIO2A5_UART2_SOUT << GPIO2A5_SHIFT);
+		break;
+	case PERIPH_ID_UART0:
+		break;
+	case PERIPH_ID_UART1:
+		break;
+	case PERIPH_ID_UART3:
+		break;
+	case PERIPH_ID_UART4:
+		rk_clrsetreg(&pmugrf->gpio0d_iomux,
+			     GPIO0D0_MASK | GPIO0D1_MASK |
+			     GPIO0D2_MASK | GPIO0D3_MASK,
+			     GPIO0D0_GPIO << GPIO0D0_SHIFT |
+			     GPIO0D1_GPIO << GPIO0D1_SHIFT |
+			     GPIO0D2_UART4_SOUT << GPIO0D2_SHIFT |
+			     GPIO0D3_UART4_SIN << GPIO0D3_SHIFT);
+		break;
+	default:
+		debug("uart id = %d iomux error!\n", uart_id);
+		break;
+	}
+}
+
+static int rk3368_pinctrl_request(struct udevice *dev, int func, int flags)
+{
+	struct rk3368_pinctrl_priv *priv = dev_get_priv(dev);
+
+	debug("%s: func=%d, flags=%x\n", __func__, func, flags);
+	switch (func) {
+	case PERIPH_ID_UART0:
+	case PERIPH_ID_UART1:
+	case PERIPH_ID_UART2:
+	case PERIPH_ID_UART3:
+	case PERIPH_ID_UART4:
+		pinctrl_rk3368_uart_config(priv, func);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int rk3368_pinctrl_get_periph_id(struct udevice *dev,
+					struct udevice *periph)
+{
+	u32 cell[3];
+	int ret;
+
+	ret = fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(periph),
+				   "interrupts", cell, ARRAY_SIZE(cell));
+	if (ret < 0)
+		return -EINVAL;
+
+	switch (cell[1]) {
+	case 59:
+		return PERIPH_ID_UART4;
+	case 58:
+		return PERIPH_ID_UART3;
+	case 57:
+		return PERIPH_ID_UART2;
+	case 56:
+		return PERIPH_ID_UART1;
+	case 55:
+		return PERIPH_ID_UART0;
+	}
+
+	return -ENOENT;
+}
+
+static int rk3368_pinctrl_set_state_simple(struct udevice *dev,
+					   struct udevice *periph)
+{
+	int func;
+
+	func = rk3368_pinctrl_get_periph_id(dev, periph);
+	if (func < 0)
+		return func;
+
+	return rk3368_pinctrl_request(dev, func, 0);
+}
+
+static struct pinctrl_ops rk3368_pinctrl_ops = {
+	.set_state_simple	= rk3368_pinctrl_set_state_simple,
+	.request	= rk3368_pinctrl_request,
+	.get_periph_id	= rk3368_pinctrl_get_periph_id,
+};
+
+static int rk3368_pinctrl_probe(struct udevice *dev)
+{
+	struct rk3368_pinctrl_priv *priv = dev_get_priv(dev);
+	int ret = 0;
+
+	priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+	priv->pmugrf = syscon_get_first_range(ROCKCHIP_SYSCON_PMUGRF);
+
+	debug("%s: grf=%p pmugrf:%p\n", __func__, priv->grf, priv->pmugrf);
+
+	return ret;
+}
+
+static const struct udevice_id rk3368_pinctrl_ids[] = {
+	{ .compatible = "rockchip,rk3368-pinctrl" },
+	{ }
+};
+
+U_BOOT_DRIVER(pinctrl_rk3368) = {
+	.name		= "rockchip_rk3368_pinctrl",
+	.id		= UCLASS_PINCTRL,
+	.of_match	= rk3368_pinctrl_ids,
+	.priv_auto_alloc_size = sizeof(struct rk3368_pinctrl_priv),
+	.ops		= &rk3368_pinctrl_ops,
+	.bind		= dm_scan_fdt_dev,
+	.probe		= rk3368_pinctrl_probe,
+};
diff --git a/drivers/pinctrl/rockchip/pinctrl_rv1108.c b/drivers/pinctrl/rockchip/pinctrl_rv1108.c
new file mode 100644
index 0000000..bdf3910
--- /dev/null
+++ b/drivers/pinctrl/rockchip/pinctrl_rv1108.c
@@ -0,0 +1,184 @@
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ * Author: Andy Yan <andy.yan@rock-chips.com>
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <syscon.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/grf_rv1108.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/periph.h>
+#include <dm/pinctrl.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct rv1108_pinctrl_priv {
+	struct rv1108_grf *grf;
+};
+
+static void pinctrl_rv1108_uart_config(struct rv1108_grf *grf, int uart_id)
+{
+	switch (uart_id) {
+	case PERIPH_ID_UART0:
+		rk_clrsetreg(&grf->gpio3a_iomux,
+			     GPIO3A6_MASK | GPIO3A5_MASK,
+			     GPIO3A6_UART1_SOUT << GPIO3A6_SHIFT |
+			     GPIO3A5_UART1_SIN << GPIO3A5_SHIFT);
+		break;
+	case PERIPH_ID_UART1:
+		rk_clrsetreg(&grf->gpio1d_iomux,
+			     GPIO1D3_MASK | GPIO1D2_MASK | GPIO1D1_MASK |
+			     GPIO1D0_MASK,
+			     GPIO1D3_UART0_SOUT << GPIO1D3_SHIFT |
+			     GPIO1D2_UART0_SIN << GPIO1D2_SHIFT |
+			     GPIO1D1_UART0_RTSN << GPIO1D1_SHIFT |
+			     GPIO1D0_UART0_CTSN << GPIO1D0_SHIFT);
+		break;
+	case PERIPH_ID_UART2:
+		rk_clrsetreg(&grf->gpio2d_iomux,
+			     GPIO2D2_MASK | GPIO2D1_MASK,
+			     GPIO2D2_UART2_SOUT_M0 << GPIO2D2_SHIFT |
+			     GPIO2D1_UART2_SIN_M0 << GPIO2D1_SHIFT);
+		break;
+	}
+}
+
+static void pinctrl_rv1108_gmac_config(struct rv1108_grf *grf, int func)
+{
+	rk_clrsetreg(&grf->gpio1b_iomux,
+		     GPIO1B7_MASK | GPIO1B6_MASK | GPIO1B5_MASK |
+		     GPIO1B4_MASK | GPIO1B3_MASK | GPIO1B2_MASK,
+		     GPIO1B7_GMAC_RXDV << GPIO1B7_SHIFT |
+		     GPIO1B6_GMAC_RXD1 << GPIO1B6_SHIFT |
+		     GPIO1B5_GMAC_RXD0 << GPIO1B5_SHIFT |
+		     GPIO1B4_GMAC_TXEN << GPIO1B4_SHIFT |
+		     GPIO1B3_GMAC_TXD1 << GPIO1B3_SHIFT |
+		     GPIO1B2_GMAC_TXD0 << GPIO1B2_SHIFT);
+	rk_clrsetreg(&grf->gpio1c_iomux,
+		     GPIO1C5_MASK | GPIO1C4_MASK |
+		     GPIO1C3_MASK | GPIO1C2_MASK,
+		     GPIO1C5_GMAC_CLK << GPIO1C5_SHIFT |
+		     GPIO1C4_GMAC_MDC << GPIO1C4_SHIFT |
+		     GPIO1C3_GMAC_MDIO << GPIO1C3_SHIFT |
+		     GPIO1C2_GMAC_RXER << GPIO1C2_SHIFT);
+	writel(0xffff57f5, &grf->gpio1b_drv);
+}
+
+static void pinctrl_rv1108_sfc_config(struct rv1108_grf *grf)
+{
+	rk_clrsetreg(&grf->gpio2a_iomux, GPIO2A3_MASK | GPIO2A2_MASK |
+		     GPIO2A1_MASK | GPIO2A0_MASK,
+		     GPIO2A3_SFC_HOLD_IO3 << GPIO2A3_SHIFT |
+		     GPIO2A2_SFC_WP_IO2 << GPIO2A2_SHIFT |
+		     GPIO2A1_SFC_SO_IO1 << GPIO2A1_SHIFT |
+		     GPIO2A0_SFC_SI_IO0 << GPIO2A0_SHIFT);
+	rk_clrsetreg(&grf->gpio2b_iomux, GPIO2B7_MASK | GPIO2B4_MASK,
+		     GPIO2B7_SFC_CLK << GPIO2B7_SHIFT |
+		     GPIO2B4_SFC_CSN0 << GPIO2B4_SHIFT);
+}
+
+static int rv1108_pinctrl_request(struct udevice *dev, int func, int flags)
+{
+	struct rv1108_pinctrl_priv *priv = dev_get_priv(dev);
+
+	switch (func) {
+	case PERIPH_ID_UART0:
+	case PERIPH_ID_UART1:
+	case PERIPH_ID_UART2:
+		pinctrl_rv1108_uart_config(priv->grf, func);
+		break;
+	case PERIPH_ID_GMAC:
+		pinctrl_rv1108_gmac_config(priv->grf, func);
+	case PERIPH_ID_SFC:
+		pinctrl_rv1108_sfc_config(priv->grf);
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int rv1108_pinctrl_get_periph_id(struct udevice *dev,
+					struct udevice *periph)
+{
+	u32 cell[3];
+	int ret;
+
+	ret = fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(periph),
+				   "interrupts", cell, ARRAY_SIZE(cell));
+	if (ret < 0)
+		return -EINVAL;
+
+	switch (cell[1]) {
+	case 11:
+		return PERIPH_ID_SDCARD;
+	case 13:
+		return PERIPH_ID_EMMC;
+	case 19:
+		return PERIPH_ID_GMAC;
+	case 30:
+		return PERIPH_ID_I2C0;
+	case 31:
+		return PERIPH_ID_I2C1;
+	case 32:
+		return PERIPH_ID_I2C2;
+	case 39:
+		return PERIPH_ID_PWM0;
+	case 44:
+		return PERIPH_ID_UART0;
+	case 45:
+		return PERIPH_ID_UART1;
+	case 46:
+		return PERIPH_ID_UART2;
+	case 56:
+		return PERIPH_ID_SFC;
+	}
+
+	return -ENOENT;
+}
+
+static int rv1108_pinctrl_set_state_simple(struct udevice *dev,
+					   struct udevice *periph)
+{
+	int func;
+
+	func = rv1108_pinctrl_get_periph_id(dev, periph);
+	if (func < 0)
+		return func;
+
+	return rv1108_pinctrl_request(dev, func, 0);
+}
+
+static struct pinctrl_ops rv1108_pinctrl_ops = {
+	.set_state_simple	= rv1108_pinctrl_set_state_simple,
+	.request		= rv1108_pinctrl_request,
+	.get_periph_id		= rv1108_pinctrl_get_periph_id,
+};
+
+static int rv1108_pinctrl_probe(struct udevice *dev)
+{
+	struct rv1108_pinctrl_priv *priv = dev_get_priv(dev);
+
+	priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+
+	return 0;
+}
+
+static const struct udevice_id rv1108_pinctrl_ids[] = {
+	{.compatible = "rockchip,rv1108-pinctrl" },
+	{ }
+};
+
+U_BOOT_DRIVER(pinctrl_rv1108) = {
+	.name           = "pinctrl_rv1108",
+	.id             = UCLASS_PINCTRL,
+	.of_match       = rv1108_pinctrl_ids,
+	.priv_auto_alloc_size = sizeof(struct rv1108_pinctrl_priv),
+	.ops            = &rv1108_pinctrl_ops,
+	.bind           = dm_scan_fdt_dev,
+	.probe          = rv1108_pinctrl_probe,
+};
diff --git a/drivers/power/pmic/rk8xx.c b/drivers/power/pmic/rk8xx.c
index 09b9b54..eb3ec0f 100644
--- a/drivers/power/pmic/rk8xx.c
+++ b/drivers/power/pmic/rk8xx.c
@@ -111,6 +111,7 @@
 #if CONFIG_IS_ENABLED(PMIC_CHILDREN)
 	.bind = rk8xx_bind,
 #endif
+	.priv_auto_alloc_size   = sizeof(struct rk8xx_priv),
 	.probe = rk8xx_probe,
 	.ops = &rk8xx_ops,
 };
diff --git a/drivers/power/regulator/pwm_regulator.c b/drivers/power/regulator/pwm_regulator.c
index a6c9fcc..00a7cca 100644
--- a/drivers/power/regulator/pwm_regulator.c
+++ b/drivers/power/regulator/pwm_regulator.c
@@ -32,13 +32,13 @@
 	bool polarity;
 	struct udevice *pwm;
 	/* initialize voltage of regulator */
-	unsigned int init_voltage;
+	int init_voltage;
 	/* the maximum voltage of regulator */
-	unsigned int max_voltage;
+	int max_voltage;
 	/* the minimum voltage of regulator */
-	unsigned int min_voltage;
+	int min_voltage;
 	/* the current voltage of regulator */
-	unsigned int volt_uV;
+	int volt_uV;
 };
 
 static int pwm_regulator_enable(struct udevice *dev, bool enable)
diff --git a/drivers/power/regulator/rk8xx.c b/drivers/power/regulator/rk8xx.c
index e655c2d..c1ece96 100644
--- a/drivers/power/regulator/rk8xx.c
+++ b/drivers/power/regulator/rk8xx.c
@@ -92,9 +92,9 @@
 	struct rk8xx_priv *priv = dev_get_priv(pmic);
 	switch (priv->variant) {
 	case RK818_ID:
-		return &rk818_ldo[num - 1];
+		return &rk818_ldo[num];
 	default:
-		return &rk808_ldo[num - 1];
+		return &rk808_ldo[num];
 	}
 }
 
diff --git a/drivers/sysreset/Makefile b/drivers/sysreset/Makefile
index b683811..a5200d3 100644
--- a/drivers/sysreset/Makefile
+++ b/drivers/sysreset/Makefile
@@ -15,7 +15,9 @@
 obj-$(CONFIG_ROCKCHIP_RK3188) += sysreset_rk3188.o
 obj-$(CONFIG_ROCKCHIP_RK3288) += sysreset_rk3288.o
 obj-$(CONFIG_ROCKCHIP_RK3328) += sysreset_rk3328.o
+obj-$(CONFIG_ROCKCHIP_RK3368) += sysreset_rk3368.o
 obj-$(CONFIG_ROCKCHIP_RK3399) += sysreset_rk3399.o
+obj-$(CONFIG_ROCKCHIP_RV1108) += sysreset_rv1108.o
 obj-$(CONFIG_SANDBOX) += sysreset_sandbox.o
 obj-$(CONFIG_ARCH_SNAPDRAGON) += sysreset_snapdragon.o
 obj-$(CONFIG_ARCH_STI) += sysreset_sti.o
diff --git a/drivers/sysreset/sysreset_rk3368.c b/drivers/sysreset/sysreset_rk3368.c
new file mode 100644
index 0000000..de62921
--- /dev/null
+++ b/drivers/sysreset/sysreset_rk3368.c
@@ -0,0 +1,62 @@
+/*
+ * (C) Copyright Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <sysreset.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/cru_rk3368.h>
+#include <asm/arch/hardware.h>
+#include <linux/err.h>
+
+static void rk3368_pll_enter_slow_mode(struct rk3368_cru *cru)
+{
+	struct rk3368_pll *pll;
+	int i;
+
+	for (i = 0; i < 6; i++) {
+		pll = &cru->pll[i];
+		rk_clrreg(&pll->con3, PLL_MODE_MASK);
+	}
+}
+
+static int rk3368_sysreset_request(struct udevice *dev, enum sysreset_t type)
+{
+	struct rk3368_cru *cru = rockchip_get_cru();
+
+	if (IS_ERR(cru))
+		return PTR_ERR(cru);
+	switch (type) {
+	case SYSRESET_WARM:
+		rk3368_pll_enter_slow_mode(cru);
+		rk_clrsetreg(&cru->glb_rst_con, PMU_GLB_SRST_CTRL_MASK,
+			     PMU_RST_BY_SND_GLB_SRST << PMU_GLB_SRST_CTRL_SHIFT);
+		writel(0xeca8, &cru->glb_srst_snd_val);
+		break;
+	case SYSRESET_COLD:
+		rk3368_pll_enter_slow_mode(cru);
+		rk_clrsetreg(&cru->glb_rst_con, PMU_GLB_SRST_CTRL_MASK,
+			     PMU_RST_BY_FST_GLB_SRST << PMU_GLB_SRST_CTRL_SHIFT);
+		writel(0xfdb9, &cru->glb_srst_fst_val);
+		break;
+	default:
+		return -EPROTONOSUPPORT;
+	}
+
+	return -EINPROGRESS;
+}
+
+static struct sysreset_ops rk3368_sysreset = {
+	.request	= rk3368_sysreset_request,
+};
+
+U_BOOT_DRIVER(sysreset_rk3368) = {
+	.name	= "rk3368_sysreset",
+	.id	= UCLASS_SYSRESET,
+	.ops	= &rk3368_sysreset,
+};
diff --git a/drivers/sysreset/sysreset_rv1108.c b/drivers/sysreset/sysreset_rv1108.c
new file mode 100644
index 0000000..9d8e9f7
--- /dev/null
+++ b/drivers/sysreset/sysreset_rv1108.c
@@ -0,0 +1,46 @@
+/*
+ * (C) Copyright 2015 Rockchip Electronics Co., Ltd
+ * Author: Andy Yan <andy.yan@rock-chips.com>
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <sysreset.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/cru_rv1108.h>
+#include <asm/arch/hardware.h>
+#include <linux/err.h>
+
+int rv1108_sysreset_request(struct udevice *dev, enum sysreset_t type)
+{
+	struct rv1108_cru *cru = rockchip_get_cru();
+
+	if (IS_ERR(cru))
+		return PTR_ERR(cru);
+
+	switch (type) {
+	case SYSRESET_WARM:
+		writel(0xeca8, &cru->glb_srst_snd_val);
+		break;
+	case SYSRESET_COLD:
+		writel(0xfdb9, &cru->glb_srst_fst_val);
+		break;
+	default:
+		return -EPROTONOSUPPORT;
+	}
+
+	return -EINPROGRESS;
+}
+
+static struct sysreset_ops rv1108_sysreset = {
+	.request	= rv1108_sysreset_request,
+};
+
+U_BOOT_DRIVER(sysreset_rv1108) = {
+	.name	= "rv1108_sysreset",
+	.id	= UCLASS_SYSRESET,
+	.ops	= &rv1108_sysreset,
+};
diff --git a/drivers/usb/host/xhci-rockchip.c b/drivers/usb/host/xhci-rockchip.c
index 38e1c68..c4ae55f 100644
--- a/drivers/usb/host/xhci-rockchip.c
+++ b/drivers/usb/host/xhci-rockchip.c
@@ -11,10 +11,10 @@
 #include <malloc.h>
 #include <usb.h>
 #include <watchdog.h>
-#include <asm/gpio.h>
 #include <linux/errno.h>
 #include <linux/compat.h>
 #include <linux/usb/dwc3.h>
+#include <power/regulator.h>
 
 #include "xhci.h"
 
@@ -23,7 +23,7 @@
 struct rockchip_xhci_platdata {
 	fdt_addr_t hcd_base;
 	fdt_addr_t phy_base;
-	struct gpio_desc vbus_gpio;
+	struct udevice *vbus_supply;
 };
 
 /*
@@ -66,11 +66,13 @@
 		return -ENXIO;
 	}
 
-	/* Vbus gpio */
-	ret = gpio_request_by_name(dev, "rockchip,vbus-gpio", 0,
-				   &plat->vbus_gpio, GPIOD_IS_OUT);
+#if defined(CONFIG_DM_USB) && defined(CONFIG_DM_REGULATOR)
+	/* Vbus regulator */
+	ret = device_get_supply_regulator(dev, "vbus-supply",
+					  &plat->vbus_supply);
 	if (ret)
-		debug("rockchip,vbus-gpio node missing!");
+		debug("Can't get vbus supply\n");
+#endif
 
 	return 0;
 }
@@ -153,9 +155,11 @@
 	hcor = (struct xhci_hcor *)((uint64_t)ctx->hcd +
 			HC_LENGTH(xhci_readl(&ctx->hcd->cr_capbase)));
 
-	/* setup the Vbus gpio here */
-	if (dm_gpio_is_valid(&plat->vbus_gpio))
-		dm_gpio_set_value(&plat->vbus_gpio, 1);
+#if defined(CONFIG_DM_USB) && defined(CONFIG_DM_REGULATOR)
+	ret = regulator_set_enable(plat->vbus_supply, true);
+	if (ret)
+		debug("XHCI: Failed to enable vbus supply\n");
+#endif
 
 	ret = rockchip_xhci_core_init(ctx, dev);
 	if (ret) {
@@ -168,6 +172,7 @@
 
 static int xhci_usb_remove(struct udevice *dev)
 {
+	struct rockchip_xhci_platdata *plat = dev_get_platdata(dev);
 	struct rockchip_xhci *ctx = dev_get_priv(dev);
 	int ret;
 
@@ -178,11 +183,18 @@
 	if (ret)
 		return ret;
 
+#if defined(CONFIG_DM_USB) && defined(CONFIG_DM_REGULATOR)
+	ret = regulator_set_enable(plat->vbus_supply, false);
+	if (ret)
+		debug("XHCI: Failed to disable vbus supply\n");
+#endif
+
 	return 0;
 }
 
 static const struct udevice_id xhci_usb_ids[] = {
 	{ .compatible = "rockchip,rk3399-xhci" },
+	{ .compatible = "rockchip,rk3328-xhci" },
 	{ }
 };
 
@@ -202,6 +214,7 @@
 
 static const struct udevice_id usb_phy_ids[] = {
 	{ .compatible = "rockchip,rk3399-usb3-phy" },
+	{ .compatible = "rockchip,rk3328-usb3-phy" },
 	{ }
 };
 
diff --git a/drivers/video/rockchip/Kconfig b/drivers/video/rockchip/Kconfig
index 80e399f..b1d7c62 100644
--- a/drivers/video/rockchip/Kconfig
+++ b/drivers/video/rockchip/Kconfig
@@ -12,11 +12,30 @@
 	bool "Enable Rockchip Video Support"
 	depends on DM_VIDEO
 	help
-		Rockchip SoCs provide video output capabilities for High-Definition
-		Multimedia Interface (HDMI), Low-voltage Differential Signalling
-		(LVDS), embedded DisplayPort (eDP) and Display Serial Interface
-		(DSI). This driver supports the on-chip video output device, and
-		targets the Rockchip RK3288 and RK3399.
+	  Rockchip SoCs provide video output capabilities for High-Definition
+	  Multimedia Interface (HDMI), Low-voltage Differential Signalling
+	  (LVDS), embedded DisplayPort (eDP) and Display Serial Interface (DSI).
+
+	  This driver supports the on-chip video output device, and targets the
+	  Rockchip RK3288 and RK3399.
+
+config VIDEO_ROCKCHIP_MAX_XRES
+        int "Maximum horizontal resolution (for memory allocation purposes)"
+	depends on VIDEO_ROCKCHIP
+	default 1920
+	help
+	  The maximum horizontal resolution to support for the framebuffer.
+	  This configuration is used for reserving/allocating memory for the
+	  framebuffer during device-model binding/probing.
+
+config VIDEO_ROCKCHIP_MAX_YRES
+        int "Maximum vertical resolution (for memory allocation purposes)"
+	depends on VIDEO_ROCKCHIP
+	default 1080
+	help
+	  The maximum vertical resolution to support for the framebuffer.
+	  This configuration is used for reserving/allocating memory for the
+	  framebuffer during device-model binding/probing.
 
 if VIDEO_ROCKCHIP
 
diff --git a/drivers/video/rockchip/Makefile b/drivers/video/rockchip/Makefile
index cd54b12..872dc0f 100644
--- a/drivers/video/rockchip/Makefile
+++ b/drivers/video/rockchip/Makefile
@@ -7,8 +7,12 @@
 
 ifdef CONFIG_VIDEO_ROCKCHIP
 obj-y += rk_vop.o
+obj-$(CONFIG_ROCKCHIP_RK3288) += rk3288_vop.o
+obj-$(CONFIG_ROCKCHIP_RK3399) += rk3399_vop.o
 obj-$(CONFIG_DISPLAY_ROCKCHIP_EDP) += rk_edp.o
 obj-$(CONFIG_DISPLAY_ROCKCHIP_LVDS) += rk_lvds.o
-obj-$(CONFIG_DISPLAY_ROCKCHIP_HDMI) += rk_hdmi.o
+obj-hdmi-$(CONFIG_ROCKCHIP_RK3288) += rk3288_hdmi.o
+obj-hdmi-$(CONFIG_ROCKCHIP_RK3399) += rk3399_hdmi.o
+obj-$(CONFIG_DISPLAY_ROCKCHIP_HDMI) += rk_hdmi.o $(obj-hdmi-y)
 obj-$(CONFIG_DISPLAY_ROCKCHIP_MIPI) += rk_mipi.o
 endif
diff --git a/drivers/video/rockchip/rk3288_hdmi.c b/drivers/video/rockchip/rk3288_hdmi.c
new file mode 100644
index 0000000..eae0dd2
--- /dev/null
+++ b/drivers/video/rockchip/rk3288_hdmi.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2017 Theobroma Systems Design und Consulting GmbH
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <display.h>
+#include <dm.h>
+#include <dw_hdmi.h>
+#include <edid.h>
+#include <regmap.h>
+#include <syscon.h>
+#include <asm/gpio.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/grf_rk3288.h>
+#include <power/regulator.h>
+#include "rk_hdmi.h"
+
+static int rk3288_hdmi_enable(struct udevice *dev, int panel_bpp,
+			      const struct display_timing *edid)
+{
+	struct rk_hdmi_priv *priv = dev_get_priv(dev);
+	struct display_plat *uc_plat = dev_get_uclass_platdata(dev);
+	int vop_id = uc_plat->source_id;
+	struct rk3288_grf *grf = priv->grf;
+
+	/* hdmi source select hdmi controller */
+	rk_setreg(&grf->soc_con6, 1 << 15);
+
+	/* hdmi data from vop id */
+	rk_clrsetreg(&grf->soc_con6, 1 << 4, (vop_id == 1) ? (1 << 4) : 0);
+
+	return 0;
+}
+
+static int rk3288_hdmi_ofdata_to_platdata(struct udevice *dev)
+{
+	struct rk_hdmi_priv *priv = dev_get_priv(dev);
+	struct dw_hdmi *hdmi = &priv->hdmi;
+
+	hdmi->i2c_clk_high = 0x7a;
+	hdmi->i2c_clk_low = 0x8d;
+
+	/*
+	 * TODO(sjg@chromium.org): The above values don't work - these
+	 * ones work better, but generate lots of errors in the data.
+	 */
+	hdmi->i2c_clk_high = 0x0d;
+	hdmi->i2c_clk_low = 0x0d;
+
+	return rk_hdmi_ofdata_to_platdata(dev);
+}
+
+static int rk3288_clk_config(struct udevice *dev)
+{
+	struct display_plat *uc_plat = dev_get_uclass_platdata(dev);
+	struct clk clk;
+	int ret;
+
+	/*
+	 * Configure the maximum clock to permit whatever resolution the
+	 * monitor wants
+	 */
+	ret = clk_get_by_index(uc_plat->src_dev, 0, &clk);
+	if (ret >= 0) {
+		ret = clk_set_rate(&clk, 384000000);
+		clk_free(&clk);
+	}
+	if (ret < 0) {
+		debug("%s: Failed to set clock in source device '%s': ret=%d\n",
+		      __func__, uc_plat->src_dev->name, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static const char * const rk3288_regulator_names[] = {
+	"vcc50_hdmi"
+};
+
+static int rk3288_hdmi_probe(struct udevice *dev)
+{
+	/* Enable VOP clock for RK3288 */
+	rk3288_clk_config(dev);
+
+	/* Enable regulators required for HDMI */
+	rk_hdmi_probe_regulators(dev, rk3288_regulator_names,
+				 ARRAY_SIZE(rk3288_regulator_names));
+
+	return rk_hdmi_probe(dev);
+}
+
+static const struct dm_display_ops rk3288_hdmi_ops = {
+	.read_edid = rk_hdmi_read_edid,
+	.enable = rk3288_hdmi_enable,
+};
+
+static const struct udevice_id rk3288_hdmi_ids[] = {
+	{ .compatible = "rockchip,rk3288-dw-hdmi" },
+	{ }
+};
+
+U_BOOT_DRIVER(rk3288_hdmi_rockchip) = {
+	.name = "rk3288_hdmi_rockchip",
+	.id = UCLASS_DISPLAY,
+	.of_match = rk3288_hdmi_ids,
+	.ops = &rk3288_hdmi_ops,
+	.ofdata_to_platdata = rk3288_hdmi_ofdata_to_platdata,
+	.probe = rk3288_hdmi_probe,
+	.priv_auto_alloc_size = sizeof(struct rk_hdmi_priv),
+};
diff --git a/drivers/video/rockchip/rk3288_vop.c b/drivers/video/rockchip/rk3288_vop.c
new file mode 100644
index 0000000..e3e1ec7
--- /dev/null
+++ b/drivers/video/rockchip/rk3288_vop.c
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2017 Theobroma Systems Design und Consulting GmbH
+ * Copyright (c) 2015 Google, Inc
+ * Copyright 2014 Rockchip Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <display.h>
+#include <dm.h>
+#include <regmap.h>
+#include <syscon.h>
+#include <video.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/grf_rk3288.h>
+#include "rk_vop.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static void rk3288_set_pin_polarity(struct udevice *dev,
+				    enum vop_modes mode, u32 polarity)
+{
+	struct rk_vop_priv *priv = dev_get_priv(dev);
+	struct rk3288_vop *regs = priv->regs;
+
+	/* The RK3328 VOP (v3.1) has its polarity configuration in ctrl0 */
+	clrsetbits_le32(&regs->dsp_ctrl0,
+			M_DSP_DCLK_POL | M_DSP_DEN_POL |
+			M_DSP_VSYNC_POL | M_DSP_HSYNC_POL,
+			V_DSP_PIN_POL(polarity));
+}
+
+static void rk3288_set_io_vsel(struct udevice *dev)
+{
+	struct rk3288_grf *grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+
+	/* lcdc(vop) iodomain select 1.8V */
+	rk_setreg(&grf->io_vsel, 1 << 0);
+}
+
+/*
+ * Try some common regulators. We should really get these from the
+ * device tree somehow.
+ */
+static const char * const rk3288_regulator_names[] = {
+	"vcc18_lcd",
+	"VCC18_LCD",
+	"vdd10_lcd_pwren_h",
+	"vdd10_lcd",
+	"VDD10_LCD",
+	"vcc33_lcd"
+};
+
+static int rk3288_vop_probe(struct udevice *dev)
+{
+	/* Before relocation we don't need to do anything */
+	if (!(gd->flags & GD_FLG_RELOC))
+		return 0;
+
+	/* Set the LCDC(vop) iodomain to 1.8V */
+	rk3288_set_io_vsel(dev);
+
+	/* Probe regulators required for the RK3288 VOP */
+	rk_vop_probe_regulators(dev, rk3288_regulator_names,
+				ARRAY_SIZE(rk3288_regulator_names));
+
+	return rk_vop_probe(dev);
+}
+
+struct rkvop_driverdata rk3288_driverdata = {
+	.features = VOP_FEATURE_OUTPUT_10BIT,
+	.set_pin_polarity = rk3288_set_pin_polarity,
+};
+
+static const struct udevice_id rk3288_vop_ids[] = {
+	{ .compatible = "rockchip,rk3288-vop",
+	  .data = (ulong)&rk3288_driverdata },
+	{ }
+};
+
+static const struct video_ops rk3288_vop_ops = {
+};
+
+U_BOOT_DRIVER(rk_vop) = {
+	.name	= "rk3288_vop",
+	.id	= UCLASS_VIDEO,
+	.of_match = rk3288_vop_ids,
+	.ops	= &rk3288_vop_ops,
+	.bind	= rk_vop_bind,
+	.probe	= rk3288_vop_probe,
+	.priv_auto_alloc_size	= sizeof(struct rk_vop_priv),
+};
diff --git a/drivers/video/rockchip/rk3399_hdmi.c b/drivers/video/rockchip/rk3399_hdmi.c
new file mode 100644
index 0000000..b1e5097
--- /dev/null
+++ b/drivers/video/rockchip/rk3399_hdmi.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2017 Theobroma Systems Design und Consulting GmbH
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <display.h>
+#include <dm.h>
+#include <dw_hdmi.h>
+#include <edid.h>
+#include <regmap.h>
+#include <syscon.h>
+#include <asm/gpio.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/grf_rk3399.h>
+#include <power/regulator.h>
+#include "rk_hdmi.h"
+
+static int rk3399_hdmi_enable(struct udevice *dev, int panel_bpp,
+			      const struct display_timing *edid)
+{
+	struct rk_hdmi_priv *priv = dev_get_priv(dev);
+	struct display_plat *uc_plat = dev_get_uclass_platdata(dev);
+	int vop_id = uc_plat->source_id;
+	struct rk3399_grf_regs *grf = priv->grf;
+
+	/* select the hdmi encoder input data from our source_id */
+	rk_clrsetreg(&grf->soc_con20, GRF_RK3399_HDMI_VOP_SEL_MASK,
+		     (vop_id == 1) ? GRF_RK3399_HDMI_VOP_SEL_L : 0);
+
+	return dw_hdmi_enable(&priv->hdmi, edid);
+}
+
+static int rk3399_hdmi_ofdata_to_platdata(struct udevice *dev)
+{
+	struct rk_hdmi_priv *priv = dev_get_priv(dev);
+	struct dw_hdmi *hdmi = &priv->hdmi;
+
+	hdmi->i2c_clk_high = 0x7a;
+	hdmi->i2c_clk_low = 0x8d;
+
+	return rk_hdmi_ofdata_to_platdata(dev);
+}
+
+static const char * const rk3399_regulator_names[] = {
+	"vcc1v8_hdmi",
+	"vcc0v9_hdmi"
+};
+
+static int rk3399_hdmi_probe(struct udevice *dev)
+{
+	/* Enable regulators required for HDMI */
+	rk_hdmi_probe_regulators(dev, rk3399_regulator_names,
+				 ARRAY_SIZE(rk3399_regulator_names));
+
+	return rk_hdmi_probe(dev);
+}
+
+static const struct dm_display_ops rk3399_hdmi_ops = {
+	.read_edid = rk_hdmi_read_edid,
+	.enable = rk3399_hdmi_enable,
+};
+
+static const struct udevice_id rk3399_hdmi_ids[] = {
+	{ .compatible = "rockchip,rk3399-dw-hdmi" },
+	{ }
+};
+
+U_BOOT_DRIVER(rk3399_hdmi_rockchip) = {
+	.name = "rk3399_hdmi_rockchip",
+	.id = UCLASS_DISPLAY,
+	.of_match = rk3399_hdmi_ids,
+	.ops = &rk3399_hdmi_ops,
+	.ofdata_to_platdata = rk3399_hdmi_ofdata_to_platdata,
+	.probe = rk3399_hdmi_probe,
+	.priv_auto_alloc_size = sizeof(struct rk_hdmi_priv),
+};
diff --git a/drivers/video/rockchip/rk3399_vop.c b/drivers/video/rockchip/rk3399_vop.c
new file mode 100644
index 0000000..91a40ab
--- /dev/null
+++ b/drivers/video/rockchip/rk3399_vop.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2017 Theobroma Systems Design und Consulting GmbH
+ * Copyright (c) 2015 Google, Inc
+ * Copyright 2014 Rockchip Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <display.h>
+#include <dm.h>
+#include <regmap.h>
+#include <video.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include "rk_vop.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static void rk3399_set_pin_polarity(struct udevice *dev,
+				    enum vop_modes mode, u32 polarity)
+{
+	struct rk_vop_priv *priv = dev_get_priv(dev);
+	struct rk3288_vop *regs = priv->regs;
+
+	/*
+	 * The RK3399 VOPs (v3.5 and v3.6) require a per-mode setting of
+	 * the polarity configuration (in ctrl1).
+	 */
+	switch (mode) {
+	case VOP_MODE_HDMI:
+		clrsetbits_le32(&regs->dsp_ctrl1,
+				M_RK3399_DSP_HDMI_POL,
+				V_RK3399_DSP_HDMI_POL(polarity));
+		break;
+
+	case VOP_MODE_EDP:
+		clrsetbits_le32(&regs->dsp_ctrl1,
+				M_RK3399_DSP_EDP_POL,
+				V_RK3399_DSP_EDP_POL(polarity));
+		break;
+
+	case VOP_MODE_MIPI:
+		clrsetbits_le32(&regs->dsp_ctrl1,
+				M_RK3399_DSP_MIPI_POL,
+				V_RK3399_DSP_MIPI_POL(polarity));
+		break;
+
+	case VOP_MODE_LVDS:
+		/* The RK3399 has neither parallel RGB nor LVDS output. */
+	default:
+		debug("%s: unsupported output mode %x\n", __func__, mode);
+	}
+}
+
+/*
+ * Try some common regulators. We should really get these from the
+ * device tree somehow.
+ */
+static const char * const rk3399_regulator_names[] = {
+	"vcc33_lcd"
+};
+
+static int rk3399_vop_probe(struct udevice *dev)
+{
+	/* Before relocation we don't need to do anything */
+	if (!(gd->flags & GD_FLG_RELOC))
+		return 0;
+
+	/* Probe regulators required for the RK3399 VOP */
+	rk_vop_probe_regulators(dev, rk3399_regulator_names,
+				ARRAY_SIZE(rk3399_regulator_names));
+
+	return rk_vop_probe(dev);
+}
+
+struct rkvop_driverdata rk3399_lit_driverdata = {
+	.set_pin_polarity = rk3399_set_pin_polarity,
+};
+
+struct rkvop_driverdata rk3399_big_driverdata = {
+	.features = VOP_FEATURE_OUTPUT_10BIT,
+	.set_pin_polarity = rk3399_set_pin_polarity,
+};
+
+static const struct udevice_id rk3399_vop_ids[] = {
+	{ .compatible = "rockchip,rk3399-vop-big",
+	  .data = (ulong)&rk3399_big_driverdata },
+	{ .compatible = "rockchip,rk3399-vop-lit",
+	  .data = (ulong)&rk3399_lit_driverdata },
+	{ }
+};
+
+static const struct video_ops rk3399_vop_ops = {
+};
+
+U_BOOT_DRIVER(rk3399_vop) = {
+	.name	= "rk3399_vop",
+	.id	= UCLASS_VIDEO,
+	.of_match = rk3399_vop_ids,
+	.ops	= &rk3399_vop_ops,
+	.bind	= rk_vop_bind,
+	.probe	= rk3399_vop_probe,
+	.priv_auto_alloc_size	= sizeof(struct rk_vop_priv),
+};
diff --git a/drivers/video/rockchip/rk_hdmi.c b/drivers/video/rockchip/rk_hdmi.c
index cd695ca..a9c8fba 100644
--- a/drivers/video/rockchip/rk_hdmi.c
+++ b/drivers/video/rockchip/rk_hdmi.c
@@ -1,4 +1,5 @@
 /*
+ * Copyright (c) 2017 Theobroma Systems Design und Consulting GmbH
  * Copyright (c) 2015 Google, Inc
  * Copyright 2014 Rockchip Inc.
  *
@@ -14,15 +15,12 @@
 #include <regmap.h>
 #include <syscon.h>
 #include <asm/gpio.h>
+#include <asm/hardware.h>
 #include <asm/io.h>
 #include <asm/arch/clock.h>
-#include <asm/arch/grf_rk3288.h>
-#include <power/regulator.h>
-
-struct rk_hdmi_priv {
-	struct dw_hdmi hdmi;
-	struct rk3288_grf *grf;
-};
+#include <asm/arch/hardware.h>
+#include "rk_hdmi.h"
+#include "rk_vop.h" /* for rk_vop_probe_regulators */
 
 static const struct hdmi_phy_config rockchip_phy_config[] = {
 	{
@@ -35,6 +33,9 @@
 		.mpixelclock = 297000000,
 		.sym_ctr = 0x8039, .term = 0x0005, .vlev_ctr = 0x028d,
 	}, {
+		.mpixelclock = 584000000,
+		.sym_ctr = 0x8039, .term = 0x0000, .vlev_ctr = 0x019d,
+	}, {
 		.mpixelclock = ~0ul,
 		.sym_ctr = 0x0000, .term = 0x0000, .vlev_ctr = 0x0000,
 	}
@@ -60,27 +61,25 @@
 		.mpixelclock = 148500000,
 		.cpce = 0x0051, .gmp = 0x0003, .curr = 0x0000,
 	}, {
+		.mpixelclock = 272000000,
+		.cpce = 0x0040, .gmp = 0x0003, .curr = 0x0000,
+	}, {
+		.mpixelclock = 340000000,
+		.cpce = 0x0040, .gmp = 0x0003, .curr = 0x0000,
+	}, {
 		.mpixelclock = ~0ul,
 		.cpce = 0x0051, .gmp = 0x0003, .curr = 0x0000,
 	}
 };
 
-static int rk_hdmi_read_edid(struct udevice *dev, u8 *buf, int buf_size)
+int rk_hdmi_read_edid(struct udevice *dev, u8 *buf, int buf_size)
 {
 	struct rk_hdmi_priv *priv = dev_get_priv(dev);
 
 	return dw_hdmi_read_edid(&priv->hdmi, buf, buf_size);
 }
 
-static int rk_hdmi_enable(struct udevice *dev, int panel_bpp,
-			  const struct display_timing *edid)
-{
-	struct rk_hdmi_priv *priv = dev_get_priv(dev);
-
-	return dw_hdmi_enable(&priv->hdmi, edid);
-}
-
-static int rk_hdmi_ofdata_to_platdata(struct udevice *dev)
+int rk_hdmi_ofdata_to_platdata(struct udevice *dev)
 {
 	struct rk_hdmi_priv *priv = dev_get_priv(dev);
 	struct dw_hdmi *hdmi = &priv->hdmi;
@@ -88,15 +87,9 @@
 	hdmi->ioaddr = (ulong)devfdt_get_addr(dev);
 	hdmi->mpll_cfg = rockchip_mpll_cfg;
 	hdmi->phy_cfg = rockchip_phy_config;
-	hdmi->i2c_clk_high = 0x7a;
-	hdmi->i2c_clk_low = 0x8d;
 
-	/*
-	 * TODO(sjg@chromium.org): The above values don't work - these ones
-	 * work better, but generate lots of errors in the data.
-	 */
-	hdmi->i2c_clk_high = 0x0d;
-	hdmi->i2c_clk_low = 0x0d;
+	/* hdmi->i2c_clk_{high,low} are set up by the SoC driver */
+
 	hdmi->reg_io_width = 4;
 	hdmi->phy_set = dw_hdmi_phy_cfg;
 
@@ -105,53 +98,17 @@
 	return 0;
 }
 
-static int rk_hdmi_probe(struct udevice *dev)
+void rk_hdmi_probe_regulators(struct udevice *dev,
+			      const char * const *names, int cnt)
 {
-	struct display_plat *uc_plat = dev_get_uclass_platdata(dev);
+	rk_vop_probe_regulators(dev, names, cnt);
+}
+
+int rk_hdmi_probe(struct udevice *dev)
+{
 	struct rk_hdmi_priv *priv = dev_get_priv(dev);
 	struct dw_hdmi *hdmi = &priv->hdmi;
-	struct udevice *reg;
-	struct clk clk;
 	int ret;
-	int vop_id = uc_plat->source_id;
-
-	ret = clk_get_by_index(dev, 0, &clk);
-	if (ret >= 0) {
-		ret = clk_set_rate(&clk, 0);
-		clk_free(&clk);
-	}
-	if (ret) {
-		debug("%s: Failed to set hdmi clock: ret=%d\n", __func__, ret);
-		return ret;
-	}
-
-	/*
-	 * Configure the maximum clock to permit whatever resolution the
-	 * monitor wants
-	 */
-	ret = clk_get_by_index(uc_plat->src_dev, 0, &clk);
-	if (ret >= 0) {
-		ret = clk_set_rate(&clk, 384000000);
-		clk_free(&clk);
-	}
-	if (ret < 0) {
-		debug("%s: Failed to set clock in source device '%s': ret=%d\n",
-		      __func__, uc_plat->src_dev->name, ret);
-		return ret;
-	}
-
-	ret = regulator_get_by_platname("vcc50_hdmi", &reg);
-	if (!ret)
-		ret = regulator_set_enable(reg, true);
-	if (ret)
-		debug("%s: Cannot set regulator vcc50_hdmi\n", __func__);
-
-	/* hdmi source select hdmi controller */
-	rk_setreg(&priv->grf->soc_con6, 1 << 15);
-
-	/* hdmi data from vop id */
-	rk_clrsetreg(&priv->grf->soc_con6, 1 << 4,
-		     (vop_id == 1) ? (1 << 4) : 0);
 
 	ret = dw_hdmi_phy_wait_for_hpd(hdmi);
 	if (ret < 0) {
@@ -164,23 +121,3 @@
 
 	return 0;
 }
-
-static const struct dm_display_ops rk_hdmi_ops = {
-	.read_edid = rk_hdmi_read_edid,
-	.enable = rk_hdmi_enable,
-};
-
-static const struct udevice_id rk_hdmi_ids[] = {
-	{ .compatible = "rockchip,rk3288-dw-hdmi" },
-	{ }
-};
-
-U_BOOT_DRIVER(hdmi_rockchip) = {
-	.name	= "hdmi_rockchip",
-	.id	= UCLASS_DISPLAY,
-	.of_match = rk_hdmi_ids,
-	.ops	= &rk_hdmi_ops,
-	.ofdata_to_platdata	= rk_hdmi_ofdata_to_platdata,
-	.probe	= rk_hdmi_probe,
-	.priv_auto_alloc_size	 = sizeof(struct rk_hdmi_priv),
-};
diff --git a/drivers/video/rockchip/rk_hdmi.h b/drivers/video/rockchip/rk_hdmi.h
new file mode 100644
index 0000000..501ed3a
--- /dev/null
+++ b/drivers/video/rockchip/rk_hdmi.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2017 Theobroma Systems Design und Consulting GmbH
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __RK_HDMI_H__
+#define __RK_HDMI_H__
+
+struct rkhdmi_driverdata {
+	/* configuration */
+	u8 i2c_clk_high;
+	u8 i2c_clk_low;
+	const char * const *regulator_names;
+	u32 regulator_names_cnt;
+	/* setters/getters */
+	int (*set_input_vop)(struct udevice *dev);
+	int (*clk_config)(struct udevice *dev);
+};
+
+struct rk_hdmi_priv {
+	struct dw_hdmi hdmi;
+	void *grf;
+};
+
+int rk_hdmi_read_edid(struct udevice *dev, u8 *buf, int buf_size);
+void rk_hdmi_probe_regulators(struct udevice *dev,
+			      const char * const *names, int cnt);
+int rk_hdmi_ofdata_to_platdata(struct udevice *dev);
+int rk_hdmi_probe(struct udevice *dev);
+
+#endif
diff --git a/drivers/video/rockchip/rk_vop.c b/drivers/video/rockchip/rk_vop.c
index 48bfcd4..9343796 100644
--- a/drivers/video/rockchip/rk_vop.c
+++ b/drivers/video/rockchip/rk_vop.c
@@ -17,24 +17,25 @@
 #include <asm/hardware.h>
 #include <asm/io.h>
 #include <asm/arch/clock.h>
-#include <asm/arch/cru_rk3288.h>
-#include <asm/arch/grf_rk3288.h>
 #include <asm/arch/edp_rk3288.h>
 #include <asm/arch/vop_rk3288.h>
 #include <dm/device-internal.h>
 #include <dm/uclass-internal.h>
-#include <dt-bindings/clock/rk3288-cru.h>
 #include <power/regulator.h>
+#include "rk_vop.h"
 
 DECLARE_GLOBAL_DATA_PTR;
 
-struct rk_vop_priv {
-	struct rk3288_vop *regs;
-	struct rk3288_grf *grf;
+enum vop_pol {
+	HSYNC_POSITIVE = 0,
+	VSYNC_POSITIVE = 1,
+	DEN_NEGATIVE   = 2,
+	DCLK_INVERT    = 3
 };
 
-void rkvop_enable(struct rk3288_vop *regs, ulong fbbase,
-		  int fb_bits_per_pixel, const struct display_timing *edid)
+static void rkvop_enable(struct rk3288_vop *regs, ulong fbbase,
+			 int fb_bits_per_pixel,
+			 const struct display_timing *edid)
 {
 	u32 lb_mode;
 	u32 rgb_mode;
@@ -89,9 +90,56 @@
 	writel(0x01, &regs->reg_cfg_done); /* enable reg config */
 }
 
-void rkvop_mode_set(struct rk3288_vop *regs,
-		    const struct display_timing *edid, enum vop_modes mode)
+static void rkvop_set_pin_polarity(struct udevice *dev,
+				   enum vop_modes mode, u32 polarity)
 {
+	struct rkvop_driverdata *ops =
+		(struct rkvop_driverdata *)dev_get_driver_data(dev);
+
+	if (ops->set_pin_polarity)
+		ops->set_pin_polarity(dev, mode, polarity);
+}
+
+static void rkvop_enable_output(struct udevice *dev, enum vop_modes mode)
+{
+	struct rk_vop_priv *priv = dev_get_priv(dev);
+	struct rk3288_vop *regs = priv->regs;
+
+	switch (mode) {
+	case VOP_MODE_HDMI:
+		clrsetbits_le32(&regs->sys_ctrl, M_ALL_OUT_EN,
+				V_HDMI_OUT_EN(1));
+		break;
+
+	case VOP_MODE_EDP:
+		clrsetbits_le32(&regs->sys_ctrl, M_ALL_OUT_EN,
+				V_EDP_OUT_EN(1));
+		break;
+
+	case VOP_MODE_LVDS:
+		clrsetbits_le32(&regs->sys_ctrl, M_ALL_OUT_EN,
+				V_RGB_OUT_EN(1));
+		break;
+
+	case VOP_MODE_MIPI:
+		clrsetbits_le32(&regs->sys_ctrl, M_ALL_OUT_EN,
+				V_MIPI_OUT_EN(1));
+		break;
+
+	default:
+		debug("%s: unsupported output mode %x\n", __func__, mode);
+	}
+}
+
+static void rkvop_mode_set(struct udevice *dev,
+			   const struct display_timing *edid,
+			   enum vop_modes mode)
+{
+	struct rk_vop_priv *priv = dev_get_priv(dev);
+	struct rk3288_vop *regs = priv->regs;
+	struct rkvop_driverdata *data =
+		(struct rkvop_driverdata *)dev_get_driver_data(dev);
+
 	u32 hactive = edid->hactive.typ;
 	u32 vactive = edid->vactive.typ;
 	u32 hsync_len = edid->hsync_len.typ;
@@ -100,43 +148,25 @@
 	u32 vback_porch = edid->vback_porch.typ;
 	u32 hfront_porch = edid->hfront_porch.typ;
 	u32 vfront_porch = edid->vfront_porch.typ;
-	uint flags;
 	int mode_flags;
+	u32 pin_polarity;
 
-	switch (mode) {
-	case VOP_MODE_HDMI:
-		clrsetbits_le32(&regs->sys_ctrl, M_ALL_OUT_EN,
-				V_HDMI_OUT_EN(1));
-		break;
-	case VOP_MODE_EDP:
-	default:
-		clrsetbits_le32(&regs->sys_ctrl, M_ALL_OUT_EN,
-				V_EDP_OUT_EN(1));
-		break;
-	case VOP_MODE_LVDS:
-		clrsetbits_le32(&regs->sys_ctrl, M_ALL_OUT_EN,
-				V_RGB_OUT_EN(1));
-		break;
-	case VOP_MODE_MIPI:
-		clrsetbits_le32(&regs->sys_ctrl, M_ALL_OUT_EN,
-				V_MIPI_OUT_EN(1));
-		 break;
-	}
+	pin_polarity = BIT(DCLK_INVERT);
+	if (edid->flags & DISPLAY_FLAGS_HSYNC_HIGH)
+		pin_polarity |= BIT(HSYNC_POSITIVE);
+	if (edid->flags & DISPLAY_FLAGS_VSYNC_HIGH)
+		pin_polarity |= BIT(VSYNC_POSITIVE);
 
-	if (mode == VOP_MODE_HDMI || mode == VOP_MODE_EDP)
-		/* RGBaaa */
-		mode_flags = 15;
-	else
-		/* RGB888 */
-		mode_flags = 0;
+	rkvop_set_pin_polarity(dev, mode, pin_polarity);
+	rkvop_enable_output(dev, mode);
 
-	flags = V_DSP_OUT_MODE(mode_flags) |
-		V_DSP_HSYNC_POL(!!(edid->flags & DISPLAY_FLAGS_HSYNC_HIGH)) |
-		V_DSP_VSYNC_POL(!!(edid->flags & DISPLAY_FLAGS_VSYNC_HIGH));
+	mode_flags = 0;  /* RGB888 */
+	if ((data->features & VOP_FEATURE_OUTPUT_10BIT) &&
+	    (mode == VOP_MODE_HDMI || mode == VOP_MODE_EDP))
+		mode_flags = 15;  /* RGBaaa */
 
-	clrsetbits_le32(&regs->dsp_ctrl0,
-			M_DSP_OUT_MODE | M_DSP_VSYNC_POL | M_DSP_HSYNC_POL,
-			flags);
+	clrsetbits_le32(&regs->dsp_ctrl0, M_DSP_OUT_MODE,
+			V_DSP_OUT_MODE(mode_flags));
 
 	writel(V_HSYNC(hsync_len) |
 	       V_HORPRD(hsync_len + hback_porch + hactive + hfront_porch),
@@ -185,7 +215,7 @@
  *		node within the VOP's 'port' list.
  * @return 0 if OK, -ve if something went wrong
  */
-int rk_display_init(struct udevice *dev, ulong fbbase, int ep_node)
+static int rk_display_init(struct udevice *dev, ulong fbbase, int ep_node)
 {
 	struct video_priv *uc_priv = dev_get_uclass_priv(dev);
 	const void *blob = gd->fdt_blob;
@@ -255,18 +285,18 @@
 	/* Set bitwidth for vop display according to vop mode */
 	switch (vop_id) {
 	case VOP_MODE_EDP:
-	case VOP_MODE_HDMI:
 	case VOP_MODE_LVDS:
 		l2bpp = VIDEO_BPP16;
 		break;
+	case VOP_MODE_HDMI:
 	case VOP_MODE_MIPI:
 		l2bpp = VIDEO_BPP32;
 		break;
 	default:
 		l2bpp = VIDEO_BPP16;
 	}
-	rkvop_mode_set(regs, &timing, vop_id);
 
+	rkvop_mode_set(dev, &timing, vop_id);
 	rkvop_enable(regs, fbbase, 1 << l2bpp, &timing);
 
 	ret = display_enable(disp, 1 << l2bpp, &timing);
@@ -281,53 +311,37 @@
 	return 0;
 }
 
-static int rk_vop_probe(struct udevice *dev)
+void rk_vop_probe_regulators(struct udevice *dev,
+			     const char * const *names, int cnt)
+{
+	int i, ret;
+	const char *name;
+	struct udevice *reg;
+
+	for (i = 0; i < cnt; ++i) {
+		name = names[i];
+		debug("%s: probing regulator '%s'\n", dev->name, name);
+
+		ret = regulator_autoset_by_name(name, &reg);
+		if (!ret)
+			ret = regulator_set_enable(reg, true);
+	}
+}
+
+int rk_vop_probe(struct udevice *dev)
 {
 	struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
 	const void *blob = gd->fdt_blob;
 	struct rk_vop_priv *priv = dev_get_priv(dev);
-	struct udevice *reg;
-	int ret, port, node;
+	int ret = 0;
+	int port, node;
 
 	/* Before relocation we don't need to do anything */
 	if (!(gd->flags & GD_FLG_RELOC))
 		return 0;
 
-	priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
 	priv->regs = (struct rk3288_vop *)devfdt_get_addr(dev);
 
-	/* lcdc(vop) iodomain select 1.8V */
-	rk_setreg(&priv->grf->io_vsel, 1 << 0);
-
-	/*
-	 * Try some common regulators. We should really get these from the
-	 * device tree somehow.
-	 */
-	ret = regulator_autoset_by_name("vcc18_lcd", &reg);
-	if (ret)
-		debug("%s: Cannot autoset regulator vcc18_lcd\n", __func__);
-	ret = regulator_autoset_by_name("VCC18_LCD", &reg);
-	if (ret)
-		debug("%s: Cannot autoset regulator VCC18_LCD\n", __func__);
-	ret = regulator_autoset_by_name("vdd10_lcd_pwren_h", &reg);
-	if (ret) {
-		debug("%s: Cannot autoset regulator vdd10_lcd_pwren_h\n",
-		      __func__);
-	}
-	ret = regulator_autoset_by_name("vdd10_lcd", &reg);
-	if (ret) {
-		debug("%s: Cannot autoset regulator vdd10_lcd\n",
-		      __func__);
-	}
-	ret = regulator_autoset_by_name("VDD10_LCD", &reg);
-	if (ret) {
-		debug("%s: Cannot autoset regulator VDD10_LCD\n",
-		      __func__);
-	}
-	ret = regulator_autoset_by_name("vcc33_lcd", &reg);
-	if (ret)
-		debug("%s: Cannot autoset regulator vcc33_lcd\n", __func__);
-
 	/*
 	 * Try all the ports until we find one that works. In practice this
 	 * tries EDP first if available, then HDMI.
@@ -353,31 +367,12 @@
 	return ret;
 }
 
-static int rk_vop_bind(struct udevice *dev)
+int rk_vop_bind(struct udevice *dev)
 {
 	struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
 
-	plat->size = 1920 * 1200 * 4;
+	plat->size = 4 * (CONFIG_VIDEO_ROCKCHIP_MAX_XRES *
+			  CONFIG_VIDEO_ROCKCHIP_MAX_YRES);
 
 	return 0;
 }
-
-static const struct video_ops rk_vop_ops = {
-};
-
-static const struct udevice_id rk_vop_ids[] = {
-	{ .compatible = "rockchip,rk3399-vop-big" },
-	{ .compatible = "rockchip,rk3399-vop-lit" },
-	{ .compatible = "rockchip,rk3288-vop" },
-	{ }
-};
-
-U_BOOT_DRIVER(rk_vop) = {
-	.name	= "rk_vop",
-	.id	= UCLASS_VIDEO,
-	.of_match = rk_vop_ids,
-	.ops	= &rk_vop_ops,
-	.bind	= rk_vop_bind,
-	.probe	= rk_vop_probe,
-	.priv_auto_alloc_size	= sizeof(struct rk_vop_priv),
-};
diff --git a/drivers/video/rockchip/rk_vop.h b/drivers/video/rockchip/rk_vop.h
new file mode 100644
index 0000000..9bda514
--- /dev/null
+++ b/drivers/video/rockchip/rk_vop.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2017 Theobroma Systems Design und Consulting GmbH
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __RK_VOP_H__
+#define __RK_VOP_H__
+
+#include <asm/arch/vop_rk3288.h>
+
+struct rk_vop_priv {
+	void *grf;
+	void *regs;
+};
+
+enum vop_features {
+	VOP_FEATURE_OUTPUT_10BIT = (1 << 0),
+};
+
+struct rkvop_driverdata {
+	/* configuration */
+	u32 features;
+	/* block-specific setters/getters */
+	void (*set_pin_polarity)(struct udevice *, enum vop_modes, u32);
+};
+
+int rk_vop_probe(struct udevice *dev);
+int rk_vop_bind(struct udevice *dev);
+void rk_vop_probe_regulators(struct udevice *dev,
+			     const char * const *names, int cnt);
+
+#endif
diff --git a/include/configs/evb_px5.h b/include/configs/evb_px5.h
new file mode 100644
index 0000000..2286837
--- /dev/null
+++ b/include/configs/evb_px5.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2017 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef __CONFIGS_PX5_EVB_H
+#define __CONFIGS_PX5_EVB_H
+
+#include <configs/rk3368_common.h>
+
+#define CONFIG_ENV_IS_NOWHERE
+#define CONFIG_ENV_SIZE			0x2000
+
+#define CONFIG_CONSOLE_SCROLL_LINES	10
+
+#endif
diff --git a/include/configs/evb_rv1108.h b/include/configs/evb_rv1108.h
new file mode 100644
index 0000000..ff3531b
--- /dev/null
+++ b/include/configs/evb_rv1108.h
@@ -0,0 +1,26 @@
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#include <configs/rv1108_common.h>
+
+/*
+ * Default environment settings
+ */
+#define CONFIG_EXTRA_ENV_SETTINGS                                       \
+	"netdev=eth0\0"                                                 \
+	"ipaddr=172.16.12.50\0"                                         \
+	"serverip=172.16.12.69\0"					\
+	""
+#define CONFIG_BOOTCOMMAND						\
+	"sf probe;"							\
+	"sf read 0x62000000 0x140800 0x500000;"				\
+	"dcache off;"							\
+	"go 0x62000000"
+
+#endif
diff --git a/include/configs/geekbox.h b/include/configs/geekbox.h
new file mode 100644
index 0000000..6f6007e
--- /dev/null
+++ b/include/configs/geekbox.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2016 Andreas Färber
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef __CONFIGS_GEEKBOX_H
+#define __CONFIGS_GEEKBOX_H
+
+#include <configs/rk3368_common.h>
+
+#define CONFIG_ENV_IS_NOWHERE
+#define CONFIG_ENV_SIZE			0x2000
+
+#define CONFIG_CONSOLE_SCROLL_LINES		10
+
+#endif
diff --git a/include/configs/puma_rk3399.h b/include/configs/puma_rk3399.h
index f778744..af1dae8 100644
--- a/include/configs/puma_rk3399.h
+++ b/include/configs/puma_rk3399.h
@@ -22,4 +22,12 @@
 
 #define SDRAM_BANK_SIZE			(2UL << 30)
 
+#define CONFIG_MISC_INIT_R
+#define CONFIG_SERIAL_TAG
+#define CONFIG_ENV_OVERWRITE
+
+#define CONFIG_BMP_16BPP
+#define CONFIG_BMP_24BPP
+#define CONFIG_BMP_32BPP
+
 #endif
diff --git a/include/configs/rk3328_common.h b/include/configs/rk3328_common.h
index 7ccbc9b..5a06244 100644
--- a/include/configs/rk3328_common.h
+++ b/include/configs/rk3328_common.h
@@ -59,4 +59,10 @@
 
 #endif
 
+/* rockchip ohci host driver */
+#define CONFIG_USB_OHCI_NEW
+#define CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS	1
+
+/* xhci host */
+#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS	2
 #endif
diff --git a/include/configs/rk3368_common.h b/include/configs/rk3368_common.h
new file mode 100644
index 0000000..8ebf232
--- /dev/null
+++ b/include/configs/rk3368_common.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2016 Andreas Färber
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef __CONFIG_RK3368_COMMON_H
+#define __CONFIG_RK3368_COMMON_H
+
+#define CONFIG_SYS_CACHELINE_SIZE	64
+
+#include <asm/arch/hardware.h>
+#include <linux/sizes.h>
+
+#define CONFIG_NR_DRAM_BANKS		1
+#define CONFIG_SYS_MAXARGS		16
+#define CONFIG_BAUDRATE			115200
+#define CONFIG_SYS_MALLOC_LEN		(32 << 20)
+#define CONFIG_SYS_CBSIZE		1024
+#define CONFIG_SKIP_LOWLEVEL_INIT
+
+#define CONFIG_SYS_NS16550_MEM32
+
+#define CONFIG_SYS_TEXT_BASE		0x00200000
+#define CONFIG_SYS_INIT_SP_ADDR		0x00300000
+#define CONFIG_SYS_LOAD_ADDR		0x00280000
+
+#define CONFIG_BOUNCE_BUFFER
+
+#ifndef CONFIG_SPL_BUILD
+#define ENV_MEM_LAYOUT_SETTINGS \
+	"scriptaddr=0x00500000\0" \
+	"pxefile_addr_r=0x00600000\0" \
+	"fdt_addr_r=0x5600000\0" \
+	"kernel_addr_r=0x280000\0" \
+	"ramdisk_addr_r=0x5bf0000\0"
+
+#include <config_distro_defaults.h>
+
+#define BOOT_TARGET_DEVICES(func)
+
+#include <config_distro_bootcmd.h>
+
+#define CONFIG_EXTRA_ENV_SETTINGS \
+	BOOTENV
+
+#endif
+
+#endif
diff --git a/include/configs/rv1108_common.h b/include/configs/rv1108_common.h
new file mode 100644
index 0000000..52750cb
--- /dev/null
+++ b/include/configs/rv1108_common.h
@@ -0,0 +1,33 @@
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+#ifndef __CONFIG_RV1108_COMMON_H
+#define __CONFIG_RV1108_COMMON_H
+
+#include <asm/arch/hardware.h>
+#include "rockchip-common.h"
+
+#define CONFIG_ENV_IS_NOWHERE
+#define CONFIG_ENV_SIZE			0x2000
+#define CONFIG_SYS_MAXARGS		16
+#define CONFIG_SYS_MALLOC_LEN		(32 << 20)
+#define CONFIG_SYS_CBSIZE		1024
+#define CONFIG_SKIP_LOWLEVEL_INIT
+
+#define CONFIG_SYS_TIMER_RATE		(24 * 1000 * 1000)
+/* TIMER1,initialized by ddr initialize code */
+#define CONFIG_SYS_TIMER_BASE		0x10350020
+#define CONFIG_SYS_TIMER_COUNTER	(CONFIG_SYS_TIMER_BASE + 8)
+
+#define CONFIG_SYS_NS16550
+#define CONFIG_SYS_NS16550_MEM32
+
+#define CONFIG_SYS_SDRAM_BASE		0x60000000
+#define CONFIG_NR_DRAM_BANKS		1
+#define CONFIG_SYS_TEXT_BASE		CONFIG_SYS_SDRAM_BASE
+#define CONFIG_SYS_INIT_SP_ADDR		(CONFIG_SYS_TEXT_BASE + 0x100000)
+#define CONFIG_SYS_LOAD_ADDR		(CONFIG_SYS_SDRAM_BASE + 0x2000000)
+
+#endif
diff --git a/include/configs/sheep_rk3368.h b/include/configs/sheep_rk3368.h
new file mode 100644
index 0000000..ec33565
--- /dev/null
+++ b/include/configs/sheep_rk3368.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2017 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef __CONFIGS_PX5_EVB_H
+#define __CONFIGS_PX5_EVB_H
+
+#include <configs/rk3368_common.h>
+
+#define CONFIG_SYS_MMC_ENV_DEV		0
+#define KERNEL_LOAD_ADDR		0x280000
+#define DTB_LOAD_ADDR			0x5600000
+#define INITRD_LOAD_ADDR		0x5bf0000
+#define CONFIG_ENV_IS_NOWHERE
+#define CONFIG_ENV_SIZE			0x2000
+
+#define CONFIG_CONSOLE_SCROLL_LINES	10
+
+#endif
diff --git a/include/dt-bindings/clock/rk3368-cru.h b/include/dt-bindings/clock/rk3368-cru.h
new file mode 100644
index 0000000..9c5dd9b
--- /dev/null
+++ b/include/dt-bindings/clock/rk3368-cru.h
@@ -0,0 +1,384 @@
+/*
+ * Copyright (c) 2015 Heiko Stuebner <heiko@sntech.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RK3368_H
+#define _DT_BINDINGS_CLK_ROCKCHIP_RK3368_H
+
+/* core clocks */
+#define PLL_APLLB		1
+#define PLL_APLLL		2
+#define PLL_DPLL		3
+#define PLL_CPLL		4
+#define PLL_GPLL		5
+#define PLL_NPLL		6
+#define ARMCLKB			7
+#define ARMCLKL			8
+
+/* sclk gates (special clocks) */
+#define SCLK_GPU_CORE		64
+#define SCLK_SPI0		65
+#define SCLK_SPI1		66
+#define SCLK_SPI2		67
+#define SCLK_SDMMC		68
+#define SCLK_SDIO0		69
+#define SCLK_EMMC		71
+#define SCLK_TSADC		72
+#define SCLK_SARADC		73
+#define SCLK_NANDC0		75
+#define SCLK_UART0		77
+#define SCLK_UART1		78
+#define SCLK_UART2		79
+#define SCLK_UART3		80
+#define SCLK_UART4		81
+#define SCLK_I2S_8CH		82
+#define SCLK_SPDIF_8CH		83
+#define SCLK_I2S_2CH		84
+#define SCLK_TIMER0		85
+#define SCLK_TIMER1		86
+#define SCLK_TIMER2		87
+#define SCLK_TIMER3		88
+#define SCLK_TIMER4		89
+#define SCLK_TIMER5		90
+#define SCLK_TIMER6		91
+#define SCLK_OTGPHY0		93
+#define SCLK_OTG_ADP		96
+#define SCLK_HSICPHY480M	97
+#define SCLK_HSICPHY12M		98
+#define SCLK_MACREF		99
+#define SCLK_VOP0_PWM		100
+#define SCLK_MAC_RX		102
+#define SCLK_MAC_TX		103
+#define SCLK_EDP_24M		104
+#define SCLK_EDP		105
+#define SCLK_RGA		106
+#define SCLK_ISP		107
+#define SCLK_HDCP		108
+#define SCLK_HDMI_HDCP		109
+#define SCLK_HDMI_CEC		110
+#define SCLK_HEVC_CABAC		111
+#define SCLK_HEVC_CORE		112
+#define SCLK_I2S_8CH_OUT	113
+#define SCLK_SDMMC_DRV		114
+#define SCLK_SDIO0_DRV		115
+#define SCLK_EMMC_DRV		117
+#define SCLK_SDMMC_SAMPLE	118
+#define SCLK_SDIO0_SAMPLE	119
+#define SCLK_EMMC_SAMPLE	121
+#define SCLK_USBPHY480M		122
+#define SCLK_PVTM_CORE		123
+#define SCLK_PVTM_GPU		124
+#define SCLK_PVTM_PMU		125
+#define SCLK_SFC		126
+#define SCLK_MAC		127
+#define SCLK_MACREF_OUT		128
+
+#define DCLK_VOP		190
+#define MCLK_CRYPTO		191
+
+/* aclk gates */
+#define ACLK_GPU_MEM		192
+#define ACLK_GPU_CFG		193
+#define ACLK_DMAC_BUS		194
+#define ACLK_DMAC_PERI		195
+#define ACLK_PERI_MMU		196
+#define ACLK_GMAC		197
+#define ACLK_VOP		198
+#define ACLK_VOP_IEP		199
+#define ACLK_RGA		200
+#define ACLK_HDCP		201
+#define ACLK_IEP		202
+#define ACLK_VIO0_NOC		203
+#define ACLK_VIP		204
+#define ACLK_ISP		205
+#define ACLK_VIO1_NOC		206
+#define ACLK_VIDEO		208
+#define ACLK_BUS		209
+#define ACLK_PERI		210
+
+/* pclk gates */
+#define PCLK_GPIO0		320
+#define PCLK_GPIO1		321
+#define PCLK_GPIO2		322
+#define PCLK_GPIO3		323
+#define PCLK_PMUGRF		324
+#define PCLK_MAILBOX		325
+#define PCLK_GRF		329
+#define PCLK_SGRF		330
+#define PCLK_PMU		331
+#define PCLK_I2C0		332
+#define PCLK_I2C1		333
+#define PCLK_I2C2		334
+#define PCLK_I2C3		335
+#define PCLK_I2C4		336
+#define PCLK_I2C5		337
+#define PCLK_SPI0		338
+#define PCLK_SPI1		339
+#define PCLK_SPI2		340
+#define PCLK_UART0		341
+#define PCLK_UART1		342
+#define PCLK_UART2		343
+#define PCLK_UART3		344
+#define PCLK_UART4		345
+#define PCLK_TSADC		346
+#define PCLK_SARADC		347
+#define PCLK_SIM		348
+#define PCLK_GMAC		349
+#define PCLK_PWM0		350
+#define PCLK_PWM1		351
+#define PCLK_TIMER0		353
+#define PCLK_TIMER1		354
+#define PCLK_EDP_CTRL		355
+#define PCLK_MIPI_DSI0		356
+#define PCLK_MIPI_CSI		358
+#define PCLK_HDCP		359
+#define PCLK_HDMI_CTRL		360
+#define PCLK_VIO_H2P		361
+#define PCLK_BUS		362
+#define PCLK_PERI		363
+#define PCLK_DDRUPCTL		364
+#define PCLK_DDRPHY		365
+#define PCLK_ISP		366
+#define PCLK_VIP		367
+#define PCLK_WDT		368
+
+/* hclk gates */
+#define HCLK_SFC		448
+#define HCLK_OTG0		449
+#define HCLK_HOST0		450
+#define HCLK_HOST1		451
+#define HCLK_HSIC		452
+#define HCLK_NANDC0		453
+#define HCLK_TSP		455
+#define HCLK_SDMMC		456
+#define HCLK_SDIO0		457
+#define HCLK_EMMC		459
+#define HCLK_HSADC		460
+#define HCLK_CRYPTO		461
+#define HCLK_I2S_2CH		462
+#define HCLK_I2S_8CH		463
+#define HCLK_SPDIF		464
+#define HCLK_VOP		465
+#define HCLK_ROM		467
+#define HCLK_IEP		468
+#define HCLK_ISP		469
+#define HCLK_RGA		470
+#define HCLK_VIO_AHB_ARBI	471
+#define HCLK_VIO_NOC		472
+#define HCLK_VIP		473
+#define HCLK_VIO_H2P		474
+#define HCLK_VIO_HDCPMMU	475
+#define HCLK_VIDEO		476
+#define HCLK_BUS		477
+#define HCLK_PERI		478
+
+#define CLK_NR_CLKS		(HCLK_PERI + 1)
+
+/* soft-reset indices */
+#define SRST_CORE_B0		0
+#define SRST_CORE_B1		1
+#define SRST_CORE_B2		2
+#define SRST_CORE_B3		3
+#define SRST_CORE_B0_PO		4
+#define SRST_CORE_B1_PO		5
+#define SRST_CORE_B2_PO		6
+#define SRST_CORE_B3_PO		7
+#define SRST_L2_B		8
+#define SRST_ADB_B		9
+#define SRST_PD_CORE_B_NIU	10
+#define SRST_PDBUS_STRSYS	11
+#define SRST_SOCDBG_B		14
+#define SRST_CORE_B_DBG		15
+
+#define SRST_DMAC1		18
+#define SRST_INTMEM		19
+#define SRST_ROM		20
+#define SRST_SPDIF8CH		21
+#define SRST_I2S8CH		23
+#define SRST_MAILBOX		24
+#define SRST_I2S2CH		25
+#define SRST_EFUSE_256		26
+#define SRST_MCU_SYS		28
+#define SRST_MCU_PO		29
+#define SRST_MCU_NOC		30
+#define SRST_EFUSE		31
+
+#define SRST_GPIO0		32
+#define SRST_GPIO1		33
+#define SRST_GPIO2		34
+#define SRST_GPIO3		35
+#define SRST_GPIO4		36
+#define SRST_PMUGRF		41
+#define SRST_I2C0		42
+#define SRST_I2C1		43
+#define SRST_I2C2		44
+#define SRST_I2C3		45
+#define SRST_I2C4		46
+#define SRST_I2C5		47
+
+#define SRST_DWPWM		48
+#define SRST_MMC_PERI		49
+#define SRST_PERIPH_MMU		50
+#define SRST_GRF		55
+#define SRST_PMU		56
+#define SRST_PERIPH_AXI		57
+#define SRST_PERIPH_AHB		58
+#define SRST_PERIPH_APB		59
+#define SRST_PERIPH_NIU		60
+#define SRST_PDPERI_AHB_ARBI	61
+#define SRST_EMEM		62
+#define SRST_USB_PERI		63
+
+#define SRST_DMAC2		64
+#define SRST_MAC		66
+#define SRST_GPS		67
+#define SRST_RKPWM		69
+#define SRST_USBHOST0		72
+#define SRST_HSIC		73
+#define SRST_HSIC_AUX		74
+#define SRST_HSIC_PHY		75
+#define SRST_HSADC		76
+#define SRST_NANDC0		77
+#define SRST_SFC		79
+
+#define SRST_SPI0		83
+#define SRST_SPI1		84
+#define SRST_SPI2		85
+#define SRST_SARADC		87
+#define SRST_PDALIVE_NIU	88
+#define SRST_PDPMU_INTMEM	89
+#define SRST_PDPMU_NIU		90
+#define SRST_SGRF		91
+
+#define SRST_VIO_ARBI		96
+#define SRST_RGA_NIU		97
+#define SRST_VIO0_NIU_AXI	98
+#define SRST_VIO_NIU_AHB	99
+#define SRST_LCDC0_AXI		100
+#define SRST_LCDC0_AHB		101
+#define SRST_LCDC0_DCLK		102
+#define SRST_VIP		104
+#define SRST_RGA_CORE		105
+#define SRST_IEP_AXI		106
+#define SRST_IEP_AHB		107
+#define SRST_RGA_AXI		108
+#define SRST_RGA_AHB		109
+#define SRST_ISP		110
+#define SRST_EDP_24M		111
+
+#define SRST_VIDEO_AXI		112
+#define SRST_VIDEO_AHB		113
+#define SRST_MIPIDPHYTX		114
+#define SRST_MIPIDSI0		115
+#define SRST_MIPIDPHYRX		116
+#define SRST_MIPICSI		117
+#define SRST_GPU		120
+#define SRST_HDMI		121
+#define SRST_EDP		122
+#define SRST_PMU_PVTM		123
+#define SRST_CORE_PVTM		124
+#define SRST_GPU_PVTM		125
+#define SRST_GPU_SYS		126
+#define SRST_GPU_MEM_NIU	127
+
+#define SRST_MMC0		128
+#define SRST_SDIO0		129
+#define SRST_EMMC		131
+#define SRST_USBOTG_AHB		132
+#define SRST_USBOTG_PHY		133
+#define SRST_USBOTG_CON		134
+#define SRST_USBHOST0_AHB	135
+#define SRST_USBHOST0_PHY	136
+#define SRST_USBHOST0_CON	137
+#define SRST_USBOTG_UTMI	138
+#define SRST_USBHOST1_UTMI	139
+#define SRST_USB_ADP		141
+
+#define SRST_CORESIGHT		144
+#define SRST_PD_CORE_AHB_NOC	145
+#define SRST_PD_CORE_APB_NOC	146
+#define SRST_GIC		148
+#define SRST_LCDC_PWM0		149
+#define SRST_RGA_H2P_BRG	153
+#define SRST_VIDEO		154
+#define SRST_GPU_CFG_NIU	157
+#define SRST_TSADC		159
+
+#define SRST_DDRPHY0		160
+#define SRST_DDRPHY0_APB	161
+#define SRST_DDRCTRL0		162
+#define SRST_DDRCTRL0_APB	163
+#define SRST_VIDEO_NIU		165
+#define SRST_VIDEO_NIU_AHB	167
+#define SRST_DDRMSCH0		170
+#define SRST_PDBUS_AHB		173
+#define SRST_CRYPTO		174
+
+#define SRST_UART0		179
+#define SRST_UART1		180
+#define SRST_UART2		181
+#define SRST_UART3		182
+#define SRST_UART4		183
+#define SRST_SIMC		186
+#define SRST_TSP		188
+#define SRST_TSP_CLKIN0		189
+
+#define SRST_CORE_L0		192
+#define SRST_CORE_L1		193
+#define SRST_CORE_L2		194
+#define SRST_CORE_L3		195
+#define SRST_CORE_L0_PO		195
+#define SRST_CORE_L1_PO		197
+#define SRST_CORE_L2_PO		198
+#define SRST_CORE_L3_PO		199
+#define SRST_L2_L		200
+#define SRST_ADB_L		201
+#define SRST_PD_CORE_L_NIU	202
+#define SRST_CCI_SYS		203
+#define SRST_CCI_DDR		204
+#define SRST_CCI		205
+#define SRST_SOCDBG_L		206
+#define SRST_CORE_L_DBG		207
+
+#define SRST_CORE_B0_NC		208
+#define SRST_CORE_B0_PO_NC	209
+#define SRST_L2_B_NC		210
+#define SRST_ADB_B_NC		211
+#define SRST_PD_CORE_B_NIU_NC	212
+#define SRST_PDBUS_STRSYS_NC	213
+#define SRST_CORE_L0_NC		214
+#define SRST_CORE_L0_PO_NC	215
+#define SRST_L2_L_NC		216
+#define SRST_ADB_L_NC		217
+#define SRST_PD_CORE_L_NIU_NC	218
+#define SRST_CCI_SYS_NC		219
+#define SRST_CCI_DDR_NC		220
+#define SRST_CCI_NC		221
+#define SRST_TRACE_NC		222
+
+#define SRST_TIMER00		224
+#define SRST_TIMER01		225
+#define SRST_TIMER02		226
+#define SRST_TIMER03		227
+#define SRST_TIMER04		228
+#define SRST_TIMER05		229
+#define SRST_TIMER10		230
+#define SRST_TIMER11		231
+#define SRST_TIMER12		232
+#define SRST_TIMER13		233
+#define SRST_TIMER14		234
+#define SRST_TIMER15		235
+#define SRST_TIMER0_APB		236
+#define SRST_TIMER1_APB		237
+
+#endif
diff --git a/include/dt-bindings/clock/rv1108-cru.h b/include/dt-bindings/clock/rv1108-cru.h
new file mode 100644
index 0000000..d2ad3bb
--- /dev/null
+++ b/include/dt-bindings/clock/rv1108-cru.h
@@ -0,0 +1,269 @@
+/*
+ * Copyright (c) 2017 Rockchip Electronics Co. Ltd.
+ * Author: Shawn Lin <shawn.lin@rock-chips.com>
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RV1108_H
+#define _DT_BINDINGS_CLK_ROCKCHIP_RV1108_H
+
+/* pll id */
+#define PLL_APLL			0
+#define PLL_DPLL			1
+#define PLL_GPLL			2
+#define ARMCLK				3
+
+/* sclk gates (special clocks) */
+#define SCLK_MAC			64
+#define SCLK_SPI0			65
+#define SCLK_NANDC			67
+#define SCLK_SDMMC			68
+#define SCLK_SDIO			69
+#define SCLK_EMMC			71
+#define SCLK_UART0			72
+#define SCLK_UART1			73
+#define SCLK_UART2			74
+#define SCLK_I2S0			75
+#define SCLK_I2S1			76
+#define SCLK_I2S2			77
+#define SCLK_TIMER0			78
+#define SCLK_TIMER1			79
+#define SCLK_SFC			80
+#define SCLK_SDMMC_DRV			81
+#define SCLK_SDIO_DRV			82
+#define SCLK_EMMC_DRV			83
+#define SCLK_SDMMC_SAMPLE		84
+#define SCLK_SDIO_SAMPLE		85
+#define SCLK_EMMC_SAMPLE		86
+#define SCLK_MAC_RX			87
+#define SCLK_MAC_TX			88
+#define SCLK_MACREF			89
+#define SCLK_MACREF_OUT			90
+
+
+/* aclk gates */
+#define ACLK_DMAC			192
+#define ACLK_PRE			193
+#define ACLK_CORE			194
+#define ACLK_ENMCORE			195
+#define ACLK_GMAC			196
+
+
+/* pclk gates */
+#define PCLK_GPIO1			256
+#define PCLK_GPIO2			257
+#define PCLK_GPIO3			258
+#define PCLK_GRF			259
+#define PCLK_I2C1			260
+#define PCLK_I2C2			261
+#define PCLK_I2C3			262
+#define PCLK_SPI			263
+#define PCLK_SFC			264
+#define PCLK_UART0			265
+#define PCLK_UART1			266
+#define PCLK_UART2			267
+#define PCLK_TSADC			268
+#define PCLK_PWM			269
+#define PCLK_TIMER			270
+#define PCLK_PERI			271
+#define PCLK_GMAC			272
+
+/* hclk gates */
+#define HCLK_I2S0_8CH			320
+#define HCLK_I2S1_8CH			321
+#define HCLK_I2S2_2CH			322
+#define HCLK_NANDC			323
+#define HCLK_SDMMC			324
+#define HCLK_SDIO			325
+#define HCLK_EMMC			326
+#define HCLK_PERI			327
+#define HCLK_SFC			328
+
+#define CLK_NR_CLKS			(HCLK_SFC + 1)
+
+/* reset id */
+#define SRST_CORE_PO_AD		0
+#define SRST_CORE_AD			1
+#define SRST_L2_AD			2
+#define SRST_CPU_NIU_AD		3
+#define SRST_CORE_PO			4
+#define SRST_CORE			5
+#define SRST_L2			6
+#define SRST_CORE_DBG			8
+#define PRST_DBG			9
+#define RST_DAP			10
+#define PRST_DBG_NIU			11
+#define ARST_STRC_SYS_AD		15
+
+#define SRST_DDRPHY_CLKDIV		16
+#define SRST_DDRPHY			17
+#define PRST_DDRPHY			18
+#define PRST_HDMIPHY			19
+#define PRST_VDACPHY			20
+#define PRST_VADCPHY			21
+#define PRST_MIPI_CSI_PHY		22
+#define PRST_MIPI_DSI_PHY		23
+#define PRST_ACODEC			24
+#define ARST_BUS_NIU			25
+#define PRST_TOP_NIU			26
+#define ARST_INTMEM			27
+#define HRST_ROM			28
+#define ARST_DMAC			29
+#define SRST_MSCH_NIU			30
+#define PRST_MSCH_NIU			31
+
+#define PRST_DDRUPCTL			32
+#define NRST_DDRUPCTL			33
+#define PRST_DDRMON			34
+#define HRST_I2S0_8CH			35
+#define MRST_I2S0_8CH			36
+#define HRST_I2S1_2CH			37
+#define MRST_IS21_2CH			38
+#define HRST_I2S2_2CH			39
+#define MRST_I2S2_2CH			40
+#define HRST_CRYPTO			41
+#define SRST_CRYPTO			42
+#define PRST_SPI			43
+#define SRST_SPI			44
+#define PRST_UART0			45
+#define PRST_UART1			46
+#define PRST_UART2			47
+
+#define SRST_UART0			48
+#define SRST_UART1			49
+#define SRST_UART2			50
+#define PRST_I2C1			51
+#define PRST_I2C2			52
+#define PRST_I2C3			53
+#define SRST_I2C1			54
+#define SRST_I2C2			55
+#define SRST_I2C3			56
+#define PRST_PWM1			58
+#define SRST_PWM1			60
+#define PRST_WDT			61
+#define PRST_GPIO1			62
+#define PRST_GPIO2			63
+
+#define PRST_GPIO3			64
+#define PRST_GRF			65
+#define PRST_EFUSE			66
+#define PRST_EFUSE512			67
+#define PRST_TIMER0			68
+#define SRST_TIMER0			69
+#define SRST_TIMER1			70
+#define PRST_TSADC			71
+#define SRST_TSADC			72
+#define PRST_SARADC			73
+#define SRST_SARADC			74
+#define HRST_SYSBUS			75
+#define PRST_USBGRF			76
+
+#define ARST_PERIPH_NIU		80
+#define HRST_PERIPH_NIU		81
+#define PRST_PERIPH_NIU		82
+#define HRST_PERIPH			83
+#define HRST_SDMMC			84
+#define HRST_SDIO			85
+#define HRST_EMMC			86
+#define HRST_NANDC			87
+#define NRST_NANDC			88
+#define HRST_SFC			89
+#define SRST_SFC			90
+#define ARST_GMAC			91
+#define HRST_OTG			92
+#define SRST_OTG			93
+#define SRST_OTG_ADP			94
+#define HRST_HOST0			95
+
+#define HRST_HOST0_AUX			96
+#define HRST_HOST0_ARB			97
+#define SRST_HOST0_EHCIPHY		98
+#define SRST_HOST0_UTMI		99
+#define SRST_USBPOR			100
+#define SRST_UTMI0			101
+#define SRST_UTMI1			102
+
+#define ARST_VIO0_NIU			102
+#define ARST_VIO1_NIU			103
+#define HRST_VIO_NIU			104
+#define PRST_VIO_NIU			105
+#define ARST_VOP			106
+#define HRST_VOP			107
+#define DRST_VOP			108
+#define ARST_IEP			109
+#define HRST_IEP			110
+#define ARST_RGA			111
+#define HRST_RGA			112
+#define SRST_RGA			113
+#define PRST_CVBS			114
+#define PRST_HDMI			115
+#define SRST_HDMI			116
+#define PRST_MIPI_DSI			117
+
+#define ARST_ISP_NIU			118
+#define HRST_ISP_NIU			119
+#define HRST_ISP			120
+#define SRST_ISP			121
+#define ARST_VIP0			122
+#define HRST_VIP0			123
+#define PRST_VIP0			124
+#define ARST_VIP1			125
+#define HRST_VIP1			126
+#define PRST_VIP1			127
+#define ARST_VIP2			128
+#define HRST_VIP2			129
+#define PRST_VIP2			120
+#define ARST_VIP3			121
+#define HRST_VIP3			122
+#define PRST_VIP4			123
+
+#define PRST_CIF1TO4			124
+#define SRST_CVBS_CLK			125
+#define HRST_CVBS			126
+
+#define ARST_VPU_NIU			140
+#define HRST_VPU_NIU			141
+#define ARST_VPU			142
+#define HRST_VPU			143
+#define ARST_RKVDEC_NIU		144
+#define HRST_RKVDEC_NIU		145
+#define ARST_RKVDEC			146
+#define HRST_RKVDEC			147
+#define SRST_RKVDEC_CABAC		148
+#define SRST_RKVDEC_CORE		149
+#define ARST_RKVENC_NIU		150
+#define HRST_RKVENC_NIU		151
+#define ARST_RKVENC			152
+#define HRST_RKVENC			153
+#define SRST_RKVENC_CORE		154
+
+#define SRST_DSP_CORE			156
+#define SRST_DSP_SYS			157
+#define SRST_DSP_GLOBAL		158
+#define SRST_DSP_OECM			159
+#define PRST_DSP_IOP_NIU		160
+#define ARST_DSP_EPP_NIU		161
+#define ARST_DSP_EDP_NIU		162
+#define PRST_DSP_DBG_NIU		163
+#define PRST_DSP_CFG_NIU		164
+#define PRST_DSP_GRF			165
+#define PRST_DSP_MAILBOX		166
+#define PRST_DSP_INTC			167
+#define PRST_DSP_PFM_MON		169
+#define SRST_DSP_PFM_MON		170
+#define ARST_DSP_EDAP_NIU		171
+
+#define SRST_PMU			172
+#define SRST_PMU_I2C0			173
+#define PRST_PMU_I2C0			174
+#define PRST_PMU_GPIO0			175
+#define PRST_PMU_INTMEM		176
+#define PRST_PMU_PWM0			177
+#define SRST_PMU_PWM0			178
+#define PRST_PMU_GRF			179
+#define SRST_PMU_NIU			180
+#define SRST_PMU_PVTM			181
+#define ARST_DSP_EDP_PERF		184
+#define ARST_DSP_EPP_PERF		185
+
+#endif /* _DT_BINDINGS_CLK_ROCKCHIP_RV1108_H */
diff --git a/include/usb/dwc2_udc.h b/include/usb/dwc2_udc.h
index 7324d8a..1a370e0 100644
--- a/include/usb/dwc2_udc.h
+++ b/include/usb/dwc2_udc.h
@@ -16,7 +16,7 @@
 	int		phy_of_node;
 	int		(*phy_control)(int on);
 	unsigned int	regs_phy;
-	unsigned int	regs_otg;
+	uintptr_t	regs_otg;
 	unsigned int    usb_phy_ctrl;
 	unsigned int    usb_flags;
 	unsigned int	usb_gusbcfg;
diff --git a/tools/rkcommon.c b/tools/rkcommon.c
index 8283a74..fd95abc 100644
--- a/tools/rkcommon.c
+++ b/tools/rkcommon.c
@@ -2,6 +2,8 @@
  * (C) Copyright 2015 Google,  Inc
  * Written by Simon Glass <sjg@chromium.org>
  *
+ * (C) 2017 Theobroma Systems Design und Consulting GmbH
+ *
  * SPDX-License-Identifier:	GPL-2.0+
  *
  * Helper functions for Rockchip images
@@ -75,6 +77,7 @@
 	{ "rk3288", "RK32", 0x8000, false, false },
 	{ "rk3328", "RK32", 0x8000 - 0x1000, false, false },
 	{ "rk3399", "RK33", 0x20000, false, true },
+	{ "rv1108", "RK11", 0x1800, false, false},
 };
 
 static unsigned char rc4_key[16] = {
@@ -182,11 +185,14 @@
 	 */
 	hdr->init_size = ROUND(hdr->init_size, 4);
 	/*
-	 * The images we create do not contain the stage following the SPL as
-	 * part of the SPL image, so the init_boot_size (which might have been
-	 * read by Rockchip's miniloder) should be the same as the init_size.
+	 * init_boot_size needs to be set, as it is read by the BootROM
+	 * to determine the size of the next-stage bootloader (e.g. U-Boot
+	 * proper), when used with the back-to-bootrom functionality.
+	 *
+	 * see https://lists.denx.de/pipermail/u-boot/2017-May/293267.html
+	 * for a more detailed explanation by Andy Yan
 	 */
-	hdr->init_boot_size = hdr->init_size;
+	hdr->init_boot_size = hdr->init_size + RK_MAX_BOOT_SIZE / RK_BLK_SIZE;
 
 	rc4_encode(buf, RK_BLK_SIZE, rc4_key);
 }
@@ -201,7 +207,7 @@
 
 	rkcommon_set_header0(buf, file_size, params);
 
-	/* Set up the SPL name */
+	/* Set up the SPL name (i.e. copy spl_hdr over) */
 	memcpy(&hdr->magic, rkcommon_get_spl_hdr(params), RK_SPL_HDR_SIZE);
 
 	if (rkcommon_need_rc4_spl(params))
@@ -211,6 +217,121 @@
 	return 0;
 }
 
+static inline unsigned rkcommon_offset_to_spi(unsigned offset)
+{
+	/*
+	 * While SD/MMC images use a flat addressing, SPI images are padded
+	 * to use the first 2K of every 4K sector only.
+	 */
+	return ((offset & ~0x7ff) << 1) + (offset & 0x7ff);
+}
+
+static inline unsigned rkcommon_spi_to_offset(unsigned offset)
+{
+	return ((offset & ~0x7ff) >> 1) + (offset & 0x7ff);
+}
+
+static int rkcommon_parse_header(const void *buf, struct header0_info *header0,
+				 struct spl_info **spl_info)
+{
+	unsigned hdr1_offset;
+	struct header1_info *hdr1_sdmmc, *hdr1_spi;
+	int i;
+
+	if (spl_info)
+		*spl_info = NULL;
+
+	/*
+	 * The first header (hdr0) is always RC4 encoded, so try to decrypt
+	 * with the well-known key.
+	 */
+	memcpy((void *)header0, buf, sizeof(struct header0_info));
+	rc4_encode((void *)header0, sizeof(struct header0_info), rc4_key);
+
+	if (header0->signature != RK_SIGNATURE)
+		return -EPROTO;
+
+	/* We don't support RC4 encoded image payloads here, yet... */
+	if (header0->disable_rc4 == 0)
+		return -ENOSYS;
+
+	hdr1_offset = header0->init_offset * RK_BLK_SIZE;
+	hdr1_sdmmc = (struct header1_info *)(buf + hdr1_offset);
+	hdr1_spi = (struct header1_info *)(buf +
+					   rkcommon_offset_to_spi(hdr1_offset));
+
+	for (i = 0; i < ARRAY_SIZE(spl_infos); i++) {
+		if (!memcmp(&hdr1_sdmmc->magic, spl_infos[i].spl_hdr, 4)) {
+			if (spl_info)
+				*spl_info = &spl_infos[i];
+			return IH_TYPE_RKSD;
+		} else if (!memcmp(&hdr1_spi->magic, spl_infos[i].spl_hdr, 4)) {
+			if (spl_info)
+				*spl_info = &spl_infos[i];
+			return IH_TYPE_RKSPI;
+		}
+	}
+
+	return -1;
+}
+
+int rkcommon_verify_header(unsigned char *buf, int size,
+			   struct image_tool_params *params)
+{
+	struct header0_info header0;
+	struct spl_info *img_spl_info, *spl_info;
+	int ret;
+
+	ret = rkcommon_parse_header(buf, &header0, &img_spl_info);
+
+	/* If this is the (unimplemented) RC4 case, then rewrite the result */
+	if (ret == -ENOSYS)
+		return 0;
+
+	if (ret < 0)
+		return ret;
+
+	/*
+	 * If no 'imagename' is specified via the commandline (e.g. if this is
+	 * 'dumpimage -l' w/o any further constraints), we accept any spl_info.
+	 */
+	if (params->imagename == NULL)
+		return 0;
+
+	/* Match the 'imagename' against the 'spl_hdr' found */
+	spl_info = rkcommon_get_spl_info(params->imagename);
+	if (spl_info && img_spl_info)
+		return strcmp(spl_info->spl_hdr, img_spl_info->spl_hdr);
+
+	return -ENOENT;
+}
+
+void rkcommon_print_header(const void *buf)
+{
+	struct header0_info header0;
+	struct spl_info *spl_info;
+	uint8_t image_type;
+	int ret;
+
+	ret = rkcommon_parse_header(buf, &header0, &spl_info);
+
+	/* If this is the (unimplemented) RC4 case, then fail silently */
+	if (ret == -ENOSYS)
+		return;
+
+	if (ret < 0) {
+		fprintf(stderr, "Error: image verification failed\n");
+		return;
+	}
+
+	image_type = ret;
+
+	printf("Image Type:   Rockchip %s (%s) boot image\n",
+	       spl_info->spl_hdr,
+	       (image_type == IH_TYPE_RKSD) ? "SD/MMC" : "SPI");
+	printf("Data Size:    %d bytes\n", header0.init_size * RK_BLK_SIZE);
+}
+
 void rkcommon_rc4_encode_spl(void *buf, unsigned int offset, unsigned int size)
 {
 	unsigned int remaining = size;
diff --git a/tools/rkcommon.h b/tools/rkcommon.h
index a21321f..8790f1c 100644
--- a/tools/rkcommon.h
+++ b/tools/rkcommon.h
@@ -10,6 +10,7 @@
 
 enum {
 	RK_BLK_SIZE		= 512,
+	RK_INIT_SIZE_ALIGN      = 2048,
 	RK_INIT_OFFSET		= 4,
 	RK_MAX_BOOT_SIZE	= 512 << 10,
 	RK_SPL_HDR_START	= RK_INIT_OFFSET * RK_BLK_SIZE,
@@ -56,6 +57,25 @@
 			struct image_tool_params *params);
 
 /**
+ * rkcommon_verify_header() - verify the header for a Rockchip boot image
+ *
+ * @buf:	Pointer to the image file
+ * @file_size:	Size of entire bootable image file (incl. all padding)
+ * @return 0 if OK
+ */
+int rkcommon_verify_header(unsigned char *buf, int size,
+			   struct image_tool_params *params);
+
+/**
+ * rkcommon_print_header() - print the header for a Rockchip boot image
+ *
+ * This prints the header, spl_name and whether this is a SD/MMC or SPI image.
+ *
+ * @buf:	Pointer to the image (can be a read-only file-mapping)
+ */
+void rkcommon_print_header(const void *buf);
+
+/**
  * rkcommon_need_rc4_spl() - check if rc4 encoded spl is required
  *
  * Some socs cannot disable the rc4-encryption of the spl binary.
diff --git a/tools/rksd.c b/tools/rksd.c
index 8627b6d..c56153d 100644
--- a/tools/rksd.c
+++ b/tools/rksd.c
@@ -13,29 +13,17 @@
 #include "mkimage.h"
 #include "rkcommon.h"
 
-static int rksd_verify_header(unsigned char *buf,  int size,
-				 struct image_tool_params *params)
-{
-	return 0;
-}
-
-static void rksd_print_header(const void *buf)
-{
-}
-
 static void rksd_set_header(void *buf,  struct stat *sbuf,  int ifd,
-			       struct image_tool_params *params)
+			    struct image_tool_params *params)
 {
 	unsigned int size;
 	int ret;
 
-	printf("params->file_size %d\n", params->file_size);
-	printf("params->orig_file_size %d\n", params->orig_file_size);
-
 	/*
 	 * We need to calculate this using 'RK_SPL_HDR_START' and not using
 	 * 'tparams->header_size', as the additional byte inserted when
-	 * 'is_boot0' is true counts towards the payload.
+	 * 'is_boot0' is true counts towards the payload (and not towards the
+	 * header).
 	 */
 	size = params->file_size - RK_SPL_HDR_START;
 	ret = rkcommon_set_header(buf, size, params);
@@ -46,11 +34,6 @@
 	}
 }
 
-static int rksd_extract_subimage(void *buf,  struct image_tool_params *params)
-{
-	return 0;
-}
-
 static int rksd_check_image_type(uint8_t type)
 {
 	if (type == IH_TYPE_RKSD)
@@ -63,10 +46,10 @@
 			    struct image_type_params *tparams)
 {
 	/*
-	 * Pad to the RK_BLK_SIZE (512 bytes) to be consistent with init_size
-	 * being encoded in RK_BLK_SIZE units in header0 (see rkcommon.c).
+	 * Pad to a 2KB alignment, as required for init_size by the ROM
+	 * (see https://lists.denx.de/pipermail/u-boot/2017-May/293268.html)
 	 */
-	return rkcommon_vrec_header(params, tparams, RK_BLK_SIZE);
+	return rkcommon_vrec_header(params, tparams, RK_INIT_SIZE_ALIGN);
 }
 
 /*
@@ -78,10 +61,10 @@
 	0,
 	NULL,
 	rkcommon_check_params,
-	rksd_verify_header,
-	rksd_print_header,
+	rkcommon_verify_header,
+	rkcommon_print_header,
 	rksd_set_header,
-	rksd_extract_subimage,
+	NULL,
 	rksd_check_image_type,
 	NULL,
 	rksd_vrec_header
diff --git a/tools/rkspi.c b/tools/rkspi.c
index 87bd1a9..4332ce1 100644
--- a/tools/rkspi.c
+++ b/tools/rkspi.c
@@ -17,16 +17,6 @@
 	RKSPI_SECT_LEN		= RK_BLK_SIZE * 4,
 };
 
-static int rkspi_verify_header(unsigned char *buf, int size,
-			       struct image_tool_params *params)
-{
-	return 0;
-}
-
-static void rkspi_print_header(const void *buf)
-{
-}
-
 static void rkspi_set_header(void *buf, struct stat *sbuf, int ifd,
 			     struct image_tool_params *params)
 {
@@ -58,11 +48,6 @@
 	}
 }
 
-static int rkspi_extract_subimage(void *buf, struct image_tool_params *params)
-{
-	return 0;
-}
-
 static int rkspi_check_image_type(uint8_t type)
 {
 	if (type == IH_TYPE_RKSPI)
@@ -78,7 +63,7 @@
 static int rkspi_vrec_header(struct image_tool_params *params,
 			     struct image_type_params *tparams)
 {
-	int padding = rkcommon_vrec_header(params, tparams, 2048);
+	int padding = rkcommon_vrec_header(params, tparams, RK_INIT_SIZE_ALIGN);
 	/*
 	 * The file size has not been adjusted at this point (our caller will
 	 * eventually add the header/padding to the file_size), so we need to
@@ -112,10 +97,10 @@
 	0,
 	NULL,
 	rkcommon_check_params,
-	rkspi_verify_header,
-	rkspi_print_header,
+	rkcommon_verify_header,
+	rkcommon_print_header,
 	rkspi_set_header,
-	rkspi_extract_subimage,
+	NULL,
 	rkspi_check_image_type,
 	NULL,
 	rkspi_vrec_header