Merge tag 'mmc-2021-4-6' of https://source.denx.de/u-boot/custodians/u-boot-mmc

Update hwpartition usage
Check bootbus's arguments
workaround for erratum A-011334 for fsl_esdhc driver
add pulse width detection workaround for fsl_esdhc driver
Use alias num before checking mmc index when creating device
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 9a8de46..cedddd3 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -114,7 +114,7 @@
 	rk3328-rock-pi-e.dtb
 
 dtb-$(CONFIG_ROCKCHIP_RK3368) += \
-	rk3368-lion.dtb \
+	rk3368-lion-haikou.dtb \
 	rk3368-sheep.dtb \
 	rk3368-geekbox.dtb \
 	rk3368-px5-evb.dtb \
@@ -131,7 +131,9 @@
 	rk3399-nanopc-t4.dtb \
 	rk3399-nanopi-m4.dtb \
 	rk3399-nanopi-m4-2gb.dtb \
+	rk3399-nanopi-m4b.dtb \
 	rk3399-nanopi-neo4.dtb \
+	rk3399-nanopi-r4s.dtb \
 	rk3399-orangepi.dtb \
 	rk3399-pinebook-pro.dtb \
 	rk3399-puma-haikou.dtb \
diff --git a/arch/arm/dts/rk3368-geekbox-u-boot.dtsi b/arch/arm/dts/rk3368-geekbox-u-boot.dtsi
index 30ea9e4..0b724fa 100644
--- a/arch/arm/dts/rk3368-geekbox-u-boot.dtsi
+++ b/arch/arm/dts/rk3368-geekbox-u-boot.dtsi
@@ -3,6 +3,8 @@
  * (C) Copyright 2017 Theobroma Systems Design und Consulting GmbH
  */
 
+#include "rk3368-u-boot.dtsi"
+
 &pinctrl {
 	u-boot,dm-pre-reloc;
 };
diff --git a/arch/arm/dts/rk3368-lion-u-boot.dtsi b/arch/arm/dts/rk3368-lion-haikou-u-boot.dtsi
similarity index 96%
rename from arch/arm/dts/rk3368-lion-u-boot.dtsi
rename to arch/arm/dts/rk3368-lion-haikou-u-boot.dtsi
index 6d54214d..7826d1e 100644
--- a/arch/arm/dts/rk3368-lion-u-boot.dtsi
+++ b/arch/arm/dts/rk3368-lion-haikou-u-boot.dtsi
@@ -3,6 +3,8 @@
  * (C) Copyright 2017 Theobroma Systems Design und Consulting GmbH
  */
 
+#include "rk3368-u-boot.dtsi"
+
 / {
 	config {
 		u-boot,spl-payload-offset = <0x40000>; /* @ 256KB */
@@ -36,6 +38,10 @@
 	};
 };
 
+&gpio2 {
+	u-boot,dm-pre-reloc;
+};
+
 &pinctrl {
 	u-boot,dm-pre-reloc;
 };
diff --git a/arch/arm/dts/rk3368-lion-haikou.dts b/arch/arm/dts/rk3368-lion-haikou.dts
new file mode 100644
index 0000000..7fcb1ea
--- /dev/null
+++ b/arch/arm/dts/rk3368-lion-haikou.dts
@@ -0,0 +1,140 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2018 Theobroma Systems Design und Consulting GmbH
+ */
+
+/dts-v1/;
+#include "rk3368-lion.dtsi"
+
+/ {
+	model = "Theobroma Systems RK3368-uQ7 Baseboard";
+	compatible = "tsd,rk3368-lion-haikou", "rockchip,rk3368";
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	i2cmux2 {
+		i2c@0 {
+			eeprom: eeprom@50 {
+				compatible = "atmel,24c01";
+				pagesize = <8>;
+				reg = <0x50>;
+			};
+		};
+	};
+
+	leds {
+		pinctrl-0 = <&module_led_pins>, <&sd_card_led_pin>;
+
+		sd_card_led: led-3 {
+			label = "sd_card_led";
+			gpios = <&gpio0 RK_PD2 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "mmc0";
+		};
+	};
+
+	dc_12v: dc-12v {
+		compatible = "regulator-fixed";
+		regulator-name = "dc_12v";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <12000000>;
+		regulator-max-microvolt = <12000000>;
+	};
+
+	vcc3v3_baseboard: vcc3v3-baseboard {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc3v3_baseboard";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&dc_12v>;
+	};
+
+	vcc5v0_otg: vcc5v0-otg-regulator {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio0 RK_PD4 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&otg_vbus_drv>;
+		regulator-name = "vcc5v0_otg";
+		regulator-always-on;
+	};
+};
+
+&sdmmc {
+	bus-width = <4>;
+	cap-mmc-highspeed;
+	cap-sd-highspeed;
+	cd-gpios = <&gpio2 RK_PB3 GPIO_ACTIVE_LOW>;
+	disable-wp;
+	max-frequency = <25000000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_bus4>;
+	rockchip,default-sample-phase = <90>;
+	vmmc-supply = <&vcc3v3_baseboard>;
+	status = "okay";
+};
+
+&spi2 {
+	cs-gpios = <0>, <&gpio2 RK_PC3 GPIO_ACTIVE_LOW>;
+	status = "okay";
+};
+
+&usb_otg {
+	dr_mode = "otg";
+	status = "okay";
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>;
+	status = "okay";
+};
+
+&uart1 {
+	/* alternate function of GPIO5/6 */
+	status = "disabled";
+};
+
+&pinctrl {
+	pinctrl-names = "default";
+	pinctrl-0 = <&haikou_pin_hog>;
+
+	hog {
+		haikou_pin_hog: haikou-pin-hog {
+			rockchip,pins =
+				/* LID_BTN */
+				<3 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>,
+				/* BATLOW# */
+				<0 RK_PD6 RK_FUNC_GPIO &pcfg_pull_up>,
+				/* SLP_BTN# */
+				<3 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>,
+				/* BIOS_DISABLE# */
+				<3 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+
+	leds {
+		sd_card_led_pin: sd-card-led-pin {
+			rockchip,pins =
+				<0 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	sdmmc {
+		sdmmc_cd_pin: sdmmc-cd-pin {
+			rockchip,pins =
+				<2 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	usb_otg {
+		otg_vbus_drv: otg-vbus-drv {
+			rockchip,pins =
+				<0 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+};
diff --git a/arch/arm/dts/rk3368-lion.dts b/arch/arm/dts/rk3368-lion.dts
deleted file mode 100644
index 2814542..0000000
--- a/arch/arm/dts/rk3368-lion.dts
+++ /dev/null
@@ -1,194 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+ OR X11
-/*
- * (C) Copyright 2017 Theobroma Systems Design und Consulting GmbH
- */
-
-/dts-v1/;
-#include "rk3368.dtsi"
-#include "rk3368-lion-u-boot.dtsi"
-#include <dt-bindings/input/input.h>
-
-/ {
-	model = "Theobroma Systems RK3368-uQ7 SoM";
-	compatible = "tsd,rk3368-uq7", "tsd,lion", "rockchip,rk3368";
-
-	aliases {
-		mmc0 = &emmc;
-		mmc1 = &sdmmc;
-	};
-
-	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>;
-	};
-
-	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;
-	};
-};
-
-&uart0 {
-	status = "okay";
-};
-
-&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 = <&vcc33_io>;
-	vqmmc-supply = <&vcc18_io>;
-	pinctrl-names = "default";
-	pinctrl-0 = <&emmc_clk>, <&emmc_cmd>, <&emmc_bus8>;
-};
-
-&sdmmc {
-	status = "okay";
-};
-
-&gmac {
-	status = "okay";
-	phy-supply = <&vcc33_io>;
-	phy-mode = "rgmii";
-	clock_in_out = "input";
-	snps,reset-gpio = <&gpio3 RK_PB3 GPIO_ACTIVE_LOW>;
-	snps,reset-active-low;
-	snps,reset-delays-us = <2 10000 50000>;
-	assigned-clocks = <&cru SCLK_MAC>;
-	assigned-clock-parents = <&ext_gmac>;
-	pinctrl-names = "default";
-	pinctrl-0 = <&rgmii_pins>;
-	tx_delay = <0x10>;
-	rx_delay = <0x10>;
-};
-
-&i2c0 {
-	status = "okay";
-
-	rk808: pmic@1b {
-		compatible = "rockchip,rk808";
-		reg = <0x1b>;
-		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_sys>;
-		vcc9-supply = <&vcc_sys>;
-		vcc10-supply = <&vcc_sys>;
-		vcc11-supply = <&vcc_sys>;
-		vcc12-supply = <&vcc_sys>;
-		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";
-			};
-
-			vcc33_io: DCDC_REG4 {
-				regulator-always-on;
-				regulator-boot-on;
-				regulator-min-microvolt = <3300000>;
-				regulator-max-microvolt = <3300000>;
-				regulator-name = "vcc33_io";
-			};
-
-			vcc33_video: LDO_REG2 {
-				regulator-always-on;
-				regulator-boot-on;
-				regulator-min-microvolt = <3300000>;
-				regulator-max-microvolt = <3300000>;
-				regulator-name = "vcc33_video";
-			};
-
-			vdd10_pll: LDO_REG3 {
-				regulator-always-on;
-				regulator-boot-on;
-				regulator-min-microvolt = <1000000>;
-				regulator-max-microvolt = <1000000>;
-				regulator-name = "vdd10_pll";
-			};
-
-			vcc18_io: LDO_REG4 {
-				regulator-boot-on;
-				regulator-min-microvolt = <1800000>;
-				regulator-max-microvolt = <1800000>;
-				regulator-name = "vcc18_io";
-			};
-
-			vdd10_video: LDO_REG6 {
-				regulator-always-on;
-				regulator-boot-on;
-				regulator-min-microvolt = <1000000>;
-				regulator-max-microvolt = <1000000>;
-				regulator-name = "vdd10_video";
-			};
-
-			vcc18_video: LDO_REG8 {
-				regulator-always-on;
-				regulator-boot-on;
-				regulator-min-microvolt = <1800000>;
-				regulator-max-microvolt = <1800000>;
-				regulator-name = "vcc18_video";
-			};
-		};
-	};
-};
-
-&uart0 {
-	status = "okay";
-};
-
-&spi1 {
-	status = "okay";
-
-	#address-cells = <1>;
-	#size-cells = <0>;
-
-	spiflash: w25q32dw@0 {
-		compatible = "jedec,spi-nor";
-		reg = <0>;
-		spi-max-frequency = <49500000>;
-		spi-cpol;
-		spi-cpha;
-	};
-};
diff --git a/arch/arm/dts/rk3368-lion.dtsi b/arch/arm/dts/rk3368-lion.dtsi
new file mode 100644
index 0000000..532e6a6
--- /dev/null
+++ b/arch/arm/dts/rk3368-lion.dtsi
@@ -0,0 +1,331 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2018 Theobroma Systems Design und Consulting GmbH
+ */
+
+/dts-v1/;
+#include "rk3368.dtsi"
+
+/ {
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	ext_gmac: gmac-clk {
+		compatible = "fixed-clock";
+		clock-frequency = <125000000>;
+		clock-output-names = "ext_gmac";
+		#clock-cells = <0>;
+	};
+
+	i2cmux1 {
+		compatible = "i2c-mux-gpio";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		i2c-parent = <&i2c1>;
+		mux-gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_HIGH>;
+
+		/* Q7_GPO_I2C */
+		i2c@0 {
+			reg = <0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		/* Q7_SMB */
+		i2c@1 {
+			reg = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+	};
+
+	i2cmux2 {
+		compatible = "i2c-mux-gpio";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		i2c-parent = <&i2c2>;
+		mux-gpios = <&gpio1 RK_PB4 GPIO_ACTIVE_HIGH>;
+
+		/* Q7_LVDS_BLC_I2C */
+		i2c@0 {
+			reg = <0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			fan: fan@18 {
+				compatible = "ti,amc6821";
+				reg = <0x18>;
+				#cooling-cells = <2>;
+			};
+
+			rtc_twi: rtc@6f {
+				compatible = "isil,isl1208";
+				reg = <0x6f>;
+			};
+		};
+
+		/* Q7_GP2_I2C */
+		i2c@1 {
+			reg = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&module_led_pins>;
+
+		module_led1: led-1 {
+			label = "module_led1";
+			gpios = <&gpio2 RK_PB5 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "heartbeat";
+			panic-indicator;
+		};
+
+		module_led2: led-2 {
+			label = "module_led2";
+			gpios = <&gpio3 RK_PA3 GPIO_ACTIVE_HIGH>;
+			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;
+	};
+};
+
+&cpu_l0 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+&cpu_l1 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+&cpu_l2 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+&cpu_l3 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+&cpu_b0 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+&cpu_b1 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+&cpu_b2 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+&cpu_b3 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+&emmc {
+	bus-width = <8>;
+	clock-frequency = <150000000>;
+	mmc-hs200-1_8v;
+	non-removable;
+	vmmc-supply = <&vcc33_io>;
+	vqmmc-supply = <&vcc18_io>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&emmc_clk>, <&emmc_cmd>, <&emmc_bus8>;
+	status = "okay";
+};
+
+&gmac {
+	assigned-clocks = <&cru SCLK_MAC>;
+	assigned-clock-parents = <&ext_gmac>;
+	clock_in_out = "input";
+	phy-handle = <&phy0>;
+	phy-supply = <&vcc33_io>;
+	phy-mode = "rgmii";
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii_pins>;
+	snps,reset-active-low;
+	snps,reset-delays-us = <0 10000 50000>;
+	snps,reset-gpio = <&gpio3 RK_PB3 GPIO_ACTIVE_LOW>;
+	tx_delay = <0x10>;
+	rx_delay = <0x10>;
+	status = "okay";
+
+	mdio {
+		compatible = "snps,dwmac-mdio";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		/* Microsemi VSC8531-02 */
+		phy0: phy@0 {
+		compatible = "ethernet-phy-id0007.0570";
+			reg = <0>;
+			vsc8531,clk-out-frequency = <125000000>;
+			vsc8531,edge-slowdown = <7>;
+			vsc8531,led-0-mode = <1>;
+			vsc8531,led-1-mode = <2>;
+		};
+	};
+};
+
+&i2c0 {
+	status = "okay";
+
+	rk808: pmic@1b {
+		compatible = "rockchip,rk808";
+		reg = <0x1b>;
+		interrupt-parent = <&gpio0>;
+		interrupts = <RK_PA5 IRQ_TYPE_LEVEL_LOW>;
+		clock-output-names = "xin32k", "rk808-clkout2";
+		#clock-cells = <1>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pmic_int_l>, <&pmic_sleep>;
+		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_sys>;
+		vcc9-supply = <&vcc_sys>;
+		vcc10-supply = <&vcc_sys>;
+		vcc11-supply = <&vcc_sys>;
+		vcc12-supply = <&vcc_sys>;
+
+		regulators {
+			vdd_cpu: DCDC_REG1 {
+				regulator-name = "vdd_cpu";
+				regulator-min-microvolt = <700000>;
+				regulator-max-microvolt = <1500000>;
+				regulator-always-on;
+				regulator-boot-on;
+			};
+
+			vdd_log: DCDC_REG2 {
+				regulator-name = "vdd_log";
+				regulator-min-microvolt = <700000>;
+				regulator-max-microvolt = <1500000>;
+				regulator-always-on;
+				regulator-boot-on;
+			};
+
+			vcc_ddr: DCDC_REG3 {
+				regulator-name = "vcc_ddr";
+				regulator-always-on;
+				regulator-boot-on;
+			};
+
+			vcc33_io: DCDC_REG4 {
+				regulator-name = "vcc33_io";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-always-on;
+				regulator-boot-on;
+			};
+
+			vcc33_video: LDO_REG2 {
+				regulator-name = "vcc33_video";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-always-on;
+				regulator-boot-on;
+			};
+
+			vdd10_pll: LDO_REG3 {
+				regulator-name = "vdd10_pll";
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <1000000>;
+				regulator-always-on;
+				regulator-boot-on;
+			};
+
+			vcc18_io: LDO_REG4 {
+				regulator-name = "vcc18_io";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-boot-on;
+			};
+
+			vdd10_video: LDO_REG6 {
+				regulator-name = "vdd10_video";
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <1000000>;
+				regulator-always-on;
+				regulator-boot-on;
+			};
+
+			vcc18_video: LDO_REG8 {
+				regulator-name = "vcc18_video";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
+				regulator-boot-on;
+			};
+		};
+	};
+};
+
+&i2c1 {
+	status = "okay";
+};
+
+&i2c2 {
+	status = "okay";
+};
+
+&pinctrl {
+	leds {
+		module_led_pins: module-led-pins {
+			rockchip,pins =
+				<2 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>,
+				<3 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+	pmic {
+		pmic_int_l: pmic-int-l {
+			rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+
+		pmic_sleep: pmic-sleep {
+			rockchip,pins = <0 RK_PA0 2 &pcfg_pull_none>;
+		};
+	};
+};
+
+&spi1 {
+	status = "okay";
+
+	norflash: flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <50000000>;
+	};
+};
+
+&uart1 {
+	status = "okay";
+};
+
+&uart3 {
+	status = "okay";
+};
+
+&usb_host0_ehci {
+	status = "okay";
+};
+
+&wdt {
+	status = "okay";
+};
diff --git a/arch/arm/dts/rk3368-px5-evb-u-boot.dtsi b/arch/arm/dts/rk3368-px5-evb-u-boot.dtsi
index 936ce55..264fb7a 100644
--- a/arch/arm/dts/rk3368-px5-evb-u-boot.dtsi
+++ b/arch/arm/dts/rk3368-px5-evb-u-boot.dtsi
@@ -2,6 +2,9 @@
 /*
  * (C) Copyright 2017 Theobroma Systems Design und Consulting GmbH
  */
+
+#include "rk3368-u-boot.dtsi"
+
 / {
 	chosen {
 		u-boot,spl-boot-order = &emmc;
diff --git a/arch/arm/dts/rk3368-sheep-u-boot.dtsi b/arch/arm/dts/rk3368-sheep-u-boot.dtsi
index 30ea9e4..0b724fa 100644
--- a/arch/arm/dts/rk3368-sheep-u-boot.dtsi
+++ b/arch/arm/dts/rk3368-sheep-u-boot.dtsi
@@ -3,6 +3,8 @@
  * (C) Copyright 2017 Theobroma Systems Design und Consulting GmbH
  */
 
+#include "rk3368-u-boot.dtsi"
+
 &pinctrl {
 	u-boot,dm-pre-reloc;
 };
diff --git a/arch/arm/dts/rk3368-u-boot.dtsi b/arch/arm/dts/rk3368-u-boot.dtsi
new file mode 100644
index 0000000..2767c26
--- /dev/null
+++ b/arch/arm/dts/rk3368-u-boot.dtsi
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2020 Theobroma Systems Design und Consulting GmbH
+ */
+
+#include <dt-bindings/memory/rk3368-dmc.h>
+
+/ {
+	dmc: dmc@ff610000 {
+		compatible = "rockchip,rk3368-dmc", "syscon";
+		rockchip,cru = <&cru>;
+		rockchip,grf = <&grf>;
+		rockchip,msch = <&service_msch>;
+		reg = <0 0xff610000 0 0x400
+		       0 0xff620000 0 0x400>;
+	};
+
+	service_msch: syscon@ffac0000 {
+		compatible = "rockchip,rk3368-msch", "syscon";
+		reg = <0x0 0xffac0000 0x0 0x2000>;
+	};
+
+	sgrf: syscon@ff740000 {
+		compatible = "rockchip,rk3368-sgrf", "syscon";
+		reg = <0x0 0xff740000 0x0 0x1000>;
+	};
+};
diff --git a/arch/arm/dts/rk3368.dtsi b/arch/arm/dts/rk3368.dtsi
index b4f4f61..cd2c322 100644
--- a/arch/arm/dts/rk3368.dtsi
+++ b/arch/arm/dts/rk3368.dtsi
@@ -1,43 +1,6 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * 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>
@@ -45,8 +8,8 @@
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/soc/rockchip,boot-mode.h>
 #include <dt-bindings/thermal/thermal.h>
-#include <dt-bindings/memory/rk3368-dmc.h>
 
 / {
 	compatible = "rockchip,rk3368";
@@ -108,84 +71,99 @@
 			};
 		};
 
-		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";
+			compatible = "arm,cortex-a53";
 			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";
+			compatible = "arm,cortex-a53";
 			reg = <0x0 0x1>;
-			cpu-idle-states = <&cpu_sleep>;
 			enable-method = "psci";
+			#cooling-cells = <2>; /* min followed by max */
 		};
 
 		cpu_l2: cpu@2 {
 			device_type = "cpu";
-			compatible = "arm,cortex-a53", "arm,armv8";
+			compatible = "arm,cortex-a53";
 			reg = <0x0 0x2>;
-			cpu-idle-states = <&cpu_sleep>;
 			enable-method = "psci";
+			#cooling-cells = <2>; /* min followed by max */
 		};
 
 		cpu_l3: cpu@3 {
 			device_type = "cpu";
-			compatible = "arm,cortex-a53", "arm,armv8";
+			compatible = "arm,cortex-a53";
 			reg = <0x0 0x3>;
-			cpu-idle-states = <&cpu_sleep>;
 			enable-method = "psci";
+			#cooling-cells = <2>; /* min followed by max */
 		};
 
 		cpu_b0: cpu@100 {
 			device_type = "cpu";
-			compatible = "arm,cortex-a53", "arm,armv8";
+			compatible = "arm,cortex-a53";
 			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";
+			compatible = "arm,cortex-a53";
 			reg = <0x0 0x101>;
-			cpu-idle-states = <&cpu_sleep>;
 			enable-method = "psci";
+			#cooling-cells = <2>; /* min followed by max */
 		};
 
 		cpu_b2: cpu@102 {
 			device_type = "cpu";
-			compatible = "arm,cortex-a53", "arm,armv8";
+			compatible = "arm,cortex-a53";
 			reg = <0x0 0x102>;
-			cpu-idle-states = <&cpu_sleep>;
 			enable-method = "psci";
+			#cooling-cells = <2>; /* min followed by max */
 		};
 
 		cpu_b3: cpu@103 {
 			device_type = "cpu";
-			compatible = "arm,cortex-a53", "arm,armv8";
+			compatible = "arm,cortex-a53";
 			reg = <0x0 0x103>;
-			cpu-idle-states = <&cpu_sleep>;
 			enable-method = "psci";
+			#cooling-cells = <2>; /* min followed by max */
+		};
+	};
+
+	amba: bus {
+		compatible = "simple-bus";
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		dmac_peri: dma-controller@ff250000 {
+			compatible = "arm,pl330", "arm,primecell";
+			reg = <0x0 0xff250000 0x0 0x4000>;
+			interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
+			#dma-cells = <1>;
+			arm,pl330-broken-no-flushp;
+			arm,pl330-periph-burst;
+			clocks = <&cru ACLK_DMAC_PERI>;
+			clock-names = "apb_pclk";
+		};
+
+		dmac_bus: dma-controller@ff600000 {
+			compatible = "arm,pl330", "arm,primecell";
+			reg = <0x0 0xff600000 0x0 0x4000>;
+			interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
+			#dma-cells = <1>;
+			arm,pl330-broken-no-flushp;
+			arm,pl330-periph-burst;
+			clocks = <&cru ACLK_DMAC_BUS>;
+			clock-names = "apb_pclk";
 		};
 	};
 
@@ -228,54 +206,45 @@
 		#clock-cells = <0>;
 	};
 
-	dmc: dmc@ff610000 {
-		compatible = "rockchip,rk3368-dmc", "syscon";
-		rockchip,cru = <&cru>;
-		rockchip,grf = <&grf>;
-		rockchip,msch = <&service_msch>;
-		reg = <0 0xff610000 0 0x400
-		       0 0xff620000 0 0x400>;
-	};
-
-	service_msch: syscon@ffac0000 {
-		compatible = "rockchip,rk3368-msch", "syscon";
-		reg = <0x0 0xffac0000 0x0 0x2000>;
-		status = "okay";
-	};
-
-	sdmmc: dwmmc@ff0c0000 {
+	sdmmc: mmc@ff0c0000 {
 		compatible = "rockchip,rk3368-dw-mshc", "rockchip,rk3288-dw-mshc";
 		reg = <0x0 0xff0c0000 0x0 0x4000>;
-		clock-freq-min-max = <400000 150000000>;
+		max-frequency = <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>;
+		resets = <&cru SRST_MMC0>;
+		reset-names = "reset";
 		status = "disabled";
 	};
 
-	sdio0: dwmmc@ff0d0000 {
+	sdio0: mmc@ff0d0000 {
 		compatible = "rockchip,rk3368-dw-mshc", "rockchip,rk3288-dw-mshc";
 		reg = <0x0 0xff0d0000 0x0 0x4000>;
-		clock-freq-min-max = <400000 150000000>;
+		max-frequency = <150000000>;
 		clocks = <&cru HCLK_SDIO0>, <&cru SCLK_SDIO0>,
 			 <&cru SCLK_SDIO0_DRV>, <&cru SCLK_SDIO0_SAMPLE>;
-		clock-names = "biu", "ciu", "ciu_drv", "ciu_sample";
+		clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
 		fifo-depth = <0x100>;
 		interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+		resets = <&cru SRST_SDIO0>;
+		reset-names = "reset";
 		status = "disabled";
 	};
 
-	emmc: dwmmc@ff0f0000 {
+	emmc: mmc@ff0f0000 {
 		compatible = "rockchip,rk3368-dw-mshc", "rockchip,rk3288-dw-mshc";
 		reg = <0x0 0xff0f0000 0x0 0x4000>;
-		clock-freq-min-max = <400000 150000000>;
+		max-frequency = <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>;
+		resets = <&cru SRST_EMMC>;
+		reset-names = "reset";
 		status = "disabled";
 	};
 
@@ -286,6 +255,8 @@
 		#io-channel-cells = <1>;
 		clocks = <&cru SCLK_SARADC>, <&cru PCLK_SARADC>;
 		clock-names = "saradc", "apb_pclk";
+		resets = <&cru SRST_SARADC>;
+		reset-names = "saradc-apb";
 		status = "disabled";
 	};
 
@@ -328,16 +299,16 @@
 		status = "disabled";
 	};
 
-	i2c1: i2c@ff140000 {
+	i2c2: 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>;
+		clocks = <&cru PCLK_I2C2>;
 		pinctrl-names = "default";
-		pinctrl-0 = <&i2c1_xfer>;
+		pinctrl-0 = <&i2c2_xfer>;
 		status = "disabled";
 	};
 
@@ -389,8 +360,6 @@
 		interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
 		reg-shift = <2>;
 		reg-io-width = <4>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&uart0_xfer>;
 		status = "disabled";
 	};
 
@@ -403,8 +372,6 @@
 		interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
 		reg-shift = <2>;
 		reg-io-width = <4>;
-		pinctrl-names = "default";
-		pinctrl-1 = <&uart0_xfer>;
 		status = "disabled";
 	};
 
@@ -417,8 +384,6 @@
 		interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>;
 		reg-shift = <2>;
 		reg-io-width = <4>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&uart3_xfer>;
 		status = "disabled";
 	};
 
@@ -431,8 +396,6 @@
 		interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>;
 		reg-shift = <2>;
 		reg-io-width = <4>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&uart4_xfer>;
 		status = "disabled";
 	};
 
@@ -465,12 +428,18 @@
 				map0 {
 					trip = <&cpu_alert0>;
 					cooling-device =
-					<&cpu_b0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+					<&cpu_b0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+					<&cpu_b1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+					<&cpu_b2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+					<&cpu_b3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
 				};
 				map1 {
 					trip = <&cpu_alert1>;
 					cooling-device =
-					<&cpu_l0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+					<&cpu_l0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+					<&cpu_l1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+					<&cpu_l2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+					<&cpu_l3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
 				};
 			};
 		};
@@ -498,7 +467,10 @@
 				map0 {
 					trip = <&gpu_alert0>;
 					cooling-device =
-					<&cpu_b0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+					<&cpu_b0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+					<&cpu_b1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+					<&cpu_b2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+					<&cpu_b3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
 				};
 			};
 		};
