Merge branch 'master' of https://gitlab.denx.de/u-boot/custodians/u-boot-spi

- Enable DM_SPI on siemens omap boards (Jagan)
- Dropped some non-dm supported omap3 boards (Jagan)
- Dropped non-dm code in omap3 spi driver (Jagan)
- Dropped non-dm code in kirkwood spi driver (Bhargav)
diff --git a/.azure-pipelines.yml b/.azure-pipelines.yml
index 9f88a53..98e8a4f 100644
--- a/.azure-pipelines.yml
+++ b/.azure-pipelines.yml
@@ -316,7 +316,7 @@
           export PATH=/opt/qemu/bin:/tmp/uboot-test-hooks/bin:${PATH};
           export PYTHONPATH=/tmp/uboot-test-hooks/py/travis-ci;
           # "${var:+"-k $var"}" expands to "" if $var is empty, "-k $var" if not
-          ./test/py/test.py --bd ${TEST_PY_BD} ${TEST_PY_ID} ${TEST_PY_TEST_SPEC:+"-k ${TEST_PY_TEST_SPEC}"} --build-dir "$UBOOT_TRAVIS_BUILD_DIR";
+          ./test/py/test.py -ra --bd ${TEST_PY_BD} ${TEST_PY_ID} ${TEST_PY_TEST_SPEC:+"-k ${TEST_PY_TEST_SPEC}"} --build-dir "$UBOOT_TRAVIS_BUILD_DIR";
           # the below corresponds to .gitlab-ci.yml "after_script"
           rm -rf /tmp/uboot-test-hooks /tmp/venv
           EOF
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index a685a78..d074695 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -46,7 +46,7 @@
     # "${var:+"-k $var"}" expands to "" if $var is empty, "-k $var" if not
     - export PATH=/opt/qemu/bin:/tmp/uboot-test-hooks/bin:${PATH};
       export PYTHONPATH=/tmp/uboot-test-hooks/py/travis-ci;
-      ./test/py/test.py --bd ${TEST_PY_BD} ${TEST_PY_ID}
+      ./test/py/test.py -ra --bd ${TEST_PY_BD} ${TEST_PY_ID}
         ${TEST_PY_TEST_SPEC:+"-k ${TEST_PY_TEST_SPEC}"}
         --build-dir "$UBOOT_TRAVIS_BUILD_DIR"
 
diff --git a/.travis.yml b/.travis.yml
index a042aa2..1ff1408 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -250,7 +250,7 @@
      virtualenv -p /usr/bin/python3 /tmp/venv;
      . /tmp/venv/bin/activate;
      pip install -r test/py/requirements.txt;
-     ./test/py/test.py --bd ${TEST_PY_BD} ${TEST_PY_ID}
+     ./test/py/test.py -ra --bd ${TEST_PY_BD} ${TEST_PY_ID}
        ${TEST_PY_TEST_SPEC:+"-k ${TEST_PY_TEST_SPEC}"}
        --build-dir "$UBOOT_TRAVIS_BUILD_DIR" || exit;
      if [[ -n "${TEST_PY_TOOLS}" ]]; then
diff --git a/arch/arm/dts/da850-evm-u-boot.dtsi b/arch/arm/dts/da850-evm-u-boot.dtsi
index d9afc5e..d588628 100644
--- a/arch/arm/dts/da850-evm-u-boot.dtsi
+++ b/arch/arm/dts/da850-evm-u-boot.dtsi
@@ -39,3 +39,7 @@
 &spi1 {
 	u-boot,dm-spl;
 };
+
+&gpio {
+	u-boot,dm-spl;
+};
diff --git a/arch/arm/dts/da850-lcdk-u-boot.dtsi b/arch/arm/dts/da850-lcdk-u-boot.dtsi
index b372d06..d50775c 100644
--- a/arch/arm/dts/da850-lcdk-u-boot.dtsi
+++ b/arch/arm/dts/da850-lcdk-u-boot.dtsi
@@ -28,3 +28,7 @@
 &serial2 {
 	u-boot,dm-spl;
 };
+
+&gpio {
+	u-boot,dm-spl;
+};
diff --git a/arch/arm/dts/rk3288-u-boot.dtsi b/arch/arm/dts/rk3288-u-boot.dtsi
index 6d31735..51b6e01 100644
--- a/arch/arm/dts/rk3288-u-boot.dtsi
+++ b/arch/arm/dts/rk3288-u-boot.dtsi
@@ -43,3 +43,7 @@
 &noc {
 	u-boot,dm-pre-reloc;
 };
+
+&gpio7 {
+	u-boot,dm-pre-reloc;
+};
diff --git a/arch/arm/dts/rk3288-veyron-speedy-u-boot.dtsi b/arch/arm/dts/rk3288-veyron-speedy-u-boot.dtsi
index eccc069..251fbde 100644
--- a/arch/arm/dts/rk3288-veyron-speedy-u-boot.dtsi
+++ b/arch/arm/dts/rk3288-veyron-speedy-u-boot.dtsi
@@ -3,7 +3,7 @@
  * Copyright 2015 Google, Inc
  */
 
-#include "rk3288-u-boot.dtsi"
+#include "rk3288-veyron-u-boot.dtsi"
 
 &dmc {
 	rockchip,pctl-timing = <0x215 0xc8 0x0 0x35 0x26 0x2 0x70 0x2000d
diff --git a/arch/arm/dts/rk3288-veyron-u-boot.dtsi b/arch/arm/dts/rk3288-veyron-u-boot.dtsi
new file mode 100644
index 0000000..899fe6e
--- /dev/null
+++ b/arch/arm/dts/rk3288-veyron-u-boot.dtsi
@@ -0,0 +1,11 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2015 Google, Inc
+ */
+
+#include "rk3288-u-boot.dtsi"
+
+&gpio7 {
+	u-boot,dm-pre-reloc;
+};
+
diff --git a/arch/arm/dts/uniphier-ld11-global.dts b/arch/arm/dts/uniphier-ld11-global.dts
index 7968d52..670e1a7 100644
--- a/arch/arm/dts/uniphier-ld11-global.dts
+++ b/arch/arm/dts/uniphier-ld11-global.dts
@@ -30,6 +30,7 @@
 		i2c3 = &i2c3;
 		i2c4 = &i2c4;
 		i2c5 = &i2c5;
+		ethernet0 = &eth;
 	};
 
 	memory@80000000 {
diff --git a/arch/arm/dts/uniphier-ld11-ref.dts b/arch/arm/dts/uniphier-ld11-ref.dts
index b8f6273..693171f 100644
--- a/arch/arm/dts/uniphier-ld11-ref.dts
+++ b/arch/arm/dts/uniphier-ld11-ref.dts
@@ -29,6 +29,7 @@
 		i2c3 = &i2c3;
 		i2c4 = &i2c4;
 		i2c5 = &i2c5;
+		ethernet0 = &eth;
 	};
 
 	memory@80000000 {
diff --git a/arch/arm/dts/uniphier-ld11.dtsi b/arch/arm/dts/uniphier-ld11.dtsi
index e0737ac..104d56d 100644
--- a/arch/arm/dts/uniphier-ld11.dtsi
+++ b/arch/arm/dts/uniphier-ld11.dtsi
@@ -129,6 +129,8 @@
 			compatible = "socionext,uniphier-scssi";
 			status = "disabled";
 			reg = <0x54006000 0x100>;
+			#address-cells = <1>;
+			#size-cells = <0>;
 			interrupts = <0 39 4>;
 			pinctrl-names = "default";
 			pinctrl-0 = <&pinctrl_spi0>;
@@ -140,11 +142,13 @@
 			compatible = "socionext,uniphier-scssi";
 			status = "disabled";
 			reg = <0x54006100 0x100>;
+			#address-cells = <1>;
+			#size-cells = <0>;
 			interrupts = <0 216 4>;
 			pinctrl-names = "default";
 			pinctrl-0 = <&pinctrl_spi1>;
-			clocks = <&peri_clk 11>;
-			resets = <&peri_rst 11>;
+			clocks = <&peri_clk 12>;
+			resets = <&peri_rst 12>;
 		};
 
 		serial0: serial@54006800 {
@@ -566,6 +570,14 @@
 			};
 		};
 
+		xdmac: dma-controller@5fc10000 {
+			compatible = "socionext,uniphier-xdmac";
+			reg = <0x5fc10000 0x5300>;
+			interrupts = <0 188 4>;
+			dma-channels = <16>;
+			#dma-cells = <2>;
+		};
+
 		aidet: interrupt-controller@5fc20000 {
 			compatible = "socionext,uniphier-ld11-aidet";
 			reg = <0x5fc20000 0x200>;
diff --git a/arch/arm/dts/uniphier-ld20-global.dts b/arch/arm/dts/uniphier-ld20-global.dts
index 9ca692e..2c00008 100644
--- a/arch/arm/dts/uniphier-ld20-global.dts
+++ b/arch/arm/dts/uniphier-ld20-global.dts
@@ -30,6 +30,7 @@
 		i2c3 = &i2c3;
 		i2c4 = &i2c4;
 		i2c5 = &i2c5;
+		ethernet0 = &eth;
 	};
 
 	memory@80000000 {
diff --git a/arch/arm/dts/uniphier-ld20-ref.dts b/arch/arm/dts/uniphier-ld20-ref.dts
index 406244a..eeb976e 100644
--- a/arch/arm/dts/uniphier-ld20-ref.dts
+++ b/arch/arm/dts/uniphier-ld20-ref.dts
@@ -29,6 +29,7 @@
 		i2c3 = &i2c3;
 		i2c4 = &i2c4;
 		i2c5 = &i2c5;
+		ethernet0 = &eth;
 	};
 
 	memory@80000000 {
diff --git a/arch/arm/dts/uniphier-ld20.dtsi b/arch/arm/dts/uniphier-ld20.dtsi
index 59e4191..a5cd026 100644
--- a/arch/arm/dts/uniphier-ld20.dtsi
+++ b/arch/arm/dts/uniphier-ld20.dtsi
@@ -234,6 +234,8 @@
 			compatible = "socionext,uniphier-scssi";
 			status = "disabled";
 			reg = <0x54006000 0x100>;
+			#address-cells = <1>;
+			#size-cells = <0>;
 			interrupts = <0 39 4>;
 			pinctrl-names = "default";
 			pinctrl-0 = <&pinctrl_spi0>;
@@ -245,33 +247,39 @@
 			compatible = "socionext,uniphier-scssi";
 			status = "disabled";
 			reg = <0x54006100 0x100>;
+			#address-cells = <1>;
+			#size-cells = <0>;
 			interrupts = <0 216 4>;
 			pinctrl-names = "default";
 			pinctrl-0 = <&pinctrl_spi1>;
-			clocks = <&peri_clk 11>;
-			resets = <&peri_rst 11>;
+			clocks = <&peri_clk 12>;
+			resets = <&peri_rst 12>;
 		};
 
 		spi2: spi@54006200 {
 			compatible = "socionext,uniphier-scssi";
 			status = "disabled";
 			reg = <0x54006200 0x100>;
+			#address-cells = <1>;
+			#size-cells = <0>;
 			interrupts = <0 229 4>;
 			pinctrl-names = "default";
 			pinctrl-0 = <&pinctrl_spi2>;
-			clocks = <&peri_clk 11>;
-			resets = <&peri_rst 11>;
+			clocks = <&peri_clk 13>;
+			resets = <&peri_rst 13>;
 		};
 
 		spi3: spi@54006300 {
 			compatible = "socionext,uniphier-scssi";
 			status = "disabled";
 			reg = <0x54006300 0x100>;
+			#address-cells = <1>;
+			#size-cells = <0>;
 			interrupts = <0 230 4>;
 			pinctrl-names = "default";
 			pinctrl-0 = <&pinctrl_spi3>;
-			clocks = <&peri_clk 11>;
-			resets = <&peri_rst 11>;
+			clocks = <&peri_clk 14>;
+			resets = <&peri_rst 14>;
 		};
 
 		serial0: serial@54006800 {
@@ -664,6 +672,14 @@
 			};
 		};
 
+		xdmac: dma-controller@5fc10000 {
+			compatible = "socionext,uniphier-xdmac";
+			reg = <0x5fc10000 0x5300>;
+			interrupts = <0 188 4>;
+			dma-channels = <16>;
+			#dma-cells = <2>;
+		};
+
 		aidet: interrupt-controller@5fc20000 {
 			compatible = "socionext,uniphier-ld20-aidet";
 			reg = <0x5fc20000 0x200>;
diff --git a/arch/arm/dts/uniphier-ld4.dtsi b/arch/arm/dts/uniphier-ld4.dtsi
index 1eebc7f..897162d 100644
--- a/arch/arm/dts/uniphier-ld4.dtsi
+++ b/arch/arm/dts/uniphier-ld4.dtsi
@@ -67,6 +67,8 @@
 			compatible = "socionext,uniphier-scssi";
 			status = "disabled";
 			reg = <0x54006000 0x100>;
+			#address-cells = <1>;
+			#size-cells = <0>;
 			interrupts = <0 39 4>;
 			pinctrl-names = "default";
 			pinctrl-0 = <&pinctrl_spi0>;
diff --git a/arch/arm/dts/uniphier-ld6b-ref.dts b/arch/arm/dts/uniphier-ld6b-ref.dts
index 3d9080e..f1a3b29 100644
--- a/arch/arm/dts/uniphier-ld6b-ref.dts
+++ b/arch/arm/dts/uniphier-ld6b-ref.dts
@@ -29,6 +29,7 @@
 		i2c4 = &i2c4;
 		i2c5 = &i2c5;
 		i2c6 = &i2c6;
+		ethernet0 = &eth;
 	};
 
 	memory@80000000 {
diff --git a/arch/arm/dts/uniphier-pro4-ace.dts b/arch/arm/dts/uniphier-pro4-ace.dts
index 92cc48d..64246fa 100644
--- a/arch/arm/dts/uniphier-pro4-ace.dts
+++ b/arch/arm/dts/uniphier-pro4-ace.dts
@@ -26,6 +26,7 @@
 		i2c3 = &i2c3;
 		i2c5 = &i2c5;
 		i2c6 = &i2c6;
+		ethernet0 = &eth;
 	};
 
 	memory@80000000 {
diff --git a/arch/arm/dts/uniphier-pro4-ref.dts b/arch/arm/dts/uniphier-pro4-ref.dts
index 06065eb..4967db5 100644
--- a/arch/arm/dts/uniphier-pro4-ref.dts
+++ b/arch/arm/dts/uniphier-pro4-ref.dts
@@ -30,6 +30,7 @@
 		i2c5 = &i2c5;
 		i2c6 = &i2c6;
 		usb0 = &usb0;
+		ethernet0 = &eth;
 	};
 
 	memory@80000000 {
diff --git a/arch/arm/dts/uniphier-pro4.dtsi b/arch/arm/dts/uniphier-pro4.dtsi
index d006b45..9dae4e9 100644
--- a/arch/arm/dts/uniphier-pro4.dtsi
+++ b/arch/arm/dts/uniphier-pro4.dtsi
@@ -75,6 +75,8 @@
 			compatible = "socionext,uniphier-scssi";
 			status = "disabled";
 			reg = <0x54006000 0x100>;
+			#address-cells = <1>;
+			#size-cells = <0>;
 			interrupts = <0 39 4>;
 			pinctrl-names = "default";
 			pinctrl-0 = <&pinctrl_spi0>;
@@ -426,6 +428,14 @@
 			};
 		};
 
+		xdmac: dma-controller@5fc10000 {
+			compatible = "socionext,uniphier-xdmac";
+			reg = <0x5fc10000 0x5300>;
+			interrupts = <0 188 4>;
+			dma-channels = <16>;
+			#dma-cells = <2>;
+		};
+
 		aidet: interrupt-controller@5fc20000 {
 			compatible = "socionext,uniphier-pro4-aidet";
 			reg = <0x5fc20000 0x200>;
diff --git a/arch/arm/dts/uniphier-pro5.dtsi b/arch/arm/dts/uniphier-pro5.dtsi
index ba7e224..8fc8433 100644
--- a/arch/arm/dts/uniphier-pro5.dtsi
+++ b/arch/arm/dts/uniphier-pro5.dtsi
@@ -160,6 +160,8 @@
 			compatible = "socionext,uniphier-scssi";
 			status = "disabled";
 			reg = <0x54006000 0x100>;
+			#address-cells = <1>;
+			#size-cells = <0>;
 			interrupts = <0 39 4>;
 			pinctrl-names = "default";
 			pinctrl-0 = <&pinctrl_spi0>;
@@ -171,11 +173,13 @@
 			compatible = "socionext,uniphier-scssi";
 			status = "disabled";
 			reg = <0x54006100 0x100>;
+			#address-cells = <1>;
+			#size-cells = <0>;
 			interrupts = <0 216 4>;
 			pinctrl-names = "default";
 			pinctrl-0 = <&pinctrl_spi1>;
-			clocks = <&peri_clk 11>;
-			resets = <&peri_rst 11>;
+			clocks = <&peri_clk 11>;	/* common with spi0 */
+			resets = <&peri_rst 12>;
 		};
 
 		serial0: serial@54006800 {
@@ -408,6 +412,14 @@
 			};
 		};
 
+		xdmac: dma-controller@5fc10000 {
+			compatible = "socionext,uniphier-xdmac";
+			reg = <0x5fc10000 0x5300>;
+			interrupts = <0 188 4>;
+			dma-channels = <16>;
+			#dma-cells = <2>;
+		};
+
 		aidet: interrupt-controller@5fc20000 {
 			compatible = "socionext,uniphier-pro5-aidet";
 			reg = <0x5fc20000 0x200>;
diff --git a/arch/arm/dts/uniphier-pxs2-gentil.dts b/arch/arm/dts/uniphier-pxs2-gentil.dts
index e27fd4f..8e9ac57 100644
--- a/arch/arm/dts/uniphier-pxs2-gentil.dts
+++ b/arch/arm/dts/uniphier-pxs2-gentil.dts
@@ -26,6 +26,7 @@
 		i2c4 = &i2c4;
 		i2c5 = &i2c5;
 		i2c6 = &i2c6;
+		ethernet0 = &eth;
 	};
 
 	memory@80000000 {
diff --git a/arch/arm/dts/uniphier-pxs2-vodka.dts b/arch/arm/dts/uniphier-pxs2-vodka.dts
index 23fe42b..8eacc7b 100644
--- a/arch/arm/dts/uniphier-pxs2-vodka.dts
+++ b/arch/arm/dts/uniphier-pxs2-vodka.dts
@@ -24,6 +24,7 @@
 		i2c4 = &i2c4;
 		i2c5 = &i2c5;
 		i2c6 = &i2c6;
+		ethernet0 = &eth;
 	};
 
 	memory@80000000 {
diff --git a/arch/arm/dts/uniphier-pxs2.dtsi b/arch/arm/dts/uniphier-pxs2.dtsi
index 8d968d3..899ff37 100644
--- a/arch/arm/dts/uniphier-pxs2.dtsi
+++ b/arch/arm/dts/uniphier-pxs2.dtsi
@@ -173,6 +173,8 @@
 			compatible = "socionext,uniphier-scssi";
 			status = "disabled";
 			reg = <0x54006000 0x100>;
+			#address-cells = <1>;
+			#size-cells = <0>;
 			interrupts = <0 39 4>;
 			pinctrl-names = "default";
 			pinctrl-0 = <&pinctrl_spi0>;
@@ -184,11 +186,13 @@
 			compatible = "socionext,uniphier-scssi";
 			status = "disabled";
 			reg = <0x54006100 0x100>;
+			#address-cells = <1>;
+			#size-cells = <0>;
 			interrupts = <0 216 4>;
 			pinctrl-names = "default";
 			pinctrl-0 = <&pinctrl_spi1>;
-			clocks = <&peri_clk 11>;
-			resets = <&peri_rst 11>;
+			clocks = <&peri_clk 12>;
+			resets = <&peri_rst 12>;
 		};
 
 		serial0: serial@54006800 {
@@ -508,6 +512,14 @@
 			};
 		};
 
+		xdmac: dma-controller@5fc10000 {
+			compatible = "socionext,uniphier-xdmac";
+			reg = <0x5fc10000 0x5300>;
+			interrupts = <0 188 4>;
+			dma-channels = <16>;
+			#dma-cells = <2>;
+		};
+
 		aidet: interrupt-controller@5fc20000 {
 			compatible = "socionext,uniphier-pxs2-aidet";
 			reg = <0x5fc20000 0x200>;
diff --git a/arch/arm/dts/uniphier-pxs3-ref.dts b/arch/arm/dts/uniphier-pxs3-ref.dts
index 1965e4d..1dacbf4 100644
--- a/arch/arm/dts/uniphier-pxs3-ref.dts
+++ b/arch/arm/dts/uniphier-pxs3-ref.dts
@@ -27,6 +27,10 @@
 		i2c2 = &i2c2;
 		i2c3 = &i2c3;
 		i2c6 = &i2c6;
+		spi0 = &spi0;
+		spi1 = &spi1;
+		ethernet0 = &eth0;
+		ethernet1 = &eth1;
 	};
 
 	memory@80000000 {
@@ -39,6 +43,14 @@
 	interrupts = <4 8>;
 };
 
+&spi0 {
+	status = "okay";
+};
+
+&spi1 {
+	status = "okay";
+};
+
 &serial0 {
 	status = "okay";
 };
@@ -116,3 +128,19 @@
 &nand {
 	status = "okay";
 };
+
+&pinctrl_ether_rgmii {
+	tx {
+		pins = "RGMII0_TXCLK", "RGMII0_TXD0", "RGMII0_TXD1",
+		       "RGMII0_TXD2", "RGMII0_TXD3", "RGMII0_TXCTL";
+		drive-strength = <9>;
+	};
+};
+
+&pinctrl_ether1_rgmii {
+	tx {
+		pins = "RGMII1_TXCLK", "RGMII1_TXD0", "RGMII1_TXD1",
+		       "RGMII1_TXD2", "RGMII1_TXD3", "RGMII1_TXCTL";
+		drive-strength = <9>;
+	};
+};
diff --git a/arch/arm/dts/uniphier-pxs3.dtsi b/arch/arm/dts/uniphier-pxs3.dtsi
index ed079c1..bf3b1eae 100644
--- a/arch/arm/dts/uniphier-pxs3.dtsi
+++ b/arch/arm/dts/uniphier-pxs3.dtsi
@@ -7,6 +7,7 @@
 
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/gpio/uniphier-gpio.h>
+#include <dt-bindings/thermal/thermal.h>
 
 / {
 	compatible = "socionext,uniphier-pxs3";
@@ -42,6 +43,7 @@
 			clocks = <&sys_clk 33>;
 			enable-method = "psci";
 			operating-points-v2 = <&cluster0_opp>;
+			#cooling-cells = <2>;
 		};
 
 		cpu1: cpu@1 {
@@ -51,6 +53,7 @@
 			clocks = <&sys_clk 33>;
 			enable-method = "psci";
 			operating-points-v2 = <&cluster0_opp>;
+			#cooling-cells = <2>;
 		};
 
 		cpu2: cpu@2 {
@@ -60,6 +63,7 @@
 			clocks = <&sys_clk 33>;
 			enable-method = "psci";
 			operating-points-v2 = <&cluster0_opp>;
+			#cooling-cells = <2>;
 		};
 
 		cpu3: cpu@3 {
@@ -69,6 +73,7 @@
 			clocks = <&sys_clk 33>;
 			enable-method = "psci";
 			operating-points-v2 = <&cluster0_opp>;
+			#cooling-cells = <2>;
 		};
 	};
 
@@ -136,6 +141,37 @@
 			     <1 10 4>;
 	};
 
+	thermal-zones {
+		cpu-thermal {
+			polling-delay-passive = <250>;	/* 250ms */
+			polling-delay = <1000>;		/* 1000ms */
+			thermal-sensors = <&pvtctl>;
+
+			trips {
+				cpu_crit: cpu-crit {
+					temperature = <110000>;	/* 110C */
+					hysteresis = <2000>;
+					type = "critical";
+				};
+				cpu_alert: cpu-alert {
+					temperature = <100000>;	/* 100C */
+					hysteresis = <2000>;
+					type = "passive";
+				};
+			};
+
+			cooling-maps {
+				map0 {
+					trip = <&cpu_alert>;
+					cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+				};
+			};
+		};
+	};
+
 	reserved-memory {
 		#address-cells = <2>;
 		#size-cells = <2>;
@@ -157,6 +193,8 @@
 			compatible = "socionext,uniphier-scssi";
 			status = "disabled";
 			reg = <0x54006000 0x100>;
+			#address-cells = <1>;
+			#size-cells = <0>;
 			interrupts = <0 39 4>;
 			pinctrl-names = "default";
 			pinctrl-0 = <&pinctrl_spi0>;
@@ -168,11 +206,13 @@
 			compatible = "socionext,uniphier-scssi";
 			status = "disabled";
 			reg = <0x54006100 0x100>;
+			#address-cells = <1>;
+			#size-cells = <0>;
 			interrupts = <0 216 4>;
 			pinctrl-names = "default";
 			pinctrl-0 = <&pinctrl_spi1>;
-			clocks = <&peri_clk 11>;
-			resets = <&peri_rst 11>;
+			clocks = <&peri_clk 12>;
+			resets = <&peri_rst 12>;
 		};
 
 		serial0: serial@54006800 {
@@ -462,6 +502,14 @@
 			};
 		};
 
+		xdmac: dma-controller@5fc10000 {
+			compatible = "socionext,uniphier-xdmac";
+			reg = <0x5fc10000 0x5300>;
+			interrupts = <0 188 4>;
+			dma-channels = <16>;
+			#dma-cells = <2>;
+		};
+
 		aidet: interrupt-controller@5fc20000 {
 			compatible = "socionext,uniphier-pxs3-aidet";
 			reg = <0x5fc20000 0x200>;
@@ -496,6 +544,13 @@
 			watchdog {
 				compatible = "socionext,uniphier-wdt";
 			};
+
+			pvtctl: pvtctl {
+				compatible = "socionext,uniphier-pxs3-thermal";
+				interrupts = <0 3 4>;
+				#thermal-sensor-cells = <0>;
+				socionext,tmod-calibration = <0x0f22 0x68ee>;
+			};
 		};
 
 		eth0: ethernet@65000000 {
diff --git a/arch/arm/dts/uniphier-sld8.dtsi b/arch/arm/dts/uniphier-sld8.dtsi
index 393157e..93ddebb 100644
--- a/arch/arm/dts/uniphier-sld8.dtsi
+++ b/arch/arm/dts/uniphier-sld8.dtsi
@@ -67,6 +67,8 @@
 			compatible = "socionext,uniphier-scssi";
 			status = "disabled";
 			reg = <0x54006000 0x100>;
+			#address-cells = <1>;
+			#size-cells = <0>;
 			interrupts = <0 39 4>;
 			pinctrl-names = "default";
 			pinctrl-0 = <&pinctrl_spi0>;
diff --git a/arch/arm/include/asm/mmu.h b/arch/arm/include/asm/mmu.h
new file mode 100644
index 0000000..9ac16f5
--- /dev/null
+++ b/arch/arm/include/asm/mmu.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+
+#ifndef __ASM_ARM_MMU_H
+#define __ASM_ARM_MMU_H
+
+void init_addr_map(void);
+
+#endif
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
index b8c1b4e..37c1bfd 100644
--- a/arch/arm/include/asm/system.h
+++ b/arch/arm/include/asm/system.h
@@ -207,7 +207,7 @@
 void __asm_switch_ttbr(u64 new_ttbr);
 
 /*
- * Switch from EL3 to EL2 for ARMv8
+ * armv8_switch_to_el2() - switch from EL3 to EL2 for ARMv8
  *
  * @args:        For loading 64-bit OS, fdt address.
  *               For loading 32-bit OS, zero.
@@ -222,7 +222,7 @@
 void __noreturn armv8_switch_to_el2(u64 args, u64 mach_nr, u64 fdt_addr,
 				    u64 arg4, u64 entry_point, u64 es_flag);
 /*
- * Switch from EL2 to EL1 for ARMv8
+ * armv8_switch_to_el1() - switch from EL2 to EL1 for ARMv8
  *
  * @args:        For loading 64-bit OS, fdt address.
  *               For loading 32-bit OS, zero.
@@ -248,11 +248,12 @@
 void mmu_change_region_attr(phys_addr_t start, size_t size, u64 attrs);
 
 /*
- *Issue a secure monitor call in accordance with ARM "SMC Calling convention",
+ * smc_call() - issue a secure monitor call
+ *
+ * Issue a secure monitor call in accordance with ARM "SMC Calling convention",
  * DEN0028A
  *
  * @args: input and output arguments
- *
  */
 void smc_call(struct pt_regs *args);
 
@@ -521,10 +522,12 @@
 #endif
 
 /**
+ * mmu_page_table_flush() - register an update to page tables
+ *
  * Register an update to the page tables, and flush the TLB
  *
- * \param start		start address of update in page table
- * \param stop		stop address of update in page table
+ * @start:	start address of update in page table
+ * @stop:	stop address of update in page table
  */
 void mmu_page_table_flush(unsigned long start, unsigned long stop);
 
@@ -585,11 +588,26 @@
 void save_boot_params_ret(void);
 
 /**
+ * mmu_set_region_dcache_behaviour_phys() - set virt/phys mapping
+ *
+ * Change the virt/phys mapping and cache settings for a region.
+ *
+ * @virt:	virtual start address of memory region to change
+ * @phys:	physical address for the memory region to set
+ * @size:	size of memory region to change
+ * @option:	dcache option to select
+ */
+void mmu_set_region_dcache_behaviour_phys(phys_addr_t virt, phys_addr_t phys,
+					size_t size, enum dcache_option option);
+
+/**
+ * mmu_set_region_dcache_behaviour() - set cache settings
+ *
  * Change the cache settings for a region.
  *
- * \param start		start address of memory region to change
- * \param size		size of memory region to change
- * \param option	dcache option to select
+ * @start:	start address of memory region to change
+ * @size:	size of memory region to change
+ * @option:	dcache option to select
  */
 void mmu_set_region_dcache_behaviour(phys_addr_t start, size_t size,
 				     enum dcache_option option);
diff --git a/arch/arm/lib/cache-cp15.c b/arch/arm/lib/cache-cp15.c
index 1da2e92..3971761 100644
--- a/arch/arm/lib/cache-cp15.c
+++ b/arch/arm/lib/cache-cp15.c
@@ -25,7 +25,8 @@
 {
 }
 
-void set_section_dcache(int section, enum dcache_option option)
+static void set_section_phys(int section, phys_addr_t phys,
+			     enum dcache_option option)
 {
 #ifdef CONFIG_ARMV7_LPAE
 	u64 *page_table = (u64 *)gd->arch.tlb_addr;
@@ -37,7 +38,7 @@
 #endif
 
 	/* Add the page offset */
-	value |= ((u32)section << MMU_SECTION_SHIFT);
+	value |= phys;
 
 	/* Add caching bits */
 	value |= option;
@@ -46,13 +47,18 @@
 	page_table[section] = value;
 }
 
+void set_section_dcache(int section, enum dcache_option option)
+{
+	set_section_phys(section, (u32)section << MMU_SECTION_SHIFT, option);
+}
+
 __weak void mmu_page_table_flush(unsigned long start, unsigned long stop)
 {
 	debug("%s: Warning: not implemented\n", __func__);
 }
 
-void mmu_set_region_dcache_behaviour(phys_addr_t start, size_t size,
-				     enum dcache_option option)
+void mmu_set_region_dcache_behaviour_phys(phys_addr_t start, phys_addr_t phys,
+					size_t size, enum dcache_option option)
 {
 #ifdef CONFIG_ARMV7_LPAE
 	u64 *page_table = (u64 *)gd->arch.tlb_addr;
@@ -74,8 +80,8 @@
 	debug("%s: start=%pa, size=%zu, option=0x%x\n", __func__, &start, size,
 	      option);
 #endif
-	for (upto = start; upto < end; upto++)
-		set_section_dcache(upto, option);
+	for (upto = start; upto < end; upto++, phys += MMU_SECTION_SIZE)
+		set_section_phys(upto, phys, option);
 
 	/*
 	 * Make sure range is cache line aligned
@@ -90,6 +96,12 @@
 	mmu_page_table_flush(startpt, stoppt);
 }
 
+void mmu_set_region_dcache_behaviour(phys_addr_t start, size_t size,
+				     enum dcache_option option)
+{
+	mmu_set_region_dcache_behaviour_phys(start, start, size, option);
+}
+
 __weak void dram_bank_mmu_setup(int bank)
 {
 	bd_t *bd = gd->bd;
diff --git a/arch/arm/mach-at91/arm926ejs/at91sam9260_devices.c b/arch/arm/mach-at91/arm926ejs/at91sam9260_devices.c
index c033ed6..8122d2f 100644
--- a/arch/arm/mach-at91/arm926ejs/at91sam9260_devices.c
+++ b/arch/arm/mach-at91/arm926ejs/at91sam9260_devices.c
@@ -220,7 +220,7 @@
 };
 
 U_BOOT_DEVICES(at91sam9260_gpios) = {
-	{ "gpio_at91", &at91sam9260_plat[0] },
-	{ "gpio_at91", &at91sam9260_plat[1] },
-	{ "gpio_at91", &at91sam9260_plat[2] },
+	{ "atmel_at91rm9200_gpio", &at91sam9260_plat[0] },
+	{ "atmel_at91rm9200_gpio", &at91sam9260_plat[1] },
+	{ "atmel_at91rm9200_gpio", &at91sam9260_plat[2] },
 };
diff --git a/arch/arm/mach-at91/arm926ejs/at91sam9m10g45_devices.c b/arch/arm/mach-at91/arm926ejs/at91sam9m10g45_devices.c
index 89cbeaf..08ca3ed 100644
--- a/arch/arm/mach-at91/arm926ejs/at91sam9m10g45_devices.c
+++ b/arch/arm/mach-at91/arm926ejs/at91sam9m10g45_devices.c
@@ -176,9 +176,9 @@
 };
 
 U_BOOT_DEVICES(at91sam9260_gpios) = {
-	{ "gpio_at91", &at91sam9260_plat[0] },
-	{ "gpio_at91", &at91sam9260_plat[1] },
-	{ "gpio_at91", &at91sam9260_plat[2] },
-	{ "gpio_at91", &at91sam9260_plat[3] },
-	{ "gpio_at91", &at91sam9260_plat[4] },
+	{ "atmel_at91rm9200_gpio", &at91sam9260_plat[0] },
+	{ "atmel_at91rm9200_gpio", &at91sam9260_plat[1] },
+	{ "atmel_at91rm9200_gpio", &at91sam9260_plat[2] },
+	{ "atmel_at91rm9200_gpio", &at91sam9260_plat[3] },
+	{ "atmel_at91rm9200_gpio", &at91sam9260_plat[4] },
 };
diff --git a/arch/arm/mach-bcm283x/Kconfig b/arch/arm/mach-bcm283x/Kconfig
index e6eb904..b3287ce 100644
--- a/arch/arm/mach-bcm283x/Kconfig
+++ b/arch/arm/mach-bcm283x/Kconfig
@@ -36,6 +36,7 @@
 	select BCM2711
 	select ARMV7_LPAE
 	select CPU_V7A
+	select PHYS_64BIT
 
 config BCM2711_64B
 	bool "Broadcom BCM2711 SoC 64-bit support"
diff --git a/arch/arm/mach-bcm283x/include/mach/base.h b/arch/arm/mach-bcm283x/include/mach/base.h
index c4ae398..4ccaf69 100644
--- a/arch/arm/mach-bcm283x/include/mach/base.h
+++ b/arch/arm/mach-bcm283x/include/mach/base.h
@@ -8,4 +8,12 @@
 
 extern unsigned long rpi_bcm283x_base;
 
+#ifdef CONFIG_ARMV7_LPAE
+#ifdef CONFIG_TARGET_RPI_4_32B
+#include <addr_map.h>
+#define phys_to_virt addrmap_phys_to_virt
+#define virt_to_phys addrmap_virt_to_phys
+#endif
+#endif
+
 #endif
diff --git a/arch/arm/mach-bcm283x/include/mach/mbox.h b/arch/arm/mach-bcm283x/include/mach/mbox.h
index 60e226c..2ae2d3d 100644
--- a/arch/arm/mach-bcm283x/include/mach/mbox.h
+++ b/arch/arm/mach-bcm283x/include/mach/mbox.h
@@ -491,6 +491,19 @@
 	} body;
 };
 
+#define BCM2835_MBOX_TAG_NOTIFY_XHCI_RESET          0x00030058
+
+struct bcm2835_mbox_tag_pci_dev_addr {
+	struct bcm2835_mbox_tag_hdr tag_hdr;
+	union {
+		struct {
+			u32 dev_addr;
+		} req;
+		struct {
+		} resp;
+	} body;
+};
+
 /*
  * Pass a raw u32 message to the VC, and receive a raw u32 back.
  *
diff --git a/arch/arm/mach-bcm283x/include/mach/msg.h b/arch/arm/mach-bcm283x/include/mach/msg.h
index 4afb086..e45c1bf 100644
--- a/arch/arm/mach-bcm283x/include/mach/msg.h
+++ b/arch/arm/mach-bcm283x/include/mach/msg.h
@@ -48,4 +48,11 @@
 			     int pixel_order, int alpha_mode, ulong *fb_basep,
 			     ulong *fb_sizep, int *pitchp);
 
+/**
+ * bcm2711_load_vl805_firmware() - get vl805's firmware loaded
+ *
+ * @return 0 if OK, -EIO on error
+ */
+int bcm2711_notify_vl805_reset(void);
+
 #endif
diff --git a/arch/arm/mach-bcm283x/init.c b/arch/arm/mach-bcm283x/init.c
index f4d00d8..f2a5411 100644
--- a/arch/arm/mach-bcm283x/init.c
+++ b/arch/arm/mach-bcm283x/init.c
@@ -12,10 +12,15 @@
 #include <dm/device.h>
 #include <fdt_support.h>
 
+#define BCM2711_RPI4_PCIE_XHCI_MMIO_PHYS	0x600000000UL
+#define BCM2711_RPI4_PCIE_XHCI_MMIO_SIZE	0x800000UL
+
 #ifdef CONFIG_ARM64
 #include <asm/armv8/mmu.h>
 
-static struct mm_region bcm283x_mem_map[] = {
+#define MEM_MAP_MAX_ENTRIES (4)
+
+static struct mm_region bcm283x_mem_map[MEM_MAP_MAX_ENTRIES] = {
 	{
 		.virt = 0x00000000UL,
 		.phys = 0x00000000UL,
@@ -35,11 +40,11 @@
 	}
 };
 
-static struct mm_region bcm2711_mem_map[] = {
+static struct mm_region bcm2711_mem_map[MEM_MAP_MAX_ENTRIES] = {
 	{
 		.virt = 0x00000000UL,
 		.phys = 0x00000000UL,
-		.size = 0xfe000000UL,
+		.size = 0xfc000000UL,
 		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
 			 PTE_BLOCK_INNER_SHARE
 	}, {
@@ -50,6 +55,13 @@
 			 PTE_BLOCK_NON_SHARE |
 			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
 	}, {
+		.virt = BCM2711_RPI4_PCIE_XHCI_MMIO_PHYS,
+		.phys = BCM2711_RPI4_PCIE_XHCI_MMIO_PHYS,
+		.size = BCM2711_RPI4_PCIE_XHCI_MMIO_SIZE,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+			 PTE_BLOCK_NON_SHARE |
+			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
+	}, {
 		/* List terminator */
 		0,
 	}
@@ -72,7 +84,7 @@
 {
 	int i;
 
-	for (i = 0; i < 2; i++) {
+	for (i = 0; i < MEM_MAP_MAX_ENTRIES; i++) {
 		mem_map[i].virt = pd[i].virt;
 		mem_map[i].phys = pd[i].phys;
 		mem_map[i].size = pd[i].size;
@@ -134,6 +146,27 @@
 }
 
 #ifdef CONFIG_ARMV7_LPAE
+#ifdef CONFIG_TARGET_RPI_4_32B
+#define BCM2711_RPI4_PCIE_XHCI_MMIO_VIRT	0xff800000UL
+#include <addr_map.h>
+#include <asm/system.h>
+
+void init_addr_map(void)
+{
+	mmu_set_region_dcache_behaviour_phys(BCM2711_RPI4_PCIE_XHCI_MMIO_VIRT,
+					     BCM2711_RPI4_PCIE_XHCI_MMIO_PHYS,
+					     BCM2711_RPI4_PCIE_XHCI_MMIO_SIZE,
+					     DCACHE_OFF);
+
+	/* identity mapping for 0..BCM2711_RPI4_PCIE_XHCI_MMIO_VIRT */
+	addrmap_set_entry(0, 0, BCM2711_RPI4_PCIE_XHCI_MMIO_VIRT, 0);
+	/* XHCI MMIO on PCIe at BCM2711_RPI4_PCIE_XHCI_MMIO_VIRT */
+	addrmap_set_entry(BCM2711_RPI4_PCIE_XHCI_MMIO_VIRT,
+			  BCM2711_RPI4_PCIE_XHCI_MMIO_PHYS,
+			  BCM2711_RPI4_PCIE_XHCI_MMIO_SIZE, 1);
+}
+#endif
+
 void enable_caches(void)
 {
 	dcache_enable();
diff --git a/arch/arm/mach-bcm283x/msg.c b/arch/arm/mach-bcm283x/msg.c
index 94b7528..347aece 100644
--- a/arch/arm/mach-bcm283x/msg.c
+++ b/arch/arm/mach-bcm283x/msg.c
@@ -7,6 +7,7 @@
 #include <memalign.h>
 #include <phys2bus.h>
 #include <asm/arch/mbox.h>
+#include <linux/delay.h>
 
 struct msg_set_power_state {
 	struct bcm2835_mbox_hdr hdr;
@@ -40,6 +41,12 @@
 	u32 end_tag;
 };
 
+struct msg_notify_vl805_reset {
+	struct bcm2835_mbox_hdr hdr;
+	struct bcm2835_mbox_tag_pci_dev_addr dev_addr;
+	u32 end_tag;
+};
+
 int bcm2835_power_on_module(u32 module)
 {
 	ALLOC_CACHE_ALIGN_BUFFER(struct msg_set_power_state, msg_pwr, 1);
@@ -151,3 +158,42 @@
 
 	return 0;
 }
+
+/*
+ * On the Raspberry Pi 4, after a PCI reset, VL805's (the xHCI chip) firmware
+ * may either be loaded directly from an EEPROM or, if not present, by the
+ * SoC's VideoCore. This informs VideoCore that VL805 needs its firmware
+ * loaded.
+ */
+int bcm2711_notify_vl805_reset(void)
+{
+	ALLOC_CACHE_ALIGN_BUFFER(struct msg_notify_vl805_reset,
+				 msg_notify_vl805_reset, 1);
+	int ret;
+
+	BCM2835_MBOX_INIT_HDR(msg_notify_vl805_reset);
+	BCM2835_MBOX_INIT_TAG(&msg_notify_vl805_reset->dev_addr,
+			      NOTIFY_XHCI_RESET);
+
+	/*
+	 * The pci device address is expected like this:
+	 *
+	 *   PCI_BUS << 20 | PCI_SLOT << 15 | PCI_FUNC << 12
+	 *
+	 * But since RPi4's PCIe setup is hardwired, we know the address in
+	 * advance.
+	 */
+	msg_notify_vl805_reset->dev_addr.body.req.dev_addr = 0x100000;
+
+	ret = bcm2835_mbox_call_prop(BCM2835_MBOX_PROP_CHAN,
+				     &msg_notify_vl805_reset->hdr);
+	if (ret) {
+		printf("bcm2711: Faild to load vl805's firmware, %d\n", ret);
+		return -EIO;
+	}
+
+	udelay(200);
+
+	return 0;
+}
+
diff --git a/arch/arm/mach-rockchip/rk3328/syscon_rk3328.c b/arch/arm/mach-rockchip/rk3328/syscon_rk3328.c
index 8a0eceb..daf74a0 100644
--- a/arch/arm/mach-rockchip/rk3328/syscon_rk3328.c
+++ b/arch/arm/mach-rockchip/rk3328/syscon_rk3328.c
@@ -13,8 +13,8 @@
 	{ }
 };
 
-U_BOOT_DRIVER(syscon_rk3328) = {
-	.name = "rk3328_syscon",
+U_BOOT_DRIVER(rockchip_rk3328_grf) = {
+	.name = "rockchip_rk3328_grf",
 	.id = UCLASS_SYSCON,
 	.of_match = rk3328_syscon_ids,
 };
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c
index 0722e4a..cbf0120 100644
--- a/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c
+++ b/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c
@@ -147,7 +147,7 @@
 		/* Try bootm for legacy and FIT format image */
 		if (genimg_get_format((void *)uimage) != IMAGE_FORMAT_INVALID)
 			do_bootm(cmdtp, 0, 4, bootm_argv);
-		else if CONFIG_IS_ENABLED(CMD_BOOTZ)
+		else if (CONFIG_IS_ENABLED(CMD_BOOTZ))
 			do_bootz(cmdtp, 0, 4, bootm_argv);
 	}
 
diff --git a/arch/arm/mach-uniphier/Kconfig b/arch/arm/mach-uniphier/Kconfig
index bfb445a..3a8eee7 100644
--- a/arch/arm/mach-uniphier/Kconfig
+++ b/arch/arm/mach-uniphier/Kconfig
@@ -3,24 +3,15 @@
 config SYS_CONFIG_NAME
 	default "uniphier"
 
-config ARCH_UNIPHIER_32BIT
-	bool
-	select ARCH_SUPPORT_PSCI
-	select ARMV7_NONSEC
-	select CPU_V7A
-	select CPU_V7_HAS_NONSEC
-
 choice
         prompt "UniPhier SoC select"
-        default ARCH_UNIPHIER_V7_MULTI
-
-config ARCH_UNIPHIER_LD4_SLD8
-	bool "UniPhier LD4/sLD8 SoCs"
-	select ARCH_UNIPHIER_32BIT
 
 config ARCH_UNIPHIER_V7_MULTI
-	bool "UniPhier Pro4/Pro5/PXs2/LD6b SoCs"
-	select ARCH_UNIPHIER_32BIT
+	bool "UniPhier V7 SoCs"
+	select ARCH_SUPPORT_PSCI
+	select ARMV7_NONSEC
+	select CPU_V7A
+	select CPU_V7_HAS_NONSEC
 
 config ARCH_UNIPHIER_V8_MULTI
 	bool "UniPhier V8 SoCs"
@@ -32,32 +23,38 @@
 
 config ARCH_UNIPHIER_LD4
 	bool "Enable UniPhier LD4 SoC support"
-	depends on ARCH_UNIPHIER_LD4_SLD8
+	depends on ARCH_UNIPHIER_V7_MULTI
+	depends on !SPL || SPL_TEXT_BASE = 0x00040000
 	default y
 
 config ARCH_UNIPHIER_SLD8
 	bool "Enable UniPhier sLD8 SoC support"
-	depends on ARCH_UNIPHIER_LD4_SLD8
+	depends on ARCH_UNIPHIER_V7_MULTI
+	depends on !SPL || SPL_TEXT_BASE = 0x00040000
 	default y
 
 config ARCH_UNIPHIER_PRO4
 	bool "Enable UniPhier Pro4 SoC support"
 	depends on ARCH_UNIPHIER_V7_MULTI
+	depends on !SPL || SPL_TEXT_BASE = 0x00100000
 	default y
 
 config ARCH_UNIPHIER_PRO5
 	bool "Enable UniPhier Pro5 SoC support"
 	depends on ARCH_UNIPHIER_V7_MULTI
+	depends on !SPL || SPL_TEXT_BASE = 0x00100000
 	default y
 
 config ARCH_UNIPHIER_PXS2
 	bool "Enable UniPhier Pxs2 SoC support"
 	depends on ARCH_UNIPHIER_V7_MULTI
+	depends on !SPL || SPL_TEXT_BASE = 0x00100000
 	default y
 
 config ARCH_UNIPHIER_LD6B
 	bool "Enable UniPhier LD6b SoC support"
 	depends on ARCH_UNIPHIER_V7_MULTI
+	depends on !SPL || SPL_TEXT_BASE = 0x00100000
 	default y
 
 config ARCH_UNIPHIER_LD11
@@ -78,7 +75,7 @@
 
 config CACHE_UNIPHIER
 	bool "Enable the UniPhier L2 cache controller"
-	depends on ARCH_UNIPHIER_32BIT
+	depends on ARCH_UNIPHIER_V7_MULTI
 	default y
 	select SYS_CACHE_SHIFT_7
 	help
@@ -86,6 +83,7 @@
 
 config MICRO_SUPPORT_CARD
 	bool "Use Micro Support Card"
+	depends on UNIPHIER_SYSTEM_BUS
 	help
 	  This option provides support for the expansion board, available
 	  on some UniPhier reference boards.
@@ -118,5 +116,5 @@
 	  training; it is useful for the evaluation of DDR Multi PHY training.
 
 config SYS_SOC
-	default "uniphier-v7" if ARCH_UNIPHIER_LD4_SLD8 || ARCH_UNIPHIER_V7_MULTI
+	default "uniphier-v7" if ARCH_UNIPHIER_V7_MULTI
 endif
diff --git a/arch/arm/mach-uniphier/Makefile b/arch/arm/mach-uniphier/Makefile
index 769778c..38b6d90 100644
--- a/arch/arm/mach-uniphier/Makefile
+++ b/arch/arm/mach-uniphier/Makefile
@@ -22,12 +22,10 @@
 obj-$(CONFIG_MICRO_SUPPORT_CARD) += micro-support-card.o
 obj-y += pinctrl-glue.o
 obj-$(CONFIG_MMC) += mmc-first-dev.o
-obj-$(CONFIG_NAND_DENALI) += nand-reset.o
 obj-y += fdt-fixup.o
 
 endif
 
-obj-y += sbc/
 obj-y += soc-info.o
 obj-y += boot-device/
 obj-y += clk/
diff --git a/arch/arm/mach-uniphier/arm64/Makefile b/arch/arm/mach-uniphier/arm64/Makefile
index c569551..750c4f756 100644
--- a/arch/arm/mach-uniphier/arm64/Makefile
+++ b/arch/arm/mach-uniphier/arm64/Makefile
@@ -1,4 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0+
 
 obj-y += mem_map.o
-obj-$(CONFIG_ARCH_UNIPHIER_LD20) += lowlevel_init.o
diff --git a/arch/arm/mach-uniphier/arm64/lowlevel_init.S b/arch/arm/mach-uniphier/arm64/lowlevel_init.S
deleted file mode 100644
index f4e5cbb..0000000
--- a/arch/arm/mach-uniphier/arm64/lowlevel_init.S
+++ /dev/null
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Copyright (C) 2017 Socionext Inc.
- */
-
-#include <linux/linkage.h>
-
-ENTRY(lowlevel_init)
-	/* LD20 needs the following code to boot.  I do not know why. */
-	mrs	x0, sctlr_el1
-	msr	sctlr_el1, x0
-	ret
-ENDPROC(lowlevel_init)
diff --git a/arch/arm/mach-uniphier/board_init.c b/arch/arm/mach-uniphier/board_init.c
index 4f9cd6e..30e4e23 100644
--- a/arch/arm/mach-uniphier/board_init.c
+++ b/arch/arm/mach-uniphier/board_init.c
@@ -13,6 +13,33 @@
 #include "micro-support-card.h"
 #include "soc-info.h"
 
+#define PC0CTRL				0x598000c0
+
+#if defined(CONFIG_ARCH_UNIPHIER_LD4) || defined(CONFIG_ARCH_UNIPHIER_SLD8)
+static void uniphier_ld4_sbc_init(void)
+{
+	u32 tmp;
+
+	/* system bus output enable */
+	tmp = readl(PC0CTRL);
+	tmp &= 0xfffffcff;
+	writel(tmp, PC0CTRL);
+}
+#endif
+
+#if defined(CONFIG_ARCH_UNIPHIER_PXS2) || \
+    defined(CONFIG_ARCH_UNIPHIER_LD6B) || \
+    defined(CONFIG_ARCH_UNIPHIER_LD11) || \
+    defined(CONFIG_ARCH_UNIPHIER_LD20) || \
+    defined(CONFIG_ARCH_UNIPHIER_PXS3)
+static void uniphier_pxs2_sbc_init(void)
+{
+	/* necessary for ROM boot ?? */
+	/* system bus output enable */
+	writel(0x17, PC0CTRL);
+}
+#endif
+
 #ifdef CONFIG_ARCH_UNIPHIER_LD20
 static void uniphier_ld20_misc_init(void)
 {
@@ -45,7 +72,6 @@
 #if defined(CONFIG_ARCH_UNIPHIER_PRO4)
 	{
 		.soc_id = UNIPHIER_PRO4_ID,
-		.sbc_init = uniphier_sbc_init_savepin,
 		.pll_init = uniphier_pro4_pll_init,
 		.clk_init = uniphier_pro4_clk_init,
 	},
@@ -60,7 +86,6 @@
 #if defined(CONFIG_ARCH_UNIPHIER_PRO5)
 	{
 		.soc_id = UNIPHIER_PRO5_ID,
-		.sbc_init = uniphier_sbc_init_savepin,
 		.clk_init = uniphier_pro5_clk_init,
 	},
 #endif
@@ -81,7 +106,7 @@
 #if defined(CONFIG_ARCH_UNIPHIER_LD11)
 	{
 		.soc_id = UNIPHIER_LD11_ID,
-		.sbc_init = uniphier_ld11_sbc_init,
+		.sbc_init = uniphier_pxs2_sbc_init,
 		.pll_init = uniphier_ld11_pll_init,
 		.clk_init = uniphier_ld11_clk_init,
 	},
@@ -89,7 +114,7 @@
 #if defined(CONFIG_ARCH_UNIPHIER_LD20)
 	{
 		.soc_id = UNIPHIER_LD20_ID,
-		.sbc_init = uniphier_ld11_sbc_init,
+		.sbc_init = uniphier_pxs2_sbc_init,
 		.pll_init = uniphier_ld20_pll_init,
 		.clk_init = uniphier_ld20_clk_init,
 		.misc_init = uniphier_ld20_misc_init,
@@ -118,7 +143,8 @@
 		return -EINVAL;
 	}
 
-	initdata->sbc_init();
+	if (initdata->sbc_init)
+		initdata->sbc_init();
 
 	support_card_init();
 
@@ -137,14 +163,6 @@
 	if (initdata->misc_init)
 		initdata->misc_init();
 
-	led_puts("U3");
-
-	support_card_late_init();
-
-	led_puts("U4");
-
-	uniphier_nand_reset_assert();
-
 	led_puts("Uboo");
 
 	return 0;
diff --git a/arch/arm/mach-uniphier/boot-device/boot-device.c b/arch/arm/mach-uniphier/boot-device/boot-device.c
index 69a35f5..98ff34c 100644
--- a/arch/arm/mach-uniphier/boot-device/boot-device.c
+++ b/arch/arm/mach-uniphier/boot-device/boot-device.c
@@ -14,11 +14,18 @@
 #include <linux/log2.h>
 
 #include "../init.h"
-#include "../sbc/sbc-regs.h"
 #include "../sg-regs.h"
 #include "../soc-info.h"
 #include "boot-device.h"
 
+#define SBBASE0			0x58c00100
+#define SBBASE_BANK_ENABLE		BIT(0)
+
+static int uniphier_sbc_boot_is_swapped(void)
+{
+	return !(readl(SBBASE0) & SBBASE_BANK_ENABLE);
+}
+
 struct uniphier_boot_device_info {
 	unsigned int soc_id;
 	unsigned int boot_device_sel_shift;
diff --git a/arch/arm/mach-uniphier/init.h b/arch/arm/mach-uniphier/init.h
index 6223037..dd978c0 100644
--- a/arch/arm/mach-uniphier/init.h
+++ b/arch/arm/mach-uniphier/init.h
@@ -34,34 +34,6 @@
 int uniphier_pro5_init(const struct uniphier_board_data *bd);
 int uniphier_pxs2_init(const struct uniphier_board_data *bd);
 
-#if defined(CONFIG_MICRO_SUPPORT_CARD)
-void uniphier_sbc_init_admulti(void);
-void uniphier_sbc_init_savepin(void);
-void uniphier_ld4_sbc_init(void);
-void uniphier_pxs2_sbc_init(void);
-void uniphier_ld11_sbc_init(void);
-#else
-static inline void uniphier_sbc_init_admulti(void)
-{
-}
-
-static inline void uniphier_sbc_init_savepin(void)
-{
-}
-
-static inline void uniphier_ld4_sbc_init(void)
-{
-}
-
-static inline void uniphier_pxs2_sbc_init(void)
-{
-}
-
-static inline void uniphier_ld11_sbc_init(void)
-{
-}
-#endif
-
 void uniphier_ld4_bcu_init(const struct uniphier_board_data *bd);
 
 int uniphier_memconf_2ch_init(const struct uniphier_board_data *bd);
@@ -103,13 +75,6 @@
 int uniphier_boot_from_backend(void);
 int uniphier_pin_init(const char *pinconfig_name);
 
-#ifdef CONFIG_NAND_DENALI
-void uniphier_nand_reset_assert(void);
-#else
-static inline void uniphier_nand_reset_assert(void)
-{
-}
-#endif
 #ifdef CONFIG_ARM64
 void uniphier_mem_map_init(unsigned long dram_base, unsigned long dram_size);
 #else
diff --git a/arch/arm/mach-uniphier/micro-support-card.c b/arch/arm/mach-uniphier/micro-support-card.c
index b09ec54..dbd156f 100644
--- a/arch/arm/mach-uniphier/micro-support-card.c
+++ b/arch/arm/mach-uniphier/micro-support-card.c
@@ -5,8 +5,7 @@
  *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
  */
 
-#include <config.h>
-#include <dm/of.h>
+#include <dm.h>
 #include <fdt_support.h>
 #include <linux/ctype.h>
 #include <linux/delay.h>
@@ -91,6 +90,17 @@
 
 void support_card_init(void)
 {
+	struct udevice *dev;
+	int ret;
+
+	/* The system bus must be initialized for access to the support card. */
+	ret = uclass_get_device_by_driver(UCLASS_SIMPLE_BUS,
+					  DM_GET_DRIVER(uniphier_system_bus_driver),
+					  &dev);
+	if (ret)
+		return;
+
+	/* Check DT to see if this board has the support card. */
 	support_card_detect();
 
 	if (!support_card_found)
@@ -107,102 +117,6 @@
 	support_card_show_revision();
 }
 
-#if defined(CONFIG_MTD_NOR_FLASH)
-
-#include <mtd/cfi_flash.h>
-
-struct memory_bank {
-	phys_addr_t base;
-	unsigned long size;
-};
-
-static int mem_is_flash(const struct memory_bank *mem)
-{
-	const int loop = 128;
-	u32 *scratch_addr;
-	u32 saved_value;
-	int ret = 1;
-	int i;
-
-	/* just in case, use the tail of the memory bank */
-	scratch_addr = map_physmem(mem->base + mem->size - sizeof(u32) * loop,
-				   sizeof(u32) * loop, MAP_NOCACHE);
-
-	for (i = 0; i < loop; i++, scratch_addr++) {
-		saved_value = readl(scratch_addr);
-		writel(~saved_value, scratch_addr);
-		if (readl(scratch_addr) != saved_value) {
-			/* We assume no memory or SRAM here. */
-			writel(saved_value, scratch_addr);
-			ret = 0;
-			break;
-		}
-	}
-
-	unmap_physmem(scratch_addr, MAP_NOCACHE);
-
-	return ret;
-}
-
-/* {address, size} */
-static const struct memory_bank memory_banks[] = {
-	{0x42000000, 0x01f00000},
-};
-
-static const struct memory_bank
-*flash_banks_list[CONFIG_SYS_MAX_FLASH_BANKS_DETECT];
-
-phys_addr_t cfi_flash_bank_addr(int i)
-{
-	return flash_banks_list[i]->base;
-}
-
-unsigned long cfi_flash_bank_size(int i)
-{
-	return flash_banks_list[i]->size;
-}
-
-static void detect_num_flash_banks(void)
-{
-	const struct memory_bank *memory_bank, *end;
-
-	cfi_flash_num_flash_banks = 0;
-
-	memory_bank = memory_banks;
-	end = memory_bank + ARRAY_SIZE(memory_banks);
-
-	for (; memory_bank < end; memory_bank++) {
-		if (cfi_flash_num_flash_banks >=
-		    CONFIG_SYS_MAX_FLASH_BANKS_DETECT)
-			break;
-
-		if (mem_is_flash(memory_bank)) {
-			flash_banks_list[cfi_flash_num_flash_banks] =
-								memory_bank;
-
-			debug("flash bank found: base = 0x%lx, size = 0x%lx\n",
-			      (unsigned long)memory_bank->base,
-			      (unsigned long)memory_bank->size);
-			cfi_flash_num_flash_banks++;
-		}
-	}
-
-	debug("number of flash banks: %d\n", cfi_flash_num_flash_banks);
-}
-#else /* CONFIG_MTD_NOR_FLASH */
-static void detect_num_flash_banks(void)
-{
-};
-#endif /* CONFIG_MTD_NOR_FLASH */
-
-void support_card_late_init(void)
-{
-	if (!support_card_found)
-		return;
-
-	detect_num_flash_banks();
-}
-
 static const u8 ledval_num[] = {
 	0x7e, /* 0 */
 	0x0c, /* 1 */
diff --git a/arch/arm/mach-uniphier/nand-reset.c b/arch/arm/mach-uniphier/nand-reset.c
deleted file mode 100644
index 11cadaa..0000000
--- a/arch/arm/mach-uniphier/nand-reset.c
+++ /dev/null
@@ -1,43 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0 or later
-/*
- * Copyright (C) 2020 Socionext Inc.
- *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
- */
-
-#include <linux/errno.h>
-#include <dm.h>
-#include <dm/uclass-internal.h>
-#include <reset.h>
-
-#include "init.h"
-
-/*
- * Assert the Denali NAND controller reset if found.
- *
- * On LD4, the bootstrap process starts running after power-on reset regardless
- * of the boot mode, here the pin-mux is not necessarily set up for NAND, then
- * the controller is stuck. Assert the controller reset here, and should be
- * deasserted in the driver after the pin-mux is correctly handled. For other
- * SoCs, the bootstrap runs only when the boot mode selects ONFi, but it is yet
- * effective when the boot swap is on. So, the reset should be asserted anyway.
- */
-void uniphier_nand_reset_assert(void)
-{
-	struct udevice *dev;
-	struct reset_ctl_bulk resets;
-	int ret;
-
-	ret = uclass_find_first_device(UCLASS_MTD, &dev);
-	if (ret || !dev)
-		return;
-
-	/* make sure this is the Denali NAND controller */
-	if (strcmp(dev->driver->name, "denali-nand-dt"))
-		return;
-
-	ret = reset_get_bulk(dev, &resets);
-	if (ret)
-		return;
-
-	reset_assert_bulk(&resets);
-}
diff --git a/arch/arm/mach-uniphier/sbc/Makefile b/arch/arm/mach-uniphier/sbc/Makefile
deleted file mode 100644
index 6c698a3..0000000
--- a/arch/arm/mach-uniphier/sbc/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0+
-
-obj-y					+= sbc-boot.o
-
-ifndef CONFIG_SPL_BUILD
-obj-y					+= sbc.o
-
-obj-$(CONFIG_ARCH_UNIPHIER_LD4)		+= sbc-ld4.o
-obj-$(CONFIG_ARCH_UNIPHIER_SLD8)	+= sbc-ld4.o
-obj-$(CONFIG_ARCH_UNIPHIER_PXS2)	+= sbc-pxs2.o
-obj-$(CONFIG_ARCH_UNIPHIER_LD6B)	+= sbc-pxs2.o
-obj-$(CONFIG_ARCH_UNIPHIER_LD11)	+= sbc-ld11.o
-obj-$(CONFIG_ARCH_UNIPHIER_LD20)	+= sbc-ld11.o
-obj-$(CONFIG_ARCH_UNIPHIER_PXS3)	+= sbc-pxs2.o
-endif
diff --git a/arch/arm/mach-uniphier/sbc/sbc-boot.c b/arch/arm/mach-uniphier/sbc/sbc-boot.c
deleted file mode 100644
index ec22b45..0000000
--- a/arch/arm/mach-uniphier/sbc/sbc-boot.c
+++ /dev/null
@@ -1,13 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-//
-// Copyright (C) 2011-2014 Panasonic Corporation
-// Copyright (C) 2015-2019 Socionext Inc.
-
-#include <linux/io.h>
-
-#include "sbc-regs.h"
-
-int uniphier_sbc_boot_is_swapped(void)
-{
-	return !(readl(SBBASE0) & SBBASE_BANK_ENABLE);
-}
diff --git a/arch/arm/mach-uniphier/sbc/sbc-ld11.c b/arch/arm/mach-uniphier/sbc/sbc-ld11.c
deleted file mode 100644
index a0162e1..0000000
--- a/arch/arm/mach-uniphier/sbc/sbc-ld11.c
+++ /dev/null
@@ -1,26 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright (C) 2016-2017 Socionext Inc.
- */
-
-#include <spl.h>
-#include <linux/io.h>
-
-#include "../init.h"
-#include "sbc-regs.h"
-
-void uniphier_ld11_sbc_init(void)
-{
-	if (!uniphier_sbc_is_enabled())
-		return;
-
-	uniphier_sbc_init_savepin();
-
-	/* necessary for ROM boot ?? */
-	/* system bus output enable */
-	writel(0x17, PC0CTRL);
-
-	/* pins for NAND and System Bus are multiplexed */
-	if (spl_boot_device() != BOOT_DEVICE_NAND)
-		uniphier_pin_init("system-bus");
-}
diff --git a/arch/arm/mach-uniphier/sbc/sbc-ld4.c b/arch/arm/mach-uniphier/sbc/sbc-ld4.c
deleted file mode 100644
index 72e9743..0000000
--- a/arch/arm/mach-uniphier/sbc/sbc-ld4.c
+++ /dev/null
@@ -1,25 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright (C) 2011-2015 Panasonic Corporation
- * Copyright (C) 2015-2017 Socionext Inc.
- */
-
-#include <linux/io.h>
-
-#include "../init.h"
-#include "sbc-regs.h"
-
-void uniphier_ld4_sbc_init(void)
-{
-	u32 tmp;
-
-	if (!uniphier_sbc_is_enabled())
-		return;
-
-	uniphier_sbc_init_savepin();
-
-	/* system bus output enable */
-	tmp = readl(PC0CTRL);
-	tmp &= 0xfffffcff;
-	writel(tmp, PC0CTRL);
-}
diff --git a/arch/arm/mach-uniphier/sbc/sbc-pxs2.c b/arch/arm/mach-uniphier/sbc/sbc-pxs2.c
deleted file mode 100644
index 3275f22..0000000
--- a/arch/arm/mach-uniphier/sbc/sbc-pxs2.c
+++ /dev/null
@@ -1,23 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright (C) 2016-2017 Socionext Inc.
- */
-
-#include <linux/io.h>
-
-#include "../init.h"
-#include "sbc-regs.h"
-
-void uniphier_pxs2_sbc_init(void)
-{
-	if (!uniphier_sbc_is_enabled())
-		return;
-
-	uniphier_sbc_init_savepin();
-
-	/* necessary for ROM boot ?? */
-	/* system bus output enable */
-	writel(0x17, PC0CTRL);
-
-	uniphier_pin_init("system-bus");	/* PXs3 */
-}
diff --git a/arch/arm/mach-uniphier/sbc/sbc-regs.h b/arch/arm/mach-uniphier/sbc/sbc-regs.h
deleted file mode 100644
index 1e96186..0000000
--- a/arch/arm/mach-uniphier/sbc/sbc-regs.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * UniPhier SBC (System Bus Controller) registers
- *
- * Copyright (C) 2011-2014 Panasonic Corporation
- * Copyright (C) 2015-2016 Socionext Inc.
- */
-
-#ifndef ARCH_SBC_REGS_H
-#define ARCH_SBC_REGS_H
-
-#define	SBBASE_BASE		0x58c00100
-#define	SBBASE(x)		(SBBASE_BASE + (x) * 0x10)
-
-#define	SBBASE0			(SBBASE(0))
-#define	SBBASE1			(SBBASE(1))
-#define	SBBASE2			(SBBASE(2))
-#define	SBBASE3			(SBBASE(3))
-#define	SBBASE4			(SBBASE(4))
-#define	SBBASE5			(SBBASE(5))
-#define	SBBASE6			(SBBASE(6))
-#define	SBBASE7			(SBBASE(7))
-
-#define	SBBASE_BANK_ENABLE	(0x00000001)
-
-#define	SBCTRL_BASE		0x58c00200
-#define	SBCTRL(x, y)		(SBCTRL_BASE + (x) * 0x10 + (y) * 4)
-
-#define	SBCTRL00		SBCTRL(0, 0)
-#define	SBCTRL01		SBCTRL(0, 1)
-#define	SBCTRL02		SBCTRL(0, 2)
-#define	SBCTRL03		SBCTRL(0, 3)
-#define	SBCTRL04		(SBCTRL_BASE + 0x100)
-
-#define	SBCTRL10		SBCTRL(1, 0)
-#define	SBCTRL11		SBCTRL(1, 1)
-#define	SBCTRL12		SBCTRL(1, 2)
-#define	SBCTRL13		SBCTRL(1, 3)
-#define	SBCTRL14		(SBCTRL_BASE + 0x110)
-
-#define	SBCTRL20		SBCTRL(2, 0)
-#define	SBCTRL21		SBCTRL(2, 1)
-#define	SBCTRL22		SBCTRL(2, 2)
-#define	SBCTRL23		SBCTRL(2, 3)
-#define	SBCTRL24		(SBCTRL_BASE + 0x120)
-
-#define	SBCTRL30		SBCTRL(3, 0)
-#define	SBCTRL31		SBCTRL(3, 1)
-#define	SBCTRL32		SBCTRL(3, 2)
-#define	SBCTRL33		SBCTRL(3, 3)
-#define	SBCTRL34		(SBCTRL_BASE + 0x130)
-
-#define	SBCTRL40		SBCTRL(4, 0)
-#define	SBCTRL41		SBCTRL(4, 1)
-#define	SBCTRL42		SBCTRL(4, 2)
-#define	SBCTRL43		SBCTRL(4, 3)
-#define	SBCTRL44		(SBCTRL_BASE + 0x140)
-
-#define	SBCTRL50		SBCTRL(5, 0)
-#define	SBCTRL51		SBCTRL(5, 1)
-#define	SBCTRL52		SBCTRL(5, 2)
-#define	SBCTRL53		SBCTRL(5, 3)
-#define	SBCTRL54		(SBCTRL_BASE + 0x150)
-
-#define	SBCTRL60		SBCTRL(6, 0)
-#define	SBCTRL61		SBCTRL(6, 1)
-#define	SBCTRL62		SBCTRL(6, 2)
-#define	SBCTRL63		SBCTRL(6, 3)
-#define	SBCTRL64		(SBCTRL_BASE + 0x160)
-
-#define	SBCTRL70		SBCTRL(7, 0)
-#define	SBCTRL71		SBCTRL(7, 1)
-#define	SBCTRL72		SBCTRL(7, 2)
-#define	SBCTRL73		SBCTRL(7, 3)
-#define	SBCTRL74		(SBCTRL_BASE + 0x170)
-
-#define PC0CTRL				0x598000c0
-
-int uniphier_sbc_boot_is_swapped(void);
-int uniphier_sbc_is_enabled(void);
-
-#endif	/* ARCH_SBC_REGS_H */
diff --git a/arch/arm/mach-uniphier/sbc/sbc.c b/arch/arm/mach-uniphier/sbc/sbc.c
deleted file mode 100644
index 2100f49..0000000
--- a/arch/arm/mach-uniphier/sbc/sbc.c
+++ /dev/null
@@ -1,95 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright (C) 2011-2015 Panasonic Corporation
- * Copyright (C) 2015-2017 Socionext Inc.
- *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
- */
-
-#include <linux/io.h>
-#include <asm/global_data.h>
-
-#include "../init.h"
-#include "sbc-regs.h"
-
-#define SBCTRL0_ADMULTIPLX_PERI_VALUE	0x33120000
-#define SBCTRL1_ADMULTIPLX_PERI_VALUE	0x03005500
-#define SBCTRL2_ADMULTIPLX_PERI_VALUE	0x14000020
-
-#define SBCTRL0_ADMULTIPLX_MEM_VALUE	0x33120000
-#define SBCTRL1_ADMULTIPLX_MEM_VALUE	0x03005500
-#define SBCTRL2_ADMULTIPLX_MEM_VALUE	0x14000010
-
-/* slower but LED works */
-#define SBCTRL0_SAVEPIN_PERI_VALUE	0x55450000
-#define SBCTRL1_SAVEPIN_PERI_VALUE	0x07168d00
-#define SBCTRL2_SAVEPIN_PERI_VALUE	0x34000009
-#define SBCTRL4_SAVEPIN_PERI_VALUE	0x02110110
-
-/* faster but LED does not work */
-#define SBCTRL0_SAVEPIN_MEM_VALUE	0x55450000
-#define SBCTRL1_SAVEPIN_MEM_VALUE	0x06057700
-/* NOR flash needs more wait counts than SRAM */
-#define SBCTRL2_SAVEPIN_MEM_VALUE	0x34000009
-#define SBCTRL4_SAVEPIN_MEM_VALUE	0x02110210
-
-int uniphier_sbc_is_enabled(void)
-{
-	DECLARE_GLOBAL_DATA_PTR;
-	const void *fdt = gd->fdt_blob;
-	int offset;
-
-	offset = fdt_node_offset_by_compatible(fdt, 0,
-					       "socionext,uniphier-system-bus");
-	if (offset < 0)
-		return 0;
-
-	return fdtdec_get_is_enabled(fdt, offset);
-}
-
-static void __uniphier_sbc_init(int savepin)
-{
-	/*
-	 * Only CS1 is connected to support card.
-	 * BKSZ[1:0] should be set to "01".
-	 */
-	if (savepin) {
-		writel(SBCTRL0_SAVEPIN_PERI_VALUE, SBCTRL10);
-		writel(SBCTRL1_SAVEPIN_PERI_VALUE, SBCTRL11);
-		writel(SBCTRL2_SAVEPIN_PERI_VALUE, SBCTRL12);
-		writel(SBCTRL4_SAVEPIN_PERI_VALUE, SBCTRL14);
-	} else {
-		writel(SBCTRL0_ADMULTIPLX_MEM_VALUE, SBCTRL10);
-		writel(SBCTRL1_ADMULTIPLX_MEM_VALUE, SBCTRL11);
-		writel(SBCTRL2_ADMULTIPLX_MEM_VALUE, SBCTRL12);
-	}
-
-	if (uniphier_sbc_boot_is_swapped()) {
-		/*
-		 * Boot Swap On: boot from external NOR/SRAM
-		 * 0x42000000-0x43ffffff is a mirror of 0x40000000-0x41ffffff.
-		 *
-		 * 0x40000000-0x41efffff, 0x42000000-0x43efffff: memory bank
-		 * 0x41f00000-0x41ffffff, 0x43f00000-0x43ffffff: peripherals
-		 */
-		writel(0x0000bc01, SBBASE0);
-	} else {
-		/*
-		 * Boot Swap Off: boot from mask ROM
-		 * 0x40000000-0x41ffffff: mask ROM
-		 * 0x42000000-0x43efffff: memory bank (31MB)
-		 * 0x43f00000-0x43ffffff: peripherals (1MB)
-		 */
-		writel(0x0000be01, SBBASE0); /* dummy */
-		writel(0x0200be01, SBBASE1);
-	}
-}
-
-void uniphier_sbc_init_admulti(void)
-{
-	__uniphier_sbc_init(0);
-}
-
-void uniphier_sbc_init_savepin(void)
-{
-	__uniphier_sbc_init(1);
-}
diff --git a/arch/sandbox/Kconfig b/arch/sandbox/Kconfig
index 2a08533..65f988e 100644
--- a/arch/sandbox/Kconfig
+++ b/arch/sandbox/Kconfig
@@ -15,6 +15,16 @@
 	select PHYS_64BIT
 	select HOST_64BIT
 
+config SANDBOX_RAM_SIZE_MB
+	int "RAM size in MiB"
+	default 128
+	range 64 4095 if !SANDBOX64
+	range 64 268435456 if SANDBOX64
+	help
+	  Memory size of the sandbox in MiB. The default value is 128 MiB.
+	  The minimum value is 64 MiB. The maximum value is 4095 MiB for the
+	  32bit sandbox.
+
 config SANDBOX_SPL
 	bool "Enable SPL for sandbox"
 	select SUPPORT_SPL
diff --git a/arch/sandbox/cpu/state.c b/arch/sandbox/cpu/state.c
index 1f79412..34b6fff 100644
--- a/arch/sandbox/cpu/state.c
+++ b/arch/sandbox/cpu/state.c
@@ -378,7 +378,10 @@
 
 	state->ram_size = CONFIG_SYS_SDRAM_SIZE;
 	state->ram_buf = os_malloc(state->ram_size);
-	assert(state->ram_buf);
+	if (!state->ram_buf) {
+		printf("Out of memory\n");
+		os_exit(1);
+	}
 
 	state_reset_for_test(state);
 	/*
diff --git a/arch/sandbox/cpu/u-boot-spl.lds b/arch/sandbox/cpu/u-boot-spl.lds
index de65b01..c60eb10 100644
--- a/arch/sandbox/cpu/u-boot-spl.lds
+++ b/arch/sandbox/cpu/u-boot-spl.lds
@@ -20,4 +20,4 @@
 	__bss_start = .;
 }
 
-INSERT BEFORE .data;
+INSERT AFTER .data;
diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h
index 705645d..1bfad30 100644
--- a/arch/sandbox/include/asm/state.h
+++ b/arch/sandbox/include/asm/state.h
@@ -73,7 +73,7 @@
 	char **argv;			/* Command line arguments */
 	const char *jumped_fname;	/* Jumped from previous U_Boot */
 	uint8_t *ram_buf;		/* Emulated RAM buffer */
-	unsigned int ram_size;		/* Size of RAM buffer */
+	unsigned long ram_size;		/* Size of RAM buffer */
 	const char *ram_buf_fname;	/* Filename to use for RAM buffer */
 	bool ram_buf_rm;		/* Remove RAM buffer file after read */
 	bool write_ram_buf;		/* Write RAM buffer on exit */
diff --git a/arch/x86/cpu/apollolake/Makefile b/arch/x86/cpu/apollolake/Makefile
index 1162125..3aa2a55 100644
--- a/arch/x86/cpu/apollolake/Makefile
+++ b/arch/x86/cpu/apollolake/Makefile
@@ -3,6 +3,7 @@
 # Copyright 2019 Google LLC
 
 obj-$(CONFIG_SPL_BUILD) += cpu_spl.o
+obj-$(CONFIG_SPL_BUILD) += spl.o
 obj-$(CONFIG_SPL_BUILD) += systemagent.o
 obj-y += cpu_common.o
 
@@ -11,7 +12,6 @@
 obj-y += punit.o
 obj-y += fsp_bindings.o
 ifdef CONFIG_SPL_BUILD
-obj-y += spl.o
 obj-y += fsp_m.o
 endif
 endif
diff --git a/arch/x86/cpu/i386/cpu.c b/arch/x86/cpu/i386/cpu.c
index 435e50e..d27324c 100644
--- a/arch/x86/cpu/i386/cpu.c
+++ b/arch/x86/cpu/i386/cpu.c
@@ -363,6 +363,11 @@
 	: : "i" (em_rst), "i" (mp_ne_set) : "eax");
 }
 
+void cpu_reinit_fpu(void)
+{
+	asm ("fninit\n");
+}
+
 static void setup_identity(void)
 {
 	/* identify CPU via cpuid and store the decoded info into gd->arch */
diff --git a/arch/x86/include/asm/u-boot-x86.h b/arch/x86/include/asm/u-boot-x86.h
index 3e5d56d..bd3f440 100644
--- a/arch/x86/include/asm/u-boot-x86.h
+++ b/arch/x86/include/asm/u-boot-x86.h
@@ -43,6 +43,14 @@
  */
 int x86_cpu_init_tpl(void);
 
+/**
+ * cpu_reinit_fpu() - Reinit the FPU if something is wrong with it
+ *
+ * The FSP-M code can leave registers in use in the FPU. This functions reinits
+ * it so that the FPU can be used safely
+ */
+void cpu_reinit_fpu(void);
+
 int cpu_init_f(void);
 void setup_gdt(struct global_data *id, u64 *gdt_addr);
 /*
diff --git a/arch/x86/lib/fsp/fsp_graphics.c b/arch/x86/lib/fsp/fsp_graphics.c
index 6e23f3c..e8c1e07 100644
--- a/arch/x86/lib/fsp/fsp_graphics.c
+++ b/arch/x86/lib/fsp/fsp_graphics.c
@@ -117,6 +117,16 @@
 	return ret;
 }
 
+static int fsp_video_bind(struct udevice *dev)
+{
+	struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
+
+	/* Set the maximum supported resolution */
+	plat->size = 2560 * 1600 * 4;
+
+	return 0;
+}
+
 static const struct udevice_id fsp_video_ids[] = {
 	{ .compatible = "fsp-fb" },
 	{ }
@@ -126,7 +136,9 @@
 	.name	= "fsp_video",
 	.id	= UCLASS_VIDEO,
 	.of_match = fsp_video_ids,
+	.bind	= fsp_video_bind,
 	.probe	= fsp_video_probe,
+	.flags	= DM_FLAG_PRE_RELOC,
 };
 
 static struct pci_device_id fsp_video_supported[] = {
diff --git a/arch/x86/lib/fsp2/fsp_meminit.c b/arch/x86/lib/fsp2/fsp_meminit.c
index 1a75814..faf9c29 100644
--- a/arch/x86/lib/fsp2/fsp_meminit.c
+++ b/arch/x86/lib/fsp2/fsp_meminit.c
@@ -85,6 +85,7 @@
 	func = (fsp_memory_init_func)(hdr->img_base + hdr->fsp_mem_init);
 	ret = func(&upd, &hob);
 	bootstage_accum(BOOTSTAGE_ID_ACCUM_FSP_M);
+	cpu_reinit_fpu();
 	if (ret)
 		return log_msg_ret("SDRAM init fail\n", ret);
 
diff --git a/board/davinci/da8xxevm/omapl138_lcdk.c b/board/davinci/da8xxevm/omapl138_lcdk.c
index 84603cb..b60c83b 100644
--- a/board/davinci/da8xxevm/omapl138_lcdk.c
+++ b/board/davinci/da8xxevm/omapl138_lcdk.c
@@ -380,7 +380,7 @@
 	},
 };
 U_BOOT_DEVICE(omapl138_mmc) = {
-	.name = "davinci_mmc",
+	.name = "ti_da830_mmc",
 	.platdata = &mmc_platdata,
 };
 
diff --git a/board/sandbox/sandbox.c b/board/sandbox/sandbox.c
index 1372003..bd39109 100644
--- a/board/sandbox/sandbox.c
+++ b/board/sandbox/sandbox.c
@@ -22,7 +22,7 @@
 
 /* Add a simple GPIO device */
 U_BOOT_DEVICE(gpio_sandbox) = {
-	.name = "gpio_sandbox",
+	.name = "sandbox_gpio",
 };
 
 void flush_cache(unsigned long start, unsigned long size)
diff --git a/cmd/fdt.c b/cmd/fdt.c
index 99b1b5b..89ab572 100644
--- a/cmd/fdt.c
+++ b/cmd/fdt.c
@@ -21,7 +21,6 @@
 
 #define MAX_LEVEL	32		/* how deeply nested we will go */
 #define SCRATCHPAD	1024		/* bytes of scratchpad memory */
-#define CMD_FDT_MAX_DUMP 64
 
 /*
  * Global data (for the gd->bd)
@@ -934,11 +933,17 @@
 static void print_data(const void *data, int len)
 {
 	int j;
+	const char *env_max_dump;
+	ulong max_dump = ULONG_MAX;
 
 	/* no data, don't print */
 	if (len == 0)
 		return;
 
+	env_max_dump = env_get("fdt_max_dump");
+	if (env_max_dump)
+		max_dump = simple_strtoul(env_max_dump, NULL, 16);
+
 	/*
 	 * It is a string, but it may have multiple strings (embedded '\0's).
 	 */
@@ -957,7 +962,7 @@
 	}
 
 	if ((len %4) == 0) {
-		if (len > CMD_FDT_MAX_DUMP)
+		if (len > max_dump)
 			printf("* 0x%p [0x%08x]", data, len);
 		else {
 			const __be32 *p;
@@ -969,7 +974,7 @@
 			printf(">");
 		}
 	} else { /* anything else... hexdump */
-		if (len > CMD_FDT_MAX_DUMP)
+		if (len > max_dump)
 			printf("* 0x%p [0x%08x]", data, len);
 		else {
 			const u8 *s;
diff --git a/cmd/log.c b/cmd/log.c
index 78352b2..6afe6ea 100644
--- a/cmd/log.c
+++ b/cmd/log.c
@@ -39,7 +39,7 @@
 		const char *str = argv[1];
 
 		if (!strcmp(str, "default")) {
-			gd->log_fmt = LOGF_DEFAULT;
+			gd->log_fmt = log_get_default_format();
 		} else if (!strcmp(str, "all")) {
 			gd->log_fmt = LOGF_ALL;
 		} else {
@@ -139,7 +139,7 @@
 	"log format <fmt> - set log output format. <fmt> is a string where\n"
 	"\teach letter indicates something that should be displayed:\n"
 	"\tc=category, l=level, F=file, L=line number, f=function, m=msg\n"
-	"\tor 'default', equivalent to 'fm', or 'all' for all\n"
+	"\tor 'default', or 'all' for all\n"
 	"log rec <category> <level> <file> <line> <func> <message> - "
 		"output a log record"
 	;
diff --git a/common/Kconfig b/common/Kconfig
index 7872bc4..67b3818 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -699,6 +699,24 @@
 	  log message is shown - other details like level, category, file and
 	  line number are omitted.
 
+config LOGF_FILE
+	bool "Show source file name in log messages by default"
+	help
+	  Show the source file name in log messages by default. This value
+	  can be overridden using the 'log format' command.
+
+config LOGF_LINE
+	bool "Show source line number in log messages by default"
+	help
+	  Show the source line number in log messages by default. This value
+	  can be overridden using the 'log format' command.
+
+config LOGF_FUNC
+	bool "Show function name in log messages by default"
+	help
+	  Show the function name in log messages by default. This value can
+	  be overridden using the 'log format' command.
+
 config LOG_SYSLOG
 	bool "Log output to syslog server"
 	depends on NET
diff --git a/common/console.c b/common/console.c
index 7b98169..07c483f 100644
--- a/common/console.c
+++ b/common/console.c
@@ -229,18 +229,34 @@
 	}
 }
 
-static void console_puts_noserial(int file, const char *s)
+/**
+ * console_puts_select() - Output a string to all console devices
+ *
+ * @file: File number to output to (e,g, stdout, see stdio.h)
+ * @serial_only: true to output only to serial, false to output to everything
+ *	else
+ * @s: String to output
+ */
+static void console_puts_select(int file, bool serial_only, const char *s)
 {
 	int i;
 	struct stdio_dev *dev;
 
 	for (i = 0; i < cd_count[file]; i++) {
+		bool is_serial;
+
 		dev = console_devices[file][i];
-		if (dev->puts != NULL && !console_dev_is_serial(dev))
+		is_serial = console_dev_is_serial(dev);
+		if (dev->puts && serial_only == is_serial)
 			dev->puts(dev, s);
 	}
 }
 
+void console_puts_select_stderr(bool serial_only, const char *s)
+{
+	console_puts_select(stderr, serial_only, s);
+}
+
 static void console_puts(int file, const char *s)
 {
 	int i;
@@ -275,9 +291,9 @@
 	stdio_devices[file]->putc(stdio_devices[file], c);
 }
 
-static inline void console_puts_noserial(int file, const char *s)
+void console_puts_select(int file, bool serial_only, const char *s)
 {
-	if (!console_dev_is_serial(stdio_devices[file]))
+	if (serial_only == console_dev_is_serial(stdio_devices[file]))
 		stdio_devices[file]->puts(stdio_devices[file], s);
 }
 
@@ -489,7 +505,7 @@
 		puts(buf_out);
 		break;
 	case PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL:
-		console_puts_noserial(stdout, buf_out);
+		console_puts_select(stdout, false, buf_out);
 		break;
 	}
 }
@@ -776,7 +792,7 @@
 
 	display_options_get_banner(false, buf, sizeof(buf));
 
-	console_puts_noserial(stdout, buf);
+	console_puts_select(stdout, false, buf);
 #endif
 
 	return 0;
diff --git a/common/log.c b/common/log.c
index c5b9b48..734d26d 100644
--- a/common/log.c
+++ b/common/log.c
@@ -45,7 +45,11 @@
 	if (cat >= LOGC_NONE)
 		return log_cat_name[cat - LOGC_NONE];
 
+#if CONFIG_IS_ENABLED(DM)
 	name = uclass_get_name((enum uclass_id)cat);
+#else
+	name = NULL;
+#endif
 
 	return name ? name : "<missing>";
 }
@@ -317,7 +321,7 @@
 	gd->flags |= GD_FLG_LOG_READY;
 	if (!gd->default_log_level)
 		gd->default_log_level = CONFIG_LOG_DEFAULT_LEVEL;
-	gd->log_fmt = LOGF_DEFAULT;
+	gd->log_fmt = log_get_default_format();
 
 	return 0;
 }
diff --git a/common/log_console.c b/common/log_console.c
index 0b5b708..bb3f846 100644
--- a/common/log_console.c
+++ b/common/log_console.c
@@ -25,18 +25,18 @@
 	 *    - function is an identifier and ends with ()
 	 *    - message has a space before it unless it is on its own
 	 */
-	if (fmt & (1 << LOGF_LEVEL))
+	if (fmt & BIT(LOGF_LEVEL))
 		printf("%s.", log_get_level_name(rec->level));
-	if (fmt & (1 << LOGF_CAT))
+	if (fmt & BIT(LOGF_CAT))
 		printf("%s,", log_get_cat_name(rec->cat));
-	if (fmt & (1 << LOGF_FILE))
+	if (fmt & BIT(LOGF_FILE))
 		printf("%s:", rec->file);
-	if (fmt & (1 << LOGF_LINE))
+	if (fmt & BIT(LOGF_LINE))
 		printf("%d-", rec->line);
-	if (fmt & (1 << LOGF_FUNC))
+	if (fmt & BIT(LOGF_FUNC))
 		printf("%s()", rec->func);
-	if (fmt & (1 << LOGF_MSG))
-		printf("%s%s", fmt != (1 << LOGF_MSG) ? " " : "", rec->msg);
+	if (fmt & BIT(LOGF_MSG))
+		printf("%s%s", fmt != BIT(LOGF_MSG) ? " " : "", rec->msg);
 
 	return 0;
 }
diff --git a/common/log_syslog.c b/common/log_syslog.c
index 698c585..149ff5a 100644
--- a/common/log_syslog.c
+++ b/common/log_syslog.c
@@ -82,21 +82,21 @@
 	if (log_hostname)
 		append(&ptr, msg_end, "%s ", log_hostname);
 	append(&ptr, msg_end, "uboot: ");
-	if (fmt & (1 << LOGF_LEVEL))
+	if (fmt & BIT(LOGF_LEVEL))
 		append(&ptr, msg_end, "%s.",
 		       log_get_level_name(rec->level));
-	if (fmt & (1 << LOGF_CAT))
+	if (fmt & BIT(LOGF_CAT))
 		append(&ptr, msg_end, "%s,",
 		       log_get_cat_name(rec->cat));
-	if (fmt & (1 << LOGF_FILE))
+	if (fmt & BIT(LOGF_FILE))
 		append(&ptr, msg_end, "%s:", rec->file);
-	if (fmt & (1 << LOGF_LINE))
+	if (fmt & BIT(LOGF_LINE))
 		append(&ptr, msg_end, "%d-", rec->line);
-	if (fmt & (1 << LOGF_FUNC))
+	if (fmt & BIT(LOGF_FUNC))
 		append(&ptr, msg_end, "%s()", rec->func);
-	if (fmt & (1 << LOGF_MSG))
+	if (fmt & BIT(LOGF_MSG))
 		append(&ptr, msg_end, "%s%s",
-		       fmt != (1 << LOGF_MSG) ? " " : "", rec->msg);
+		       fmt != BIT(LOGF_MSG) ? " " : "", rec->msg);
 	/* Consider trailing 0x00 */
 	ptr++;
 
diff --git a/configs/Cyrus_P5020_defconfig b/configs/Cyrus_P5020_defconfig
index 19fc741..d7798ef 100644
--- a/configs/Cyrus_P5020_defconfig
+++ b/configs/Cyrus_P5020_defconfig
@@ -42,4 +42,6 @@
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
 CONFIG_USB_KEYBOARD=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
 CONFIG_OF_LIBFDT=y
diff --git a/configs/Cyrus_P5040_defconfig b/configs/Cyrus_P5040_defconfig
index 9c6919f..39191de 100644
--- a/configs/Cyrus_P5040_defconfig
+++ b/configs/Cyrus_P5040_defconfig
@@ -42,4 +42,6 @@
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
 CONFIG_USB_KEYBOARD=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
 CONFIG_OF_LIBFDT=y
diff --git a/configs/MPC8548CDS_36BIT_defconfig b/configs/MPC8548CDS_36BIT_defconfig
index 010e375..6884754 100644
--- a/configs/MPC8548CDS_36BIT_defconfig
+++ b/configs/MPC8548CDS_36BIT_defconfig
@@ -46,3 +46,4 @@
 CONFIG_PCIE_FSL=y
 CONFIG_CONS_INDEX=2
 CONFIG_SYS_NS16550=y
+CONFIG_ADDR_MAP=y
diff --git a/configs/MPC8572DS_36BIT_defconfig b/configs/MPC8572DS_36BIT_defconfig
index 50912bf..4053cb7 100644
--- a/configs/MPC8572DS_36BIT_defconfig
+++ b/configs/MPC8572DS_36BIT_defconfig
@@ -51,4 +51,5 @@
 CONFIG_USB_EHCI_PCI=y
 CONFIG_USB_STORAGE=y
 CONFIG_VIDEO=y
+CONFIG_ADDR_MAP=y
 CONFIG_OF_LIBFDT=y
diff --git a/configs/MPC8641HPCN_36BIT_defconfig b/configs/MPC8641HPCN_36BIT_defconfig
index 1e64367..c75e665 100644
--- a/configs/MPC8641HPCN_36BIT_defconfig
+++ b/configs/MPC8641HPCN_36BIT_defconfig
@@ -42,4 +42,6 @@
 CONFIG_USB=y
 CONFIG_USB_KEYBOARD=y
 CONFIG_VIDEO=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=8
 CONFIG_OF_LIBFDT=y
diff --git a/configs/MPC8641HPCN_defconfig b/configs/MPC8641HPCN_defconfig
index 7ce7891..b60813d 100644
--- a/configs/MPC8641HPCN_defconfig
+++ b/configs/MPC8641HPCN_defconfig
@@ -42,4 +42,6 @@
 CONFIG_USB=y
 CONFIG_USB_KEYBOARD=y
 CONFIG_VIDEO=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=8
 CONFIG_OF_LIBFDT=y
diff --git a/configs/P1010RDB-PA_36BIT_NAND_SECBOOT_defconfig b/configs/P1010RDB-PA_36BIT_NAND_SECBOOT_defconfig
index c104452..c406667 100644
--- a/configs/P1010RDB-PA_36BIT_NAND_SECBOOT_defconfig
+++ b/configs/P1010RDB-PA_36BIT_NAND_SECBOOT_defconfig
@@ -57,6 +57,7 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
 CONFIG_RSA=y
 CONFIG_SPL_RSA=y
 CONFIG_RSA_SOFTWARE_EXP=y
diff --git a/configs/P1010RDB-PA_36BIT_NAND_defconfig b/configs/P1010RDB-PA_36BIT_NAND_defconfig
index 86c90da..a5ffbda 100644
--- a/configs/P1010RDB-PA_36BIT_NAND_defconfig
+++ b/configs/P1010RDB-PA_36BIT_NAND_defconfig
@@ -83,3 +83,4 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
diff --git a/configs/P1010RDB-PA_36BIT_NOR_SECBOOT_defconfig b/configs/P1010RDB-PA_36BIT_NOR_SECBOOT_defconfig
index 723f6ca..c3cfaf1 100644
--- a/configs/P1010RDB-PA_36BIT_NOR_SECBOOT_defconfig
+++ b/configs/P1010RDB-PA_36BIT_NOR_SECBOOT_defconfig
@@ -56,6 +56,7 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
 CONFIG_RSA=y
 CONFIG_SPL_RSA=y
 CONFIG_RSA_SOFTWARE_EXP=y
diff --git a/configs/P1010RDB-PA_36BIT_NOR_defconfig b/configs/P1010RDB-PA_36BIT_NOR_defconfig
index e6edd39..5a2dcae 100644
--- a/configs/P1010RDB-PA_36BIT_NOR_defconfig
+++ b/configs/P1010RDB-PA_36BIT_NOR_defconfig
@@ -65,3 +65,4 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
diff --git a/configs/P1010RDB-PA_36BIT_SDCARD_defconfig b/configs/P1010RDB-PA_36BIT_SDCARD_defconfig
index 2850e30..c8c7bed 100644
--- a/configs/P1010RDB-PA_36BIT_SDCARD_defconfig
+++ b/configs/P1010RDB-PA_36BIT_SDCARD_defconfig
@@ -77,3 +77,4 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
diff --git a/configs/P1010RDB-PA_36BIT_SPIFLASH_SECBOOT_defconfig b/configs/P1010RDB-PA_36BIT_SPIFLASH_SECBOOT_defconfig
index 9987cde..8a13e3a 100644
--- a/configs/P1010RDB-PA_36BIT_SPIFLASH_SECBOOT_defconfig
+++ b/configs/P1010RDB-PA_36BIT_SPIFLASH_SECBOOT_defconfig
@@ -58,6 +58,7 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
 CONFIG_RSA=y
 CONFIG_SPL_RSA=y
 CONFIG_RSA_SOFTWARE_EXP=y
diff --git a/configs/P1010RDB-PA_36BIT_SPIFLASH_defconfig b/configs/P1010RDB-PA_36BIT_SPIFLASH_defconfig
index 98ad4b6..2aa476c 100644
--- a/configs/P1010RDB-PA_36BIT_SPIFLASH_defconfig
+++ b/configs/P1010RDB-PA_36BIT_SPIFLASH_defconfig
@@ -79,3 +79,4 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
diff --git a/configs/P1010RDB-PB_36BIT_NAND_SECBOOT_defconfig b/configs/P1010RDB-PB_36BIT_NAND_SECBOOT_defconfig
index 66bdebb..1f2e969 100644
--- a/configs/P1010RDB-PB_36BIT_NAND_SECBOOT_defconfig
+++ b/configs/P1010RDB-PB_36BIT_NAND_SECBOOT_defconfig
@@ -57,6 +57,7 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
 CONFIG_RSA=y
 CONFIG_SPL_RSA=y
 CONFIG_RSA_SOFTWARE_EXP=y
diff --git a/configs/P1010RDB-PB_36BIT_NAND_defconfig b/configs/P1010RDB-PB_36BIT_NAND_defconfig
index bd779aa..25fb606 100644
--- a/configs/P1010RDB-PB_36BIT_NAND_defconfig
+++ b/configs/P1010RDB-PB_36BIT_NAND_defconfig
@@ -83,3 +83,4 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
diff --git a/configs/P1010RDB-PB_36BIT_NOR_SECBOOT_defconfig b/configs/P1010RDB-PB_36BIT_NOR_SECBOOT_defconfig
index f2e4066..bbaec2b 100644
--- a/configs/P1010RDB-PB_36BIT_NOR_SECBOOT_defconfig
+++ b/configs/P1010RDB-PB_36BIT_NOR_SECBOOT_defconfig
@@ -56,6 +56,7 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
 CONFIG_RSA=y
 CONFIG_SPL_RSA=y
 CONFIG_RSA_SOFTWARE_EXP=y
diff --git a/configs/P1010RDB-PB_36BIT_NOR_defconfig b/configs/P1010RDB-PB_36BIT_NOR_defconfig
index e85af32..58f4430 100644
--- a/configs/P1010RDB-PB_36BIT_NOR_defconfig
+++ b/configs/P1010RDB-PB_36BIT_NOR_defconfig
@@ -65,3 +65,4 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
diff --git a/configs/P1010RDB-PB_36BIT_SDCARD_defconfig b/configs/P1010RDB-PB_36BIT_SDCARD_defconfig
index 8559ffe..137f613 100644
--- a/configs/P1010RDB-PB_36BIT_SDCARD_defconfig
+++ b/configs/P1010RDB-PB_36BIT_SDCARD_defconfig
@@ -77,3 +77,4 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
diff --git a/configs/P1010RDB-PB_36BIT_SPIFLASH_SECBOOT_defconfig b/configs/P1010RDB-PB_36BIT_SPIFLASH_SECBOOT_defconfig
index 50b5c5f..63ac2f2 100644
--- a/configs/P1010RDB-PB_36BIT_SPIFLASH_SECBOOT_defconfig
+++ b/configs/P1010RDB-PB_36BIT_SPIFLASH_SECBOOT_defconfig
@@ -58,6 +58,7 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
 CONFIG_RSA=y
 CONFIG_SPL_RSA=y
 CONFIG_RSA_SOFTWARE_EXP=y
diff --git a/configs/P1010RDB-PB_36BIT_SPIFLASH_defconfig b/configs/P1010RDB-PB_36BIT_SPIFLASH_defconfig
index fe503c1..493597e 100644
--- a/configs/P1010RDB-PB_36BIT_SPIFLASH_defconfig
+++ b/configs/P1010RDB-PB_36BIT_SPIFLASH_defconfig
@@ -79,3 +79,4 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
diff --git a/configs/P1020MBG-PC_36BIT_SDCARD_defconfig b/configs/P1020MBG-PC_36BIT_SDCARD_defconfig
index a9befd2..1178c27 100644
--- a/configs/P1020MBG-PC_36BIT_SDCARD_defconfig
+++ b/configs/P1020MBG-PC_36BIT_SDCARD_defconfig
@@ -64,4 +64,5 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
 CONFIG_OF_LIBFDT=y
diff --git a/configs/P1020MBG-PC_36BIT_defconfig b/configs/P1020MBG-PC_36BIT_defconfig
index 7930af3..2385da4 100644
--- a/configs/P1020MBG-PC_36BIT_defconfig
+++ b/configs/P1020MBG-PC_36BIT_defconfig
@@ -52,4 +52,5 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
 CONFIG_OF_LIBFDT=y
diff --git a/configs/P1020RDB-PC_36BIT_NAND_defconfig b/configs/P1020RDB-PC_36BIT_NAND_defconfig
index c148f4d..00f9fb5 100644
--- a/configs/P1020RDB-PC_36BIT_NAND_defconfig
+++ b/configs/P1020RDB-PC_36BIT_NAND_defconfig
@@ -83,3 +83,4 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
+CONFIG_ADDR_MAP=y
diff --git a/configs/P1020RDB-PC_36BIT_SDCARD_defconfig b/configs/P1020RDB-PC_36BIT_SDCARD_defconfig
index 7b40858..7ffac2e 100644
--- a/configs/P1020RDB-PC_36BIT_SDCARD_defconfig
+++ b/configs/P1020RDB-PC_36BIT_SDCARD_defconfig
@@ -78,3 +78,4 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
+CONFIG_ADDR_MAP=y
diff --git a/configs/P1020RDB-PC_36BIT_SPIFLASH_defconfig b/configs/P1020RDB-PC_36BIT_SPIFLASH_defconfig
index 7a7ae29..b8e5e33 100644
--- a/configs/P1020RDB-PC_36BIT_SPIFLASH_defconfig
+++ b/configs/P1020RDB-PC_36BIT_SPIFLASH_defconfig
@@ -80,3 +80,4 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
+CONFIG_ADDR_MAP=y
diff --git a/configs/P1020RDB-PC_36BIT_defconfig b/configs/P1020RDB-PC_36BIT_defconfig
index f9a4b73..850a152 100644
--- a/configs/P1020RDB-PC_36BIT_defconfig
+++ b/configs/P1020RDB-PC_36BIT_defconfig
@@ -67,3 +67,4 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
+CONFIG_ADDR_MAP=y
diff --git a/configs/P1020UTM-PC_36BIT_SDCARD_defconfig b/configs/P1020UTM-PC_36BIT_SDCARD_defconfig
index a24f14a..36bb136 100644
--- a/configs/P1020UTM-PC_36BIT_SDCARD_defconfig
+++ b/configs/P1020UTM-PC_36BIT_SDCARD_defconfig
@@ -64,4 +64,5 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
 CONFIG_OF_LIBFDT=y
diff --git a/configs/P1020UTM-PC_36BIT_defconfig b/configs/P1020UTM-PC_36BIT_defconfig
index 968d3ed..47232d9 100644
--- a/configs/P1020UTM-PC_36BIT_defconfig
+++ b/configs/P1020UTM-PC_36BIT_defconfig
@@ -52,4 +52,5 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
 CONFIG_OF_LIBFDT=y
diff --git a/configs/P1021RDB-PC_36BIT_NAND_defconfig b/configs/P1021RDB-PC_36BIT_NAND_defconfig
index 353f467..8732438 100644
--- a/configs/P1021RDB-PC_36BIT_NAND_defconfig
+++ b/configs/P1021RDB-PC_36BIT_NAND_defconfig
@@ -81,4 +81,5 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
 CONFIG_OF_LIBFDT=y
diff --git a/configs/P1021RDB-PC_36BIT_SDCARD_defconfig b/configs/P1021RDB-PC_36BIT_SDCARD_defconfig
index 62cbbc0..66c37f9 100644
--- a/configs/P1021RDB-PC_36BIT_SDCARD_defconfig
+++ b/configs/P1021RDB-PC_36BIT_SDCARD_defconfig
@@ -76,4 +76,5 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
 CONFIG_OF_LIBFDT=y
diff --git a/configs/P1021RDB-PC_36BIT_SPIFLASH_defconfig b/configs/P1021RDB-PC_36BIT_SPIFLASH_defconfig
index 7f71b52..eaf45a6 100644
--- a/configs/P1021RDB-PC_36BIT_SPIFLASH_defconfig
+++ b/configs/P1021RDB-PC_36BIT_SPIFLASH_defconfig
@@ -78,4 +78,5 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
 CONFIG_OF_LIBFDT=y
diff --git a/configs/P1021RDB-PC_36BIT_defconfig b/configs/P1021RDB-PC_36BIT_defconfig
index ca1be9c..608a6d1 100644
--- a/configs/P1021RDB-PC_36BIT_defconfig
+++ b/configs/P1021RDB-PC_36BIT_defconfig
@@ -64,4 +64,5 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
 CONFIG_OF_LIBFDT=y
diff --git a/configs/P1024RDB_36BIT_defconfig b/configs/P1024RDB_36BIT_defconfig
index 5116fac..bb016af 100644
--- a/configs/P1024RDB_36BIT_defconfig
+++ b/configs/P1024RDB_36BIT_defconfig
@@ -58,4 +58,5 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
 CONFIG_OF_LIBFDT=y
diff --git a/configs/P1025RDB_36BIT_defconfig b/configs/P1025RDB_36BIT_defconfig
index 8eaddb1..c096593 100644
--- a/configs/P1025RDB_36BIT_defconfig
+++ b/configs/P1025RDB_36BIT_defconfig
@@ -60,4 +60,5 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
 CONFIG_OF_LIBFDT=y
diff --git a/configs/P2020RDB-PC_36BIT_NAND_defconfig b/configs/P2020RDB-PC_36BIT_NAND_defconfig
index dff2afa..13f16ef 100644
--- a/configs/P2020RDB-PC_36BIT_NAND_defconfig
+++ b/configs/P2020RDB-PC_36BIT_NAND_defconfig
@@ -88,3 +88,4 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
+CONFIG_ADDR_MAP=y
diff --git a/configs/P2020RDB-PC_36BIT_SDCARD_defconfig b/configs/P2020RDB-PC_36BIT_SDCARD_defconfig
index 700fabe..c11c304 100644
--- a/configs/P2020RDB-PC_36BIT_SDCARD_defconfig
+++ b/configs/P2020RDB-PC_36BIT_SDCARD_defconfig
@@ -83,3 +83,4 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
+CONFIG_ADDR_MAP=y
diff --git a/configs/P2020RDB-PC_36BIT_SPIFLASH_defconfig b/configs/P2020RDB-PC_36BIT_SPIFLASH_defconfig
index 6b6ab7e..2ea28e7 100644
--- a/configs/P2020RDB-PC_36BIT_SPIFLASH_defconfig
+++ b/configs/P2020RDB-PC_36BIT_SPIFLASH_defconfig
@@ -85,3 +85,4 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
+CONFIG_ADDR_MAP=y
diff --git a/configs/P2020RDB-PC_36BIT_defconfig b/configs/P2020RDB-PC_36BIT_defconfig
index 88e24c3..1140177 100644
--- a/configs/P2020RDB-PC_36BIT_defconfig
+++ b/configs/P2020RDB-PC_36BIT_defconfig
@@ -72,3 +72,4 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
+CONFIG_ADDR_MAP=y
diff --git a/configs/P2041RDB_NAND_defconfig b/configs/P2041RDB_NAND_defconfig
index 4670d82..af48fc5 100644
--- a/configs/P2041RDB_NAND_defconfig
+++ b/configs/P2041RDB_NAND_defconfig
@@ -65,3 +65,5 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
diff --git a/configs/P2041RDB_SDCARD_defconfig b/configs/P2041RDB_SDCARD_defconfig
index dc23e10..0fa5caa 100644
--- a/configs/P2041RDB_SDCARD_defconfig
+++ b/configs/P2041RDB_SDCARD_defconfig
@@ -64,3 +64,5 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
diff --git a/configs/P2041RDB_SECURE_BOOT_defconfig b/configs/P2041RDB_SECURE_BOOT_defconfig
index 35a9d00..e1b2ee0 100644
--- a/configs/P2041RDB_SECURE_BOOT_defconfig
+++ b/configs/P2041RDB_SECURE_BOOT_defconfig
@@ -54,6 +54,8 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
 CONFIG_RSA=y
 CONFIG_SPL_RSA=y
 CONFIG_RSA_SOFTWARE_EXP=y
diff --git a/configs/P2041RDB_SPIFLASH_defconfig b/configs/P2041RDB_SPIFLASH_defconfig
index bf8d9a2..99611caf 100644
--- a/configs/P2041RDB_SPIFLASH_defconfig
+++ b/configs/P2041RDB_SPIFLASH_defconfig
@@ -65,3 +65,5 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
diff --git a/configs/P2041RDB_SRIO_PCIE_BOOT_defconfig b/configs/P2041RDB_SRIO_PCIE_BOOT_defconfig
index dd5f2a4..2832a86 100644
--- a/configs/P2041RDB_SRIO_PCIE_BOOT_defconfig
+++ b/configs/P2041RDB_SRIO_PCIE_BOOT_defconfig
@@ -47,4 +47,6 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
 CONFIG_OF_LIBFDT=y
diff --git a/configs/P2041RDB_defconfig b/configs/P2041RDB_defconfig
index bbf6ea6..cd05a7a 100644
--- a/configs/P2041RDB_defconfig
+++ b/configs/P2041RDB_defconfig
@@ -63,3 +63,5 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
diff --git a/configs/P3041DS_NAND_SECURE_BOOT_defconfig b/configs/P3041DS_NAND_SECURE_BOOT_defconfig
index 8ab2537..c14a05b 100644
--- a/configs/P3041DS_NAND_SECURE_BOOT_defconfig
+++ b/configs/P3041DS_NAND_SECURE_BOOT_defconfig
@@ -53,6 +53,8 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
 CONFIG_RSA=y
 CONFIG_SPL_RSA=y
 CONFIG_RSA_SOFTWARE_EXP=y
diff --git a/configs/P3041DS_NAND_defconfig b/configs/P3041DS_NAND_defconfig
index 55613cc..f774e1f 100644
--- a/configs/P3041DS_NAND_defconfig
+++ b/configs/P3041DS_NAND_defconfig
@@ -62,3 +62,5 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
diff --git a/configs/P3041DS_SDCARD_defconfig b/configs/P3041DS_SDCARD_defconfig
index b52068d..89678ea 100644
--- a/configs/P3041DS_SDCARD_defconfig
+++ b/configs/P3041DS_SDCARD_defconfig
@@ -61,3 +61,5 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
diff --git a/configs/P3041DS_SECURE_BOOT_defconfig b/configs/P3041DS_SECURE_BOOT_defconfig
index d6cabeb..afb1aec 100644
--- a/configs/P3041DS_SECURE_BOOT_defconfig
+++ b/configs/P3041DS_SECURE_BOOT_defconfig
@@ -51,6 +51,8 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
 CONFIG_RSA=y
 CONFIG_SPL_RSA=y
 CONFIG_RSA_SOFTWARE_EXP=y
diff --git a/configs/P3041DS_SPIFLASH_defconfig b/configs/P3041DS_SPIFLASH_defconfig
index 3af52b9..a5d881a 100644
--- a/configs/P3041DS_SPIFLASH_defconfig
+++ b/configs/P3041DS_SPIFLASH_defconfig
@@ -62,3 +62,5 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
diff --git a/configs/P3041DS_SRIO_PCIE_BOOT_defconfig b/configs/P3041DS_SRIO_PCIE_BOOT_defconfig
index c34311b..6c7b951 100644
--- a/configs/P3041DS_SRIO_PCIE_BOOT_defconfig
+++ b/configs/P3041DS_SRIO_PCIE_BOOT_defconfig
@@ -47,4 +47,6 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
 CONFIG_OF_LIBFDT=y
diff --git a/configs/P3041DS_defconfig b/configs/P3041DS_defconfig
index cc3234c..0a766c8 100644
--- a/configs/P3041DS_defconfig
+++ b/configs/P3041DS_defconfig
@@ -60,3 +60,5 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
diff --git a/configs/P4080DS_SDCARD_defconfig b/configs/P4080DS_SDCARD_defconfig
index 18ad56a..c0d184e 100644
--- a/configs/P4080DS_SDCARD_defconfig
+++ b/configs/P4080DS_SDCARD_defconfig
@@ -60,3 +60,5 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
diff --git a/configs/P4080DS_SECURE_BOOT_defconfig b/configs/P4080DS_SECURE_BOOT_defconfig
index 22a6ebe..e4d494b 100644
--- a/configs/P4080DS_SECURE_BOOT_defconfig
+++ b/configs/P4080DS_SECURE_BOOT_defconfig
@@ -50,6 +50,8 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
 CONFIG_RSA=y
 CONFIG_SPL_RSA=y
 CONFIG_RSA_SOFTWARE_EXP=y
diff --git a/configs/P4080DS_SPIFLASH_defconfig b/configs/P4080DS_SPIFLASH_defconfig
index 81a513b..f171d7c 100644
--- a/configs/P4080DS_SPIFLASH_defconfig
+++ b/configs/P4080DS_SPIFLASH_defconfig
@@ -61,3 +61,5 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
diff --git a/configs/P4080DS_SRIO_PCIE_BOOT_defconfig b/configs/P4080DS_SRIO_PCIE_BOOT_defconfig
index a740bc4..46aee4d 100644
--- a/configs/P4080DS_SRIO_PCIE_BOOT_defconfig
+++ b/configs/P4080DS_SRIO_PCIE_BOOT_defconfig
@@ -45,4 +45,6 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
 CONFIG_OF_LIBFDT=y
diff --git a/configs/P4080DS_defconfig b/configs/P4080DS_defconfig
index 52db2e0..2980020 100644
--- a/configs/P4080DS_defconfig
+++ b/configs/P4080DS_defconfig
@@ -59,3 +59,5 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
diff --git a/configs/P5020DS_NAND_SECURE_BOOT_defconfig b/configs/P5020DS_NAND_SECURE_BOOT_defconfig
index 52efa92..5f0c597 100644
--- a/configs/P5020DS_NAND_SECURE_BOOT_defconfig
+++ b/configs/P5020DS_NAND_SECURE_BOOT_defconfig
@@ -54,6 +54,8 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
 CONFIG_RSA=y
 CONFIG_SPL_RSA=y
 CONFIG_RSA_SOFTWARE_EXP=y
diff --git a/configs/P5020DS_NAND_defconfig b/configs/P5020DS_NAND_defconfig
index baf7d83..b711f3b 100644
--- a/configs/P5020DS_NAND_defconfig
+++ b/configs/P5020DS_NAND_defconfig
@@ -54,4 +54,6 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
 CONFIG_OF_LIBFDT=y
diff --git a/configs/P5020DS_SDCARD_defconfig b/configs/P5020DS_SDCARD_defconfig
index c5b4241..b459047 100644
--- a/configs/P5020DS_SDCARD_defconfig
+++ b/configs/P5020DS_SDCARD_defconfig
@@ -52,4 +52,6 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
 CONFIG_OF_LIBFDT=y
diff --git a/configs/P5020DS_SECURE_BOOT_defconfig b/configs/P5020DS_SECURE_BOOT_defconfig
index c08f9ff..79e8cc9 100644
--- a/configs/P5020DS_SECURE_BOOT_defconfig
+++ b/configs/P5020DS_SECURE_BOOT_defconfig
@@ -51,6 +51,8 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
 CONFIG_RSA=y
 CONFIG_SPL_RSA=y
 CONFIG_RSA_SOFTWARE_EXP=y
diff --git a/configs/P5020DS_SPIFLASH_defconfig b/configs/P5020DS_SPIFLASH_defconfig
index 03d7a16..3777c1d 100644
--- a/configs/P5020DS_SPIFLASH_defconfig
+++ b/configs/P5020DS_SPIFLASH_defconfig
@@ -53,4 +53,6 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
 CONFIG_OF_LIBFDT=y
diff --git a/configs/P5020DS_SRIO_PCIE_BOOT_defconfig b/configs/P5020DS_SRIO_PCIE_BOOT_defconfig
index 7569364..9b7cb68 100644
--- a/configs/P5020DS_SRIO_PCIE_BOOT_defconfig
+++ b/configs/P5020DS_SRIO_PCIE_BOOT_defconfig
@@ -47,4 +47,6 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
 CONFIG_OF_LIBFDT=y
diff --git a/configs/P5020DS_defconfig b/configs/P5020DS_defconfig
index a1b410c..77fcf26 100644
--- a/configs/P5020DS_defconfig
+++ b/configs/P5020DS_defconfig
@@ -51,4 +51,6 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
 CONFIG_OF_LIBFDT=y
diff --git a/configs/P5040DS_NAND_SECURE_BOOT_defconfig b/configs/P5040DS_NAND_SECURE_BOOT_defconfig
index beab855..782b027 100644
--- a/configs/P5040DS_NAND_SECURE_BOOT_defconfig
+++ b/configs/P5040DS_NAND_SECURE_BOOT_defconfig
@@ -54,6 +54,8 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
 CONFIG_RSA=y
 CONFIG_SPL_RSA=y
 CONFIG_RSA_SOFTWARE_EXP=y
diff --git a/configs/P5040DS_NAND_defconfig b/configs/P5040DS_NAND_defconfig
index efffb70..35584e2 100644
--- a/configs/P5040DS_NAND_defconfig
+++ b/configs/P5040DS_NAND_defconfig
@@ -63,3 +63,5 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
diff --git a/configs/P5040DS_SDCARD_defconfig b/configs/P5040DS_SDCARD_defconfig
index fdd39ac..91c0285 100644
--- a/configs/P5040DS_SDCARD_defconfig
+++ b/configs/P5040DS_SDCARD_defconfig
@@ -61,3 +61,5 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
diff --git a/configs/P5040DS_SECURE_BOOT_defconfig b/configs/P5040DS_SECURE_BOOT_defconfig
index 5d48206..34e024a 100644
--- a/configs/P5040DS_SECURE_BOOT_defconfig
+++ b/configs/P5040DS_SECURE_BOOT_defconfig
@@ -51,6 +51,8 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
 CONFIG_RSA=y
 CONFIG_SPL_RSA=y
 CONFIG_RSA_SOFTWARE_EXP=y
diff --git a/configs/P5040DS_SPIFLASH_defconfig b/configs/P5040DS_SPIFLASH_defconfig
index 3f4642f..49a2b93 100644
--- a/configs/P5040DS_SPIFLASH_defconfig
+++ b/configs/P5040DS_SPIFLASH_defconfig
@@ -62,3 +62,5 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
diff --git a/configs/P5040DS_defconfig b/configs/P5040DS_defconfig
index d2a2e02..a797088 100644
--- a/configs/P5040DS_defconfig
+++ b/configs/P5040DS_defconfig
@@ -60,3 +60,5 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
diff --git a/configs/T1023RDB_NAND_defconfig b/configs/T1023RDB_NAND_defconfig
index 385dcb3..2a544d7 100644
--- a/configs/T1023RDB_NAND_defconfig
+++ b/configs/T1023RDB_NAND_defconfig
@@ -74,4 +74,6 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
 CONFIG_OF_LIBFDT=y
diff --git a/configs/T1023RDB_SDCARD_defconfig b/configs/T1023RDB_SDCARD_defconfig
index 825ab47..641b392 100644
--- a/configs/T1023RDB_SDCARD_defconfig
+++ b/configs/T1023RDB_SDCARD_defconfig
@@ -71,4 +71,6 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
 CONFIG_OF_LIBFDT=y
diff --git a/configs/T1023RDB_SECURE_BOOT_defconfig b/configs/T1023RDB_SECURE_BOOT_defconfig
index 34fe6e5..a9c9794 100644
--- a/configs/T1023RDB_SECURE_BOOT_defconfig
+++ b/configs/T1023RDB_SECURE_BOOT_defconfig
@@ -58,6 +58,8 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
 CONFIG_RSA=y
 CONFIG_SPL_RSA=y
 CONFIG_RSA_SOFTWARE_EXP=y
diff --git a/configs/T1023RDB_SPIFLASH_defconfig b/configs/T1023RDB_SPIFLASH_defconfig
index d537047..e30695e 100644
--- a/configs/T1023RDB_SPIFLASH_defconfig
+++ b/configs/T1023RDB_SPIFLASH_defconfig
@@ -74,4 +74,6 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
 CONFIG_OF_LIBFDT=y
diff --git a/configs/T1023RDB_defconfig b/configs/T1023RDB_defconfig
index 62cc129..3366ff02 100644
--- a/configs/T1023RDB_defconfig
+++ b/configs/T1023RDB_defconfig
@@ -58,4 +58,6 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
 CONFIG_OF_LIBFDT=y
diff --git a/configs/T1024RDB_NAND_defconfig b/configs/T1024RDB_NAND_defconfig
index 0d38d66..2c5ae11 100644
--- a/configs/T1024RDB_NAND_defconfig
+++ b/configs/T1024RDB_NAND_defconfig
@@ -87,3 +87,5 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
diff --git a/configs/T1024RDB_SDCARD_defconfig b/configs/T1024RDB_SDCARD_defconfig
index d091d7c..f9bf5ac 100644
--- a/configs/T1024RDB_SDCARD_defconfig
+++ b/configs/T1024RDB_SDCARD_defconfig
@@ -84,3 +84,5 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
diff --git a/configs/T1024RDB_SECURE_BOOT_defconfig b/configs/T1024RDB_SECURE_BOOT_defconfig
index fe3d28b..bbcf145 100644
--- a/configs/T1024RDB_SECURE_BOOT_defconfig
+++ b/configs/T1024RDB_SECURE_BOOT_defconfig
@@ -63,6 +63,8 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
 CONFIG_RSA=y
 CONFIG_SPL_RSA=y
 CONFIG_RSA_SOFTWARE_EXP=y
diff --git a/configs/T1024RDB_SPIFLASH_defconfig b/configs/T1024RDB_SPIFLASH_defconfig
index cab645d..d550959 100644
--- a/configs/T1024RDB_SPIFLASH_defconfig
+++ b/configs/T1024RDB_SPIFLASH_defconfig
@@ -87,3 +87,5 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
diff --git a/configs/T1024RDB_defconfig b/configs/T1024RDB_defconfig
index 46c857d..20e85c1 100644
--- a/configs/T1024RDB_defconfig
+++ b/configs/T1024RDB_defconfig
@@ -72,3 +72,5 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
diff --git a/configs/T1040D4RDB_NAND_defconfig b/configs/T1040D4RDB_NAND_defconfig
index 21875e6..17664da 100644
--- a/configs/T1040D4RDB_NAND_defconfig
+++ b/configs/T1040D4RDB_NAND_defconfig
@@ -72,4 +72,6 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
 CONFIG_OF_LIBFDT=y
diff --git a/configs/T1040D4RDB_SDCARD_defconfig b/configs/T1040D4RDB_SDCARD_defconfig
index 07c4974..72440c6 100644
--- a/configs/T1040D4RDB_SDCARD_defconfig
+++ b/configs/T1040D4RDB_SDCARD_defconfig
@@ -69,4 +69,6 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
 CONFIG_OF_LIBFDT=y
diff --git a/configs/T1040D4RDB_SECURE_BOOT_defconfig b/configs/T1040D4RDB_SECURE_BOOT_defconfig
index 7adffb7..01fa29c 100644
--- a/configs/T1040D4RDB_SECURE_BOOT_defconfig
+++ b/configs/T1040D4RDB_SECURE_BOOT_defconfig
@@ -55,6 +55,8 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
 CONFIG_RSA=y
 CONFIG_SPL_RSA=y
 CONFIG_RSA_SOFTWARE_EXP=y
diff --git a/configs/T1040D4RDB_SPIFLASH_defconfig b/configs/T1040D4RDB_SPIFLASH_defconfig
index 8979ebf..8abc3f7 100644
--- a/configs/T1040D4RDB_SPIFLASH_defconfig
+++ b/configs/T1040D4RDB_SPIFLASH_defconfig
@@ -72,4 +72,6 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
 CONFIG_OF_LIBFDT=y
diff --git a/configs/T1040D4RDB_defconfig b/configs/T1040D4RDB_defconfig
index eb25930..dcf3dce 100644
--- a/configs/T1040D4RDB_defconfig
+++ b/configs/T1040D4RDB_defconfig
@@ -56,4 +56,6 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
 CONFIG_OF_LIBFDT=y
diff --git a/configs/T1040RDB_NAND_defconfig b/configs/T1040RDB_NAND_defconfig
index b2c07d5..f08e03f 100644
--- a/configs/T1040RDB_NAND_defconfig
+++ b/configs/T1040RDB_NAND_defconfig
@@ -73,4 +73,6 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
 CONFIG_OF_LIBFDT=y
diff --git a/configs/T1040RDB_SDCARD_defconfig b/configs/T1040RDB_SDCARD_defconfig
index 2c64794..047fca3 100644
--- a/configs/T1040RDB_SDCARD_defconfig
+++ b/configs/T1040RDB_SDCARD_defconfig
@@ -70,4 +70,6 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
 CONFIG_OF_LIBFDT=y
diff --git a/configs/T1040RDB_SECURE_BOOT_defconfig b/configs/T1040RDB_SECURE_BOOT_defconfig
index 910b984..aa22883 100644
--- a/configs/T1040RDB_SECURE_BOOT_defconfig
+++ b/configs/T1040RDB_SECURE_BOOT_defconfig
@@ -56,6 +56,8 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
 CONFIG_RSA=y
 CONFIG_SPL_RSA=y
 CONFIG_RSA_SOFTWARE_EXP=y
diff --git a/configs/T1040RDB_SPIFLASH_defconfig b/configs/T1040RDB_SPIFLASH_defconfig
index a7f9f7d..19a0a8f 100644
--- a/configs/T1040RDB_SPIFLASH_defconfig
+++ b/configs/T1040RDB_SPIFLASH_defconfig
@@ -73,4 +73,6 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
 CONFIG_OF_LIBFDT=y
diff --git a/configs/T1040RDB_defconfig b/configs/T1040RDB_defconfig
index e8c5393..56d61ae 100644
--- a/configs/T1040RDB_defconfig
+++ b/configs/T1040RDB_defconfig
@@ -57,4 +57,6 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
 CONFIG_OF_LIBFDT=y
diff --git a/configs/T1042D4RDB_NAND_defconfig b/configs/T1042D4RDB_NAND_defconfig
index f607973..855f9a4 100644
--- a/configs/T1042D4RDB_NAND_defconfig
+++ b/configs/T1042D4RDB_NAND_defconfig
@@ -84,3 +84,5 @@
 CONFIG_DM_USB=y
 CONFIG_VIDEO=y
 CONFIG_CFB_CONSOLE_ANSI=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
diff --git a/configs/T1042D4RDB_SDCARD_defconfig b/configs/T1042D4RDB_SDCARD_defconfig
index e31d95a..81362a8 100644
--- a/configs/T1042D4RDB_SDCARD_defconfig
+++ b/configs/T1042D4RDB_SDCARD_defconfig
@@ -81,3 +81,5 @@
 CONFIG_DM_USB=y
 CONFIG_VIDEO=y
 CONFIG_CFB_CONSOLE_ANSI=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
diff --git a/configs/T1042D4RDB_SECURE_BOOT_defconfig b/configs/T1042D4RDB_SECURE_BOOT_defconfig
index f460b17..b9adcc0 100644
--- a/configs/T1042D4RDB_SECURE_BOOT_defconfig
+++ b/configs/T1042D4RDB_SECURE_BOOT_defconfig
@@ -58,6 +58,8 @@
 CONFIG_USB_STORAGE=y
 CONFIG_VIDEO=y
 CONFIG_CFB_CONSOLE_ANSI=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
 CONFIG_RSA=y
 CONFIG_SPL_RSA=y
 CONFIG_RSA_SOFTWARE_EXP=y
diff --git a/configs/T1042D4RDB_SPIFLASH_defconfig b/configs/T1042D4RDB_SPIFLASH_defconfig
index 11bbdb4..e5e4fea 100644
--- a/configs/T1042D4RDB_SPIFLASH_defconfig
+++ b/configs/T1042D4RDB_SPIFLASH_defconfig
@@ -84,3 +84,5 @@
 CONFIG_DM_USB=y
 CONFIG_VIDEO=y
 CONFIG_CFB_CONSOLE_ANSI=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
diff --git a/configs/T1042D4RDB_defconfig b/configs/T1042D4RDB_defconfig
index 70ddffb..2c6e8d0 100644
--- a/configs/T1042D4RDB_defconfig
+++ b/configs/T1042D4RDB_defconfig
@@ -69,3 +69,5 @@
 CONFIG_DM_USB=y
 CONFIG_VIDEO=y
 CONFIG_CFB_CONSOLE_ANSI=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
diff --git a/configs/T1042RDB_PI_NAND_SECURE_BOOT_defconfig b/configs/T1042RDB_PI_NAND_SECURE_BOOT_defconfig
index a6878f5..ffb65d2 100644
--- a/configs/T1042RDB_PI_NAND_SECURE_BOOT_defconfig
+++ b/configs/T1042RDB_PI_NAND_SECURE_BOOT_defconfig
@@ -79,6 +79,8 @@
 CONFIG_USB_STORAGE=y
 CONFIG_VIDEO=y
 CONFIG_CFB_CONSOLE_ANSI=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
 CONFIG_RSA=y
 CONFIG_SPL_RSA=y
 CONFIG_RSA_SOFTWARE_EXP=y
diff --git a/configs/T1042RDB_PI_NAND_defconfig b/configs/T1042RDB_PI_NAND_defconfig
index 5585517..a048862 100644
--- a/configs/T1042RDB_PI_NAND_defconfig
+++ b/configs/T1042RDB_PI_NAND_defconfig
@@ -77,4 +77,6 @@
 CONFIG_USB_STORAGE=y
 CONFIG_VIDEO=y
 CONFIG_CFB_CONSOLE_ANSI=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
 CONFIG_OF_LIBFDT=y
diff --git a/configs/T1042RDB_PI_SDCARD_defconfig b/configs/T1042RDB_PI_SDCARD_defconfig
index 4aadd90..12e96a0 100644
--- a/configs/T1042RDB_PI_SDCARD_defconfig
+++ b/configs/T1042RDB_PI_SDCARD_defconfig
@@ -74,4 +74,6 @@
 CONFIG_USB_STORAGE=y
 CONFIG_VIDEO=y
 CONFIG_CFB_CONSOLE_ANSI=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
 CONFIG_OF_LIBFDT=y
diff --git a/configs/T1042RDB_PI_SPIFLASH_defconfig b/configs/T1042RDB_PI_SPIFLASH_defconfig
index b8a96cc..56173eb 100644
--- a/configs/T1042RDB_PI_SPIFLASH_defconfig
+++ b/configs/T1042RDB_PI_SPIFLASH_defconfig
@@ -77,4 +77,6 @@
 CONFIG_USB_STORAGE=y
 CONFIG_VIDEO=y
 CONFIG_CFB_CONSOLE_ANSI=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
 CONFIG_OF_LIBFDT=y
diff --git a/configs/T1042RDB_PI_defconfig b/configs/T1042RDB_PI_defconfig
index 07ad865..4a9e534 100644
--- a/configs/T1042RDB_PI_defconfig
+++ b/configs/T1042RDB_PI_defconfig
@@ -61,4 +61,6 @@
 CONFIG_USB_STORAGE=y
 CONFIG_VIDEO=y
 CONFIG_CFB_CONSOLE_ANSI=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
 CONFIG_OF_LIBFDT=y
diff --git a/configs/T1042RDB_SECURE_BOOT_defconfig b/configs/T1042RDB_SECURE_BOOT_defconfig
index c5f39e8..2633b83 100644
--- a/configs/T1042RDB_SECURE_BOOT_defconfig
+++ b/configs/T1042RDB_SECURE_BOOT_defconfig
@@ -55,6 +55,8 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
 CONFIG_RSA=y
 CONFIG_SPL_RSA=y
 CONFIG_RSA_SOFTWARE_EXP=y
diff --git a/configs/T1042RDB_defconfig b/configs/T1042RDB_defconfig
index c94730d..0755a95 100644
--- a/configs/T1042RDB_defconfig
+++ b/configs/T1042RDB_defconfig
@@ -56,4 +56,6 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
 CONFIG_OF_LIBFDT=y
diff --git a/configs/T2080QDS_NAND_defconfig b/configs/T2080QDS_NAND_defconfig
index 1de486f..d088e11 100644
--- a/configs/T2080QDS_NAND_defconfig
+++ b/configs/T2080QDS_NAND_defconfig
@@ -81,3 +81,5 @@
 CONFIG_USB=y
 CONFIG_DM_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
diff --git a/configs/T2080QDS_SDCARD_defconfig b/configs/T2080QDS_SDCARD_defconfig
index 0e2dce2..c12a651 100644
--- a/configs/T2080QDS_SDCARD_defconfig
+++ b/configs/T2080QDS_SDCARD_defconfig
@@ -78,3 +78,5 @@
 CONFIG_USB=y
 CONFIG_DM_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
diff --git a/configs/T2080QDS_SECURE_BOOT_defconfig b/configs/T2080QDS_SECURE_BOOT_defconfig
index 9b3f709..35891cc 100644
--- a/configs/T2080QDS_SECURE_BOOT_defconfig
+++ b/configs/T2080QDS_SECURE_BOOT_defconfig
@@ -65,6 +65,8 @@
 CONFIG_USB=y
 CONFIG_DM_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
 CONFIG_RSA=y
 CONFIG_SPL_RSA=y
 CONFIG_RSA_SOFTWARE_EXP=y
diff --git a/configs/T2080QDS_SPIFLASH_defconfig b/configs/T2080QDS_SPIFLASH_defconfig
index 49db2fe..901ad2c 100644
--- a/configs/T2080QDS_SPIFLASH_defconfig
+++ b/configs/T2080QDS_SPIFLASH_defconfig
@@ -81,3 +81,5 @@
 CONFIG_USB=y
 CONFIG_DM_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
diff --git a/configs/T2080QDS_SRIO_PCIE_BOOT_defconfig b/configs/T2080QDS_SRIO_PCIE_BOOT_defconfig
index 4958435..38d947c 100644
--- a/configs/T2080QDS_SRIO_PCIE_BOOT_defconfig
+++ b/configs/T2080QDS_SRIO_PCIE_BOOT_defconfig
@@ -58,3 +58,5 @@
 CONFIG_USB=y
 CONFIG_DM_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
diff --git a/configs/T2080QDS_defconfig b/configs/T2080QDS_defconfig
index 602bf57..a5bd06c 100644
--- a/configs/T2080QDS_defconfig
+++ b/configs/T2080QDS_defconfig
@@ -66,3 +66,5 @@
 CONFIG_USB=y
 CONFIG_DM_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
diff --git a/configs/T2080RDB_NAND_defconfig b/configs/T2080RDB_NAND_defconfig
index 5ec264b..da21b31 100644
--- a/configs/T2080RDB_NAND_defconfig
+++ b/configs/T2080RDB_NAND_defconfig
@@ -82,3 +82,5 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
diff --git a/configs/T2080RDB_SDCARD_defconfig b/configs/T2080RDB_SDCARD_defconfig
index 05fa2d6..6e23c57 100644
--- a/configs/T2080RDB_SDCARD_defconfig
+++ b/configs/T2080RDB_SDCARD_defconfig
@@ -79,3 +79,5 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
diff --git a/configs/T2080RDB_SECURE_BOOT_defconfig b/configs/T2080RDB_SECURE_BOOT_defconfig
index 7d04a94..1a89cd8 100644
--- a/configs/T2080RDB_SECURE_BOOT_defconfig
+++ b/configs/T2080RDB_SECURE_BOOT_defconfig
@@ -57,6 +57,8 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
 CONFIG_RSA=y
 CONFIG_SPL_RSA=y
 CONFIG_RSA_SOFTWARE_EXP=y
diff --git a/configs/T2080RDB_SPIFLASH_defconfig b/configs/T2080RDB_SPIFLASH_defconfig
index da562d2..8af05ee 100644
--- a/configs/T2080RDB_SPIFLASH_defconfig
+++ b/configs/T2080RDB_SPIFLASH_defconfig
@@ -82,3 +82,5 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
diff --git a/configs/T2080RDB_SRIO_PCIE_BOOT_defconfig b/configs/T2080RDB_SRIO_PCIE_BOOT_defconfig
index a8f0a96..729edaa 100644
--- a/configs/T2080RDB_SRIO_PCIE_BOOT_defconfig
+++ b/configs/T2080RDB_SRIO_PCIE_BOOT_defconfig
@@ -50,4 +50,6 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
 CONFIG_OF_LIBFDT=y
diff --git a/configs/T2080RDB_defconfig b/configs/T2080RDB_defconfig
index 85e3b64..d957e40 100644
--- a/configs/T2080RDB_defconfig
+++ b/configs/T2080RDB_defconfig
@@ -66,3 +66,5 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
diff --git a/configs/T2081QDS_NAND_defconfig b/configs/T2081QDS_NAND_defconfig
index bf2f36f..d40fd6e 100644
--- a/configs/T2081QDS_NAND_defconfig
+++ b/configs/T2081QDS_NAND_defconfig
@@ -72,4 +72,6 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
 CONFIG_OF_LIBFDT=y
diff --git a/configs/T2081QDS_SDCARD_defconfig b/configs/T2081QDS_SDCARD_defconfig
index f6ebc48..bc22928 100644
--- a/configs/T2081QDS_SDCARD_defconfig
+++ b/configs/T2081QDS_SDCARD_defconfig
@@ -69,4 +69,6 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
 CONFIG_OF_LIBFDT=y
diff --git a/configs/T2081QDS_SPIFLASH_defconfig b/configs/T2081QDS_SPIFLASH_defconfig
index cd8fa25..82bacdb 100644
--- a/configs/T2081QDS_SPIFLASH_defconfig
+++ b/configs/T2081QDS_SPIFLASH_defconfig
@@ -72,4 +72,6 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
 CONFIG_OF_LIBFDT=y
diff --git a/configs/T2081QDS_SRIO_PCIE_BOOT_defconfig b/configs/T2081QDS_SRIO_PCIE_BOOT_defconfig
index a10f39b..87cfb5f 100644
--- a/configs/T2081QDS_SRIO_PCIE_BOOT_defconfig
+++ b/configs/T2081QDS_SRIO_PCIE_BOOT_defconfig
@@ -48,4 +48,6 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
 CONFIG_OF_LIBFDT=y
diff --git a/configs/T2081QDS_defconfig b/configs/T2081QDS_defconfig
index 22ca083..c7ff58a 100644
--- a/configs/T2081QDS_defconfig
+++ b/configs/T2081QDS_defconfig
@@ -56,4 +56,6 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
 CONFIG_OF_LIBFDT=y
diff --git a/configs/T4160RDB_defconfig b/configs/T4160RDB_defconfig
index f3c7e1e..70e6d92 100644
--- a/configs/T4160RDB_defconfig
+++ b/configs/T4160RDB_defconfig
@@ -51,4 +51,6 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
 CONFIG_OF_LIBFDT=y
diff --git a/configs/T4240RDB_SDCARD_defconfig b/configs/T4240RDB_SDCARD_defconfig
index 85825da..e916fbf 100644
--- a/configs/T4240RDB_SDCARD_defconfig
+++ b/configs/T4240RDB_SDCARD_defconfig
@@ -72,3 +72,5 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
diff --git a/configs/T4240RDB_defconfig b/configs/T4240RDB_defconfig
index dfe8953..2d8ab6f 100644
--- a/configs/T4240RDB_defconfig
+++ b/configs/T4240RDB_defconfig
@@ -60,3 +60,5 @@
 CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
diff --git a/configs/chromebook_link_defconfig b/configs/chromebook_link_defconfig
index 3d51ec9..7e9a7a3 100644
--- a/configs/chromebook_link_defconfig
+++ b/configs/chromebook_link_defconfig
@@ -62,10 +62,10 @@
 CONFIG_TPM_TIS_LPC=y
 CONFIG_USB_STORAGE=y
 CONFIG_USB_KEYBOARD=y
+CONFIG_VIDEO_COPY=y
 CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
 CONFIG_FRAMEBUFFER_VESA_MODE_11A=y
 CONFIG_VIDEO_IVYBRIDGE_IGD=y
-CONFIG_CONSOLE_SCROLL_LINES=5
 CONFIG_CMD_DHRYSTONE=y
 CONFIG_TPM=y
 # CONFIG_GZIP is not set
diff --git a/configs/chromebook_samus_defconfig b/configs/chromebook_samus_defconfig
index c18cba9..bf03cde 100644
--- a/configs/chromebook_samus_defconfig
+++ b/configs/chromebook_samus_defconfig
@@ -67,8 +67,8 @@
 CONFIG_TPM_TIS_LPC=y
 CONFIG_USB_STORAGE=y
 CONFIG_USB_KEYBOARD=y
+CONFIG_VIDEO_COPY=y
 CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
 CONFIG_FRAMEBUFFER_VESA_MODE_11A=y
-CONFIG_CONSOLE_SCROLL_LINES=5
 CONFIG_TPM=y
 # CONFIG_GZIP is not set
diff --git a/configs/controlcenterd_36BIT_SDCARD_DEVELOP_defconfig b/configs/controlcenterd_36BIT_SDCARD_DEVELOP_defconfig
index 90fe803..41785d0 100644
--- a/configs/controlcenterd_36BIT_SDCARD_DEVELOP_defconfig
+++ b/configs/controlcenterd_36BIT_SDCARD_DEVELOP_defconfig
@@ -64,5 +64,6 @@
 CONFIG_USB_STORAGE=y
 CONFIG_VIDEO=y
 # CONFIG_VIDEO_SW_CURSOR is not set
+CONFIG_ADDR_MAP=y
 CONFIG_TPM=y
 CONFIG_OF_LIBFDT=y
diff --git a/configs/controlcenterd_36BIT_SDCARD_defconfig b/configs/controlcenterd_36BIT_SDCARD_defconfig
index 55a46c3..777f5ae 100644
--- a/configs/controlcenterd_36BIT_SDCARD_defconfig
+++ b/configs/controlcenterd_36BIT_SDCARD_defconfig
@@ -64,5 +64,6 @@
 CONFIG_USB_STORAGE=y
 CONFIG_VIDEO=y
 # CONFIG_VIDEO_SW_CURSOR is not set
+CONFIG_ADDR_MAP=y
 CONFIG_TPM=y
 CONFIG_OF_LIBFDT=y
diff --git a/configs/kmcoge4_defconfig b/configs/kmcoge4_defconfig
index a0d2c1a..cf54e9f 100644
--- a/configs/kmcoge4_defconfig
+++ b/configs/kmcoge4_defconfig
@@ -64,5 +64,7 @@
 CONFIG_SYS_NS16550=y
 CONFIG_SPI=y
 CONFIG_FSL_ESPI=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=64
 CONFIG_BCH=y
 CONFIG_OF_LIBFDT=y
diff --git a/configs/minnowmax_defconfig b/configs/minnowmax_defconfig
index 40ed9e4..13d6edd 100644
--- a/configs/minnowmax_defconfig
+++ b/configs/minnowmax_defconfig
@@ -59,7 +59,7 @@
 CONFIG_SPI=y
 CONFIG_USB_STORAGE=y
 CONFIG_USB_KEYBOARD=y
+CONFIG_VIDEO_COPY=y
 CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
-CONFIG_FRAMEBUFFER_VESA_MODE_11B=y
-CONFIG_CONSOLE_SCROLL_LINES=5
+CONFIG_FRAMEBUFFER_VESA_MODE_118=y
 # CONFIG_GZIP is not set
diff --git a/configs/qemu-ppce500_defconfig b/configs/qemu-ppce500_defconfig
index ab4bc5d..ba2ee27 100644
--- a/configs/qemu-ppce500_defconfig
+++ b/configs/qemu-ppce500_defconfig
@@ -27,5 +27,6 @@
 # CONFIG_MMC is not set
 CONFIG_E1000=y
 CONFIG_SYS_NS16550=y
+CONFIG_ADDR_MAP=y
 CONFIG_PANIC_HANG=y
 CONFIG_OF_LIBFDT=y
diff --git a/configs/rpi_4_32b_defconfig b/configs/rpi_4_32b_defconfig
index a36a249..db7b781 100644
--- a/configs/rpi_4_32b_defconfig
+++ b/configs/rpi_4_32b_defconfig
@@ -6,6 +6,8 @@
 CONFIG_ENV_SIZE=0x4000
 CONFIG_DISTRO_DEFAULTS=y
 CONFIG_OF_BOARD_SETUP=y
+CONFIG_USE_PREBOOT=y
+CONFIG_PREBOOT="pci enum; usb start;"
 CONFIG_MISC_INIT_R=y
 # CONFIG_DISPLAY_CPUINFO is not set
 # CONFIG_DISPLAY_BOARDINFO is not set
@@ -13,6 +15,8 @@
 CONFIG_CMD_DFU=y
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_MMC=y
+CONFIG_CMD_PCI=y
+CONFIG_CMD_USB=y
 CONFIG_CMD_FS_UUID=y
 CONFIG_OF_BOARD=y
 CONFIG_ENV_FAT_DEVICE_AND_PART="0:1"
@@ -26,12 +30,18 @@
 CONFIG_MMC_SDHCI_BCM2835=y
 CONFIG_DM_ETH=y
 CONFIG_BCMGENET=y
+CONFIG_PCI=y
+CONFIG_DM_PCI=y
+CONFIG_PCI_BRCMSTB=y
 CONFIG_PINCTRL=y
 # CONFIG_PINCTRL_GENERIC is not set
+CONFIG_DM_RESET=y
 # CONFIG_REQUIRE_SERIAL_CONSOLE is not set
 CONFIG_USB=y
 CONFIG_DM_USB=y
 CONFIG_DM_USB_GADGET=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_PCI=y
 CONFIG_USB_GADGET=y
 CONFIG_USB_GADGET_MANUFACTURER="FSL"
 CONFIG_USB_GADGET_VENDOR_NUM=0x0525
@@ -44,4 +54,6 @@
 CONFIG_SYS_WHITE_ON_BLACK=y
 CONFIG_CONSOLE_SCROLL_LINES=10
 CONFIG_PHYS_TO_BUS=y
+CONFIG_ADDR_MAP=y
+CONFIG_SYS_NUM_ADDR_MAP=2
 CONFIG_OF_LIBFDT_OVERLAY=y
diff --git a/configs/rpi_4_defconfig b/configs/rpi_4_defconfig
index f0301dc..71f95ed 100644
--- a/configs/rpi_4_defconfig
+++ b/configs/rpi_4_defconfig
@@ -6,6 +6,8 @@
 CONFIG_ENV_SIZE=0x4000
 CONFIG_DISTRO_DEFAULTS=y
 CONFIG_OF_BOARD_SETUP=y
+CONFIG_USE_PREBOOT=y
+CONFIG_PREBOOT="pci enum; usb start;"
 CONFIG_MISC_INIT_R=y
 # CONFIG_DISPLAY_CPUINFO is not set
 # CONFIG_DISPLAY_BOARDINFO is not set
@@ -13,6 +15,8 @@
 CONFIG_CMD_DFU=y
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_MMC=y
+CONFIG_CMD_PCI=y
+CONFIG_CMD_USB=y
 CONFIG_CMD_FS_UUID=y
 CONFIG_OF_BOARD=y
 CONFIG_ENV_FAT_DEVICE_AND_PART="0:1"
@@ -26,12 +30,19 @@
 CONFIG_MMC_SDHCI_BCM2835=y
 CONFIG_DM_ETH=y
 CONFIG_BCMGENET=y
+CONFIG_PCI=y
+CONFIG_DM_PCI=y
+CONFIG_PCI_BRCMSTB=y
 CONFIG_PINCTRL=y
 # CONFIG_PINCTRL_GENERIC is not set
+CONFIG_DM_RESET=y
 # CONFIG_REQUIRE_SERIAL_CONSOLE is not set
 CONFIG_USB=y
 CONFIG_DM_USB=y
 CONFIG_DM_USB_GADGET=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_PCI=y
+CONFIG_USB_KEYBOARD=y
 CONFIG_USB_GADGET=y
 CONFIG_USB_GADGET_MANUFACTURER="FSL"
 CONFIG_USB_GADGET_VENDOR_NUM=0x0525
diff --git a/configs/rpi_arm64_defconfig b/configs/rpi_arm64_defconfig
index d16c238..4ce8469 100644
--- a/configs/rpi_arm64_defconfig
+++ b/configs/rpi_arm64_defconfig
@@ -7,13 +7,14 @@
 CONFIG_DISTRO_DEFAULTS=y
 CONFIG_OF_BOARD_SETUP=y
 CONFIG_USE_PREBOOT=y
-CONFIG_PREBOOT="usb start"
+CONFIG_PREBOOT="pci enum; usb start;"
 CONFIG_MISC_INIT_R=y
 # CONFIG_DISPLAY_CPUINFO is not set
 # CONFIG_DISPLAY_BOARDINFO is not set
 CONFIG_SYS_PROMPT="U-Boot> "
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_MMC=y
+CONFIG_CMD_PCI=y
 CONFIG_CMD_USB=y
 CONFIG_CMD_FS_UUID=y
 CONFIG_OF_BOARD=y
@@ -26,11 +27,17 @@
 CONFIG_MMC_SDHCI_BCM2835=y
 CONFIG_DM_ETH=y
 CONFIG_BCMGENET=y
+CONFIG_PCI=y
+CONFIG_DM_PCI=y
+CONFIG_PCI_BRCMSTB=y
 CONFIG_PINCTRL=y
 # CONFIG_PINCTRL_GENERIC is not set
+CONFIG_DM_RESET=y
 # CONFIG_REQUIRE_SERIAL_CONSOLE is not set
 CONFIG_USB=y
 CONFIG_DM_USB=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_PCI=y
 CONFIG_USB_DWC2=y
 CONFIG_USB_KEYBOARD=y
 CONFIG_USB_HOST_ETHER=y
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index e0dffa3..9b74e40 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -220,6 +220,7 @@
 CONFIG_USB_EMUL=y
 CONFIG_USB_KEYBOARD=y
 CONFIG_DM_VIDEO=y
+CONFIG_VIDEO_COPY=y
 CONFIG_CONSOLE_ROTATION=y
 CONFIG_CONSOLE_TRUETYPE=y
 CONFIG_CONSOLE_TRUETYPE_CANTORAONE=y
diff --git a/configs/uniphier_ld4_sld8_defconfig b/configs/uniphier_ld4_sld8_defconfig
index 2e809ca..3c9cab0 100644
--- a/configs/uniphier_ld4_sld8_defconfig
+++ b/configs/uniphier_ld4_sld8_defconfig
@@ -8,7 +8,6 @@
 CONFIG_SPL_SERIAL_SUPPORT=y
 CONFIG_NR_DRAM_BANKS=3
 CONFIG_SPL=y
-CONFIG_ARCH_UNIPHIER_LD4_SLD8=y
 CONFIG_MICRO_SUPPORT_CARD=y
 # CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
 CONFIG_BOOTCOMMAND="run ${bootdev}script; run ${bootdev}boot"
@@ -18,7 +17,6 @@
 CONFIG_SPL_NAND_SUPPORT=y
 CONFIG_SPL_NOR_SUPPORT=y
 CONFIG_CMD_CONFIG=y
-CONFIG_CMD_IMLS=y
 # CONFIG_CMD_XIMG is not set
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_GPT=y
@@ -45,8 +43,6 @@
 CONFIG_SUPPORT_EMMC_BOOT=y
 CONFIG_MMC_UNIPHIER=y
 CONFIG_MTD=y
-CONFIG_FLASH_CFI_DRIVER=y
-CONFIG_SYS_FLASH_CFI=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_NAND_DENALI_DT=y
 CONFIG_SPL_NAND_DENALI=y
diff --git a/configs/uniphier_v7_defconfig b/configs/uniphier_v7_defconfig
index 07c38a2..48958b1 100644
--- a/configs/uniphier_v7_defconfig
+++ b/configs/uniphier_v7_defconfig
@@ -17,7 +17,6 @@
 CONFIG_SPL_NAND_SUPPORT=y
 CONFIG_SPL_NOR_SUPPORT=y
 CONFIG_CMD_CONFIG=y
-CONFIG_CMD_IMLS=y
 # CONFIG_CMD_XIMG is not set
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_GPT=y
@@ -45,8 +44,6 @@
 CONFIG_SUPPORT_EMMC_BOOT=y
 CONFIG_MMC_UNIPHIER=y
 CONFIG_MTD=y
-CONFIG_FLASH_CFI_DRIVER=y
-CONFIG_SYS_FLASH_CFI=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_NAND_DENALI_DT=y
 CONFIG_SPL_NAND_DENALI=y
diff --git a/configs/uniphier_v8_defconfig b/configs/uniphier_v8_defconfig
index 9edb7ec..9ab3e26 100644
--- a/configs/uniphier_v8_defconfig
+++ b/configs/uniphier_v8_defconfig
@@ -14,7 +14,6 @@
 CONFIG_PREBOOT="env exist ${bootdev}preboot && run ${bootdev}preboot"
 CONFIG_LOGLEVEL=6
 CONFIG_CMD_CONFIG=y
-CONFIG_CMD_IMLS=y
 # CONFIG_CMD_XIMG is not set
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_GPT=y
@@ -45,8 +44,6 @@
 CONFIG_MMC_SDHCI_ADMA=y
 CONFIG_MMC_SDHCI_CADENCE=y
 CONFIG_MTD=y
-CONFIG_FLASH_CFI_DRIVER=y
-CONFIG_SYS_FLASH_CFI=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_NAND_DENALI_DT=y
 CONFIG_SNI_AVE=y
diff --git a/doc/driver-model/of-plat.rst b/doc/driver-model/of-plat.rst
index 034a68b..1e3fad1 100644
--- a/doc/driver-model/of-plat.rst
+++ b/doc/driver-model/of-plat.rst
@@ -69,9 +69,8 @@
    - Correct relations between nodes are not implemented. This means that
      parent/child relations (like bus device iteration) do not work yet.
      Some phandles (those that are recognised as such) are converted into
-     a pointer to platform data. This pointer can potentially be used to
-     access the referenced device (by searching for the pointer value).
-     This feature is not yet implemented, however.
+     a pointer to struct driver_info. This pointer can be used to access
+     the referenced device.
 
 
 How it works
@@ -146,10 +145,10 @@
             .clock_freq_min_max     = {0x61a80, 0x8f0d180},
             .vmmc_supply            = 0xb,
             .num_slots              = 0x1,
-            .clocks                 = {{&dtv_clock_controller_at_ff760000, 456},
-                                       {&dtv_clock_controller_at_ff760000, 68},
-                                       {&dtv_clock_controller_at_ff760000, 114},
-                                       {&dtv_clock_controller_at_ff760000, 118}},
+            .clocks                 = {{NULL, 456},
+                                       {NULL, 68},
+                                       {NULL, 114},
+                                       {NULL, 118}},
             .cap_mmc_highspeed      = true,
             .disable_wp             = true,
             .bus_width              = 0x4,
@@ -164,6 +163,13 @@
             .platdata_size  = sizeof(dtv_dwmmc_at_ff0c0000),
     };
 
+    void dm_populate_phandle_data(void) {
+            dtv_dwmmc_at_ff0c0000.clocks[0].node = DM_GET_DEVICE(clock_controller_at_ff760000);
+            dtv_dwmmc_at_ff0c0000.clocks[1].node = DM_GET_DEVICE(clock_controller_at_ff760000);
+            dtv_dwmmc_at_ff0c0000.clocks[2].node = DM_GET_DEVICE(clock_controller_at_ff760000);
+            dtv_dwmmc_at_ff0c0000.clocks[3].node = DM_GET_DEVICE(clock_controller_at_ff760000);
+    }
+
 The device is then instantiated at run-time and the platform data can be
 accessed using:
 
@@ -183,6 +189,17 @@
 it to a valid name for C) is needed, so a dedicated driver is required for
 each 'compatible' string.
 
+In order to make this a bit more flexible U_BOOT_DRIVER_ALIAS macro can be
+used to declare an alias for a driver name, typically a 'compatible' string.
+This macro produces no code, but it is by dtoc tool.
+
+During the build process dtoc parses both U_BOOT_DRIVER and U_BOOT_DRIVER_ALIAS
+to build a list of valid driver names and driver aliases. If the 'compatible'
+string used for a device does not not match a valid driver name, it will be
+checked against the list of driver aliases in order to get the right driver
+name to use. If in this step there is no match found a warning is issued to
+avoid run-time failures.
+
 Where a node has multiple compatible strings, a #define is used to make them
 equivalent, e.g.:
 
@@ -269,7 +286,7 @@
     };
 
     U_BOOT_DRIVER(mmc_drv) = {
-            .name           = "vendor_mmc",  /* matches compatible string */
+            .name           = "mmc_drv",
             .id             = UCLASS_MMC,
             .of_match       = mmc_ids,
             .ofdata_to_platdata = mmc_ofdata_to_platdata,
@@ -278,6 +295,7 @@
             .platdata_auto_alloc_size = sizeof(struct mmc_platdata),
     };
 
+    U_BOOT_DRIVER_ALIAS(mmc_drv, vendor_mmc) /* matches compatible string */
 
 Note that struct mmc_platdata is defined in the C file, not in a header. This
 is to avoid needing to include dt-structs.h in a header file. The idea is to
@@ -317,7 +335,9 @@
 #if CONFIG_IS_ENABLED(OF_PLATDATA).
 
 The dt-platdata.c file contains the device declarations and is is built in
-spl/dt-platdata.c.
+spl/dt-platdata.c. It additionally contains the definition of
+dm_populate_phandle_data() which is responsible of filling the phandle
+information by adding references to U_BOOT_DEVICE by using DM_GET_DEVICE
 
 The beginnings of a libfdt Python module are provided. So far this only
 implements a subset of the features.
diff --git a/drivers/Kconfig b/drivers/Kconfig
index e34a227..7a839fa 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -10,6 +10,8 @@
 
 source "drivers/axi/Kconfig"
 
+source "drivers/bus/Kconfig"
+
 source "drivers/block/Kconfig"
 
 source "drivers/bootcount/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index 94e8c5d..afd159e 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -74,6 +74,7 @@
 
 obj-y += adc/
 obj-y += ata/
+obj-y += bus/
 obj-$(CONFIG_DM_DEMO) += demo/
 obj-$(CONFIG_BIOSEMU) += bios_emulator/
 obj-y += block/
diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
new file mode 100644
index 0000000..07a33c6
--- /dev/null
+++ b/drivers/bus/Kconfig
@@ -0,0 +1,16 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Bus Devices
+#
+
+menu "Bus devices"
+
+config UNIPHIER_SYSTEM_BUS
+	bool "UniPhier System Bus driver"
+	depends on ARCH_UNIPHIER
+	default y
+	help
+	  Support for UniPhier System Bus, a simple external bus.  This is
+	  needed to use on-board devices connected to UniPhier SoCs.
+
+endmenu
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
new file mode 100644
index 0000000..0b97fc1
--- /dev/null
+++ b/drivers/bus/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for the bus drivers.
+#
+
+obj-$(CONFIG_UNIPHIER_SYSTEM_BUS) += uniphier-system-bus.o
diff --git a/drivers/bus/uniphier-system-bus.c b/drivers/bus/uniphier-system-bus.c
new file mode 100644
index 0000000..ea08d66
--- /dev/null
+++ b/drivers/bus/uniphier-system-bus.c
@@ -0,0 +1,100 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <linux/bitops.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+#include <linux/sizes.h>
+#include <linux/types.h>
+#include <dm.h>
+
+/* System Bus Controller registers */
+#define UNIPHIER_SBC_BASE	0x100	/* base address of bank0 space */
+#define    UNIPHIER_SBC_BASE_BE		BIT(0)	/* bank_enable */
+#define UNIPHIER_SBC_CTRL0	0x200	/* timing parameter 0 of bank0 */
+#define UNIPHIER_SBC_CTRL1	0x204	/* timing parameter 1 of bank0 */
+#define UNIPHIER_SBC_CTRL2	0x208	/* timing parameter 2 of bank0 */
+#define UNIPHIER_SBC_CTRL3	0x20c	/* timing parameter 3 of bank0 */
+#define UNIPHIER_SBC_CTRL4	0x300	/* timing parameter 4 of bank0 */
+
+#define UNIPHIER_SBC_STRIDE	0x10	/* register stride to next bank */
+
+#if 1
+/* slower but LED works */
+#define SBCTRL0_VALUE	0x55450000
+#define SBCTRL1_VALUE	0x07168d00
+#define SBCTRL2_VALUE	0x34000009
+#define SBCTRL4_VALUE	0x02110110
+
+#else
+/* faster but LED does not work */
+#define SBCTRL0_VALUE	0x55450000
+#define SBCTRL1_VALUE	0x06057700
+/* NOR flash needs more wait counts than SRAM */
+#define SBCTRL2_VALUE	0x34000009
+#define SBCTRL4_VALUE	0x02110210
+#endif
+
+void uniphier_system_bus_set_reg(void __iomem *membase)
+{
+	void __iomem *bank0_base = membase;
+	void __iomem *bank1_base = membase + UNIPHIER_SBC_STRIDE;
+
+	/*
+	 * Only CS1 is connected to support card.
+	 * BKSZ[1:0] should be set to "01".
+	 */
+	writel(SBCTRL0_VALUE, bank1_base + UNIPHIER_SBC_CTRL0);
+	writel(SBCTRL1_VALUE, bank1_base + UNIPHIER_SBC_CTRL1);
+	writel(SBCTRL2_VALUE, bank1_base + UNIPHIER_SBC_CTRL2);
+	writel(SBCTRL4_VALUE, bank1_base + UNIPHIER_SBC_CTRL4);
+
+	if (readl(bank1_base + UNIPHIER_SBC_BASE) & UNIPHIER_SBC_BASE_BE) {
+		/*
+		 * Boot Swap On: boot from external NOR/SRAM
+		 * 0x42000000-0x43ffffff is a mirror of 0x40000000-0x41ffffff.
+		 *
+		 * 0x40000000-0x41efffff, 0x42000000-0x43efffff: memory bank
+		 * 0x41f00000-0x41ffffff, 0x43f00000-0x43ffffff: peripherals
+		 */
+		writel(0x0000bc01, bank0_base + UNIPHIER_SBC_BASE);
+	} else {
+		/*
+		 * Boot Swap Off: boot from mask ROM
+		 * 0x40000000-0x41ffffff: mask ROM
+		 * 0x42000000-0x43efffff: memory bank (31MB)
+		 * 0x43f00000-0x43ffffff: peripherals (1MB)
+		 */
+		writel(0x0000be01, bank0_base + UNIPHIER_SBC_BASE); /* dummy */
+		writel(0x0200be01, bank0_base + UNIPHIER_SBC_BASE);
+	}
+}
+
+static int uniphier_system_bus_probe(struct udevice *dev)
+{
+	fdt_addr_t base;
+	void __iomem *membase;
+
+	base = dev_read_addr(dev);
+	if (base == FDT_ADDR_T_NONE)
+		return -EINVAL;
+
+	membase = devm_ioremap(dev, base, SZ_1K);
+	if (!membase)
+		return -ENOMEM;
+
+	uniphier_system_bus_set_reg(membase);
+
+	return 0;
+}
+
+static const struct udevice_id uniphier_system_bus_match[] = {
+	{ .compatible = "socionext,uniphier-system-bus" },
+	{ /* sentinel */ }
+};
+
+U_BOOT_DRIVER(uniphier_system_bus_driver) = {
+	.name	= "uniphier-system-bus",
+	.id	= UCLASS_SIMPLE_BUS,
+	.of_match = uniphier_system_bus_match,
+	.probe = uniphier_system_bus_probe,
+};
diff --git a/drivers/clk/at91/clk-master.c b/drivers/clk/at91/clk-master.c
index 4fa33c4..e078fab 100644
--- a/drivers/clk/at91/clk-master.c
+++ b/drivers/clk/at91/clk-master.c
@@ -25,8 +25,8 @@
 	{}
 };
 
-U_BOOT_DRIVER(at91_master_clk) = {
-	.name = "at91-master-clk",
+U_BOOT_DRIVER(atmel_at91rm9200_clk_master) = {
+	.name = "atmel_at91rm9200_clk_master",
 	.id = UCLASS_CLK,
 	.of_match = at91_master_clk_match,
 	.ops = &at91_master_clk_ops,
diff --git a/drivers/clk/at91/clk-peripheral.c b/drivers/clk/at91/clk-peripheral.c
index c55e621..cd9d5e7 100644
--- a/drivers/clk/at91/clk-peripheral.c
+++ b/drivers/clk/at91/clk-peripheral.c
@@ -43,8 +43,8 @@
 	{}
 };
 
-U_BOOT_DRIVER(sam9x5_periph_clk) = {
-	.name = "sam9x5-periph-clk",
+U_BOOT_DRIVER(atmel_at91rm9200_clk_peripheral) = {
+	.name = "atmel_at91rm9200_clk_peripheral",
 	.id = UCLASS_MISC,
 	.of_match = sam9x5_periph_clk_match,
 	.bind = sam9x5_periph_clk_bind,
diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c
index 9d9d77d..54ae0d2 100644
--- a/drivers/clk/at91/pmc.c
+++ b/drivers/clk/at91/pmc.c
@@ -25,12 +25,14 @@
 	{}
 };
 
-U_BOOT_DRIVER(at91_pmc) = {
-	.name = "at91-pmc",
+U_BOOT_DRIVER(atmel_at91rm9200_pmc) = {
+	.name = "atmel_at91rm9200_pmc",
 	.id = UCLASS_SIMPLE_BUS,
 	.of_match = at91_pmc_match,
 };
 
+U_BOOT_DRIVER_ALIAS(atmel_at91rm9200_pmc, atmel_at91sam9260_pmc)
+
 /*---------------------------------------------------------*/
 
 int at91_pmc_core_probe(struct udevice *dev)
diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c
index 70df9d4..15656f5 100644
--- a/drivers/clk/clk-uclass.c
+++ b/drivers/clk/clk-uclass.c
@@ -27,17 +27,16 @@
 
 #if CONFIG_IS_ENABLED(OF_CONTROL)
 # if CONFIG_IS_ENABLED(OF_PLATDATA)
-int clk_get_by_index_platdata(struct udevice *dev, int index,
-			      struct phandle_1_arg *cells, struct clk *clk)
+int clk_get_by_driver_info(struct udevice *dev, struct phandle_1_arg *cells,
+			   struct clk *clk)
 {
 	int ret;
 
-	if (index != 0)
-		return -ENOSYS;
-	ret = uclass_get_device(UCLASS_CLK, 0, &clk->dev);
+	ret = device_get_by_driver_info((struct driver_info *)cells->node,
+					&clk->dev);
 	if (ret)
 		return ret;
-	clk->id = cells[0].arg[0];
+	clk->id = cells->arg[0];
 
 	return 0;
 }
diff --git a/drivers/core/device.c b/drivers/core/device.c
index a7408d9..476133f 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -248,10 +248,11 @@
 }
 
 int device_bind_by_name(struct udevice *parent, bool pre_reloc_only,
-			const struct driver_info *info, struct udevice **devp)
+			struct driver_info *info, struct udevice **devp)
 {
 	struct driver *drv;
 	uint platdata_size = 0;
+	int ret;
 
 	drv = lists_driver_lookup_name(info->name);
 	if (!drv)
@@ -262,9 +263,16 @@
 #if CONFIG_IS_ENABLED(OF_PLATDATA)
 	platdata_size = info->platdata_size;
 #endif
+	ret = device_bind_common(parent, drv, info->name,
+				 (void *)info->platdata, 0, ofnode_null(),
+				 platdata_size, devp);
+	if (ret)
+		return ret;
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+	info->dev = *devp;
+#endif
-	return device_bind_common(parent, drv, info->name,
-			(void *)info->platdata, 0, ofnode_null(), platdata_size,
-			devp);
+
+	return ret;
 }
 
 static void *alloc_priv(int size, uint flags)
@@ -728,6 +736,18 @@
 	dev = _device_find_global_by_ofnode(gd->dm_root, ofnode);
 	return device_get_device_tail(dev, dev ? 0 : -ENOENT, devp);
 }
+
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+int device_get_by_driver_info(const struct driver_info *info,
+			      struct udevice **devp)
+{
+	struct udevice *dev;
+
+	dev = info->dev;
+
+	return device_get_device_tail(dev, dev ? 0 : -ENOENT, devp);
+}
+#endif
 
 int device_find_first_child(const struct udevice *parent, struct udevice **devp)
 {
diff --git a/drivers/core/root.c b/drivers/core/root.c
index 7d257ea..0de5d7c 100644
--- a/drivers/core/root.c
+++ b/drivers/core/root.c
@@ -26,7 +26,7 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-static const struct driver_info root_info = {
+static struct driver_info root_info = {
 	.name		= "root_driver",
 };
 
@@ -347,6 +347,10 @@
 {
 	int ret;
 
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+	dm_populate_phandle_data();
+#endif
+
 	ret = dm_init(IS_ENABLED(CONFIG_OF_LIVE));
 	if (ret) {
 		debug("dm_init() failed: %d\n", ret);
diff --git a/drivers/core/simple-bus.c b/drivers/core/simple-bus.c
index 7fc23ef..7cc1d46 100644
--- a/drivers/core/simple-bus.c
+++ b/drivers/core/simple-bus.c
@@ -56,8 +56,8 @@
 	{ }
 };
 
-U_BOOT_DRIVER(simple_bus_drv) = {
-	.name	= "generic_simple_bus",
+U_BOOT_DRIVER(simple_bus) = {
+	.name	= "simple_bus",
 	.id	= UCLASS_SIMPLE_BUS,
 	.of_match = generic_simple_bus_ids,
 	.flags	= DM_FLAG_PRE_RELOC,
diff --git a/drivers/gpio/at91_gpio.c b/drivers/gpio/at91_gpio.c
index 3621cf2..4a8b2e6 100644
--- a/drivers/gpio/at91_gpio.c
+++ b/drivers/gpio/at91_gpio.c
@@ -624,8 +624,8 @@
 };
 #endif
 
-U_BOOT_DRIVER(gpio_at91) = {
-	.name	= "gpio_at91",
+U_BOOT_DRIVER(atmel_at91rm9200_gpio) = {
+	.name	= "atmel_at91rm9200_gpio",
 	.id	= UCLASS_GPIO,
 #if CONFIG_IS_ENABLED(OF_CONTROL)
 	.of_match = at91_gpio_ids,
diff --git a/drivers/gpio/da8xx_gpio.c b/drivers/gpio/da8xx_gpio.c
index 0d0e9d2..ab0a5cf 100644
--- a/drivers/gpio/da8xx_gpio.c
+++ b/drivers/gpio/da8xx_gpio.c
@@ -553,8 +553,8 @@
 	return 0;
 }
 
-U_BOOT_DRIVER(gpio_davinci) = {
-	.name	= "gpio_davinci",
+U_BOOT_DRIVER(ti_dm6441_gpio) = {
+	.name	= "ti_dm6441_gpio",
 	.id	= UCLASS_GPIO,
 	.ops	= &gpio_davinci_ops,
 	.ofdata_to_platdata = of_match_ptr(davinci_gpio_ofdata_to_platdata),
diff --git a/drivers/gpio/mxs_gpio.c b/drivers/gpio/mxs_gpio.c
index 815339a..cb79726 100644
--- a/drivers/gpio/mxs_gpio.c
+++ b/drivers/gpio/mxs_gpio.c
@@ -299,12 +299,8 @@
 };
 #endif
 
-U_BOOT_DRIVER(gpio_mxs) = {
-#ifdef CONFIG_MX28
-	.name = "fsl_imx28_gpio",
-#else /* CONFIG_MX23 */
+U_BOOT_DRIVER(fsl_imx23_gpio) = {
 	.name = "fsl_imx23_gpio",
-#endif
 	.id	= UCLASS_GPIO,
 	.ops	= &gpio_mxs_ops,
 	.probe	= mxs_gpio_probe,
@@ -315,4 +311,6 @@
 	.ofdata_to_platdata = mxs_ofdata_to_platdata,
 #endif
 };
+
+U_BOOT_DRIVER_ALIAS(fsl_imx23_gpio, fsl_imx28_gpio)
 #endif /* DM_GPIO */
diff --git a/drivers/gpio/rk_gpio.c b/drivers/gpio/rk_gpio.c
index 3d96678..8cc2885 100644
--- a/drivers/gpio/rk_gpio.c
+++ b/drivers/gpio/rk_gpio.c
@@ -172,8 +172,8 @@
 	{ }
 };
 
-U_BOOT_DRIVER(gpio_rockchip) = {
-	.name	= "gpio_rockchip",
+U_BOOT_DRIVER(rockchip_gpio_bank) = {
+	.name	= "rockchip_gpio_bank",
 	.id	= UCLASS_GPIO,
 	.of_match = rockchip_gpio_ids,
 	.ops	= &gpio_rockchip_ops,
diff --git a/drivers/gpio/sandbox.c b/drivers/gpio/sandbox.c
index 98b7fa4..b9a1d65 100644
--- a/drivers/gpio/sandbox.c
+++ b/drivers/gpio/sandbox.c
@@ -244,8 +244,8 @@
 	{ }
 };
 
-U_BOOT_DRIVER(gpio_sandbox) = {
-	.name	= "gpio_sandbox",
+U_BOOT_DRIVER(sandbox_gpio) = {
+	.name	= "sandbox_gpio",
 	.id	= UCLASS_GPIO,
 	.of_match = sandbox_gpio_ids,
 	.ofdata_to_platdata = sandbox_gpio_ofdata_to_platdata,
@@ -254,6 +254,8 @@
 	.ops	= &gpio_sandbox_ops,
 };
 
+U_BOOT_DRIVER_ALIAS(sandbox_gpio, sandbox_gpio_alias)
+
 /* pincontrol: used only to check GPIO pin configuration (pinmux command) */
 
 struct sb_pinctrl_priv {
diff --git a/drivers/i2c/rk_i2c.c b/drivers/i2c/rk_i2c.c
index fa6f69f..6594610 100644
--- a/drivers/i2c/rk_i2c.c
+++ b/drivers/i2c/rk_i2c.c
@@ -485,8 +485,8 @@
 	{ }
 };
 
-U_BOOT_DRIVER(i2c_rockchip) = {
-	.name	= "i2c_rockchip",
+U_BOOT_DRIVER(rockchip_rk3066_i2c) = {
+	.name	= "rockchip_rk3066_i2c",
 	.id	= UCLASS_I2C,
 	.of_match = rockchip_i2c_ids,
 	.ofdata_to_platdata = rockchip_i2c_ofdata_to_platdata,
@@ -494,3 +494,5 @@
 	.priv_auto_alloc_size = sizeof(struct rk_i2c),
 	.ops	= &rockchip_i2c_ops,
 };
+
+U_BOOT_DRIVER_ALIAS(rockchip_rk3066_i2c, rockchip_rk3288_i2c)
diff --git a/drivers/input/cros_ec_keyb.c b/drivers/input/cros_ec_keyb.c
index 6f12ec8..00bf58f 100644
--- a/drivers/input/cros_ec_keyb.c
+++ b/drivers/input/cros_ec_keyb.c
@@ -225,8 +225,8 @@
 	{ }
 };
 
-U_BOOT_DRIVER(cros_ec_kbd) = {
-	.name	= "cros_ec_kbd",
+U_BOOT_DRIVER(google_cros_ec_keyb) = {
+	.name	= "google_cros_ec_keyb",
 	.id	= UCLASS_KEYBOARD,
 	.of_match = cros_ec_kbd_ids,
 	.probe = cros_ec_kbd_probe,
diff --git a/drivers/misc/cros_ec_sandbox.c b/drivers/misc/cros_ec_sandbox.c
index c9fa7ab..a191f06 100644
--- a/drivers/misc/cros_ec_sandbox.c
+++ b/drivers/misc/cros_ec_sandbox.c
@@ -572,8 +572,8 @@
 	{ }
 };
 
-U_BOOT_DRIVER(cros_ec_sandbox) = {
-	.name		= "cros_ec_sandbox",
+U_BOOT_DRIVER(google_cros_ec_sandbox) = {
+	.name		= "google_cros_ec_sandbox",
 	.id		= UCLASS_CROS_EC,
 	.of_match	= cros_ec_ids,
 	.probe		= cros_ec_probe,
diff --git a/drivers/misc/irq-uclass.c b/drivers/misc/irq-uclass.c
index 16dc0be..ec70866 100644
--- a/drivers/misc/irq-uclass.c
+++ b/drivers/misc/irq-uclass.c
@@ -64,17 +64,15 @@
 }
 
 #if CONFIG_IS_ENABLED(OF_PLATDATA)
-int irq_get_by_index_platdata(struct udevice *dev, int index,
-			      struct phandle_1_arg *cells, struct irq *irq)
+int irq_get_by_driver_info(struct udevice *dev,
+			   struct phandle_1_arg *cells, struct irq *irq)
 {
 	int ret;
 
-	if (index != 0)
-		return -ENOSYS;
-	ret = uclass_get_device(UCLASS_IRQ, 0, &irq->dev);
+	ret = device_get_by_driver_info(cells->node, &irq->dev);
 	if (ret)
 		return ret;
-	irq->id = cells[0].arg[0];
+	irq->id = cells->arg[0];
 
 	return 0;
 }
diff --git a/drivers/mmc/bcm2835_sdhci.c b/drivers/mmc/bcm2835_sdhci.c
index dc3dffb..5cdf3c5 100644
--- a/drivers/mmc/bcm2835_sdhci.c
+++ b/drivers/mmc/bcm2835_sdhci.c
@@ -210,7 +210,7 @@
 	priv->last_write = 0;
 
 	host->name = dev->name;
-	host->ioaddr = (void *)base;
+	host->ioaddr = (void *)(uintptr_t)base;
 	host->quirks = SDHCI_QUIRK_BROKEN_VOLTAGE | SDHCI_QUIRK_BROKEN_R1B |
 		SDHCI_QUIRK_WAIT_SEND_CMD | SDHCI_QUIRK_NO_HISPD_BIT;
 	host->max_clk = emmc_freq;
diff --git a/drivers/mmc/davinci_mmc.c b/drivers/mmc/davinci_mmc.c
index 4ef9f7c..f3ccd02 100644
--- a/drivers/mmc/davinci_mmc.c
+++ b/drivers/mmc/davinci_mmc.c
@@ -522,7 +522,7 @@
 	{},
 };
 #endif
-U_BOOT_DRIVER(davinci_mmc_drv) = {
+U_BOOT_DRIVER(ti_da830_mmc) = {
 	.name = "davinci_mmc",
 	.id		= UCLASS_MMC,
 #if CONFIG_IS_ENABLED(OF_CONTROL)
diff --git a/drivers/mmc/ftsdc010_mci.c b/drivers/mmc/ftsdc010_mci.c
index b37523e..fb28f01 100644
--- a/drivers/mmc/ftsdc010_mci.c
+++ b/drivers/mmc/ftsdc010_mci.c
@@ -439,7 +439,7 @@
 	chip->priv = dev;
 	chip->dev_index = 1;
 	memcpy(priv->minmax, dtplat->clock_freq_min_max, sizeof(priv->minmax));
-	ret = clk_get_by_index_platdata(dev, 0, dtplat->clocks, &priv->clk);
+	ret = clk_get_by_driver_info(dev, dtplat->clocks, &priv->clk);
 	if (ret < 0)
 		return ret;
 #endif
diff --git a/drivers/mmc/mxsmmc.c b/drivers/mmc/mxsmmc.c
index e3c352b..c6a06b9 100644
--- a/drivers/mmc/mxsmmc.c
+++ b/drivers/mmc/mxsmmc.c
@@ -711,12 +711,8 @@
 };
 #endif
 
-U_BOOT_DRIVER(mxsmmc) = {
-#ifdef CONFIG_MX28
-	.name = "fsl_imx28_mmc",
-#else /* CONFIG_MX23 */
+U_BOOT_DRIVER(fsl_imx23_mmc) = {
 	.name = "fsl_imx23_mmc",
-#endif
 	.id	= UCLASS_MMC,
 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
 	.of_match = mxsmmc_ids,
@@ -731,4 +727,5 @@
 	.platdata_auto_alloc_size = sizeof(struct mxsmmc_platdata),
 };
 
+U_BOOT_DRIVER_ALIAS(fsl_imx23_mmc, fsl_imx28_mmc)
 #endif /* CONFIG_DM_MMC */
diff --git a/drivers/mmc/rockchip_dw_mmc.c b/drivers/mmc/rockchip_dw_mmc.c
index 638107a..f1dafa6 100644
--- a/drivers/mmc/rockchip_dw_mmc.c
+++ b/drivers/mmc/rockchip_dw_mmc.c
@@ -122,7 +122,7 @@
 	priv->minmax[0] = 400000;  /*  400 kHz */
 	priv->minmax[1] = dtplat->max_frequency;
 
-	ret = clk_get_by_index_platdata(dev, 0, dtplat->clocks, &priv->clk);
+	ret = clk_get_by_driver_info(dev, dtplat->clocks, &priv->clk);
 	if (ret < 0)
 		return ret;
 #else
@@ -168,7 +168,7 @@
 	{ }
 };
 
-U_BOOT_DRIVER(rockchip_dwmmc_drv) = {
+U_BOOT_DRIVER(rockchip_rk3288_dw_mshc) = {
 	.name		= "rockchip_rk3288_dw_mshc",
 	.id		= UCLASS_MMC,
 	.of_match	= rockchip_dwmmc_ids,
@@ -180,6 +180,9 @@
 	.platdata_auto_alloc_size = sizeof(struct rockchip_mmc_plat),
 };
 
+U_BOOT_DRIVER_ALIAS(rockchip_rk3288_dw_mshc, rockchip_rk3328_dw_mshc)
+U_BOOT_DRIVER_ALIAS(rockchip_rk3288_dw_mshc, rockchip_rk3368_dw_mshc)
+
 #ifdef CONFIG_PWRSEQ
 static int rockchip_dwmmc_pwrseq_set_power(struct udevice *dev, bool enable)
 {
diff --git a/drivers/mmc/rockchip_sdhci.c b/drivers/mmc/rockchip_sdhci.c
index b440996..b073f1a 100644
--- a/drivers/mmc/rockchip_sdhci.c
+++ b/drivers/mmc/rockchip_sdhci.c
@@ -46,7 +46,7 @@
 	host->name = dev->name;
 	host->ioaddr = map_sysmem(dtplat->reg[0], dtplat->reg[1]);
 	max_frequency = dtplat->max_frequency;
-	ret = clk_get_by_index_platdata(dev, 0, dtplat->clocks, &clk);
+	ret = clk_get_by_driver_info(dev, dtplat->clocks, &clk);
 #else
 	max_frequency = dev_read_u32_default(dev, "max-frequency", 0);
 	ret = clk_get_by_index(dev, 0, &clk);
diff --git a/drivers/mtd/nand/raw/denali.c b/drivers/mtd/nand/raw/denali.c
index 15e9029..ab91db8 100644
--- a/drivers/mtd/nand/raw/denali.c
+++ b/drivers/mtd/nand/raw/denali.c
@@ -1220,6 +1220,17 @@
 	return 0;
 }
 
+int denali_wait_reset_complete(struct denali_nand_info *denali)
+{
+	u32 irq_status;
+
+	irq_status = denali_wait_for_irq(denali, INTR__RST_COMP);
+	if (!(irq_status & INTR__RST_COMP))
+		return -EIO;
+
+	return 0;
+}
+
 int denali_init(struct denali_nand_info *denali)
 {
 	struct nand_chip *chip = &denali->nand;
diff --git a/drivers/mtd/nand/raw/denali.h b/drivers/mtd/nand/raw/denali.h
index 019deda..6cd02b2 100644
--- a/drivers/mtd/nand/raw/denali.h
+++ b/drivers/mtd/nand/raw/denali.h
@@ -321,6 +321,7 @@
 #define DENALI_CAP_DMA_64BIT			BIT(1)
 
 int denali_calc_ecc_bytes(int step_size, int strength);
+int denali_wait_reset_complete(struct denali_nand_info *denali);
 int denali_init(struct denali_nand_info *denali);
 
 #endif /* __DENALI_H__ */
diff --git a/drivers/mtd/nand/raw/denali_dt.c b/drivers/mtd/nand/raw/denali_dt.c
index 2728e80..8318ff5 100644
--- a/drivers/mtd/nand/raw/denali_dt.c
+++ b/drivers/mtd/nand/raw/denali_dt.c
@@ -148,6 +148,8 @@
 	if (ret) {
 		dev_warn(dev, "Can't get reset: %d\n", ret);
 	} else {
+		reset_assert_bulk(&resets);
+		udelay(2);
 		reset_deassert_bulk(&resets);
 
 		/*
@@ -155,7 +157,11 @@
 		 * kicked (bootstrap process). The driver must wait until it is
 		 * finished. Otherwise, it will result in unpredictable behavior.
 		 */
-		udelay(200);
+		ret = denali_wait_reset_complete(denali);
+		if (ret) {
+			dev_err(denali->dev, "reset not completed.\n");
+			return ret;
+		}
 	}
 
 	return denali_init(denali);
diff --git a/drivers/mtd/spi/sandbox.c b/drivers/mtd/spi/sandbox.c
index 8cbe97e..0b602dc 100644
--- a/drivers/mtd/spi/sandbox.c
+++ b/drivers/mtd/spi/sandbox.c
@@ -44,7 +44,6 @@
 	SF_WRITE_STATUS, /* write the flash's status register */
 };
 
-#if CONFIG_IS_ENABLED(LOG)
 static const char *sandbox_sf_state_name(enum sandbox_sf_state state)
 {
 	static const char * const states[] = {
@@ -53,7 +52,6 @@
 	};
 	return states[state];
 }
-#endif /* LOG */
 
 /* Bits for the status register */
 #define STAT_WIP	(1 << 0)
diff --git a/drivers/mtd/spi/sf-uclass.c b/drivers/mtd/spi/sf-uclass.c
index 9ce2ecb..09c1143 100644
--- a/drivers/mtd/spi/sf-uclass.c
+++ b/drivers/mtd/spi/sf-uclass.c
@@ -68,7 +68,7 @@
 	str = strdup(name);
 #endif
 	ret = spi_get_bus_and_cs(busnum, cs, max_hz, spi_mode,
-				  "spi_flash_std", str, &bus, &slave);
+				  "jedec_spi_nor", str, &bus, &slave);
 	if (ret)
 		return ret;
 
diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c
index afda241..475f6c3 100644
--- a/drivers/mtd/spi/sf_probe.c
+++ b/drivers/mtd/spi/sf_probe.c
@@ -160,8 +160,8 @@
 	{ }
 };
 
-U_BOOT_DRIVER(spi_flash_std) = {
-	.name		= "spi_flash_std",
+U_BOOT_DRIVER(jedec_spi_nor) = {
+	.name		= "jedec_spi_nor",
 	.id		= UCLASS_SPI_FLASH,
 	.of_match	= spi_flash_std_ids,
 	.probe		= spi_flash_std_probe,
@@ -170,4 +170,6 @@
 	.ops		= &spi_flash_std_ops,
 };
 
+U_BOOT_DRIVER_ALIAS(jedec_spi_nor, spansion_m25p16)
+
 #endif /* CONFIG_DM_SPI_FLASH */
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index 6d8c22a..7e1e51d9 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -205,4 +205,13 @@
 	  Say Y here if you want to enable PCIe controller support on
 	  Rockchip SoCs.
 
+config PCI_BRCMSTB
+	bool "Broadcom STB PCIe controller"
+	depends on DM_PCI
+	depends on ARCH_BCM283X
+	help
+	  Say Y here if you want to enable support for PCIe controller
+	  on Broadcom set-top-box (STB) SoCs.
+	  This driver currently supports only BCM2711 SoC and RC mode
+	  of the controller.
 endif
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index 955351c..2909291 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -44,3 +44,4 @@
 obj-$(CONFIG_PCI_KEYSTONE) += pcie_dw_ti.o
 obj-$(CONFIG_PCIE_MEDIATEK) += pcie_mediatek.o
 obj-$(CONFIG_PCIE_ROCKCHIP) += pcie_rockchip.o pcie_rockchip_phy.o
+obj-$(CONFIG_PCI_BRCMSTB) += pcie_brcmstb.o
diff --git a/drivers/pci/pci-rcar-gen3.c b/drivers/pci/pci-rcar-gen3.c
index df7b37a..1f51854 100644
--- a/drivers/pci/pci-rcar-gen3.c
+++ b/drivers/pci/pci-rcar-gen3.c
@@ -118,14 +118,6 @@
 #define RCAR_PCI_MAX_RESOURCES	4
 #define MAX_NR_INBOUND_MAPS	6
 
-#define PCI_EXP_FLAGS		2		/* Capabilities register */
-#define PCI_EXP_FLAGS_TYPE	0x00f0		/* Device/Port type */
-#define PCI_EXP_TYPE_ROOT_PORT	0x4		/* Root Port */
-#define PCI_EXP_LNKCAP		12		/* Link Capabilities */
-#define PCI_EXP_LNKCAP_DLLLARC	0x00100000	/* Data Link Layer Link Active Reporting Capable */
-#define PCI_EXP_SLTCAP		20		/* Slot Capabilities */
-#define PCI_EXP_SLTCAP_PSN	0xfff80000	/* Physical Slot Number */
-
 enum {
 	RCAR_PCI_ACCESS_READ,
 	RCAR_PCI_ACCESS_WRITE,
diff --git a/drivers/pci/pci_rom.c b/drivers/pci/pci_rom.c
index 6a9bc49..fa29d69 100644
--- a/drivers/pci/pci_rom.c
+++ b/drivers/pci/pci_rom.c
@@ -22,6 +22,8 @@
  * Copyright 1997 -- 1999 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
  */
 
+#define LOG_CATEGORY UCLASS_PCI
+
 #include <common.h>
 #include <bios_emul.h>
 #include <bootstage.h>
@@ -344,7 +346,16 @@
 	default:
 		return -EPROTONOSUPPORT;
 	}
+
+	/* Use double buffering if enabled */
+	if (IS_ENABLED(CONFIG_VIDEO_COPY)) {
+		if (!plat->base)
+			return log_msg_ret("copy", -ENFILE);
+		plat->copy_base = vesa->phys_base_ptr;
+	} else {
+		plat->base = vesa->phys_base_ptr;
+	}
-	plat->base = vesa->phys_base_ptr;
+	log_debug("base = %lx, copy_base = %lx\n", plat->base, plat->copy_base);
 	plat->size = vesa->bytes_per_scanline * vesa->y_resolution;
 
 	return 0;
@@ -372,6 +383,15 @@
 
 	ret = vbe_setup_video_priv(&mode_info.vesa, uc_priv, plat);
 	if (ret) {
+		if (ret == -ENFILE) {
+			/*
+			 * See video-uclass.c for how to set up reserved memory
+			 * in your video driver
+			 */
+			log_err("CONFIG_VIDEO_COPY enabled but driver '%s' set up no reserved memory\n",
+				dev->driver->name);
+		}
+
 		debug("No video mode configured\n");
 		return ret;
 	}
diff --git a/drivers/pci/pcie_brcmstb.c b/drivers/pci/pcie_brcmstb.c
new file mode 100644
index 0000000..dade79e
--- /dev/null
+++ b/drivers/pci/pcie_brcmstb.c
@@ -0,0 +1,623 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Broadcom STB PCIe controller driver
+ *
+ * Copyright (C) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Based on upstream Linux kernel driver:
+ * drivers/pci/controller/pcie-brcmstb.c
+ * Copyright (C) 2009 - 2017 Broadcom
+ *
+ * Based driver by Nicolas Saenz Julienne
+ * Copyright (C) 2020 Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <dm.h>
+#include <dm/ofnode.h>
+#include <pci.h>
+#include <asm/io.h>
+#include <linux/bitfield.h>
+#include <linux/log2.h>
+#include <linux/iopoll.h>
+
+/* Offset of the mandatory PCIe capability config registers */
+#define BRCM_PCIE_CAP_REGS				0x00ac
+
+/* The PCIe controller register offsets */
+#define PCIE_RC_CFG_VENDOR_SPECIFIC_REG1		0x0188
+#define  VENDOR_SPECIFIC_REG1_ENDIAN_MODE_BAR2_MASK	0xc
+#define  VENDOR_SPECIFIC_REG1_LITTLE_ENDIAN		0x0
+
+#define PCIE_RC_CFG_PRIV1_ID_VAL3			0x043c
+#define  CFG_PRIV1_ID_VAL3_CLASS_CODE_MASK		0xffffff
+
+#define PCIE_RC_DL_MDIO_ADDR				0x1100
+#define PCIE_RC_DL_MDIO_WR_DATA				0x1104
+#define PCIE_RC_DL_MDIO_RD_DATA				0x1108
+
+#define PCIE_MISC_MISC_CTRL				0x4008
+#define  MISC_CTRL_SCB_ACCESS_EN_MASK			0x1000
+#define  MISC_CTRL_CFG_READ_UR_MODE_MASK		0x2000
+#define  MISC_CTRL_MAX_BURST_SIZE_MASK			0x300000
+#define  MISC_CTRL_MAX_BURST_SIZE_128			0x0
+#define  MISC_CTRL_SCB0_SIZE_MASK			0xf8000000
+
+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO		0x400c
+#define PCIE_MEM_WIN0_LO(win)	\
+		PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO + ((win) * 4)
+
+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_HI		0x4010
+#define PCIE_MEM_WIN0_HI(win)	\
+		PCIE_MISC_CPU_2_PCIE_MEM_WIN0_HI + ((win) * 4)
+
+#define PCIE_MISC_RC_BAR1_CONFIG_LO			0x402c
+#define  RC_BAR1_CONFIG_LO_SIZE_MASK			0x1f
+
+#define PCIE_MISC_RC_BAR2_CONFIG_LO			0x4034
+#define  RC_BAR2_CONFIG_LO_SIZE_MASK			0x1f
+#define PCIE_MISC_RC_BAR2_CONFIG_HI			0x4038
+
+#define PCIE_MISC_RC_BAR3_CONFIG_LO			0x403c
+#define  RC_BAR3_CONFIG_LO_SIZE_MASK			0x1f
+
+#define PCIE_MISC_PCIE_STATUS				0x4068
+#define  STATUS_PCIE_PORT_MASK				0x80
+#define  STATUS_PCIE_PORT_SHIFT				7
+#define  STATUS_PCIE_DL_ACTIVE_MASK			0x20
+#define  STATUS_PCIE_DL_ACTIVE_SHIFT			5
+#define  STATUS_PCIE_PHYLINKUP_MASK			0x10
+#define  STATUS_PCIE_PHYLINKUP_SHIFT			4
+
+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT	0x4070
+#define  MEM_WIN0_BASE_LIMIT_LIMIT_MASK			0xfff00000
+#define  MEM_WIN0_BASE_LIMIT_BASE_MASK			0xfff0
+#define  MEM_WIN0_BASE_LIMIT_BASE_HI_SHIFT		12
+#define PCIE_MEM_WIN0_BASE_LIMIT(win)	\
+	 PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT + ((win) * 4)
+
+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI		0x4080
+#define  MEM_WIN0_BASE_HI_BASE_MASK			0xff
+#define PCIE_MEM_WIN0_BASE_HI(win)	\
+	 PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI + ((win) * 8)
+
+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI		0x4084
+#define  PCIE_MEM_WIN0_LIMIT_HI_LIMIT_MASK		0xff
+#define PCIE_MEM_WIN0_LIMIT_HI(win)	\
+	 PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI + ((win) * 8)
+
+#define PCIE_MISC_HARD_PCIE_HARD_DEBUG			0x4204
+#define  PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK	0x2
+#define  PCIE_HARD_DEBUG_SERDES_IDDQ_MASK		0x08000000
+
+#define PCIE_MSI_INTR2_CLR				0x4508
+#define PCIE_MSI_INTR2_MASK_SET				0x4510
+
+#define PCIE_EXT_CFG_DATA				0x8000
+
+#define PCIE_EXT_CFG_INDEX				0x9000
+#define  PCIE_EXT_BUSNUM_SHIFT				20
+#define  PCIE_EXT_SLOT_SHIFT				15
+#define  PCIE_EXT_FUNC_SHIFT				12
+
+#define PCIE_RGR1_SW_INIT_1				0x9210
+#define  RGR1_SW_INIT_1_PERST_MASK			0x1
+#define  RGR1_SW_INIT_1_INIT_MASK			0x2
+
+/* PCIe parameters */
+#define BRCM_NUM_PCIE_OUT_WINS				4
+
+/* MDIO registers */
+#define MDIO_PORT0					0x0
+#define MDIO_DATA_MASK					0x7fffffff
+#define MDIO_DATA_SHIFT					0
+#define MDIO_PORT_MASK					0xf0000
+#define MDIO_PORT_SHIFT					16
+#define MDIO_REGAD_MASK					0xffff
+#define MDIO_REGAD_SHIFT				0
+#define MDIO_CMD_MASK					0xfff00000
+#define MDIO_CMD_SHIFT					20
+#define MDIO_CMD_READ					0x1
+#define MDIO_CMD_WRITE					0x0
+#define MDIO_DATA_DONE_MASK				0x80000000
+#define SSC_REGS_ADDR					0x1100
+#define SET_ADDR_OFFSET					0x1f
+#define SSC_CNTL_OFFSET					0x2
+#define SSC_CNTL_OVRD_EN_MASK				0x8000
+#define SSC_CNTL_OVRD_VAL_MASK				0x4000
+#define SSC_STATUS_OFFSET				0x1
+#define SSC_STATUS_SSC_MASK				0x400
+#define SSC_STATUS_SSC_SHIFT				10
+#define SSC_STATUS_PLL_LOCK_MASK			0x800
+#define SSC_STATUS_PLL_LOCK_SHIFT			11
+
+/**
+ * struct brcm_pcie - the PCIe controller state
+ * @base: Base address of memory mapped IO registers of the controller
+ * @gen: Non-zero value indicates limitation of the PCIe controller operation
+ *       to a specific generation (1, 2 or 3)
+ * @ssc: true indicates active Spread Spectrum Clocking operation
+ */
+struct brcm_pcie {
+	void __iomem		*base;
+
+	int			gen;
+	bool			ssc;
+};
+
+/**
+ * brcm_pcie_encode_ibar_size() - Encode the inbound "BAR" region size
+ * @size: The inbound region size
+ *
+ * This function converts size of the inbound "BAR" region to the non-linear
+ * values of the PCIE_MISC_RC_BAR[123]_CONFIG_LO register SIZE field.
+ *
+ * Return: The encoded inbound region size
+ */
+static int brcm_pcie_encode_ibar_size(u64 size)
+{
+	int log2_in = ilog2(size);
+
+	if (log2_in >= 12 && log2_in <= 15)
+		/* Covers 4KB to 32KB (inclusive) */
+		return (log2_in - 12) + 0x1c;
+	else if (log2_in >= 16 && log2_in <= 37)
+		/* Covers 64KB to 32GB, (inclusive) */
+		return log2_in - 15;
+
+	/* Something is awry so disable */
+	return 0;
+}
+
+/**
+ * brcm_pcie_rc_mode() - Check if PCIe controller is in RC mode
+ * @pcie: Pointer to the PCIe controller state
+ *
+ * The controller is capable of serving in both RC and EP roles.
+ *
+ * Return: true for RC mode, false for EP mode.
+ */
+static bool brcm_pcie_rc_mode(struct brcm_pcie *pcie)
+{
+	u32 val;
+
+	val = readl(pcie->base + PCIE_MISC_PCIE_STATUS);
+
+	return (val & STATUS_PCIE_PORT_MASK) >> STATUS_PCIE_PORT_SHIFT;
+}
+
+/**
+ * brcm_pcie_link_up() - Check whether the PCIe link is up
+ * @pcie: Pointer to the PCIe controller state
+ *
+ * Return: true if the link is up, false otherwise.
+ */
+static bool brcm_pcie_link_up(struct brcm_pcie *pcie)
+{
+	u32 val, dla, plu;
+
+	val = readl(pcie->base + PCIE_MISC_PCIE_STATUS);
+	dla = (val & STATUS_PCIE_DL_ACTIVE_MASK) >> STATUS_PCIE_DL_ACTIVE_SHIFT;
+	plu = (val & STATUS_PCIE_PHYLINKUP_MASK) >> STATUS_PCIE_PHYLINKUP_SHIFT;
+
+	return dla && plu;
+}
+
+static int brcm_pcie_config_address(const struct udevice *dev, pci_dev_t bdf,
+				    uint offset, void **paddress)
+{
+	struct brcm_pcie *pcie = dev_get_priv(dev);
+	unsigned int pci_bus = PCI_BUS(bdf);
+	unsigned int pci_dev = PCI_DEV(bdf);
+	unsigned int pci_func = PCI_FUNC(bdf);
+	int idx;
+
+	/*
+	 * Busses 0 (host PCIe bridge) and 1 (its immediate child)
+	 * are limited to a single device each
+	 */
+	if (pci_bus < 2 && pci_dev > 0)
+		return -EINVAL;
+
+	/* Accesses to the RC go right to the RC registers */
+	if (pci_bus == 0) {
+		*paddress = pcie->base + offset;
+		return 0;
+	}
+
+	/* For devices, write to the config space index register */
+	idx = (pci_bus << PCIE_EXT_BUSNUM_SHIFT)
+		| (pci_dev << PCIE_EXT_SLOT_SHIFT)
+		| (pci_func << PCIE_EXT_FUNC_SHIFT);
+
+	writel(idx, pcie->base + PCIE_EXT_CFG_INDEX);
+	*paddress = pcie->base + PCIE_EXT_CFG_DATA + offset;
+
+	return 0;
+}
+
+static int brcm_pcie_read_config(const struct udevice *bus, pci_dev_t bdf,
+				 uint offset, ulong *valuep,
+				 enum pci_size_t size)
+{
+	return pci_generic_mmap_read_config(bus, brcm_pcie_config_address,
+					    bdf, offset, valuep, size);
+}
+
+static int brcm_pcie_write_config(struct udevice *bus, pci_dev_t bdf,
+				  uint offset, ulong value,
+				  enum pci_size_t size)
+{
+	return pci_generic_mmap_write_config(bus, brcm_pcie_config_address,
+					     bdf, offset, value, size);
+}
+
+static const char *link_speed_to_str(unsigned int cls)
+{
+	switch (cls) {
+	case PCI_EXP_LNKSTA_CLS_2_5GB: return "2.5";
+	case PCI_EXP_LNKSTA_CLS_5_0GB: return "5.0";
+	case PCI_EXP_LNKSTA_CLS_8_0GB: return "8.0";
+	default:
+		break;
+	}
+
+	return "??";
+}
+
+static u32 brcm_pcie_mdio_form_pkt(unsigned int port, unsigned int regad,
+				   unsigned int cmd)
+{
+	u32 pkt;
+
+	pkt = (port << MDIO_PORT_SHIFT) & MDIO_PORT_MASK;
+	pkt |= (regad << MDIO_REGAD_SHIFT) & MDIO_REGAD_MASK;
+	pkt |= (cmd << MDIO_CMD_SHIFT) & MDIO_CMD_MASK;
+
+	return pkt;
+}
+
+/**
+ * brcm_pcie_mdio_read() - Perform a register read on the internal MDIO bus
+ * @base: Pointer to the PCIe controller IO registers
+ * @port: The MDIO port number
+ * @regad: The register address
+ * @val: A pointer at which to store the read value
+ *
+ * Return: 0 on success and register value in @val, negative error value
+ *         on failure.
+ */
+static int brcm_pcie_mdio_read(void __iomem *base, unsigned int port,
+			       unsigned int regad, u32 *val)
+{
+	u32 data, addr;
+	int ret;
+
+	addr = brcm_pcie_mdio_form_pkt(port, regad, MDIO_CMD_READ);
+	writel(addr, base + PCIE_RC_DL_MDIO_ADDR);
+	readl(base + PCIE_RC_DL_MDIO_ADDR);
+
+	ret = readl_poll_timeout(base + PCIE_RC_DL_MDIO_RD_DATA, data,
+				 (data & MDIO_DATA_DONE_MASK), 100);
+
+	*val = data & MDIO_DATA_MASK;
+
+	return ret;
+}
+
+/**
+ * brcm_pcie_mdio_write() - Perform a register write on the internal MDIO bus
+ * @base: Pointer to the PCIe controller IO registers
+ * @port: The MDIO port number
+ * @regad: Address of the register
+ * @wrdata: The value to write
+ *
+ * Return: 0 on success, negative error value on failure.
+ */
+static int brcm_pcie_mdio_write(void __iomem *base, unsigned int port,
+				unsigned int regad, u16 wrdata)
+{
+	u32 data, addr;
+
+	addr = brcm_pcie_mdio_form_pkt(port, regad, MDIO_CMD_WRITE);
+	writel(addr, base + PCIE_RC_DL_MDIO_ADDR);
+	readl(base + PCIE_RC_DL_MDIO_ADDR);
+	writel(MDIO_DATA_DONE_MASK | wrdata, base + PCIE_RC_DL_MDIO_WR_DATA);
+
+	return readl_poll_timeout(base + PCIE_RC_DL_MDIO_WR_DATA, data,
+				  !(data & MDIO_DATA_DONE_MASK), 100);
+}
+
+/**
+ * brcm_pcie_set_ssc() - Configure the controller for Spread Spectrum Clocking
+ * @base: pointer to the PCIe controller IO registers
+ *
+ * Return: 0 on success, negative error value on failure.
+ */
+static int brcm_pcie_set_ssc(void __iomem *base)
+{
+	int pll, ssc;
+	int ret;
+	u32 tmp;
+
+	ret = brcm_pcie_mdio_write(base, MDIO_PORT0, SET_ADDR_OFFSET,
+				   SSC_REGS_ADDR);
+	if (ret < 0)
+		return ret;
+
+	ret = brcm_pcie_mdio_read(base, MDIO_PORT0, SSC_CNTL_OFFSET, &tmp);
+	if (ret < 0)
+		return ret;
+
+	tmp |= (SSC_CNTL_OVRD_EN_MASK | SSC_CNTL_OVRD_VAL_MASK);
+
+	ret = brcm_pcie_mdio_write(base, MDIO_PORT0, SSC_CNTL_OFFSET, tmp);
+	if (ret < 0)
+		return ret;
+
+	udelay(1000);
+	ret = brcm_pcie_mdio_read(base, MDIO_PORT0, SSC_STATUS_OFFSET, &tmp);
+	if (ret < 0)
+		return ret;
+
+	ssc = (tmp & SSC_STATUS_SSC_MASK) >> SSC_STATUS_SSC_SHIFT;
+	pll = (tmp & SSC_STATUS_PLL_LOCK_MASK) >> SSC_STATUS_PLL_LOCK_SHIFT;
+
+	return ssc && pll ? 0 : -EIO;
+}
+
+/**
+ * brcm_pcie_set_gen() - Limits operation to a specific generation (1, 2 or 3)
+ * @pcie: pointer to the PCIe controller state
+ * @gen: PCIe generation to limit the controller's operation to
+ */
+static void brcm_pcie_set_gen(struct brcm_pcie *pcie, unsigned int gen)
+{
+	void __iomem *cap_base = pcie->base + BRCM_PCIE_CAP_REGS;
+
+	u16 lnkctl2 = readw(cap_base + PCI_EXP_LNKCTL2);
+	u32 lnkcap = readl(cap_base + PCI_EXP_LNKCAP);
+
+	lnkcap = (lnkcap & ~PCI_EXP_LNKCAP_SLS) | gen;
+	writel(lnkcap, cap_base + PCI_EXP_LNKCAP);
+
+	lnkctl2 = (lnkctl2 & ~0xf) | gen;
+	writew(lnkctl2, cap_base + PCI_EXP_LNKCTL2);
+}
+
+static void brcm_pcie_set_outbound_win(struct brcm_pcie *pcie,
+				       unsigned int win, u64 phys_addr,
+				       u64 pcie_addr, u64 size)
+{
+	void __iomem *base = pcie->base;
+	u32 phys_addr_mb_high, limit_addr_mb_high;
+	phys_addr_t phys_addr_mb, limit_addr_mb;
+	int high_addr_shift;
+	u32 tmp;
+
+	/* Set the base of the pcie_addr window */
+	writel(lower_32_bits(pcie_addr), base + PCIE_MEM_WIN0_LO(win));
+	writel(upper_32_bits(pcie_addr), base + PCIE_MEM_WIN0_HI(win));
+
+	/* Write the addr base & limit lower bits (in MBs) */
+	phys_addr_mb = phys_addr / SZ_1M;
+	limit_addr_mb = (phys_addr + size - 1) / SZ_1M;
+
+	tmp = readl(base + PCIE_MEM_WIN0_BASE_LIMIT(win));
+	u32p_replace_bits(&tmp, phys_addr_mb,
+			  MEM_WIN0_BASE_LIMIT_BASE_MASK);
+	u32p_replace_bits(&tmp, limit_addr_mb,
+			  MEM_WIN0_BASE_LIMIT_LIMIT_MASK);
+	writel(tmp, base + PCIE_MEM_WIN0_BASE_LIMIT(win));
+
+	/* Write the cpu & limit addr upper bits */
+	high_addr_shift = MEM_WIN0_BASE_LIMIT_BASE_HI_SHIFT;
+	phys_addr_mb_high = phys_addr_mb >> high_addr_shift;
+	tmp = readl(base + PCIE_MEM_WIN0_BASE_HI(win));
+	u32p_replace_bits(&tmp, phys_addr_mb_high,
+			  MEM_WIN0_BASE_HI_BASE_MASK);
+	writel(tmp, base + PCIE_MEM_WIN0_BASE_HI(win));
+
+	limit_addr_mb_high = limit_addr_mb >> high_addr_shift;
+	tmp = readl(base + PCIE_MEM_WIN0_LIMIT_HI(win));
+	u32p_replace_bits(&tmp, limit_addr_mb_high,
+			  PCIE_MEM_WIN0_LIMIT_HI_LIMIT_MASK);
+	writel(tmp, base + PCIE_MEM_WIN0_LIMIT_HI(win));
+}
+
+static int brcm_pcie_probe(struct udevice *dev)
+{
+	struct udevice *ctlr = pci_get_controller(dev);
+	struct pci_controller *hose = dev_get_uclass_priv(ctlr);
+	struct brcm_pcie *pcie = dev_get_priv(dev);
+	void __iomem *base = pcie->base;
+	bool ssc_good = false;
+	int num_out_wins = 0;
+	u64 rc_bar2_offset, rc_bar2_size;
+	unsigned int scb_size_val;
+	int i, ret;
+	u16 nlw, cls, lnksta;
+	u32 tmp;
+
+	/*
+	 * Reset the bridge, assert the fundamental reset. Note for some SoCs,
+	 * e.g. BCM7278, the fundamental reset should not be asserted here.
+	 * This will need to be changed when support for other SoCs is added.
+	 */
+	setbits_le32(base + PCIE_RGR1_SW_INIT_1,
+		     RGR1_SW_INIT_1_INIT_MASK | RGR1_SW_INIT_1_PERST_MASK);
+	/*
+	 * The delay is a safety precaution to preclude the reset signal
+	 * from looking like a glitch.
+	 */
+	udelay(100);
+
+	/* Take the bridge out of reset */
+	clrbits_le32(base + PCIE_RGR1_SW_INIT_1, RGR1_SW_INIT_1_INIT_MASK);
+
+	clrbits_le32(base + PCIE_MISC_HARD_PCIE_HARD_DEBUG,
+		     PCIE_HARD_DEBUG_SERDES_IDDQ_MASK);
+
+	/* Wait for SerDes to be stable */
+	udelay(100);
+
+	/* Set SCB_MAX_BURST_SIZE, CFG_READ_UR_MODE, SCB_ACCESS_EN */
+	clrsetbits_le32(base + PCIE_MISC_MISC_CTRL,
+			MISC_CTRL_MAX_BURST_SIZE_MASK,
+			MISC_CTRL_SCB_ACCESS_EN_MASK |
+			MISC_CTRL_CFG_READ_UR_MODE_MASK |
+			MISC_CTRL_MAX_BURST_SIZE_128);
+	/*
+	 * TODO: When support for other SoCs than BCM2711 is added we may
+	 * need to use the base address and size(s) provided in the dma-ranges
+	 * property.
+	 */
+	rc_bar2_offset = 0;
+	rc_bar2_size = 0xc0000000;
+
+	tmp = lower_32_bits(rc_bar2_offset);
+	u32p_replace_bits(&tmp, brcm_pcie_encode_ibar_size(rc_bar2_size),
+			  RC_BAR2_CONFIG_LO_SIZE_MASK);
+	writel(tmp, base + PCIE_MISC_RC_BAR2_CONFIG_LO);
+	writel(upper_32_bits(rc_bar2_offset),
+	       base + PCIE_MISC_RC_BAR2_CONFIG_HI);
+
+	scb_size_val = rc_bar2_size ?
+		       ilog2(rc_bar2_size) - 15 : 0xf; /* 0xf is 1GB */
+
+	tmp = readl(base + PCIE_MISC_MISC_CTRL);
+	u32p_replace_bits(&tmp, scb_size_val,
+			  MISC_CTRL_SCB0_SIZE_MASK);
+	writel(tmp, base + PCIE_MISC_MISC_CTRL);
+
+	/* Disable the PCIe->GISB memory window (RC_BAR1) */
+	clrbits_le32(base + PCIE_MISC_RC_BAR1_CONFIG_LO,
+		     RC_BAR1_CONFIG_LO_SIZE_MASK);
+
+	/* Disable the PCIe->SCB memory window (RC_BAR3) */
+	clrbits_le32(base + PCIE_MISC_RC_BAR3_CONFIG_LO,
+		     RC_BAR3_CONFIG_LO_SIZE_MASK);
+
+	/* Mask all interrupts since we are not handling any yet */
+	writel(0xffffffff, base + PCIE_MSI_INTR2_MASK_SET);
+
+	/* Clear any interrupts we find on boot */
+	writel(0xffffffff, base + PCIE_MSI_INTR2_CLR);
+
+	if (pcie->gen)
+		brcm_pcie_set_gen(pcie, pcie->gen);
+
+	/* Unassert the fundamental reset */
+	clrbits_le32(pcie->base + PCIE_RGR1_SW_INIT_1,
+		     RGR1_SW_INIT_1_PERST_MASK);
+
+	/* Give the RC/EP time to wake up, before trying to configure RC.
+	 * Intermittently check status for link-up, up to a total of 100ms.
+	 */
+	for (i = 0; i < 100 && !brcm_pcie_link_up(pcie); i += 5)
+		mdelay(5);
+
+	if (!brcm_pcie_link_up(pcie)) {
+		printf("PCIe BRCM: link down\n");
+		return -EINVAL;
+	}
+
+	if (!brcm_pcie_rc_mode(pcie)) {
+		printf("PCIe misconfigured; is in EP mode\n");
+		return -EINVAL;
+	}
+
+	for (i = 0; i < hose->region_count; i++) {
+		struct pci_region *reg = &hose->regions[i];
+
+		if (reg->flags != PCI_REGION_MEM)
+			continue;
+
+		if (num_out_wins >= BRCM_NUM_PCIE_OUT_WINS)
+			return -EINVAL;
+
+		brcm_pcie_set_outbound_win(pcie, num_out_wins, reg->phys_start,
+					   reg->bus_start, reg->size);
+
+		num_out_wins++;
+	}
+
+	/*
+	 * For config space accesses on the RC, show the right class for
+	 * a PCIe-PCIe bridge (the default setting is to be EP mode).
+	 */
+	clrsetbits_le32(base + PCIE_RC_CFG_PRIV1_ID_VAL3,
+			CFG_PRIV1_ID_VAL3_CLASS_CODE_MASK, 0x060400);
+
+	if (pcie->ssc) {
+		ret = brcm_pcie_set_ssc(pcie->base);
+		if (!ret)
+			ssc_good = true;
+		else
+			printf("PCIe BRCM: failed attempt to enter SSC mode\n");
+	}
+
+	lnksta = readw(base + BRCM_PCIE_CAP_REGS + PCI_EXP_LNKSTA);
+	cls = lnksta & PCI_EXP_LNKSTA_CLS;
+	nlw = (lnksta & PCI_EXP_LNKSTA_NLW) >> PCI_EXP_LNKSTA_NLW_SHIFT;
+
+	printf("PCIe BRCM: link up, %s Gbps x%u %s\n", link_speed_to_str(cls),
+	       nlw, ssc_good ? "(SSC)" : "(!SSC)");
+
+	/* PCIe->SCB endian mode for BAR */
+	clrsetbits_le32(base + PCIE_RC_CFG_VENDOR_SPECIFIC_REG1,
+			VENDOR_SPECIFIC_REG1_ENDIAN_MODE_BAR2_MASK,
+			VENDOR_SPECIFIC_REG1_LITTLE_ENDIAN);
+	/*
+	 * Refclk from RC should be gated with CLKREQ# input when ASPM L0s,L1
+	 * is enabled => setting the CLKREQ_DEBUG_ENABLE field to 1.
+	 */
+	setbits_le32(base + PCIE_MISC_HARD_PCIE_HARD_DEBUG,
+		     PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK);
+
+	return 0;
+}
+
+static int brcm_pcie_ofdata_to_platdata(struct udevice *dev)
+{
+	struct brcm_pcie *pcie = dev_get_priv(dev);
+	ofnode dn = dev_ofnode(dev);
+	u32 max_link_speed;
+	int ret;
+
+	/* Get the controller base address */
+	pcie->base = dev_read_addr_ptr(dev);
+	if (!pcie->base)
+		return -EINVAL;
+
+	pcie->ssc = ofnode_read_bool(dn, "brcm,enable-ssc");
+
+	ret = ofnode_read_u32(dn, "max-link-speed", &max_link_speed);
+	if (ret < 0 || max_link_speed > 4)
+		pcie->gen = 0;
+	else
+		pcie->gen = max_link_speed;
+
+	return 0;
+}
+
+static const struct dm_pci_ops brcm_pcie_ops = {
+	.read_config	= brcm_pcie_read_config,
+	.write_config	= brcm_pcie_write_config,
+};
+
+static const struct udevice_id brcm_pcie_ids[] = {
+	{ .compatible = "brcm,bcm2711-pcie" },
+	{ }
+};
+
+U_BOOT_DRIVER(pcie_brcm_base) = {
+	.name			= "pcie_brcm",
+	.id			= UCLASS_PCI,
+	.ops			= &brcm_pcie_ops,
+	.of_match		= brcm_pcie_ids,
+	.probe			= brcm_pcie_probe,
+	.ofdata_to_platdata	= brcm_pcie_ofdata_to_platdata,
+	.priv_auto_alloc_size	= sizeof(struct brcm_pcie),
+};
diff --git a/drivers/pci/pcie_intel_fpga.c b/drivers/pci/pcie_intel_fpga.c
index aa1903e..9f102c6 100644
--- a/drivers/pci/pcie_intel_fpga.c
+++ b/drivers/pci/pcie_intel_fpga.c
@@ -67,9 +67,6 @@
 #define IS_ROOT_PORT(pcie, bdf)				\
 		((PCI_BUS(bdf) == pcie->first_busno) ? true : false)
 
-#define PCI_EXP_LNKSTA		18	/* Link Status */
-#define PCI_EXP_LNKSTA_DLLLA	0x2000	/* Data Link Layer Link Active */
-
 /**
  * struct intel_fpga_pcie - Intel FPGA PCIe controller state
  * @bus: Pointer to the PCI bus
diff --git a/drivers/pinctrl/nxp/pinctrl-mxs.c b/drivers/pinctrl/nxp/pinctrl-mxs.c
index a403114..db463fc 100644
--- a/drivers/pinctrl/nxp/pinctrl-mxs.c
+++ b/drivers/pinctrl/nxp/pinctrl-mxs.c
@@ -180,8 +180,8 @@
 	{ /* sentinel */ }
 };
 
-U_BOOT_DRIVER(mxs_pinctrl) = {
-	.name = "mxs-pinctrl",
+U_BOOT_DRIVER(fsl_imx23_pinctrl) = {
+	.name = "fsl_imx23_pinctrl",
 	.id = UCLASS_PINCTRL,
 	.of_match = of_match_ptr(mxs_pinctrl_match),
 	.probe = mxs_pinctrl_probe,
@@ -191,3 +191,5 @@
 	.priv_auto_alloc_size = sizeof(struct mxs_pinctrl_priv),
 	.ops = &mxs_pinctrl_ops,
 };
+
+U_BOOT_DRIVER_ALIAS(fsl_imx23_pinctrl, fsl_imx28_pinctrl)
diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c
index b3fa124..cd7b32c 100644
--- a/drivers/pinctrl/pinctrl-at91.c
+++ b/drivers/pinctrl/pinctrl-at91.c
@@ -519,11 +519,13 @@
 	{}
 };
 
-U_BOOT_DRIVER(at91_pinctrl) = {
-	.name = "pinctrl_at91",
+U_BOOT_DRIVER(atmel_sama5d3_pinctrl) = {
+	.name = "atmel_sama5d3_pinctrl",
 	.id = UCLASS_PINCTRL,
 	.of_match = at91_pinctrl_match,
 	.probe = at91_pinctrl_probe,
 	.priv_auto_alloc_size = sizeof(struct at91_pinctrl_priv),
 	.ops = &at91_pinctrl_ops,
 };
+
+U_BOOT_DRIVER_ALIAS(atmel_sama5d3_pinctrl, atmel_at91rm9200_pinctrl)
diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3188.c b/drivers/pinctrl/rockchip/pinctrl-rk3188.c
index afde809..8f19711 100644
--- a/drivers/pinctrl/rockchip/pinctrl-rk3188.c
+++ b/drivers/pinctrl/rockchip/pinctrl-rk3188.c
@@ -120,7 +120,7 @@
 	{ }
 };
 
-U_BOOT_DRIVER(pinctrl_rk3188) = {
+U_BOOT_DRIVER(rockchip_rk3188_pinctrl) = {
 	.name		= "rockchip_rk3188_pinctrl",
 	.id		= UCLASS_PINCTRL,
 	.of_match	= rk3188_pinctrl_ids,
diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3288.c b/drivers/pinctrl/rockchip/pinctrl-rk3288.c
index faaa2ce..011ca28 100644
--- a/drivers/pinctrl/rockchip/pinctrl-rk3288.c
+++ b/drivers/pinctrl/rockchip/pinctrl-rk3288.c
@@ -242,7 +242,7 @@
 	{ }
 };
 
-U_BOOT_DRIVER(pinctrl_rk3288) = {
+U_BOOT_DRIVER(rockchip_rk3288_pinctrl) = {
 	.name		= "rockchip_rk3288_pinctrl",
 	.id		= UCLASS_PINCTRL,
 	.of_match	= rk3288_pinctrl_ids,
diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3328.c b/drivers/pinctrl/rockchip/pinctrl-rk3328.c
index f9160f2..61eb9e0 100644
--- a/drivers/pinctrl/rockchip/pinctrl-rk3328.c
+++ b/drivers/pinctrl/rockchip/pinctrl-rk3328.c
@@ -317,7 +317,7 @@
 	{ }
 };
 
-U_BOOT_DRIVER(pinctrl_rk3328) = {
+U_BOOT_DRIVER(rockchip_rk3328_pinctrl) = {
 	.name		= "rockchip_rk3328_pinctrl",
 	.id		= UCLASS_PINCTRL,
 	.of_match	= rk3328_pinctrl_ids,
diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3368.c b/drivers/pinctrl/rockchip/pinctrl-rk3368.c
index 7a60599..d8ccd4d 100644
--- a/drivers/pinctrl/rockchip/pinctrl-rk3368.c
+++ b/drivers/pinctrl/rockchip/pinctrl-rk3368.c
@@ -171,7 +171,7 @@
 	{ }
 };
 
-U_BOOT_DRIVER(pinctrl_rk3368) = {
+U_BOOT_DRIVER(rockchip_rk3368_pinctrl) = {
 	.name		= "rockchip_rk3368_pinctrl",
 	.id		= UCLASS_PINCTRL,
 	.of_match	= rk3368_pinctrl_ids,
diff --git a/drivers/power/pmic/rk8xx.c b/drivers/power/pmic/rk8xx.c
index 195884b..148ee29 100644
--- a/drivers/power/pmic/rk8xx.c
+++ b/drivers/power/pmic/rk8xx.c
@@ -183,8 +183,8 @@
 	{ }
 };
 
-U_BOOT_DRIVER(pmic_rk8xx) = {
-	.name = "rk8xx pmic",
+U_BOOT_DRIVER(rockchip_rk805) = {
+	.name = "rockchip_rk805",
 	.id = UCLASS_PMIC,
 	.of_match = rk8xx_ids,
 #if CONFIG_IS_ENABLED(PMIC_CHILDREN)
@@ -194,3 +194,5 @@
 	.probe = rk8xx_probe,
 	.ops = &rk8xx_ops,
 };
+
+U_BOOT_DRIVER_ALIAS(rockchip_rk805, rockchip_rk808)
diff --git a/drivers/power/regulator/fixed.c b/drivers/power/regulator/fixed.c
index f9f9659..b5f7aec 100644
--- a/drivers/power/regulator/fixed.c
+++ b/drivers/power/regulator/fixed.c
@@ -82,8 +82,8 @@
 	{ },
 };
 
-U_BOOT_DRIVER(fixed_regulator) = {
-	.name = "fixed regulator",
+U_BOOT_DRIVER(regulator_fixed) = {
+	.name = "regulator_fixed",
 	.id = UCLASS_REGULATOR,
 	.ops = &fixed_regulator_ops,
 	.of_match = fixed_regulator_ids,
diff --git a/drivers/ram/rockchip/dmc-rk3368.c b/drivers/ram/rockchip/dmc-rk3368.c
index 92457a1..4fa6321 100644
--- a/drivers/ram/rockchip/dmc-rk3368.c
+++ b/drivers/ram/rockchip/dmc-rk3368.c
@@ -992,7 +992,7 @@
 	{ }
 };
 
-U_BOOT_DRIVER(dmc_rk3368) = {
+U_BOOT_DRIVER(rockchip_rk3368_dmc) = {
 	.name = "rockchip_rk3368_dmc",
 	.id = UCLASS_RAM,
 	.of_match = rk3368_dmc_ids,
diff --git a/drivers/ram/rockchip/sdram_rk3188.c b/drivers/ram/rockchip/sdram_rk3188.c
index 7aedb4f..06f9eba 100644
--- a/drivers/ram/rockchip/sdram_rk3188.c
+++ b/drivers/ram/rockchip/sdram_rk3188.c
@@ -945,7 +945,7 @@
 	{ }
 };
 
-U_BOOT_DRIVER(dmc_rk3188) = {
+U_BOOT_DRIVER(rockchip_rk3188_dmc) = {
 	.name = "rockchip_rk3188_dmc",
 	.id = UCLASS_RAM,
 	.of_match = rk3188_dmc_ids,
diff --git a/drivers/ram/rockchip/sdram_rk3288.c b/drivers/ram/rockchip/sdram_rk3288.c
index 64d704e..26e8d05 100644
--- a/drivers/ram/rockchip/sdram_rk3288.c
+++ b/drivers/ram/rockchip/sdram_rk3288.c
@@ -1113,7 +1113,7 @@
 	{ }
 };
 
-U_BOOT_DRIVER(dmc_rk3288) = {
+U_BOOT_DRIVER(rockchip_rk3288_dmc) = {
 	.name = "rockchip_rk3288_dmc",
 	.id = UCLASS_RAM,
 	.of_match = rk3288_dmc_ids,
diff --git a/drivers/ram/rockchip/sdram_rk3328.c b/drivers/ram/rockchip/sdram_rk3328.c
index 3f3926f..98c7feb 100644
--- a/drivers/ram/rockchip/sdram_rk3328.c
+++ b/drivers/ram/rockchip/sdram_rk3328.c
@@ -606,7 +606,7 @@
 	{ }
 };
 
-U_BOOT_DRIVER(dmc_rk3328) = {
+U_BOOT_DRIVER(rockchip_rk3328_dmc) = {
 	.name = "rockchip_rk3328_dmc",
 	.id = UCLASS_RAM,
 	.of_match = rk3328_dmc_ids,
diff --git a/drivers/ram/rockchip/sdram_rk3399.c b/drivers/ram/rockchip/sdram_rk3399.c
index 60a1ab8..0fe2ced 100644
--- a/drivers/ram/rockchip/sdram_rk3399.c
+++ b/drivers/ram/rockchip/sdram_rk3399.c
@@ -3128,7 +3128,7 @@
 	      priv->cic, priv->pmugrf, priv->pmusgrf, priv->pmucru, priv->pmu);
 
 #if CONFIG_IS_ENABLED(OF_PLATDATA)
-	ret = clk_get_by_index_platdata(dev, 0, dtplat->clocks, &priv->ddr_clk);
+	ret = clk_get_by_driver_info(dev, dtplat->clocks, &priv->ddr_clk);
 #else
 	ret = clk_get_by_index(dev, 0, &priv->ddr_clk);
 #endif
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index 58ba0c6..6d53561 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -153,4 +153,15 @@
 	depends on DM_RESET
 	help
 	  Support generic syscon mapped register reset devices.
+
+config RESET_RASPBERRYPI
+	bool "Raspberry Pi 4 Firmware Reset Controller Driver"
+	depends on DM_RESET && ARCH_BCM283X
+	default USB_XHCI_PCI
+	help
+	  Raspberry Pi 4's co-processor controls some of the board's HW
+	  initialization process, but it's up to Linux to trigger it when
+	  relevant. This driver provides a reset controller capable of
+	  interfacing with RPi4's co-processor and model these firmware
+	  initialization routines as reset lines.
 endmenu
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index 433f1ec..8e0124b 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -24,3 +24,4 @@
 obj-$(CONFIG_RESET_HISILICON) += reset-hisilicon.o
 obj-$(CONFIG_RESET_IMX7) += reset-imx7.o
 obj-$(CONFIG_RESET_SYSCON) += reset-syscon.o
+obj-$(CONFIG_RESET_RASPBERRYPI) += reset-raspberrypi.o
diff --git a/drivers/reset/reset-raspberrypi.c b/drivers/reset/reset-raspberrypi.c
new file mode 100644
index 0000000..e2d284e
--- /dev/null
+++ b/drivers/reset/reset-raspberrypi.c
@@ -0,0 +1,60 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Raspberry Pi 4 firmware reset driver
+ *
+ * Copyright (C) 2020 Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+ */
+#include <common.h>
+#include <dm.h>
+#include <reset-uclass.h>
+#include <asm/arch/msg.h>
+#include <dt-bindings/reset/raspberrypi,firmware-reset.h>
+
+static int raspberrypi_reset_request(struct reset_ctl *reset_ctl)
+{
+	if (reset_ctl->id >= RASPBERRYPI_FIRMWARE_RESET_NUM_IDS)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int raspberrypi_reset_free(struct reset_ctl *reset_ctl)
+{
+	return 0;
+}
+
+static int raspberrypi_reset_assert(struct reset_ctl *reset_ctl)
+{
+	switch (reset_ctl->id) {
+	case RASPBERRYPI_FIRMWARE_RESET_ID_USB:
+		bcm2711_notify_vl805_reset();
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
+static int raspberrypi_reset_deassert(struct reset_ctl *reset_ctl)
+{
+	return 0;
+}
+
+struct reset_ops raspberrypi_reset_ops = {
+	.request = raspberrypi_reset_request,
+	.rfree = raspberrypi_reset_free,
+	.rst_assert = raspberrypi_reset_assert,
+	.rst_deassert = raspberrypi_reset_deassert,
+};
+
+static const struct udevice_id raspberrypi_reset_ids[] = {
+	{ .compatible = "raspberrypi,firmware-reset" },
+	{ }
+};
+
+U_BOOT_DRIVER(raspberrypi_reset) = {
+	.name = "raspberrypi-reset",
+	.id = UCLASS_RESET,
+	.of_match = raspberrypi_reset_ids,
+	.ops = &raspberrypi_reset_ops,
+};
+
diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c
index cca798d..702109b 100644
--- a/drivers/serial/ns16550.c
+++ b/drivers/serial/ns16550.c
@@ -620,6 +620,10 @@
 	.flags	= DM_FLAG_PRE_RELOC,
 #endif
 };
+
+U_BOOT_DRIVER_ALIAS(ns16550_serial, rockchip_rk3328_uart)
+U_BOOT_DRIVER_ALIAS(ns16550_serial, rockchip_rk3368_uart)
+U_BOOT_DRIVER_ALIAS(ns16550_serial, ti_da830_uart)
 #endif
 #endif /* SERIAL_PRESENT */
 
diff --git a/drivers/serial/sandbox.c b/drivers/serial/sandbox.c
index 545ff3f..f09d291 100644
--- a/drivers/serial/sandbox.c
+++ b/drivers/serial/sandbox.c
@@ -93,7 +93,9 @@
 	struct sandbox_serial_priv *priv = dev_get_priv(dev);
 	struct sandbox_serial_platdata *plat = dev->platdata;
 
-	if (priv->start_of_line && plat->colour != -1) {
+	/* With of-platdata we don't real the colour correctly, so disable it */
+	if (!CONFIG_IS_ENABLED(OF_PLATDATA) && priv->start_of_line &&
+	    plat->colour != -1) {
 		priv->start_of_line = false;
 		output_ansi_colour(plat->colour);
 	}
@@ -252,8 +254,8 @@
 	{ }
 };
 
-U_BOOT_DRIVER(serial_sandbox) = {
-	.name	= "serial_sandbox",
+U_BOOT_DRIVER(sandbox_serial) = {
+	.name	= "sandbox_serial",
 	.id	= UCLASS_SERIAL,
 	.of_match = sandbox_serial_ids,
 	.ofdata_to_platdata = sandbox_serial_ofdata_to_platdata,
@@ -270,7 +272,7 @@
 };
 
 U_BOOT_DEVICE(serial_sandbox_non_fdt) = {
-	.name = "serial_sandbox",
+	.name = "sandbox_serial",
 	.platdata = &platdata_non_fdt,
 };
 #endif /* CONFIG_IS_ENABLED(OF_CONTROL) */
diff --git a/drivers/serial/serial_uniphier.c b/drivers/serial/serial_uniphier.c
index c7f46e5..ad691b6 100644
--- a/drivers/serial/serial_uniphier.c
+++ b/drivers/serial/serial_uniphier.c
@@ -7,6 +7,8 @@
 
 #include <common.h>
 #include <dm.h>
+#include <linux/bitfield.h>
+#include <linux/bitops.h>
 #include <linux/bug.h>
 #include <linux/io.h>
 #include <linux/serial_reg.h>
@@ -15,77 +17,72 @@
 #include <serial.h>
 #include <fdtdec.h>
 
-/*
- * Note: Register map is slightly different from that of 16550.
- */
-struct uniphier_serial {
-	u32 rx;			/* In:  Receive buffer */
-#define tx rx			/* Out: Transmit buffer */
-	u32 ier;		/* Interrupt Enable Register */
-	u32 iir;		/* In: Interrupt ID Register */
-	u32 char_fcr;		/* Charactor / FIFO Control Register */
-	u32 lcr_mcr;		/* Line/Modem Control Register */
-#define LCR_SHIFT	8
-#define LCR_MASK	(0xff << (LCR_SHIFT))
-	u32 lsr;		/* In: Line Status Register */
-	u32 msr;		/* In: Modem Status Register */
-	u32 __rsv0;
-	u32 __rsv1;
-	u32 dlr;		/* Divisor Latch Register */
-};
+#define UNIPHIER_UART_REGSHIFT		2
+
+#define UNIPHIER_UART_RX		(0 << (UNIPHIER_UART_REGSHIFT))
+#define UNIPHIER_UART_TX		UNIPHIER_UART_RX
+/* bit[15:8] = CHAR, bit[7:0] = FCR */
+#define UNIPHIER_UART_CHAR_FCR		(3 << (UNIPHIER_UART_REGSHIFT))
+#define   UNIPHIER_UART_FCR_MASK		GENMASK(7, 0)
+/* bit[15:8] = LCR, bit[7:0] = MCR */
+#define UNIPHIER_UART_LCR_MCR		(4 << (UNIPHIER_UART_REGSHIFT))
+#define   UNIPHIER_UART_LCR_MASK		GENMASK(15, 8)
+#define UNIPHIER_UART_LSR		(5 << (UNIPHIER_UART_REGSHIFT))
+/* Divisor Latch Register */
+#define UNIPHIER_UART_DLR		(9 << (UNIPHIER_UART_REGSHIFT))
 
 struct uniphier_serial_priv {
-	struct uniphier_serial __iomem *membase;
+	void __iomem *membase;
 	unsigned int uartclk;
 };
 
-#define uniphier_serial_port(dev)	\
-	((struct uniphier_serial_priv *)dev_get_priv(dev))->membase
-
 static int uniphier_serial_setbrg(struct udevice *dev, int baudrate)
 {
 	struct uniphier_serial_priv *priv = dev_get_priv(dev);
-	struct uniphier_serial __iomem *port = uniphier_serial_port(dev);
-	const unsigned int mode_x_div = 16;
+	static const unsigned int mode_x_div = 16;
 	unsigned int divisor;
 
 	divisor = DIV_ROUND_CLOSEST(priv->uartclk, mode_x_div * baudrate);
 
+	/* flush the trasmitter before changing hw setting */
+	while (!(readl(priv->membase + UNIPHIER_UART_LSR) & UART_LSR_TEMT))
+		;
+
-	writel(divisor, &port->dlr);
+	writel(divisor, priv->membase + UNIPHIER_UART_DLR);
 
 	return 0;
 }
 
 static int uniphier_serial_getc(struct udevice *dev)
 {
-	struct uniphier_serial __iomem *port = uniphier_serial_port(dev);
+	struct uniphier_serial_priv *priv = dev_get_priv(dev);
 
-	if (!(readl(&port->lsr) & UART_LSR_DR))
+	if (!(readl(priv->membase + UNIPHIER_UART_LSR) & UART_LSR_DR))
 		return -EAGAIN;
 
-	return readl(&port->rx);
+	return readl(priv->membase + UNIPHIER_UART_RX);
 }
 
 static int uniphier_serial_putc(struct udevice *dev, const char c)
 {
-	struct uniphier_serial __iomem *port = uniphier_serial_port(dev);
+	struct uniphier_serial_priv *priv = dev_get_priv(dev);
 
-	if (!(readl(&port->lsr) & UART_LSR_THRE))
+	if (!(readl(priv->membase + UNIPHIER_UART_LSR) & UART_LSR_THRE))
 		return -EAGAIN;
 
-	writel(c, &port->tx);
+	writel(c, priv->membase + UNIPHIER_UART_TX);
 
 	return 0;
 }
 
 static int uniphier_serial_pending(struct udevice *dev, bool input)
 {
-	struct uniphier_serial __iomem *port = uniphier_serial_port(dev);
+	struct uniphier_serial_priv *priv = dev_get_priv(dev);
 
 	if (input)
-		return readl(&port->lsr) & UART_LSR_DR;
+		return readl(priv->membase + UNIPHIER_UART_LSR) & UART_LSR_DR;
 	else
-		return !(readl(&port->lsr) & UART_LSR_THRE);
+		return !(readl(priv->membase + UNIPHIER_UART_LSR) & UART_LSR_THRE);
 }
 
 /*
@@ -113,7 +110,6 @@
 static int uniphier_serial_probe(struct udevice *dev)
 {
 	struct uniphier_serial_priv *priv = dev_get_priv(dev);
-	struct uniphier_serial __iomem *port;
 	const struct uniphier_serial_clk_data *clk_data;
 	ofnode root_node;
 	fdt_addr_t base;
@@ -123,12 +119,10 @@
 	if (base == FDT_ADDR_T_NONE)
 		return -EINVAL;
 
-	port = devm_ioremap(dev, base, SZ_64);
-	if (!port)
+	priv->membase = devm_ioremap(dev, base, SZ_64);
+	if (!priv->membase)
 		return -ENOMEM;
 
-	priv->membase = port;
-
 	root_node = ofnode_path("/");
 	clk_data = uniphier_serial_clk_data;
 	while (clk_data->compatible) {
@@ -143,10 +137,20 @@
 
 	priv->uartclk = clk_data->clk_rate;
 
+	/* flush the trasmitter empty before changing hw setting */
+	while (!(readl(priv->membase + UNIPHIER_UART_LSR) & UART_LSR_TEMT))
+		;
+
+	/* enable FIFO */
+	tmp = readl(priv->membase + UNIPHIER_UART_CHAR_FCR);
+	tmp &= ~UNIPHIER_UART_FCR_MASK;
+	tmp |= FIELD_PREP(UNIPHIER_UART_FCR_MASK, UART_FCR_ENABLE_FIFO);
+	writel(tmp, priv->membase + UNIPHIER_UART_CHAR_FCR);
+
-	tmp = readl(&port->lcr_mcr);
-	tmp &= ~LCR_MASK;
-	tmp |= UART_LCR_WLEN8 << LCR_SHIFT;
-	writel(tmp, &port->lcr_mcr);
+	tmp = readl(priv->membase + UNIPHIER_UART_LCR_MCR);
+	tmp &= ~UNIPHIER_UART_LCR_MASK;
+	tmp |= FIELD_PREP(UNIPHIER_UART_LCR_MASK, UART_LCR_WLEN8);
+	writel(tmp, priv->membase + UNIPHIER_UART_LCR_MCR);
 
 	return 0;
 }
diff --git a/drivers/spi/mxs_spi.c b/drivers/spi/mxs_spi.c
index e231e96..3c1af83 100644
--- a/drivers/spi/mxs_spi.c
+++ b/drivers/spi/mxs_spi.c
@@ -486,12 +486,8 @@
 };
 #endif
 
-U_BOOT_DRIVER(mxs_spi) = {
-#ifdef CONFIG_MX28
-	.name = "fsl_imx28_spi",
-#else /* CONFIG_MX23 */
+U_BOOT_DRIVER(fsl_imx23_spi) = {
 	.name = "fsl_imx23_spi",
-#endif
 	.id	= UCLASS_SPI,
 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
 	.of_match = mxs_spi_ids,
@@ -502,3 +498,5 @@
 	.priv_auto_alloc_size = sizeof(struct mxs_spi_priv),
 	.probe	= mxs_spi_probe,
 };
+
+U_BOOT_DRIVER_ALIAS(fsl_imx23_spi, fsl_imx28_spi)
diff --git a/drivers/spi/rk_spi.c b/drivers/spi/rk_spi.c
index 833cb04..b6f95fa 100644
--- a/drivers/spi/rk_spi.c
+++ b/drivers/spi/rk_spi.c
@@ -183,7 +183,7 @@
 
 	plat->base = dtplat->reg[0];
 	plat->frequency = 20000000;
-	ret = clk_get_by_index_platdata(dev, 0, dtplat->clocks, &priv->clk);
+	ret = clk_get_by_driver_info(dev, dtplat->clocks, &priv->clk);
 	if (ret < 0)
 		return ret;
 	dev->req_seq = 0;
@@ -553,12 +553,8 @@
 	{ }
 };
 
-U_BOOT_DRIVER(rockchip_spi) = {
-#if CONFIG_IS_ENABLED(OF_PLATDATA)
+U_BOOT_DRIVER(rockchip_rk3288_spi) = {
 	.name	= "rockchip_rk3288_spi",
-#else
-	.name	= "rockchip_spi",
-#endif
 	.id	= UCLASS_SPI,
 	.of_match = rockchip_spi_ids,
 	.ops	= &rockchip_spi_ops,
@@ -567,3 +563,5 @@
 	.priv_auto_alloc_size = sizeof(struct rockchip_spi_priv),
 	.probe	= rockchip_spi_probe,
 };
+
+U_BOOT_DRIVER_ALIAS(rockchip_rk3288_spi, rockchip_rk3368_spi)
diff --git a/drivers/spi/sandbox_spi.c b/drivers/spi/sandbox_spi.c
index b0a46c8..570ae28 100644
--- a/drivers/spi/sandbox_spi.c
+++ b/drivers/spi/sandbox_spi.c
@@ -146,8 +146,8 @@
 	{ }
 };
 
-U_BOOT_DRIVER(spi_sandbox) = {
-	.name	= "spi_sandbox",
+U_BOOT_DRIVER(sandbox_spi) = {
+	.name	= "sandbox_spi",
 	.id	= UCLASS_SPI,
 	.of_match = sandbox_spi_ids,
 	.ops	= &sandbox_spi_ops,
diff --git a/drivers/tpm/tpm_tis_sandbox.c b/drivers/tpm/tpm_tis_sandbox.c
index 2dff0d3..e167d0a 100644
--- a/drivers/tpm/tpm_tis_sandbox.c
+++ b/drivers/tpm/tpm_tis_sandbox.c
@@ -355,8 +355,8 @@
 	{ }
 };
 
-U_BOOT_DRIVER(sandbox_tpm) = {
-	.name   = "sandbox_tpm",
+U_BOOT_DRIVER(google_sandbox_tpm) = {
+	.name   = "google_sandbox_tpm",
 	.id     = UCLASS_TPM,
 	.of_match = sandbox_tpm_ids,
 	.ops    = &sandbox_tpm_ops,
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 2d968aa..108f4bd 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -180,6 +180,8 @@
 	xhci_free_virt_devices(ctrl);
 	free(ctrl->erst.entries);
 	free(ctrl->dcbaa);
+	if (reset_valid(&ctrl->reset))
+		reset_free(&ctrl->reset);
 	memset(ctrl, '\0', sizeof(struct xhci_ctrl));
 }
 
@@ -395,6 +397,9 @@
 		scratchpad->sp_array[i] = cpu_to_le64(ptr);
 	}
 
+	xhci_flush_cache((uintptr_t)scratchpad->sp_array,
+			 sizeof(u64) * num_sp);
+
 	return 0;
 
 fail_sp3:
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index ebd2954..f635bb3 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -190,6 +190,37 @@
 	return ret;
 }
 
+#if CONFIG_IS_ENABLED(DM_USB)
+/**
+ * Resets XHCI Hardware
+ *
+ * @param ctrl	pointer to host controller
+ * @return 0 if OK, or a negative error code.
+ */
+static int xhci_reset_hw(struct xhci_ctrl *ctrl)
+{
+	int ret;
+
+	ret = reset_get_by_index(ctrl->dev, 0, &ctrl->reset);
+	if (ret && ret != -ENOENT && ret != -ENOTSUPP) {
+		dev_err(ctrl->dev, "failed to get reset\n");
+		return ret;
+	}
+
+	if (reset_valid(&ctrl->reset)) {
+		ret = reset_assert(&ctrl->reset);
+		if (ret)
+			return ret;
+
+		ret = reset_deassert(&ctrl->reset);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+#endif
+
 /**
  * Resets the XHCI Controller
  *
@@ -1508,6 +1539,10 @@
 
 	ctrl->dev = dev;
 
+	ret = xhci_reset_hw(ctrl);
+	if (ret)
+		goto err;
+
 	/*
 	 * XHCI needs to issue a Address device command to setup
 	 * proper device context structures, before it can interact
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 0cf13ad..89ad603 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -22,6 +22,37 @@
 	  This provides backlight uclass driver that enables basic panel
 	  backlight support.
 
+config VIDEO_PCI_DEFAULT_FB_SIZE
+	hex "Default framebuffer size to use if no drivers request it"
+	depends on DM_VIDEO
+	default 0x1000000 if X86 && PCI
+	default 0 if !(X86 && PCI)
+	help
+	  Generally, video drivers request the amount of memory they need for
+	  the frame buffer when they are bound, by setting the size field in
+	  struct video_uc_platdata. That memory is then reserved for use after
+	  relocation. But PCI drivers cannot be bound before relocation unless
+	  they are mentioned in the devicetree.
+
+	  With this value set appropriately, it is possible for PCI video
+	  devices to have a framebuffer allocated by U-Boot.
+
+	  Note: the framebuffer needs to be large enough to store all pixels at
+	  maximum resolution. For example, at 1920 x 1200 with 32 bits per
+	  pixel, 2560 * 1600 * 32 / 8 = 0xfa0000 bytes are needed.
+
+config VIDEO_COPY
+	bool "Enable copying the frame buffer to a hardware copy"
+	depends on DM_VIDEO
+	help
+	  On some machines (e.g. x86), reading from the frame buffer is very
+	  slow because it is uncached. To improve performance, this feature
+	  allows the frame buffer to be kept in cached memory (allocated by
+	  U-Boot) and then copied to the hardware frame-buffer as needed.
+
+	  To use this, your video driver must set @copy_base in
+	  struct video_uc_platdata.
+
 config BACKLIGHT_PWM
 	bool "Generic PWM based Backlight Driver"
 	depends on BACKLIGHT && DM_PWM
diff --git a/drivers/video/broadwell_igd.c b/drivers/video/broadwell_igd.c
index 8e8fe9d..df6a761 100644
--- a/drivers/video/broadwell_igd.c
+++ b/drivers/video/broadwell_igd.c
@@ -664,6 +664,7 @@
 	struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
 	struct video_priv *uc_priv = dev_get_uclass_priv(dev);
 	bool is_broadwell;
+	ulong fbbase;
 	int ret;
 
 	if (!ll_boot_init()) {
@@ -690,7 +691,8 @@
 		return ret;
 
 	/* Use write-combining for the graphics memory, 256MB */
-	ret = mtrr_add_request(MTRR_TYPE_WRCOMB, plat->base, 256 << 20);
+	fbbase = IS_ENABLED(CONFIG_VIDEO_COPY) ? plat->copy_base : plat->base;
+	ret = mtrr_add_request(MTRR_TYPE_WRCOMB, fbbase, 256 << 20);
 	if (!ret)
 		ret = mtrr_commit(true);
 	if (ret && ret != -ENOSYS) {
@@ -752,6 +754,17 @@
 	return 0;
 }
 
+static int broadwell_igd_bind(struct udevice *dev)
+{
+	struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev);
+
+	/* Set the maximum supported resolution */
+	uc_plat->size = 2560 * 1600 * 4;
+	log_debug("%s: Frame buffer size %x\n", __func__, uc_plat->size);
+
+	return 0;
+}
+
 static const struct video_ops broadwell_igd_ops = {
 };
 
@@ -766,6 +779,7 @@
 	.of_match = broadwell_igd_ids,
 	.ops	= &broadwell_igd_ops,
 	.ofdata_to_platdata = broadwell_igd_ofdata_to_platdata,
+	.bind	= broadwell_igd_bind,
 	.probe	= broadwell_igd_probe,
 	.priv_auto_alloc_size	= sizeof(struct broadwell_igd_priv),
 	.platdata_auto_alloc_size	= sizeof(struct broadwell_igd_plat),
diff --git a/drivers/video/console_normal.c b/drivers/video/console_normal.c
index c3f7ef8..04f0224 100644
--- a/drivers/video/console_normal.c
+++ b/drivers/video/console_normal.c
@@ -16,8 +16,9 @@
 static int console_normal_set_row(struct udevice *dev, uint row, int clr)
 {
 	struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
-	void *line;
+	void *line, *end;
 	int pixels = VIDEO_FONT_HEIGHT * vid_priv->xsize;
+	int ret;
 	int i;
 
 	line = vid_priv->fb + row * VIDEO_FONT_HEIGHT * vid_priv->line_length;
@@ -28,6 +29,7 @@
 
 			for (i = 0; i < pixels; i++)
 				*dst++ = clr;
+			end = dst;
 			break;
 		}
 	case VIDEO_BPP16:
@@ -36,6 +38,7 @@
 
 			for (i = 0; i < pixels; i++)
 				*dst++ = clr;
+			end = dst;
 			break;
 		}
 	case VIDEO_BPP32:
@@ -44,11 +47,15 @@
 
 			for (i = 0; i < pixels; i++)
 				*dst++ = clr;
+			end = dst;
 			break;
 		}
 	default:
 		return -ENOSYS;
 	}
+	ret = vidconsole_sync_copy(dev, line, end);
+	if (ret)
+		return ret;
 
 	return 0;
 }
@@ -59,10 +66,15 @@
 	struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
 	void *dst;
 	void *src;
+	int size;
+	int ret;
 
 	dst = vid_priv->fb + rowdst * VIDEO_FONT_HEIGHT * vid_priv->line_length;
 	src = vid_priv->fb + rowsrc * VIDEO_FONT_HEIGHT * vid_priv->line_length;
-	memmove(dst, src, VIDEO_FONT_HEIGHT * vid_priv->line_length * count);
+	size = VIDEO_FONT_HEIGHT * vid_priv->line_length * count;
+	ret = vidconsole_memmove(dev, dst, src, size);
+	if (ret)
+		return ret;
 
 	return 0;
 }
@@ -74,8 +86,13 @@
 	struct udevice *vid = dev->parent;
 	struct video_priv *vid_priv = dev_get_uclass_priv(vid);
 	int i, row;
-	void *line = vid_priv->fb + y * vid_priv->line_length +
+	void *start;
+	void *line;
+	int ret;
+
+	start = vid_priv->fb + y * vid_priv->line_length +
 		VID_TO_PIXEL(x_frac) * VNBYTES(vid_priv->bpix);
+	line = start;
 
 	if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
 		return -EAGAIN;
@@ -126,6 +143,9 @@
 		}
 		line += vid_priv->line_length;
 	}
+	ret = vidconsole_sync_copy(dev, start, line);
+	if (ret)
+		return ret;
 
 	return VID_TO_POS(VIDEO_FONT_WIDTH);
 }
diff --git a/drivers/video/console_rotate.c b/drivers/video/console_rotate.c
index b485255..36c8d06 100644
--- a/drivers/video/console_rotate.c
+++ b/drivers/video/console_rotate.c
@@ -15,11 +15,13 @@
 {
 	struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
 	int pbytes = VNBYTES(vid_priv->bpix);
-	void *line;
+	void *start, *line;
 	int i, j;
+	int ret;
 
-	line = vid_priv->fb + vid_priv->line_length -
+	start = vid_priv->fb + vid_priv->line_length -
 		(row + 1) * VIDEO_FONT_HEIGHT * pbytes;
+	line = start;
 	for (j = 0; j < vid_priv->ysize; j++) {
 		switch (vid_priv->bpix) {
 		case VIDEO_BPP8:
@@ -51,6 +53,9 @@
 		}
 		line += vid_priv->line_length;
 	}
+	ret = vidconsole_sync_copy(dev, start, line);
+	if (ret)
+		return ret;
 
 	return 0;
 }
@@ -59,10 +64,10 @@
 			       uint count)
 {
 	struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
+	int pbytes = VNBYTES(vid_priv->bpix);
 	void *dst;
 	void *src;
-	int pbytes = VNBYTES(vid_priv->bpix);
-	int j;
+	int j, ret;
 
 	dst = vid_priv->fb + vid_priv->line_length -
 		(rowdst + count) * VIDEO_FONT_HEIGHT * pbytes;
@@ -70,7 +75,10 @@
 		(rowsrc + count) * VIDEO_FONT_HEIGHT * pbytes;
 
 	for (j = 0; j < vid_priv->ysize; j++) {
-		memmove(dst, src, VIDEO_FONT_HEIGHT * pbytes * count);
+		ret = vidconsole_memmove(dev, dst, src,
+					 VIDEO_FONT_HEIGHT * pbytes * count);
+		if (ret)
+			return ret;
 		src += vid_priv->line_length;
 		dst += vid_priv->line_length;
 	}
@@ -83,14 +91,16 @@
 	struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
 	struct udevice *vid = dev->parent;
 	struct video_priv *vid_priv = dev_get_uclass_priv(vid);
+	uchar *pfont = video_fontdata + (u8)ch * VIDEO_FONT_HEIGHT;
 	int pbytes = VNBYTES(vid_priv->bpix);
-	int i, col;
+	int i, col, x, linenum, ret;
 	int mask = 0x80;
-	void *line;
-	uchar *pfont = video_fontdata + (u8)ch * VIDEO_FONT_HEIGHT;
+	void *start, *line;
 
-	line = vid_priv->fb + (VID_TO_PIXEL(x_frac) + 1) *
-			vid_priv->line_length - (y + 1) * pbytes;
+	linenum = VID_TO_PIXEL(x_frac) + 1;
+	x = y + 1;
+	start = vid_priv->fb + linenum * vid_priv->line_length - x * pbytes;
+	line = start;
 	if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
 		return -EAGAIN;
 
@@ -135,6 +145,10 @@
 		line += vid_priv->line_length;
 		mask >>= 1;
 	}
+	/* We draw backwards from 'start, so account for the first line */
+	ret = vidconsole_sync_copy(dev, start - vid_priv->line_length, line);
+	if (ret)
+		return ret;
 
 	return VID_TO_POS(VIDEO_FONT_WIDTH);
 }
@@ -143,12 +157,13 @@
 static int console_set_row_2(struct udevice *dev, uint row, int clr)
 {
 	struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
-	void *line;
+	void *start, *line, *end;
 	int pixels = VIDEO_FONT_HEIGHT * vid_priv->xsize;
-	int i;
+	int i, ret;
 
-	line = vid_priv->fb + vid_priv->ysize * vid_priv->line_length -
+	start = vid_priv->fb + vid_priv->ysize * vid_priv->line_length -
 		(row + 1) * VIDEO_FONT_HEIGHT * vid_priv->line_length;
+	line = start;
 	switch (vid_priv->bpix) {
 	case VIDEO_BPP8:
 		if (IS_ENABLED(CONFIG_VIDEO_BPP8)) {
@@ -156,6 +171,7 @@
 
 			for (i = 0; i < pixels; i++)
 				*dst++ = clr;
+			end = dst;
 			break;
 		}
 	case VIDEO_BPP16:
@@ -164,6 +180,7 @@
 
 			for (i = 0; i < pixels; i++)
 				*dst++ = clr;
+			end = dst;
 			break;
 		}
 	case VIDEO_BPP32:
@@ -172,11 +189,15 @@
 
 			for (i = 0; i < pixels; i++)
 				*dst++ = clr;
+			end = dst;
 			break;
 		}
 	default:
 		return -ENOSYS;
 	}
+	ret = vidconsole_sync_copy(dev, start, end);
+	if (ret)
+		return ret;
 
 	return 0;
 }
@@ -194,7 +215,8 @@
 		vid_priv->line_length;
 	src = end - (rowsrc + count) * VIDEO_FONT_HEIGHT *
 		vid_priv->line_length;
-	memmove(dst, src, VIDEO_FONT_HEIGHT * vid_priv->line_length * count);
+	vidconsole_memmove(dev, dst, src,
+			   VIDEO_FONT_HEIGHT * vid_priv->line_length * count);
 
 	return 0;
 }
@@ -204,16 +226,16 @@
 	struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
 	struct udevice *vid = dev->parent;
 	struct video_priv *vid_priv = dev_get_uclass_priv(vid);
-	int i, row;
-	void *line;
+	int pbytes = VNBYTES(vid_priv->bpix);
+	int i, row, x, linenum, ret;
+	void *start, *line;
 
 	if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
 		return -EAGAIN;
-
-	line = vid_priv->fb + (vid_priv->ysize - y - 1) *
-			vid_priv->line_length +
-			(vid_priv->xsize - VID_TO_PIXEL(x_frac) -
-			VIDEO_FONT_WIDTH - 1) * VNBYTES(vid_priv->bpix);
+	linenum = vid_priv->ysize - y - 1;
+	x = vid_priv->xsize - VID_TO_PIXEL(x_frac) - 1;
+	start = vid_priv->fb + linenum * vid_priv->line_length + x * pbytes;
+	line = start;
 
 	for (row = 0; row < VIDEO_FONT_HEIGHT; row++) {
 		unsigned int idx = (u8)ch * VIDEO_FONT_HEIGHT + row;
@@ -261,6 +283,10 @@
 		}
 		line -= vid_priv->line_length;
 	}
+	/* Add 4 bytes to allow for the first pixel writen */
+	ret = vidconsole_sync_copy(dev, start + 4, line);
+	if (ret)
+		return ret;
 
 	return VID_TO_POS(VIDEO_FONT_WIDTH);
 }
@@ -269,10 +295,11 @@
 {
 	struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
 	int pbytes = VNBYTES(vid_priv->bpix);
-	void *line;
-	int i, j;
+	void *start, *line;
+	int i, j, ret;
 
-	line = vid_priv->fb + row * VIDEO_FONT_HEIGHT * pbytes;
+	start = vid_priv->fb + row * VIDEO_FONT_HEIGHT * pbytes;
+	line = start;
 	for (j = 0; j < vid_priv->ysize; j++) {
 		switch (vid_priv->bpix) {
 		case VIDEO_BPP8:
@@ -304,6 +331,9 @@
 		}
 		line += vid_priv->line_length;
 	}
+	ret = vidconsole_sync_copy(dev, start, line);
+	if (ret)
+		return ret;
 
 	return 0;
 }
@@ -312,16 +342,19 @@
 			       uint count)
 {
 	struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
+	int pbytes = VNBYTES(vid_priv->bpix);
 	void *dst;
 	void *src;
-	int pbytes = VNBYTES(vid_priv->bpix);
-	int j;
+	int j, ret;
 
 	dst = vid_priv->fb + rowdst * VIDEO_FONT_HEIGHT * pbytes;
 	src = vid_priv->fb + rowsrc * VIDEO_FONT_HEIGHT * pbytes;
 
 	for (j = 0; j < vid_priv->ysize; j++) {
-		memmove(dst, src, VIDEO_FONT_HEIGHT * pbytes * count);
+		ret = vidconsole_memmove(dev, dst, src,
+					 VIDEO_FONT_HEIGHT * pbytes * count);
+		if (ret)
+			return ret;
 		src += vid_priv->line_length;
 		dst += vid_priv->line_length;
 	}
@@ -334,17 +367,17 @@
 	struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
 	struct udevice *vid = dev->parent;
 	struct video_priv *vid_priv = dev_get_uclass_priv(vid);
+	uchar *pfont = video_fontdata + (u8)ch * VIDEO_FONT_HEIGHT;
 	int pbytes = VNBYTES(vid_priv->bpix);
-	int i, col;
+	int i, col, x, ret;
 	int mask = 0x80;
-	void *line = vid_priv->fb +
-		(vid_priv->ysize - VID_TO_PIXEL(x_frac) - 1) *
-		vid_priv->line_length + y * pbytes;
-	uchar *pfont = video_fontdata + (u8)ch * VIDEO_FONT_HEIGHT;
+	void *start, *line;
 
 	if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
 		return -EAGAIN;
-
+	x = vid_priv->ysize - VID_TO_PIXEL(x_frac) - 1;
+	start = vid_priv->fb + x * vid_priv->line_length + y * pbytes;
+	line = start;
 	for (col = 0; col < VIDEO_FONT_HEIGHT; col++) {
 		switch (vid_priv->bpix) {
 		case VIDEO_BPP8:
@@ -386,6 +419,10 @@
 		line -= vid_priv->line_length;
 		mask >>= 1;
 	}
+	/* Add a line to allow for the first pixels writen */
+	ret = vidconsole_sync_copy(dev, start + vid_priv->line_length, line);
+	if (ret)
+		return ret;
 
 	return VID_TO_POS(VIDEO_FONT_WIDTH);
 }
diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c
index 5f7f039..22b2ea7 100644
--- a/drivers/video/console_truetype.c
+++ b/drivers/video/console_truetype.c
@@ -127,9 +127,9 @@
 {
 	struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
 	struct console_tt_priv *priv = dev_get_priv(dev);
-	void *line;
+	void *end, *line;
 	int pixels = priv->font_size * vid_priv->line_length;
-	int i;
+	int i, ret;
 
 	line = vid_priv->fb + row * priv->font_size * vid_priv->line_length;
 	switch (vid_priv->bpix) {
@@ -139,6 +139,7 @@
 
 		for (i = 0; i < pixels; i++)
 			*dst++ = clr;
+		end = dst;
 		break;
 	}
 #endif
@@ -148,6 +149,7 @@
 
 		for (i = 0; i < pixels; i++)
 			*dst++ = clr;
+		end = dst;
 		break;
 	}
 #endif
@@ -157,12 +159,16 @@
 
 		for (i = 0; i < pixels; i++)
 			*dst++ = clr;
+		end = dst;
 		break;
 	}
 #endif
 	default:
 		return -ENOSYS;
 	}
+	ret = vidconsole_sync_copy(dev, line, end);
+	if (ret)
+		return ret;
 
 	return 0;
 }
@@ -174,11 +180,14 @@
 	struct console_tt_priv *priv = dev_get_priv(dev);
 	void *dst;
 	void *src;
-	int i, diff;
+	int i, diff, ret;
 
 	dst = vid_priv->fb + rowdst * priv->font_size * vid_priv->line_length;
 	src = vid_priv->fb + rowsrc * priv->font_size * vid_priv->line_length;
-	memmove(dst, src, priv->font_size * vid_priv->line_length * count);
+	ret = vidconsole_memmove(dev, dst, src, priv->font_size *
+				 vid_priv->line_length * count);
+	if (ret)
+		return ret;
 
 	/* Scroll up our position history */
 	diff = (rowsrc - rowdst) * priv->font_size;
@@ -203,8 +212,8 @@
 	struct pos_info *pos;
 	u8 *bits, *data;
 	int advance;
-	void *line;
-	int row;
+	void *start, *end, *line;
+	int row, ret;
 
 	/* First get some basic metrics about this character */
 	stbtt_GetCodepointHMetrics(font, ch, &advance, &lsb);
@@ -253,11 +262,12 @@
 
 	/* Figure out where to write the character in the frame buffer */
 	bits = data;
-	line = vid_priv->fb + y * vid_priv->line_length +
+	start = vid_priv->fb + y * vid_priv->line_length +
 		VID_TO_PIXEL(x) * VNBYTES(vid_priv->bpix);
 	linenum = priv->baseline + yoff;
 	if (linenum > 0)
-		line += linenum * vid_priv->line_length;
+		start += linenum * vid_priv->line_length;
+	line = start;
 
 	/*
 	 * Write a row at a time, converting the 8bpp image into the colour
@@ -286,6 +296,7 @@
 					*dst++ &= out;
 				bits++;
 			}
+			end = dst;
 			break;
 		}
 #endif
@@ -307,6 +318,7 @@
 					*dst++ &= out;
 				bits++;
 			}
+			end = dst;
 			break;
 		}
 #endif
@@ -317,6 +329,9 @@
 
 		line += vid_priv->line_length;
 	}
+	ret = vidconsole_sync_copy(dev, start, line);
+	if (ret)
+		return ret;
 	free(data);
 
 	return width_frac;
@@ -340,12 +355,13 @@
 				  int xend, int yend, int clr)
 {
 	struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
-	void *line;
+	void *start, *line;
 	int pixels = xend - xstart;
-	int row, i;
+	int row, i, ret;
 
-	line = vid_priv->fb + ystart * vid_priv->line_length;
-	line += xstart * VNBYTES(vid_priv->bpix);
+	start = vid_priv->fb + ystart * vid_priv->line_length;
+	start += xstart * VNBYTES(vid_priv->bpix);
+	line = start;
 	for (row = ystart; row < yend; row++) {
 		switch (vid_priv->bpix) {
 #ifdef CONFIG_VIDEO_BPP8
@@ -380,6 +396,9 @@
 		}
 		line += vid_priv->line_length;
 	}
+	ret = vidconsole_sync_copy(dev, start, line);
+	if (ret)
+		return ret;
 
 	return 0;
 }
diff --git a/drivers/video/ivybridge_igd.c b/drivers/video/ivybridge_igd.c
index 4c57e31..2587f53 100644
--- a/drivers/video/ivybridge_igd.c
+++ b/drivers/video/ivybridge_igd.c
@@ -11,6 +11,7 @@
 #include <log.h>
 #include <pci_rom.h>
 #include <vbe.h>
+#include <video.h>
 #include <asm/intel_regs.h>
 #include <asm/io.h>
 #include <asm/mtrr.h>
@@ -722,7 +723,6 @@
 {
 	struct udevice *nbridge;
 	void *gtt_bar;
-	ulong base;
 	u32 reg32;
 	int ret;
 	int rev;
@@ -742,11 +742,6 @@
 	reg32 |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
 	dm_pci_write_config32(dev, PCI_COMMAND, reg32);
 
-	/* Use write-combining for the graphics memory, 256MB */
-	base = dm_pci_read_bar32(dev, 2);
-	mtrr_add_request(MTRR_TYPE_WRCOMB, base, 256 << 20);
-	mtrr_commit(true);
-
 	gtt_bar = (void *)(ulong)dm_pci_read_bar32(dev, 0);
 	debug("GT bar %p\n", gtt_bar);
 	ret = gma_pm_init_pre_vbios(gtt_bar, rev);
@@ -758,6 +753,8 @@
 
 static int bd82x6x_video_probe(struct udevice *dev)
 {
+	struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
+	ulong fbbase;
 	void *gtt_bar;
 	int ret, rev;
 
@@ -774,9 +771,25 @@
 	if (ret)
 		return ret;
 
+	/* Use write-combining for the graphics memory, 256MB */
+	fbbase = IS_ENABLED(CONFIG_VIDEO_COPY) ? plat->copy_base : plat->base;
+	mtrr_add_request(MTRR_TYPE_WRCOMB, fbbase, 256 << 20);
+	mtrr_commit(true);
+
 	return 0;
 }
 
+static int bd82x6x_video_bind(struct udevice *dev)
+{
+	struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev);
+
+	/* Set the maximum supported resolution */
+	uc_plat->size = 2560 * 1600 * 4;
+	log_debug("%s: Frame buffer size %x\n", __func__, uc_plat->size);
+
+	return 0;
+}
+
 static const struct udevice_id bd82x6x_video_ids[] = {
 	{ .compatible = "intel,gma" },
 	{ }
@@ -786,5 +799,6 @@
 	.name	= "bd82x6x_video",
 	.id	= UCLASS_VIDEO,
 	.of_match = bd82x6x_video_ids,
+	.bind	= bd82x6x_video_bind,
 	.probe	= bd82x6x_video_probe,
 };
diff --git a/drivers/video/rockchip/rk3288_vop.c b/drivers/video/rockchip/rk3288_vop.c
index 25ef25b..68d1507 100644
--- a/drivers/video/rockchip/rk3288_vop.c
+++ b/drivers/video/rockchip/rk3288_vop.c
@@ -97,8 +97,8 @@
 static const struct video_ops rk3288_vop_ops = {
 };
 
-U_BOOT_DRIVER(rk_vop) = {
-	.name	= "rk3288_vop",
+U_BOOT_DRIVER(rockchip_rk3288_vop) = {
+	.name	= "rockchip_rk3288_vop",
 	.id	= UCLASS_VIDEO,
 	.of_match = rk3288_vop_ids,
 	.ops	= &rk3288_vop_ops,
diff --git a/drivers/video/sandbox_sdl.c b/drivers/video/sandbox_sdl.c
index 20248e6..d806f35 100644
--- a/drivers/video/sandbox_sdl.c
+++ b/drivers/video/sandbox_sdl.c
@@ -23,6 +23,7 @@
 
 static int sandbox_sdl_probe(struct udevice *dev)
 {
+	struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev);
 	struct sandbox_sdl_plat *plat = dev_get_platdata(dev);
 	struct video_priv *uc_priv = dev_get_uclass_priv(dev);
 	struct sandbox_state *state = state_get_current();
@@ -40,6 +41,8 @@
 	uc_priv->rot = plat->rot;
 	uc_priv->vidconsole_drv_name = plat->vidconsole_drv_name;
 	uc_priv->font_size = plat->font_size;
+	if (IS_ENABLED(CONFIG_VIDEO_COPY))
+		uc_plat->copy_base = uc_plat->base - uc_plat->size / 2;
 
 	return 0;
 }
@@ -53,8 +56,13 @@
 	plat->xres = dev_read_u32_default(dev, "xres", LCD_MAX_WIDTH);
 	plat->yres = dev_read_u32_default(dev, "yres", LCD_MAX_HEIGHT);
 	plat->bpix = dev_read_u32_default(dev, "log2-depth", VIDEO_BPP16);
+	plat->rot = dev_read_u32_default(dev, "rotate", 0);
 	uc_plat->size = plat->xres * plat->yres * (1 << plat->bpix) / 8;
-	debug("%s: Frame buffer size %x\n", __func__, uc_plat->size);
+
+	/* Allow space for two buffers, the lower one being the copy buffer */
+	log_debug("Frame buffer size %x\n", uc_plat->size);
+	if (IS_ENABLED(CONFIG_VIDEO_COPY))
+		uc_plat->size *= 2;
 
 	return ret;
 }
@@ -64,8 +72,8 @@
 	{ }
 };
 
-U_BOOT_DRIVER(sdl_sandbox) = {
-	.name	= "sdl_sandbox",
+U_BOOT_DRIVER(sandbox_lcd_sdl) = {
+	.name	= "sandbox_lcd_sdl",
 	.id	= UCLASS_VIDEO,
 	.of_match = sandbox_sdl_ids,
 	.bind	= sandbox_sdl_bind,
diff --git a/drivers/video/vesa.c b/drivers/video/vesa.c
index 6c03611..9656326 100644
--- a/drivers/video/vesa.c
+++ b/drivers/video/vesa.c
@@ -5,12 +5,39 @@
 
 #include <common.h>
 #include <dm.h>
+#include <log.h>
 #include <pci.h>
 #include <vbe.h>
+#include <video.h>
+#include <asm/mtrr.h>
 
 static int vesa_video_probe(struct udevice *dev)
 {
-	return vbe_setup_video(dev, NULL);
+	struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
+	ulong fbbase;
+	int ret;
+
+	ret = vbe_setup_video(dev, NULL);
+	if (ret)
+		return log_ret(ret);
+
+	/* Use write-combining for the graphics memory, 256MB */
+	fbbase = IS_ENABLED(CONFIG_VIDEO_COPY) ? plat->copy_base : plat->base;
+	mtrr_add_request(MTRR_TYPE_WRCOMB, fbbase, 256 << 20);
+	mtrr_commit(true);
+
+	return 0;
+}
+
+static int vesa_video_bind(struct udevice *dev)
+{
+	struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev);
+
+	/* Set the maximum supported resolution */
+	uc_plat->size = 2560 * 1600 * 4;
+	log_debug("%s: Frame buffer size %x\n", __func__, uc_plat->size);
+
+	return 0;
 }
 
 static const struct udevice_id vesa_video_ids[] = {
@@ -22,6 +49,7 @@
 	.name	= "vesa_video",
 	.id	= UCLASS_VIDEO,
 	.of_match = vesa_video_ids,
+	.bind	= vesa_video_bind,
 	.probe	= vesa_video_probe,
 };
 
diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c
index 3f20f70..3a07f36 100644
--- a/drivers/video/vidconsole-uclass.c
+++ b/drivers/video/vidconsole-uclass.c
@@ -9,12 +9,13 @@
 
 #include <common.h>
 #include <command.h>
+#include <console.h>
 #include <log.h>
-#include <linux/ctype.h>
 #include <dm.h>
 #include <video.h>
 #include <video_console.h>
 #include <video_font.h>		/* Bitmap font for code page 437 */
+#include <linux/ctype.h>
 
 /*
  * Structure to describe a console color
@@ -556,16 +557,31 @@
 static void vidconsole_putc(struct stdio_dev *sdev, const char ch)
 {
 	struct udevice *dev = sdev->priv;
+	int ret;
 
-	vidconsole_put_char(dev, ch);
+	ret = vidconsole_put_char(dev, ch);
+	if (ret) {
+#ifdef DEBUG
+		console_puts_select_stderr(true, "[vc err: putc]");
+#endif
+	}
 	video_sync(dev->parent, false);
 }
 
 static void vidconsole_puts(struct stdio_dev *sdev, const char *s)
 {
 	struct udevice *dev = sdev->priv;
+	int ret;
+
+	ret = vidconsole_put_string(dev, s);
+	if (ret) {
+#ifdef DEBUG
+		char str[30];
 
-	vidconsole_put_string(dev, s);
+		snprintf(str, sizeof(str), "[vc err: puts %d]", ret);
+		console_puts_select_stderr(true, str);
+#endif
+	}
 	video_sync(dev->parent, false);
 }
 
@@ -613,6 +629,22 @@
 	.per_device_auto_alloc_size	= sizeof(struct vidconsole_priv),
 };
 
+#ifdef CONFIG_VIDEO_COPY
+int vidconsole_sync_copy(struct udevice *dev, void *from, void *to)
+{
+	struct udevice *vid = dev_get_parent(dev);
+
+	return video_sync_copy(vid, from, to);
+}
+
+int vidconsole_memmove(struct udevice *dev, void *dst, const void *src,
+		       int size)
+{
+	memmove(dst, src, size);
+	return vidconsole_sync_copy(dev, dst, dst + size);
+}
+#endif
+
 #if CONFIG_IS_ENABLED(CMD_VIDCONSOLE)
 void vidconsole_position_cursor(struct udevice *dev, unsigned col, unsigned row)
 {
diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c
index 1f28745..650891e 100644
--- a/drivers/video/video-uclass.c
+++ b/drivers/video/video-uclass.c
@@ -4,6 +4,7 @@
  */
 
 #include <common.h>
+#include <console.h>
 #include <cpu_func.h>
 #include <dm.h>
 #include <log.h>
@@ -45,6 +46,19 @@
  */
 DECLARE_GLOBAL_DATA_PTR;
 
+/**
+ * struct video_uc_priv - Information for the video uclass
+ *
+ * @video_ptr: Current allocation position of the video framebuffer pointer.
+ *	While binding devices after relocation, this points to the next
+ *	available address to use for a device's framebuffer. It starts at
+ *	gd->video_top and works downwards, running out of space when it hits
+ *	gd->video_bottom.
+ */
+struct video_uc_priv {
+	ulong video_ptr;
+};
+
 void video_set_flush_dcache(struct udevice *dev, bool flush)
 {
 	struct video_priv *priv = dev_get_uclass_priv(dev);
@@ -83,6 +97,11 @@
 		debug("%s: Reserving %lx bytes at %lx for video device '%s'\n",
 		      __func__, size, *addrp, dev->name);
 	}
+
+	/* Allocate space for PCI video devices in case there were not bound */
+	if (*addrp == gd->video_top)
+		*addrp -= CONFIG_VIDEO_PCI_DEFAULT_FB_SIZE;
+
 	gd->video_bottom = *addrp;
 	gd->fb_base = *addrp;
 	debug("Video frame buffers from %lx to %lx\n", gd->video_bottom,
@@ -94,6 +113,7 @@
 int video_clear(struct udevice *dev)
 {
 	struct video_priv *priv = dev_get_uclass_priv(dev);
+	int ret;
 
 	switch (priv->bpix) {
 	case VIDEO_BPP16:
@@ -118,6 +138,9 @@
 		memset(priv->fb, priv->colour_bg, priv->fb_size);
 		break;
 	}
+	ret = video_sync_copy(dev, priv->fb, priv->fb + priv->fb_size);
+	if (ret)
+		return ret;
 
 	return 0;
 }
@@ -201,6 +224,59 @@
 	return priv->ysize;
 }
 
+#ifdef CONFIG_VIDEO_COPY
+int video_sync_copy(struct udevice *dev, void *from, void *to)
+{
+	struct video_priv *priv = dev_get_uclass_priv(dev);
+
+	if (priv->copy_fb) {
+		long offset, size;
+
+		/* Find the offset of the first byte to copy */
+		if ((ulong)to > (ulong)from) {
+			size = to - from;
+			offset = from - priv->fb;
+		} else {
+			size = from - to;
+			offset = to - priv->fb;
+		}
+
+		/*
+		 * Allow a bit of leeway for valid requests somewhere near the
+		 * frame buffer
+		 */
+		if (offset < -priv->fb_size || offset > 2 * priv->fb_size) {
+#ifdef DEBUG
+			char str[80];
+
+			snprintf(str, sizeof(str),
+				 "[sync_copy fb=%p, from=%p, to=%p, offset=%lx]",
+				 priv->fb, from, to, offset);
+			console_puts_select_stderr(true, str);
+#endif
+			return -EFAULT;
+		}
+
+		/*
+		 * Silently crop the memcpy. This allows callers to avoid doing
+		 * this themselves. It is common for the end pointer to go a
+		 * few lines after the end of the frame buffer, since most of
+		 * the update algorithms terminate a line after their last write
+		 */
+		if (offset + size > priv->fb_size) {
+			size = priv->fb_size - offset;
+		} else if (offset < 0) {
+			size += offset;
+			offset = 0;
+		}
+
+		memcpy(priv->copy_fb + offset, priv->fb + offset, size);
+	}
+
+	return 0;
+}
+#endif
+
 /* Set up the colour map */
 static int video_pre_probe(struct udevice *dev)
 {
@@ -239,6 +315,9 @@
 
 	priv->fb_size = priv->line_length * priv->ysize;
 
+	if (IS_ENABLED(CONFIG_VIDEO_COPY) && plat->copy_base)
+		priv->copy_fb = map_sysmem(plat->copy_base, plat->size);
+
 	/* Set up colors  */
 	video_set_default_colors(dev, false);
 
@@ -290,12 +369,21 @@
 /* Post-relocation, allocate memory for the frame buffer */
 static int video_post_bind(struct udevice *dev)
 {
-	ulong addr = gd->video_top;
+	struct video_uc_priv *uc_priv;
+	ulong addr;
 	ulong size;
 
 	/* Before relocation there is nothing to do here */
 	if (!(gd->flags & GD_FLG_RELOC))
 		return 0;
+
+	/* Set up the video pointer, if this is the first device */
+	uc_priv = dev->uclass->priv;
+	if (!uc_priv->video_ptr)
+		uc_priv->video_ptr = gd->video_top;
+
+	/* Allocate framebuffer space for this device */
+	addr = uc_priv->video_ptr;
 	size = alloc_fb(dev, &addr);
 	if (addr < gd->video_bottom) {
 		/* Device tree node may need the 'u-boot,dm-pre-reloc' or
@@ -307,7 +395,7 @@
 	}
 	debug("%s: Claiming %lx bytes at %lx for video device '%s'\n",
 	      __func__, size, addr, dev->name);
-	gd->video_bottom = addr;
+	uc_priv->video_ptr = addr;
 
 	return 0;
 }
@@ -320,6 +408,7 @@
 	.pre_probe	= video_pre_probe,
 	.post_probe	= video_post_probe,
 	.pre_remove	= video_pre_remove,
+	.priv_auto_alloc_size	= sizeof(struct video_uc_priv),
 	.per_device_auto_alloc_size	= sizeof(struct video_priv),
 	.per_device_platdata_auto_alloc_size = sizeof(struct video_uc_platdata),
 };
diff --git a/drivers/video/video_bmp.c b/drivers/video/video_bmp.c
index 7d7f37b..5a4d12c 100644
--- a/drivers/video/video_bmp.c
+++ b/drivers/video/video_bmp.c
@@ -192,7 +192,7 @@
 	struct video_priv *priv = dev_get_uclass_priv(dev);
 	ushort *cmap_base = NULL;
 	int i, j;
-	uchar *fb;
+	uchar *start, *fb;
 	struct bmp_image *bmp = map_sysmem(bmp_image, 0);
 	uchar *bmap;
 	ushort padded_width;
@@ -201,6 +201,7 @@
 	unsigned colours, bpix, bmp_bpix;
 	struct bmp_color_table_entry *palette;
 	int hdr_size;
+	int ret;
 
 	if (!bmp || !(bmp->header.signature[0] == 'B' &&
 	    bmp->header.signature[1] == 'M')) {
@@ -261,8 +262,11 @@
 		height = priv->ysize - y;
 
 	bmap = (uchar *)bmp + get_unaligned_le32(&bmp->header.data_offset);
-	fb = (uchar *)(priv->fb +
-		(y + height - 1) * priv->line_length + x * bpix / 8);
+	start = (uchar *)(priv->fb +
+		(y + height) * priv->line_length + x * bpix / 8);
+
+	/* Move back to the final line to be drawn */
+	fb = start - priv->line_length;
 
 	switch (bmp_bpix) {
 	case 1:
@@ -369,6 +373,12 @@
 		break;
 	};
 
+	/* Find the position of the top left of the image in the framebuffer */
+	fb = (uchar *)(priv->fb + y * priv->line_length + x * bpix / 8);
+	ret = video_sync_copy(dev, start, fb);
+	if (ret)
+		return log_ret(ret);
+
 	video_sync(dev, false);
 
 	return 0;
diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c
index 18756e3..33f5c35 100644
--- a/drivers/watchdog/at91sam9_wdt.c
+++ b/drivers/watchdog/at91sam9_wdt.c
@@ -113,8 +113,8 @@
 	return 0;
 }
 
-U_BOOT_DRIVER(at91_wdt) = {
-	.name = "at91_wdt",
+U_BOOT_DRIVER(atmel_at91sam9260_wdt) = {
+	.name = "atmel_at91sam9260_wdt",
 	.id = UCLASS_WDT,
 	.of_match = at91_wdt_ids,
 	.priv_auto_alloc_size = sizeof(struct at91_wdt_priv),
diff --git a/include/bootstage.h b/include/bootstage.h
index f507271..00c85fb 100644
--- a/include/bootstage.h
+++ b/include/bootstage.h
@@ -338,7 +338,7 @@
  * @param base	Base address of memory buffer
  * @param size	Size of memory buffer (-1 if unknown)
  * @return 0 if unstashed ok, -ENOENT if bootstage info not found, -ENOSPC if
- *	there is not space for read the stacked data, or other error if
+ *	there is not space for read the stashed data, or other error if
  *	something else went wrong
  */
 int bootstage_unstash(const void *base, int size);
diff --git a/include/clk.h b/include/clk.h
index c6a2713..a62e2ef 100644
--- a/include/clk.h
+++ b/include/clk.h
@@ -89,8 +89,8 @@
 
 #if CONFIG_IS_ENABLED(OF_CONTROL) && CONFIG_IS_ENABLED(CLK)
 struct phandle_1_arg;
-int clk_get_by_index_platdata(struct udevice *dev, int index,
-			      struct phandle_1_arg *cells, struct clk *clk);
+int clk_get_by_driver_info(struct udevice *dev,
+			   struct phandle_1_arg *cells, struct clk *clk);
 
 /**
  * clk_get_by_index - Get/request a clock by integer index.
diff --git a/include/configs/MPC8548CDS.h b/include/configs/MPC8548CDS.h
index 1cb62ae..4b40129 100644
--- a/include/configs/MPC8548CDS.h
+++ b/include/configs/MPC8548CDS.h
@@ -43,11 +43,6 @@
  */
 #define CONFIG_ENABLE_36BIT_PHYS	1
 
-#ifdef CONFIG_PHYS_64BIT
-#define CONFIG_ADDR_MAP
-#define CONFIG_SYS_NUM_ADDR_MAP		16	/* number of TLB1 entries */
-#endif
-
 #define CONFIG_SYS_CCSRBAR		0xe0000000
 #define CONFIG_SYS_CCSRBAR_PHYS_LOW	CONFIG_SYS_CCSRBAR
 
diff --git a/include/configs/MPC8572DS.h b/include/configs/MPC8572DS.h
index b4e5e3b..429dae1 100644
--- a/include/configs/MPC8572DS.h
+++ b/include/configs/MPC8572DS.h
@@ -45,11 +45,6 @@
 
 #define CONFIG_ENABLE_36BIT_PHYS	1
 
-#ifdef CONFIG_PHYS_64BIT
-#define CONFIG_ADDR_MAP			1
-#define CONFIG_SYS_NUM_ADDR_MAP		16	/* number of TLB1 entries */
-#endif
-
 /*
  * Config the L2 Cache as L2 SRAM
  */
diff --git a/include/configs/MPC8641HPCN.h b/include/configs/MPC8641HPCN.h
index a7f02ae..1560b61 100644
--- a/include/configs/MPC8641HPCN.h
+++ b/include/configs/MPC8641HPCN.h
@@ -19,7 +19,6 @@
 
 /* High Level Configuration Options */
 #define CONFIG_LINUX_RESET_VEC	0x100	/* Reset vector used by Linux */
-#define CONFIG_ADDR_MAP		1	/* Use addr map */
 
 /*
  * default CCSRBAR is at 0xff700000
@@ -47,7 +46,6 @@
 #define CONFIG_ENV_OVERWRITE
 
 #define CONFIG_BAT_RW		1	/* Use common BAT rw code */
-#define CONFIG_SYS_NUM_ADDR_MAP 8	/* Number of addr map slots = 8 dbats */
 
 #define CONFIG_ALTIVEC		1
 
diff --git a/include/configs/P1010RDB.h b/include/configs/P1010RDB.h
index 8f709a6..fc74d57 100644
--- a/include/configs/P1010RDB.h
+++ b/include/configs/P1010RDB.h
@@ -196,11 +196,6 @@
 
 #define CONFIG_ENABLE_36BIT_PHYS
 
-#ifdef CONFIG_PHYS_64BIT
-#define CONFIG_ADDR_MAP			1
-#define CONFIG_SYS_NUM_ADDR_MAP		16	/* number of TLB1 entries */
-#endif
-
 /* DDR Setup */
 #define CONFIG_SYS_DDR_RAW_TIMING
 #define CONFIG_DDR_SPD
diff --git a/include/configs/P2041RDB.h b/include/configs/P2041RDB.h
index 94cbe10..c6a64ee 100644
--- a/include/configs/P2041RDB.h
+++ b/include/configs/P2041RDB.h
@@ -70,11 +70,6 @@
 
 #define CONFIG_ENABLE_36BIT_PHYS
 
-#ifdef CONFIG_PHYS_64BIT
-#define CONFIG_ADDR_MAP
-#define CONFIG_SYS_NUM_ADDR_MAP		64	/* number of TLB1 entries */
-#endif
-
 #define CONFIG_POST CONFIG_SYS_POST_MEMORY	/* test POST memory test */
 
 /*
diff --git a/include/configs/T102xRDB.h b/include/configs/T102xRDB.h
index f5d9657..efd9b6b 100644
--- a/include/configs/T102xRDB.h
+++ b/include/configs/T102xRDB.h
@@ -17,11 +17,6 @@
 #define CONFIG_SYS_BOOK3E_HV		/* Category E.HV supported */
 #define CONFIG_ENABLE_36BIT_PHYS
 
-#ifdef CONFIG_PHYS_64BIT
-#define CONFIG_ADDR_MAP		1
-#define CONFIG_SYS_NUM_ADDR_MAP	64	/* number of TLB1 entries */
-#endif
-
 #define CONFIG_SYS_FSL_CPC		/* Corenet Platform Cache */
 #define CONFIG_SYS_NUM_CPC		CONFIG_SYS_NUM_DDR_CTLRS
 
diff --git a/include/configs/T104xRDB.h b/include/configs/T104xRDB.h
index 4237dfc..8f9de56 100644
--- a/include/configs/T104xRDB.h
+++ b/include/configs/T104xRDB.h
@@ -186,9 +186,6 @@
 
 #define CONFIG_ENABLE_36BIT_PHYS
 
-#define CONFIG_ADDR_MAP
-#define CONFIG_SYS_NUM_ADDR_MAP		64	/* number of TLB1 entries */
-
 /*
  *  Config the L3 Cache as L3 SRAM
  */
diff --git a/include/configs/T208xQDS.h b/include/configs/T208xQDS.h
index c54f7f5..f32e668 100644
--- a/include/configs/T208xQDS.h
+++ b/include/configs/T208xQDS.h
@@ -26,11 +26,6 @@
 #define CONFIG_SYS_BOOK3E_HV	/* Category E.HV supported */
 #define CONFIG_ENABLE_36BIT_PHYS
 
-#ifdef CONFIG_PHYS_64BIT
-#define CONFIG_ADDR_MAP 1
-#define CONFIG_SYS_NUM_ADDR_MAP 64 /* number of TLB1 entries */
-#endif
-
 #define CONFIG_SYS_FSL_CPC	/* Corenet Platform Cache */
 #define CONFIG_SYS_NUM_CPC	CONFIG_SYS_NUM_DDR_CTLRS
 #define CONFIG_ENV_OVERWRITE
diff --git a/include/configs/T208xRDB.h b/include/configs/T208xRDB.h
index 70eafc3..e666e4f 100644
--- a/include/configs/T208xRDB.h
+++ b/include/configs/T208xRDB.h
@@ -20,11 +20,6 @@
 #define CONFIG_SYS_BOOK3E_HV	/* Category E.HV supported */
 #define CONFIG_ENABLE_36BIT_PHYS
 
-#ifdef CONFIG_PHYS_64BIT
-#define CONFIG_ADDR_MAP 1
-#define CONFIG_SYS_NUM_ADDR_MAP 64 /* number of TLB1 entries */
-#endif
-
 #define CONFIG_SYS_FSL_CPC	/* Corenet Platform Cache */
 #define CONFIG_SYS_NUM_CPC	CONFIG_SYS_NUM_DDR_CTLRS
 #define CONFIG_ENV_OVERWRITE
diff --git a/include/configs/T4240RDB.h b/include/configs/T4240RDB.h
index 9832f85..ebe7a9c 100644
--- a/include/configs/T4240RDB.h
+++ b/include/configs/T4240RDB.h
@@ -80,9 +80,6 @@
 
 #define CONFIG_ENABLE_36BIT_PHYS
 
-#define CONFIG_ADDR_MAP
-#define CONFIG_SYS_NUM_ADDR_MAP		64	/* number of TLB1 entries */
-
 /*
  *  Config the L3 Cache as L3 SRAM
  */
diff --git a/include/configs/controlcenterd.h b/include/configs/controlcenterd.h
index 823586c..512d8e1 100644
--- a/include/configs/controlcenterd.h
+++ b/include/configs/controlcenterd.h
@@ -41,11 +41,6 @@
 
 #define CONFIG_ENABLE_36BIT_PHYS
 
-#ifdef CONFIG_PHYS_64BIT
-#define CONFIG_ADDR_MAP
-#define CONFIG_SYS_NUM_ADDR_MAP		16	/* number of TLB1 entries */
-#endif
-
 #define CONFIG_L2_CACHE
 #define CONFIG_BTB
 
diff --git a/include/configs/corenet_ds.h b/include/configs/corenet_ds.h
index a49f905..d7812bd 100644
--- a/include/configs/corenet_ds.h
+++ b/include/configs/corenet_ds.h
@@ -84,11 +84,6 @@
 
 #define CONFIG_ENABLE_36BIT_PHYS
 
-#ifdef CONFIG_PHYS_64BIT
-#define CONFIG_ADDR_MAP
-#define CONFIG_SYS_NUM_ADDR_MAP		64	/* number of TLB1 entries */
-#endif
-
 #define CONFIG_POST CONFIG_SYS_POST_MEMORY	/* test POST memory test */
 
 /*
diff --git a/include/configs/cyrus.h b/include/configs/cyrus.h
index 052e601..b587cb8 100644
--- a/include/configs/cyrus.h
+++ b/include/configs/cyrus.h
@@ -70,11 +70,6 @@
 
 #define CONFIG_ENABLE_36BIT_PHYS
 
-#ifdef CONFIG_PHYS_64BIT
-#define CONFIG_ADDR_MAP
-#define CONFIG_SYS_NUM_ADDR_MAP		64	/* number of TLB1 entries */
-#endif
-
 /* test POST memory test */
 #undef CONFIG_POST
 
diff --git a/include/configs/kmp204x.h b/include/configs/kmp204x.h
index e43b2f7..6cd77ed 100644
--- a/include/configs/kmp204x.h
+++ b/include/configs/kmp204x.h
@@ -64,9 +64,6 @@
 
 #define CONFIG_ENABLE_36BIT_PHYS
 
-#define CONFIG_ADDR_MAP
-#define CONFIG_SYS_NUM_ADDR_MAP		64	/* number of TLB1 entries */
-
 #define CONFIG_POST CONFIG_SYS_POST_MEM_REGIONS	/* POST memory regions test */
 
 /*
diff --git a/include/configs/p1_p2_rdb_pc.h b/include/configs/p1_p2_rdb_pc.h
index 6b57be9..a33f2f3 100644
--- a/include/configs/p1_p2_rdb_pc.h
+++ b/include/configs/p1_p2_rdb_pc.h
@@ -233,11 +233,6 @@
 
 #define CONFIG_ENABLE_36BIT_PHYS
 
-#ifdef CONFIG_PHYS_64BIT
-#define CONFIG_ADDR_MAP			1
-#define CONFIG_SYS_NUM_ADDR_MAP		16	/* number of TLB1 entries */
-#endif
-
 #define CONFIG_SYS_CCSRBAR		0xffe00000
 #define CONFIG_SYS_CCSRBAR_PHYS_LOW	CONFIG_SYS_CCSRBAR
 
diff --git a/include/configs/qemu-ppce500.h b/include/configs/qemu-ppce500.h
index 03b0896..b3ec430 100644
--- a/include/configs/qemu-ppce500.h
+++ b/include/configs/qemu-ppce500.h
@@ -21,9 +21,6 @@
 
 #define CONFIG_ENABLE_36BIT_PHYS
 
-#define CONFIG_ADDR_MAP
-#define CONFIG_SYS_NUM_ADDR_MAP		16	/* number of TLB1 entries */
-
 /* Needed to fill the ccsrbar pointer */
 
 /* Virtual address to CCSRBAR */
diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h
index 1a981a7..0353a19 100644
--- a/include/configs/sandbox.h
+++ b/include/configs/sandbox.h
@@ -47,8 +47,11 @@
 #define CONFIG_PHYSMEM
 
 /* Size of our emulated memory */
+#define SB_CONCAT(x, y) x ## y
+#define SB_TO_UL(s) SB_CONCAT(s, UL)
 #define CONFIG_SYS_SDRAM_BASE		0
-#define CONFIG_SYS_SDRAM_SIZE		(128 << 20)
+#define CONFIG_SYS_SDRAM_SIZE \
+		(SB_TO_UL(CONFIG_SANDBOX_RAM_SIZE_MB) << 20)
 #define CONFIG_SYS_MONITOR_BASE	0
 
 #define CONFIG_SYS_BAUDRATE_TABLE	{4800, 9600, 19200, 38400, 57600,\
diff --git a/include/configs/t4qds.h b/include/configs/t4qds.h
index 3da7ee7..1f6ae46 100644
--- a/include/configs/t4qds.h
+++ b/include/configs/t4qds.h
@@ -42,9 +42,6 @@
 
 #define CONFIG_ENABLE_36BIT_PHYS
 
-#define CONFIG_ADDR_MAP
-#define CONFIG_SYS_NUM_ADDR_MAP		64	/* number of TLB1 entries */
-
 /*
  *  Config the L3 Cache as L3 SRAM
  */
diff --git a/include/configs/uniphier.h b/include/configs/uniphier.h
index 55fa85e..03bbbab 100644
--- a/include/configs/uniphier.h
+++ b/include/configs/uniphier.h
@@ -41,32 +41,12 @@
 
 #define CONFIG_ARMV7_PSCI_1_0
 
-/*-----------------------------------------------------------------------
- * MMU and Cache Setting
- *----------------------------------------------------------------------*/
-
 #define CONFIG_SYS_MALLOC_LEN		(4 * 1024 * 1024)
 
 #define CONFIG_TIMESTAMP
 
-/* FLASH related */
-
-#define CONFIG_SYS_MAX_FLASH_SECT	256
 #define CONFIG_SYS_MONITOR_BASE		0
-#define CONFIG_SYS_MONITOR_LEN		0x000d0000	/* 832KB */
-#define CONFIG_SYS_FLASH_BASE		0
-
-/*
- * flash_toggle does not work for our support card.
- * We need to use flash_status_poll.
- */
-#define CONFIG_SYS_CFI_FLASH_STATUS_POLL
-
-#define CONFIG_FLASH_SHOW_PROGRESS	45 /* count down from 45/5: 9..1 */
-
-#define CONFIG_SYS_MAX_FLASH_BANKS_DETECT 1
-
-/* serial console configuration */
+#define CONFIG_SYS_MONITOR_LEN		0x00200000	/* 2MB */
 
 #define CONFIG_SYS_CBSIZE		1024	/* Console I/O Buffer Size */
 /* Boot Argument Buffer Size */
@@ -221,7 +201,7 @@
 #define CONFIG_SYS_INIT_SP_ADDR		(CONFIG_SYS_TEXT_BASE)
 
 /* only for SPL */
-#define CONFIG_SPL_STACK		(0x00200000)
+#define CONFIG_SPL_STACK		(0x00100000)
 
 #define CONFIG_SYS_NAND_U_BOOT_OFFS		0x20000
 
diff --git a/include/console.h b/include/console.h
index 74afe22..4c6b8f26 100644
--- a/include/console.h
+++ b/include/console.h
@@ -7,6 +7,8 @@
 #ifndef __CONSOLE_H
 #define __CONSOLE_H
 
+#include <stdbool.h>
+
 extern char console_buffer[];
 
 /* common/console.c */
@@ -72,6 +74,17 @@
  */
 int console_announce_r(void);
 
+/**
+ * console_puts_select_stderr() - Output a string to selected console devices
+ *
+ * This writes to stderr only. It is useful for outputting errors
+ *
+ * @serial_only: true to output only to serial, false to output to everything
+ *	else
+ * @s: String to output
+ */
+void console_puts_select_stderr(bool serial_only, const char *s);
+
 /*
  * CONSOLE multiplexing.
  */
diff --git a/include/dm/device-internal.h b/include/dm/device-internal.h
index 294d6c1..5145fb4 100644
--- a/include/dm/device-internal.h
+++ b/include/dm/device-internal.h
@@ -81,7 +81,7 @@
  * @return 0 if OK, -ve on error
  */
 int device_bind_by_name(struct udevice *parent, bool pre_reloc_only,
-			const struct driver_info *info, struct udevice **devp);
+			struct driver_info *info, struct udevice **devp);
 
 /**
  * device_ofdata_to_platdata() - Read platform data for a device
diff --git a/include/dm/device.h b/include/dm/device.h
index 975eec5..f5738a0 100644
--- a/include/dm/device.h
+++ b/include/dm/device.h
@@ -283,6 +283,13 @@
 	ll_entry_get(struct driver, __name, driver)
 
 /**
+ * Declare a macro to state a alias for a driver name. This macro will
+ * produce no code but its information will be parsed by tools like
+ * dtoc
+ */
+#define U_BOOT_DRIVER_ALIAS(__name, __alias)
+
+/**
  * dev_get_platdata() - Get the platform data for a device
  *
  * This checks that dev is not NULL, but no other checks for now
@@ -532,6 +539,21 @@
 int device_get_global_by_ofnode(ofnode node, struct udevice **devp);
 
 /**
+ * device_get_by_driver_info() - Get a device based on driver_info
+ *
+ * Locates a device by its struct driver_info, by using its reference which
+ * is updated during the bind process.
+ *
+ * The device is probed to activate it ready for use.
+ *
+ * @info: Struct driver_info
+ * @devp: Returns pointer to device if found, otherwise this is set to NULL
+ * @return 0 if OK, -ve on error
+ */
+int device_get_by_driver_info(const struct driver_info *info,
+			      struct udevice **devp);
+
+/**
  * device_find_first_child() - Find the first child of a device
  *
  * @parent: Parent device to search
diff --git a/include/dm/platdata.h b/include/dm/platdata.h
index c972fa6..cab93b0 100644
--- a/include/dm/platdata.h
+++ b/include/dm/platdata.h
@@ -22,12 +22,14 @@
  * @name:	Driver name
  * @platdata:	Driver-specific platform data
  * @platdata_size: Size of platform data structure
+ * @dev:	Device created from this structure data
  */
 struct driver_info {
 	const char *name;
 	const void *platdata;
 #if CONFIG_IS_ENABLED(OF_PLATDATA)
 	uint platdata_size;
+	struct udevice *dev;
 #endif
 };
 
@@ -43,4 +45,16 @@
 #define U_BOOT_DEVICES(__name)						\
 	ll_entry_declare_list(struct driver_info, __name, driver_info)
 
+/* Get a pointer to a given driver */
+#define DM_GET_DEVICE(__name)						\
+	ll_entry_get(struct driver_info, __name, driver_info)
+
+/**
+ * dm_populate_phandle_data() - Populates phandle data in platda
+ *
+ * This populates phandle data with an U_BOOT_DEVICE entry get by
+ * DM_GET_DEVICE. The implementation of this function will be done
+ * by dtoc when parsing dtb.
+ */
+void dm_populate_phandle_data(void);
 #endif
diff --git a/include/dm/test.h b/include/dm/test.h
index f0f3662..d39686c 100644
--- a/include/dm/test.h
+++ b/include/dm/test.h
@@ -159,7 +159,19 @@
 /* Declare a new driver model test */
 #define DM_TEST(_name, _flags)	UNIT_TEST(_name, _flags, dm_test)
 
-/* This platform data is needed in tests, so declare it here */
+/*
+ * struct sandbox_sdl_plat - Platform data for the SDL video driver
+ *
+ * This platform data is needed in tests, so declare it here
+ *
+ * @xres: Width of display in pixels
+ * @yres: Height of display in pixels
+ * @bpix: Log2 of bits per pixel (enum video_log2_bpp)
+ * @rot: Console rotation (0=normal orientation, 1=90 degrees clockwise,
+ *	2=upside down, 3=90 degree counterclockwise)
+ * @vidconsole_drv_name: Name of video console driver (set by tests)
+ * @font_size: Console font size to select (set by tests)
+ */
 struct sandbox_sdl_plat {
 	int xres;
 	int yres;
diff --git a/include/dm/uclass.h b/include/dm/uclass.h
index 70fca79..67ff746 100644
--- a/include/dm/uclass.h
+++ b/include/dm/uclass.h
@@ -390,7 +390,7 @@
  * @id: enum uclass_id ID to use
  * @pos: struct udevice * to hold the current device. Set to NULL when there
  * are no more devices.
- * @uc: temporary uclass variable (struct udevice *)
+ * @uc: temporary uclass variable (struct uclass *)
  */
 #define uclass_id_foreach_dev(id, pos, uc) \
 	if (!uclass_get(id, &uc)) \
diff --git a/include/dt-bindings/reset/raspberrypi,firmware-reset.h b/include/dt-bindings/reset/raspberrypi,firmware-reset.h
new file mode 100644
index 0000000..1a4f4c7
--- /dev/null
+++ b/include/dt-bindings/reset/raspberrypi,firmware-reset.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2020 Nicolas Saenz Julienne
+ * Author: Nicolas Saenz Julienne <nsaenzjulienne@suse.com>
+ */
+
+#ifndef _DT_BINDINGS_RASPBERRYPI_FIRMWARE_RESET_H
+#define _DT_BINDINGS_RASPBERRYPI_FIRMWARE_RESET_H
+
+#define RASPBERRYPI_FIRMWARE_RESET_ID_USB	0
+#define RASPBERRYPI_FIRMWARE_RESET_NUM_IDS	1
+
+#endif
diff --git a/include/linux/bitfield.h b/include/linux/bitfield.h
index 8b9d6ff..7ad02f8 100644
--- a/include/linux/bitfield.h
+++ b/include/linux/bitfield.h
@@ -16,6 +16,7 @@
 #define _LINUX_BITFIELD_H
 
 #include <linux/bug.h>
+#include <asm/byteorder.h>
 
 /*
  * Bitfield access macros
@@ -103,4 +104,56 @@
 		(typeof(_mask))(((_reg) & (_mask)) >> __bf_shf(_mask));	\
 	})
 
+extern void __compiletime_error("value doesn't fit into mask")
+__field_overflow(void);
+extern void __compiletime_error("bad bitfield mask")
+__bad_mask(void);
+
+static __always_inline u64 field_multiplier(u64 field)
+{
+	if ((field | (field - 1)) & ((field | (field - 1)) + 1))
+		__bad_mask();
+	return field & -field;
+}
+
+static __always_inline u64 field_mask(u64 field)
+{
+	return field / field_multiplier(field);
+}
+
+#define ____MAKE_OP(type, base, to, from)				\
+static __always_inline __##type type##_encode_bits(base v, base field)	\
+{									\
+	if (__builtin_constant_p(v) && (v & ~field_mask(field)))	\
+		__field_overflow();					\
+	return to((v & field_mask(field)) * field_multiplier(field));	\
+}									\
+static __always_inline __##type type##_replace_bits(__##type old,	\
+					base val, base field)		\
+{									\
+	return (old & ~to(field)) | type##_encode_bits(val, field);	\
+}									\
+static __always_inline void type##p_replace_bits(__##type * p,		\
+					base val, base field)		\
+{									\
+	*p = (*p & ~to(field)) | type##_encode_bits(val, field);	\
+}									\
+static __always_inline base type##_get_bits(__##type v, base field)	\
+{									\
+	return (from(v) & field) / field_multiplier(field);		\
+}
+
+#define __MAKE_OP(size)							\
+	____MAKE_OP(le##size, u##size, cpu_to_le##size, le##size##_to_cpu) \
+	____MAKE_OP(be##size, u##size, cpu_to_be##size, be##size##_to_cpu) \
+	____MAKE_OP(u##size, u##size, ,)
+
+____MAKE_OP(u8, u8, ,)
+__MAKE_OP(16)
+__MAKE_OP(32)
+__MAKE_OP(64)
+
+#undef __MAKE_OP
+#undef ____MAKE_OP
+
 #endif
diff --git a/include/linux/kconfig.h b/include/linux/kconfig.h
index 3a2da73..d109ed3 100644
--- a/include/linux/kconfig.h
+++ b/include/linux/kconfig.h
@@ -23,54 +23,30 @@
 #define ___config_enabled(__ignored, val, ...) val
 
 /*
- * IS_ENABLED(CONFIG_FOO) evaluates to 1 if CONFIG_FOO is set to 'y' or 'm',
+ * IS_ENABLED(CONFIG_FOO) evaluates to 1 if CONFIG_FOO is set to 'y',
  * 0 otherwise.
  *
  */
 #define IS_ENABLED(option) \
-	(config_enabled(option) || config_enabled(option##_MODULE))
+	(config_enabled(option))
 
 /*
- * IS_BUILTIN(CONFIG_FOO) evaluates to 1 if CONFIG_FOO is set to 'y', 0
- * otherwise. For boolean options, this is equivalent to
- * IS_ENABLED(CONFIG_FOO).
- */
-#define IS_BUILTIN(option) config_enabled(option)
-
-/*
- * IS_MODULE(CONFIG_FOO) evaluates to 1 if CONFIG_FOO is set to 'm', 0
- * otherwise.
- */
-#define IS_MODULE(option) config_enabled(option##_MODULE)
-
-/*
  * U-Boot add-on: Helper macros to reference to different macros
  * (CONFIG_ or CONFIG_SPL_ prefixed), depending on the build context.
  */
-#ifdef CONFIG_SPL_BUILD
-#define _IS_SPL 1
-#endif
-
-#ifdef CONFIG_TPL_BUILD
-#define _IS_TPL 1
-#endif
 
 #if defined(CONFIG_TPL_BUILD)
-#define config_val(cfg) _config_val(_IS_TPL, cfg)
-#define _config_val(x, cfg) __config_val(x, cfg)
-#define __config_val(x, cfg) ___config_val(__ARG_PLACEHOLDER_##x, cfg)
-#define ___config_val(arg1_or_junk, cfg)  \
-	____config_val(arg1_or_junk CONFIG_TPL_##cfg, CONFIG_##cfg)
-#define ____config_val(__ignored, val, ...) val
+#define _CONFIG_PREFIX TPL_
+#elif defined(CONFIG_SPL_BUILD)
+#define _CONFIG_PREFIX SPL_
 #else
-#define config_val(cfg) _config_val(_IS_SPL, cfg)
-#define _config_val(x, cfg) __config_val(x, cfg)
-#define __config_val(x, cfg) ___config_val(__ARG_PLACEHOLDER_##x, cfg)
-#define ___config_val(arg1_or_junk, cfg)  \
-	____config_val(arg1_or_junk CONFIG_SPL_##cfg, CONFIG_##cfg)
-#define ____config_val(__ignored, val, ...) val
+#define _CONFIG_PREFIX
 #endif
 
+#define   config_val(cfg)       _config_val(_CONFIG_PREFIX, cfg)
+#define  _config_val(pfx, cfg) __config_val(pfx, cfg)
+#define __config_val(pfx, cfg) CONFIG_ ## pfx ## cfg
+
 /*
  * CONFIG_VAL(FOO) evaluates to the value of
  *  CONFIG_FOO if CONFIG_SPL_BUILD is undefined,
@@ -80,30 +56,55 @@
 #define CONFIG_VAL(option)  config_val(option)
 
 /*
- * CONFIG_IS_ENABLED(FOO) evaluates to
- *  1 if CONFIG_SPL_BUILD is undefined and CONFIG_FOO is set to 'y' or 'm',
- *  1 if CONFIG_SPL_BUILD is defined and CONFIG_SPL_FOO is set to 'y' or 'm',
- *  1 if CONFIG_TPL_BUILD is defined and CONFIG_TPL_FOO is set to 'y' or 'm',
- *  0 otherwise.
+ * Count number of arguments to a variadic macro. Currently only need
+ * it for 1, 2 or 3 arguments.
  */
-#define CONFIG_IS_ENABLED(option) \
-	(config_enabled(CONFIG_VAL(option)) ||		\
-	 config_enabled(CONFIG_VAL(option##_MODULE)))
+#define __arg6(a1, a2, a3, a4, a5, a6, ...) a6
+#define __count_args(...) __arg6(dummy, ##__VA_ARGS__, 4, 3, 2, 1, 0)
+
+#define __concat(a, b)   ___concat(a, b)
+#define ___concat(a, b)  a ## b
+
+#define __unwrap(...) __VA_ARGS__
+#define __unwrap1(case1, case0) __unwrap case1
+#define __unwrap0(case1, case0) __unwrap case0
+
+#define __CONFIG_IS_ENABLED_1(option)        __CONFIG_IS_ENABLED_3(option, (1), (0))
+#define __CONFIG_IS_ENABLED_2(option, case1) __CONFIG_IS_ENABLED_3(option, case1, ())
+#define __CONFIG_IS_ENABLED_3(option, case1, case0) \
+	__concat(__unwrap, config_enabled(CONFIG_VAL(option))) (case1, case0)
 
 /*
- * CONFIG_IS_BUILTIN(FOO) evaluates to
+ * CONFIG_IS_ENABLED(FOO) expands to
  *  1 if CONFIG_SPL_BUILD is undefined and CONFIG_FOO is set to 'y',
  *  1 if CONFIG_SPL_BUILD is defined and CONFIG_SPL_FOO is set to 'y',
+ *  1 if CONFIG_TPL_BUILD is defined and CONFIG_TPL_FOO is set to 'y',
  *  0 otherwise.
+ *
+ * CONFIG_IS_ENABLED(FOO, (abc)) expands to
+ *  abc if CONFIG_SPL_BUILD is undefined and CONFIG_FOO is set to 'y',
+ *  abc if CONFIG_SPL_BUILD is defined and CONFIG_SPL_FOO is set to 'y',
+ *  abc if CONFIG_TPL_BUILD is defined and CONFIG_TPL_FOO is set to 'y',
+ *  nothing otherwise.
+ *
+ * CONFIG_IS_ENABLED(FOO, (abc), (def)) expands to
+ *  abc if CONFIG_SPL_BUILD is undefined and CONFIG_FOO is set to 'y',
+ *  abc if CONFIG_SPL_BUILD is defined and CONFIG_SPL_FOO is set to 'y',
+ *  abc if CONFIG_TPL_BUILD is defined and CONFIG_TPL_FOO is set to 'y',
+ *  def otherwise.
+ *
+ * The optional second and third arguments must be parenthesized; that
+ * allows one to include a trailing comma, e.g. for use in
+ *
+ * CONFIG_IS_ENABLED(ACME, ({.compatible = "acme,frobnozzle"},))
+ *
+ * which adds an entry to the array being defined if CONFIG_ACME (or
+ * CONFIG_SPL_ACME/CONFIG_TPL_ACME, depending on build context) is
+ * set, and nothing otherwise.
  */
-#define CONFIG_IS_BUILTIN(option) config_enabled(CONFIG_VAL(option))
 
-/*
- * CONFIG_IS_MODULE(FOO) evaluates to
- *  1 if CONFIG_SPL_BUILD is undefined and CONFIG_FOO is set to 'm',
- *  1 if CONFIG_SPL_BUILD is defined and CONFIG_SPL_FOO is set to 'm',
- *  0 otherwise.
- */
-#define CONFIG_IS_MODULE(option) config_enabled(CONFIG_VAL(option##_MODULE))
+#define CONFIG_IS_ENABLED(option, ...)					\
+	__concat(__CONFIG_IS_ENABLED_, __count_args(option, ##__VA_ARGS__)) (option, ##__VA_ARGS__)
+
 
 #endif /* __LINUX_KCONFIG_H */
diff --git a/include/log.h b/include/log.h
index df65398..2859ce1 100644
--- a/include/log.h
+++ b/include/log.h
@@ -12,6 +12,7 @@
 #include <stdio.h>
 #include <linker_lists.h>
 #include <dm/uclass-id.h>
+#include <linux/bitops.h>
 #include <linux/list.h>
 
 struct cmd_tbl;
@@ -411,7 +412,6 @@
 	LOGF_MSG,
 
 	LOGF_COUNT,
-	LOGF_DEFAULT = (1 << LOGF_FUNC) | (1 << LOGF_MSG),
 	LOGF_ALL = 0x3f,
 };
 
@@ -460,4 +460,20 @@
 }
 #endif
 
+/**
+ * log_get_default_format() - get default log format
+ *
+ * The default log format is configurable via
+ * CONFIG_LOGF_FILE, CONFIG_LOGF_LINE, CONFIG_LOGF_FUNC.
+ *
+ * Return:	default log format
+ */
+static inline int log_get_default_format(void)
+{
+	return BIT(LOGF_MSG) |
+	       (IS_ENABLED(CONFIG_LOGF_FILE) ? BIT(LOGF_FILE) : 0) |
+	       (IS_ENABLED(CONFIG_LOGF_LINE) ? BIT(LOGF_LINE) : 0) |
+	       (IS_ENABLED(CONFIG_LOGF_FUNC) ? BIT(LOGF_FUNC) : 0);
+}
+
 #endif
diff --git a/include/pci.h b/include/pci.h
index 19c9244..281f353 100644
--- a/include/pci.h
+++ b/include/pci.h
@@ -471,10 +471,28 @@
 #define  PCI_EA_FIELD_MASK	0xfffffffc	/* For Base & Max Offset */
 
 /* PCI Express capabilities */
+#define PCI_EXP_FLAGS		2	/* Capabilities register */
+#define  PCI_EXP_FLAGS_TYPE	0x00f0	/* Device/Port type */
+#define  PCI_EXP_TYPE_ROOT_PORT 0x4	/* Root Port */
 #define PCI_EXP_DEVCAP		4	/* Device capabilities */
-#define  PCI_EXP_DEVCAP_FLR     0x10000000 /* Function Level Reset */
+#define  PCI_EXP_DEVCAP_FLR	0x10000000 /* Function Level Reset */
 #define PCI_EXP_DEVCTL		8	/* Device Control */
-#define  PCI_EXP_DEVCTL_BCR_FLR 0x8000  /* Bridge Configuration Retry / FLR */
+#define  PCI_EXP_DEVCTL_BCR_FLR	0x8000  /* Bridge Configuration Retry / FLR */
+#define PCI_EXP_LNKCAP		12	/* Link Capabilities */
+#define  PCI_EXP_LNKCAP_SLS	0x0000000f /* Supported Link Speeds */
+#define  PCI_EXP_LNKCAP_MLW	0x000003f0 /* Maximum Link Width */
+#define  PCI_EXP_LNKCAP_DLLLARC	0x00100000 /* Data Link Layer Link Active Reporting Capable */
+#define PCI_EXP_LNKSTA		18	/* Link Status */
+#define  PCI_EXP_LNKSTA_CLS	0x000f	/* Current Link Speed */
+#define  PCI_EXP_LNKSTA_CLS_2_5GB 0x0001 /* Current Link Speed 2.5GT/s */
+#define  PCI_EXP_LNKSTA_CLS_5_0GB 0x0002 /* Current Link Speed 5.0GT/s */
+#define  PCI_EXP_LNKSTA_CLS_8_0GB 0x0003 /* Current Link Speed 8.0GT/s */
+#define  PCI_EXP_LNKSTA_NLW	0x03f0	/* Negotiated Link Width */
+#define  PCI_EXP_LNKSTA_NLW_SHIFT 4	/* start of NLW mask in link status */
+#define  PCI_EXP_LNKSTA_DLLLA	0x2000	/* Data Link Layer Link Active */
+#define PCI_EXP_SLTCAP		20	/* Slot Capabilities */
+#define  PCI_EXP_SLTCAP_PSN	0xfff80000 /* Physical Slot Number */
+#define PCI_EXP_LNKCTL2		48	/* Link Control 2 */
 
 /* Include the ID list */
 
diff --git a/include/spi.h b/include/spi.h
index 9b4fb8d..a37900b 100644
--- a/include/spi.h
+++ b/include/spi.h
@@ -39,7 +39,6 @@
 
 #define SPI_DEFAULT_WORDLEN	8
 
-#if CONFIG_IS_ENABLED(DM_SPI)
 /* TODO(sjg@chromium.org): Remove this and use max_hz from struct spi_slave */
 struct dm_spi_bus {
 	uint max_hz;
@@ -65,8 +64,6 @@
 	uint mode;
 };
 
-#endif /* CONFIG_DM_SPI */
-
 /**
  * enum spi_clock_phase - indicates  the clock phase to use for SPI (CPHA)
  *
@@ -317,6 +314,11 @@
  */
 int spi_cs_is_valid(unsigned int bus, unsigned int cs);
 
+/*
+ * These names are used in several drivers and these declarations will be
+ * removed soon as part of the SPI DM migration. Drop them if driver model is
+ * enabled for SPI.
+ */
 #if !CONFIG_IS_ENABLED(DM_SPI)
 /**
  * Activate a SPI chipselect.
@@ -335,6 +337,7 @@
  * select to the device identified by "slave".
  */
 void spi_cs_deactivate(struct spi_slave *slave);
+#endif
 
 /**
  * Set transfer speed.
@@ -343,7 +346,6 @@
  * @hz:		The transfer speed
  */
 void spi_set_speed(struct spi_slave *slave, uint hz);
-#endif
 
 /**
  * Write 8 bits, then read 8 bits.
@@ -367,8 +369,6 @@
 	return ret < 0 ? ret : din[1];
 }
 
-#if CONFIG_IS_ENABLED(DM_SPI)
-
 /**
  * struct spi_cs_info - Information about a bus chip select
  *
@@ -717,6 +717,5 @@
 /* Access the operations for a SPI device */
 #define spi_get_ops(dev)	((struct dm_spi_ops *)(dev)->driver->ops)
 #define spi_emul_get_ops(dev)	((struct dm_spi_emul_ops *)(dev)->driver->ops)
-#endif /* CONFIG_DM_SPI */
 
 #endif	/* _SPI_H_ */
diff --git a/include/usb/xhci.h b/include/usb/xhci.h
index 20e4a21..7d34103 100644
--- a/include/usb/xhci.h
+++ b/include/usb/xhci.h
@@ -16,6 +16,7 @@
 #ifndef HOST_XHCI_H_
 #define HOST_XHCI_H_
 
+#include <reset.h>
 #include <asm/types.h>
 #include <asm/cache.h>
 #include <asm/io.h>
@@ -1114,28 +1115,20 @@
  */
 static inline u64 xhci_readq(__le64 volatile *regs)
 {
-#if BITS_PER_LONG == 64
-	return readq(regs);
-#else
 	__u32 *ptr = (__u32 *)regs;
 	u64 val_lo = readl(ptr);
 	u64 val_hi = readl(ptr + 1);
 	return val_lo + (val_hi << 32);
-#endif
 }
 
 static inline void xhci_writeq(__le64 volatile *regs, const u64 val)
 {
-#if BITS_PER_LONG == 64
-	writeq(val, regs);
-#else
 	__u32 *ptr = (__u32 *)regs;
 	u32 val_lo = lower_32_bits(val);
 	/* FIXME */
 	u32 val_hi = upper_32_bits(val);
 	writel(val_lo, ptr);
 	writel(val_hi, ptr + 1);
-#endif
 }
 
 int xhci_hcd_init(int index, struct xhci_hccr **ret_hccr,
@@ -1217,6 +1210,7 @@
 #if CONFIG_IS_ENABLED(DM_USB)
 	struct udevice *dev;
 #endif
+	struct reset_ctl reset;
 	struct xhci_hccr *hccr;	/* R/O registers, not need for volatile */
 	struct xhci_hcor *hcor;
 	struct xhci_doorbell_array *dba;
diff --git a/include/video.h b/include/video.h
index e7c58e8..1a0ffd8 100644
--- a/include/video.h
+++ b/include/video.h
@@ -19,10 +19,25 @@
 
 struct udevice;
 
+/**
+ * struct video_uc_platdata - uclass platform data for a video device
+ *
+ * This holds information that the uclass needs to know about each device. It
+ * is accessed using dev_get_uclass_platdata(dev). See 'Theory of operation' at
+ * the top of video-uclass.c for details on how this information is set.
+ *
+ * @align: Frame-buffer alignment, indicating the memory boundary the frame
+ *	buffer should start on. If 0, 1MB is assumed
+ * @size: Frame-buffer size, in bytes
+ * @base: Base address of frame buffer, 0 if not yet known
+ * @copy_base: Base address of a hardware copy of the frame buffer. See
+ *	CONFIG_VIDEO_COPY.
+ */
 struct video_uc_platdata {
 	uint align;
 	uint size;
 	ulong base;
+	ulong copy_base;
 };
 
 enum video_polarity {
@@ -63,6 +78,8 @@
  * @font_size:	Font size in pixels (0 to use a default value)
  * @fb:		Frame buffer
  * @fb_size:	Frame buffer size
+ * @copy_fb:	Copy of the frame buffer to keep up to date; see struct
+ *		video_uc_platdata
  * @line_length:	Length of each frame buffer line, in bytes. This can be
  *		set by the driver, but if not, the uclass will set it after
  *		probing
@@ -89,6 +106,7 @@
 	 */
 	void *fb;
 	int fb_size;
+	void *copy_fb;
 	int line_length;
 	u32 colour_fg;
 	u32 colour_bg;
@@ -202,6 +220,29 @@
  */
 void video_set_default_colors(struct udevice *dev, bool invert);
 
+#ifdef CONFIG_VIDEO_COPY
+/**
+ * vidconsole_sync_copy() - Sync back to the copy framebuffer
+ *
+ * This ensures that the copy framebuffer has the same data as the framebuffer
+ * for a particular region. It should be called after the framebuffer is updated
+ *
+ * @from and @to can be in either order. The region between them is synced.
+ *
+ * @dev: Vidconsole device being updated
+ * @from: Start/end address within the framebuffer (->fb)
+ * @to: Other address within the frame buffer
+ * @return 0 if OK, -EFAULT if the start address is before the start of the
+ *	frame buffer start
+ */
+int video_sync_copy(struct udevice *dev, void *from, void *to);
+#else
+static inline int video_sync_copy(struct udevice *dev, void *from, void *to)
+{
+	return 0;
+}
+#endif
+
 #endif /* CONFIG_DM_VIDEO */
 
 #ifndef CONFIG_DM_VIDEO
diff --git a/include/video_console.h b/include/video_console.h
index 0936cea..06b798e 100644
--- a/include/video_console.h
+++ b/include/video_console.h
@@ -8,6 +8,8 @@
 
 #include <video.h>
 
+struct video_priv;
+
 #define VID_FRAC_DIV	256
 
 #define VID_TO_PIXEL(x)	((x) / VID_FRAC_DIV)
@@ -241,8 +243,6 @@
 void vidconsole_position_cursor(struct udevice *dev, unsigned col,
 				unsigned row);
 
-#ifdef CONFIG_DM_VIDEO
-
 /**
  * vid_console_color() - convert a color code to a pixel's internal
  * representation
@@ -256,6 +256,53 @@
  */
 u32 vid_console_color(struct video_priv *priv, unsigned int idx);
 
+#ifdef CONFIG_VIDEO_COPY
+/**
+ * vidconsole_sync_copy() - Sync back to the copy framebuffer
+ *
+ * This ensures that the copy framebuffer has the same data as the framebuffer
+ * for a particular region. It should be called after the framebuffer is updated
+ *
+ * @from and @to can be in either order. The region between them is synced.
+ *
+ * @dev: Vidconsole device being updated
+ * @from: Start/end address within the framebuffer (->fb)
+ * @to: Other address within the frame buffer
+ * @return 0 if OK, -EFAULT if the start address is before the start of the
+ *	frame buffer start
+ */
+int vidconsole_sync_copy(struct udevice *dev, void *from, void *to);
+
+/**
+ * vidconsole_memmove() - Perform a memmove() within the frame buffer
+ *
+ * This handles a memmove(), e.g. for scrolling. It also updates the copy
+ * framebuffer.
+ *
+ * @dev: Vidconsole device being updated
+ * @dst: Destination address within the framebuffer (->fb)
+ * @src: Source address within the framebuffer (->fb)
+ * @size: Number of bytes to transfer
+ * @return 0 if OK, -EFAULT if the start address is before the start of the
+ *	frame buffer start
+ */
+int vidconsole_memmove(struct udevice *dev, void *dst, const void *src,
+		       int size);
+#else
+static inline int vidconsole_sync_copy(struct udevice *dev, void *from,
+				       void *to)
+{
+	return 0;
+}
+
+static inline int vidconsole_memmove(struct udevice *dev, void *dst,
+				     const void *src, int size)
+{
+	memmove(dst, src, size);
+
+	return 0;
+}
+
 #endif
 
 #endif
diff --git a/lib/Kconfig b/lib/Kconfig
index fc7d684..2142bd0 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -1,5 +1,18 @@
 menu "Library routines"
 
+config ADDR_MAP
+	bool "Enable support for non-identity virtual-physical mappings"
+	help
+	  Enables helper code for implementing non-identity virtual-physical
+	  memory mappings for 32bit CPUs.
+
+config SYS_NUM_ADDR_MAP
+	int "Size of the address-map table"
+	depends on ADDR_MAP
+	default 16
+	help
+	  Sets the number of entries in the virtual-physical mapping table.
+
 config BCH
 	bool "Enable Software based BCH ECC"
 	help
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 9544e57..238f12c 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -2343,7 +2343,7 @@
 	}
 
 	# use if instead of #if
-	if ($line =~ /^\+#if.*CONFIG.*/) {
+	if ($realfile =~ /\.c$/ && $line =~ /^\+#if.*CONFIG.*/) {
 		WARN("PREFER_IF",
 		     "Use 'if (IS_ENABLED(CONFIG...))' instead of '#if or #ifdef' where possible\n" . $herecurr);
 	}
diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt
index 699d6ce..ca40b9b 100644
--- a/scripts/config_whitelist.txt
+++ b/scripts/config_whitelist.txt
@@ -15,7 +15,6 @@
 CONFIG_ACX544AKN
 CONFIG_ADDRESS
 CONFIG_ADDR_AUTO_INCR_BIT
-CONFIG_ADDR_MAP
 CONFIG_ADNPESC1
 CONFIG_AEABI
 CONFIG_AEMIF_CNTRL_BASE
@@ -872,9 +871,7 @@
 CONFIG_IRAM_STACK
 CONFIG_IRAM_TOP
 CONFIG_IRDA_BASE
-CONFIG_IS_BUILTIN
 CONFIG_IS_ENABLED
-CONFIG_IS_MODULE
 CONFIG_JFFS2_CMDLINE
 CONFIG_JFFS2_DEV
 CONFIG_JFFS2_LZO
@@ -3266,7 +3263,6 @@
 CONFIG_SYS_NS16550_PORT_MAPPED
 CONFIG_SYS_NS16550_REG_SIZE
 CONFIG_SYS_NS16550_SERIAL
-CONFIG_SYS_NUM_ADDR_MAP
 CONFIG_SYS_NUM_CPC
 CONFIG_SYS_NUM_FM1_10GEC
 CONFIG_SYS_NUM_FM1_DTSEC
diff --git a/test/dm/fdtdec.c b/test/dm/fdtdec.c
index b2f75b5..56f6f4f 100644
--- a/test/dm/fdtdec.c
+++ b/test/dm/fdtdec.c
@@ -9,6 +9,8 @@
 #include <dm/test.h>
 #include <test/ut.h>
 
+DECLARE_GLOBAL_DATA_PTR;
+
 static int dm_test_fdtdec_set_carveout(struct unit_test_state *uts)
 {
 	struct fdt_memory resv;
@@ -20,7 +22,7 @@
 	blob = malloc(blob_sz);
 	ut_assertnonnull(blob);
 
-	/* Make a writtable copy of the fdt blob */
+	/* Make a writable copy of the fdt blob */
 	ut_assertok(fdt_open_into(gd->fdt_blob, blob, blob_sz));
 
 	resv.start = 0x1000;
@@ -57,3 +59,72 @@
 }
 DM_TEST(dm_test_fdtdec_set_carveout,
 	DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT | DM_TESTF_FLAT_TREE);
+
+static int dm_test_fdtdec_add_reserved_memory(struct unit_test_state *uts)
+{
+	struct fdt_memory resv;
+	fdt_addr_t addr;
+	fdt_size_t size;
+	void *blob;
+	int blob_sz, parent, subnode;
+	uint32_t phandle, phandle1;
+
+	blob_sz = fdt_totalsize(gd->fdt_blob) + 128;
+	blob = malloc(blob_sz);
+	ut_assertnonnull(blob);
+
+	/* Make a writable copy of the fdt blob */
+	ut_assertok(fdt_open_into(gd->fdt_blob, blob, blob_sz));
+
+	/* Insert a memory region in /reserved-memory node */
+	resv.start = 0x1000;
+	resv.end = 0x1fff;
+	ut_assertok(fdtdec_add_reserved_memory(blob, "rsvd_region",
+					       &resv, &phandle));
+
+	/* Test /reserve-memory and its subnode should exist */
+	parent = fdt_path_offset(blob, "/reserved-memory");
+	ut_assert(parent > 0);
+	subnode = fdt_path_offset(blob, "/reserved-memory/rsvd_region");
+	ut_assert(subnode > 0);
+
+	/* Test reg property of /reserved-memory/rsvd_region node */
+	addr = fdtdec_get_addr_size_auto_parent(blob, parent, subnode,
+						"reg", 0, &size, false);
+	ut_assert(addr == resv.start);
+	ut_assert(size == resv.end -  resv.start + 1);
+
+	/* Insert another memory region in /reserved-memory node */
+	subnode = fdt_path_offset(blob, "/reserved-memory/rsvd_region1");
+	ut_assert(subnode < 0);
+
+	resv.start = 0x2000;
+	resv.end = 0x2fff;
+	ut_assertok(fdtdec_add_reserved_memory(blob, "rsvd_region1",
+					       &resv, &phandle1));
+	subnode = fdt_path_offset(blob, "/reserved-memory/rsvd_region1");
+	ut_assert(subnode > 0);
+
+	/* phandles must be different */
+	ut_assert(phandle != phandle1);
+
+	/*
+	 * Insert a 3rd memory region with the same addr/size as the 1st one,
+	 * but a new node should not be inserted due to the same addr/size.
+	 */
+	resv.start = 0x1000;
+	resv.end = 0x1fff;
+	ut_assertok(fdtdec_add_reserved_memory(blob, "rsvd_region2",
+					       &resv, &phandle1));
+	subnode = fdt_path_offset(blob, "/reserved-memory/rsvd_region2");
+	ut_assert(subnode < 0);
+
+	/* phandle must be same as the 1st one */
+	ut_assert(phandle == phandle1);
+
+	free(blob);
+
+	return 0;
+}
+DM_TEST(dm_test_fdtdec_add_reserved_memory,
+	DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT | DM_TESTF_FLAT_TREE);
diff --git a/test/dm/gpio.c b/test/dm/gpio.c
index fcee1fe..e3be57b 100644
--- a/test/dm/gpio.c
+++ b/test/dm/gpio.c
@@ -244,7 +244,7 @@
 
 	/* And the anonymous bank */
 	ut_assertok(gpio_lookup_name("14", &dev, &offset, &gpio));
-	ut_asserteq_str(dev->name, "gpio_sandbox");
+	ut_asserteq_str(dev->name, "sandbox_gpio");
 	ut_asserteq(14, offset);
 	ut_asserteq(14, gpio);
 
diff --git a/test/dm/spi.c b/test/dm/spi.c
index 474008c..ff2cddd 100644
--- a/test/dm/spi.c
+++ b/test/dm/spi.c
@@ -58,7 +58,7 @@
 	 */
 	ut_asserteq(-ENODEV, spi_find_bus_and_cs(busnum, cs, &bus, &dev));
 	ut_asserteq(-ENOENT, spi_get_bus_and_cs(busnum, cs, speed, mode,
-						"spi_flash_std", "name", &bus,
+						"jedec_spi_nor", "name", &bus,
 						&slave));
 	sandbox_sf_unbind_emul(state_get_current(), busnum, cs);
 	ut_assertok(spi_cs_info(bus, cs, &info));
@@ -69,7 +69,7 @@
 					 "name"));
 	ut_assertok(spi_find_bus_and_cs(busnum, cs, &bus, &dev));
 	ut_assertok(spi_get_bus_and_cs(busnum, cs, speed, mode,
-				       "spi_flash_std", "name", &bus, &slave));
+				       "jedec_spi_nor", "name", &bus, &slave));
 
 	ut_assertok(spi_cs_info(bus, cs, &info));
 	ut_asserteq_ptr(info.dev, slave->dev);
@@ -78,7 +78,7 @@
 	ut_assertok(sandbox_sf_bind_emul(state, busnum, cs_b, bus, node,
 					 "name"));
 	ut_asserteq(-EINVAL, spi_get_bus_and_cs(busnum, cs_b, speed, mode,
-				       "spi_flash_std", "name", &bus, &slave));
+				       "jedec_spi_nor", "name", &bus, &slave));
 	ut_asserteq(-EINVAL, spi_cs_info(bus, cs_b, &info));
 	ut_asserteq_ptr(NULL, info.dev);
 
diff --git a/test/dm/video.c b/test/dm/video.c
index 0664e3f..19f78b6 100644
--- a/test/dm/video.c
+++ b/test/dm/video.c
@@ -51,12 +51,18 @@
  * size of the compressed data. This provides a pretty good level of
  * certainty and the resulting tests need only check a single value.
  *
+ * If the copy framebuffer is enabled, this compares it to the main framebuffer
+ * too.
+ *
+ * @uts:	Test state
  * @dev:	Video device
  * @return compressed size of the frame buffer, or -ve on error
  */
-static int compress_frame_buffer(struct udevice *dev)
+static int compress_frame_buffer(struct unit_test_state *uts,
+				 struct udevice *dev)
 {
 	struct video_priv *priv = dev_get_uclass_priv(dev);
+	struct video_priv *uc_priv = dev_get_uclass_priv(dev);
 	uint destlen;
 	void *dest;
 	int ret;
@@ -72,6 +78,13 @@
 	if (ret)
 		return ret;
 
+	/* Check here that the copy frame buffer is working correctly */
+	if (IS_ENABLED(CONFIG_VIDEO_COPY)) {
+		ut_assertf(!memcmp(uc_priv->fb, uc_priv->copy_fb,
+				   uc_priv->fb_size),
+				   "Copy framebuffer does not match fb");
+	}
+
 	return destlen;
 }
 
@@ -110,25 +123,25 @@
 
 	ut_assertok(select_vidconsole(uts, "vidconsole0"));
 	ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
-	ut_asserteq(46, compress_frame_buffer(dev));
+	ut_asserteq(46, compress_frame_buffer(uts, dev));
 
 	ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
 	vidconsole_putc_xy(con, 0, 0, 'a');
-	ut_asserteq(79, compress_frame_buffer(dev));
+	ut_asserteq(79, compress_frame_buffer(uts, dev));
 
 	vidconsole_putc_xy(con, 0, 0, ' ');
-	ut_asserteq(46, compress_frame_buffer(dev));
+	ut_asserteq(46, compress_frame_buffer(uts, dev));
 
 	for (i = 0; i < 20; i++)
 		vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i);
-	ut_asserteq(273, compress_frame_buffer(dev));
+	ut_asserteq(273, compress_frame_buffer(uts, dev));
 
 	vidconsole_set_row(con, 0, WHITE);
-	ut_asserteq(46, compress_frame_buffer(dev));
+	ut_asserteq(46, compress_frame_buffer(uts, dev));
 
 	for (i = 0; i < 20; i++)
 		vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i);
-	ut_asserteq(273, compress_frame_buffer(dev));
+	ut_asserteq(273, compress_frame_buffer(uts, dev));
 
 	return 0;
 }
@@ -144,7 +157,7 @@
 	ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
 	ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
 	vidconsole_put_string(con, test_string);
-	ut_asserteq(466, compress_frame_buffer(dev));
+	ut_asserteq(466, compress_frame_buffer(uts, dev));
 
 	return 0;
 }
@@ -164,20 +177,20 @@
 	/* reference clear: */
 	video_clear(con->parent);
 	video_sync(con->parent, false);
-	ut_asserteq(46, compress_frame_buffer(dev));
+	ut_asserteq(46, compress_frame_buffer(uts, dev));
 
 	/* test clear escape sequence: [2J */
 	vidconsole_put_string(con, "A\tB\tC"ANSI_ESC"[2J");
-	ut_asserteq(46, compress_frame_buffer(dev));
+	ut_asserteq(46, compress_frame_buffer(uts, dev));
 
 	/* test set-cursor: [%d;%df */
 	vidconsole_put_string(con, "abc"ANSI_ESC"[2;2fab"ANSI_ESC"[4;4fcd");
-	ut_asserteq(143, compress_frame_buffer(dev));
+	ut_asserteq(143, compress_frame_buffer(uts, dev));
 
 	/* test colors (30-37 fg color, 40-47 bg color) */
 	vidconsole_put_string(con, ANSI_ESC"[30;41mfoo"); /* black on red */
 	vidconsole_put_string(con, ANSI_ESC"[33;44mbar"); /* yellow on blue */
-	ut_asserteq(272, compress_frame_buffer(dev));
+	ut_asserteq(272, compress_frame_buffer(uts, dev));
 
 	return 0;
 }
@@ -188,7 +201,8 @@
  * check_vidconsole_output() - Run a text console test
  *
  * @uts:	Test state
- * @rot:	Console rotation (0, 90, 180, 270)
+ * @rot:	Console rotation (0=normal orientation, 1=90 degrees clockwise,
+ *		2=upside down, 3=90 degree counterclockwise)
  * @wrap_size:	Expected size of compressed frame buffer for the wrap test
  * @scroll_size: Same for the scroll test
  * @return 0 on success
@@ -207,24 +221,24 @@
 
 	ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
 	ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
-	ut_asserteq(46, compress_frame_buffer(dev));
+	ut_asserteq(46, compress_frame_buffer(uts, dev));
 
 	/* Check display wrap */
 	for (i = 0; i < 120; i++)
 		vidconsole_put_char(con, 'A' + i % 50);
-	ut_asserteq(wrap_size, compress_frame_buffer(dev));
+	ut_asserteq(wrap_size, compress_frame_buffer(uts, dev));
 
 	/* Check display scrolling */
 	for (i = 0; i < SCROLL_LINES; i++) {
 		vidconsole_put_char(con, 'A' + i % 50);
 		vidconsole_put_char(con, '\n');
 	}
-	ut_asserteq(scroll_size, compress_frame_buffer(dev));
+	ut_asserteq(scroll_size, compress_frame_buffer(uts, dev));
 
 	/* If we scroll enough, the screen becomes blank again */
 	for (i = 0; i < SCROLL_LINES; i++)
 		vidconsole_put_char(con, '\n');
-	ut_asserteq(46, compress_frame_buffer(dev));
+	ut_asserteq(46, compress_frame_buffer(uts, dev));
 
 	return 0;
 }
@@ -251,7 +265,7 @@
 /* Test rotated text output through the console uclass */
 static int dm_test_video_rotation2(struct unit_test_state *uts)
 {
-	ut_assertok(check_vidconsole_output(uts, 2, 785, 446));
+	ut_assertok(check_vidconsole_output(uts, 2, 783, 445));
 
 	return 0;
 }
@@ -298,7 +312,7 @@
 	ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr));
 
 	ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
-	ut_asserteq(1368, compress_frame_buffer(dev));
+	ut_asserteq(1368, compress_frame_buffer(uts, dev));
 
 	return 0;
 }
@@ -314,7 +328,7 @@
 	ut_assertok(read_file(uts, "tools/logos/denx-comp.bmp", &addr));
 
 	ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
-	ut_asserteq(1368, compress_frame_buffer(dev));
+	ut_asserteq(1368, compress_frame_buffer(uts, dev));
 
 	return 0;
 }
@@ -329,7 +343,7 @@
 	ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
 	ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
 	vidconsole_put_string(con, test_string);
-	ut_asserteq(12237, compress_frame_buffer(dev));
+	ut_asserteq(12237, compress_frame_buffer(uts, dev));
 
 	return 0;
 }
@@ -350,7 +364,7 @@
 	ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
 	ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
 	vidconsole_put_string(con, test_string);
-	ut_asserteq(35030, compress_frame_buffer(dev));
+	ut_asserteq(35030, compress_frame_buffer(uts, dev));
 
 	return 0;
 }
@@ -371,7 +385,7 @@
 	ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
 	ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
 	vidconsole_put_string(con, test_string);
-	ut_asserteq(29018, compress_frame_buffer(dev));
+	ut_asserteq(29018, compress_frame_buffer(uts, dev));
 
 	return 0;
 }
diff --git a/test/log/syslog_test.c b/test/log/syslog_test.c
index 26536eb..120a8b2 100644
--- a/test/log/syslog_test.c
+++ b/test/log/syslog_test.c
@@ -21,6 +21,8 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+#define LOGF_TEST (BIT(LOGF_FUNC) | BIT(LOGF_MSG))
+
 /**
  * struct sb_log_env - private data for sandbox ethernet driver
  *
@@ -102,7 +104,7 @@
 	int old_log_level = gd->default_log_level;
 	struct sb_log_env env;
 
-	gd->log_fmt = LOGF_DEFAULT;
+	gd->log_fmt = LOGF_TEST;
 	gd->default_log_level = LOGL_INFO;
 	env_set("ethact", "eth@10002000");
 	env_set("log_hostname", "sandbox");
@@ -116,6 +118,7 @@
 	/* Check that the callback function was called */
 	sandbox_eth_set_tx_handler(0, NULL);
 	gd->default_log_level = old_log_level;
+	gd->log_fmt = log_get_default_format();
 
 	return 0;
 }
@@ -132,7 +135,7 @@
 	int old_log_level = gd->default_log_level;
 	struct sb_log_env env;
 
-	gd->log_fmt = LOGF_DEFAULT;
+	gd->log_fmt = LOGF_TEST;
 	gd->default_log_level = LOGL_INFO;
 	env_set("ethact", "eth@10002000");
 	env_set("log_hostname", "sandbox");
@@ -147,6 +150,7 @@
 	/* Check that the callback function was called */
 	ut_assertnull(env.expected);
 	gd->default_log_level = old_log_level;
+	gd->log_fmt = log_get_default_format();
 
 	return 0;
 }
@@ -163,7 +167,7 @@
 	int old_log_level = gd->default_log_level;
 	struct sb_log_env env;
 
-	gd->log_fmt = LOGF_DEFAULT;
+	gd->log_fmt = LOGF_TEST;
 	gd->default_log_level = LOGL_INFO;
 	env_set("ethact", "eth@10002000");
 	env_set("log_hostname", "sandbox");
@@ -178,6 +182,7 @@
 	/* Check that the callback function was called */
 	ut_assertnull(env.expected);
 	gd->default_log_level = old_log_level;
+	gd->log_fmt = log_get_default_format();
 
 	return 0;
 }
@@ -194,7 +199,7 @@
 	int old_log_level = gd->default_log_level;
 	struct sb_log_env env;
 
-	gd->log_fmt = LOGF_DEFAULT;
+	gd->log_fmt = LOGF_TEST;
 	gd->default_log_level = LOGL_INFO;
 	env_set("ethact", "eth@10002000");
 	env_set("log_hostname", "sandbox");
@@ -209,6 +214,7 @@
 	/* Check that the callback function was called */
 	ut_assertnull(env.expected);
 	gd->default_log_level = old_log_level;
+	gd->log_fmt = log_get_default_format();
 
 	return 0;
 }
@@ -225,7 +231,7 @@
 	int old_log_level = gd->default_log_level;
 	struct sb_log_env env;
 
-	gd->log_fmt = LOGF_DEFAULT;
+	gd->log_fmt = LOGF_TEST;
 	gd->default_log_level = LOGL_DEBUG;
 	env_set("ethact", "eth@10002000");
 	env_set("log_hostname", "sandbox");
@@ -240,6 +246,7 @@
 	/* Check that the callback function was called */
 	ut_assertnull(env.expected);
 	gd->default_log_level = old_log_level;
+	gd->log_fmt = log_get_default_format();
 
 	return 0;
 }
@@ -259,7 +266,7 @@
 	int old_log_level = gd->default_log_level;
 	struct sb_log_env env;
 
-	gd->log_fmt = LOGF_DEFAULT;
+	gd->log_fmt = LOGF_TEST;
 	gd->default_log_level = LOGL_INFO;
 	env_set("ethact", "eth@10002000");
 	env_set("log_hostname", "sandbox");
@@ -274,6 +281,7 @@
 	/* Check that the callback function was not called */
 	ut_assertnonnull(env.expected);
 	gd->default_log_level = old_log_level;
+	gd->log_fmt = log_get_default_format();
 
 	return 0;
 }
diff --git a/test/py/tests/test_bind.py b/test/py/tests/test_bind.py
index 20c6050..e9681c6 100644
--- a/test/py/tests/test_bind.py
+++ b/test/py/tests/test_bind.py
@@ -26,45 +26,45 @@
 def test_bind_unbind_with_node(u_boot_console):
 
 	#bind /bind-test. Device should come up as well as its children
-	response = u_boot_console.run_command('bind  /bind-test generic_simple_bus')
+	response = u_boot_console.run_command('bind  /bind-test simple_bus')
 	assert response == ''
 	tree = u_boot_console.run_command('dm tree')
-	assert in_tree(tree, 'bind-test', 'simple_bus', 'generic_simple_bus', 0, True)
+	assert in_tree(tree, 'bind-test', 'simple_bus', 'simple_bus', 0, True)
 	assert in_tree(tree, 'bind-test-child1', 'phy', 'phy_sandbox', 1, False)
-	assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'generic_simple_bus', 1, True)
+	assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'simple_bus', 1, True)
 
 	#Unbind child #1. No error expected and all devices should be there except for bind-test-child1
 	response = u_boot_console.run_command('unbind  /bind-test/bind-test-child1')
 	assert response == ''
 	tree = u_boot_console.run_command('dm tree')
-	assert in_tree(tree, 'bind-test', 'simple_bus', 'generic_simple_bus', 0, True)
+	assert in_tree(tree, 'bind-test', 'simple_bus', 'simple_bus', 0, True)
 	assert 'bind-test-child1' not in tree
-	assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'generic_simple_bus', 1, True)
+	assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'simple_bus', 1, True)
 
 	#bind child #1. No error expected and all devices should be there
 	response = u_boot_console.run_command('bind  /bind-test/bind-test-child1 phy_sandbox')
 	assert response == ''
 	tree = u_boot_console.run_command('dm tree')
-	assert in_tree(tree, 'bind-test', 'simple_bus', 'generic_simple_bus', 0, True)
+	assert in_tree(tree, 'bind-test', 'simple_bus', 'simple_bus', 0, True)
 	assert in_tree(tree, 'bind-test-child1', 'phy', 'phy_sandbox', 1, True)
-	assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'generic_simple_bus', 1, False)
+	assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'simple_bus', 1, False)
 
 	#Unbind child #2. No error expected and all devices should be there except for bind-test-child2
 	response = u_boot_console.run_command('unbind  /bind-test/bind-test-child2')
 	assert response == ''
 	tree = u_boot_console.run_command('dm tree')
-	assert in_tree(tree, 'bind-test', 'simple_bus', 'generic_simple_bus', 0, True)
+	assert in_tree(tree, 'bind-test', 'simple_bus', 'simple_bus', 0, True)
 	assert in_tree(tree, 'bind-test-child1', 'phy', 'phy_sandbox', 1, True)
 	assert 'bind-test-child2' not in tree
 
 
 	#Bind child #2. No error expected and all devices should be there
-	response = u_boot_console.run_command('bind /bind-test/bind-test-child2 generic_simple_bus')
+	response = u_boot_console.run_command('bind /bind-test/bind-test-child2 simple_bus')
 	assert response == ''
 	tree = u_boot_console.run_command('dm tree')
-	assert in_tree(tree, 'bind-test', 'simple_bus', 'generic_simple_bus', 0, True)
+	assert in_tree(tree, 'bind-test', 'simple_bus', 'simple_bus', 0, True)
 	assert in_tree(tree, 'bind-test-child1', 'phy', 'phy_sandbox', 1, False)
-	assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'generic_simple_bus', 1, True)
+	assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'simple_bus', 1, True)
 
 	#Unbind parent. No error expected. All devices should be removed and unbound
 	response = u_boot_console.run_command('unbind  /bind-test')
@@ -75,7 +75,7 @@
 	assert 'bind-test-child2' not in tree
 
 	#try binding invalid node with valid driver
-	response = u_boot_console.run_command('bind  /not-a-valid-node generic_simple_bus')
+	response = u_boot_console.run_command('bind  /not-a-valid-node simple_bus')
 	assert response != ''
 	tree = u_boot_console.run_command('dm tree')
 	assert 'not-a-valid-node' not in tree
@@ -87,12 +87,12 @@
 	assert 'bind-test' not in tree
 
 	#bind /bind-test. Device should come up as well as its children
-	response = u_boot_console.run_command('bind  /bind-test generic_simple_bus')
+	response = u_boot_console.run_command('bind  /bind-test simple_bus')
 	assert response == ''
 	tree = u_boot_console.run_command('dm tree')
-	assert in_tree(tree, 'bind-test', 'simple_bus', 'generic_simple_bus', 0, True)
+	assert in_tree(tree, 'bind-test', 'simple_bus', 'simple_bus', 0, True)
 	assert in_tree(tree, 'bind-test-child1', 'phy', 'phy_sandbox', 1, False)
-	assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'generic_simple_bus', 1, True)
+	assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'simple_bus', 1, True)
 
 	response = u_boot_console.run_command('unbind  /bind-test')
 	assert response == ''
@@ -112,7 +112,7 @@
 @pytest.mark.buildconfigspec('cmd_bind')
 def test_bind_unbind_with_uclass(u_boot_console):
 	#bind /bind-test
-	response = u_boot_console.run_command('bind  /bind-test generic_simple_bus')
+	response = u_boot_console.run_command('bind  /bind-test simple_bus')
 	assert response == ''
 
 	#make sure bind-test-child2 is there and get its uclass/index pair
@@ -123,8 +123,8 @@
 	child2_uclass = child2_line[0].split()[0]
 	child2_index = int(child2_line[0].split()[1])
 
-	#bind generic_simple_bus as a child of bind-test-child2
-	response = u_boot_console.run_command('bind  {} {} generic_simple_bus'.format(child2_uclass, child2_index, 'generic_simple_bus'))
+	#bind simple_bus as a child of bind-test-child2
+	response = u_boot_console.run_command('bind  {} {} simple_bus'.format(child2_uclass, child2_index, 'simple_bus'))
 
 	#check that the child is there and its uclass/index pair is right
 	tree = u_boot_console.run_command('dm tree')
@@ -132,20 +132,20 @@
 	child_of_child2_line = get_next_line(tree, 'bind-test-child2')
 	assert child_of_child2_line
 	child_of_child2_index = int(child_of_child2_line.split()[1])
-	assert in_tree(tree, 'generic_simple_bus', 'simple_bus', 'generic_simple_bus', 2, True)
+	assert in_tree(tree, 'simple_bus', 'simple_bus', 'simple_bus', 2, True)
 	assert child_of_child2_index == child2_index + 1
 
 	#unbind the child and check it has been removed
 	response = u_boot_console.run_command('unbind  simple_bus {}'.format(child_of_child2_index))
 	assert response == ''
 	tree = u_boot_console.run_command('dm tree')
-	assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'generic_simple_bus', 1, True)
-	assert not in_tree(tree, 'generic_simple_bus', 'simple_bus', 'generic_simple_bus', 2, True)
+	assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'simple_bus', 1, True)
+	assert not in_tree(tree, 'simple_bus', 'simple_bus', 'simple_bus', 2, True)
 	child_of_child2_line = get_next_line(tree, 'bind-test-child2')
 	assert child_of_child2_line == ''
 
-	#bind generic_simple_bus as a child of bind-test-child2
-	response = u_boot_console.run_command('bind  {} {} generic_simple_bus'.format(child2_uclass, child2_index, 'generic_simple_bus'))
+	#bind simple_bus as a child of bind-test-child2
+	response = u_boot_console.run_command('bind  {} {} simple_bus'.format(child2_uclass, child2_index, 'simple_bus'))
 
 	#check that the child is there and its uclass/index pair is right
 	tree = u_boot_console.run_command('dm tree')
@@ -154,22 +154,22 @@
 	child_of_child2_line = get_next_line(tree, 'bind-test-child2')
 	assert child_of_child2_line
 	child_of_child2_index = int(child_of_child2_line.split()[1])
-	assert in_tree(tree, 'generic_simple_bus', 'simple_bus', 'generic_simple_bus', 2, True)
+	assert in_tree(tree, 'simple_bus', 'simple_bus', 'simple_bus', 2, True)
 	assert child_of_child2_index == child2_index + 1
 
 	#unbind the child and check it has been removed
-	response = u_boot_console.run_command('unbind  {} {} generic_simple_bus'.format(child2_uclass, child2_index, 'generic_simple_bus'))
+	response = u_boot_console.run_command('unbind  {} {} simple_bus'.format(child2_uclass, child2_index, 'simple_bus'))
 	assert response == ''
 
 	tree = u_boot_console.run_command('dm tree')
-	assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'generic_simple_bus', 1, True)
+	assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'simple_bus', 1, True)
 
 	child_of_child2_line = get_next_line(tree, 'bind-test-child2')
 	assert child_of_child2_line == ''
 
 	#unbind the child again and check it doesn't change the tree
 	tree_old = u_boot_console.run_command('dm tree')
-	response = u_boot_console.run_command('unbind  {} {} generic_simple_bus'.format(child2_uclass, child2_index, 'generic_simple_bus'))
+	response = u_boot_console.run_command('unbind  {} {} simple_bus'.format(child2_uclass, child2_index, 'simple_bus'))
 	tree_new = u_boot_console.run_command('dm tree')
 
 	assert response == ''
diff --git a/test/py/tests/test_log.py b/test/py/tests/test_log.py
index 75325fa..ddc28f1 100644
--- a/test/py/tests/test_log.py
+++ b/test/py/tests/test_log.py
@@ -39,6 +39,8 @@
         Returns:
             iterator containing the lines output from the command
         """
+        output = u_boot_console.run_command('log format fm')
+        assert output == ''
         with cons.log.section('basic'):
            output = u_boot_console.run_command('log test %d' % testnum)
         split = output.replace('\r', '').splitlines()
diff --git a/tools/dtoc/dtb_platdata.py b/tools/dtoc/dtb_platdata.py
index ecfe062..c148c49 100644
--- a/tools/dtoc/dtb_platdata.py
+++ b/tools/dtoc/dtb_platdata.py
@@ -13,6 +13,8 @@
 
 import collections
 import copy
+import os
+import re
 import sys
 
 from dtoc import fdt
@@ -139,16 +141,61 @@
         _valid_nodes: A list of Node object with compatible strings
         _include_disabled: true to include nodes marked status = "disabled"
         _outfile: The current output file (sys.stdout or a real file)
+        _warning_disabled: true to disable warnings about driver names not found
         _lines: Stashed list of output lines for outputting in the future
+        _aliases: Dict that hold aliases for compatible strings
+            key: First compatible string declared in a node
+            value: List of additional compatible strings declared in a node
+        _drivers: List of valid driver names found in drivers/
+        _driver_aliases: Dict that holds aliases for driver names
+            key: Driver alias declared with
+                U_BOOT_DRIVER_ALIAS(driver_alias, driver_name)
+            value: Driver name declared with U_BOOT_DRIVER(driver_name)
+        _links: List of links to be included in dm_populate_phandle_data()
     """
-    def __init__(self, dtb_fname, include_disabled):
+    def __init__(self, dtb_fname, include_disabled, warning_disabled):
         self._fdt = None
         self._dtb_fname = dtb_fname
         self._valid_nodes = None
         self._include_disabled = include_disabled
         self._outfile = None
+        self._warning_disabled = warning_disabled
         self._lines = []
         self._aliases = {}
+        self._drivers = []
+        self._driver_aliases = {}
+        self._links = []
+
+    def get_normalized_compat_name(self, node):
+        """Get a node's normalized compat name
+
+        Returns a valid driver name by retrieving node's first compatible
+        string as a C identifier and performing a check against _drivers
+        and a lookup in driver_aliases printing a warning in case of failure.
+
+        Args:
+            node: Node object to check
+        Return:
+            Tuple:
+                Driver name associated with the first compatible string
+                List of C identifiers for all the other compatible strings
+                    (possibly empty)
+                In case of no match found, the return will be the same as
+                get_compat_name()
+        """
+        compat_c, aliases_c = get_compat_name(node)
+        if compat_c not in self._drivers:
+            compat_c_old = compat_c
+            compat_c = self._driver_aliases.get(compat_c)
+            if not compat_c:
+                if not self._warning_disabled:
+                    print('WARNING: the driver %s was not found in the driver list'
+                          % (compat_c_old))
+                compat_c = compat_c_old
+            else:
+                aliases_c = [compat_c_old] + aliases_c
+
+        return compat_c, aliases_c
 
     def setup_output(self, fname):
         """Set up the output destination
@@ -211,7 +258,7 @@
         Return:
             Number of argument cells is this is a phandle, else None
         """
-        if prop.name in ['clocks']:
+        if prop.name in ['clocks', 'cd-gpios']:
             if not isinstance(prop.value, list):
                 prop.value = [prop.value]
             val = prop.value
@@ -231,11 +278,14 @@
                 if not target:
                     raise ValueError("Cannot parse '%s' in node '%s'" %
                                      (prop.name, node_name))
-                prop_name = '#clock-cells'
-                cells = target.props.get(prop_name)
+                cells = None
+                for prop_name in ['#clock-cells', '#gpio-cells']:
+                    cells = target.props.get(prop_name)
+                    if cells:
+                        break
                 if not cells:
-                    raise ValueError("Node '%s' has no '%s' property" %
-                            (target.name, prop_name))
+                    raise ValueError("Node '%s' has no cells property" %
+                            (target.name))
                 num_args = fdt_util.fdt32_to_cpu(cells.value)
                 max_args = max(max_args, num_args)
                 args.append(num_args)
@@ -243,6 +293,54 @@
             return PhandleInfo(max_args, args)
         return None
 
+    def scan_driver(self, fn):
+        """Scan a driver file to build a list of driver names and aliases
+
+        This procedure will populate self._drivers and self._driver_aliases
+
+        Args
+            fn: Driver filename to scan
+        """
+        with open(fn, encoding='utf-8') as fd:
+            try:
+                buff = fd.read()
+            except UnicodeDecodeError:
+                # This seems to happen on older Python versions
+                print("Skipping file '%s' due to unicode error" % fn)
+                return
+
+            # The following re will search for driver names declared as
+            # U_BOOT_DRIVER(driver_name)
+            drivers = re.findall('U_BOOT_DRIVER\((.*)\)', buff)
+
+            for driver in drivers:
+                self._drivers.append(driver)
+
+            # The following re will search for driver aliases declared as
+            # U_BOOT_DRIVER_ALIAS(alias, driver_name)
+            driver_aliases = re.findall('U_BOOT_DRIVER_ALIAS\(\s*(\w+)\s*,\s*(\w+)\s*\)',
+                                        buff)
+
+            for alias in driver_aliases: # pragma: no cover
+                if len(alias) != 2:
+                    continue
+                self._driver_aliases[alias[1]] = alias[0]
+
+    def scan_drivers(self):
+        """Scan the driver folders to build a list of driver names and aliases
+
+        This procedure will populate self._drivers and self._driver_aliases
+
+        """
+        basedir = sys.argv[0].replace('tools/dtoc/dtoc', '')
+        if basedir == '':
+            basedir = './'
+        for (dirpath, dirnames, filenames) in os.walk(basedir):
+            for fn in filenames:
+                if not fn.endswith('.c'):
+                    continue
+                self.scan_driver(dirpath + '/' + fn)
+
     def scan_dtb(self):
         """Scan the device tree to obtain a tree of nodes and properties
 
@@ -353,7 +451,7 @@
         """
         structs = {}
         for node in self._valid_nodes:
-            node_name, _ = get_compat_name(node)
+            node_name, _ = self.get_normalized_compat_name(node)
             fields = {}
 
             # Get a list of all the valid properties in this node.
@@ -377,14 +475,14 @@
 
         upto = 0
         for node in self._valid_nodes:
-            node_name, _ = get_compat_name(node)
+            node_name, _ = self.get_normalized_compat_name(node)
             struct = structs[node_name]
             for name, prop in node.props.items():
                 if name not in PROP_IGNORE_LIST and name[0] != '#':
                     prop.Widen(struct[name])
             upto += 1
 
-            struct_name, aliases = get_compat_name(node)
+            struct_name, aliases = self.get_normalized_compat_name(node)
             for alias in aliases:
                 self._aliases[alias] = struct_name
 
@@ -461,9 +559,9 @@
         Args:
             node: node to output
         """
-        struct_name, _ = get_compat_name(node)
+        struct_name, _ = self.get_normalized_compat_name(node)
         var_name = conv_name_to_c(node.name)
-        self.buf('static const struct %s%s %s%s = {\n' %
+        self.buf('static struct %s%s %s%s = {\n' %
                  (STRUCT_PREFIX, struct_name, VAL_PREFIX, var_name))
         for pname in sorted(node.props):
             prop = node.props[pname]
@@ -482,6 +580,7 @@
                 if info:
                     # Process the list as pairs of (phandle, id)
                     pos = 0
+                    item = 0
                     for args in info.args:
                         phandle_cell = prop.value[pos]
                         phandle = fdt_util.fdt32_to_cpu(phandle_cell)
@@ -491,8 +590,16 @@
                         for i in range(args):
                             arg_values.append(str(fdt_util.fdt32_to_cpu(prop.value[pos + 1 + i])))
                         pos += 1 + args
-                        vals.append('\t{&%s%s, {%s}}' % (VAL_PREFIX, name,
-                                                     ', '.join(arg_values)))
+                        # node member is filled with NULL as the real value
+                        # will be update at run-time during dm_init_and_scan()
+                        # by dm_populate_phandle_data()
+                        vals.append('\t{NULL, {%s}}' % (', '.join(arg_values)))
+                        var_node = '%s%s.%s[%d].node' % \
+                                    (VAL_PREFIX, var_name, member_name, item)
+                        # Save the the link information to be use to define
+                        # dm_populate_phandle_data()
+                        self._links.append({'var_node': var_node, 'dev_name': name})
+                        item += 1
                     for val in vals:
                         self.buf('\n\t\t%s,' % val)
                 else:
@@ -548,8 +655,18 @@
             self.output_node(node)
             nodes_to_output.remove(node)
 
+        # Define dm_populate_phandle_data() which will add the linking between
+        # nodes using DM_GET_DEVICE
+        # dtv_dmc_at_xxx.clocks[0].node = DM_GET_DEVICE(clock_controller_at_xxx)
+        self.buf('void dm_populate_phandle_data(void) {\n')
+        for l in self._links:
+            self.buf('\t%s = DM_GET_DEVICE(%s);\n' %
+                     (l['var_node'], l['dev_name']))
+        self.buf('}\n')
+
+        self.out(''.join(self.get_buf()))
 
-def run_steps(args, dtb_file, include_disabled, output):
+def run_steps(args, dtb_file, include_disabled, output, warning_disabled=False):
     """Run all the steps of the dtoc tool
 
     Args:
@@ -561,7 +678,8 @@
     if not args:
         raise ValueError('Please specify a command: struct, platdata')
 
-    plat = DtbPlatdata(dtb_file, include_disabled)
+    plat = DtbPlatdata(dtb_file, include_disabled, warning_disabled)
+    plat.scan_drivers()
     plat.scan_dtb()
     plat.scan_tree()
     plat.scan_reg_sizes()
diff --git a/tools/dtoc/dtoc_test_driver_alias.dts b/tools/dtoc/dtoc_test_driver_alias.dts
new file mode 100644
index 0000000..da7973b
--- /dev/null
+++ b/tools/dtoc/dtoc_test_driver_alias.dts
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Test device tree file for dtoc
+ *
+ * Copyright 2020 Collabora Ltd.
+ */
+
+/dts-v1/;
+
+/ {
+	gpio_a: gpios@0 {
+		u-boot,dm-pre-reloc;
+		gpio-controller;
+		compatible = "sandbox_gpio_alias";
+		#gpio-cells = <1>;
+		gpio-bank-name = "a";
+		sandbox,gpio-count = <20>;
+	};
+
+};
diff --git a/tools/dtoc/dtoc_test_invalid_driver.dts b/tools/dtoc/dtoc_test_invalid_driver.dts
new file mode 100644
index 0000000..914ac3e
--- /dev/null
+++ b/tools/dtoc/dtoc_test_invalid_driver.dts
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Test device tree file for dtoc
+ *
+ * Copyright 2017 Google, Inc
+ */
+
+/dts-v1/;
+
+/ {
+	spl-test {
+		u-boot,dm-pre-reloc;
+		compatible = "invalid";
+	};
+};
diff --git a/tools/dtoc/dtoc_test_phandle_cd_gpios.dts b/tools/dtoc/dtoc_test_phandle_cd_gpios.dts
new file mode 100644
index 0000000..241743e
--- /dev/null
+++ b/tools/dtoc/dtoc_test_phandle_cd_gpios.dts
@@ -0,0 +1,42 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Test device tree file for dtoc
+ *
+ * Copyright 2020 Collabora Ltd.
+ */
+
+/dts-v1/;
+
+/ {
+	phandle: phandle-target {
+		u-boot,dm-pre-reloc;
+		compatible = "target";
+		intval = <0>;
+		#gpio-cells = <0>;
+	};
+
+	phandle_1: phandle2-target {
+		u-boot,dm-pre-reloc;
+		compatible = "target";
+		intval = <1>;
+		#gpio-cells = <1>;
+	};
+	phandle_2: phandle3-target {
+		u-boot,dm-pre-reloc;
+		compatible = "target";
+		intval = <2>;
+		#gpio-cells = <2>;
+	};
+
+	phandle-source {
+		u-boot,dm-pre-reloc;
+		compatible = "source";
+		cd-gpios = <&phandle &phandle_1 11 &phandle_2 12 13 &phandle>;
+	};
+
+	phandle-source2 {
+		u-boot,dm-pre-reloc;
+		compatible = "source";
+		cd-gpios = <&phandle>;
+	};
+};
diff --git a/tools/dtoc/test_dtoc.py b/tools/dtoc/test_dtoc.py
index 8498e83..3c8e343 100755
--- a/tools/dtoc/test_dtoc.py
+++ b/tools/dtoc/test_dtoc.py
@@ -12,6 +12,7 @@
 import collections
 import os
 import struct
+import sys
 import unittest
 
 from dtoc import dtb_platdata
@@ -47,6 +48,9 @@
 #include <dt-structs.h>
 '''
 
+C_EMPTY_POPULATE_PHANDLE_DATA = '''void dm_populate_phandle_data(void) {
+}
+'''
 
 
 def get_dtb_file(dts_fname, capture_stderr=False):
@@ -101,6 +105,10 @@
             print('Failures written to /tmp/binman.{expected,actual}')
         self.assertEquals(expected, actual)
 
+
+    def run_test(self, args, dtb_file, output):
+        dtb_platdata.run_steps(args, dtb_file, False, output, True)
+
     def test_name(self):
         """Test conversion of device tree names to C identifiers"""
         self.assertEqual('serial_at_0x12', conv_name_to_c('serial@0x12'))
@@ -154,21 +162,22 @@
         """Test output from a device tree file with no nodes"""
         dtb_file = get_dtb_file('dtoc_test_empty.dts')
         output = tools.GetOutputFilename('output')
-        dtb_platdata.run_steps(['struct'], dtb_file, False, output)
+        self.run_test(['struct'], dtb_file, output)
         with open(output) as infile:
             lines = infile.read().splitlines()
         self.assertEqual(HEADER.splitlines(), lines)
 
-        dtb_platdata.run_steps(['platdata'], dtb_file, False, output)
+        self.run_test(['platdata'], dtb_file, output)
         with open(output) as infile:
             lines = infile.read().splitlines()
-        self.assertEqual(C_HEADER.splitlines() + [''], lines)
+        self.assertEqual(C_HEADER.splitlines() + [''] +
+                         C_EMPTY_POPULATE_PHANDLE_DATA.splitlines(), lines)
 
     def test_simple(self):
         """Test output from some simple nodes with various types of data"""
         dtb_file = get_dtb_file('dtoc_test_simple.dts')
         output = tools.GetOutputFilename('output')
-        dtb_platdata.run_steps(['struct'], dtb_file, False, output)
+        self.run_test(['struct'], dtb_file, output)
         with open(output) as infile:
             data = infile.read()
         self._CheckStrings(HEADER + '''
@@ -193,11 +202,11 @@
 };
 ''', data)
 
-        dtb_platdata.run_steps(['platdata'], dtb_file, False, output)
+        self.run_test(['platdata'], dtb_file, output)
         with open(output) as infile:
             data = infile.read()
         self._CheckStrings(C_HEADER + '''
-static const struct dtd_sandbox_spl_test dtv_spl_test = {
+static struct dtd_sandbox_spl_test dtv_spl_test = {
 \t.boolval\t\t= true,
 \t.bytearray\t\t= {0x6, 0x0, 0x0},
 \t.byteval\t\t= 0x5,
@@ -215,7 +224,7 @@
 \t.platdata_size\t= sizeof(dtv_spl_test),
 };
 
-static const struct dtd_sandbox_spl_test dtv_spl_test2 = {
+static struct dtd_sandbox_spl_test dtv_spl_test2 = {
 \t.bytearray\t\t= {0x1, 0x23, 0x34},
 \t.byteval\t\t= 0x8,
 \t.intarray\t\t= {0x5, 0x0, 0x0, 0x0},
@@ -231,7 +240,7 @@
 \t.platdata_size\t= sizeof(dtv_spl_test2),
 };
 
-static const struct dtd_sandbox_spl_test dtv_spl_test3 = {
+static struct dtd_sandbox_spl_test dtv_spl_test3 = {
 \t.stringarray\t\t= {"one", "", ""},
 };
 U_BOOT_DEVICE(spl_test3) = {
@@ -240,7 +249,7 @@
 \t.platdata_size\t= sizeof(dtv_spl_test3),
 };
 
-static const struct dtd_sandbox_spl_test_2 dtv_spl_test4 = {
+static struct dtd_sandbox_spl_test_2 dtv_spl_test4 = {
 };
 U_BOOT_DEVICE(spl_test4) = {
 \t.name\t\t= "sandbox_spl_test_2",
@@ -248,7 +257,7 @@
 \t.platdata_size\t= sizeof(dtv_spl_test4),
 };
 
-static const struct dtd_sandbox_i2c_test dtv_i2c_at_0 = {
+static struct dtd_sandbox_i2c_test dtv_i2c_at_0 = {
 };
 U_BOOT_DEVICE(i2c_at_0) = {
 \t.name\t\t= "sandbox_i2c_test",
@@ -256,7 +265,7 @@
 \t.platdata_size\t= sizeof(dtv_i2c_at_0),
 };
 
-static const struct dtd_sandbox_pmic_test dtv_pmic_at_9 = {
+static struct dtd_sandbox_pmic_test dtv_pmic_at_9 = {
 \t.low_power\t\t= true,
 \t.reg\t\t\t= {0x9, 0x0},
 };
@@ -265,14 +274,79 @@
 \t.platdata\t= &dtv_pmic_at_9,
 \t.platdata_size\t= sizeof(dtv_pmic_at_9),
 };
+
+''' + C_EMPTY_POPULATE_PHANDLE_DATA, data)
+
+    def test_driver_alias(self):
+        """Test output from a device tree file with a driver alias"""
+        dtb_file = get_dtb_file('dtoc_test_driver_alias.dts')
+        output = tools.GetOutputFilename('output')
+        self.run_test(['struct'], dtb_file, output)
+        with open(output) as infile:
+            data = infile.read()
+        self._CheckStrings(HEADER + '''
+struct dtd_sandbox_gpio {
+\tconst char *\tgpio_bank_name;
+\tbool\t\tgpio_controller;
+\tfdt32_t\t\tsandbox_gpio_count;
+};
+#define dtd_sandbox_gpio_alias dtd_sandbox_gpio
+''', data)
+
+        self.run_test(['platdata'], dtb_file, output)
+        with open(output) as infile:
+            data = infile.read()
+        self._CheckStrings(C_HEADER + '''
+static struct dtd_sandbox_gpio dtv_gpios_at_0 = {
+\t.gpio_bank_name\t\t= "a",
+\t.gpio_controller\t= true,
+\t.sandbox_gpio_count\t= 0x14,
+};
+U_BOOT_DEVICE(gpios_at_0) = {
+\t.name\t\t= "sandbox_gpio",
+\t.platdata\t= &dtv_gpios_at_0,
+\t.platdata_size\t= sizeof(dtv_gpios_at_0),
+};
+
+void dm_populate_phandle_data(void) {
+}
+''', data)
+
+    def test_invalid_driver(self):
+        """Test output from a device tree file with an invalid driver"""
+        dtb_file = get_dtb_file('dtoc_test_invalid_driver.dts')
+        output = tools.GetOutputFilename('output')
+        with test_util.capture_sys_output() as (stdout, stderr):
+            dtb_platdata.run_steps(['struct'], dtb_file, False, output)
+        with open(output) as infile:
+            data = infile.read()
+        self._CheckStrings(HEADER + '''
+struct dtd_invalid {
+};
+''', data)
 
+        with test_util.capture_sys_output() as (stdout, stderr):
+            dtb_platdata.run_steps(['platdata'], dtb_file, False, output)
+        with open(output) as infile:
+            data = infile.read()
+        self._CheckStrings(C_HEADER + '''
+static struct dtd_invalid dtv_spl_test = {
+};
+U_BOOT_DEVICE(spl_test) = {
+\t.name\t\t= "invalid",
+\t.platdata\t= &dtv_spl_test,
+\t.platdata_size\t= sizeof(dtv_spl_test),
+};
+
+void dm_populate_phandle_data(void) {
+}
 ''', data)
 
     def test_phandle(self):
         """Test output from a node containing a phandle reference"""
         dtb_file = get_dtb_file('dtoc_test_phandle.dts')
         output = tools.GetOutputFilename('output')
-        dtb_platdata.run_steps(['struct'], dtb_file, False, output)
+        self.run_test(['struct'], dtb_file, output)
         with open(output) as infile:
             data = infile.read()
         self._CheckStrings(HEADER + '''
@@ -284,11 +358,11 @@
 };
 ''', data)
 
-        dtb_platdata.run_steps(['platdata'], dtb_file, False, output)
+        self.run_test(['platdata'], dtb_file, output)
         with open(output) as infile:
             data = infile.read()
         self._CheckStrings(C_HEADER + '''
-static const struct dtd_target dtv_phandle_target = {
+static struct dtd_target dtv_phandle_target = {
 \t.intval\t\t\t= 0x0,
 };
 U_BOOT_DEVICE(phandle_target) = {
@@ -297,7 +371,7 @@
 \t.platdata_size\t= sizeof(dtv_phandle_target),
 };
 
-static const struct dtd_target dtv_phandle2_target = {
+static struct dtd_target dtv_phandle2_target = {
 \t.intval\t\t\t= 0x1,
 };
 U_BOOT_DEVICE(phandle2_target) = {
@@ -306,7 +380,7 @@
 \t.platdata_size\t= sizeof(dtv_phandle2_target),
 };
 
-static const struct dtd_target dtv_phandle3_target = {
+static struct dtd_target dtv_phandle3_target = {
 \t.intval\t\t\t= 0x2,
 };
 U_BOOT_DEVICE(phandle3_target) = {
@@ -315,12 +389,12 @@
 \t.platdata_size\t= sizeof(dtv_phandle3_target),
 };
 
-static const struct dtd_source dtv_phandle_source = {
+static struct dtd_source dtv_phandle_source = {
 \t.clocks\t\t\t= {
-\t\t\t{&dtv_phandle_target, {}},
-\t\t\t{&dtv_phandle2_target, {11}},
-\t\t\t{&dtv_phandle3_target, {12, 13}},
-\t\t\t{&dtv_phandle_target, {}},},
+\t\t\t{NULL, {}},
+\t\t\t{NULL, {11}},
+\t\t\t{NULL, {12, 13}},
+\t\t\t{NULL, {}},},
 };
 U_BOOT_DEVICE(phandle_source) = {
 \t.name\t\t= "source",
@@ -328,9 +402,9 @@
 \t.platdata_size\t= sizeof(dtv_phandle_source),
 };
 
-static const struct dtd_source dtv_phandle_source2 = {
+static struct dtd_source dtv_phandle_source2 = {
 \t.clocks\t\t\t= {
-\t\t\t{&dtv_phandle_target, {}},},
+\t\t\t{NULL, {}},},
 };
 U_BOOT_DEVICE(phandle_source2) = {
 \t.name\t\t= "source",
@@ -338,13 +412,20 @@
 \t.platdata_size\t= sizeof(dtv_phandle_source2),
 };
 
+void dm_populate_phandle_data(void) {
+\tdtv_phandle_source.clocks[0].node = DM_GET_DEVICE(phandle_target);
+\tdtv_phandle_source.clocks[1].node = DM_GET_DEVICE(phandle2_target);
+\tdtv_phandle_source.clocks[2].node = DM_GET_DEVICE(phandle3_target);
+\tdtv_phandle_source.clocks[3].node = DM_GET_DEVICE(phandle_target);
+\tdtv_phandle_source2.clocks[0].node = DM_GET_DEVICE(phandle_target);
+}
 ''', data)
 
     def test_phandle_single(self):
         """Test output from a node containing a phandle reference"""
         dtb_file = get_dtb_file('dtoc_test_phandle_single.dts')
         output = tools.GetOutputFilename('output')
-        dtb_platdata.run_steps(['struct'], dtb_file, False, output)
+        self.run_test(['struct'], dtb_file, output)
         with open(output) as infile:
             data = infile.read()
         self._CheckStrings(HEADER + '''
@@ -360,11 +441,11 @@
         """Test that phandle targets are generated before their references"""
         dtb_file = get_dtb_file('dtoc_test_phandle_reorder.dts')
         output = tools.GetOutputFilename('output')
-        dtb_platdata.run_steps(['platdata'], dtb_file, False, output)
+        self.run_test(['platdata'], dtb_file, output)
         with open(output) as infile:
             data = infile.read()
         self._CheckStrings(C_HEADER + '''
-static const struct dtd_target dtv_phandle_target = {
+static struct dtd_target dtv_phandle_target = {
 };
 U_BOOT_DEVICE(phandle_target) = {
 \t.name\t\t= "target",
@@ -372,9 +453,72 @@
 \t.platdata_size\t= sizeof(dtv_phandle_target),
 };
 
-static const struct dtd_source dtv_phandle_source2 = {
+static struct dtd_source dtv_phandle_source2 = {
 \t.clocks\t\t\t= {
-\t\t\t{&dtv_phandle_target, {}},},
+\t\t\t{NULL, {}},},
+};
+U_BOOT_DEVICE(phandle_source2) = {
+\t.name\t\t= "source",
+\t.platdata\t= &dtv_phandle_source2,
+\t.platdata_size\t= sizeof(dtv_phandle_source2),
+};
+
+void dm_populate_phandle_data(void) {
+\tdtv_phandle_source2.clocks[0].node = DM_GET_DEVICE(phandle_target);
+}
+''', data)
+
+    def test_phandle_cd_gpio(self):
+        """Test that phandle targets are generated when unsing cd-gpios"""
+        dtb_file = get_dtb_file('dtoc_test_phandle_cd_gpios.dts')
+        output = tools.GetOutputFilename('output')
+        dtb_platdata.run_steps(['platdata'], dtb_file, False, output, True)
+        with open(output) as infile:
+            data = infile.read()
+        self._CheckStrings(C_HEADER + '''
+static struct dtd_target dtv_phandle_target = {
+\t.intval\t\t\t= 0x0,
+};
+U_BOOT_DEVICE(phandle_target) = {
+\t.name\t\t= "target",
+\t.platdata\t= &dtv_phandle_target,
+\t.platdata_size\t= sizeof(dtv_phandle_target),
+};
+
+static struct dtd_target dtv_phandle2_target = {
+\t.intval\t\t\t= 0x1,
+};
+U_BOOT_DEVICE(phandle2_target) = {
+\t.name\t\t= "target",
+\t.platdata\t= &dtv_phandle2_target,
+\t.platdata_size\t= sizeof(dtv_phandle2_target),
+};
+
+static struct dtd_target dtv_phandle3_target = {
+\t.intval\t\t\t= 0x2,
+};
+U_BOOT_DEVICE(phandle3_target) = {
+\t.name\t\t= "target",
+\t.platdata\t= &dtv_phandle3_target,
+\t.platdata_size\t= sizeof(dtv_phandle3_target),
+};
+
+static struct dtd_source dtv_phandle_source = {
+\t.cd_gpios\t\t= {
+\t\t\t{NULL, {}},
+\t\t\t{NULL, {11}},
+\t\t\t{NULL, {12, 13}},
+\t\t\t{NULL, {}},},
+};
+U_BOOT_DEVICE(phandle_source) = {
+\t.name\t\t= "source",
+\t.platdata\t= &dtv_phandle_source,
+\t.platdata_size\t= sizeof(dtv_phandle_source),
+};
+
+static struct dtd_source dtv_phandle_source2 = {
+\t.cd_gpios\t\t= {
+\t\t\t{NULL, {}},},
 };
 U_BOOT_DEVICE(phandle_source2) = {
 \t.name\t\t= "source",
@@ -382,6 +526,13 @@
 \t.platdata_size\t= sizeof(dtv_phandle_source2),
 };
 
+void dm_populate_phandle_data(void) {
+\tdtv_phandle_source.cd_gpios[0].node = DM_GET_DEVICE(phandle_target);
+\tdtv_phandle_source.cd_gpios[1].node = DM_GET_DEVICE(phandle2_target);
+\tdtv_phandle_source.cd_gpios[2].node = DM_GET_DEVICE(phandle3_target);
+\tdtv_phandle_source.cd_gpios[3].node = DM_GET_DEVICE(phandle_target);
+\tdtv_phandle_source2.cd_gpios[0].node = DM_GET_DEVICE(phandle_target);
+}
 ''', data)
 
     def test_phandle_bad(self):
@@ -390,7 +541,7 @@
                                 capture_stderr=True)
         output = tools.GetOutputFilename('output')
         with self.assertRaises(ValueError) as e:
-            dtb_platdata.run_steps(['struct'], dtb_file, False, output)
+            self.run_test(['struct'], dtb_file, output)
         self.assertIn("Cannot parse 'clocks' in node 'phandle-source'",
                       str(e.exception))
 
@@ -400,15 +551,15 @@
                                 capture_stderr=True)
         output = tools.GetOutputFilename('output')
         with self.assertRaises(ValueError) as e:
-            dtb_platdata.run_steps(['struct'], dtb_file, False, output)
-        self.assertIn("Node 'phandle-target' has no '#clock-cells' property",
+            self.run_test(['struct'], dtb_file, output)
+        self.assertIn("Node 'phandle-target' has no cells property",
                       str(e.exception))
 
     def test_aliases(self):
         """Test output from a node with multiple compatible strings"""
         dtb_file = get_dtb_file('dtoc_test_aliases.dts')
         output = tools.GetOutputFilename('output')
-        dtb_platdata.run_steps(['struct'], dtb_file, False, output)
+        self.run_test(['struct'], dtb_file, output)
         with open(output) as infile:
             data = infile.read()
         self._CheckStrings(HEADER + '''
@@ -419,11 +570,11 @@
 #define dtd_compat3 dtd_compat1
 ''', data)
 
-        dtb_platdata.run_steps(['platdata'], dtb_file, False, output)
+        self.run_test(['platdata'], dtb_file, output)
         with open(output) as infile:
             data = infile.read()
         self._CheckStrings(C_HEADER + '''
-static const struct dtd_compat1 dtv_spl_test = {
+static struct dtd_compat1 dtv_spl_test = {
 \t.intval\t\t\t= 0x1,
 };
 U_BOOT_DEVICE(spl_test) = {
@@ -432,13 +583,13 @@
 \t.platdata_size\t= sizeof(dtv_spl_test),
 };
 
-''', data)
+''' + C_EMPTY_POPULATE_PHANDLE_DATA, data)
 
     def test_addresses64(self):
         """Test output from a node with a 'reg' property with na=2, ns=2"""
         dtb_file = get_dtb_file('dtoc_test_addr64.dts')
         output = tools.GetOutputFilename('output')
-        dtb_platdata.run_steps(['struct'], dtb_file, False, output)
+        self.run_test(['struct'], dtb_file, output)
         with open(output) as infile:
             data = infile.read()
         self._CheckStrings(HEADER + '''
@@ -453,11 +604,11 @@
 };
 ''', data)
 
-        dtb_platdata.run_steps(['platdata'], dtb_file, False, output)
+        self.run_test(['platdata'], dtb_file, output)
         with open(output) as infile:
             data = infile.read()
         self._CheckStrings(C_HEADER + '''
-static const struct dtd_test1 dtv_test1 = {
+static struct dtd_test1 dtv_test1 = {
 \t.reg\t\t\t= {0x1234, 0x5678},
 };
 U_BOOT_DEVICE(test1) = {
@@ -466,7 +617,7 @@
 \t.platdata_size\t= sizeof(dtv_test1),
 };
 
-static const struct dtd_test2 dtv_test2 = {
+static struct dtd_test2 dtv_test2 = {
 \t.reg\t\t\t= {0x1234567890123456, 0x9876543210987654},
 };
 U_BOOT_DEVICE(test2) = {
@@ -475,7 +626,7 @@
 \t.platdata_size\t= sizeof(dtv_test2),
 };
 
-static const struct dtd_test3 dtv_test3 = {
+static struct dtd_test3 dtv_test3 = {
 \t.reg\t\t\t= {0x1234567890123456, 0x9876543210987654, 0x2, 0x3},
 };
 U_BOOT_DEVICE(test3) = {
@@ -484,13 +635,13 @@
 \t.platdata_size\t= sizeof(dtv_test3),
 };
 
-''', data)
+''' + C_EMPTY_POPULATE_PHANDLE_DATA, data)
 
     def test_addresses32(self):
         """Test output from a node with a 'reg' property with na=1, ns=1"""
         dtb_file = get_dtb_file('dtoc_test_addr32.dts')
         output = tools.GetOutputFilename('output')
-        dtb_platdata.run_steps(['struct'], dtb_file, False, output)
+        self.run_test(['struct'], dtb_file, output)
         with open(output) as infile:
             data = infile.read()
         self._CheckStrings(HEADER + '''
@@ -502,11 +653,11 @@
 };
 ''', data)
 
-        dtb_platdata.run_steps(['platdata'], dtb_file, False, output)
+        self.run_test(['platdata'], dtb_file, output)
         with open(output) as infile:
             data = infile.read()
         self._CheckStrings(C_HEADER + '''
-static const struct dtd_test1 dtv_test1 = {
+static struct dtd_test1 dtv_test1 = {
 \t.reg\t\t\t= {0x1234, 0x5678},
 };
 U_BOOT_DEVICE(test1) = {
@@ -515,7 +666,7 @@
 \t.platdata_size\t= sizeof(dtv_test1),
 };
 
-static const struct dtd_test2 dtv_test2 = {
+static struct dtd_test2 dtv_test2 = {
 \t.reg\t\t\t= {0x12345678, 0x98765432, 0x2, 0x3},
 };
 U_BOOT_DEVICE(test2) = {
@@ -524,13 +675,13 @@
 \t.platdata_size\t= sizeof(dtv_test2),
 };
 
-''', data)
+''' + C_EMPTY_POPULATE_PHANDLE_DATA, data)
 
     def test_addresses64_32(self):
         """Test output from a node with a 'reg' property with na=2, ns=1"""
         dtb_file = get_dtb_file('dtoc_test_addr64_32.dts')
         output = tools.GetOutputFilename('output')
-        dtb_platdata.run_steps(['struct'], dtb_file, False, output)
+        self.run_test(['struct'], dtb_file, output)
         with open(output) as infile:
             data = infile.read()
         self._CheckStrings(HEADER + '''
@@ -545,11 +696,11 @@
 };
 ''', data)
 
-        dtb_platdata.run_steps(['platdata'], dtb_file, False, output)
+        self.run_test(['platdata'], dtb_file, output)
         with open(output) as infile:
             data = infile.read()
         self._CheckStrings(C_HEADER + '''
-static const struct dtd_test1 dtv_test1 = {
+static struct dtd_test1 dtv_test1 = {
 \t.reg\t\t\t= {0x123400000000, 0x5678},
 };
 U_BOOT_DEVICE(test1) = {
@@ -558,7 +709,7 @@
 \t.platdata_size\t= sizeof(dtv_test1),
 };
 
-static const struct dtd_test2 dtv_test2 = {
+static struct dtd_test2 dtv_test2 = {
 \t.reg\t\t\t= {0x1234567890123456, 0x98765432},
 };
 U_BOOT_DEVICE(test2) = {
@@ -567,7 +718,7 @@
 \t.platdata_size\t= sizeof(dtv_test2),
 };
 
-static const struct dtd_test3 dtv_test3 = {
+static struct dtd_test3 dtv_test3 = {
 \t.reg\t\t\t= {0x1234567890123456, 0x98765432, 0x2, 0x3},
 };
 U_BOOT_DEVICE(test3) = {
@@ -576,13 +727,13 @@
 \t.platdata_size\t= sizeof(dtv_test3),
 };
 
-''', data)
+''' + C_EMPTY_POPULATE_PHANDLE_DATA, data)
 
     def test_addresses32_64(self):
         """Test output from a node with a 'reg' property with na=1, ns=2"""
         dtb_file = get_dtb_file('dtoc_test_addr32_64.dts')
         output = tools.GetOutputFilename('output')
-        dtb_platdata.run_steps(['struct'], dtb_file, False, output)
+        self.run_test(['struct'], dtb_file, output)
         with open(output) as infile:
             data = infile.read()
         self._CheckStrings(HEADER + '''
@@ -597,11 +748,11 @@
 };
 ''', data)
 
-        dtb_platdata.run_steps(['platdata'], dtb_file, False, output)
+        self.run_test(['platdata'], dtb_file, output)
         with open(output) as infile:
             data = infile.read()
         self._CheckStrings(C_HEADER + '''
-static const struct dtd_test1 dtv_test1 = {
+static struct dtd_test1 dtv_test1 = {
 \t.reg\t\t\t= {0x1234, 0x567800000000},
 };
 U_BOOT_DEVICE(test1) = {
@@ -610,7 +761,7 @@
 \t.platdata_size\t= sizeof(dtv_test1),
 };
 
-static const struct dtd_test2 dtv_test2 = {
+static struct dtd_test2 dtv_test2 = {
 \t.reg\t\t\t= {0x12345678, 0x9876543210987654},
 };
 U_BOOT_DEVICE(test2) = {
@@ -619,7 +770,7 @@
 \t.platdata_size\t= sizeof(dtv_test2),
 };
 
-static const struct dtd_test3 dtv_test3 = {
+static struct dtd_test3 dtv_test3 = {
 \t.reg\t\t\t= {0x12345678, 0x9876543210987654, 0x2, 0x3},
 };
 U_BOOT_DEVICE(test3) = {
@@ -628,7 +779,7 @@
 \t.platdata_size\t= sizeof(dtv_test3),
 };
 
-''', data)
+''' + C_EMPTY_POPULATE_PHANDLE_DATA, data)
 
     def test_bad_reg(self):
         """Test that a reg property with an invalid type generates an error"""
@@ -636,7 +787,7 @@
         dtb_file = get_dtb_file('dtoc_test_bad_reg.dts', capture_stderr=True)
         output = tools.GetOutputFilename('output')
         with self.assertRaises(ValueError) as e:
-            dtb_platdata.run_steps(['struct'], dtb_file, False, output)
+            self.run_test(['struct'], dtb_file, output)
         self.assertIn("Node 'spl-test' reg property is not an int",
                       str(e.exception))
 
@@ -646,7 +797,7 @@
         dtb_file = get_dtb_file('dtoc_test_bad_reg2.dts', capture_stderr=True)
         output = tools.GetOutputFilename('output')
         with self.assertRaises(ValueError) as e:
-            dtb_platdata.run_steps(['struct'], dtb_file, False, output)
+            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)",
                       str(e.exception))
 
@@ -654,7 +805,7 @@
         """Test that a subequent node can add a new property to a struct"""
         dtb_file = get_dtb_file('dtoc_test_add_prop.dts')
         output = tools.GetOutputFilename('output')
-        dtb_platdata.run_steps(['struct'], dtb_file, False, output)
+        self.run_test(['struct'], dtb_file, output)
         with open(output) as infile:
             data = infile.read()
         self._CheckStrings(HEADER + '''
@@ -664,11 +815,11 @@
 };
 ''', data)
 
-        dtb_platdata.run_steps(['platdata'], dtb_file, False, output)
+        self.run_test(['platdata'], dtb_file, output)
         with open(output) as infile:
             data = infile.read()
         self._CheckStrings(C_HEADER + '''
-static const struct dtd_sandbox_spl_test dtv_spl_test = {
+static struct dtd_sandbox_spl_test dtv_spl_test = {
 \t.intval\t\t\t= 0x1,
 };
 U_BOOT_DEVICE(spl_test) = {
@@ -677,7 +828,7 @@
 \t.platdata_size\t= sizeof(dtv_spl_test),
 };
 
-static const struct dtd_sandbox_spl_test dtv_spl_test2 = {
+static struct dtd_sandbox_spl_test dtv_spl_test2 = {
 \t.intarray\t\t= 0x5,
 };
 U_BOOT_DEVICE(spl_test2) = {
@@ -686,18 +837,18 @@
 \t.platdata_size\t= sizeof(dtv_spl_test2),
 };
 
-''', data)
+''' + C_EMPTY_POPULATE_PHANDLE_DATA, data)
 
     def testStdout(self):
         """Test output to stdout"""
         dtb_file = get_dtb_file('dtoc_test_simple.dts')
         with test_util.capture_sys_output() as (stdout, stderr):
-            dtb_platdata.run_steps(['struct'], dtb_file, False, '-')
+            self.run_test(['struct'], dtb_file, '-')
 
     def testNoCommand(self):
         """Test running dtoc without a command"""
         with self.assertRaises(ValueError) as e:
-            dtb_platdata.run_steps([], '', False, '')
+            self.run_test([], '', '')
         self.assertIn("Please specify a command: struct, platdata",
                       str(e.exception))
 
@@ -706,6 +857,6 @@
         dtb_file = get_dtb_file('dtoc_test_simple.dts')
         output = tools.GetOutputFilename('output')
         with self.assertRaises(ValueError) as e:
-            dtb_platdata.run_steps(['invalid-cmd'], dtb_file, False, output)
+            self.run_test(['invalid-cmd'], dtb_file, output)
         self.assertIn("Unknown command 'invalid-cmd': (use: struct, platdata)",
                       str(e.exception))
diff --git a/tools/patman/checkpatch.py b/tools/patman/checkpatch.py
index 98c63af..07c3e27 100644
--- a/tools/patman/checkpatch.py
+++ b/tools/patman/checkpatch.py
@@ -38,7 +38,7 @@
     sys.exit('Cannot find checkpatch.pl - please put it in your ' +
              '~/bin directory or use --no-check')
 
-def CheckPatch(fname, verbose=False):
+def CheckPatch(fname, verbose=False, show_types=False):
     """Run checkpatch.pl on a file.
 
     Returns:
@@ -64,8 +64,10 @@
     result.problems = []
     chk = FindCheckPatch()
     item = {}
-    result.stdout = command.Output(chk, '--no-tree', fname,
-                                   raise_on_error=False)
+    args = [chk, '--no-tree']
+    if show_types:
+        args.append('--show-types')
+    result.stdout = command.Output(*args, fname, raise_on_error=False)
     #pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE)
     #stdout, stderr = pipe.communicate()
 
@@ -81,9 +83,10 @@
                                ' checks, (\d+)')
     re_ok = re.compile('.*has no obvious style problems')
     re_bad = re.compile('.*has style problems, please review')
-    re_error = re.compile('ERROR: (.*)')
-    re_warning = re.compile(emacs_prefix + 'WARNING:(?:[A-Z_]+:)? (.*)')
-    re_check = re.compile('CHECK: (.*)')
+    type_name = '([A-Z_]+:)?'
+    re_error = re.compile('ERROR:%s (.*)' % type_name)
+    re_warning = re.compile(emacs_prefix + 'WARNING:%s (.*)' % type_name)
+    re_check = re.compile('CHECK:%s (.*)' % type_name)
     re_file = re.compile('#\d+: FILE: ([^:]*):(\d+):')
     re_note = re.compile('NOTE: (.*)')
     indent = ' ' * 6
@@ -129,13 +132,16 @@
         check_match = re_check.match(line)
         subject_match = line.startswith('Subject:')
         if err_match:
-            item['msg'] = err_match.group(1)
+            item['cptype'] = err_match.group(1)
+            item['msg'] = err_match.group(2)
             item['type'] = 'error'
         elif warn_match:
-            item['msg'] = warn_match.group(1)
+            item['cptype'] = warn_match.group(1)
+            item['msg'] = warn_match.group(2)
             item['type'] = 'warning'
         elif check_match:
-            item['msg'] = check_match.group(1)
+            item['cptype'] = check_match.group(1)
+            item['msg'] = check_match.group(2)
             item['type'] = 'check'
         elif file_match:
             item['file'] = file_match.group(1)
diff --git a/tools/patman/command.py b/tools/patman/command.py
index e67ac15..bf8ea6c 100644
--- a/tools/patman/command.py
+++ b/tools/patman/command.py
@@ -5,7 +5,6 @@
 import os
 
 from patman import cros_subprocess
-from patman import tools
 
 """Shell command ease-ups for Python."""
 
@@ -35,9 +34,9 @@
 
     def ToOutput(self, binary):
         if not binary:
-            self.stdout = tools.ToString(self.stdout)
-            self.stderr = tools.ToString(self.stderr)
-            self.combined = tools.ToString(self.combined)
+            self.stdout = self.stdout.decode('utf-8')
+            self.stderr = self.stderr.decode('utf-8')
+            self.combined = self.combined.decode('utf-8')
         return self
 
 
diff --git a/tools/patman/get_maintainer.py b/tools/patman/get_maintainer.py
index 473f0fe..af4ba15 100644
--- a/tools/patman/get_maintainer.py
+++ b/tools/patman/get_maintainer.py
@@ -5,17 +5,16 @@
 import os
 
 from patman import command
-from patman import gitutil
 
-def FindGetMaintainer():
+def FindGetMaintainer(try_list):
     """Look for the get_maintainer.pl script.
 
+    Args:
+        try_list: List of directories to try for the get_maintainer.pl script
+
     Returns:
         If the script is found we'll return a path to it; else None.
     """
-    try_list = [
-        os.path.join(gitutil.GetTopLevel(), 'scripts'),
-        ]
     # Look in the list
     for path in try_list:
         fname = os.path.join(path, 'get_maintainer.pl')
@@ -24,7 +23,7 @@
 
     return None
 
-def GetMaintainer(fname, verbose=False):
+def GetMaintainer(dir_list, fname, verbose=False):
     """Run get_maintainer.pl on a file if we find it.
 
     We look for get_maintainer.pl in the 'scripts' directory at the top of
@@ -32,12 +31,13 @@
     then we fail silently.
 
     Args:
+        dir_list: List of directories to try for the get_maintainer.pl script
         fname: Path to the patch file to run get_maintainer.pl on.
 
     Returns:
         A list of email addresses to CC to.
     """
-    get_maintainer = FindGetMaintainer()
+    get_maintainer = FindGetMaintainer(dir_list)
     if not get_maintainer:
         if verbose:
             print("WARNING: Couldn't find get_maintainer.pl")
diff --git a/tools/patman/gitutil.py b/tools/patman/gitutil.py
index 72fc95d..5189840 100644
--- a/tools/patman/gitutil.py
+++ b/tools/patman/gitutil.py
@@ -7,9 +7,7 @@
 import subprocess
 import sys
 
-from patman import checkpatch
 from patman import command
-from patman import series
 from patman import settings
 from patman import terminal
 from patman import tools
@@ -369,9 +367,9 @@
     >>> alias['boys'] = ['fred', ' john']
     >>> alias['all'] = ['fred ', 'john', '   mary   ']
     >>> alias[os.getenv('USER')] = ['this-is-me@me.com']
-    >>> series = series.Series()
-    >>> series.to = ['fred']
-    >>> series.cc = ['mary']
+    >>> series = {}
+    >>> series['to'] = ['fred']
+    >>> series['cc'] = ['mary']
     >>> EmailPatches(series, 'cover', ['p1', 'p2'], True, True, 'cc-fname', \
             False, alias)
     'git send-email --annotate --to "f.bloggs@napier.co.nz" --cc \
@@ -380,7 +378,7 @@
             alias)
     'git send-email --annotate --to "f.bloggs@napier.co.nz" --cc \
 "m.poppins@cloud.net" --cc-cmd "./patman --cc-cmd cc-fname" p1'
-    >>> series.cc = ['all']
+    >>> series['cc'] = ['all']
     >>> EmailPatches(series, 'cover', ['p1', 'p2'], True, True, 'cc-fname', \
             True, alias)
     'git send-email --annotate --to "this-is-me@me.com" --cc-cmd "./patman \
diff --git a/tools/patman/main.py b/tools/patman/main.py
index 0974c84..28a9a26 100755
--- a/tools/patman/main.py
+++ b/tools/patman/main.py
@@ -25,7 +25,7 @@
 from patman import project
 from patman import settings
 from patman import terminal
-from patman import test
+from patman import test_checkpatch
 
 
 parser = OptionParser()
@@ -80,7 +80,7 @@
 # Parse options twice: first to get the project and second to handle
 # defaults properly (which depends on project).
 (options, args) = parser.parse_args()
-settings.Setup(parser, options.project, '')
+settings.Setup(gitutil, parser, options.project, '')
 (options, args) = parser.parse_args()
 
 if __name__ != "__main__":
@@ -93,7 +93,7 @@
 
     sys.argv = [sys.argv[0]]
     result = unittest.TestResult()
-    for module in (test.TestPatch, func_test.TestFunctional):
+    for module in (test_checkpatch.TestPatch, func_test.TestFunctional):
         suite = unittest.TestLoader().loadTestsFromTestCase(module)
         suite.run(result)
 
diff --git a/tools/patman/series.py b/tools/patman/series.py
index ca7ca55..b7eef37 100644
--- a/tools/patman/series.py
+++ b/tools/patman/series.py
@@ -263,7 +263,8 @@
             if type(add_maintainers) == type(cc):
                 cc += add_maintainers
             elif add_maintainers:
-                cc += get_maintainer.GetMaintainer(commit.patch)
+                dir_list = [os.path.join(gitutil.GetTopLevel(), 'scripts')]
+                cc += get_maintainer.GetMaintainer(dir_list, commit.patch)
             for x in set(cc) & set(settings.bounces):
                 print(col.Color(col.YELLOW, 'Skipping "%s"' % x))
             cc = set(cc) - set(settings.bounces)
diff --git a/tools/patman/settings.py b/tools/patman/settings.py
index ca74fc6..635561a 100644
--- a/tools/patman/settings.py
+++ b/tools/patman/settings.py
@@ -11,7 +11,6 @@
 import re
 
 from patman import command
-from patman import gitutil
 from patman import tools
 
 """Default settings per-project.
@@ -185,7 +184,7 @@
 
     fd.close()
 
-def CreatePatmanConfigFile(config_fname):
+def CreatePatmanConfigFile(gitutil, config_fname):
     """Creates a config file under $(HOME)/.patman if it can't find one.
 
     Args:
@@ -301,7 +300,7 @@
     except:
         raise
 
-def Setup(parser, project_name, config_fname=''):
+def Setup(gitutil, parser, project_name, config_fname=''):
     """Set up the settings module by reading config files.
 
     Args:
@@ -318,7 +317,7 @@
 
     if not os.path.exists(config_fname):
         print("No config file found ~/.patman\nCreating one...\n")
-        CreatePatmanConfigFile(config_fname)
+        CreatePatmanConfigFile(gitutil, config_fname)
 
     config.read(config_fname)
 
diff --git a/tools/patman/test.py b/tools/patman/test_checkpatch.py
similarity index 69%
rename from tools/patman/test.py
rename to tools/patman/test_checkpatch.py
index e7f709e..c9580ad 100644
--- a/tools/patman/test.py
+++ b/tools/patman/test_checkpatch.py
@@ -1,6 +1,8 @@
 # -*- coding: utf-8 -*-
 # SPDX-License-Identifier: GPL-2.0+
 #
+# Tests for U-Boot-specific checkpatch.pl features
+#
 # Copyright (c) 2011 The Chromium OS Authors.
 #
 
@@ -15,11 +17,76 @@
 from patman import commit
 
 
-class TestPatch(unittest.TestCase):
-    """Test this program
+class Line:
+    def __init__(self, fname, text):
+        self.fname = fname
+        self.text = text
+
+
+class PatchMaker:
+    def __init__(self):
+        self.lines = []
+
+    def add_line(self, fname, text):
+        self.lines.append(Line(fname, text))
+
+    def get_patch_text(self):
+        base = '''From 125b77450f4c66b8fd9654319520bbe795c9ef31 Mon Sep 17 00:00:00 2001
+From: Simon Glass <sjg@chromium.org>
+Date: Sun, 14 Jun 2020 09:45:14 -0600
+Subject: [PATCH] Test commit
+
+This is a test commit.
+
+Signed-off-by: Simon Glass <sjg@chromium.org>
+---
+
+'''
+        lines = base.splitlines()
+
+        # Create the diffstat
+        change = 0
+        insert = 0
+        for line in self.lines:
+            lines.append(' %s      | 1 +' % line.fname)
+            change += 1
+            insert += 1
+        lines.append(' %d files changed, %d insertions(+)' % (change, insert))
+        lines.append('')
+
+        # Create the patch info for each file
+        for line in self.lines:
+            lines.append('diff --git a/%s b/%s' % (line.fname, line.fname))
+            lines.append('index 7837d459f18..5ba7840f68e 100644')
+            lines.append('--- a/%s' % line.fname)
+            lines.append('+++ b/%s' % line.fname)
+            lines += ('''@@ -121,6 +121,7 @@ enum uclass_id {
+ 	UCLASS_W1,		/* Dallas 1-Wire bus */
+ 	UCLASS_W1_EEPROM,	/* one-wire EEPROMs */
+ 	UCLASS_WDT,		/* Watchdog Timer driver */
++%s
+
+ 	UCLASS_COUNT,
+ 	UCLASS_INVALID = -1,
+''' % line.text).splitlines()
+        lines.append('---')
+        lines.append('2.17.1')
 
-    TODO: Write tests for the rest of the functionality
-    """
+        return '\n'.join(lines)
+
+    def get_patch(self):
+        inhandle, inname = tempfile.mkstemp()
+        infd = os.fdopen(inhandle, 'w')
+        infd.write(self.get_patch_text())
+        infd.close()
+        return inname
+
+    def run_checkpatch(self):
+        return checkpatch.CheckPatch(self.get_patch(), show_types=True)
+
+
+class TestPatch(unittest.TestCase):
+    """Test the u_boot_line() function in checkpatch.pl"""
 
     def testBasic(self):
         """Test basic filter operation"""
@@ -281,6 +348,56 @@
         self.assertEqual(result.lines, 62)
         os.remove(inf)
 
+    def checkSingleMessage(self, pm, msg, pmtype = 'warning'):
+        """Helper function to run checkpatch and check the result
+
+        Args:
+            pm: PatchMaker object to use
+            msg" Expected message (e.g. 'LIVETREE')
+            pmtype: Type of problem ('error', 'warning')
+        """
+        result = pm.run_checkpatch()
+        if pmtype == 'warning':
+            self.assertEqual(result.warnings, 1)
+        elif pmtype == 'error':
+            self.assertEqual(result.errors, 1)
+        if len(result.problems) != 1:
+            print(result.problems)
+        self.assertEqual(len(result.problems), 1)
+        self.assertIn(msg, result.problems[0]['cptype'])
+
+    def testUclass(self):
+        """Test for possible new uclass"""
+        pm = PatchMaker()
+        pm.add_line('include/dm/uclass-id.h', 'UCLASS_WIBBLE,')
+        self.checkSingleMessage(pm, 'NEW_UCLASS')
+
+    def testLivetree(self):
+        """Test for Use the livetree API"""
+        pm = PatchMaker()
+        pm.add_line('common/main.c', 'fdtdec_do_something()')
+        self.checkSingleMessage(pm, 'LIVETREE')
+
+    def testNewCommand(self):
+        """Test for Use the livetree API"""
+        pm = PatchMaker()
+        pm.add_line('common/main.c', 'do_wibble(struct cmd_tbl *cmd_tbl)')
+        self.checkSingleMessage(pm, 'CMD_TEST')
+
+    def testNewCommand(self):
+        """Test for Use the livetree API"""
+        pm = PatchMaker()
+        pm.add_line('common/main.c', '#ifdef CONFIG_YELLOW')
+        pm.add_line('common/init.h', '#ifdef CONFIG_YELLOW')
+        pm.add_line('fred.dtsi', '#ifdef CONFIG_YELLOW')
+        self.checkSingleMessage(pm, "PREFER_IF")
+
+    def testCommandUseDefconfig(self):
+        """Test for Use the livetree API"""
+        pm = PatchMaker()
+        pm.add_line('common/main.c', '#undef CONFIG_CMD_WHICH')
+        self.checkSingleMessage(pm, 'DEFINE_CONFIG_CMD', 'error')
+
 
 if __name__ == "__main__":
     unittest.main()
diff --git a/tools/patman/test_util.py b/tools/patman/test_util.py
index 4d28d9f..aac58fb 100644
--- a/tools/patman/test_util.py
+++ b/tools/patman/test_util.py
@@ -11,7 +11,6 @@
 import unittest
 
 from patman import command
-from patman import test_util
 
 from io import StringIO