@@ -513,9 +485,9 @@
 		resets = <&cru SRST_TSADC>;
 		reset-names = "tsadc-apb";
 		pinctrl-names = "init", "default", "sleep";
-		pinctrl-0 = <&otp_gpio>;
+		pinctrl-0 = <&otp_pin>;
 		pinctrl-1 = <&otp_out>;
-		pinctrl-2 = <&otp_gpio>;
+		pinctrl-2 = <&otp_pin>;
 		#thermal-sensor-cells = <1>;
 		rockchip,hw-tshut-temp = <95000>;
 		status = "disabled";
@@ -543,7 +515,6 @@
 		reg = <0x0 0xff500000 0x0 0x100>;
 		interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&cru HCLK_HOST0>;
-		clock-names = "usbhost";
 		status = "disabled";
 	};
 
@@ -558,7 +529,6 @@
 		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";
 	};
 
@@ -575,16 +545,16 @@
 		status = "disabled";
 	};
 
-	i2c2: i2c@ff660000 {
+	i2c1: 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>;
+		clocks = <&cru PCLK_I2C1>;
 		pinctrl-names = "default";
-		pinctrl-0 = <&i2c2_xfer>;
+		pinctrl-0 = <&i2c1_xfer>;
 		status = "disabled";
 	};
 
@@ -633,7 +603,6 @@
 	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>;
@@ -654,16 +623,26 @@
 		clocks = <&cru PCLK_MAILBOX>;
 		clock-names = "pclk_mailbox";
 		#mbox-cells = <1>;
+		status = "disabled";
 	};
 
 	pmugrf: syscon@ff738000 {
-		compatible = "rockchip,rk3368-pmugrf", "syscon";
+		compatible = "rockchip,rk3368-pmugrf", "syscon", "simple-mfd";
 		reg = <0x0 0xff738000 0x0 0x1000>;
-	};
 
-	sgrf: syscon@ff740000 {
-	        compatible = "rockchip,rk3368-sgrf", "syscon";
-		reg = <0x0 0xff740000 0x0 0x1000>;
+		pmu_io_domains: io-domains {
+			compatible = "rockchip,rk3368-pmu-io-voltage-domain";
+			status = "disabled";
+		};
+
+		reboot-mode {
+			compatible = "syscon-reboot-mode";
+			offset = <0x200>;
+			mode-normal = <BOOT_NORMAL>;
+			mode-recovery = <BOOT_RECOVERY>;
+			mode-bootloader = <BOOT_FASTBOOT>;
+			mode-loader = <BOOT_BL_DOWNLOAD>;
+		};
 	};
 
 	cru: clock-controller@ff760000 {
@@ -675,8 +654,13 @@
 	};
 
 	grf: syscon@ff770000 {
-		compatible = "rockchip,rk3368-grf", "syscon";
+		compatible = "rockchip,rk3368-grf", "syscon", "simple-mfd";
 		reg = <0x0 0xff770000 0x0 0x1000>;
+
+		io_domains: io-domains {
+			compatible = "rockchip,rk3368-io-voltage-domain";
+			status = "disabled";
+		};
 	};
 
 	wdt: watchdog@ff800000 {
@@ -693,6 +677,118 @@
 		interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
 	};
 
+	spdif: spdif@ff880000 {
+		compatible = "rockchip,rk3368-spdif";
+		reg = <0x0 0xff880000 0x0 0x1000>;
+		interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru SCLK_SPDIF_8CH>, <&cru HCLK_SPDIF>;
+		clock-names = "mclk", "hclk";
+		dmas = <&dmac_bus 3>;
+		dma-names = "tx";
+		pinctrl-names = "default";
+		pinctrl-0 = <&spdif_tx>;
+		status = "disabled";
+	};
+
+	i2s_2ch: i2s-2ch@ff890000 {
+		compatible = "rockchip,rk3368-i2s", "rockchip,rk3066-i2s";
+		reg = <0x0 0xff890000 0x0 0x1000>;
+		interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+		clock-names = "i2s_clk", "i2s_hclk";
+		clocks = <&cru SCLK_I2S_2CH>, <&cru HCLK_I2S_2CH>;
+		dmas = <&dmac_bus 6>, <&dmac_bus 7>;
+		dma-names = "tx", "rx";
+		status = "disabled";
+	};
+
+	i2s_8ch: i2s-8ch@ff898000 {
+		compatible = "rockchip,rk3368-i2s", "rockchip,rk3066-i2s";
+		reg = <0x0 0xff898000 0x0 0x1000>;
+		interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
+		clock-names = "i2s_clk", "i2s_hclk";
+		clocks = <&cru SCLK_I2S_8CH>, <&cru HCLK_I2S_8CH>;
+		dmas = <&dmac_bus 0>, <&dmac_bus 1>;
+		dma-names = "tx", "rx";
+		pinctrl-names = "default";
+		pinctrl-0 = <&i2s_8ch_bus>;
+		status = "disabled";
+	};
+
+	iep_mmu: iommu@ff900800 {
+		compatible = "rockchip,iommu";
+		reg = <0x0 0xff900800 0x0 0x100>;
+		interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "iep_mmu";
+		clocks = <&cru ACLK_IEP>, <&cru HCLK_IEP>;
+		clock-names = "aclk", "iface";
+		#iommu-cells = <0>;
+		status = "disabled";
+	};
+
+	isp_mmu: iommu@ff914000 {
+		compatible = "rockchip,iommu";
+		reg = <0x0 0xff914000 0x0 0x100>,
+		      <0x0 0xff915000 0x0 0x100>;
+		interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "isp_mmu";
+		clocks = <&cru ACLK_ISP>, <&cru HCLK_ISP>;
+		clock-names = "aclk", "iface";
+		#iommu-cells = <0>;
+		rockchip,disable-mmu-reset;
+		status = "disabled";
+	};
+
+	vop_mmu: iommu@ff930300 {
+		compatible = "rockchip,iommu";
+		reg = <0x0 0xff930300 0x0 0x100>;
+		interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "vop_mmu";
+		clocks = <&cru ACLK_VOP>, <&cru HCLK_VOP>;
+		clock-names = "aclk", "iface";
+		#iommu-cells = <0>;
+		status = "disabled";
+	};
+
+	hevc_mmu: iommu@ff9a0440 {
+		compatible = "rockchip,iommu";
+		reg = <0x0 0xff9a0440 0x0 0x40>,
+		      <0x0 0xff9a0480 0x0 0x40>;
+		interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "hevc_mmu";
+		clocks = <&cru ACLK_VIDEO>, <&cru HCLK_VIDEO>;
+		clock-names = "aclk", "iface";
+		#iommu-cells = <0>;
+		status = "disabled";
+	};
+
+	vpu_mmu: iommu@ff9a0800 {
+		compatible = "rockchip,iommu";
+		reg = <0x0 0xff9a0800 0x0 0x100>;
+		interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "vepu_mmu", "vdpu_mmu";
+		clocks = <&cru ACLK_VIDEO>, <&cru HCLK_VIDEO>;
+		clock-names = "aclk", "iface";
+		#iommu-cells = <0>;
+		status = "disabled";
+	};
+
+	efuse256: efuse@ffb00000 {
+		compatible = "rockchip,rk3368-efuse";
+		reg = <0x0 0xffb00000 0x0 0x20>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		clocks = <&cru PCLK_EFUSE256>;
+		clock-names = "pclk_efuse";
+
+		cpu_leakage: cpu-leakage@17 {
+			reg = <0x17 0x1>;
+		};
+		temp_adjust: temp-adjust@1f {
+			reg = <0x1f 0x1>;
+		};
+	};
+
 	gic: interrupt-controller@ffb71000 {
 		compatible = "arm,gic-400";
 		interrupt-controller;
@@ -700,7 +796,7 @@
 		#address-cells = <0>;
 
 		reg = <0x0 0xffb71000 0x0 0x1000>,
-		      <0x0 0xffb72000 0x0 0x1000>,
+		      <0x0 0xffb72000 0x0 0x2000>,
 		      <0x0 0xffb74000 0x0 0x2000>,
 		      <0x0 0xffb76000 0x0 0x2000>;
 		interrupts = <GIC_PPI 9
@@ -786,325 +882,345 @@
 
 		emmc {
 			emmc_clk: emmc-clk {
-				rockchip,pins = <2 4 RK_FUNC_2 &pcfg_pull_none>;
+				rockchip,pins = <2 RK_PA4 2 &pcfg_pull_none>;
 			};
 
 			emmc_cmd: emmc-cmd {
-				rockchip,pins = <1 26 RK_FUNC_2 &pcfg_pull_up>;
+				rockchip,pins = <1 RK_PD2 2 &pcfg_pull_up>;
 			};
 
 			emmc_pwr: emmc-pwr {
-				rockchip,pins = <1 27 RK_FUNC_2 &pcfg_pull_up>;
+				rockchip,pins = <1 RK_PD3 2 &pcfg_pull_up>;
 			};
 
 			emmc_bus1: emmc-bus1 {
-				rockchip,pins = <1 18 RK_FUNC_2 &pcfg_pull_up>;
+				rockchip,pins = <1 RK_PC2 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>;
+				rockchip,pins = <1 RK_PC2 2 &pcfg_pull_up>,
+						<1 RK_PC3 2 &pcfg_pull_up>,
+						<1 RK_PC4 2 &pcfg_pull_up>,
+						<1 RK_PC5 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>;
+				rockchip,pins = <1 RK_PC2 2 &pcfg_pull_up>,
+						<1 RK_PC3 2 &pcfg_pull_up>,
+						<1 RK_PC4 2 &pcfg_pull_up>,
+						<1 RK_PC5 2 &pcfg_pull_up>,
+						<1 RK_PC6 2 &pcfg_pull_up>,
+						<1 RK_PC7 2 &pcfg_pull_up>,
+						<1 RK_PD0 2 &pcfg_pull_up>,
+						<1 RK_PD1 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>;
+				rockchip,pins =	<3 RK_PC6 1 &pcfg_pull_none>,
+						<3 RK_PD0 1 &pcfg_pull_none>,
+						<3 RK_PC3 1 &pcfg_pull_none>,
+						<3 RK_PB0 1 &pcfg_pull_none_12ma>,
+						<3 RK_PB1 1 &pcfg_pull_none_12ma>,
+						<3 RK_PB2 1 &pcfg_pull_none_12ma>,
+						<3 RK_PB6 1 &pcfg_pull_none_12ma>,
+						<3 RK_PD4 1 &pcfg_pull_none_12ma>,
+						<3 RK_PB5 1 &pcfg_pull_none_12ma>,
+						<3 RK_PB7 1 &pcfg_pull_none>,
+						<3 RK_PC0 1 &pcfg_pull_none>,
+						<3 RK_PC1 1 &pcfg_pull_none>,
+						<3 RK_PC2 1 &pcfg_pull_none>,
+						<3 RK_PD1 1 &pcfg_pull_none>,
+						<3 RK_PC4 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>;
+				rockchip,pins =	<3 RK_PC6 1 &pcfg_pull_none>,
+						<3 RK_PD0 1 &pcfg_pull_none>,
+						<3 RK_PC3 1 &pcfg_pull_none>,
+						<3 RK_PB0 1 &pcfg_pull_none_12ma>,
+						<3 RK_PB1 1 &pcfg_pull_none_12ma>,
+						<3 RK_PB5 1 &pcfg_pull_none_12ma>,
+						<3 RK_PB7 1 &pcfg_pull_none>,
+						<3 RK_PC0 1 &pcfg_pull_none>,
+						<3 RK_PC4 1 &pcfg_pull_none>,
+						<3 RK_PC5 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>;
+				rockchip,pins = <0 RK_PA6 1 &pcfg_pull_none>,
+						<0 RK_PA7 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>;
+				rockchip,pins = <2 RK_PC5 1 &pcfg_pull_none>,
+						<2 RK_PC6 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>;
+				rockchip,pins = <0 RK_PB1 2 &pcfg_pull_none>,
+						<3 RK_PD7 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>;
+				rockchip,pins = <1 RK_PC0 1 &pcfg_pull_none>,
+						<1 RK_PC1 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>;
+				rockchip,pins = <3 RK_PD0 2 &pcfg_pull_none>,
+						<3 RK_PD1 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>;
+				rockchip,pins = <3 RK_PD2 2 &pcfg_pull_none>,
+						<3 RK_PD3 2 &pcfg_pull_none>;
+			};
+		};
+
+		i2s {
+			i2s_8ch_bus: i2s-8ch-bus {
+				rockchip,pins = <2 RK_PB4 1 &pcfg_pull_none>,
+						<2 RK_PB5 1 &pcfg_pull_none>,
+						<2 RK_PB6 1 &pcfg_pull_none>,
+						<2 RK_PB7 1 &pcfg_pull_none>,
+						<2 RK_PC0 1 &pcfg_pull_none>,
+						<2 RK_PC1 1 &pcfg_pull_none>,
+						<2 RK_PC2 1 &pcfg_pull_none>,
+						<2 RK_PC3 1 &pcfg_pull_none>,
+						<2 RK_PC4 1 &pcfg_pull_none>;
 			};
 		};
 
 		pwm0 {
 			pwm0_pin: pwm0-pin {
-				rockchip,pins = <3 8 RK_FUNC_2 &pcfg_pull_none>;
+				rockchip,pins = <3 RK_PB0 2 &pcfg_pull_none>;
 			};
 		};
 
 		pwm1 {
 			pwm1_pin: pwm1-pin {
-				rockchip,pins = <0 8 RK_FUNC_2 &pcfg_pull_none>;
+				rockchip,pins = <0 RK_PB0 2 &pcfg_pull_none>;
 			};
 		};
 
 		pwm3 {
 			pwm3_pin: pwm3-pin {
-				rockchip,pins = <3 29 RK_FUNC_3 &pcfg_pull_none>;
+				rockchip,pins = <3 RK_PD5 3 &pcfg_pull_none>;
 			};
 		};
 
 		sdio0 {
 			sdio0_bus1: sdio0-bus1 {
-				rockchip,pins = <2 28 RK_FUNC_1 &pcfg_pull_up>;
+				rockchip,pins = <2 RK_PD4 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>;
+				rockchip,pins = <2 RK_PD4 1 &pcfg_pull_up>,
+						<2 RK_PD5 1 &pcfg_pull_up>,
+						<2 RK_PD6 1 &pcfg_pull_up>,
+						<2 RK_PD7 1 &pcfg_pull_up>;
 			};
 
 			sdio0_cmd: sdio0-cmd {
-				rockchip,pins = <3 0 RK_FUNC_1 &pcfg_pull_up>;
+				rockchip,pins = <3 RK_PA0 1 &pcfg_pull_up>;
 			};
 
 			sdio0_clk: sdio0-clk {
-				rockchip,pins = <3 1 RK_FUNC_1 &pcfg_pull_none>;
+				rockchip,pins = <3 RK_PA1 1 &pcfg_pull_none>;
 			};
 
 			sdio0_cd: sdio0-cd {
-				rockchip,pins = <3 2 RK_FUNC_1 &pcfg_pull_up>;
+				rockchip,pins = <3 RK_PA2 1 &pcfg_pull_up>;
 			};
 
 			sdio0_wp: sdio0-wp {
-				rockchip,pins = <3 3 RK_FUNC_1 &pcfg_pull_up>;
+				rockchip,pins = <3 RK_PA3 1 &pcfg_pull_up>;
 			};
 
 			sdio0_pwr: sdio0-pwr {
-				rockchip,pins = <3 4 RK_FUNC_1 &pcfg_pull_up>;
+				rockchip,pins = <3 RK_PA4 1 &pcfg_pull_up>;
 			};
 
 			sdio0_bkpwr: sdio0-bkpwr {
-				rockchip,pins = <3 5 RK_FUNC_1 &pcfg_pull_up>;
+				rockchip,pins = <3 RK_PA5 1 &pcfg_pull_up>;
 			};
 
 			sdio0_int: sdio0-int {
-				rockchip,pins = <3 6 RK_FUNC_1 &pcfg_pull_up>;
+				rockchip,pins = <3 RK_PA6 1 &pcfg_pull_up>;
 			};
 		};
 
 		sdmmc {
 			sdmmc_clk: sdmmc-clk {
-				rockchip,pins = <2 9 RK_FUNC_1 &pcfg_pull_none>;
+				rockchip,pins = <2 RK_PB1 1 &pcfg_pull_none>;
 			};
 
 			sdmmc_cmd: sdmmc-cmd {
-				rockchip,pins = <2 10 RK_FUNC_1 &pcfg_pull_up>;
+				rockchip,pins = <2 RK_PB2 1 &pcfg_pull_up>;
 			};
 
 			sdmmc_cd: sdmmc-cd {
-				rockchip,pins = <2 11 RK_FUNC_1 &pcfg_pull_up>;
+				rockchip,pins = <2 RK_PB3 1 &pcfg_pull_up>;
 			};
 
 			sdmmc_bus1: sdmmc-bus1 {
-				rockchip,pins = <2 5 RK_FUNC_1 &pcfg_pull_up>;
+				rockchip,pins = <2 RK_PA5 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>;
+				rockchip,pins = <2 RK_PA5 1 &pcfg_pull_up>,
+						<2 RK_PA6 1 &pcfg_pull_up>,
+						<2 RK_PA7 1 &pcfg_pull_up>,
+						<2 RK_PB0 1 &pcfg_pull_up>;
+			};
+		};
+
+		spdif {
+			spdif_tx: spdif-tx {
+				rockchip,pins =	<2 RK_PC7 1 &pcfg_pull_none>;
 			};
 		};
 
 		spi0 {
 			spi0_clk: spi0-clk {
-				rockchip,pins = <1 29 RK_FUNC_2 &pcfg_pull_up>;
+				rockchip,pins = <1 RK_PD5 2 &pcfg_pull_up>;
 			};
 			spi0_cs0: spi0-cs0 {
-				rockchip,pins = <1 24 RK_FUNC_3 &pcfg_pull_up>;
+				rockchip,pins = <1 RK_PD0 3 &pcfg_pull_up>;
 			};
 			spi0_cs1: spi0-cs1 {
-				rockchip,pins = <1 25 RK_FUNC_3 &pcfg_pull_up>;
+				rockchip,pins = <1 RK_PD1 3 &pcfg_pull_up>;
 			};
 			spi0_tx: spi0-tx {
-				rockchip,pins = <1 23 RK_FUNC_3 &pcfg_pull_up>;
+				rockchip,pins = <1 RK_PC7 3 &pcfg_pull_up>;
 			};
 			spi0_rx: spi0-rx {
-				rockchip,pins = <1 22 RK_FUNC_3 &pcfg_pull_up>;
+				rockchip,pins = <1 RK_PC6 3 &pcfg_pull_up>;
 			};
 		};
 
 		spi1 {
 			spi1_clk: spi1-clk {
-				rockchip,pins = <1 14 RK_FUNC_2 &pcfg_pull_up>;
+				rockchip,pins = <1 RK_PB6 2 &pcfg_pull_up>;
 			};
 			spi1_cs0: spi1-cs0 {
-				rockchip,pins = <1 15 RK_FUNC_2 &pcfg_pull_up>;
+				rockchip,pins = <1 RK_PB7 2 &pcfg_pull_up>;
 			};
 			spi1_cs1: spi1-cs1 {
-				rockchip,pins = <3 28 RK_FUNC_2 &pcfg_pull_up>;
+				rockchip,pins = <3 RK_PD4 2 &pcfg_pull_up>;
 			};
 			spi1_rx: spi1-rx {
-				rockchip,pins = <1 16 RK_FUNC_2 &pcfg_pull_up>;
+				rockchip,pins = <1 RK_PC0 2 &pcfg_pull_up>;
 			};
 			spi1_tx: spi1-tx {
-				rockchip,pins = <1 17 RK_FUNC_2 &pcfg_pull_up>;
+				rockchip,pins = <1 RK_PC1 2 &pcfg_pull_up>;
 			};
 		};
 
 		spi2 {
 			spi2_clk: spi2-clk {
-				rockchip,pins = <0 12 RK_FUNC_2 &pcfg_pull_up>;
+				rockchip,pins = <0 RK_PB4 2 &pcfg_pull_up>;
 			};
 			spi2_cs0: spi2-cs0 {
-				rockchip,pins = <0 13 RK_FUNC_2 &pcfg_pull_up>;
+				rockchip,pins = <0 RK_PB5 2 &pcfg_pull_up>;
 			};
 			spi2_rx: spi2-rx {
-				rockchip,pins = <0 10 RK_FUNC_2 &pcfg_pull_up>;
+				rockchip,pins = <0 RK_PB2 2 &pcfg_pull_up>;
 			};
 			spi2_tx: spi2-tx {
-				rockchip,pins = <0 11 RK_FUNC_2 &pcfg_pull_up>;
+				rockchip,pins = <0 RK_PB3 2 &pcfg_pull_up>;
 			};
 		};
 
 		tsadc {
-			otp_gpio: otp-gpio {
-				rockchip,pins = <0 3 RK_FUNC_GPIO &pcfg_pull_none>;
+			otp_pin: otp-pin {
+				rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none>;
 			};
 
 			otp_out: otp-out {
-				rockchip,pins = <0 3 RK_FUNC_1 &pcfg_pull_none>;
+				rockchip,pins = <0 RK_PA3 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>;
+				rockchip,pins = <2 RK_PD0 1 &pcfg_pull_up>,
+						<2 RK_PD1 1 &pcfg_pull_none>;
 			};
 
 			uart0_cts: uart0-cts {
-				rockchip,pins = <2 26 RK_FUNC_1 &pcfg_pull_none>;
+				rockchip,pins = <2 RK_PD2 1 &pcfg_pull_none>;
 			};
 
 			uart0_rts: uart0-rts {
-				rockchip,pins = <2 27 RK_FUNC_1 &pcfg_pull_none>;
+				rockchip,pins = <2 RK_PD3 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>;
+				rockchip,pins = <0 RK_PC4 3 &pcfg_pull_up>,
+						<0 RK_PC5 3 &pcfg_pull_none>;
 			};
 
 			uart1_cts: uart1-cts {
-				rockchip,pins = <0 22 RK_FUNC_3 &pcfg_pull_none>;
+				rockchip,pins = <0 RK_PC6 3 &pcfg_pull_none>;
 			};
 
 			uart1_rts: uart1-rts {
-				rockchip,pins = <0 23 RK_FUNC_3 &pcfg_pull_none>;
+				rockchip,pins = <0 RK_PC7 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>;
+				rockchip,pins = <2 RK_PA6 2 &pcfg_pull_up>,
+						<2 RK_PA5 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>;
+				rockchip,pins = <3 RK_PD5 2 &pcfg_pull_up>,
+						<3 RK_PD6 3 &pcfg_pull_none>;
 			};
 
 			uart3_cts: uart3-cts {
-				rockchip,pins = <3 16 RK_FUNC_2 &pcfg_pull_none>;
+				rockchip,pins = <3 RK_PC0 2 &pcfg_pull_none>;
 			};
 
 			uart3_rts: uart3-rts {
-				rockchip,pins = <3 17 RK_FUNC_2 &pcfg_pull_none>;
+				rockchip,pins = <3 RK_PC1 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>;
+				rockchip,pins = <0 RK_PD3 3 &pcfg_pull_up>,
+						<0 RK_PD2 3 &pcfg_pull_none>;
 			};
 
 			uart4_cts: uart4-cts {
-				rockchip,pins = <0 24 RK_FUNC_3 &pcfg_pull_none>;
+				rockchip,pins = <0 RK_PD0 3 &pcfg_pull_none>;
 			};
 
 			uart4_rts: uart4-rts {
-				rockchip,pins = <0 25 RK_FUNC_3 &pcfg_pull_none>;
+				rockchip,pins = <0 RK_PD1 3 &pcfg_pull_none>;
 			};
 		};
 	};
diff --git a/arch/arm/dts/rk3399-nanopi-m4b-u-boot.dtsi b/arch/arm/dts/rk3399-nanopi-m4b-u-boot.dtsi
new file mode 100644
index 0000000..9c3c1ef
--- /dev/null
+++ b/arch/arm/dts/rk3399-nanopi-m4b-u-boot.dtsi
@@ -0,0 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021 Alexandre Vicenzi <linux@alxd.me>
+ */
+
+#include "rk3399-nanopi4-u-boot.dtsi"
+#include "rk3399-sdram-ddr3-1866.dtsi"
diff --git a/arch/arm/dts/rk3399-nanopi-m4b.dts b/arch/arm/dts/rk3399-nanopi-m4b.dts
new file mode 100644
index 0000000..72182c5
--- /dev/null
+++ b/arch/arm/dts/rk3399-nanopi-m4b.dts
@@ -0,0 +1,52 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * FriendlyElec NanoPi M4B board device tree source
+ *
+ * Copyright (c) 2020 Chen-Yu Tsai <wens@csie.org>
+ */
+
+/dts-v1/;
+#include "rk3399-nanopi-m4.dts"
+
+/ {
+	model = "FriendlyElec NanoPi M4B";
+	compatible = "friendlyarm,nanopi-m4b", "rockchip,rk3399";
+
+	adc-keys {
+		compatible = "adc-keys";
+		io-channels = <&saradc 1>;
+		io-channel-names = "buttons";
+		keyup-threshold-microvolt = <1500000>;
+		poll-interval = <100>;
+
+		recovery {
+			label = "Recovery";
+			linux,code = <KEY_VENDOR>;
+			press-threshold-microvolt = <18000>;
+		};
+	};
+};
+
+/* No USB type-C PD power manager */
+/delete-node/ &fusb0;
+
+&i2c4 {
+	status = "disabled";
+};
+
+&u2phy0_host {
+	phy-supply = <&vcc5v0_usb2>;
+};
+
+&u2phy0_otg {
+	phy-supply = <&vbus_typec>;
+};
+
+&u2phy1_otg {
+	phy-supply = <&vcc5v0_usb1>;
+};
+
+&vbus_typec {
+	enable-active-high;
+	gpios = <&gpio4 RK_PD2 GPIO_ACTIVE_HIGH>;
+};
diff --git a/arch/arm/dts/rk3399-nanopi-r4s-u-boot.dtsi b/arch/arm/dts/rk3399-nanopi-r4s-u-boot.dtsi
new file mode 100644
index 0000000..cd16425
--- /dev/null
+++ b/arch/arm/dts/rk3399-nanopi-r4s-u-boot.dtsi
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * RK3399-based FriendlyElec boards device tree source
+ *
+ * Copyright (c) 2016 Fuzhou Rockchip Electronics Co., Ltd
+ *
+ * Copyright (c) 2018 FriendlyElec Computer Tech. Co., Ltd.
+ * (http://www.friendlyarm.com)
+ *
+ * Copyright (c) 2018 Collabora Ltd.
+ * Copyright (c) 2019 Arm Ltd.
+ * Copyright (C) 2020 Xiaobo <peterwillcn@gmail.com>
+ */
+
+#include "rk3399-nanopi4-u-boot.dtsi"
+#include "rk3399-sdram-lpddr4-100.dtsi"
diff --git a/arch/arm/dts/rk3399-nanopi-r4s.dts b/arch/arm/dts/rk3399-nanopi-r4s.dts
new file mode 100644
index 0000000..6f2cf17
--- /dev/null
+++ b/arch/arm/dts/rk3399-nanopi-r4s.dts
@@ -0,0 +1,138 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2016 Fuzhou Rockchip Electronics Co., Ltd
+ *
+ * Copyright (c) 2018 FriendlyElec Computer Tech. Co., Ltd.
+ * (http://www.friendlyarm.com)
+ *
+ * Copyright (c) 2018 Collabora Ltd.
+ * Copyright (c) 2019 Arm Ltd.
+ * Copyright (C) 2020 Xiaobo <peterwillcn@gmail.com>
+ */
+
+/dts-v1/;
+#include "rk3399-nanopi4.dtsi"
+
+/ {
+	model = "FriendlyElec NanoPi R4S";
+	compatible = "friendlyarm,nanopi-r4s", "rockchip,rk3399";
+
+	aliases {
+		ethernet1 = &r8169;
+	};
+
+	vdd_5v: vdd-5v {
+		compatible = "regulator-fixed";
+		regulator-name = "vdd_5v";
+		regulator-always-on;
+		regulator-boot-on;
+	};
+
+	fan: pwm-fan {
+		compatible = "pwm-fan";
+		cooling-levels = <0 12 18 255>;
+		#cooling-cells = <2>;
+		fan-supply = <&vdd_5v>;
+		pwms = <&pwm1 0 50000 0>;
+	};
+};
+
+&cpu_thermal {
+	trips {
+		cpu_warm: cpu_warm {
+			temperature = <55000>;
+			hysteresis = <2000>;
+			type = "active";
+		};
+
+		cpu_hot: cpu_hot {
+			temperature = <65000>;
+			hysteresis = <2000>;
+			type = "active";
+		};
+	};
+
+	cooling-maps {
+		map2 {
+			trip = <&cpu_warm>;
+			cooling-device = <&fan THERMAL_NO_LIMIT 1>;
+		};
+
+		map3 {
+			trip = <&cpu_hot>;
+			cooling-device = <&fan 2 THERMAL_NO_LIMIT>;
+		};
+	};
+};
+
+&emmc_phy {
+	status = "disabled";
+};
+
+&fusb0 {
+	status = "disabled";
+};
+
+&leds {
+	lan_led: led-1 {
+		gpios = <&gpio1 RK_PA1 GPIO_ACTIVE_HIGH>;
+		label = "nanopi-r4s:green:lan";
+	};
+
+	wan_led: led-2 {
+		gpios = <&gpio1 RK_PA0 GPIO_ACTIVE_HIGH>;
+		label = "nanopi-r4s:green:wan";
+	};
+};
+
+&leds_gpio {
+	rockchip,pins =
+		<0 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>,
+		<1 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>,
+		<1 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none>;
+};
+
+&pcie0 {
+	max-link-speed = <1>;
+	num-lanes = <1>;
+	vpcie3v3-supply = <&vcc3v3_sys>;
+
+	pcie@0 {
+		reg = <0x00000000 0 0 0 0>;
+		#address-cells = <3>;
+		#size-cells = <2>;
+
+		r8169: pcie@0,0 {
+			reg = <0x000000 0 0 0 0>;
+			local-mac-address = [ 00 00 00 00 00 00 ];
+		};
+	};
+};
+
+&sdhci {
+	status = "disabled";
+};
+
+&sdio0 {
+	status = "disabled";
+};
+
+&sdmmc {
+	host-index-min = <1>;
+};
+
+&u2phy0_host {
+	phy-supply = <&vdd_5v>;
+};
+
+&u2phy1_host {
+	status = "disabled";
+};
+
+&usbdrd_dwc3_0 {
+	dr_mode = "host";
+};
+
+&vcc3v3_sys {
+	vin-supply = <&vcc5v0_sys>;
+};
diff --git a/arch/arm/dts/rk3399-puma-haikou-u-boot.dtsi b/arch/arm/dts/rk3399-puma-haikou-u-boot.dtsi
index e7a1aea..e0476ab 100644
--- a/arch/arm/dts/rk3399-puma-haikou-u-boot.dtsi
+++ b/arch/arm/dts/rk3399-puma-haikou-u-boot.dtsi
@@ -48,6 +48,18 @@
 		regulator-min-microvolt = <1800000>;
 		regulator-max-microvolt = <1800000>;
 	};
+
+	vdd_log: vdd-log {
+		compatible = "pwm-regulator";
+		pwms = <&pwm2 0 25000 1>;
+		regulator-name = "vdd_log";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <800000>;
+		regulator-max-microvolt = <1400000>;
+		regulator-init-microvolt = <950000>;
+		vin-supply = <&vcc5v0_sys>;
+	};
 };
 
 &gpio1 {
diff --git a/arch/arm/include/asm/arch-meson/axg.h b/arch/arm/include/asm/arch-meson/axg.h
index 91c8769..12042de 100644
--- a/arch/arm/include/asm/arch-meson/axg.h
+++ b/arch/arm/include/asm/arch-meson/axg.h
@@ -31,26 +31,4 @@
 #define AXG_AO_BL31_RSVMEM_SIZE_SHIFT	16
 #define AXG_AO_BL32_RSVMEM_SIZE_MASK	0xFFFF
 
-/* Peripherals registers */
-#define AXG_PERIPHS_ADDR(off)	(AXG_PERIPHS_BASE + ((off) << 2))
-
-#define AXG_ETH_REG_0		AXG_PERIPHS_ADDR(0x50)
-#define AXG_ETH_REG_1		AXG_PERIPHS_ADDR(0x51)
-
-#define AXG_ETH_REG_0_PHY_INTF_RGMII	BIT(0)
-#define AXG_ETH_REG_0_PHY_INTF_RMII	BIT(2)
-#define AXG_ETH_REG_0_TX_PHASE(x)	(((x) & 3) << 5)
-#define AXG_ETH_REG_0_TX_RATIO(x)	(((x) & 7) << 7)
-#define AXG_ETH_REG_0_PHY_CLK_EN	BIT(10)
-#define AXG_ETH_REG_0_INVERT_RMII_CLK	BIT(11)
-#define AXG_ETH_REG_0_CLK_EN		BIT(12)
-
-/* HIU registers */
-#define AXG_HIU_ADDR(off)	(AXG_HIU_BASE + ((off) << 2))
-
-#define AXG_MEM_PD_REG_0	AXG_HIU_ADDR(0x40)
-
-/* Ethernet memory power domain */
-#define AXG_MEM_PD_REG_0_ETH_MASK	(BIT(2) | BIT(3))
-
 #endif /* __AXG_H__ */
diff --git a/arch/arm/include/asm/arch-meson/eth.h b/arch/arm/include/asm/arch-meson/eth.h
index f765cd7..c007061 100644
--- a/arch/arm/include/asm/arch-meson/eth.h
+++ b/arch/arm/include/asm/arch-meson/eth.h
@@ -7,18 +7,6 @@
 #ifndef __MESON_ETH_H__
 #define __MESON_ETH_H__
 
-#include <phy.h>
-
-enum {
-	/* Use Internal RMII PHY */
-	MESON_USE_INTERNAL_RMII_PHY = 1,
-};
-
-/* Configure the Ethernet MAC with the requested interface mode
- * with some optional flags.
- */
-void meson_eth_init(phy_interface_t mode, unsigned int flags);
-
 /* Generate an unique MAC address based on the HW serial */
 int meson_generate_serial_ethaddr(void);
 
diff --git a/arch/arm/include/asm/arch-meson/g12a.h b/arch/arm/include/asm/arch-meson/g12a.h
index db29cc3..ef4f301 100644
--- a/arch/arm/include/asm/arch-meson/g12a.h
+++ b/arch/arm/include/asm/arch-meson/g12a.h
@@ -32,39 +32,4 @@
 #define G12A_AO_BL31_RSVMEM_SIZE_SHIFT	16
 #define G12A_AO_BL32_RSVMEM_SIZE_MASK	0xFFFF
 
-/* Peripherals registers */
-#define G12A_PERIPHS_ADDR(off)	(G12A_PERIPHS_BASE + ((off) << 2))
-
-#define G12A_ETH_REG_0			G12A_PERIPHS_ADDR(0x50)
-#define G12A_ETH_REG_1			G12A_PERIPHS_ADDR(0x51)
-
-#define G12A_ETH_REG_0_PHY_INTF_RGMII	BIT(0)
-#define G12A_ETH_REG_0_PHY_INTF_RMII	BIT(2)
-#define G12A_ETH_REG_0_TX_PHASE(x)	(((x) & 3) << 5)
-#define G12A_ETH_REG_0_TX_RATIO(x)	(((x) & 7) << 7)
-#define G12A_ETH_REG_0_PHY_CLK_EN	BIT(10)
-#define G12A_ETH_REG_0_INVERT_RMII_CLK	BIT(11)
-#define G12A_ETH_REG_0_CLK_EN		BIT(12)
-
-#define G12A_ETH_PHY_ADDR(off)	(G12A_ETH_PHY_BASE + ((off) << 2))
-#define ETH_PLL_CNTL0			G12A_ETH_PHY_ADDR(0x11)
-#define ETH_PLL_CNTL1			G12A_ETH_PHY_ADDR(0x12)
-#define ETH_PLL_CNTL2			G12A_ETH_PHY_ADDR(0x13)
-#define ETH_PLL_CNTL3			G12A_ETH_PHY_ADDR(0x14)
-#define ETH_PLL_CNTL4			G12A_ETH_PHY_ADDR(0x15)
-#define ETH_PLL_CNTL5			G12A_ETH_PHY_ADDR(0x16)
-#define ETH_PLL_CNTL6			G12A_ETH_PHY_ADDR(0x17)
-#define ETH_PLL_CNTL7			G12A_ETH_PHY_ADDR(0x18)
-#define ETH_PHY_CNTL0			G12A_ETH_PHY_ADDR(0x20)
-#define ETH_PHY_CNTL1			G12A_ETH_PHY_ADDR(0x21)
-#define ETH_PHY_CNTL2			G12A_ETH_PHY_ADDR(0x22)
-
-/* HIU registers */
-#define G12A_HIU_ADDR(off)	(G12A_HIU_BASE + ((off) << 2))
-
-#define G12A_MEM_PD_REG_0		G12A_HIU_ADDR(0x40)
-
-/* Ethernet memory power domain */
-#define G12A_MEM_PD_REG_0_ETH_MASK	(BIT(2) | BIT(3))
-
 #endif /* __G12A_H__ */
diff --git a/arch/arm/include/asm/arch-meson/gx.h b/arch/arm/include/asm/arch-meson/gx.h
index 743d2e8..26ec5d0 100644
--- a/arch/arm/include/asm/arch-meson/gx.h
+++ b/arch/arm/include/asm/arch-meson/gx.h
@@ -41,24 +41,4 @@
 #define GX_GPIO_IN(n)		GX_PERIPHS_ADDR(_GX_GPIO_OFF(n) + 1)
 #define GX_GPIO_OUT(n)	GX_PERIPHS_ADDR(_GX_GPIO_OFF(n) + 2)
 
-#define GX_ETH_REG_0		GX_PERIPHS_ADDR(0x50)
-#define GX_ETH_REG_1		GX_PERIPHS_ADDR(0x51)
-#define GX_ETH_REG_2		GX_PERIPHS_ADDR(0x56)
-#define GX_ETH_REG_3		GX_PERIPHS_ADDR(0x57)
-
-#define GX_ETH_REG_0_PHY_INTF		BIT(0)
-#define GX_ETH_REG_0_TX_PHASE(x)	(((x) & 3) << 5)
-#define GX_ETH_REG_0_TX_RATIO(x)	(((x) & 7) << 7)
-#define GX_ETH_REG_0_PHY_CLK_EN	BIT(10)
-#define GX_ETH_REG_0_INVERT_RMII_CLK	BIT(11)
-#define GX_ETH_REG_0_CLK_EN		BIT(12)
-
-/* HIU registers */
-#define GX_HIU_ADDR(off)	(GX_HIU_BASE + ((off) << 2))
-
-#define GX_MEM_PD_REG_0	GX_HIU_ADDR(0x40)
-
-/* Ethernet memory power domain */
-#define GX_MEM_PD_REG_0_ETH_MASK	(BIT(2) | BIT(3))
-
 #endif /* __GX_H__ */
diff --git a/arch/arm/mach-meson/board-axg.c b/arch/arm/mach-meson/board-axg.c
index 3b14bc9..71ac65c 100644
--- a/arch/arm/mach-meson/board-axg.c
+++ b/arch/arm/mach-meson/board-axg.c
@@ -91,40 +91,6 @@
 
 struct mm_region *mem_map = axg_mem_map;
 
-/* Configure the Ethernet MAC with the requested interface mode
- * with some optional flags.
- */
-void meson_eth_init(phy_interface_t mode, unsigned int flags)
-{
-	switch (mode) {
-	case PHY_INTERFACE_MODE_RGMII:
-	case PHY_INTERFACE_MODE_RGMII_ID:
-	case PHY_INTERFACE_MODE_RGMII_RXID:
-	case PHY_INTERFACE_MODE_RGMII_TXID:
-		/* Set RGMII mode */
-		setbits_le32(AXG_ETH_REG_0, AXG_ETH_REG_0_PHY_INTF_RGMII |
-			     AXG_ETH_REG_0_TX_PHASE(1) |
-			     AXG_ETH_REG_0_TX_RATIO(4) |
-			     AXG_ETH_REG_0_PHY_CLK_EN |
-			     AXG_ETH_REG_0_CLK_EN);
-		break;
-
-	case PHY_INTERFACE_MODE_RMII:
-		/* Set RMII mode */
-		out_le32(AXG_ETH_REG_0, AXG_ETH_REG_0_PHY_INTF_RMII |
-					AXG_ETH_REG_0_INVERT_RMII_CLK |
-					AXG_ETH_REG_0_CLK_EN);
-		break;
-
-	default:
-		printf("Invalid Ethernet interface mode\n");
-		return;
-	}
-
-	/* Enable power gate */
-	clrbits_le32(AXG_MEM_PD_REG_0, AXG_MEM_PD_REG_0_ETH_MASK);
-}
-
 #if CONFIG_IS_ENABLED(USB_DWC3_MESON_GXL) && \
 	CONFIG_IS_ENABLED(USB_GADGET_DWC2_OTG)
 static struct dwc2_plat_otg_data meson_gx_dwc2_data;
diff --git a/arch/arm/mach-meson/board-g12a.c b/arch/arm/mach-meson/board-g12a.c
index bb75d4f..2e59eee 100644
--- a/arch/arm/mach-meson/board-g12a.c
+++ b/arch/arm/mach-meson/board-g12a.c
@@ -97,73 +97,6 @@
 
 struct mm_region *mem_map = g12a_mem_map;
 
-static void g12a_enable_external_mdio(void)
-{
-	writel(0x0, ETH_PHY_CNTL2);
-}
-
-static void g12a_enable_internal_mdio(void)
-{
-	/* Fire up the PHY PLL */
-	writel(0x29c0040a, ETH_PLL_CNTL0);
-	writel(0x927e0000, ETH_PLL_CNTL1);
-	writel(0xac5f49e5, ETH_PLL_CNTL2);
-	writel(0x00000000, ETH_PLL_CNTL3);
-	writel(0x00000000, ETH_PLL_CNTL4);
-	writel(0x20200000, ETH_PLL_CNTL5);
-	writel(0x0000c002, ETH_PLL_CNTL6);
-	writel(0x00000023, ETH_PLL_CNTL7);
-	writel(0x39c0040a, ETH_PLL_CNTL0);
-	writel(0x19c0040a, ETH_PLL_CNTL0);
-
-	/* Select the internal MDIO */
-	writel(0x33000180, ETH_PHY_CNTL0);
-	writel(0x00074043, ETH_PHY_CNTL1);
-	writel(0x00000260, ETH_PHY_CNTL2);
-}
-
-/* Configure the Ethernet MAC with the requested interface mode
- * with some optional flags.
- */
-void meson_eth_init(phy_interface_t mode, unsigned int flags)
-{
-	switch (mode) {
-	case PHY_INTERFACE_MODE_RGMII:
-	case PHY_INTERFACE_MODE_RGMII_ID:
-	case PHY_INTERFACE_MODE_RGMII_RXID:
-	case PHY_INTERFACE_MODE_RGMII_TXID:
-		/* Set RGMII mode */
-		setbits_le32(G12A_ETH_REG_0, G12A_ETH_REG_0_PHY_INTF_RGMII |
-			     G12A_ETH_REG_0_TX_PHASE(1) |
-			     G12A_ETH_REG_0_TX_RATIO(4) |
-			     G12A_ETH_REG_0_PHY_CLK_EN |
-			     G12A_ETH_REG_0_CLK_EN);
-		g12a_enable_external_mdio();
-		break;
-
-	case PHY_INTERFACE_MODE_RMII:
-		/* Set RMII mode */
-		out_le32(G12A_ETH_REG_0, G12A_ETH_REG_0_PHY_INTF_RMII |
-					G12A_ETH_REG_0_INVERT_RMII_CLK |
-					G12A_ETH_REG_0_CLK_EN);
-
-		/* Use G12A RMII Internal PHY */
-		if (flags & MESON_USE_INTERNAL_RMII_PHY)
-			g12a_enable_internal_mdio();
-		else
-			g12a_enable_external_mdio();
-
-		break;
-
-	default:
-		printf("Invalid Ethernet interface mode\n");
-		return;
-	}
-
-	/* Enable power gate */
-	clrbits_le32(G12A_MEM_PD_REG_0, G12A_MEM_PD_REG_0_ETH_MASK);
-}
-
 #if CONFIG_IS_ENABLED(USB_DWC3_MESON_G12A) && \
 	CONFIG_IS_ENABLED(USB_GADGET_DWC2_OTG)
 static struct dwc2_plat_otg_data meson_g12a_dwc2_data;
diff --git a/arch/arm/mach-meson/board-gx.c b/arch/arm/mach-meson/board-gx.c
index f5273f4..01fafd8 100644
--- a/arch/arm/mach-meson/board-gx.c
+++ b/arch/arm/mach-meson/board-gx.c
@@ -109,54 +109,6 @@
 
 struct mm_region *mem_map = gx_mem_map;
 
-/* Configure the Ethernet MAC with the requested interface mode
- * with some optional flags.
- */
-void meson_eth_init(phy_interface_t mode, unsigned int flags)
-{
-	switch (mode) {
-	case PHY_INTERFACE_MODE_RGMII:
-	case PHY_INTERFACE_MODE_RGMII_ID:
-	case PHY_INTERFACE_MODE_RGMII_RXID:
-	case PHY_INTERFACE_MODE_RGMII_TXID:
-		/* Set RGMII mode */
-		setbits_le32(GX_ETH_REG_0, GX_ETH_REG_0_PHY_INTF |
-			     GX_ETH_REG_0_TX_PHASE(1) |
-			     GX_ETH_REG_0_TX_RATIO(4) |
-			     GX_ETH_REG_0_PHY_CLK_EN |
-			     GX_ETH_REG_0_CLK_EN);
-
-		/* Reset to external PHY */
-		if(!IS_ENABLED(CONFIG_MESON_GXBB))
-			writel(0x2009087f, GX_ETH_REG_3);
-
-		break;
-
-	case PHY_INTERFACE_MODE_RMII:
-		/* Set RMII mode */
-		out_le32(GX_ETH_REG_0, GX_ETH_REG_0_INVERT_RMII_CLK |
-					 GX_ETH_REG_0_CLK_EN);
-
-		/* Use GXL RMII Internal PHY (also on GXM) */
-		if (!IS_ENABLED(CONFIG_MESON_GXBB)) {
-			if ((flags & MESON_USE_INTERNAL_RMII_PHY)) {
-				writel(0x10110181, GX_ETH_REG_2);
-				writel(0xe40908ff, GX_ETH_REG_3);
-			} else
-				writel(0x2009087f, GX_ETH_REG_3);
-		}
-
-		break;
-
-	default:
-		printf("Invalid Ethernet interface mode\n");
-		return;
-	}
-
-	/* Enable power gate */
-	clrbits_le32(GX_MEM_PD_REG_0, GX_MEM_PD_REG_0_ETH_MASK);
-}
-
 #if CONFIG_IS_ENABLED(USB_DWC3_MESON_GXL) && \
 	CONFIG_IS_ENABLED(USB_GADGET_DWC2_OTG)
 static struct dwc2_plat_otg_data meson_gx_dwc2_data;
diff --git a/arch/arm/mach-rockchip/rk3368/Kconfig b/arch/arm/mach-rockchip/rk3368/Kconfig
index d6ca5f1..78eb96d 100644
--- a/arch/arm/mach-rockchip/rk3368/Kconfig
+++ b/arch/arm/mach-rockchip/rk3368/Kconfig
@@ -49,7 +49,7 @@
 	default "rk3368"
 
 config SYS_MALLOC_F_LEN
-	default 0x2000
+	default 0x4000
 
 config SPL_LIBCOMMON_SUPPORT
 	default y
@@ -65,6 +65,9 @@
 config SPL_LDSCRIPT
 	default "arch/arm/cpu/armv8/u-boot-spl.lds"
 
+config SPL_STACK_R_ADDR
+	default 0x04000000
+
 config TPL_MAX_SIZE
         default 28672
 
diff --git a/board/amlogic/beelink-s922x/beelink-s922x.c b/board/amlogic/beelink-s922x/beelink-s922x.c
index dc0d933..bb74426 100644
--- a/board/amlogic/beelink-s922x/beelink-s922x.c
+++ b/board/amlogic/beelink-s922x/beelink-s922x.c
@@ -28,8 +28,6 @@
 	    meson_get_soc_rev(tmp, sizeof(tmp)) > 0)
 		env_set("soc_rev", tmp);
 
-	meson_eth_init(PHY_INTERFACE_MODE_RGMII, 0);
-
 	if (!eth_env_get_enetaddr("ethaddr", mac_addr)) {
 		len = meson_sm_read_efuse(EFUSE_MAC_OFFSET,
 					  efuse_mac_addr, EFUSE_MAC_SIZE);
diff --git a/board/amlogic/odroid-n2/odroid-n2.c b/board/amlogic/odroid-n2/odroid-n2.c
index 863975e..88a60f3 100644
--- a/board/amlogic/odroid-n2/odroid-n2.c
+++ b/board/amlogic/odroid-n2/odroid-n2.c
@@ -115,8 +115,6 @@
 	    meson_get_soc_rev(tmp, sizeof(tmp)) > 0)
 		env_set("soc_rev", tmp);
 
-	meson_eth_init(PHY_INTERFACE_MODE_RGMII, 0);
-
 	if (!eth_env_get_enetaddr("ethaddr", mac_addr)) {
 		len = meson_sm_read_efuse(EFUSE_MAC_OFFSET,
 					  efuse_mac_addr, EFUSE_MAC_SIZE);
diff --git a/board/amlogic/p200/p200.c b/board/amlogic/p200/p200.c
index 8f1bf8b..7c432f9 100644
--- a/board/amlogic/p200/p200.c
+++ b/board/amlogic/p200/p200.c
@@ -25,8 +25,6 @@
 	char serial[EFUSE_SN_SIZE];
 	ssize_t len;
 
-	meson_eth_init(PHY_INTERFACE_MODE_RGMII, 0);
-
 	if (!eth_env_get_enetaddr("ethaddr", mac_addr)) {
 		len = meson_sm_read_efuse(EFUSE_MAC_OFFSET,
 					  mac_addr, EFUSE_MAC_SIZE);
diff --git a/board/amlogic/p201/p201.c b/board/amlogic/p201/p201.c
index 597bb71..7c432f9 100644
--- a/board/amlogic/p201/p201.c
+++ b/board/amlogic/p201/p201.c
@@ -25,8 +25,6 @@
 	char serial[EFUSE_SN_SIZE];
 	ssize_t len;
 
-	meson_eth_init(PHY_INTERFACE_MODE_RMII, 0);
-
 	if (!eth_env_get_enetaddr("ethaddr", mac_addr)) {
 		len = meson_sm_read_efuse(EFUSE_MAC_OFFSET,
 					  mac_addr, EFUSE_MAC_SIZE);
diff --git a/board/amlogic/p212/p212.c b/board/amlogic/p212/p212.c
index fbc49e9..fcef90b 100644
--- a/board/amlogic/p212/p212.c
+++ b/board/amlogic/p212/p212.c
@@ -26,9 +26,6 @@
 	char serial[EFUSE_SN_SIZE];
 	ssize_t len;
 
-	meson_eth_init(PHY_INTERFACE_MODE_RMII,
-		       MESON_USE_INTERNAL_RMII_PHY);
-
 	if (!eth_env_get_enetaddr("ethaddr", mac_addr)) {
 		len = meson_sm_read_efuse(EFUSE_MAC_OFFSET,
 					  mac_addr, EFUSE_MAC_SIZE);
diff --git a/board/amlogic/q200/q200.c b/board/amlogic/q200/q200.c
index 62e6fa3..3aa6d8f 100644
--- a/board/amlogic/q200/q200.c
+++ b/board/amlogic/q200/q200.c
@@ -26,8 +26,6 @@
 	char serial[EFUSE_SN_SIZE];
 	ssize_t len;
 
-	meson_eth_init(PHY_INTERFACE_MODE_RGMII, 0);
-
 	if (!eth_env_get_enetaddr("ethaddr", mac_addr)) {
 		len = meson_sm_read_efuse(EFUSE_MAC_OFFSET,
 					  mac_addr, EFUSE_MAC_SIZE);
diff --git a/board/amlogic/s400/s400.c b/board/amlogic/s400/s400.c
index b081942..06a9044 100644
--- a/board/amlogic/s400/s400.c
+++ b/board/amlogic/s400/s400.c
@@ -16,8 +16,6 @@
 
 int misc_init_r(void)
 {
-	meson_eth_init(PHY_INTERFACE_MODE_RGMII, 0);
-
 	meson_generate_serial_ethaddr();
 
 	return 0;
diff --git a/board/amlogic/sei510/sei510.c b/board/amlogic/sei510/sei510.c
index 5a5148e..bb188c2 100644
--- a/board/amlogic/sei510/sei510.c
+++ b/board/amlogic/sei510/sei510.c
@@ -18,9 +18,6 @@
 
 int misc_init_r(void)
 {
-	meson_eth_init(PHY_INTERFACE_MODE_RMII,
-		       MESON_USE_INTERNAL_RMII_PHY);
-
 	meson_generate_serial_ethaddr();
 
 	env_set("serial#", "AMLG12ASEI510");
diff --git a/board/amlogic/sei610/sei610.c b/board/amlogic/sei610/sei610.c
index 27dba93..6490bac 100644
--- a/board/amlogic/sei610/sei610.c
+++ b/board/amlogic/sei610/sei610.c
@@ -18,9 +18,6 @@
 
 int misc_init_r(void)
 {
-	meson_eth_init(PHY_INTERFACE_MODE_RMII,
-		       MESON_USE_INTERNAL_RMII_PHY);
-
 	meson_generate_serial_ethaddr();
 
 	env_set("serial#", "AMLG12ASEI610");
diff --git a/board/amlogic/u200/u200.c b/board/amlogic/u200/u200.c
index 373235d..06a9044 100644
--- a/board/amlogic/u200/u200.c
+++ b/board/amlogic/u200/u200.c
@@ -16,8 +16,7 @@
 
 int misc_init_r(void)
 {
-	meson_eth_init(PHY_INTERFACE_MODE_RMII,
-		       MESON_USE_INTERNAL_RMII_PHY);
+	meson_generate_serial_ethaddr();
 
 	return 0;
 }
diff --git a/board/amlogic/vim3/vim3.c b/board/amlogic/vim3/vim3.c
index 7b09617..6cd5f2e 100644
--- a/board/amlogic/vim3/vim3.c
+++ b/board/amlogic/vim3/vim3.c
@@ -149,8 +149,6 @@
 	char efuse_mac_addr[EFUSE_MAC_SIZE], tmp[3];
 	ssize_t len;
 
-	meson_eth_init(PHY_INTERFACE_MODE_RGMII, 0);
-
 	if (!eth_env_get_enetaddr("ethaddr", mac_addr)) {
 		len = meson_sm_read_efuse(EFUSE_MAC_OFFSET,
 					  efuse_mac_addr, EFUSE_MAC_SIZE);
diff --git a/board/amlogic/w400/w400.c b/board/amlogic/w400/w400.c
index 47a5171..4199198 100644
--- a/board/amlogic/w400/w400.c
+++ b/board/amlogic/w400/w400.c
@@ -14,7 +14,7 @@
 
 int misc_init_r(void)
 {
-	meson_eth_init(PHY_INTERFACE_MODE_RGMII, 0);
+	meson_generate_serial_ethaddr();
 
 	return 0;
 }
diff --git a/board/rockchip/evb_rk3399/MAINTAINERS b/board/rockchip/evb_rk3399/MAINTAINERS
index 4c889e0..25e308d 100644
--- a/board/rockchip/evb_rk3399/MAINTAINERS
+++ b/board/rockchip/evb_rk3399/MAINTAINERS
@@ -49,12 +49,24 @@
 F:	configs/nanopi-m4-2gb-rk3399_defconfig
 F:	arch/arm/dts/rk3399-nanopi-m4-2gb-u-boot.dtsi
 
+NANOPI-M4B
+M:	Alexandre Vicenzi <linux@alxd.me>
+S:	Maintained
+F:	configs/nanopi-m4b-rk3399_defconfig
+F:	arch/arm/dts/rk3399-nanopi-m4b-u-boot.dtsi
+
 NANOPI-NEO4
 M:	Jagan Teki <jagan@amarulasolutions.com>
 S:	Maintained
 F:	configs/nanopi-neo4-rk3399_defconfig
 F:	arch/arm/dts/rk3399-nanopi-neo4-u-boot.dtsi
 
+NANOPI-R4S
+M:	Xiaobo Tian <peterwillcn@gmail.com>
+S:	Maintained
+F:	configs/nanopi-r4s-rk3399_defconfig
+F:	arch/arm/dts/rk3399-nanopi-r4s-u-boot.dtsi
+
 ORANGEPI-RK3399
 M:	Jagan Teki <jagan@amarulasolutions.com>
 S:	Maintained
diff --git a/board/theobroma-systems/puma_rk3399/Kconfig b/board/theobroma-systems/puma_rk3399/Kconfig
index e82623a..21946d9 100644
--- a/board/theobroma-systems/puma_rk3399/Kconfig
+++ b/board/theobroma-systems/puma_rk3399/Kconfig
@@ -13,7 +13,7 @@
 	def_bool y
 
 config ENV_SIZE
-	default 0x2000
+	default 0x4000
 
 config ENV_OFFSET
 	default 0x3fc000 if ENV_IS_IN_SPI_FLASH
diff --git a/common/Kconfig b/common/Kconfig
index 482f123..0e36dfd 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -527,6 +527,12 @@
 	  U-Boot calls last_stage_init() before the command-line interpreter is
 	  started.
 
+config MISC_INIT_F
+	bool "Execute pre-relocation misc init"
+	help
+	  Enabling this option calls the 'misc_init_f' function in the init
+	  sequence just before DRAM is inited.
+
 config MISC_INIT_R
 	bool "Execute Misc Init"
 	default y if ARCH_KEYSTONE || ARCH_SUNXI || MPC85xx
diff --git a/common/usb_hub.c b/common/usb_hub.c
index 3d856e7..ba11a18 100644
--- a/common/usb_hub.c
+++ b/common/usb_hub.c
@@ -144,7 +144,8 @@
 
 	if (!usb_hub_is_root_hub(dev->dev) && usb_hub_is_superspeed(dev)) {
 		struct usb_port_status *status = (struct usb_port_status *)data;
-		u16 tmp = (status->wPortStatus) & USB_SS_PORT_STAT_MASK;
+		u16 tmp = le16_to_cpu(status->wPortStatus) &
+			USB_SS_PORT_STAT_MASK;
 
 		if (status->wPortStatus & USB_SS_PORT_STAT_POWER)
 			tmp |= USB_PORT_STAT_POWER;
@@ -152,7 +153,7 @@
 		    USB_SS_PORT_STAT_SPEED_5GBPS)
 			tmp |= USB_PORT_STAT_SUPER_SPEED;
 
-		status->wPortStatus = tmp;
+		status->wPortStatus = cpu_to_le16(tmp);
 	}
 #endif
 
diff --git a/configs/MPC8349ITXGP_defconfig b/configs/MPC8349ITXGP_defconfig
index 28e4ebf..92f2093 100644
--- a/configs/MPC8349ITXGP_defconfig
+++ b/configs/MPC8349ITXGP_defconfig
@@ -154,6 +154,7 @@
 CONFIG_BOOTDELAY=6
 CONFIG_USE_BOOTARGS=y
 CONFIG_BOOTARGS="root=/dev/nfs rw nfsroot=:/nfsroot/rootfs ip=::::mpc8349emitxgp:eth0:off console=ttyS0,115200"
+CONFIG_MISC_INIT_F=y
 CONFIG_MISC_INIT_R=y
 CONFIG_HUSH_PARSER=y
 CONFIG_SYS_PROMPT="MPC8349E-mITX-GP> "
diff --git a/configs/MPC8349ITX_LOWBOOT_defconfig b/configs/MPC8349ITX_LOWBOOT_defconfig
index 46f7afc..cf1e90d 100644
--- a/configs/MPC8349ITX_LOWBOOT_defconfig
+++ b/configs/MPC8349ITX_LOWBOOT_defconfig
@@ -153,6 +153,7 @@
 CONFIG_BOOTDELAY=6
 CONFIG_USE_BOOTARGS=y
 CONFIG_BOOTARGS="root=/dev/nfs rw nfsroot=:/nfsroot/rootfs ip=::::mpc8349emitx:eth0:off console=ttyS0,115200"
+CONFIG_MISC_INIT_F=y
 CONFIG_MISC_INIT_R=y
 CONFIG_HUSH_PARSER=y
 CONFIG_SYS_PROMPT="MPC8349E-mITX> "
diff --git a/configs/MPC8349ITX_defconfig b/configs/MPC8349ITX_defconfig
index 1f70b75..733e5d3 100644
--- a/configs/MPC8349ITX_defconfig
+++ b/configs/MPC8349ITX_defconfig
@@ -152,6 +152,7 @@
 CONFIG_BOOTDELAY=6
 CONFIG_USE_BOOTARGS=y
 CONFIG_BOOTARGS="root=/dev/nfs rw nfsroot=:/nfsroot/rootfs ip=::::mpc8349emitx:eth0:off console=ttyS0,115200"
+CONFIG_MISC_INIT_F=y
 CONFIG_MISC_INIT_R=y
 CONFIG_HUSH_PARSER=y
 CONFIG_SYS_PROMPT="MPC8349E-mITX> "
diff --git a/configs/beelink-gtking_defconfig b/configs/beelink-gtking_defconfig
index 6270c23..12caa58 100644
--- a/configs/beelink-gtking_defconfig
+++ b/configs/beelink-gtking_defconfig
@@ -30,9 +30,12 @@
 CONFIG_MMC_MESON_GX=y
 CONFIG_MTD=y
 CONFIG_DM_MTD=y
+CONFIG_DM_MDIO=y
+CONFIG_DM_MDIO_MUX=y
+CONFIG_MDIO_MUX_MESON_G12A=y
 CONFIG_PHY_REALTEK=y
 CONFIG_DM_ETH=y
-CONFIG_ETH_DESIGNWARE=y
+CONFIG_ETH_DESIGNWARE_MESON8B=y
 CONFIG_MESON_G12A_USB_PHY=y
 CONFIG_PINCTRL=y
 CONFIG_PINCTRL_MESON_G12A=y
diff --git a/configs/beelink-gtkingpro_defconfig b/configs/beelink-gtkingpro_defconfig
index 310654e..2b022e4 100644
--- a/configs/beelink-gtkingpro_defconfig
+++ b/configs/beelink-gtkingpro_defconfig
@@ -30,9 +30,12 @@
 CONFIG_MMC_MESON_GX=y
 CONFIG_MTD=y
 CONFIG_DM_MTD=y
+CONFIG_DM_MDIO=y
+CONFIG_DM_MDIO_MUX=y
+CONFIG_MDIO_MUX_MESON_G12A=y
 CONFIG_PHY_REALTEK=y
 CONFIG_DM_ETH=y
-CONFIG_ETH_DESIGNWARE=y
+CONFIG_ETH_DESIGNWARE_MESON8B=y
 CONFIG_MESON_G12A_USB_PHY=y
 CONFIG_PINCTRL=y
 CONFIG_PINCTRL_MESON_G12A=y
diff --git a/configs/khadas-vim2_defconfig b/configs/khadas-vim2_defconfig
index c26c0ca..0aaa6c0 100644
--- a/configs/khadas-vim2_defconfig
+++ b/configs/khadas-vim2_defconfig
@@ -36,9 +36,12 @@
 CONFIG_DM_MTD=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_DM_MDIO=y
+CONFIG_DM_MDIO_MUX=y
+CONFIG_MDIO_MUX_MMIOREG=y
 CONFIG_PHY_REALTEK=y
 CONFIG_DM_ETH=y
-CONFIG_ETH_DESIGNWARE=y
+CONFIG_ETH_DESIGNWARE_MESON8B=y
 CONFIG_MESON_GXL_USB_PHY=y
 CONFIG_PINCTRL=y
 CONFIG_PINCTRL_MESON_GXL=y
diff --git a/configs/khadas-vim3_defconfig b/configs/khadas-vim3_defconfig
index bc17430..cd0327c 100644
--- a/configs/khadas-vim3_defconfig
+++ b/configs/khadas-vim3_defconfig
@@ -41,9 +41,12 @@
 CONFIG_DM_MTD=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_DM_MDIO=y
+CONFIG_DM_MDIO_MUX=y
+CONFIG_MDIO_MUX_MESON_G12A=y
 CONFIG_PHY_REALTEK=y
 CONFIG_DM_ETH=y
-CONFIG_ETH_DESIGNWARE=y
+CONFIG_ETH_DESIGNWARE_MESON8B=y
 CONFIG_MESON_G12A_USB_PHY=y
 CONFIG_PINCTRL=y
 CONFIG_PINCTRL_MESON_G12A=y
diff --git a/configs/khadas-vim3l_defconfig b/configs/khadas-vim3l_defconfig
index c187792..ef85f00 100644
--- a/configs/khadas-vim3l_defconfig
+++ b/configs/khadas-vim3l_defconfig
@@ -41,9 +41,12 @@
 CONFIG_DM_MTD=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_DM_MDIO=y
+CONFIG_DM_MDIO_MUX=y
+CONFIG_MDIO_MUX_MESON_G12A=y
 CONFIG_PHY_REALTEK=y
 CONFIG_DM_ETH=y
-CONFIG_ETH_DESIGNWARE=y
+CONFIG_ETH_DESIGNWARE_MESON8B=y
 CONFIG_MESON_G12A_USB_PHY=y
 CONFIG_PINCTRL=y
 CONFIG_PINCTRL_MESON_G12A=y
diff --git a/configs/khadas-vim_defconfig b/configs/khadas-vim_defconfig
index e7e5c42..60cdfff 100644
--- a/configs/khadas-vim_defconfig
+++ b/configs/khadas-vim_defconfig
@@ -30,11 +30,12 @@
 CONFIG_SARADC_MESON=y
 CONFIG_DM_MMC=y
 CONFIG_MMC_MESON_GX=y
-CONFIG_PHY_ADDR_ENABLE=y
-CONFIG_PHY_ADDR=8
+CONFIG_DM_MDIO=y
+CONFIG_DM_MDIO_MUX=y
+CONFIG_MDIO_MUX_MMIOREG=y
 CONFIG_PHY_MESON_GXL=y
 CONFIG_DM_ETH=y
-CONFIG_ETH_DESIGNWARE=y
+CONFIG_ETH_DESIGNWARE_MESON8B=y
 CONFIG_MESON_GXL_USB_PHY=y
 CONFIG_PINCTRL=y
 CONFIG_PINCTRL_MESON_GXL=y
diff --git a/configs/kmcoge4_defconfig b/configs/kmcoge4_defconfig
index ddc8f8a..462e567 100644
--- a/configs/kmcoge4_defconfig
+++ b/configs/kmcoge4_defconfig
@@ -20,6 +20,7 @@
 CONFIG_BOARD_EARLY_INIT_F=y
 CONFIG_BOARD_EARLY_INIT_R=y
 CONFIG_LAST_STAGE_INIT=y
+CONFIG_MISC_INIT_F=y
 CONFIG_HUSH_PARSER=y
 CONFIG_CMD_ASKENV=y
 CONFIG_CMD_GREPENV=y
diff --git a/configs/libretech-ac_defconfig b/configs/libretech-ac_defconfig
index ca61591..b383dfb 100644
--- a/configs/libretech-ac_defconfig
+++ b/configs/libretech-ac_defconfig
@@ -37,16 +37,17 @@
 CONFIG_SARADC_MESON=y
 CONFIG_DM_MMC=y
 CONFIG_MMC_MESON_GX=y
+CONFIG_DM_MDIO=y
+CONFIG_DM_MDIO_MUX=y
+CONFIG_MDIO_MUX_MMIOREG=y
 CONFIG_MTD=y
 CONFIG_DM_MTD=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH_GIGADEVICE=y
 CONFIG_SPI_FLASH_SPANSION=y
-CONFIG_PHY_ADDR_ENABLE=y
-CONFIG_PHY_ADDR=8
 CONFIG_PHY_MESON_GXL=y
 CONFIG_DM_ETH=y
-CONFIG_ETH_DESIGNWARE=y
+CONFIG_ETH_DESIGNWARE_MESON8B=y
 CONFIG_MESON_GXL_USB_PHY=y
 CONFIG_PINCTRL=y
 CONFIG_PINCTRL_MESON_GXL=y
diff --git a/configs/libretech-cc_defconfig b/configs/libretech-cc_defconfig
index fb4bf4c..ba59dee 100644
--- a/configs/libretech-cc_defconfig
+++ b/configs/libretech-cc_defconfig
@@ -29,11 +29,12 @@
 CONFIG_SARADC_MESON=y
 CONFIG_DM_MMC=y
 CONFIG_MMC_MESON_GX=y
-CONFIG_PHY_ADDR_ENABLE=y
-CONFIG_PHY_ADDR=8
+CONFIG_DM_MDIO=y
+CONFIG_DM_MDIO_MUX=y
+CONFIG_MDIO_MUX_MMIOREG=y
 CONFIG_PHY_MESON_GXL=y
 CONFIG_DM_ETH=y
-CONFIG_ETH_DESIGNWARE=y
+CONFIG_ETH_DESIGNWARE_MESON8B=y
 CONFIG_MESON_GXL_USB_PHY=y
 CONFIG_PINCTRL=y
 CONFIG_PINCTRL_MESON_GXL=y
diff --git a/configs/libretech-cc_v2_defconfig b/configs/libretech-cc_v2_defconfig
index 86f88db..50ae3e1 100644
--- a/configs/libretech-cc_v2_defconfig
+++ b/configs/libretech-cc_v2_defconfig
@@ -37,11 +37,12 @@
 CONFIG_DM_MTD=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH_GIGADEVICE=y
-CONFIG_PHY_ADDR_ENABLE=y
-CONFIG_PHY_ADDR=8
+CONFIG_DM_MDIO=y
+CONFIG_DM_MDIO_MUX=y
+CONFIG_MDIO_MUX_MMIOREG=y
 CONFIG_PHY_MESON_GXL=y
 CONFIG_DM_ETH=y
-CONFIG_ETH_DESIGNWARE=y
+CONFIG_ETH_DESIGNWARE_MESON8B=y
 CONFIG_PHY=y
 CONFIG_MESON_GXL_USB_PHY=y
 CONFIG_PINCTRL=y
diff --git a/configs/libretech-s905d-pc_defconfig b/configs/libretech-s905d-pc_defconfig
index 85dfd9c..9ef6385 100644
--- a/configs/libretech-s905d-pc_defconfig
+++ b/configs/libretech-s905d-pc_defconfig
@@ -38,9 +38,12 @@
 CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_DM_MDIO=y
+CONFIG_DM_MDIO_MUX=y
+CONFIG_MDIO_MUX_MMIOREG=y
 CONFIG_PHY_REALTEK=y
 CONFIG_DM_ETH=y
-CONFIG_ETH_DESIGNWARE=y
+CONFIG_ETH_DESIGNWARE_MESON8B=y
 CONFIG_MESON_GXL_USB_PHY=y
 CONFIG_PINCTRL=y
 CONFIG_PINCTRL_MESON_GXL=y
diff --git a/configs/libretech-s912-pc_defconfig b/configs/libretech-s912-pc_defconfig
index a515833..a14ac20 100644
--- a/configs/libretech-s912-pc_defconfig
+++ b/configs/libretech-s912-pc_defconfig
@@ -37,9 +37,12 @@
 CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_DM_MDIO=y
+CONFIG_DM_MDIO_MUX=y
+CONFIG_MDIO_MUX_MMIOREG=y
 CONFIG_PHY_REALTEK=y
 CONFIG_DM_ETH=y
-CONFIG_ETH_DESIGNWARE=y
+CONFIG_ETH_DESIGNWARE_MESON8B=y
 CONFIG_MESON_GXL_USB_PHY=y
 CONFIG_PINCTRL=y
 CONFIG_PINCTRL_MESON_GXL=y
diff --git a/configs/lion-rk3368_defconfig b/configs/lion-rk3368_defconfig
index 583dd44..6d6b73d 100644
--- a/configs/lion-rk3368_defconfig
+++ b/configs/lion-rk3368_defconfig
@@ -9,7 +9,7 @@
 CONFIG_TPL_LIBCOMMON_SUPPORT=y
 CONFIG_TPL_LIBGENERIC_SUPPORT=y
 CONFIG_SPL_DRIVERS_MISC_SUPPORT=y
-CONFIG_SPL_STACK_R_ADDR=0x600000
+CONFIG_TARGET_LION_RK3368=y
 CONFIG_SPL=y
 CONFIG_DEBUG_UART_BASE=0xFF180000
 CONFIG_DEBUG_UART_CLOCK=24000000
@@ -33,18 +33,22 @@
 # CONFIG_SPL_RAW_IMAGE_SUPPORT is not set
 CONFIG_TPL_SYS_MALLOC_SIMPLE=y
 CONFIG_SPL_STACK_R=y
+CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x4000
 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x200
 CONFIG_SPL_ATF=y
 CONFIG_TPL=y
 CONFIG_TPL_DRIVERS_MISC_SUPPORT=y
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_MMC=y
+CONFIG_CMD_SPI=y
+CONFIG_CMD_USB=y
 CONFIG_CMD_BOOTSTAGE=y
 CONFIG_CMD_REGULATOR=y
 CONFIG_CMD_MTDPARTS=y
 CONFIG_SPL_OF_CONTROL=y
 CONFIG_TPL_OF_CONTROL=y
 CONFIG_OF_LIVE=y
+CONFIG_DEFAULT_DEVICE_TREE="rk3368-lion-haikou"
 CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names interrupt-parent"
 CONFIG_TPL_OF_PLATDATA=y
 CONFIG_ENV_IS_IN_MMC=y
@@ -61,14 +65,15 @@
 CONFIG_SPL_CLK=y
 CONFIG_TPL_CLK=y
 CONFIG_ROCKCHIP_GPIO=y
+CONFIG_SYS_I2C_ROCKCHIP=y
 CONFIG_MMC_DW=y
 CONFIG_MMC_DW_ROCKCHIP=y
 CONFIG_MTD=y
 CONFIG_SPI_FLASH_MACRONIX=y
 CONFIG_SPI_FLASH_WINBOND=y
-CONFIG_PHY_MICREL=y
-CONFIG_PHY_MICREL_KSZ90X1=y
+CONFIG_PHY_MSCC=y
 CONFIG_DM_ETH=y
+CONFIG_DM_ETH_PHY=y
 CONFIG_ETH_DESIGNWARE=y
 CONFIG_RGMII=y
 CONFIG_GMAC_ROCKCHIP=y
@@ -77,6 +82,7 @@
 CONFIG_DM_PMIC=y
 CONFIG_PMIC_RK8XX=y
 CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_REGULATOR_RK8XX=y
 CONFIG_RAM=y
 CONFIG_SPL_RAM=y
 CONFIG_TPL_RAM=y
@@ -87,6 +93,13 @@
 CONFIG_SYSINFO=y
 CONFIG_SYSINFO_SMBIOS=y
 CONFIG_SYSRESET=y
+CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_GENERIC=y
+CONFIG_USB_DWC2=y
+CONFIG_ROCKCHIP_USB2_PHY=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_DWC2_OTG=y
 CONFIG_SPL_TINY_MEMSET=y
 CONFIG_LZO=y
 CONFIG_ERRNO_STR=y
diff --git a/configs/mvebu_espressobin-88f3720_defconfig b/configs/mvebu_espressobin-88f3720_defconfig
index 212bc00..dd586c3 100644
--- a/configs/mvebu_espressobin-88f3720_defconfig
+++ b/configs/mvebu_espressobin-88f3720_defconfig
@@ -32,6 +32,7 @@
 CONFIG_CMD_PCI=y
 CONFIG_CMD_SPI=y
 CONFIG_CMD_USB=y
+CONFIG_CMD_WDT=y
 CONFIG_CMD_TFTPPUT=y
 CONFIG_CMD_CACHE=y
 CONFIG_CMD_TIME=y
@@ -88,4 +89,7 @@
 CONFIG_USB_ETHER_MCS7830=y
 CONFIG_USB_ETHER_RTL8152=y
 CONFIG_USB_ETHER_SMSC95XX=y
+# CONFIG_WATCHDOG_AUTOSTART is not set
+CONFIG_WDT=y
+CONFIG_WDT_ARMADA_37XX=y
 CONFIG_SHA1=y
diff --git a/configs/nanopi-k2_defconfig b/configs/nanopi-k2_defconfig
index c2dc488..4332271 100644
--- a/configs/nanopi-k2_defconfig
+++ b/configs/nanopi-k2_defconfig
@@ -29,7 +29,7 @@
 CONFIG_MMC_MESON_GX=y
 CONFIG_PHY_REALTEK=y
 CONFIG_DM_ETH=y
-CONFIG_ETH_DESIGNWARE=y
+CONFIG_ETH_DESIGNWARE_MESON8B=y
 CONFIG_PINCTRL=y
 CONFIG_PINCTRL_MESON_GXBB=y
 CONFIG_DM_REGULATOR=y
diff --git a/configs/nanopi-m4b-rk3399_defconfig b/configs/nanopi-m4b-rk3399_defconfig
new file mode 100644
index 0000000..eceb67e
--- /dev/null
+++ b/configs/nanopi-m4b-rk3399_defconfig
@@ -0,0 +1,61 @@
+CONFIG_ARM=y
+CONFIG_ARCH_ROCKCHIP=y
+CONFIG_SYS_TEXT_BASE=0x00200000
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_ENV_OFFSET=0x3F8000
+CONFIG_ROCKCHIP_RK3399=y
+CONFIG_TARGET_EVB_RK3399=y
+CONFIG_DEBUG_UART_BASE=0xFF1A0000
+CONFIG_DEBUG_UART_CLOCK=24000000
+CONFIG_DEFAULT_DEVICE_TREE="rk3399-nanopi-m4b"
+CONFIG_DEBUG_UART=y
+CONFIG_DEFAULT_FDT_FILE="rockchip/rk3399-nanopi-m4b.dtb"
+CONFIG_DISPLAY_BOARDINFO_LATE=y
+# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set
+CONFIG_SPL_STACK_R=y
+CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x10000
+CONFIG_TPL=y
+CONFIG_CMD_BOOTZ=y
+CONFIG_CMD_GPT=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_USB=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_TIME=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_ENV_IS_IN_MMC=y
+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+CONFIG_ROCKCHIP_GPIO=y
+CONFIG_SYS_I2C_ROCKCHIP=y
+CONFIG_MMC_DW=y
+CONFIG_MMC_DW_ROCKCHIP=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_ROCKCHIP=y
+CONFIG_DM_ETH=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_GMAC_ROCKCHIP=y
+CONFIG_PMIC_RK8XX=y
+CONFIG_REGULATOR_PWM=y
+CONFIG_REGULATOR_RK8XX=y
+CONFIG_PWM_ROCKCHIP=y
+CONFIG_BAUDRATE=1500000
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_SYSRESET=y
+CONFIG_USB=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_DWC3=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_GENERIC=y
+CONFIG_USB_KEYBOARD=y
+CONFIG_USB_HOST_ETHER=y
+CONFIG_USB_ETHER_ASIX=y
+CONFIG_USB_ETHER_ASIX88179=y
+CONFIG_USB_ETHER_MCS7830=y
+CONFIG_USB_ETHER_RTL8152=y
+CONFIG_USB_ETHER_SMSC95XX=y
+CONFIG_DM_VIDEO=y
+CONFIG_DISPLAY=y
+CONFIG_VIDEO_ROCKCHIP=y
+CONFIG_DISPLAY_ROCKCHIP_HDMI=y
+CONFIG_SPL_TINY_MEMSET=y
+CONFIG_ERRNO_STR=y
diff --git a/configs/nanopi-r4s-rk3399_defconfig b/configs/nanopi-r4s-rk3399_defconfig
new file mode 100644
index 0000000..0a3c28b
--- /dev/null
+++ b/configs/nanopi-r4s-rk3399_defconfig
@@ -0,0 +1,62 @@
+CONFIG_ARM=y
+CONFIG_ARCH_ROCKCHIP=y
+CONFIG_SYS_TEXT_BASE=0x00200000
+CONFIG_ENV_OFFSET=0x3F8000
+CONFIG_ROCKCHIP_RK3399=y
+CONFIG_TARGET_EVB_RK3399=y
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_DEBUG_UART_BASE=0xFF1A0000
+CONFIG_DEBUG_UART_CLOCK=24000000
+CONFIG_DEBUG_UART=y
+CONFIG_DEFAULT_FDT_FILE="rockchip/rk3399-nanopi-r4s.dtb"
+CONFIG_DISPLAY_BOARDINFO_LATE=y
+# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set
+CONFIG_SPL_STACK_R=y
+CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x10000
+CONFIG_TPL=y
+CONFIG_CMD_BOOTZ=y
+CONFIG_CMD_GPT=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_USB=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_TIME=y
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_DEFAULT_DEVICE_TREE="rk3399-nanopi-r4s"
+CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents"
+CONFIG_ENV_IS_IN_MMC=y
+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+CONFIG_ROCKCHIP_GPIO=y
+CONFIG_SYS_I2C_ROCKCHIP=y
+CONFIG_MMC_DW=y
+CONFIG_MMC_DW_ROCKCHIP=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_ROCKCHIP=y
+CONFIG_DM_ETH=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_GMAC_ROCKCHIP=y
+CONFIG_PMIC_RK8XX=y
+CONFIG_REGULATOR_PWM=y
+CONFIG_REGULATOR_RK8XX=y
+CONFIG_PWM_ROCKCHIP=y
+CONFIG_RAM_RK3399_LPDDR4=y
+CONFIG_BAUDRATE=1500000
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_SYSRESET=y
+CONFIG_USB=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_DWC3=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_GENERIC=y
+CONFIG_USB_KEYBOARD=y
+CONFIG_USB_HOST_ETHER=y
+CONFIG_USB_ETHER_ASIX=y
+CONFIG_USB_ETHER_ASIX88179=y
+CONFIG_USB_ETHER_MCS7830=y
+CONFIG_USB_ETHER_RTL8152=y
+CONFIG_USB_ETHER_SMSC95XX=y
+CONFIG_DM_VIDEO=y
+CONFIG_DISPLAY=y
+CONFIG_VIDEO_ROCKCHIP=y
+CONFIG_DISPLAY_ROCKCHIP_HDMI=y
+CONFIG_SPL_TINY_MEMSET=y
+CONFIG_ERRNO_STR=y
diff --git a/configs/odroid-c2_defconfig b/configs/odroid-c2_defconfig
index 5c02fa1..7ce65b1 100644
--- a/configs/odroid-c2_defconfig
+++ b/configs/odroid-c2_defconfig
@@ -32,7 +32,7 @@
 CONFIG_MMC_MESON_GX=y
 CONFIG_PHY_REALTEK=y
 CONFIG_DM_ETH=y
-CONFIG_ETH_DESIGNWARE=y
+CONFIG_ETH_DESIGNWARE_MESON8B=y
 CONFIG_PHY=y
 CONFIG_MESON_GXBB_USB_PHY=y
 CONFIG_PINCTRL=y
diff --git a/configs/odroid-c4_defconfig b/configs/odroid-c4_defconfig
index 8a9b8b0..48fb891 100644
--- a/configs/odroid-c4_defconfig
+++ b/configs/odroid-c4_defconfig
@@ -30,9 +30,12 @@
 CONFIG_SARADC_MESON=y
 CONFIG_DM_MMC=y
 CONFIG_MMC_MESON_GX=y
+CONFIG_DM_MDIO=y
+CONFIG_DM_MDIO_MUX=y
+CONFIG_MDIO_MUX_MESON_G12A=y
 CONFIG_PHY_REALTEK=y
 CONFIG_DM_ETH=y
-CONFIG_ETH_DESIGNWARE=y
+CONFIG_ETH_DESIGNWARE_MESON8B=y
 CONFIG_MESON_G12A_USB_PHY=y
 CONFIG_PINCTRL=y
 CONFIG_PINCTRL_MESON_G12A=y
diff --git a/configs/odroid-go2_defconfig b/configs/odroid-go2_defconfig
index 8538909..6aa41e3 100644
--- a/configs/odroid-go2_defconfig
+++ b/configs/odroid-go2_defconfig
@@ -24,7 +24,7 @@
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_BEST_MATCH=y
 CONFIG_SPL_LOAD_FIT=y
-CONFIG_DEFAULT_FDT_FILE="rk3326-odroidgo2.dtb"
+CONFIG_DEFAULT_FDT_FILE="rockchip/rk3326-odroid-go2.dtb"
 # CONFIG_CONSOLE_MUX is not set
 # CONFIG_DISPLAY_CPUINFO is not set
 CONFIG_DISPLAY_BOARDINFO_LATE=y
@@ -33,7 +33,6 @@
 # CONFIG_SPL_RAW_IMAGE_SUPPORT is not set
 CONFIG_SPL_STACK_R=y
 # CONFIG_TPL_BANNER_PRINT is not set
-CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x200
 CONFIG_SPL_CRC32_SUPPORT=y
 CONFIG_SPL_I2C_SUPPORT=y
 CONFIG_SPL_POWER_SUPPORT=y
@@ -110,4 +109,3 @@
 CONFIG_TPL_TINY_MEMSET=y
 CONFIG_LZO=y
 CONFIG_ERRNO_STR=y
-# CONFIG_EFI_LOADER is not set
diff --git a/configs/odroid-n2_defconfig b/configs/odroid-n2_defconfig
index b82bd78..d2a8c34 100644
--- a/configs/odroid-n2_defconfig
+++ b/configs/odroid-n2_defconfig
@@ -30,9 +30,12 @@
 CONFIG_SARADC_MESON=y
 CONFIG_DM_MMC=y
 CONFIG_MMC_MESON_GX=y
+CONFIG_DM_MDIO=y
+CONFIG_DM_MDIO_MUX=y
+CONFIG_MDIO_MUX_MESON_G12A=y
 CONFIG_PHY_REALTEK=y
 CONFIG_DM_ETH=y
-CONFIG_ETH_DESIGNWARE=y
+CONFIG_ETH_DESIGNWARE_MESON8B=y
 CONFIG_MESON_G12A_USB_PHY=y
 CONFIG_PINCTRL=y
 CONFIG_PINCTRL_MESON_G12A=y
diff --git a/configs/p200_defconfig b/configs/p200_defconfig
index 6efc7bc..c61e974 100644
--- a/configs/p200_defconfig
+++ b/configs/p200_defconfig
@@ -28,7 +28,7 @@
 CONFIG_DM_MMC=y
 CONFIG_MMC_MESON_GX=y
 CONFIG_DM_ETH=y
-CONFIG_ETH_DESIGNWARE=y
+CONFIG_ETH_DESIGNWARE_MESON8B=y
 CONFIG_PINCTRL=y
 CONFIG_PINCTRL_MESON_GXBB=y
 CONFIG_DM_REGULATOR=y
diff --git a/configs/p201_defconfig b/configs/p201_defconfig
index a1d3f04..34dc154 100644
--- a/configs/p201_defconfig
+++ b/configs/p201_defconfig
@@ -29,7 +29,7 @@
 CONFIG_DM_MMC=y
 CONFIG_MMC_MESON_GX=y
 CONFIG_DM_ETH=y
-CONFIG_ETH_DESIGNWARE=y
+CONFIG_ETH_DESIGNWARE_MESON8B=y
 CONFIG_PINCTRL=y
 CONFIG_PINCTRL_MESON_GXBB=y
 CONFIG_DM_REGULATOR=y
diff --git a/configs/p212_defconfig b/configs/p212_defconfig
index da66c50..c36a674 100644
--- a/configs/p212_defconfig
+++ b/configs/p212_defconfig
@@ -27,11 +27,12 @@
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_DM_MMC=y
 CONFIG_MMC_MESON_GX=y
-CONFIG_PHY_ADDR_ENABLE=y
-CONFIG_PHY_ADDR=8
+CONFIG_DM_MDIO=y
+CONFIG_DM_MDIO_MUX=y
+CONFIG_MDIO_MUX_MMIOREG=y
 CONFIG_PHY_MESON_GXL=y
 CONFIG_DM_ETH=y
-CONFIG_ETH_DESIGNWARE=y
+CONFIG_ETH_DESIGNWARE_MESON8B=y
 CONFIG_MESON_GXL_USB_PHY=y
 CONFIG_PINCTRL=y
 CONFIG_PINCTRL_MESON_GXL=y
diff --git a/configs/rock960-rk3399_defconfig b/configs/rock960-rk3399_defconfig
index 28d1fc5..9f1aeaa 100644
--- a/configs/rock960-rk3399_defconfig
+++ b/configs/rock960-rk3399_defconfig
@@ -23,6 +23,7 @@
 CONFIG_CMD_PCI=y
 CONFIG_CMD_USB=y
 # CONFIG_CMD_SETEXPR is not set
+# CONFIG_CMD_SF is not set
 CONFIG_CMD_TIME=y
 CONFIG_CMD_PMIC=y
 CONFIG_CMD_REGULATOR=y
diff --git a/configs/s400_defconfig b/configs/s400_defconfig
index a15ac32..39e44c0 100644
--- a/configs/s400_defconfig
+++ b/configs/s400_defconfig
@@ -29,7 +29,7 @@
 CONFIG_MMC_MESON_GX=y
 CONFIG_PHY_REALTEK=y
 CONFIG_DM_ETH=y
-CONFIG_ETH_DESIGNWARE=y
+CONFIG_ETH_DESIGNWARE_MESON8B=y
 CONFIG_MESON_GXL_USB_PHY=y
 CONFIG_PINCTRL=y
 CONFIG_PINCTRL_MESON_AXG=y
diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig
index cfda834..4648808 100644
--- a/configs/sandbox64_defconfig
+++ b/configs/sandbox64_defconfig
@@ -20,8 +20,8 @@
 CONFIG_CONSOLE_RECORD=y
 CONFIG_CONSOLE_RECORD_OUT_SIZE=0x1000
 CONFIG_PRE_CONSOLE_BUFFER=y
-CONFIG_LOG_SYSLOG=y
 CONFIG_DISPLAY_BOARDINFO_LATE=y
+CONFIG_MISC_INIT_F=y
 CONFIG_CMD_CPU=y
 CONFIG_CMD_LICENSE=y
 CONFIG_CMD_BOOTZ=y
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 5bc90d0..5da8d16 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -24,6 +24,7 @@
 CONFIG_LOG_SYSLOG=y
 CONFIG_LOG_ERROR_RETURN=y
 CONFIG_DISPLAY_BOARDINFO_LATE=y
+CONFIG_MISC_INIT_F=y
 CONFIG_ANDROID_AB=y
 CONFIG_CMD_CPU=y
 CONFIG_CMD_LICENSE=y
diff --git a/configs/sandbox_flattree_defconfig b/configs/sandbox_flattree_defconfig
index 4401f33..b68f938 100644
--- a/configs/sandbox_flattree_defconfig
+++ b/configs/sandbox_flattree_defconfig
@@ -17,8 +17,8 @@
 CONFIG_BOOTSTAGE_STASH_SIZE=0x4096
 CONFIG_CONSOLE_RECORD=y
 CONFIG_CONSOLE_RECORD_OUT_SIZE=0x1000
-CONFIG_LOG_SYSLOG=y
 CONFIG_DISPLAY_BOARDINFO_LATE=y
+CONFIG_MISC_INIT_F=y
 CONFIG_CMD_CPU=y
 CONFIG_CMD_LICENSE=y
 CONFIG_CMD_BOOTZ=y
diff --git a/configs/sandbox_spl_defconfig b/configs/sandbox_spl_defconfig
index ac71cab..0e40b17 100644
--- a/configs/sandbox_spl_defconfig
+++ b/configs/sandbox_spl_defconfig
@@ -11,6 +11,7 @@
 CONFIG_SPL=y
 CONFIG_BOOTSTAGE_STASH_ADDR=0x0
 CONFIG_DEFAULT_DEVICE_TREE="sandbox"
+CONFIG_TARGET_SANDBOX_SPL=y
 CONFIG_SANDBOX_SPL=y
 CONFIG_DEBUG_UART=y
 CONFIG_DISTRO_DEFAULTS=y
@@ -27,6 +28,7 @@
 CONFIG_CONSOLE_RECORD=y
 CONFIG_CONSOLE_RECORD_OUT_SIZE=0x1000
 CONFIG_DISPLAY_BOARDINFO_LATE=y
+CONFIG_MISC_INIT_F=y
 CONFIG_HANDOFF=y
 CONFIG_SPL_BOARD_INIT=y
 CONFIG_SPL_ENV_SUPPORT=y
diff --git a/configs/sei510_defconfig b/configs/sei510_defconfig
index 7b97a2f..2c84abf 100644
--- a/configs/sei510_defconfig
+++ b/configs/sei510_defconfig
@@ -45,10 +45,11 @@
 # CONFIG_INPUT is not set
 CONFIG_DM_MMC=y
 CONFIG_MMC_MESON_GX=y
-CONFIG_PHY_ADDR_ENABLE=y
-CONFIG_PHY_ADDR=8
+CONFIG_DM_MDIO=y
+CONFIG_DM_MDIO_MUX=y
+CONFIG_MDIO_MUX_MESON_G12A=y
 CONFIG_DM_ETH=y
-CONFIG_ETH_DESIGNWARE=y
+CONFIG_ETH_DESIGNWARE_MESON8B=y
 CONFIG_MESON_G12A_USB_PHY=y
 CONFIG_PINCTRL=y
 CONFIG_PINCTRL_MESON_G12A=y
diff --git a/configs/sei610_defconfig b/configs/sei610_defconfig
index 0ed1709..392ab64 100644
--- a/configs/sei610_defconfig
+++ b/configs/sei610_defconfig
@@ -45,10 +45,11 @@
 # CONFIG_INPUT is not set
 CONFIG_DM_MMC=y
 CONFIG_MMC_MESON_GX=y
-CONFIG_PHY_ADDR_ENABLE=y
-CONFIG_PHY_ADDR=8
+CONFIG_DM_MDIO=y
+CONFIG_DM_MDIO_MUX=y
+CONFIG_MDIO_MUX_MESON_G12A=y
 CONFIG_DM_ETH=y
-CONFIG_ETH_DESIGNWARE=y
+CONFIG_ETH_DESIGNWARE_MESON8B=y
 CONFIG_MESON_G12A_USB_PHY=y
 CONFIG_PINCTRL=y
 CONFIG_PINCTRL_MESON_G12A=y
diff --git a/configs/tools-only_defconfig b/configs/tools-only_defconfig
index a853abf..e16f702 100644
--- a/configs/tools-only_defconfig
+++ b/configs/tools-only_defconfig
@@ -4,6 +4,7 @@
 CONFIG_ANDROID_BOOT_IMAGE=y
 CONFIG_FIT=y
 CONFIG_FIT_SIGNATURE=y
+CONFIG_MISC_INIT_F=y
 # CONFIG_CMD_BOOTD is not set
 # CONFIG_CMD_BOOTM is not set
 # CONFIG_CMD_ELF is not set
diff --git a/configs/u200_defconfig b/configs/u200_defconfig
index b0b822b..4da02f1 100644
--- a/configs/u200_defconfig
+++ b/configs/u200_defconfig
@@ -27,10 +27,11 @@
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_DM_MMC=y
 CONFIG_MMC_MESON_GX=y
-CONFIG_PHY_ADDR_ENABLE=y
-CONFIG_PHY_ADDR=8
+CONFIG_DM_MDIO=y
+CONFIG_DM_MDIO_MUX=y
+CONFIG_MDIO_MUX_MESON_G12A=y
 CONFIG_DM_ETH=y
-CONFIG_ETH_DESIGNWARE=y
+CONFIG_ETH_DESIGNWARE_MESON8B=y
 CONFIG_MESON_G12A_USB_PHY=y
 CONFIG_PINCTRL=y
 CONFIG_PINCTRL_MESON_G12A=y
diff --git a/configs/wetek-core2_defconfig b/configs/wetek-core2_defconfig
index cbe747b..098e249 100644
--- a/configs/wetek-core2_defconfig
+++ b/configs/wetek-core2_defconfig
@@ -31,9 +31,12 @@
 CONFIG_MMC_MESON_GX=y
 CONFIG_MTD=y
 CONFIG_DM_MTD=y
+CONFIG_DM_MDIO=y
+CONFIG_DM_MDIO_MUX=y
+CONFIG_MDIO_MUX_MMIOREG=y
 CONFIG_PHY_REALTEK=y
 CONFIG_DM_ETH=y
-CONFIG_ETH_DESIGNWARE=y
+CONFIG_ETH_DESIGNWARE_MESON8B=y
 CONFIG_MESON_GXL_USB_PHY=y
 CONFIG_PINCTRL=y
 CONFIG_PINCTRL_MESON_GXL=y
diff --git a/doc/board/rockchip/rockchip.rst b/doc/board/rockchip/rockchip.rst
index 955e685..fbb9983 100644
--- a/doc/board/rockchip/rockchip.rst
+++ b/doc/board/rockchip/rockchip.rst
@@ -61,6 +61,7 @@
      - Firefly ROC-RK3399-PC
      - FriendlyElec NanoPC-T4 (nanopc-t4-rk3399)
      - FriendlyElec NanoPi M4 (nanopi-m4-rk3399)
+     - FriendlyElec NanoPi M4B (nanopi-m4b-rk3399)
      - FriendlyARM NanoPi NEO4 (nanopi-neo4-rk3399)
      - Google Bob (chromebook_bob)
      - Khadas Edge (khadas-edge-rk3399)
diff --git a/doc/develop/driver-model/design.rst b/doc/develop/driver-model/design.rst
index 4e5cecb..b0e6337 100644
--- a/doc/develop/driver-model/design.rst
+++ b/doc/develop/driver-model/design.rst
@@ -900,6 +900,139 @@
 The dm_remove_devices_flags() function can be used to remove devices based on
 their driver flags.
 
+
+Error codes
+-----------
+
+Driver model tries to use errors codes in a consistent way, as follows:
+
+\-EAGAIN
+   Try later, e.g. dependencies not ready
+
+\-EINVAL
+   Invalid argument, such as `dev_read_...()` failed or any other
+   devicetree-related access. Also used when a driver method is passed an
+   argument it considers invalid or does not support.
+
+\-EIO
+   Failed to perform an I/O operation. This is used when a local device
+   (i.e. part of the SOC) does not work as expected. Use -EREMOTEIO for
+   failures to talk to a separate device, e.g. over an I2C or SPI
+   channel.
+
+\-ENODEV
+   Do not bind the device. This should not be used to indicate an
+   error probing the device or for any other purpose, lest driver model get
+   confused. Using `-ENODEV` inside a driver method makes no sense, since
+   clearly there is a device.
+
+\-ENOENT
+   Entry or object not found. This is used when a device, file or directory
+   cannot be found (e.g. when looked up by name), It can also indicate a
+   missing devicetree subnode.
+
+\-ENOMEM
+   Out of memory
+
+\-ENOSPC
+   Ran out of space (e.g. in a buffer or limited-size array)
+
+\-ENOSYS
+   Function not implemented. This is returned by uclasses where the driver does
+   not implement a particular method. It can also be returned by drivers when
+   a particular sub-method is not implemented. This is widely checked in the
+   wider code base, where a feature may or may not be compiled into U-Boot. It
+   indicates that the feature is not available, but this is often just normal
+   operation. Please do not use -ENOSUPP. If an incorrect or unknown argument
+   is provided to a method (e.g. an unknown clock ID), return -EINVAL.
+
+\-ENXIO
+   Couldn't find device/address. This is used when a device or address
+   could not be obtained or is not valid. It is often used to indicate a
+   different type of problem, if -ENOENT is already used for something else in
+   the driver.
+
+\-EPERM
+   This is -1 so some older code may use it as a generic error. This indicates
+   that an operation is not permitted, e.g. a security violation or policy
+   constraint. It is returned internally when binding devices before relocation,
+   if the device is not marked for pre-relocation use.
+
+\-EPFNOSUPPORT
+   Missing uclass. This is deliberately an uncommon error code so that it can
+   easily be distinguished. If you see this very early in U-Boot, it means that
+   a device exists with a particular uclass but the uclass does not (mostly
+   likely because it is not compiled in). Enable DEBUG in uclass.c or lists.c
+   to see which uclass ID or driver is causing the problem.
+
+\-EREMOTEIO
+   This indicates an error in talking to a peripheral over a comms link, such
+   as I2C or SPI. It might indicate that the device is not present or is not
+   responding as expected.
+
+\-ETIMEDOUT
+   Hardware access or some other operation has timed out. This is used where
+   there is an expected time of response and that was exceeded by enough of
+   a margin that there is probably something wrong.
+
+
+Less common ones:
+
+\-ECOMM
+   Not widely used, but similar to -EREMOTEIO. Can be useful as a secondary
+   error to distinguish the problem from -EREMOTEIO.
+
+\-EKEYREJECTED
+   Attempt to remove a device which does not match the removal flags. See
+   device_remove().
+
+\-EILSEQ
+   Devicetree read failure, specifically trying to read a string index which
+   does not exist, in a string-listg property
+
+\-ENOEXEC
+   Attempt to use a uclass method on a device not in that uclass. This is
+   seldom checked at present, since it is generally a programming error and a
+   waste of code space. A DEBUG-only check would be useful here.
+
+\-ENODATA
+   Devicetree read error, where a property exists but has no data associated
+   with it
+
+\-EOVERFLOW
+   Devicetree read error, where the property is longer than expected
+
+\-EPROBE_DEFER
+   Attempt to remove a non-vital device when the removal flags indicate that
+   only vital devices should be removed
+
+\-ERANGE
+   Returned by regmap functions when arguments are out of range. This can be
+   useful for disinguishing regmap errors from other errors obtained while
+   probing devices.
+
+Drivers should use the same conventions so that things function as expected.
+In particular, if a driver fails to probe, or a uclass operation fails, the
+error code is the primary way to indicate what actually happened.
+
+Printing error messages in drivers is discouraged due to code size bloat and
+since it can result in messages appearing in normal operation. For example, if
+a command tries two different devices and uses whichever one probes correctly,
+we don't want an error message displayed, even if the command itself might show
+a warning or informational message. Ideally, messages in drivers should only be
+displayed when debugging, e.g. by using log_debug() although in extreme cases
+log_warning() or log_error() may be used.
+
+Error messages can be logged using `log_msg_ret()`, so that enabling
+`CONFIG_LOG` and `CONFIG_LOG_ERROR_RETURN` shows a trace of error codes returned
+through the call stack. That can be a handy way of quickly figuring out where
+an error occurred. Get into the habit of return errors with
+`return log_msg_ret("here", ret)` instead of just `return ret`. The string
+just needs to be long enough to find in a single function, since a log record
+stores (and can print with `CONFIG_LOGF_FUNC`) the function where it was
+generated.
+
+
 Data Structures
 ---------------
 
diff --git a/drivers/clk/aspeed/clk_ast2600.c b/drivers/clk/aspeed/clk_ast2600.c
index acb7eca..3a92739 100644
--- a/drivers/clk/aspeed/clk_ast2600.c
+++ b/drivers/clk/aspeed/clk_ast2600.c
@@ -1140,7 +1140,7 @@
 
 		clk_free(&clk);
 
-		if (ret == -ENOTSUPP) {
+		if (ret == -EINVAL) {
 			printf("clk ID %lu not supported yet\n",
 			       aspeed_clk_names[i].id);
 			continue;
diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c
index 7e99c5b..bb5351e 100644
--- a/drivers/clk/clk-composite.c
+++ b/drivers/clk/clk-composite.c
@@ -37,10 +37,10 @@
 	const struct clk_ops *mux_ops = composite->mux_ops;
 	struct clk *mux = composite->mux;
 
-	if (mux && mux_ops)
-		return mux_ops->set_parent(mux, parent);
-	else
-		return -ENOTSUPP;
+	if (!mux || !mux_ops)
+		return -ENOSYS;
+
+	return mux_ops->set_parent(mux, parent);
 }
 
 static unsigned long clk_composite_recalc_rate(struct clk *clk)
diff --git a/drivers/clk/clk-hsdk-cgu.c b/drivers/clk/clk-hsdk-cgu.c
index 449b430..26b0aa9 100644
--- a/drivers/clk/clk-hsdk-cgu.c
+++ b/drivers/clk/clk-hsdk-cgu.c
@@ -718,7 +718,7 @@
 	if (clk->map[sclk->id].set_rate)
 		return clk->map[sclk->id].set_rate(sclk, rate);
 
-	return -ENOTSUPP;
+	return -EINVAL;
 }
 
 static int hsdk_cgu_disable(struct clk *sclk)
@@ -731,7 +731,7 @@
 	if (clk->map[sclk->id].disable)
 		return clk->map[sclk->id].disable(sclk);
 
-	return -ENOTSUPP;
+	return -EINVAL;
 }
 
 static const struct clk_ops hsdk_cgu_ops = {
diff --git a/drivers/clk/imx/clk-imx8.c b/drivers/clk/imx/clk-imx8.c
index 8484613..b3dc138 100644
--- a/drivers/clk/imx/clk-imx8.c
+++ b/drivers/clk/imx/clk-imx8.c
@@ -29,7 +29,7 @@
 
 __weak int __imx8_clk_enable(struct clk *clk, bool enable)
 {
-	return -ENOTSUPP;
+	return -EINVAL;
 }
 
 static int imx8_clk_disable(struct clk *clk)
@@ -70,7 +70,7 @@
 
 		clk_free(&clk);
 
-		if (ret == -ENOTSUPP) {
+		if (ret == -EINVAL) {
 			printf("clk ID %lu not supported yet\n",
 			       imx8_clk_names[i].id);
 			continue;
diff --git a/drivers/clk/imx/clk-imx8qm.c b/drivers/clk/imx/clk-imx8qm.c
index 7e466d6..7759dc6 100644
--- a/drivers/clk/imx/clk-imx8qm.c
+++ b/drivers/clk/imx/clk-imx8qm.c
@@ -133,7 +133,7 @@
 			       __func__, clk->id);
 			return -EINVAL;
 		}
-		return -ENOTSUPP;
+		return -EINVAL;
 	};
 
 	ret = sc_pm_get_clock_rate(-1, resource, pm_clk,
@@ -237,7 +237,7 @@
 			       __func__, clk->id);
 			return -EINVAL;
 		}
-		return -ENOTSUPP;
+		return -EINVAL;
 	};
 
 	ret = sc_pm_set_clock_rate(-1, resource, pm_clk, &new_rate);
@@ -337,7 +337,7 @@
 			       __func__, clk->id);
 			return -EINVAL;
 		}
-		return -ENOTSUPP;
+		return -EINVAL;
 	}
 
 	ret = sc_pm_clock_enable(-1, resource, pm_clk, enable, 0);
diff --git a/drivers/clk/imx/clk-imx8qxp.c b/drivers/clk/imx/clk-imx8qxp.c
index e6b2fb4..ffa2fce 100644
--- a/drivers/clk/imx/clk-imx8qxp.c
+++ b/drivers/clk/imx/clk-imx8qxp.c
@@ -126,7 +126,7 @@
 			       __func__, clk->id);
 			return -EINVAL;
 		}
-		return -ENOTSUPP;
+		return -EINVAL;
 	};
 
 	ret = sc_pm_get_clock_rate(-1, resource, pm_clk,
@@ -221,7 +221,7 @@
 			       __func__, clk->id);
 			return -EINVAL;
 		}
-		return -ENOTSUPP;
+		return -EINVAL;
 	};
 
 	ret = sc_pm_set_clock_rate(-1, resource, pm_clk, &new_rate);
@@ -311,7 +311,7 @@
 			       __func__, clk->id);
 			return -EINVAL;
 		}
-		return -ENOTSUPP;
+		return -EINVAL;
 	}
 
 	ret = sc_pm_clock_enable(-1, resource, pm_clk, enable, 0);
diff --git a/drivers/clk/imx/clk-pllv3.c b/drivers/clk/imx/clk-pllv3.c
index feacaee..b5cbf80 100644
--- a/drivers/clk/imx/clk-pllv3.c
+++ b/drivers/clk/imx/clk-pllv3.c
@@ -290,7 +290,7 @@
 		break;
 	default:
 		kfree(pll);
-		return ERR_PTR(-ENOTSUPP);
+		return ERR_PTR(-EINVAL);
 	}
 
 	pll->base = base;
diff --git a/drivers/clk/kendryte/bypass.c b/drivers/clk/kendryte/bypass.c
index 5f1986f..bbdbd9a 100644
--- a/drivers/clk/kendryte/bypass.c
+++ b/drivers/clk/kendryte/bypass.c
@@ -157,7 +157,7 @@
 	if (ops->set_parent)
 		return ops->set_parent(bypass->bypassee, parent);
 	else
-		return -ENOTSUPP;
+		return -EINVAL;
 }
 
 /*
diff --git a/drivers/clk/kendryte/clk.c b/drivers/clk/kendryte/clk.c
index 4b95940..3b674a9 100644
--- a/drivers/clk/kendryte/clk.c
+++ b/drivers/clk/kendryte/clk.c
@@ -495,7 +495,7 @@
 	 * could fix this, but it's Probably Not Worth It (TM).
 	 */
 	if (probed)
-		return -ENOTSUPP;
+		return -EINVAL;
 
 	base = dev_read_addr_ptr(dev_get_parent(dev));
 	if (!base)
diff --git a/drivers/clk/mvebu/armada-37xx-periph.c b/drivers/clk/mvebu/armada-37xx-periph.c
index 0132fcb..b0f47c3 100644
--- a/drivers/clk/mvebu/armada-37xx-periph.c
+++ b/drivers/clk/mvebu/armada-37xx-periph.c
@@ -340,7 +340,7 @@
 		return -EINVAL;
 
 	if (!periph_clk->can_gate)
-		return -ENOTSUPP;
+		return -EINVAL;
 
 	if (enable)
 		clrbits_le32(priv->reg + CLK_DIS, periph_clk->disable_bit);
@@ -408,7 +408,7 @@
 		return old_rate;
 
 	if (!periph_clk->can_gate || !periph_clk->dividers)
-		return -ENOTSUPP;
+		return -EINVAL;
 
 	parent_rate = get_parent_rate(priv, clk->id);
 	if (parent_rate == -EINVAL)
@@ -445,7 +445,7 @@
 		return -EINVAL;
 
 	if (!periph_clk->can_mux || !periph_clk->can_gate)
-		return -ENOTSUPP;
+		return -EINVAL;
 
 	ret = clk_get_by_index(clk->dev, 0, &check_parent);
 	if (ret < 0)
diff --git a/drivers/core/acpi.c b/drivers/core/acpi.c
index 0901b92..2176d8b 100644
--- a/drivers/core/acpi.c
+++ b/drivers/core/acpi.c
@@ -91,7 +91,7 @@
 	path = dev_read_string(dev, "acpi,path");
 	if (path) {
 		if (strlen(path) >= maxlen)
-			return -E2BIG;
+			return -ENOSPC;
 		strcpy(out_path, path);
 		return 0;
 	}
diff --git a/drivers/core/simple-pm-bus.c b/drivers/core/simple-pm-bus.c
index 7a18953..1bb0d86 100644
--- a/drivers/core/simple-pm-bus.c
+++ b/drivers/core/simple-pm-bus.c
@@ -21,7 +21,7 @@
 		return ret;
 
 	ret = clk_enable_bulk(bulk);
-	if (ret && ret != -ENOSYS && ret != -ENOTSUPP) {
+	if (ret && ret != -ENOSYS) {
 		clk_release_bulk(bulk);
 		return ret;
 	}
@@ -34,7 +34,7 @@
 	struct clk_bulk *bulk = dev_get_priv(dev);
 
 	ret = clk_release_bulk(bulk);
-	if (ret && ret != -ENOSYS && ret != -ENOTSUPP)
+	if (ret && ret != -ENOSYS)
 		return ret;
 	else
 		return 0;
diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c
index b4512e3..9642d7c 100644
--- a/drivers/mtd/cfi_flash.c
+++ b/drivers/mtd/cfi_flash.c
@@ -218,7 +218,7 @@
 {
 	unsigned int byte_offset = offset * info->portwidth;
 
-	return (void *)(info->start[sect] + byte_offset);
+	return (void *)(info->start[sect] + (byte_offset << info->chip_lsb));
 }
 
 static inline void flash_unmap(flash_info_t *info, flash_sect_t sect,
@@ -1918,12 +1918,27 @@
 			flash_read_cfi(info, qry, FLASH_OFFSET_CFI_RESP,
 				       sizeof(struct cfi_qry));
 			info->interface	= le16_to_cpu(qry->interface_desc);
+			/* Some flash chips can support multiple bus widths.
+			 * In this case, override the interface width and
+			 * limit it to the port width.
+			 */
+			if ((info->interface == FLASH_CFI_X8X16) &&
+					(info->portwidth == FLASH_CFI_8BIT)) {
+				debug("Overriding 16-bit interface width to"
+						" 8-bit port width\n");
+				info->interface = FLASH_CFI_X8;
+			} else if ((info->interface == FLASH_CFI_X16X32) &&
+					(info->portwidth == FLASH_CFI_16BIT)) {
+				debug("Overriding 16-bit interface width to"
+						" 16-bit port width\n");
+				info->interface = FLASH_CFI_X16;
+			}
 
 			info->cfi_offset = flash_offset_cfi[cfi_offset];
 			debug("device interface is %d\n",
 			      info->interface);
-			debug("found port %d chip %d ",
-			      info->portwidth, info->chipwidth);
+			debug("found port %d chip %d chip_lsb %d ",
+			      info->portwidth, info->chipwidth, info->chip_lsb);
 			debug("port %d bits chip %d bits\n",
 			      info->portwidth << CFI_FLASH_SHIFT_WIDTH,
 			      info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
@@ -1962,9 +1977,23 @@
 	     info->portwidth <= FLASH_CFI_64BIT; info->portwidth <<= 1) {
 		for (info->chipwidth = FLASH_CFI_BY8;
 		     info->chipwidth <= info->portwidth;
-		     info->chipwidth <<= 1)
+		     info->chipwidth <<= 1) {
+			/*
+			 * First, try detection without shifting the addresses
+			 * for 8bit devices (16bit wide connection)
+			 */
+			info->chip_lsb = 0;
+			if (__flash_detect_cfi(info, qry))
+				return 1;
+
+			/*
+			 * Not detected, so let's try with shifting
+			 * for 8bit devices
+			 */
+			info->chip_lsb = 1;
 			if (__flash_detect_cfi(info, qry))
 				return 1;
+		}
 	}
 	debug("not found\n");
 	return 0;
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 0e84c22..cf062fa 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -271,6 +271,14 @@
 	  100Mbit and 1 Gbit operation. You must enable CONFIG_PHYLIB to
 	  provide the PHY (physical media interface).
 
+config ETH_DESIGNWARE_MESON8B
+	bool "Amlogic Meson8b and later glue driver for Synopsys Designware Ethernet MAC"
+	depends on DM_ETH
+	select ETH_DESIGNWARE
+	help
+	  This provides glue layer to use Synopsys Designware Ethernet MAC
+	  present on the Amlogic Meson8b, GX, AXG & G12A SoCs.
+
 config ETH_DESIGNWARE_SOCFPGA
 	select REGMAP
 	select SYSCON
@@ -790,4 +798,18 @@
 	  This driver supports the MDIO bus found on the Fman 10G Ethernet MACs and
 	  on the mEMAC (which supports both Clauses 22 and 45).
 
+config MDIO_MUX_MMIOREG
+	bool "MDIO MUX accessed as a MMIO register access"
+	depends on DM_MDIO_MUX
+	help
+	  This driver is used for MDIO muxes driven by writing to a register in
+	  the MMIO physical memory.
+
+config MDIO_MUX_MESON_G12A
+	bool "MDIO MUX for Amlogic Meson G12A SoCs"
+	depends on DM_MDIO_MUX
+	help
+	  This driver is used for the MDIO mux found on the Amlogic G12A & compatible
+	  SoCs.
+
 endif # NETDEVICES
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index a19511a..ce7b9e3 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -18,6 +18,7 @@
 obj-$(CONFIG_CS8900) += cs8900.o
 obj-$(CONFIG_TULIP) += dc2114x.o
 obj-$(CONFIG_ETH_DESIGNWARE) += designware.o
+obj-$(CONFIG_ETH_DESIGNWARE_MESON8B) += dwmac_meson8b.o
 obj-$(CONFIG_ETH_DESIGNWARE_SOCFPGA) += dwmac_socfpga.o
 obj-$(CONFIG_ETH_DESIGNWARE_S700) += dwmac_s700.o
 obj-$(CONFIG_DRIVER_DM9000) += dm9000x.o
@@ -43,6 +44,8 @@
 obj-$(CONFIG_MCFFEC) += mcffec.o mcfmii.o
 obj-$(CONFIG_MDIO_IPQ4019) += mdio-ipq4019.o
 obj-$(CONFIG_MDIO_MUX_I2CREG) += mdio_mux_i2creg.o
+obj-$(CONFIG_MDIO_MUX_MESON_G12A) += mdio_mux_meson_g12a.o
+obj-$(CONFIG_MDIO_MUX_MMIOREG) += mdio_mux_mmioreg.o
 obj-$(CONFIG_MDIO_MUX_SANDBOX) += mdio_mux_sandbox.o
 obj-$(CONFIG_MPC8XX_FEC) += mpc8xx_fec.o
 obj-$(CONFIG_MT7620_ETH) += mt7620-eth.o
diff --git a/drivers/net/designware.c b/drivers/net/designware.c
index 9dba55a..b8ba00b 100644
--- a/drivers/net/designware.c
+++ b/drivers/net/designware.c
@@ -21,7 +21,9 @@
 #include <reset.h>
 #include <asm/cache.h>
 #include <dm/device_compat.h>
+#include <dm/device-internal.h>
 #include <dm/devres.h>
+#include <dm/lists.h>
 #include <linux/compiler.h>
 #include <linux/delay.h>
 #include <linux/err.h>
@@ -122,6 +124,55 @@
 }
 #endif
 
+#if IS_ENABLED(CONFIG_DM_MDIO)
+int designware_eth_mdio_read(struct udevice *mdio_dev, int addr, int devad, int reg)
+{
+	struct mdio_perdev_priv *pdata = dev_get_uclass_priv(mdio_dev);
+
+	return dw_mdio_read(pdata->mii_bus, addr, devad, reg);
+}
+
+int designware_eth_mdio_write(struct udevice *mdio_dev, int addr, int devad, int reg, u16 val)
+{
+	struct mdio_perdev_priv *pdata = dev_get_uclass_priv(mdio_dev);
+
+	return dw_mdio_write(pdata->mii_bus, addr, devad, reg, val);
+}
+
+#if CONFIG_IS_ENABLED(DM_GPIO)
+int designware_eth_mdio_reset(struct udevice *mdio_dev)
+{
+	struct mdio_perdev_priv *pdata = dev_get_uclass_priv(mdio_dev);
+
+	return dw_mdio_reset(pdata->mii_bus);
+}
+#endif
+
+static const struct mdio_ops designware_eth_mdio_ops = {
+	.read = designware_eth_mdio_read,
+	.write = designware_eth_mdio_write,
+#if CONFIG_IS_ENABLED(DM_GPIO)
+	.reset = designware_eth_mdio_reset,
+#endif
+};
+
+static int designware_eth_mdio_probe(struct udevice *dev)
+{
+	/* Use the priv data of parent */
+	dev_set_priv(dev, dev_get_priv(dev->parent));
+
+	return 0;
+}
+
+U_BOOT_DRIVER(designware_eth_mdio) = {
+	.name = "eth_designware_mdio",
+	.id = UCLASS_MDIO,
+	.probe = designware_eth_mdio_probe,
+	.ops = &designware_eth_mdio_ops,
+	.plat_auto = sizeof(struct mdio_perdev_priv),
+};
+#endif
+
 static int dw_mdio_init(const char *name, void *priv)
 {
 	struct mii_dev *bus = mdio_alloc();
@@ -142,6 +193,34 @@
 
 	return mdio_register(bus);
 }
+
+#if IS_ENABLED(CONFIG_DM_MDIO)
+static int dw_dm_mdio_init(const char *name, void *priv)
+{
+	struct udevice *dev = priv;
+	ofnode node;
+	int ret;
+
+	ofnode_for_each_subnode(node, dev_ofnode(dev)) {
+		const char *subnode_name = ofnode_get_name(node);
+		struct udevice *mdiodev;
+
+		if (strcmp(subnode_name, "mdio"))
+			continue;
+
+		ret = device_bind_driver_to_node(dev, "eth_designware_mdio",
+						 subnode_name, node, &mdiodev);
+		if (ret)
+			debug("%s: not able to bind mdio device node\n", __func__);
+
+		return 0;
+	}
+
+	printf("%s: mdio node is missing, registering legacy mdio bus", __func__);
+
+	return dw_mdio_init(name, priv);
+}
+#endif
 
 static void tx_descs_init(struct dw_eth_dev *priv)
 {
@@ -487,7 +566,14 @@
 static int dw_phy_init(struct dw_eth_dev *priv, void *dev)
 {
 	struct phy_device *phydev;
-	int phy_addr = -1, ret;
+	int ret;
+
+#if IS_ENABLED(CONFIG_DM_MDIO) && IS_ENABLED(CONFIG_DM_ETH)
+	phydev = dm_eth_phy_connect(dev);
+	if (!phydev)
+		return -ENODEV;
+#else
+	int phy_addr = -1;
 
 #ifdef CONFIG_PHY_ADDR
 	phy_addr = CONFIG_PHY_ADDR;
@@ -496,6 +582,7 @@
 	phydev = phy_connect(priv->bus, phy_addr, dev, priv->interface);
 	if (!phydev)
 		return -ENODEV;
+#endif
 
 	phydev->supported &= PHY_GBIT_FEATURES;
 	if (priv->max_speed) {
@@ -759,7 +846,11 @@
 	priv->interface = pdata->phy_interface;
 	priv->max_speed = pdata->max_speed;
 
+#if IS_ENABLED(CONFIG_DM_MDIO)
+	ret = dw_dm_mdio_init(dev->name, dev);
+#else
 	ret = dw_mdio_init(dev->name, dev);
+#endif
 	if (ret) {
 		err = ret;
 		goto mdio_err;
@@ -856,9 +947,6 @@
 static const struct udevice_id designware_eth_ids[] = {
 	{ .compatible = "allwinner,sun7i-a20-gmac" },
 	{ .compatible = "amlogic,meson6-dwmac" },
-	{ .compatible = "amlogic,meson-gx-dwmac" },
-	{ .compatible = "amlogic,meson-gxbb-dwmac" },
-	{ .compatible = "amlogic,meson-axg-dwmac" },
 	{ .compatible = "st,stm32-dwmac" },
 	{ .compatible = "snps,arc-dwmac-3.70a" },
 	{ }
diff --git a/drivers/net/dwmac_meson8b.c b/drivers/net/dwmac_meson8b.c
new file mode 100644
index 0000000..c0b6ef4
--- /dev/null
+++ b/drivers/net/dwmac_meson8b.c
@@ -0,0 +1,150 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021 BayLibre, SAS
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <dm.h>
+#include <phy.h>
+#include "designware.h"
+#include <dm/device_compat.h>
+#include <linux/err.h>
+
+#define ETH_REG_0		0x0
+#define ETH_REG_1		0x4
+#define ETH_REG_2		0x18
+#define ETH_REG_3		0x1c
+
+#define GX_ETH_REG_0_PHY_INTF		BIT(0)
+#define GX_ETH_REG_0_TX_PHASE(x)	(((x) & 3) << 5)
+#define GX_ETH_REG_0_TX_RATIO(x)	(((x) & 7) << 7)
+#define GX_ETH_REG_0_PHY_CLK_EN	BIT(10)
+#define GX_ETH_REG_0_INVERT_RMII_CLK	BIT(11)
+#define GX_ETH_REG_0_CLK_EN		BIT(12)
+
+#define AXG_ETH_REG_0_PHY_INTF_RGMII	BIT(0)
+#define AXG_ETH_REG_0_PHY_INTF_RMII	BIT(2)
+#define AXG_ETH_REG_0_TX_PHASE(x)	(((x) & 3) << 5)
+#define AXG_ETH_REG_0_TX_RATIO(x)	(((x) & 7) << 7)
+#define AXG_ETH_REG_0_PHY_CLK_EN	BIT(10)
+#define AXG_ETH_REG_0_INVERT_RMII_CLK	BIT(11)
+#define AXG_ETH_REG_0_CLK_EN		BIT(12)
+
+struct dwmac_meson8b_plat {
+	struct dw_eth_pdata dw_eth_pdata;
+	int (*dwmac_setup)(struct udevice *dev, struct eth_pdata *edata);
+	void *regs;
+};
+
+static int dwmac_meson8b_of_to_plat(struct udevice *dev)
+{
+	struct dwmac_meson8b_plat *pdata = dev_get_plat(dev);
+
+	pdata->regs = (void *)dev_read_addr_index(dev, 1);
+	if ((fdt_addr_t)pdata->regs == FDT_ADDR_T_NONE)
+		return -EINVAL;
+
+	pdata->dwmac_setup = (void *)dev_get_driver_data(dev);
+	if (!pdata->dwmac_setup)
+		return -EINVAL;
+
+	return designware_eth_of_to_plat(dev);
+}
+
+static int dwmac_setup_axg(struct udevice *dev, struct eth_pdata *edata)
+{
+	struct dwmac_meson8b_plat *plat = dev_get_plat(dev);
+
+	switch (edata->phy_interface) {
+	case PHY_INTERFACE_MODE_RGMII:
+	case PHY_INTERFACE_MODE_RGMII_ID:
+	case PHY_INTERFACE_MODE_RGMII_RXID:
+	case PHY_INTERFACE_MODE_RGMII_TXID:
+		/* Set RGMII mode */
+		setbits_le32(plat->regs + ETH_REG_0, AXG_ETH_REG_0_PHY_INTF_RGMII |
+						     AXG_ETH_REG_0_TX_PHASE(1) |
+						     AXG_ETH_REG_0_TX_RATIO(4) |
+						     AXG_ETH_REG_0_PHY_CLK_EN |
+						     AXG_ETH_REG_0_CLK_EN);
+		break;
+
+	case PHY_INTERFACE_MODE_RMII:
+		/* Set RMII mode */
+		out_le32(plat->regs + ETH_REG_0, AXG_ETH_REG_0_PHY_INTF_RMII |
+						 AXG_ETH_REG_0_INVERT_RMII_CLK |
+						 AXG_ETH_REG_0_CLK_EN);
+		break;
+	default:
+		dev_err(dev, "Unsupported PHY mode\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int dwmac_setup_gx(struct udevice *dev, struct eth_pdata *edata)
+{
+	struct dwmac_meson8b_plat *plat = dev_get_plat(dev);
+
+	switch (edata->phy_interface) {
+	case PHY_INTERFACE_MODE_RGMII:
+	case PHY_INTERFACE_MODE_RGMII_ID:
+	case PHY_INTERFACE_MODE_RGMII_RXID:
+	case PHY_INTERFACE_MODE_RGMII_TXID:
+		/* Set RGMII mode */
+		setbits_le32(plat->regs + ETH_REG_0, GX_ETH_REG_0_PHY_INTF |
+						     GX_ETH_REG_0_TX_PHASE(1) |
+						     GX_ETH_REG_0_TX_RATIO(4) |
+						     GX_ETH_REG_0_PHY_CLK_EN |
+						     GX_ETH_REG_0_CLK_EN);
+
+		break;
+
+	case PHY_INTERFACE_MODE_RMII:
+		/* Set RMII mode */
+		out_le32(plat->regs + ETH_REG_0, GX_ETH_REG_0_INVERT_RMII_CLK |
+						 GX_ETH_REG_0_CLK_EN);
+
+		if (!IS_ENABLED(CONFIG_MESON_GXBB))
+			writel(0x10110181, plat->regs + ETH_REG_2);
+
+		break;
+	default:
+		dev_err(dev, "Unsupported PHY mode\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int dwmac_meson8b_probe(struct udevice *dev)
+{
+	struct dwmac_meson8b_plat *pdata = dev_get_plat(dev);
+	struct eth_pdata *edata = &pdata->dw_eth_pdata.eth_pdata;
+	int ret;
+
+	ret = pdata->dwmac_setup(dev, edata);
+	if (ret)
+		return ret;
+
+	return designware_eth_probe(dev);
+}
+
+static const struct udevice_id dwmac_meson8b_ids[] = {
+	{ .compatible = "amlogic,meson-gxbb-dwmac", .data = (ulong)dwmac_setup_gx },
+	{ .compatible = "amlogic,meson-axg-dwmac", .data = (ulong)dwmac_setup_axg },
+	{ }
+};
+
+U_BOOT_DRIVER(dwmac_meson8b) = {
+	.name		= "dwmac_meson8b",
+	.id		= UCLASS_ETH,
+	.of_match	= dwmac_meson8b_ids,
+	.of_to_plat = dwmac_meson8b_of_to_plat,
+	.probe		= dwmac_meson8b_probe,
+	.ops		= &designware_eth_ops,
+	.priv_auto	= sizeof(struct dw_eth_dev),
+	.plat_auto	= sizeof(struct dwmac_meson8b_plat),
+	.flags		= DM_FLAG_ALLOC_PRIV_DMA,
+};
diff --git a/drivers/net/mdio_mux_meson_g12a.c b/drivers/net/mdio_mux_meson_g12a.c
new file mode 100644
index 0000000..b520bf9
--- /dev/null
+++ b/drivers/net/mdio_mux_meson_g12a.c
@@ -0,0 +1,149 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * (C) Copyright 2021 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ */
+
+#include <dm.h>
+#include <errno.h>
+#include <log.h>
+#include <miiphy.h>
+#include <asm/io.h>
+#include <linux/bitfield.h>
+
+#define ETH_PLL_STS		0x40
+#define ETH_PLL_CTL0		0x44
+#define  PLL_CTL0_LOCK_DIG	BIT(30)
+#define  PLL_CTL0_RST		BIT(29)
+#define  PLL_CTL0_EN		BIT(28)
+#define  PLL_CTL0_SEL		BIT(23)
+#define  PLL_CTL0_N		GENMASK(14, 10)
+#define  PLL_CTL0_M		GENMASK(8, 0)
+#define  PLL_LOCK_TIMEOUT	1000000
+#define  PLL_MUX_NUM_PARENT	2
+#define ETH_PLL_CTL1		0x48
+#define ETH_PLL_CTL2		0x4c
+#define ETH_PLL_CTL3		0x50
+#define ETH_PLL_CTL4		0x54
+#define ETH_PLL_CTL5		0x58
+#define ETH_PLL_CTL6		0x5c
+#define ETH_PLL_CTL7		0x60
+
+#define ETH_PHY_CNTL0		0x80
+#define   EPHY_G12A_ID		0x33010180
+#define ETH_PHY_CNTL1		0x84
+#define  PHY_CNTL1_ST_MODE	GENMASK(2, 0)
+#define  PHY_CNTL1_ST_PHYADD	GENMASK(7, 3)
+#define   EPHY_DFLT_ADD		8
+#define  PHY_CNTL1_MII_MODE	GENMASK(15, 14)
+#define   EPHY_MODE_RMII	0x1
+#define  PHY_CNTL1_CLK_EN	BIT(16)
+#define  PHY_CNTL1_CLKFREQ	BIT(17)
+#define  PHY_CNTL1_PHY_ENB	BIT(18)
+#define ETH_PHY_CNTL2		0x88
+#define  PHY_CNTL2_USE_INTERNAL	BIT(5)
+#define  PHY_CNTL2_SMI_SRC_MAC	BIT(6)
+#define  PHY_CNTL2_RX_CLK_EPHY	BIT(9)
+
+#define MESON_G12A_MDIO_EXTERNAL_ID 0
+#define MESON_G12A_MDIO_INTERNAL_ID 1
+
+struct mdio_mux_meson_g12a_priv {
+	struct udevice *chip;
+	phys_addr_t phys;
+};
+
+static int meson_g12a_ephy_pll_init(struct mdio_mux_meson_g12a_priv *priv)
+{
+	/* Fire up the PHY PLL */
+	writel(0x29c0040a, priv->phys + ETH_PLL_CTL0);
+	writel(0x927e0000, priv->phys + ETH_PLL_CTL1);
+	writel(0xac5f49e5, priv->phys + ETH_PLL_CTL2);
+	writel(0x00000000, priv->phys + ETH_PLL_CTL3);
+	writel(0x00000000, priv->phys + ETH_PLL_CTL4);
+	writel(0x20200000, priv->phys + ETH_PLL_CTL5);
+	writel(0x0000c002, priv->phys + ETH_PLL_CTL6);
+	writel(0x00000023, priv->phys + ETH_PLL_CTL7);
+	writel(0x39c0040a, priv->phys + ETH_PLL_CTL0);
+	writel(0x19c0040a, priv->phys + ETH_PLL_CTL0);
+
+	return 0;
+}
+
+static int meson_g12a_enable_internal_mdio(struct mdio_mux_meson_g12a_priv *priv)
+{
+	/* Initialize ephy control */
+	writel(EPHY_G12A_ID, priv->phys + ETH_PHY_CNTL0);
+	writel(FIELD_PREP(PHY_CNTL1_ST_MODE, 3) |
+	       FIELD_PREP(PHY_CNTL1_ST_PHYADD, EPHY_DFLT_ADD) |
+	       FIELD_PREP(PHY_CNTL1_MII_MODE, EPHY_MODE_RMII) |
+	       PHY_CNTL1_CLK_EN |
+	       PHY_CNTL1_CLKFREQ |
+	       PHY_CNTL1_PHY_ENB,
+	       priv->phys + ETH_PHY_CNTL1);
+	writel(PHY_CNTL2_USE_INTERNAL |
+	       PHY_CNTL2_SMI_SRC_MAC |
+	       PHY_CNTL2_RX_CLK_EPHY,
+	       priv->phys + ETH_PHY_CNTL2);
+
+	return 0;
+}
+
+static int meson_g12a_enable_external_mdio(struct mdio_mux_meson_g12a_priv *priv)
+{
+	/* Reset the mdio bus mux */
+	writel(0x0, priv->phys + ETH_PHY_CNTL2);
+
+	return 0;
+}
+
+static int mdio_mux_meson_g12a_select(struct udevice *mux, int cur, int sel)
+{
+	struct mdio_mux_meson_g12a_priv *priv = dev_get_priv(mux);
+
+	debug("%s: %x -> %x\n", __func__, (u32)cur, (u32)sel);
+
+	/* if last selection didn't change we're good to go */
+	if (cur == sel)
+		return 0;
+
+	switch (sel) {
+	case MESON_G12A_MDIO_EXTERNAL_ID:
+		return meson_g12a_enable_external_mdio(priv);
+	case MESON_G12A_MDIO_INTERNAL_ID:
+		return meson_g12a_enable_internal_mdio(priv);
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static const struct mdio_mux_ops mdio_mux_meson_g12a_ops = {
+	.select = mdio_mux_meson_g12a_select,
+};
+
+static int mdio_mux_meson_g12a_probe(struct udevice *dev)
+{
+	struct mdio_mux_meson_g12a_priv *priv = dev_get_priv(dev);
+
+	priv->phys = dev_read_addr(dev);
+
+	meson_g12a_ephy_pll_init(priv);
+
+	return 0;
+}
+
+static const struct udevice_id mdio_mux_meson_g12a_ids[] = {
+	{ .compatible = "amlogic,g12a-mdio-mux" },
+	{ }
+};
+
+U_BOOT_DRIVER(mdio_mux_meson_g12a) = {
+	.name		= "mdio_mux_meson_g12a",
+	.id		= UCLASS_MDIO_MUX,
+	.of_match	= mdio_mux_meson_g12a_ids,
+	.probe		= mdio_mux_meson_g12a_probe,
+	.ops		= &mdio_mux_meson_g12a_ops,
+	.priv_auto	= sizeof(struct mdio_mux_meson_g12a_priv),
+};
diff --git a/drivers/net/mdio_mux_mmioreg.c b/drivers/net/mdio_mux_mmioreg.c
new file mode 100644
index 0000000..e1a23e4
--- /dev/null
+++ b/drivers/net/mdio_mux_mmioreg.c
@@ -0,0 +1,129 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * (C) Copyright 2021 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ *
+ * Based on linux/drivers/net/phy/mdio-mux-mmioreg.c :
+ *   Copyright 2012 Freescale Semiconductor, Inc.
+ */
+
+#include <dm.h>
+#include <errno.h>
+#include <log.h>
+#include <miiphy.h>
+#include <linux/io.h>
+
+struct mdio_mux_mmioreg_priv {
+	struct udevice *chip;
+	phys_addr_t phys;
+	unsigned int iosize;
+	unsigned int mask;
+};
+
+static int mdio_mux_mmioreg_select(struct udevice *mux, int cur, int sel)
+{
+	struct mdio_mux_mmioreg_priv *priv = dev_get_priv(mux);
+
+	debug("%s: %x -> %x\n", __func__, (u32)cur, (u32)sel);
+
+	/* if last selection didn't change we're good to go */
+	if (cur == sel)
+		return 0;
+
+	switch (priv->iosize) {
+	case sizeof(u8): {
+		u8 x, y;
+
+		x = ioread8((void *)priv->phys);
+		y = (x & ~priv->mask) | (u32)sel;
+		if (x != y) {
+			iowrite8((x & ~priv->mask) | sel, (void *)priv->phys);
+			debug("%s: %02x -> %02x\n", __func__, x, y);
+		}
+
+		break;
+	}
+	case sizeof(u16): {
+		u16 x, y;
+
+		x = ioread16((void *)priv->phys);
+		y = (x & ~priv->mask) | (u32)sel;
+		if (x != y) {
+			iowrite16((x & ~priv->mask) | sel, (void *)priv->phys);
+			debug("%s: %04x -> %04x\n", __func__, x, y);
+		}
+
+		break;
+	}
+	case sizeof(u32): {
+		u32 x, y;
+
+		x = ioread32((void *)priv->phys);
+		y = (x & ~priv->mask) | (u32)sel;
+		if (x != y) {
+			iowrite32((x & ~priv->mask) | sel, (void *)priv->phys);
+			debug("%s: %08x -> %08x\n", __func__, x, y);
+		}
+
+		break;
+	}
+	}
+
+	return 0;
+}
+
+static const struct mdio_mux_ops mdio_mux_mmioreg_ops = {
+	.select = mdio_mux_mmioreg_select,
+};
+
+static int mdio_mux_mmioreg_probe(struct udevice *dev)
+{
+	struct mdio_mux_mmioreg_priv *priv = dev_get_priv(dev);
+	phys_addr_t reg_base, reg_size;
+	u32 reg_mask;
+	int err;
+
+	reg_base = ofnode_get_addr_size_index(dev_ofnode(dev), 0, &reg_size);
+	if (reg_base == FDT_ADDR_T_NONE)
+		return -EINVAL;
+
+	if (reg_size != sizeof(u8) &&
+	    reg_size != sizeof(u16) &&
+	    reg_size != sizeof(u32)) {
+		printf("%s: only 8/16/32-bit registers are supported\n", __func__);
+		return -EINVAL;
+	}
+
+	err = dev_read_u32(dev, "mux-mask", &reg_mask);
+	if (err) {
+		debug("%s: error reading mux-mask property\n", __func__);
+		return err;
+	}
+
+	if (reg_mask >= BIT(reg_size * 8)) {
+		printf("%s: mask doesn't fix in register width\n", __func__);
+		return -EINVAL;
+	}
+
+	priv->phys = reg_base;
+	priv->iosize = reg_size;
+	priv->mask = reg_mask;
+
+	debug("%s: %llx@%lld / %x\n", __func__, reg_base, reg_size, reg_mask);
+
+	return 0;
+}
+
+static const struct udevice_id mdio_mux_mmioreg_ids[] = {
+	{ .compatible = "mdio-mux-mmioreg" },
+	{ }
+};
+
+U_BOOT_DRIVER(mdio_mux_mmioreg) = {
+	.name		= "mdio_mux_mmioreg",
+	.id		= UCLASS_MDIO_MUX,
+	.of_match	= mdio_mux_mmioreg_ids,
+	.probe		= mdio_mux_mmioreg_probe,
+	.ops		= &mdio_mux_mmioreg_ops,
+	.priv_auto	= sizeof(struct mdio_mux_mmioreg_priv),
+};
diff --git a/drivers/pinctrl/pinctrl-uclass.c b/drivers/pinctrl/pinctrl-uclass.c
index b0f30aa..6e68e52 100644
--- a/drivers/pinctrl/pinctrl-uclass.c
+++ b/drivers/pinctrl/pinctrl-uclass.c
@@ -235,8 +235,9 @@
 		return ret;
 
 	ops = pinctrl_get_ops(pctldev);
-	if (!ops || !ops->gpio_request_enable)
-		return -ENOTSUPP;
+	assert(ops);
+	if (!ops->gpio_request_enable)
+		return -ENOSYS;
 
 	return ops->gpio_request_enable(pctldev, pin_selector);
 }
@@ -261,8 +262,9 @@
 		return ret;
 
 	ops = pinctrl_get_ops(pctldev);
-	if (!ops || !ops->gpio_disable_free)
-		return -ENOTSUPP;
+	assert(ops);
+	if (!ops->gpio_disable_free)
+		return -ENOSYS;
 
 	return ops->gpio_disable_free(pctldev, pin_selector);
 }
diff --git a/drivers/usb/gadget/udc/udc-uclass.c b/drivers/usb/gadget/udc/udc-uclass.c
index 3053ccf..dbc354e 100644
--- a/drivers/usb/gadget/udc/udc-uclass.c
+++ b/drivers/usb/gadget/udc/udc-uclass.c
@@ -45,7 +45,7 @@
 		dev_array[index] = NULL;
 	return ret;
 #else
-	return -ENOTSUPP;
+	return -ENOSYS;
 #endif
 }
 
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 83147d5..1c11c2e 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -434,9 +434,9 @@
 	BUG_ON((type != XHCI_CTX_TYPE_DEVICE) && (type != XHCI_CTX_TYPE_INPUT));
 	ctx->type = type;
 	ctx->size = (MAX_EP_CTX_NUM + 1) *
-			CTX_SIZE(readl(&ctrl->hccr->cr_hccparams));
+			CTX_SIZE(xhci_readl(&ctrl->hccr->cr_hccparams));
 	if (type == XHCI_CTX_TYPE_INPUT)
-		ctx->size += CTX_SIZE(readl(&ctrl->hccr->cr_hccparams));
+		ctx->size += CTX_SIZE(xhci_readl(&ctrl->hccr->cr_hccparams));
 
 	ctx->bytes = xhci_malloc(ctx->size);
 
@@ -636,7 +636,7 @@
 		return (struct xhci_slot_ctx *)ctx->bytes;
 
 	return (struct xhci_slot_ctx *)
-		(ctx->bytes + CTX_SIZE(readl(&ctrl->hccr->cr_hccparams)));
+		(ctx->bytes + CTX_SIZE(xhci_readl(&ctrl->hccr->cr_hccparams)));
 }
 
 /**
@@ -658,7 +658,7 @@
 
 	return (struct xhci_ep_ctx *)
 		(ctx->bytes +
-		(ep_index * CTX_SIZE(readl(&ctrl->hccr->cr_hccparams))));
+		(ep_index * CTX_SIZE(xhci_readl(&ctrl->hccr->cr_hccparams))));
 }
 
 /**
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 46c137f..35bd5cd 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -849,12 +849,9 @@
 		}
 	}
 
-	debug("req->requesttype = %d, req->request = %d,"
-		"le16_to_cpu(req->value) = %d,"
-		"le16_to_cpu(req->index) = %d,"
-		"le16_to_cpu(req->length) = %d\n",
-		req->requesttype, req->request, le16_to_cpu(req->value),
-		le16_to_cpu(req->index), le16_to_cpu(req->length));
+	debug("req->requesttype = %d, req->request = %d, req->value = %d, req->index = %d, req->length = %d\n",
+	      req->requesttype, req->request, le16_to_cpu(req->value),
+	      le16_to_cpu(req->index), le16_to_cpu(req->length));
 
 	trb_fields[0] = req->requesttype | req->request << 8 |
 				le16_to_cpu(req->value) << 16;
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 602ccbe..aa76a8f 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -9,6 +9,19 @@
 	  this option if you want to service enabled watchdog by U-Boot. Disable
 	  this option if you want U-Boot to start watchdog but never service it.
 
+config WATCHDOG_AUTOSTART
+	bool "Automatically start watchdog timer"
+	depends on WDT
+	default y
+	help
+	  Automatically start watchdog timer and start servicing it during
+	  init phase. Enabled by default. Disable this option if you want
+	  to compile U-Boot with CONFIG_WDT support but do not want to
+	  activate watchdog, like when CONFIG_WDT option is disabled. You
+	  would be able to start watchdog manually by 'wdt' command. Useful
+	  when you want to have support for 'wdt' command but do not want
+	  to have watchdog enabled by default.
+
 config WATCHDOG_TIMEOUT_MSECS
 	int "Watchdog timeout in msec"
 	default 128000 if ARCH_MX25 || ARCH_MX31 || ARCH_MX5 || ARCH_MX6
diff --git a/drivers/watchdog/wdt-uclass.c b/drivers/watchdog/wdt-uclass.c
index 28f7918..0603ffb 100644
--- a/drivers/watchdog/wdt-uclass.c
+++ b/drivers/watchdog/wdt-uclass.c
@@ -27,6 +27,7 @@
 int initr_watchdog(void)
 {
 	u32 timeout = WATCHDOG_TIMEOUT_SECS;
+	int ret;
 
 	/*
 	 * Init watchdog: This will call the probe function of the
@@ -50,8 +51,17 @@
 						    4 * reset_period) / 4;
 	}
 
-	wdt_start(gd->watchdog_dev, timeout * 1000, 0);
-	gd->flags |= GD_FLG_WDT_READY;
+	if (!CONFIG_IS_ENABLED(WATCHDOG_AUTOSTART)) {
+		printf("WDT:   Not starting\n");
+		return 0;
+	}
+
+	ret = wdt_start(gd->watchdog_dev, timeout * 1000, 0);
+	if (ret != 0) {
+		printf("WDT:   Failed to start\n");
+		return 0;
+	}
+
 	printf("WDT:   Started with%s servicing (%ds timeout)\n",
 	       IS_ENABLED(CONFIG_WATCHDOG) ? "" : "out", timeout);
 
@@ -61,21 +71,31 @@
 int wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags)
 {
 	const struct wdt_ops *ops = device_get_ops(dev);
+	int ret;
 
 	if (!ops->start)
 		return -ENOSYS;
 
-	return ops->start(dev, timeout_ms, flags);
+	ret = ops->start(dev, timeout_ms, flags);
+	if (ret == 0)
+		gd->flags |= GD_FLG_WDT_READY;
+
+	return ret;
 }
 
 int wdt_stop(struct udevice *dev)
 {
 	const struct wdt_ops *ops = device_get_ops(dev);
+	int ret;
 
 	if (!ops->stop)
 		return -ENOSYS;
 
-	return ops->stop(dev);
+	ret = ops->stop(dev);
+	if (ret == 0)
+		gd->flags &= ~GD_FLG_WDT_READY;
+
+	return ret;
 }
 
 int wdt_reset(struct udevice *dev)
diff --git a/include/configs/MPC8349ITX.h b/include/configs/MPC8349ITX.h
index f50cdd7..586c1e9 100644
--- a/include/configs/MPC8349ITX.h
+++ b/include/configs/MPC8349ITX.h
@@ -39,8 +39,6 @@
 #ifndef __CONFIG_H
 #define __CONFIG_H
 
-#define CONFIG_MISC_INIT_F
-
 /*
  * On-board devices
  */
diff --git a/include/configs/kmp204x.h b/include/configs/kmp204x.h
index 90e3702..af3b03b 100644
--- a/include/configs/kmp204x.h
+++ b/include/configs/kmp204x.h
@@ -177,8 +177,6 @@
 #define CONFIG_SYS_BR1_PRELIM  CONFIG_SYS_QRIO_BR_PRELIM /* QRIO Base Address */
 #define CONFIG_SYS_OR1_PRELIM  CONFIG_SYS_QRIO_OR_PRELIM /* QRIO Options */
 
-#define CONFIG_MISC_INIT_F
-
 #define CONFIG_HWCONFIG
 
 /* define to use L1 as initial stack */
diff --git a/include/configs/rk3368_common.h b/include/configs/rk3368_common.h
index f178a06..fbbb8cf 100644
--- a/include/configs/rk3368_common.h
+++ b/include/configs/rk3368_common.h
@@ -24,13 +24,15 @@
 #define CONFIG_IRAM_BASE		0xff8c0000
 
 #define CONFIG_SYS_INIT_SP_ADDR		0x00300000
-#define CONFIG_SYS_LOAD_ADDR		0x00280000
+#define CONFIG_SYS_LOAD_ADDR		0x00800800
 
 #define CONFIG_SPL_MAX_SIZE             0x40000
 #define CONFIG_SPL_BSS_START_ADDR       0x400000
 #define CONFIG_SPL_BSS_MAX_SIZE         0x20000
 #define CONFIG_SPL_STACK                0x00188000
 
+#define CONFIG_SYS_BOOTM_LEN	(64 << 20)	/* 64M */
+
 #ifndef CONFIG_SPL_BUILD
 #define ENV_MEM_LAYOUT_SETTINGS \
 	"scriptaddr=0x00500000\0" \
diff --git a/include/configs/rk3399_common.h b/include/configs/rk3399_common.h
index d0fc598..b37ed5c 100644
--- a/include/configs/rk3399_common.h
+++ b/include/configs/rk3399_common.h
@@ -75,6 +75,4 @@
 
 #endif
 
-/* enable usb config for usb ether */
-
 #endif
diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h
index e0708fe..bbb7d12 100644
--- a/include/configs/sandbox.h
+++ b/include/configs/sandbox.h
@@ -130,6 +130,4 @@
 
 #define CONFIG_SYS_SATA_MAX_DEVICE	2
 
-#define CONFIG_MISC_INIT_F
-
 #endif
diff --git a/include/dt-bindings/clock/rk3368-cru.h b/include/dt-bindings/clock/rk3368-cru.h
index 9c5dd9b..0a06c5f 100644
--- a/include/dt-bindings/clock/rk3368-cru.h
+++ b/include/dt-bindings/clock/rk3368-cru.h
@@ -1,15 +1,6 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
 /*
  * 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
@@ -44,13 +35,12 @@
 #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_TIMER00		85
+#define SCLK_TIMER01		86
+#define SCLK_TIMER02		87
+#define SCLK_TIMER03		88
+#define SCLK_TIMER04		89
+#define SCLK_TIMER05		90
 #define SCLK_OTGPHY0		93
 #define SCLK_OTG_ADP		96
 #define SCLK_HSICPHY480M	97
@@ -82,6 +72,12 @@
 #define SCLK_SFC		126
 #define SCLK_MAC		127
 #define SCLK_MACREF_OUT		128
+#define SCLK_TIMER10		133
+#define SCLK_TIMER11		134
+#define SCLK_TIMER12		135
+#define SCLK_TIMER13		136
+#define SCLK_TIMER14		137
+#define SCLK_TIMER15		138
 
 #define DCLK_VOP		190
 #define MCLK_CRYPTO		191
@@ -151,6 +147,7 @@
 #define PCLK_ISP		366
 #define PCLK_VIP		367
 #define PCLK_WDT		368
+#define PCLK_EFUSE256		369
 
 /* hclk gates */
 #define HCLK_SFC		448
diff --git a/include/flash.h b/include/flash.h
index 3bf6b22..42b18a6 100644
--- a/include/flash.h
+++ b/include/flash.h
@@ -24,6 +24,8 @@
 #ifdef CONFIG_SYS_FLASH_CFI
 	uchar	portwidth;		/* the width of the port		*/
 	uchar	chipwidth;		/* the width of the chip		*/
+	uchar	chip_lsb;		/* extra Least Significant Bit in the */
+					/* address of chip	*/
 	ushort	buffer_size;		/* # of bytes in write buffer		*/
 	ulong	erase_blk_tout;		/* maximum block erase timeout		*/
 	ulong	write_tout;		/* maximum write timeout		*/
diff --git a/include/log.h b/include/log.h
index 6ef891d..add3a1e 100644
--- a/include/log.h
+++ b/include/log.h
@@ -222,11 +222,14 @@
 #define _SPL_BUILD	0
 #endif
 
-#if !_DEBUG && CONFIG_IS_ENABLED(LOG)
+#if CONFIG_IS_ENABLED(LOG)
 
-#define debug_cond(cond, fmt, args...)			\
-({							\
-	log(LOG_CATEGORY, LOGL_DEBUG, fmt, ##args);	\
+#define debug_cond(cond, fmt, args...)					\
+({									\
+	if (cond)							\
+		log(LOG_CATEGORY,					\
+		    (enum log_level_t)(LOGL_FORCE_DEBUG | _LOG_DEBUG),	\
+		    fmt, ##args);					\
 })
 
 #else /* _DEBUG */
diff --git a/include/os.h b/include/os.h
index 77d8bd8..bd1096e 100644
--- a/include/os.h
+++ b/include/os.h
@@ -134,7 +134,9 @@
  * This follows the semantics of realloc(), so can perform an os_malloc() or
  * os_free() depending on @ptr and @length.
  *
- * Return:	Pointer to reallocated memory or NULL if @length is 0
+ * @ptr:	pointer to previously allocated memory of NULL
+ * @length:	number of bytes to allocate
+ * Return:	pointer to reallocated memory or NULL if @length is 0
  */
 void *os_realloc(void *ptr, size_t length);
 
diff --git a/include/spi-mem.h b/include/spi-mem.h
index 8be3e2b..e354c38 100644
--- a/include/spi-mem.h
+++ b/include/spi-mem.h
@@ -222,7 +222,7 @@
 				   const struct spi_mem_op *op,
 				   struct sg_table *sg)
 {
-	return -ENOTSUPP;
+	return -ENOSYS;
 }
 
 static inline void
diff --git a/include/test/test.h b/include/test/test.h
index 0b124ed..bf7d785 100644
--- a/include/test/test.h
+++ b/include/test/test.h
@@ -124,4 +124,13 @@
  */
 struct udevice *testbus_get_clear_removed(void);
 
+static inline void arch_reset_for_test(void)
+{
+#ifdef CONFIG_SANDBOX
+#include <asm/state.h>
+
+	state_reset_for_test(state_get_current());
+#endif
+}
+
 #endif /* __TEST_TEST_H */
diff --git a/include/tlv_eeprom.h b/include/tlv_eeprom.h
index 1de2fe2..a2c333e 100644
--- a/include/tlv_eeprom.h
+++ b/include/tlv_eeprom.h
@@ -114,19 +114,19 @@
 
 static inline int read_tlv_eeprom(void *eeprom, int offset, int len, int dev)
 {
-	return -ENOTSUPP;
+	return -ENOSYS;
 }
 
 static inline int write_tlv_eeprom(void *eeprom, int len)
 {
-	return -ENOTSUPP;
+	return -ENOSYS;
 }
 
 static inline int
 read_tlvinfo_tlv_eeprom(void *eeprom, struct tlvinfo_header **hdr,
 			struct tlvinfo_tlv **first_entry, int dev)
 {
-	return -ENOTSUPP;
+	return -ENOSYS;
 }
 
 #endif /* CONFIG_IS_ENABLED(CMD_TLV_EEPROM) */
diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt
index 85857a7..b693925 100644
--- a/scripts/config_whitelist.txt
+++ b/scripts/config_whitelist.txt
@@ -1030,7 +1030,6 @@
 CONFIG_MIPS_MT_FPAFF
 CONFIG_MIRQ_EN
 CONFIG_MISC_COMMON
-CONFIG_MISC_INIT_F
 CONFIG_MIU_1BIT_INTERLEAVED
 CONFIG_MIU_2BIT_21_7_INTERLEAVED
 CONFIG_MIU_2BIT_INTERLEAVED
diff --git a/scripts/dtc/pylibfdt/Makefile b/scripts/dtc/pylibfdt/Makefile
index 4782dd4..493995e 100644
--- a/scripts/dtc/pylibfdt/Makefile
+++ b/scripts/dtc/pylibfdt/Makefile
@@ -34,6 +34,7 @@
 	fi
 
 $(obj)/_libfdt.so $(obj)/libfdt.py &: rebuild
+	@:
 
 always += _libfdt.so libfdt.py
 
diff --git a/test/test-main.c b/test/test-main.c
index 46a0c2e..8c852d7 100644
--- a/test/test-main.c
+++ b/test/test-main.c
@@ -7,7 +7,6 @@
 #include <common.h>
 #include <console.h>
 #include <dm.h>
-#include <asm/state.h>
 #include <dm/root.h>
 #include <dm/test.h>
 #include <dm/uclass-internal.h>
@@ -46,9 +45,9 @@
 	uts->force_fail_alloc = false;
 	uts->skip_post_probe = false;
 	gd->dm_root = NULL;
-	if (!CONFIG_IS_ENABLED(OF_PLATDATA))
+	if (IS_ENABLED(CONFIG_UT_DM) && !CONFIG_IS_ENABLED(OF_PLATDATA))
 		memset(dm_testdrv_op_count, '\0', sizeof(dm_testdrv_op_count));
-	state_reset_for_test(state_get_current());
+	arch_reset_for_test();
 
 	/* Determine whether to make the live tree available */
 	gd_set_of_root(of_live ? uts->of_root : NULL);
diff --git a/tools/buildman/builderthread.py b/tools/buildman/builderthread.py
index 6c6dbd7..06ed272 100644
--- a/tools/buildman/builderthread.py
+++ b/tools/buildman/builderthread.py
@@ -344,7 +344,8 @@
 
             # Write out the image and function size information and an objdump
             env = result.toolchain.MakeEnvironment(self.builder.full_path)
-            with open(os.path.join(build_dir, 'out-env'), 'w') as fd:
+            with open(os.path.join(build_dir, 'out-env'), 'w',
+                      encoding='utf-8') as fd:
                 for var in sorted(env.keys()):
                     print('%s="%s"' % (var, env[var]), file=fd)
             lines = []
diff --git a/tools/dtoc/dtb_platdata.py b/tools/dtoc/dtb_platdata.py
index c9c657c..1374f01 100644
--- a/tools/dtoc/dtb_platdata.py
+++ b/tools/dtoc/dtb_platdata.py
@@ -440,6 +440,9 @@
                 Number of size cells for this node
         """
         parent = node.parent
+        if parent and not parent.props:
+            raise ValueError("Parent node '%s' has no properties - do you need u-boot,dm-spl or similar?" %
+                             parent.path)
         num_addr, num_size = 2, 2
         if parent:
             addr_prop = parent.props.get('#address-cells')
@@ -467,20 +470,21 @@
             if reg.type != fdt.Type.INT:
                 raise ValueError("Node '%s' reg property is not an int" %
                                  node.name)
+            if not isinstance(reg.value, list):
+                reg.value = [reg.value]
             if len(reg.value) % total:
                 raise ValueError(
-                    "Node '%s' reg property has %d cells "
+                    "Node '%s' (parent '%s') reg property has %d cells "
                     'which is not a multiple of na + ns = %d + %d)' %
-                    (node.name, len(reg.value), num_addr, num_size))
+                    (node.name, node.parent.name, len(reg.value), num_addr,
+                     num_size))
             reg.num_addr = num_addr
             reg.num_size = num_size
-            if num_addr != 1 or num_size != 1:
+            if num_addr > 1 or num_size > 1:
                 reg.type = fdt.Type.INT64
                 i = 0
                 new_value = []
                 val = reg.value
-                if not isinstance(val, list):
-                    val = [val]
                 while i < len(val):
                     addr = fdt_util.fdt_cells_to_cpu(val[i:], reg.num_addr)
                     i += num_addr
@@ -1194,8 +1198,7 @@
         raise ValueError('Must specify either output or output_dirs, not both')
 
     if not scan:
-        scan = src_scan.Scanner(basedir, warning_disabled, drivers_additional,
-                                phase)
+        scan = src_scan.Scanner(basedir, drivers_additional, phase)
         scan.scan_drivers()
         do_process = True
     else:
@@ -1232,4 +1235,7 @@
         plat.out_header(outfile)
         outfile.method(plat)
     plat.finish_output()
+
+    if not warning_disabled:
+        scan.show_warnings()
     return plat
diff --git a/tools/dtoc/src_scan.py b/tools/dtoc/src_scan.py
index 114212c..2db9688 100644
--- a/tools/dtoc/src_scan.py
+++ b/tools/dtoc/src_scan.py
@@ -188,7 +188,6 @@
             key: Driver alias declared with
                 DM_DRIVER_ALIAS(driver_alias, driver_name)
             value: Driver name declared with U_BOOT_DRIVER(driver_name)
-        _warning_disabled: true to disable warnings about driver names not found
         _drivers_additional (list or str): List of additional drivers to use
             during scanning
         _of_match: Dict holding information about compatible strings
@@ -206,7 +205,7 @@
         _phase: The phase of U-Boot that we are generating data for, e.g. 'spl'
              or 'tpl'. None if not known
     """
-    def __init__(self, basedir, warning_disabled, drivers_additional, phase=''):
+    def __init__(self, basedir, drivers_additional, phase=''):
         """Set up a new Scanner
         """
         if not basedir:
@@ -217,7 +216,7 @@
         self._drivers = {}
         self._driver_aliases = {}
         self._drivers_additional = drivers_additional or []
-        self._warning_disabled = warning_disabled
+        self._missing_drivers = set()
         self._of_match = {}
         self._compat_to_driver = {}
         self._uclass = {}
@@ -268,9 +267,7 @@
                 aliases_c.remove(compat_c)
             return compat_c, aliases_c
 
-        if not self._warning_disabled:
-            print('WARNING: the driver %s was not found in the driver list'
-                  % (compat_list_c[0]))
+        self._missing_drivers.add(compat_list_c[0])
 
         return compat_list_c[0], compat_list_c[1:]
 
@@ -578,6 +575,12 @@
             self._drivers[driver.name] = driver
         self._of_match.update(of_match)
 
+    def show_warnings(self):
+        """Show any warnings that have been collected"""
+        for name in sorted(list(self._missing_drivers)):
+            print('WARNING: the driver %s was not found in the driver list'
+                  % name)
+
     def scan_driver(self, fname):
         """Scan a driver file to build a list of driver names and aliases
 
diff --git a/tools/dtoc/test/dtoc_test_noprops.dts b/tools/dtoc/test/dtoc_test_noprops.dts
new file mode 100644
index 0000000..e6fdd11
--- /dev/null
+++ b/tools/dtoc/test/dtoc_test_noprops.dts
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Test device tree file for dtoc
+ *
+ * Copyright 2017 Google, Inc
+ */
+
+/dts-v1/;
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	i2c@0 {
+		pmic@9 {
+			compatible = "sandbox,pmic";
+			u-boot,dm-pre-reloc;
+			reg = <9>;
+			low-power;
+		};
+	};
+};
diff --git a/tools/dtoc/test/dtoc_test_single_reg.dts b/tools/dtoc/test/dtoc_test_single_reg.dts
new file mode 100644
index 0000000..804b678
--- /dev/null
+++ b/tools/dtoc/test/dtoc_test_single_reg.dts
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Test device tree file for dtoc
+ *
+ * Copyright 2017 Google, Inc
+ */
+
+/dts-v1/;
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	i2c@0 {
+		compatible = "sandbox,i2c";
+		u-boot,dm-pre-reloc;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		pmic@9 {
+			compatible = "sandbox,pmic";
+			u-boot,dm-pre-reloc;
+			reg = <9>;
+			low-power;
+
+			gpio {
+				compatible = "sandbox,gpio";
+			};
+		};
+	};
+};
diff --git a/tools/dtoc/test_dtoc.py b/tools/dtoc/test_dtoc.py
index e951283..a05e3d9 100755
--- a/tools/dtoc/test_dtoc.py
+++ b/tools/dtoc/test_dtoc.py
@@ -104,7 +104,7 @@
 
     # Disable warnings so that calls to get_normalized_compat_name() will not
     # output things.
-    saved_scan = src_scan.Scanner(None, True, False)
+    saved_scan = src_scan.Scanner(None, False)
     saved_scan.scan_drivers()
 
 def copy_scan():
@@ -293,7 +293,7 @@
 };
 struct dtd_sandbox_pmic {
 \tbool\t\tlow_power;
-\tfdt64_t\t\treg[2];
+\tfdt32_t\t\treg[1];
 };
 struct dtd_sandbox_spl_test {
 \tconst char *	acpi_name;
@@ -341,7 +341,7 @@
  */
 static struct dtd_sandbox_pmic dtv_pmic_at_9 = {
 \t.low_power\t\t= true,
-\t.reg\t\t\t= {0x9, 0x0},
+\t.reg\t\t\t= {0x9},
 };
 U_BOOT_DRVINFO(pmic_at_9) = {
 \t.name\t\t= "sandbox_pmic",
@@ -721,7 +721,7 @@
 \t.dtplat = {
 \t\t.ping_add\t\t= 0x5,
 \t\t.ping_expect\t\t= 0x5,
-\t\t.reg\t\t\t= {0x5, 0x0},
+\t\t.reg\t\t\t= {0x5},
 \t},
 };
 #include <dm/test.h>
@@ -1462,7 +1462,7 @@
         with self.assertRaises(ValueError) as exc:
             self.run_test(['struct'], dtb_file, output)
         self.assertIn(
-            "Node 'spl-test' reg property has 3 cells which is not a multiple of na + ns = 1 + 1)",
+            "Node 'spl-test' (parent '/') reg property has 3 cells which is not a multiple of na + ns = 1 + 1)",
             str(exc.exception))
 
     def test_add_prop(self):
@@ -1824,3 +1824,18 @@
         self.assertEqual(
             'Warning: Cannot find header file for struct dm_test_uc_priv',
             stdout.getvalue().strip())
+
+    def test_missing_props(self):
+        """Test detection of a parent node with no properties"""
+        dtb_file = get_dtb_file('dtoc_test_noprops.dts', capture_stderr=True)
+        output = tools.GetOutputFilename('output')
+        with self.assertRaises(ValueError) as exc:
+            self.run_test(['struct'], dtb_file, output)
+        self.assertIn("Parent node '/i2c@0' has no properties - do you need",
+                      str(exc.exception))
+
+    def test_single_reg(self):
+        """Test detection of a parent node with no properties"""
+        dtb_file = get_dtb_file('dtoc_test_single_reg.dts')
+        output = tools.GetOutputFilename('output')
+        self.run_test(['struct'], dtb_file, output)
diff --git a/tools/dtoc/test_src_scan.py b/tools/dtoc/test_src_scan.py
index 0af86dc..d6da038 100644
--- a/tools/dtoc/test_src_scan.py
+++ b/tools/dtoc/test_src_scan.py
@@ -48,7 +48,7 @@
 
     def test_simple(self):
         """Simple test of scanning drivers"""
-        scan = src_scan.Scanner(None, True, None)
+        scan = src_scan.Scanner(None, None)
         scan.scan_drivers()
         self.assertIn('sandbox_gpio', scan._drivers)
         self.assertIn('sandbox_gpio_alias', scan._driver_aliases)
@@ -59,8 +59,7 @@
     def test_additional(self):
         """Test with additional drivers to scan"""
         scan = src_scan.Scanner(
-            None, True,
-            [None, '', 'tools/dtoc/test/dtoc_test_scan_drivers.cxx'])
+            None, [None, '', 'tools/dtoc/test/dtoc_test_scan_drivers.cxx'])
         scan.scan_drivers()
         self.assertIn('sandbox_gpio_alias2', scan._driver_aliases)
         self.assertEqual('sandbox_gpio',
@@ -77,7 +76,7 @@
         with open(driver_fn, 'wb+') as fout:
             fout.write(b'\x81')
 
-        scan = src_scan.Scanner(None, True, [driver_fn])
+        scan = src_scan.Scanner(None, [driver_fn])
         with test_util.capture_sys_output() as (stdout, _):
             scan.scan_drivers()
         self.assertRegex(stdout.getvalue(),
@@ -126,7 +125,7 @@
             # Mock out scan_driver and check that it is called with the
             # expected files
             with mock.patch.object(src_scan.Scanner, "scan_driver")  as mocked:
-                scan = src_scan.Scanner(indir, True, None)
+                scan = src_scan.Scanner(indir, None)
                 scan.scan_drivers()
             self.assertEqual(2, len(mocked.mock_calls))
             self.assertEqual(mock.call(fname_list[0]),
@@ -141,7 +140,7 @@
         """Test scanning of a driver"""
         fname = os.path.join(OUR_PATH, '..', '..', 'drivers/i2c/tegra_i2c.c')
         buff = tools.ReadFile(fname, False)
-        scan = src_scan.Scanner(None, False, None)
+        scan = src_scan.Scanner(None, None)
         scan._parse_driver(fname, buff)
         self.assertIn('i2c_tegra', scan._drivers)
         drv = scan._drivers['i2c_tegra']
@@ -165,14 +164,15 @@
         # get_normalized_compat_name() uses this to check for root node
         node.parent = FakeNode()
 
-        scan = src_scan.Scanner(None, False, None)
+        scan = src_scan.Scanner(None, None)
         with test_util.capture_sys_output() as (stdout, _):
             name, aliases = scan.get_normalized_compat_name(node)
         self.assertEqual('rockchip_rk3288_grf', name)
         self.assertEqual([], aliases)
-        self.assertEqual(
-            'WARNING: the driver rockchip_rk3288_grf was not found in the driver list',
-            stdout.getvalue().strip())
+        self.assertEqual(1, len(scan._missing_drivers))
+        self.assertEqual({'rockchip_rk3288_grf'}, scan._missing_drivers)
+            #'WARNING: the driver rockchip_rk3288_grf was not found in the driver list',
+            #stdout.getvalue().strip())
 
         i2c = 'I2C_UCLASS'
         compat = {'rockchip,rk3288-grf': 'ROCKCHIP_SYSCON_GRF',
@@ -211,7 +211,7 @@
 	.of_match = tegra_i2c_ids,
 };
 '''
-        scan = src_scan.Scanner(None, False, None)
+        scan = src_scan.Scanner(None, None)
         with self.assertRaises(ValueError) as exc:
             scan._parse_driver('file.c', buff)
         self.assertIn(
@@ -232,7 +232,7 @@
 	.of_match = of_match_ptr(tegra_i2c_ids),
 };
 '''
-        scan = src_scan.Scanner(None, False, None)
+        scan = src_scan.Scanner(None, None)
         scan._parse_driver('file.c', buff)
         self.assertIn('i2c_tegra', scan._drivers)
         drv = scan._drivers['i2c_tegra']
@@ -261,7 +261,7 @@
 	DM_HEADER(<asm/clk.h>)
 };
 '''
-        scan = src_scan.Scanner(None, False, None)
+        scan = src_scan.Scanner(None, None)
         scan._parse_driver('file.c', buff)
         self.assertIn('testing', scan._drivers)
         drv = scan._drivers['testing']
@@ -293,7 +293,7 @@
 };
 
 '''
-        scan = src_scan.Scanner(None, False, None)
+        scan = src_scan.Scanner(None, None)
         scan._parse_uclass_driver('file.c', buff)
         self.assertIn('UCLASS_I2C', scan._uclass)
         drv = scan._uclass['UCLASS_I2C']
@@ -325,7 +325,7 @@
 };
 
 '''
-        scan = src_scan.Scanner(None, False, None)
+        scan = src_scan.Scanner(None, None)
         with self.assertRaises(ValueError) as exc:
             scan._parse_uclass_driver('file.c', buff)
         self.assertIn("file.c: Cannot parse uclass ID in driver 'i2c'",
@@ -340,7 +340,7 @@
 	uint nmsgs;
 };
 '''
-        scan = src_scan.Scanner(None, False, None)
+        scan = src_scan.Scanner(None, None)
         scan._basedir = os.path.join(OUR_PATH, '..', '..')
         scan._parse_structs('arch/arm/include/asm/file.h', buff)
         self.assertIn('some_struct1', scan._structs)
@@ -371,7 +371,7 @@
         output = tools.GetOutputFilename('output.h')
         tools.WriteFile(output, b'struct this is a test \x81 of bad unicode')
 
-        scan = src_scan.Scanner(None, False, None)
+        scan = src_scan.Scanner(None, None)
         with test_util.capture_sys_output() as (stdout, _):
             scan.scan_header(output)
         self.assertIn('due to unicode error', stdout.getvalue())
@@ -411,7 +411,7 @@
 	.of_match = test_ids,
 };
 ''' % name
-        scan = src_scan.Scanner(None, False, None, phase)
+        scan = src_scan.Scanner(None, None, phase)
         scan._parse_driver('file1.c', driver1)
         self.assertIn(name, scan._drivers)
         drv1 = scan._drivers[name]
@@ -476,7 +476,7 @@
 
     def test_sequence(self):
         """Test assignment of sequence numnbers"""
-        scan = src_scan.Scanner(None, False, None, '')
+        scan = src_scan.Scanner(None, None, '')
         node = FakeNode()
         uc = src_scan.UclassDriver('UCLASS_I2C')
         node.uclass = uc
diff --git a/tools/moveconfig.py b/tools/moveconfig.py
index 9514d9a..1ac30c0 100755
--- a/tools/moveconfig.py
+++ b/tools/moveconfig.py
@@ -12,6 +12,10 @@
 
 This tool intends to help this tremendous work.
 
+Installing
+----------
+
+You may need to install 'python3-asteval' for the 'asteval' module.
 
 Usage
 -----
@@ -573,7 +577,11 @@
     """
     pattern = re.compile(r'^\s*#\s*if.*$\n^\s*#\s*endif.*$\n*', flags=re.M)
     with open(header_path) as f:
-        data = f.read()
+        try:
+            data = f.read()
+        except UnicodeDecodeError as e:
+            print("Failed on file %s': %s" % (header_path, e))
+            return
 
     new_data = pattern.sub('\n', data)
 
@@ -596,7 +604,11 @@
       options: option flags.
     """
     with open(header_path) as f:
-        lines = f.readlines()
+        try:
+            lines = f.readlines()
+        except UnicodeDecodeError as e:
+            print("Failed on file %s': %s" % (header_path, e))
+            return
 
     matched = []
     for i, line in enumerate(lines):
diff --git a/tools/patman/patchstream.py b/tools/patman/patchstream.py
index cdcd50a..a44cd86 100644
--- a/tools/patman/patchstream.py
+++ b/tools/patman/patchstream.py
@@ -133,8 +133,8 @@
             ValueError: Warning is generated with no commit associated
         """
         if not self.commit:
-            raise ValueError('Warning outside commit: %s' % warn)
-        if warn not in self.commit.warn:
+            print('Warning outside commit: %s' % warn)
+        elif warn not in self.commit.warn:
             self.commit.warn.append(warn)
 
     def _add_to_series(self, line, name, value):