Merge tag 'ti-v2021.04-rc3' of https://gitlab.denx.de/u-boot/custodians/u-boot-ti

- Fix ethernet on J721e
- Sync am335x DT nodes from Linux 5.9-rc7
- Minor Clock fixes
diff --git a/README b/README
index f7f9aa5..b962ba7 100644
--- a/README
+++ b/README
@@ -575,7 +575,6 @@
 		 * The bootm command automatically updates the fdt
 
 		OF_TBCLK - The timebase frequency.
-		OF_STDOUT_PATH - The path to the console device
 
 		boards with QUICC Engines require OF_QE to set UCC MAC
 		addresses
diff --git a/arch/arm/dts/fsl-ls1028a-rdb.dts b/arch/arm/dts/fsl-ls1028a-rdb.dts
index 85b4815..3432fca 100644
--- a/arch/arm/dts/fsl-ls1028a-rdb.dts
+++ b/arch/arm/dts/fsl-ls1028a-rdb.dts
@@ -15,6 +15,12 @@
 	compatible = "fsl,ls1028a-rdb", "fsl,ls1028a";
 	aliases {
 		spi0 = &fspi;
+		eth0 = &enetc0;
+		eth1 = &enetc2;
+		eth2 = &mscc_felix_port0;
+		eth3 = &mscc_felix_port1;
+		eth4 = &mscc_felix_port2;
+		eth5 = &mscc_felix_port3;
 	};
 };
 
@@ -131,9 +137,67 @@
 	phy-handle = <&rdb_phy0>;
 };
 
+&enetc2 {
+	status = "okay";
+};
+
+&mscc_felix {
+	status = "okay";
+};
+
+&mscc_felix_port0 {
+	label = "swp0";
+	phy-handle = <&sw_phy0>;
+	phy-mode = "qsgmii";
+	status = "okay";
+};
+
+&mscc_felix_port1 {
+	label = "swp1";
+	phy-handle = <&sw_phy1>;
+	phy-mode = "qsgmii";
+	status = "okay";
+};
+
+&mscc_felix_port2 {
+	label = "swp2";
+	phy-handle = <&sw_phy2>;
+	phy-mode = "qsgmii";
+	status = "okay";
+};
+
+&mscc_felix_port3 {
+	label = "swp3";
+	phy-handle = <&sw_phy3>;
+	phy-mode = "qsgmii";
+	status = "okay";
+};
+
+&mscc_felix_port4 {
+	ethernet = <&enetc2>;
+	status = "okay";
+};
+
 &mdio0 {
 	status = "okay";
 	rdb_phy0: phy@2 {
 		reg = <2>;
 	};
+
+	/* VSC8514 QSGMII PHY */
+	sw_phy0: phy@10 {
+		reg = <0x10>;
+	};
+
+	sw_phy1: phy@11 {
+		reg = <0x11>;
+	};
+
+	sw_phy2: phy@12 {
+		reg = <0x12>;
+	};
+
+	sw_phy3: phy@13 {
+		reg = <0x13>;
+	};
 };
diff --git a/arch/arm/dts/fsl-ls1028a.dtsi b/arch/arm/dts/fsl-ls1028a.dtsi
index 5171bf2..c7c725a 100644
--- a/arch/arm/dts/fsl-ls1028a.dtsi
+++ b/arch/arm/dts/fsl-ls1028a.dtsi
@@ -151,9 +151,63 @@
 			reg = <0x000300 0 0 0 0>;
 			status = "disabled";
 		};
+
+		mscc_felix: pci@0,5 {
+			reg = <0x000500 0 0 0 0>;
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				mscc_felix_port0: port@0 {
+					reg = <0>;
+					status = "disabled";
+				};
+
+				mscc_felix_port1: port@1 {
+					reg = <1>;
+					status = "disabled";
+				};
+
+				mscc_felix_port2: port@2 {
+					reg = <2>;
+					status = "disabled";
+				};
+
+				mscc_felix_port3: port@3 {
+					reg = <3>;
+					status = "disabled";
+				};
+
+				mscc_felix_port4: port@4 {
+					reg = <4>;
+					phy-mode = "internal";
+					status = "disabled";
+
+					fixed-link {
+						speed = <2500>;
+						full-duplex;
+					};
+				};
+
+				mscc_felix_port5: port@5 {
+					reg = <5>;
+					phy-mode = "internal";
+					status = "disabled";
+
+					fixed-link {
+						speed = <1000>;
+						full-duplex;
+					};
+
+				};
+			};
+		};
+
 		enetc6: pci@0,6 {
 			reg = <0x000600 0 0 0 0>;
-			status = "okay";
+			status = "disabled";
 			phy-mode = "internal";
 		};
 	};
diff --git a/arch/arm/include/asm/arch-fsl-layerscape/config.h b/arch/arm/include/asm/arch-fsl-layerscape/config.h
index a9bd8b2..da7ca05 100644
--- a/arch/arm/include/asm/arch-fsl-layerscape/config.h
+++ b/arch/arm/include/asm/arch-fsl-layerscape/config.h
@@ -183,7 +183,7 @@
 #elif defined(CONFIG_ARCH_LX2160A) || defined(CONFIG_ARCH_LX2162A)
 #define TZPC_BASE				0x02200000
 #define TZPCDECPROT_0_SET_BASE			(TZPC_BASE + 0x804)
-#if !defined(CONFIG_DM_I2C)
+#if !CONFIG_IS_ENABLED(DM_I2C)
 #define CONFIG_SYS_I2C
 #define CONFIG_SYS_I2C_EARLY_INIT
 #endif
diff --git a/arch/arm/include/asm/arch-lpc32xx/i2c.h b/arch/arm/include/asm/arch-lpc32xx/i2c.h
index f39b140..3918178 100644
--- a/arch/arm/include/asm/arch-lpc32xx/i2c.h
+++ b/arch/arm/include/asm/arch-lpc32xx/i2c.h
@@ -22,7 +22,7 @@
 	u32 stxfl;
 };
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 enum {
 	I2C_0, I2C_1, I2C_2,
 };
diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h
index de77bf6..2969a53 100644
--- a/arch/arm/include/asm/arch-sunxi/gpio.h
+++ b/arch/arm/include/asm/arch-sunxi/gpio.h
@@ -190,6 +190,7 @@
 #define SUN5I_GPG_SDC1		2
 #define SUN6I_GPG_SDC1		2
 #define SUN8I_GPG_SDC1		2
+#define SUN8I_GPG_UART1		2
 #define SUN6I_GPG_TWI3		2
 #define SUN5I_GPG_UART1		4
 
diff --git a/arch/arm/include/asm/mach-imx/mxc_i2c.h b/arch/arm/include/asm/mach-imx/mxc_i2c.h
index c016aa7..e8b330f 100644
--- a/arch/arm/include/asm/mach-imx/mxc_i2c.h
+++ b/arch/arm/include/asm/mach-imx/mxc_i2c.h
@@ -53,7 +53,7 @@
 #if CONFIG_IS_ENABLED(CLK)
 	struct clk per_clk;
 #endif
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	int (*idle_bus_fn)(void *p);
 	void *idle_bus_data;
 #else
diff --git a/arch/arm/include/asm/omap_i2c.h b/arch/arm/include/asm/omap_i2c.h
index ec7a145..9f0f272 100644
--- a/arch/arm/include/asm/omap_i2c.h
+++ b/arch/arm/include/asm/omap_i2c.h
@@ -3,7 +3,7 @@
 #ifndef _OMAP_I2C_H
 #define _OMAP_I2C_H
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 
 /* Information about a GPIO bank */
 struct omap_i2c_plat {
diff --git a/arch/arm/mach-imx/i2c-mxv7.c b/arch/arm/mach-imx/i2c-mxv7.c
index e6c74bf..d36347d 100644
--- a/arch/arm/mach-imx/i2c-mxv7.c
+++ b/arch/arm/mach-imx/i2c-mxv7.c
@@ -102,7 +102,7 @@
 	if (ret)
 		goto err_idle;
 
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	bus_i2c_init(i2c_index, speed, slave_addr, force_idle_bus, p);
 #endif
 
diff --git a/arch/arm/mach-imx/spl.c b/arch/arm/mach-imx/spl.c
index be4da0f..36033d6 100644
--- a/arch/arm/mach-imx/spl.c
+++ b/arch/arm/mach-imx/spl.c
@@ -19,6 +19,7 @@
 #include <asm/mach-imx/hab.h>
 #include <asm/mach-imx/boot_mode.h>
 #include <g_dnl.h>
+#include <linux/libfdt.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -321,11 +322,11 @@
 	return size;
 }
 
-void board_spl_fit_post_load(ulong load_addr, size_t length)
+void board_spl_fit_post_load(const void *fit)
 {
-	u32 offset = length - CONFIG_CSF_SIZE;
+	u32 offset = ALIGN(fdt_totalsize(fit), 0x1000);
 
-	if (imx_hab_authenticate_image(load_addr,
+	if (imx_hab_authenticate_image((uintptr_t)fit,
 				       offset + IVT_SIZE + CSF_PAD_SIZE,
 				       offset)) {
 		panic("spl: ERROR:  image authentication unsuccessful\n");
diff --git a/arch/arm/mach-keystone/ddr3_spd.c b/arch/arm/mach-keystone/ddr3_spd.c
index 3803449..c4a1908 100644
--- a/arch/arm/mach-keystone/ddr3_spd.c
+++ b/arch/arm/mach-keystone/ddr3_spd.c
@@ -404,7 +404,7 @@
 static int ddr3_read_spd(ddr3_spd_eeprom_t *spd_params)
 {
 	int ret;
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	int old_bus;
 
 	i2c_init(CONFIG_SYS_DAVINCI_I2C_SPEED, CONFIG_SYS_DAVINCI_I2C_SLAVE);
diff --git a/arch/arm/mach-kirkwood/include/mach/config.h b/arch/arm/mach-kirkwood/include/mach/config.h
index 3bd032e..4794f7a 100644
--- a/arch/arm/mach-kirkwood/include/mach/config.h
+++ b/arch/arm/mach-kirkwood/include/mach/config.h
@@ -96,7 +96,7 @@
 /*
  * I2C related stuff
  */
-#if defined(CONFIG_CMD_I2C) && !defined(CONFIG_DM_I2C)
+#if defined(CONFIG_CMD_I2C) && !CONFIG_IS_ENABLED(DM_I2C)
 #ifndef CONFIG_SYS_I2C_SOFT
 #define CONFIG_SYS_I2C
 #define CONFIG_SYS_I2C_MVTWSI
diff --git a/arch/arm/mach-meson/Kconfig b/arch/arm/mach-meson/Kconfig
index 513a33d..6cba2c4 100644
--- a/arch/arm/mach-meson/Kconfig
+++ b/arch/arm/mach-meson/Kconfig
@@ -9,6 +9,7 @@
 	select SYSCON
 	select REGMAP
 	select PWRSEQ
+	select MMC_PWRSEQ
 	select BOARD_LATE_INIT
 	imply CMD_DM
 
diff --git a/arch/arm/mach-omap2/am33xx/board.c b/arch/arm/mach-omap2/am33xx/board.c
index ef33b3c..62178f1 100644
--- a/arch/arm/mach-omap2/am33xx/board.c
+++ b/arch/arm/mach-omap2/am33xx/board.c
@@ -113,7 +113,7 @@
 #  endif
 };
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 static const struct omap_i2c_plat am33xx_i2c[] = {
 	{ I2C_BASE1, 100000, OMAP_I2C_REV_V2},
 	{ I2C_BASE2, 100000, OMAP_I2C_REV_V2},
diff --git a/arch/arm/mach-omap2/am33xx/clk_synthesizer.c b/arch/arm/mach-omap2/am33xx/clk_synthesizer.c
index ff1bfaf..59f0d8e 100644
--- a/arch/arm/mach-omap2/am33xx/clk_synthesizer.c
+++ b/arch/arm/mach-omap2/am33xx/clk_synthesizer.c
@@ -29,7 +29,7 @@
 	/* Enable Bye read */
 	addr = addr | CLK_SYNTHESIZER_BYTE_MODE;
 
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	/* Send the command byte */
 	rc = i2c_write(CLK_SYNTHESIZER_I2C_ADDR, addr, 1, buf, 1);
 	if (rc)
@@ -72,7 +72,7 @@
 	cmd[0] = addr | CLK_SYNTHESIZER_BYTE_MODE;
 	cmd[1] = val;
 
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	rc = i2c_write(CLK_SYNTHESIZER_I2C_ADDR, addr, 1, cmd, 2);
 #else
 	rc = dm_i2c_write(dev, addr, cmd, 2);
@@ -96,7 +96,7 @@
 	int rc;
 	u8 val = 0;
 	struct udevice *dev = NULL;
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	rc =  i2c_probe(CLK_SYNTHESIZER_I2C_ADDR);
 	if (rc) {
 		printf("i2c probe failed at address 0x%x\n",
diff --git a/arch/arm/mach-omap2/boot-common.c b/arch/arm/mach-omap2/boot-common.c
index 05efe04..1268a32 100644
--- a/arch/arm/mach-omap2/boot-common.c
+++ b/arch/arm/mach-omap2/boot-common.c
@@ -202,7 +202,7 @@
 #if defined(CONFIG_SPL_NAND_SUPPORT) || defined(CONFIG_SPL_ONENAND_SUPPORT)
 	gpmc_init();
 #endif
-#if defined(CONFIG_SPL_I2C_SUPPORT) && !defined(CONFIG_DM_I2C)
+#if defined(CONFIG_SPL_I2C_SUPPORT) && !CONFIG_IS_ENABLED(DM_I2C)
 	i2c_init(CONFIG_SYS_OMAP24_I2C_SPEED, CONFIG_SYS_OMAP24_I2C_SLAVE);
 #endif
 #if defined(CONFIG_AM33XX) && defined(CONFIG_SPL_MUSB_NEW_SUPPORT)
diff --git a/arch/arm/mach-omap2/clocks-common.c b/arch/arm/mach-omap2/clocks-common.c
index 757fa38..14b638a 100644
--- a/arch/arm/mach-omap2/clocks-common.c
+++ b/arch/arm/mach-omap2/clocks-common.c
@@ -912,7 +912,7 @@
 		enable_basic_uboot_clocks();
 }
 
-#if !defined(CONFIG_DM_I2C)
+#if !CONFIG_IS_ENABLED(DM_I2C)
 void gpi2c_init(void)
 {
 	static int gpi2c = 1;
diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c
index ae6bc65..fa2b6fc 100644
--- a/arch/arm/mach-sunxi/board.c
+++ b/arch/arm/mach-sunxi/board.c
@@ -144,6 +144,11 @@
 	sunxi_gpio_set_cfgpin(SUNXI_GPL(2), SUN8I_GPL_R_UART);
 	sunxi_gpio_set_cfgpin(SUNXI_GPL(3), SUN8I_GPL_R_UART);
 	sunxi_gpio_set_pull(SUNXI_GPL(3), SUNXI_GPIO_PULL_UP);
+#elif CONFIG_CONS_INDEX == 2 && defined(CONFIG_MACH_SUN8I) && \
+				!defined(CONFIG_MACH_SUN8I_R40)
+	sunxi_gpio_set_cfgpin(SUNXI_GPG(6), SUN8I_GPG_UART1);
+	sunxi_gpio_set_cfgpin(SUNXI_GPG(7), SUN8I_GPG_UART1);
+	sunxi_gpio_set_pull(SUNXI_GPG(7), SUNXI_GPIO_PULL_UP);
 #else
 #error Unsupported console port number. Please fix pin mux settings in board.c
 #endif
@@ -222,7 +227,7 @@
 	clock_init();
 	timer_init();
 	gpio_init();
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	i2c_init_board();
 #endif
 	eth_init_board();
diff --git a/arch/arm/mach-sunxi/clock_sun50i_h6.c b/arch/arm/mach-sunxi/clock_sun50i_h6.c
index 06d84eb..492fc4a 100644
--- a/arch/arm/mach-sunxi/clock_sun50i_h6.c
+++ b/arch/arm/mach-sunxi/clock_sun50i_h6.c
@@ -9,6 +9,11 @@
 {
 	struct sunxi_ccm_reg *const ccm =
 		(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+
+	/* this seems to enable PLLs on H616 */
+	if (IS_ENABLED(CONFIG_MACH_SUN50I_H616))
+		setbits_le32(SUNXI_PRCM_BASE + 0x250, 0x10);
+
 	clock_set_pll1(408000000);
 
 	writel(CCM_PLL6_DEFAULT, &ccm->pll6_cfg);
diff --git a/arch/powerpc/dts/Makefile b/arch/powerpc/dts/Makefile
index 3ecda36..ceaa8ce 100644
--- a/arch/powerpc/dts/Makefile
+++ b/arch/powerpc/dts/Makefile
@@ -7,6 +7,7 @@
 dtb-$(CONFIG_TARGET_KMSUPX5) += kmsupc5.dtb kmsupm5.dtb
 dtb-$(CONFIG_TARGET_KMTEGR1) += kmtegr1.dtb
 dtb-$(CONFIG_TARGET_KMTEPR2) += kmtepr2.dtb
+dtb-$(CONFIG_TARGET_MPC837XERDB) += mpc8379erdb.dtb
 dtb-$(CONFIG_TARGET_MPC8548CDS) += mpc8548cds.dtb mpc8548cds_36b.dtb
 dtb-$(CONFIG_TARGET_P1010RDB_PA) += p1010rdb-pa.dtb p1010rdb-pa_36b.dtb
 dtb-$(CONFIG_TARGET_P1010RDB_PB) += p1010rdb-pb.dtb p1010rdb-pb_36b.dtb
diff --git a/arch/powerpc/dts/mpc8379erdb.dts b/arch/powerpc/dts/mpc8379erdb.dts
new file mode 100644
index 0000000..b1881b1
--- /dev/null
+++ b/arch/powerpc/dts/mpc8379erdb.dts
@@ -0,0 +1,74 @@
+// SPDX-License-Identifier: GPL-2.0+ OR X11
+/*
+ * MPC8379E RDB Device Tree Source
+ *
+ * Copyright 2020 NXP
+ */
+
+/dts-v1/;
+
+/ {
+	compatible = "fsl,mpc8379erdb";
+
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		PowerPC,8379@0 {
+			device_type = "cpu";
+			reg = <0x0>;
+			d-cache-line-size = <32>;
+			i-cache-line-size = <32>;
+			d-cache-size = <32768>;
+			i-cache-size = <32768>;
+			timebase-frequency = <0>;
+			bus-frequency = <0>;
+			clock-frequency = <0>;
+		};
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0x00000000 0x10000000>;  // 256MB at 0
+	};
+
+	localbus@e0005000 {
+		#address-cells = <2>;
+		#size-cells = <1>;
+		compatible = "fsl,elbc", "simple-bus";
+		reg = <0xe0005000 0x1000>;
+		interrupts = <77 0x8>;
+		interrupt-parent = <&ipic>;
+	};
+
+	immr@e0000000 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		device_type = "soc";
+		compatible = "simple-bus";
+		ranges = <0 0xe0000000 0x00100000>;
+		reg = <0xe0000000 0x00000200>;
+		bus-frequency = <0>;
+
+		sdhc@2e000 {
+			compatible = "fsl,esdhc";
+			reg = <0x2e000 0x1000>;
+			bus-width = <0x4>;
+			clock-frequency = <0>;
+		};
+
+		ipic: interrupt-controller@700 {
+			compatible = "fsl,ipic";
+			interrupt-controller;
+			#address-cells = <0>;
+			#interrupt-cells = <2>;
+			reg = <0x700 0x100>;
+			device_type = "ipic";
+		};
+
+	};
+
+};
diff --git a/arch/powerpc/include/asm/fsl_i2c.h b/arch/powerpc/include/asm/fsl_i2c.h
index 73105fa..1b17661 100644
--- a/arch/powerpc/include/asm/fsl_i2c.h
+++ b/arch/powerpc/include/asm/fsl_i2c.h
@@ -68,7 +68,7 @@
 	u8 res6[0xE8];
 } fsl_i2c_t;
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 struct fsl_i2c_dev {
 	struct fsl_i2c_base __iomem *base;      /* register base */
 	u32 i2c_clk;
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index e95f463..d4195b4 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -350,6 +350,27 @@
 		test5-gpios = <&gpio_a 19>;
 	};
 
+	mmio-bus@0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "denx,u-boot-test-bus";
+		dma-ranges = <0x10000000 0x00000000 0x00040000>;
+
+		subnode@0 {
+			compatible = "denx,u-boot-fdt-test";
+		};
+	};
+
+	mmio-bus@1 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "denx,u-boot-test-bus";
+
+		subnode@0 {
+			compatible = "denx,u-boot-fdt-test";
+		};
+	};
+
 	acpi_test1: acpi-test {
 		compatible = "denx,u-boot-acpi-test";
 		acpi-ssdt-test-data = "ab";
diff --git a/board/freescale/common/dcu_sii9022a.c b/board/freescale/common/dcu_sii9022a.c
index 832ae25..9137d24 100644
--- a/board/freescale/common/dcu_sii9022a.c
+++ b/board/freescale/common/dcu_sii9022a.c
@@ -64,7 +64,7 @@
 	u8 temp;
 	u16 temp1, temp2;
 	u32 temp3;
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	struct udevice *dev;
 	int ret;
 
diff --git a/board/freescale/common/diu_ch7301.c b/board/freescale/common/diu_ch7301.c
index 02a2718..05e6a3a 100644
--- a/board/freescale/common/diu_ch7301.c
+++ b/board/freescale/common/diu_ch7301.c
@@ -53,7 +53,7 @@
 	u8 temp;
 
 	temp = I2C_DVI_TEST_PATTERN_VAL;
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	struct udevice *dev;
 
 	ret = i2c_get_chip_for_busnum(CONFIG_SYS_I2C_DVI_BUS_NUM,
diff --git a/board/freescale/common/emc2305.c b/board/freescale/common/emc2305.c
index 12ad4b3..9a75c5a 100644
--- a/board/freescale/common/emc2305.c
+++ b/board/freescale/common/emc2305.c
@@ -24,7 +24,7 @@
 			       I2C_EMC2305_FAN5};
 
 	for (index = 0; index < NUM_OF_FANS; index++) {
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 		if (i2c_write(chip_addr, Fan[index], 1, &data, 1) != 0) {
 			printf("Error: failed to change fan speed @%x\n",
 			       Fan[index]);
@@ -48,7 +48,7 @@
 	u8 data;
 
 	data = I2C_EMC2305_CMD;
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	if (i2c_write(chip_addr, I2C_EMC2305_CONF, 1, &data, 1) != 0)
 		printf("Error: failed to configure EMC2305\n");
 #else
diff --git a/board/freescale/common/qixis.c b/board/freescale/common/qixis.c
index 1696c24..2bb838c 100644
--- a/board/freescale/common/qixis.c
+++ b/board/freescale/common/qixis.c
@@ -32,7 +32,7 @@
 #ifdef CONFIG_SYS_I2C_FPGA_ADDR
 u8 qixis_read_i2c(unsigned int reg)
 {
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	return i2c_reg_read(CONFIG_SYS_I2C_FPGA_ADDR, reg);
 #else
 	struct udevice *dev;
@@ -47,7 +47,7 @@
 void qixis_write_i2c(unsigned int reg, u8 value)
 {
 	u8 val = value;
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	i2c_reg_write(CONFIG_SYS_I2C_FPGA_ADDR, reg, val);
 #else
 	struct udevice *dev;
diff --git a/board/freescale/common/sys_eeprom.c b/board/freescale/common/sys_eeprom.c
index 33ae4c1..be0fda0 100644
--- a/board/freescale/common/sys_eeprom.c
+++ b/board/freescale/common/sys_eeprom.c
@@ -152,7 +152,7 @@
 {
 	int ret;
 #ifdef CONFIG_SYS_EEPROM_BUS_NUM
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	unsigned int bus;
 #endif
 #endif
@@ -161,13 +161,13 @@
 		return 0;
 
 #ifdef CONFIG_SYS_EEPROM_BUS_NUM
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	bus = i2c_get_bus_num();
 	i2c_set_bus_num(CONFIG_SYS_EEPROM_BUS_NUM);
 #endif
 #endif
 
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	ret = i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0,
 		       CONFIG_SYS_I2C_EEPROM_ADDR_LEN,
 		       (void *)&e, sizeof(e));
@@ -186,7 +186,7 @@
 #endif
 
 #ifdef CONFIG_SYS_EEPROM_BUS_NUM
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	i2c_set_bus_num(bus);
 #endif
 #endif
@@ -223,7 +223,7 @@
 	int i;
 	void *p;
 #ifdef CONFIG_SYS_EEPROM_BUS_NUM
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	unsigned int bus;
 #endif
 #endif
@@ -237,7 +237,7 @@
 #endif
 	update_crc();
 
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 #ifdef CONFIG_SYS_EEPROM_BUS_NUM
 	bus = i2c_get_bus_num();
 	i2c_set_bus_num(CONFIG_SYS_EEPROM_BUS_NUM);
@@ -250,7 +250,7 @@
 	 * complete a given write.
 	 */
 	for (i = 0, p = &e; i < sizeof(e); i += 8, p += 8) {
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 		ret = i2c_write(CONFIG_SYS_I2C_EEPROM_ADDR, i,
 				CONFIG_SYS_I2C_EEPROM_ADDR_LEN,
 				p, min((int)(sizeof(e) - i), 8));
@@ -279,7 +279,7 @@
 		/* Verify the write by reading back the EEPROM and comparing */
 		struct eeprom e2;
 
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 		ret = i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0,
 			       CONFIG_SYS_I2C_EEPROM_ADDR_LEN,
 			       (void *)&e2, sizeof(e2));
@@ -302,7 +302,7 @@
 			ret = -1;
 	}
 
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 #ifdef CONFIG_SYS_EEPROM_BUS_NUM
 	i2c_set_bus_num(bus);
 #endif
@@ -594,7 +594,7 @@
 		u8 minor;         /* 0x05        Board revision, minor */
 	} be;
 
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0, CONFIG_SYS_I2C_EEPROM_ADDR_LEN,
 		(void *)&be, sizeof(be));
 #else
diff --git a/board/freescale/common/vid.c b/board/freescale/common/vid.c
index 2617f61..20f5421 100644
--- a/board/freescale/common/vid.c
+++ b/board/freescale/common/vid.c
@@ -65,14 +65,14 @@
 	u8 byte;
 	int i;
 	const int ir_i2c_addr[] = {0x38, 0x08, 0x09};
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	struct udevice *dev;
 #endif
 
 	/* Check all the address */
 	for (i = 0; i < (sizeof(ir_i2c_addr)/sizeof(ir_i2c_addr[0])); i++) {
 		i2caddress = ir_i2c_addr[i];
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 		ret = i2c_read(i2caddress,
 			       IR36021_MFR_ID_OFFSET, 1, (void *)&byte,
 			       sizeof(byte));
@@ -117,12 +117,12 @@
 	int i, ret, voltage_read = 0;
 	u16 vol_mon;
 	u8 buf[2];
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	struct udevice *dev;
 #endif
 
 	for (i = 0; i < NUM_READINGS; i++) {
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 		ret = i2c_read(I2C_VOL_MONITOR_ADDR,
 			       I2C_VOL_MONITOR_BUS_V_OFFSET, 1,
 			       (void *)&buf, 2);
@@ -160,12 +160,12 @@
 	int i, ret, voltage_read = 0;
 	u16 vol_mon;
 	u8 buf;
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	struct udevice *dev;
 #endif
 
 	for (i = 0; i < NUM_READINGS; i++) {
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 		ret = i2c_read(i2caddress,
 			       IR36021_LOOP1_VOUT_OFFSET,
 			       1, (void *)&buf, 1);
@@ -213,7 +213,7 @@
 	int  ret, vcode = 0;
 	u8 chan = PWM_CHANNEL0;
 
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	/* select the PAGE 0 using PMBus commands PAGE for VDD*/
 	ret = i2c_write(I2C_VOL_MONITOR_ADDR,
 			PMBUS_CMD_PAGE, 1, &chan, 1);
@@ -229,7 +229,7 @@
 		return ret;
 	}
 
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	/*read the output voltage using PMBus command READ_VOUT*/
 	ret = i2c_read(I2C_VOL_MONITOR_ADDR,
 		       PMBUS_CMD_READ_VOUT, 1, (void *)&vcode, 2);
@@ -344,7 +344,7 @@
 	vid = DIV_ROUND_UP(vdd - 245, 5);
 #endif
 
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	ret = i2c_write(i2caddress, IR36021_LOOP1_MANUAL_ID_OFFSET,
 			1, (void *)&vid, sizeof(vid));
 #else
@@ -392,7 +392,7 @@
 			vdd & 0xFF, (vdd & 0xFF00) >> 8};
 
 	/* Write the desired voltage code to the regulator */
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	/* Check write protect state */
 	ret = i2c_read(I2C_VOL_MONITOR_ADDR,
 		       PMBUS_CMD_WRITE_PROTECT, 1,
@@ -621,7 +621,7 @@
 	}
 
 	/* check IR chip work on Intel mode*/
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	ret = i2c_read(i2caddress,
 		       IR36021_INTEL_MODE_OOFSET,
 		       1, (void *)&buf, 1);
@@ -803,7 +803,7 @@
 	}
 
 	/* check IR chip work on Intel mode*/
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	ret = i2c_read(i2caddress,
 		       IR36021_INTEL_MODE_OOFSET,
 		       1, (void *)&buf, 1);
diff --git a/board/freescale/common/vsc3316_3308.c b/board/freescale/common/vsc3316_3308.c
index 8aceb8e..c51f3c5 100644
--- a/board/freescale/common/vsc3316_3308.c
+++ b/board/freescale/common/vsc3316_3308.c
@@ -34,7 +34,7 @@
 
 	/* enable 2-wire Serial InterFace (I2C) */
 	data = 0x02;
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	int ret, bus_num = 0;
 	struct udevice *dev;
 
@@ -62,7 +62,7 @@
 	debug("VSC:Initializing VSC3316 at I2C address 0x%2x"
 		" for Tx\n", vsc_addr);
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	int bus_num = 0;
 	struct udevice *dev;
 
@@ -185,7 +185,7 @@
 	debug("VSC:Initializing VSC3308 at I2C address 0x%x for Tx\n",
 	      vsc_addr);
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	int bus_num = 0;
 	struct udevice *dev;
 
@@ -385,7 +385,7 @@
 
 	debug("VSC:Initializing VSC3308 at I2C address 0x%x"
 		" for Tx\n", vsc_addr);
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	int bus_num = 0;
 	struct udevice *dev;
 
@@ -509,7 +509,7 @@
 
 	/* For new crosspoint configuration to occur, WP bit of
 	 * CORE_CONFIG_REG should be set 1 and then reset to 0 */
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	int ret, bus_num = 0;
 	struct udevice *dev;
 
diff --git a/board/freescale/ls1012aqds/ls1012aqds.c b/board/freescale/ls1012aqds/ls1012aqds.c
index b77808e..cfe3f33 100644
--- a/board/freescale/ls1012aqds/ls1012aqds.c
+++ b/board/freescale/ls1012aqds/ls1012aqds.c
@@ -112,7 +112,7 @@
 	u8 mux_sdhc_cd = 0x80;
 	int bus_num = 0;
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	struct udevice *dev;
 	int ret;
 
diff --git a/board/freescale/ls1012ardb/eth.c b/board/freescale/ls1012ardb/eth.c
index 2241d06..bb3fbc7 100644
--- a/board/freescale/ls1012ardb/eth.c
+++ b/board/freescale/ls1012ardb/eth.c
@@ -29,7 +29,7 @@
 {
 #ifdef CONFIG_TARGET_LS1012ARDB
 	/* Through reset IO expander reset both RGMII and SGMII PHYs */
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	struct udevice *dev;
 	int ret;
 
diff --git a/board/freescale/ls1012ardb/ls1012ardb.c b/board/freescale/ls1012ardb/ls1012ardb.c
index ed6dc9f..41bcf6f 100644
--- a/board/freescale/ls1012ardb/ls1012ardb.c
+++ b/board/freescale/ls1012ardb/ls1012ardb.c
@@ -43,7 +43,7 @@
 	puts("Board: LS1012ARDB ");
 
 	/* Initialize i2c early for Serial flash bank information */
-#if defined(CONFIG_DM_I2C)
+#if CONFIG_IS_ENABLED(DM_I2C)
 	struct udevice *dev;
 
 	ret = i2c_get_chip_for_busnum(bus_num, I2C_MUX_IO_ADDR,
@@ -195,7 +195,7 @@
 	u8 io = 0;
 	int ret, bus_num = 0;
 
-#if defined(CONFIG_DM_I2C)
+#if CONFIG_IS_ENABLED(DM_I2C)
 	struct udevice *dev;
 
 	ret = i2c_get_chip_for_busnum(bus_num, I2C_MUX_IO_ADDR,
@@ -234,7 +234,7 @@
 		 *	10 - eMMC Memory
 		 *	11 - SPI
 		 */
-#if defined(CONFIG_DM_I2C)
+#if CONFIG_IS_ENABLED(DM_I2C)
 		ret = dm_i2c_read(dev, I2C_MUX_IO_0, &io, 1);
 #else
 		ret = i2c_read(I2C_MUX_IO_ADDR, I2C_MUX_IO_0, 1, &io, 1);
@@ -273,7 +273,7 @@
 	u8 data = 0xf4, chip_addr = 0x24, offset_addr = 0x03;
 	int ret, bus_num = 0;
 
-#if defined(CONFIG_DM_I2C)
+#if CONFIG_IS_ENABLED(DM_I2C)
 	struct udevice *dev;
 
 	ret = i2c_get_chip_for_busnum(bus_num, chip_addr,
@@ -338,7 +338,7 @@
 	u8 chip_addr = 0x24;
 	int ret, i, bus_num = 0;
 
-#if defined(CONFIG_DM_I2C)
+#if CONFIG_IS_ENABLED(DM_I2C)
 	struct udevice *dev;
 
 	ret = i2c_get_chip_for_busnum(bus_num, chip_addr,
@@ -361,7 +361,7 @@
 	 *	  CS routed to SPI memory bank2
 	 */
 	for (i = 0; i < sizeof(data); i++) {
-#if defined(CONFIG_DM_I2C)
+#if CONFIG_IS_ENABLED(DM_I2C)
 		ret = dm_i2c_write(dev, offset_addr[i], &data[i], 1);
 #else /* Non DM I2C support - will be removed */
 		ret = i2c_write(chip_addr, offset_addr[i], 1, &data[i], 1);
diff --git a/board/freescale/ls1021aqds/dcu.c b/board/freescale/ls1021aqds/dcu.c
index f66961c..7532f7c 100644
--- a/board/freescale/ls1021aqds/dcu.c
+++ b/board/freescale/ls1021aqds/dcu.c
@@ -20,7 +20,7 @@
 static int select_i2c_ch_pca9547(u8 ch, int bus_num)
 {
 	int ret;
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	struct udevice *dev;
 
 	ret = i2c_get_chip_for_busnum(bus_num, I2C_MUX_PCA_ADDR_PRI,
@@ -65,7 +65,7 @@
 	u8 ch;
 
 	/* Mux I2C3+I2C4 as HSYNC+VSYNC */
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	struct udevice *dev;
 
 	/* QIXIS device mount on I2C1 bus*/
@@ -113,7 +113,7 @@
 		pixval = 1000000000 / dcu_fb_videomode->pixclock;
 		pixval *= 1000;
 
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 		i2c_set_bus_num(CONFIG_SYS_I2C_DVI_BUS_NUM);
 #endif
 		select_i2c_ch_pca9547(I2C_MUX_CH_CH7301,
diff --git a/board/freescale/ls1021aqds/ls1021aqds.c b/board/freescale/ls1021aqds/ls1021aqds.c
index 4169a0f..aa1f602 100644
--- a/board/freescale/ls1021aqds/ls1021aqds.c
+++ b/board/freescale/ls1021aqds/ls1021aqds.c
@@ -144,7 +144,7 @@
 int select_i2c_ch_pca9547(u8 ch, int bus_num)
 {
 	int ret;
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	struct udevice *dev;
 
 	ret = i2c_get_chip_for_busnum(bus_num, I2C_MUX_PCA_ADDR_PRI,
diff --git a/board/freescale/ls1021atwr/ls1021atwr.c b/board/freescale/ls1021atwr/ls1021atwr.c
index 0cd38a1..4c3be42 100644
--- a/board/freescale/ls1021atwr/ls1021atwr.c
+++ b/board/freescale/ls1021atwr/ls1021atwr.c
@@ -458,7 +458,7 @@
 #define MC34VR500_ADDR			0x8
 #define MC34VR500_DEVICEID		0x4
 #define MC34VR500_DEVICEID_MASK		0x0f
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	struct udevice *dev;
 	int ret;
 
diff --git a/board/freescale/ls1028a/ls1028a.c b/board/freescale/ls1028a/ls1028a.c
index f3c1d95..5269fd3 100644
--- a/board/freescale/ls1028a/ls1028a.c
+++ b/board/freescale/ls1028a/ls1028a.c
@@ -92,7 +92,7 @@
 #if defined(CONFIG_TARGET_LS1028ARDB)
 	u8 val = I2C_MUX_CH_DEFAULT;
 
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	i2c_write(I2C_MUX_PCA_ADDR_PRI, 0x0b, 1, &val, 1);
 #else
 	struct udevice *dev;
diff --git a/board/freescale/ls1043aqds/ls1043aqds.c b/board/freescale/ls1043aqds/ls1043aqds.c
index 44e4c61..5b131d1 100644
--- a/board/freescale/ls1043aqds/ls1043aqds.c
+++ b/board/freescale/ls1043aqds/ls1043aqds.c
@@ -283,7 +283,7 @@
 {
 	int ret;
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	struct udevice *dev;
 
 	ret = i2c_get_chip_for_busnum(bus_num, I2C_MUX_PCA_ADDR_PRI,
@@ -338,7 +338,7 @@
 	/* Retimer is connected to I2C1_CH7_CH5 */
 	select_i2c_ch_pca9547(I2C_MUX_CH7, bus_num);
 	reg = I2C_MUX_CH5;
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	struct udevice *dev;
 	int ret;
 
diff --git a/board/freescale/ls1046afrwy/ls1046afrwy.c b/board/freescale/ls1046afrwy/ls1046afrwy.c
index 9813a36..f1709dc 100644
--- a/board/freescale/ls1046afrwy/ls1046afrwy.c
+++ b/board/freescale/ls1046afrwy/ls1046afrwy.c
@@ -42,7 +42,7 @@
 {
 	int ret;
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	struct udevice *dev;
 
 	ret = i2c_get_chip_for_busnum(bus_num, I2C_MUX_PCA_ADDR_PRI,
diff --git a/board/freescale/ls1046aqds/ls1046aqds.c b/board/freescale/ls1046aqds/ls1046aqds.c
index 3c96c90..2069442 100644
--- a/board/freescale/ls1046aqds/ls1046aqds.c
+++ b/board/freescale/ls1046aqds/ls1046aqds.c
@@ -279,7 +279,7 @@
 int select_i2c_ch_pca9547(u8 ch, int bus_num)
 {
 	int ret;
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	struct udevice *dev;
 
 	ret = i2c_get_chip_for_busnum(bus_num, I2C_MUX_PCA_ADDR_PRI,
diff --git a/board/freescale/ls1088a/eth_ls1088aqds.c b/board/freescale/ls1088a/eth_ls1088aqds.c
index bf4f57e..140733d 100644
--- a/board/freescale/ls1088a/eth_ls1088aqds.c
+++ b/board/freescale/ls1088a/eth_ls1088aqds.c
@@ -114,12 +114,12 @@
 		{0x18, NULL}, {0x23, &reg_val[3]},
 		{0x2d, &reg_val[4]}, {4, &reg_val[5]},
 	};
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	struct udevice *udev;
 #endif
 
 	/* Set I2c to Slot 1 */
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	ret = i2c_write(0x77, 0, 0, &a, 1);
 #else
 	ret = i2c_get_chip_for_busnum(0, 0x77, 1, &udev);
@@ -173,7 +173,7 @@
 		return;
 	}
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	i2c_get_chip_for_busnum(0, i2c_phy_addr, 1, &udev);
 #endif
 
@@ -184,7 +184,7 @@
 			reg_pair[5].val = &ch_b_eq[i];
 			reg_pair[6].val = &ch_b_ctl2[j];
 			for (k = 0; k < 10; k++) {
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 				ret = i2c_write(i2c_phy_addr,
 						reg_pair[k].addr,
 						1, reg_pair[k].val, 1);
@@ -257,12 +257,12 @@
 	const char *dev = mdio_names[EMI1_SLOT1];
 	int ret = 0;
 	unsigned short value;
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	struct udevice *udev;
 #endif
 
 	/* Set I2c to Slot 1 */
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	ret = i2c_write(0x77, 0, 0, &a, 1);
 #else
 	ret = i2c_get_chip_for_busnum(0, 0x77, 1, &udev);
@@ -304,7 +304,7 @@
 		return;
 	}
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	i2c_get_chip_for_busnum(0, i2c_phy_addr, 1, &udev);
 #endif
 
@@ -316,7 +316,7 @@
 			reg_pair[6].val = &ch_b_ctl2[j];
 
 			for (k = 0; k < 10; k++) {
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 				ret = i2c_write(i2c_phy_addr,
 						reg_pair[k].addr,
 						1, reg_pair[k].val, 1);
diff --git a/board/freescale/ls1088a/ls1088a.c b/board/freescale/ls1088a/ls1088a.c
index 2ba6a39..e76ea01 100644
--- a/board/freescale/ls1088a/ls1088a.c
+++ b/board/freescale/ls1088a/ls1088a.c
@@ -379,7 +379,7 @@
 {
 	int ret;
 
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	ret = i2c_write(I2C_MUX_PCA_ADDR_PRI, 0, 1, &ch, 1);
 #else
 	struct udevice *dev;
@@ -406,7 +406,7 @@
 
 	/* Access to Control/Shared register */
 	reg = 0x0;
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	i2c_write(I2C_RETIMER_ADDR, 0xff, 1, &reg, 1);
 #else
 	struct udevice *dev;
@@ -416,7 +416,7 @@
 #endif
 
 	/* Read device revision and ID */
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	i2c_read(I2C_RETIMER_ADDR, 1, 1, &reg, 1);
 #else
 	dm_i2c_read(dev, 1, &reg, 1);
@@ -425,20 +425,20 @@
 
 	/* Enable Broadcast. All writes target all channel register sets */
 	reg = 0x0c;
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	i2c_write(I2C_RETIMER_ADDR, 0xff, 1, &reg, 1);
 #else
 	dm_i2c_write(dev, 0xff, &reg, 1);
 #endif
 
 	/* Reset Channel Registers */
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	i2c_read(I2C_RETIMER_ADDR, 0, 1, &reg, 1);
 #else
 	dm_i2c_read(dev, 0, &reg, 1);
 #endif
 	reg |= 0x4;
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	i2c_write(I2C_RETIMER_ADDR, 0, 1, &reg, 1);
 #else
 	dm_i2c_write(dev, 0, &reg, 1);
@@ -446,45 +446,45 @@
 
 	/* Set data rate as 10.3125 Gbps */
 	reg = 0x90;
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	i2c_write(I2C_RETIMER_ADDR, 0x60, 1, &reg, 1);
 #else
 	dm_i2c_write(dev, 0x60, &reg, 1);
 #endif
 	reg = 0xb3;
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	i2c_write(I2C_RETIMER_ADDR, 0x61, 1, &reg, 1);
 #else
 	dm_i2c_write(dev, 0x61, &reg, 1);
 #endif
 	reg = 0x90;
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	i2c_write(I2C_RETIMER_ADDR, 0x62, 1, &reg, 1);
 #else
 	dm_i2c_write(dev, 0x62, &reg, 1);
 #endif
 	reg = 0xb3;
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	i2c_write(I2C_RETIMER_ADDR, 0x63, 1, &reg, 1);
 #else
 	dm_i2c_write(dev, 0x63, &reg, 1);
 #endif
 	reg = 0xcd;
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	i2c_write(I2C_RETIMER_ADDR, 0x64, 1, &reg, 1);
 #else
 	dm_i2c_write(dev, 0x64, &reg, 1);
 #endif
 
 	/* Select VCO Divider to full rate (000) */
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	i2c_read(I2C_RETIMER_ADDR, 0x2F, 1, &reg, 1);
 #else
 	dm_i2c_read(dev, 0x2F, &reg, 1);
 #endif
 	reg &= 0x0f;
 	reg |= 0x70;
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	i2c_write(I2C_RETIMER_ADDR, 0x2F, 1, &reg, 1);
 #else
 	dm_i2c_write(dev, 0x2F, &reg, 1);
@@ -496,7 +496,7 @@
 
 	/* Access to Control/Shared register */
 	reg = 0x0;
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	i2c_write(I2C_RETIMER_ADDR2, 0xff, 1, &reg, 1);
 #else
 	i2c_get_chip_for_busnum(0, I2C_RETIMER_ADDR2, 1, &dev);
@@ -504,7 +504,7 @@
 #endif
 
 	/* Read device revision and ID */
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	i2c_read(I2C_RETIMER_ADDR2, 1, 1, &reg, 1);
 #else
 	dm_i2c_read(dev, 1, &reg, 1);
@@ -513,20 +513,20 @@
 
 	/* Enable Broadcast. All writes target all channel register sets */
 	reg = 0x0c;
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	i2c_write(I2C_RETIMER_ADDR2, 0xff, 1, &reg, 1);
 #else
 	dm_i2c_write(dev, 0xff, &reg, 1);
 #endif
 
 	/* Reset Channel Registers */
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	i2c_read(I2C_RETIMER_ADDR2, 0, 1, &reg, 1);
 #else
 	dm_i2c_read(dev, 0, &reg, 1);
 #endif
 	reg |= 0x4;
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	i2c_write(I2C_RETIMER_ADDR2, 0, 1, &reg, 1);
 #else
 	dm_i2c_write(dev, 0, &reg, 1);
@@ -534,45 +534,45 @@
 
 	/* Set data rate as 10.3125 Gbps */
 	reg = 0x90;
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	i2c_write(I2C_RETIMER_ADDR2, 0x60, 1, &reg, 1);
 #else
 	dm_i2c_write(dev, 0x60, &reg, 1);
 #endif
 	reg = 0xb3;
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	i2c_write(I2C_RETIMER_ADDR2, 0x61, 1, &reg, 1);
 #else
 	dm_i2c_write(dev, 0x61, &reg, 1);
 #endif
 	reg = 0x90;
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	i2c_write(I2C_RETIMER_ADDR2, 0x62, 1, &reg, 1);
 #else
 	dm_i2c_write(dev, 0x62, &reg, 1);
 #endif
 	reg = 0xb3;
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	i2c_write(I2C_RETIMER_ADDR2, 0x63, 1, &reg, 1);
 #else
 	dm_i2c_write(dev, 0x63, &reg, 1);
 #endif
 	reg = 0xcd;
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	i2c_write(I2C_RETIMER_ADDR2, 0x64, 1, &reg, 1);
 #else
 	dm_i2c_write(dev, 0x64, &reg, 1);
 #endif
 
 	/* Select VCO Divider to full rate (000) */
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	i2c_read(I2C_RETIMER_ADDR2, 0x2F, 1, &reg, 1);
 #else
 	dm_i2c_read(dev, 0x2F, &reg, 1);
 #endif
 	reg &= 0x0f;
 	reg |= 0x70;
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	i2c_write(I2C_RETIMER_ADDR2, 0x2F, 1, &reg, 1);
 #else
 	dm_i2c_write(dev, 0x2F, &reg, 1);
@@ -640,7 +640,7 @@
 	u8 chan = PWM_CHANNEL0;
 
 	/* Select the PAGE 0 using PMBus commands PAGE for VDD */
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	ret = i2c_write(I2C_SVDD_MONITOR_ADDR,
 			PMBUS_CMD_PAGE, 1, &chan, 1);
 #else
@@ -658,7 +658,7 @@
 	}
 
 	/* Read the output voltage using PMBus command READ_VOUT */
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	ret = i2c_read(I2C_SVDD_MONITOR_ADDR,
 		       PMBUS_CMD_READ_VOUT, 1, (void *)&vcode, 2);
 #else
@@ -679,7 +679,7 @@
 			svdd & 0xFF, (svdd & 0xFF00) >> 8};
 
 	/* Write the desired voltage code to the SVDD regulator */
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	ret = i2c_write(I2C_SVDD_MONITOR_ADDR,
 			PMBUS_CMD_PAGE_PLUS_WRITE, 1, (void *)&buff, 5);
 #else
@@ -720,7 +720,7 @@
 	printf("SVDD changing of RDB\n");
 
 	/* Read the BRDCFG54 via CLPD */
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	ret = i2c_read(CONFIG_SYS_I2C_FPGA_ADDR,
 		       QIXIS_BRDCFG4_OFFSET, 1, (void *)&brdcfg4, 1);
 #else
@@ -740,7 +740,7 @@
 	brdcfg4 = brdcfg4 | 0x08;
 
 	/* Write to the BRDCFG4 */
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	ret = i2c_write(CONFIG_SYS_I2C_FPGA_ADDR,
 			QIXIS_BRDCFG4_OFFSET, 1, (void *)&brdcfg4, 1);
 #else
diff --git a/board/freescale/ls2080aqds/eth.c b/board/freescale/ls2080aqds/eth.c
index 4b7f855..914cd0a 100644
--- a/board/freescale/ls2080aqds/eth.c
+++ b/board/freescale/ls2080aqds/eth.c
@@ -125,12 +125,12 @@
 	};
 
 	int *riser_phy_addr = &xqsgii_riser_phy_addr[0];
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	struct udevice *udev;
 #endif
 
 	/* Set I2c to Slot 1 */
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	ret = i2c_write(0x77, 0, 0, &a, 1);
 #else
 	ret = i2c_get_chip_for_busnum(0, 0x77, 1, &udev);
@@ -151,7 +151,7 @@
 			mii_bus = 1;
 			dpmac_id = dpmac + 9;
 			a = 0xb;
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 			ret = i2c_write(0x76, 0, 0, &a, 1);
 #else
 			ret = i2c_get_chip_for_busnum(0, 0x76, 1, &udev);
@@ -198,7 +198,7 @@
 				reg_pair[6].val = &ch_b_ctl2[j];
 
 				for (k = 0; k < 10; k++) {
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 					ret = i2c_write(i2c_addr[dpmac],
 							reg_pair[k].addr,
 							1, reg_pair[k].val, 1);
@@ -277,12 +277,12 @@
 	const char *dev = "LS2080A_QDS_MDIO0";
 	int ret = 0;
 	unsigned short value;
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	struct udevice *udev;
 #endif
 
 	/* Set I2c to Slot 1 */
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	ret = i2c_write(0x77, 0, 0, &a, 1);
 #else
 	ret = i2c_get_chip_for_busnum(0, 0x77, 1, &udev);
@@ -347,7 +347,7 @@
 			reg_pair[6].val = &ch_b_ctl2[j];
 
 			for (k = 0; k < 10; k++) {
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 				ret = i2c_write(i2c_phy_addr,
 						reg_pair[k].addr,
 						1, reg_pair[k].val, 1);
diff --git a/board/freescale/ls2080aqds/ls2080aqds.c b/board/freescale/ls2080aqds/ls2080aqds.c
index a6f6897..9572319 100644
--- a/board/freescale/ls2080aqds/ls2080aqds.c
+++ b/board/freescale/ls2080aqds/ls2080aqds.c
@@ -164,7 +164,7 @@
 int select_i2c_ch_pca9547(u8 ch)
 {
 	int ret;
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	struct udevice *dev;
 
 	ret = i2c_get_chip_for_busnum(0, I2C_MUX_PCA_ADDR_PRI, 1, &dev);
@@ -238,7 +238,7 @@
 	select_i2c_ch_pca9547(I2C_MUX_CH_DEFAULT);
 
 #ifdef CONFIG_RTC_ENABLE_32KHZ_OUTPUT
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	rtc_enable_32khz_output(0, CONFIG_SYS_I2C_RTC_ADDR);
 #else
 	rtc_enable_32khz_output();
diff --git a/board/freescale/ls2080ardb/ls2080ardb.c b/board/freescale/ls2080ardb/ls2080ardb.c
index 26ce5a8..c5ae02b 100644
--- a/board/freescale/ls2080ardb/ls2080ardb.c
+++ b/board/freescale/ls2080ardb/ls2080ardb.c
@@ -167,7 +167,7 @@
 {
 	int ret;
 
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	ret = i2c_write(I2C_MUX_PCA_ADDR_PRI, 0, 1, &ch, 1);
 #else
 	struct udevice *dev;
diff --git a/board/freescale/lx2160a/lx2160a.c b/board/freescale/lx2160a/lx2160a.c
index 1d203ec..b32e487 100644
--- a/board/freescale/lx2160a/lx2160a.c
+++ b/board/freescale/lx2160a/lx2160a.c
@@ -83,7 +83,7 @@
 {
 	int ret;
 
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	ret = i2c_write(I2C_MUX_PCA_ADDR_PRI, 0, 1, &ch, 1);
 #else
 	struct udevice *dev;
diff --git a/board/freescale/mpc837xerdb/mpc837xerdb.c b/board/freescale/mpc837xerdb/mpc837xerdb.c
index 81d31f1..624e92e 100644
--- a/board/freescale/mpc837xerdb/mpc837xerdb.c
+++ b/board/freescale/mpc837xerdb/mpc837xerdb.c
@@ -139,8 +139,8 @@
 
 int board_early_init_f(void)
 {
-#ifdef CONFIG_FSL_SERDES
 	immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
+#ifdef CONFIG_FSL_SERDES
 	u32 spridr = in_be32(&immr->sysconf.spridr);
 
 	/* we check only part num, and don't look for CPU revisions */
@@ -167,10 +167,16 @@
 		break;
 	}
 #endif /* CONFIG_FSL_SERDES */
+
+#ifdef CONFIG_FSL_ESDHC
+	clrsetbits_be32(&immr->sysconf.sicrl, SICRL_USB_B, SICRL_USB_B_SD);
+	clrsetbits_be32(&immr->sysconf.sicrh, SICRH_SPI, SICRH_SPI_SD);
+#endif
 	return 0;
 }
 
 #ifdef CONFIG_FSL_ESDHC
+#if !(CONFIG_IS_ENABLED(DM_MMC))
 int board_mmc_init(struct bd_info *bd)
 {
 	struct immap __iomem *im = (struct immap __iomem *)CONFIG_SYS_IMMR;
@@ -189,6 +195,7 @@
 	return fsl_esdhc_mmc_init(bd);
 }
 #endif
+#endif
 
 /*
  * Miscellaneous late-boot configurations
diff --git a/board/freescale/p1010rdb/p1010rdb.c b/board/freescale/p1010rdb/p1010rdb.c
index 7e007da..9043633 100644
--- a/board/freescale/p1010rdb/p1010rdb.c
+++ b/board/freescale/p1010rdb/p1010rdb.c
@@ -141,7 +141,7 @@
 	ccsr_gur_t __iomem *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
 	u8 tmp;
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	struct udevice *dev;
 	int ret;
 #if defined(CONFIG_TARGET_P1010RDB_PA)
@@ -377,7 +377,7 @@
 	u8 val;
 	int bus_num = I2C_PCA9557_BUS_NUM;
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	struct udevice *dev;
 	int ret;
 
@@ -419,7 +419,7 @@
 	printf("Board: %sRDB-PA, ", cpu->name);
 #elif defined(CONFIG_TARGET_P1010RDB_PB)
 	printf("Board: %sRDB-PB, ", cpu->name);
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	struct udevice *dev;
 	int ret;
 
@@ -462,7 +462,7 @@
 	case 0xe:
 		puts("SDHC\n");
 		val = 0x60; /* set pca9557 pin input/output */
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 		dm_i2c_write(dev, 3, &val, 1);
 #else
 		i2c_write(I2C_PCA9557_ADDR2, 3, 1, &val, 1);
diff --git a/board/freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c b/board/freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c
index 4584f01..8273384 100644
--- a/board/freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c
+++ b/board/freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c
@@ -173,7 +173,7 @@
 		in_8(&cpld_data->pcba_rev) & 0x0F);
 
 	/* Initialize i2c early for rom_loc and flash bank information */
-	#if defined(CONFIG_DM_I2C)
+	#if CONFIG_IS_ENABLED(DM_I2C)
 	struct udevice *dev;
 	int ret;
 
diff --git a/board/freescale/t102xrdb/t102xrdb.c b/board/freescale/t102xrdb/t102xrdb.c
index 2770e10..51a36ab 100644
--- a/board/freescale/t102xrdb/t102xrdb.c
+++ b/board/freescale/t102xrdb/t102xrdb.c
@@ -259,7 +259,7 @@
 	u8 tmp;
 	int bus_num = I2C_PCA6408_BUS_NUM;
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	struct udevice *dev;
 	int ret;
 
diff --git a/board/freescale/t208xqds/t208xqds.c b/board/freescale/t208xqds/t208xqds.c
index dedf722..36bb399 100644
--- a/board/freescale/t208xqds/t208xqds.c
+++ b/board/freescale/t208xqds/t208xqds.c
@@ -83,7 +83,7 @@
 {
 	int ret;
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	struct udevice *dev;
 
 	ret = i2c_get_chip_for_busnum(bus_num, I2C_MUX_PCA_ADDR_PRI, 1, &dev);
diff --git a/board/friendlyarm/nanopi2/onewire.c b/board/friendlyarm/nanopi2/onewire.c
index 994befb..fb35663 100644
--- a/board/friendlyarm/nanopi2/onewire.c
+++ b/board/friendlyarm/nanopi2/onewire.c
@@ -35,7 +35,7 @@
 static int lcd_id = -1;
 static unsigned short lcd_fwrev;
 static int current_brightness = -1;
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 static struct udevice *i2c_dev;
 #endif
 
@@ -182,7 +182,7 @@
 	tx[0] = req;
 	tx[1] = crc8_ow(req << 24, 8);
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	if (dm_i2c_write(i2c_dev, 0, tx, 2))
 		return -EIO;
 
@@ -214,7 +214,7 @@
 	unsigned char buf[4];
 	int ret;
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	ret = i2c_get_chip_for_busnum(ONEWIRE_I2C_BUS,
 				      ONEWIRE_I2C_ADDR, 0, &i2c_dev);
 #else
diff --git a/board/keymile/common/ivm.c b/board/keymile/common/ivm.c
index bc8ffd5..9a3a856 100644
--- a/board/keymile/common/ivm.c
+++ b/board/keymile/common/ivm.c
@@ -333,7 +333,7 @@
 int ivm_read_eeprom(unsigned char *buf, int len, int mac_address_offset)
 {
 	int ret;
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	struct udevice *eedev = NULL;
 
 	ret = i2c_get_chip_for_busnum(CONFIG_KM_IVM_BUS,
diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c
index 6b1fa5f..df52a46 100644
--- a/board/raspberrypi/rpi/rpi.c
+++ b/board/raspberrypi/rpi/rpi.c
@@ -157,6 +157,16 @@
 		DTB_DIR "bcm2711-rpi-4-b.dtb",
 		true,
 	},
+	[0x13] = {
+		"400",
+		DTB_DIR "bcm2711-rpi-400.dtb",
+		true,
+	},
+	[0x14] = {
+		"Compute Module 4",
+		DTB_DIR "bcm2711-rpi-cm4.dtb",
+		true,
+	},
 };
 
 static const struct rpi_model rpi_models_old_scheme[] = {
@@ -268,6 +278,13 @@
 
 	gd->ram_size = msg->get_arm_mem.body.resp.mem_size;
 
+	/*
+	 * In some configurations the memory size returned by VideoCore
+	 * is not aligned to the section size, what is mandatory for
+	 * the u-boot's memory setup.
+	 */
+	gd->ram_size &= ~MMU_SECTION_SIZE;
+
 	return 0;
 }
 
diff --git a/board/samsung/common/misc.c b/board/samsung/common/misc.c
index 7d3b984..d48ba7e 100644
--- a/board/samsung/common/misc.c
+++ b/board/samsung/common/misc.c
@@ -117,7 +117,7 @@
 #ifdef CONFIG_LCD_MENU
 static int power_key_pressed(u32 reg)
 {
-#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */
+#if !CONFIG_IS_ENABLED(DM_I2C) /* TODO(maintainer): Convert to driver model */
 	struct pmic *pmic;
 	u32 status;
 	u32 mask;
diff --git a/board/samsung/trats/trats.c b/board/samsung/trats/trats.c
index 2e80dbb..d066876 100644
--- a/board/samsung/trats/trats.c
+++ b/board/samsung/trats/trats.c
@@ -52,7 +52,7 @@
 	return 0;
 }
 
-#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */
+#if !CONFIG_IS_ENABLED(DM_I2C) /* TODO(maintainer): Convert to driver model */
 static void trats_low_power_mode(void)
 {
 	struct exynos4_clock *clk =
@@ -114,7 +114,7 @@
 
 int exynos_power_init(void)
 {
-#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */
+#if !CONFIG_IS_ENABLED(DM_I2C) /* TODO(maintainer): Convert to driver model */
 	int chrg, ret;
 	struct power_battery *pb;
 	struct pmic *p_fg, *p_chrg, *p_muic, *p_bat;
@@ -293,7 +293,7 @@
 
 int g_dnl_board_usb_cable_connected(void)
 {
-#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */
+#if !CONFIG_IS_ENABLED(DM_I2C) /* TODO(maintainer): Convert to driver model */
 	struct pmic *muic = pmic_get("MAX8997_MUIC");
 	if (!muic)
 		return 0;
@@ -415,7 +415,7 @@
 
 int lcd_power(void)
 {
-#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */
+#if !CONFIG_IS_ENABLED(DM_I2C) /* TODO(maintainer): Convert to driver model */
 	int ret = 0;
 	struct pmic *p = pmic_get("MAX8997_PMIC");
 	if (!p)
@@ -439,7 +439,7 @@
 
 int mipi_power(void)
 {
-#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */
+#if !CONFIG_IS_ENABLED(DM_I2C) /* TODO(maintainer): Convert to driver model */
 	int ret = 0;
 	struct pmic *p = pmic_get("MAX8997_PMIC");
 	if (!p)
diff --git a/board/samsung/trats2/trats2.c b/board/samsung/trats2/trats2.c
index 69e0ef1..59e6fbf 100644
--- a/board/samsung/trats2/trats2.c
+++ b/board/samsung/trats2/trats2.c
@@ -129,7 +129,7 @@
 
 int exynos_power_init(void)
 {
-#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */
+#if !CONFIG_IS_ENABLED(DM_I2C) /* TODO(maintainer): Convert to driver model */
 	int chrg;
 	struct power_battery *pb;
 	struct pmic *p_chrg, *p_muic, *p_fg, *p_bat;
@@ -192,7 +192,7 @@
 #ifdef CONFIG_USB_GADGET
 static int s5pc210_phy_control(int on)
 {
-#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */
+#if !CONFIG_IS_ENABLED(DM_I2C) /* TODO(maintainer): Convert to driver model */
 	int ret = 0;
 	unsigned int val;
 	struct pmic *p, *p_pmic, *p_muic;
@@ -269,7 +269,7 @@
 
 int g_dnl_board_usb_cable_connected(void)
 {
-#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */
+#if !CONFIG_IS_ENABLED(DM_I2C) /* TODO(maintainer): Convert to driver model */
 	struct pmic *muic = pmic_get("MAX77693_MUIC");
 	if (!muic)
 		return 0;
@@ -288,7 +288,7 @@
 #ifdef CONFIG_LCD
 int mipi_power(void)
 {
-#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */
+#if !CONFIG_IS_ENABLED(DM_I2C) /* TODO(maintainer): Convert to driver model */
 	struct pmic *p = pmic_get("MAX77686_PMIC");
 
 	/* LDO8 VMIPI_1.0V_AP */
@@ -302,7 +302,7 @@
 
 void exynos_lcd_power_on(void)
 {
-#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */
+#if !CONFIG_IS_ENABLED(DM_I2C) /* TODO(maintainer): Convert to driver model */
 	struct pmic *p = pmic_get("MAX77686_PMIC");
 
 	/* LCD_2.2V_EN: GPC0[1] */
diff --git a/board/socrates/socrates.c b/board/socrates/socrates.c
index 0c9262d..3444af6 100644
--- a/board/socrates/socrates.c
+++ b/board/socrates/socrates.c
@@ -26,14 +26,12 @@
 #include <fdt_support.h>
 #include <asm/io.h>
 #include <i2c.h>
-#include <mb862xx.h>
 #include <video_fb.h>
 #include "upm_table.h"
 
 DECLARE_GLOBAL_DATA_PTR;
 
 extern flash_info_t flash_info[];	/* FLASH chips info */
-extern GraphicDevice mb862xx;
 
 void local_bus_init (void);
 ulong flash_get_size (ulong base, int banknum);
@@ -207,16 +205,6 @@
 	val[i++] = gd->bd->bi_flashstart;
 	val[i++] = gd->bd->bi_flashsize;
 
-#if defined(CONFIG_VIDEO_MB862xx)
-	if (mb862xx.frameAdrs == CONFIG_SYS_LIME_BASE) {
-		/* Fixup LIME mapping */
-		val[i++] = 2;			/* chip select number */
-		val[i++] = 0;			/* always 0 */
-		val[i++] = CONFIG_SYS_LIME_BASE;
-		val[i++] = CONFIG_SYS_LIME_SIZE;
-	}
-#endif
-
 	/* Fixup FPGA mapping */
 	val[i++] = 3;				/* chip select number */
 	val[i++] = 0;				/* always 0 */
diff --git a/board/sunxi/board.c b/board/sunxi/board.c
index c150810..21651a1 100644
--- a/board/sunxi/board.c
+++ b/board/sunxi/board.c
@@ -293,7 +293,7 @@
 		}
 	}
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	/*
 	 * Temporary workaround for enabling I2C clocks until proper sunxi DM
 	 * clk, reset and pinctrl drivers land.
diff --git a/board/ti/am335x/board.c b/board/ti/am335x/board.c
index 2cd0a12..bc1657e 100644
--- a/board/ti/am335x/board.c
+++ b/board/ti/am335x/board.c
@@ -77,7 +77,7 @@
 void do_board_detect(void)
 {
 	enable_i2c0_pin_mux();
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	i2c_init(CONFIG_SYS_OMAP24_I2C_SPEED, CONFIG_SYS_OMAP24_I2C_SLAVE);
 #endif
 	if (ti_i2c_eeprom_am_get(CONFIG_EEPROM_BUS_ADDRESS,
@@ -336,7 +336,7 @@
 	if (board_is_bone() && !strncmp(board_ti_get_rev(), "00A1", 4))
 		return;
 
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	if (i2c_probe(TPS65217_CHIP_PM))
 		return;
 #else
@@ -435,7 +435,7 @@
 	 * 1.10V.  For MPU voltage we need to switch based on
 	 * the frequency we are running at.
 	 */
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	if (i2c_probe(TPS65910_CTRL_I2C_ADDR))
 		return;
 #else
@@ -469,7 +469,7 @@
 
 	if (first_time) {
 		enable_i2c0_pin_mux();
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 		i2c_init(CONFIG_SYS_OMAP24_I2C_SPEED,
 			 CONFIG_SYS_OMAP24_I2C_SLAVE);
 #endif
diff --git a/board/ti/am335x/mux.c b/board/ti/am335x/mux.c
index 6fb2c00..03adcd2 100644
--- a/board/ti/am335x/mux.c
+++ b/board/ti/am335x/mux.c
@@ -333,7 +333,7 @@
 {
 	unsigned short val;
 
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	if (i2c_probe(I2C_CPLD_ADDR))
 		return PROFILE_NONE;
 
diff --git a/board/ti/am43xx/board.c b/board/ti/am43xx/board.c
index ac0d792..e9febb9 100644
--- a/board/ti/am43xx/board.c
+++ b/board/ti/am43xx/board.c
@@ -393,7 +393,7 @@
 {
 	int mpu_vdd, ddr_volt;
 
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	if (i2c_probe(TPS65218_CHIP_PM))
 		return;
 #else
@@ -451,7 +451,7 @@
 {
 	int mpu_vdd;
 
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	if (i2c_probe(TPS62362_I2C_ADDR))
 		return;
 #else
@@ -492,7 +492,7 @@
 
 	if (first_time) {
 		enable_i2c0_pin_mux();
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 		i2c_init(CONFIG_SYS_OMAP24_I2C_SPEED,
 			 CONFIG_SYS_OMAP24_I2C_SLAVE);
 #endif
@@ -632,14 +632,14 @@
 int power_init_board(void)
 {
 	int rc;
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	struct pmic *p = NULL;
 #endif
 	if (board_is_idk()) {
 		rc = power_tps62362_init(0);
 		if (rc)
 			goto done;
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 		p = pmic_get("TPS62362");
 		if (!p || pmic_probe(p))
 			goto done;
@@ -649,7 +649,7 @@
 		rc = power_tps65218_init(0);
 		if (rc)
 			goto done;
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 		p = pmic_get("TPS65218_PMIC");
 		if (!p || pmic_probe(p))
 			goto done;
diff --git a/board/ti/common/board_detect.c b/board/ti/common/board_detect.c
index 8b3b4bc..de92eb0 100644
--- a/board/ti/common/board_detect.c
+++ b/board/ti/common/board_detect.c
@@ -22,7 +22,7 @@
 
 #include "board_detect.h"
 
-#if !defined(CONFIG_DM_I2C)
+#if !CONFIG_IS_ENABLED(DM_I2C)
 /**
  * ti_i2c_eeprom_init - Initialize an i2c bus and probe for a device
  * @i2c_bus: i2c bus number to initialize
@@ -89,7 +89,7 @@
 	u32 hdr_read;
 	int rc;
 
-#if defined(CONFIG_DM_I2C)
+#if CONFIG_IS_ENABLED(DM_I2C)
 	struct udevice *dev;
 	struct udevice *bus;
 
diff --git a/board/ti/ks2_evm/board_k2g.c b/board/ti/ks2_evm/board_k2g.c
index 2be86d6..5229afa 100644
--- a/board/ti/ks2_evm/board_k2g.c
+++ b/board/ti/ks2_evm/board_k2g.c
@@ -259,7 +259,7 @@
 #if defined(CONFIG_DTB_RESELECT)
 static int k2g_alt_board_detect(void)
 {
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	int rc;
 
 	rc = i2c_set_bus_num(1);
diff --git a/board/wandboard/wandboard.c b/board/wandboard/wandboard.c
index 53299c8..da995dd 100644
--- a/board/wandboard/wandboard.c
+++ b/board/wandboard/wandboard.c
@@ -54,7 +54,7 @@
 #define REV_DETECTION		IMX_GPIO_NR(2, 28)
 
 /* Speed defined in Kconfig is only applicable when not using DM_I2C.  */
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 #define I2C1_SPEED_NON_DM	0
 #define I2C2_SPEED_NON_DM	0
 #else
@@ -259,7 +259,7 @@
 
 static int detect_i2c(struct display_info_t const *dev)
 {
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	struct udevice *bus, *udev;
 	int rc;
 
diff --git a/cmd/eeprom.c b/cmd/eeprom.c
index 7fa62bb..b3fd37c 100644
--- a/cmd/eeprom.c
+++ b/cmd/eeprom.c
@@ -61,7 +61,7 @@
 #endif
 #endif
 
-#if defined(CONFIG_DM_I2C)
+#if CONFIG_IS_ENABLED(DM_I2C)
 static int eeprom_i2c_bus;
 #endif
 
@@ -73,7 +73,7 @@
 void eeprom_init(int bus)
 {
 	/* I2C EEPROM */
-#if defined(CONFIG_DM_I2C)
+#if CONFIG_IS_ENABLED(DM_I2C)
 	eeprom_i2c_bus = bus;
 #elif defined(CONFIG_SYS_I2C)
 	if (bus >= 0)
@@ -132,7 +132,7 @@
 {
 	int ret = 0;
 
-#if defined(CONFIG_DM_I2C)
+#if CONFIG_IS_ENABLED(DM_I2C)
 	struct udevice *dev;
 
 	ret = i2c_get_chip_for_busnum(eeprom_i2c_bus, addr[0],
diff --git a/cmd/i2c.c b/cmd/i2c.c
index aae2dd4..5d0e207 100644
--- a/cmd/i2c.c
+++ b/cmd/i2c.c
@@ -124,13 +124,13 @@
  * For legacy code, this is not stored, so we need to use a suitable
  * default.
  */
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 #define DEFAULT_ADDR_LEN	(-1)
 #else
 #define DEFAULT_ADDR_LEN	1
 #endif
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 static struct udevice *i2c_cur_bus;
 
 static int cmd_i2c_set_bus_num(unsigned int busnum)
@@ -209,7 +209,7 @@
  *
  * Returns I2C bus speed in Hz.
  */
-#if !defined(CONFIG_SYS_I2C) && !defined(CONFIG_DM_I2C)
+#if !defined(CONFIG_SYS_I2C) && !CONFIG_IS_ENABLED(DM_I2C)
 /*
  * TODO: Implement architecture-specific get/set functions
  * Should go away, if we switched completely to new multibus support
@@ -298,7 +298,7 @@
 	int alen;
 	u_char  *memaddr;
 	int ret;
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	struct udevice *dev;
 #endif
 
@@ -329,7 +329,7 @@
 	 */
 	memaddr = (u_char *)simple_strtoul(argv[4], NULL, 16);
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	ret = i2c_get_cur_bus_chip(chip, &dev);
 	if (!ret && alen != -1)
 		ret = i2c_set_chip_offset_len(dev, alen);
@@ -352,7 +352,7 @@
 	int alen;
 	u_char  *memaddr;
 	int ret;
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	struct udevice *dev;
 	struct dm_i2c_chip *i2c_chip;
 #endif
@@ -384,7 +384,7 @@
 	 */
 	length = simple_strtoul(argv[4], NULL, 16);
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	ret = i2c_get_cur_bus_chip(chip, &dev);
 	if (!ret && alen != -1)
 		ret = i2c_set_chip_offset_len(dev, alen);
@@ -402,7 +402,7 @@
 		 * a page boundary. No write delay upon completion, take this
 		 * into account if linking commands.
 		 */
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 		i2c_chip->flags &= ~DM_I2C_CHIP_WR_ADDRESS;
 		ret = dm_i2c_write(dev, devaddr, memaddr, length);
 #else
@@ -416,7 +416,7 @@
 		 * write transactions of one byte each
 		 */
 		while (length-- > 0) {
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 			i2c_chip->flags |= DM_I2C_CHIP_WR_ADDRESS;
 			ret = dm_i2c_write(dev, devaddr++, memaddr++, 1);
 #else
@@ -435,7 +435,7 @@
 	return 0;
 }
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 static int do_i2c_flags(struct cmd_tbl *cmdtp, int flag, int argc,
 			char *const argv[])
 {
@@ -520,7 +520,7 @@
 	int alen;
 	int	j, nbytes, linebytes;
 	int ret;
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	struct udevice *dev;
 #endif
 
@@ -562,7 +562,7 @@
 			length = simple_strtoul(argv[3], NULL, 16);
 	}
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	ret = i2c_get_cur_bus_chip(chip, &dev);
 	if (!ret && alen != -1)
 		ret = i2c_set_chip_offset_len(dev, alen);
@@ -583,7 +583,7 @@
 
 		linebytes = (nbytes > DISP_LINE_LEN) ? DISP_LINE_LEN : nbytes;
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 		ret = dm_i2c_read(dev, addr, linebuf, linebytes);
 #else
 		ret = i2c_read(chip, addr, alen, linebuf, linebytes);
@@ -641,7 +641,7 @@
 	uchar	byte;
 	int	count;
 	int ret;
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	struct udevice *dev;
 #endif
 
@@ -661,7 +661,7 @@
 	if (alen > 3)
 		return CMD_RET_USAGE;
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	ret = i2c_get_cur_bus_chip(chip, &dev);
 	if (!ret && alen != -1)
 		ret = i2c_set_chip_offset_len(dev, alen);
@@ -682,7 +682,7 @@
 		count = 1;
 
 	while (count-- > 0) {
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 		ret = dm_i2c_write(dev, addr++, &byte, 1);
 #else
 		ret = i2c_write(chip, addr++, alen, &byte, 1);
@@ -730,7 +730,7 @@
 	ulong	crc;
 	ulong	err;
 	int ret = 0;
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	struct udevice *dev;
 #endif
 
@@ -750,7 +750,7 @@
 	if (alen > 3)
 		return CMD_RET_USAGE;
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	ret = i2c_get_cur_bus_chip(chip, &dev);
 	if (!ret && alen != -1)
 		ret = i2c_set_chip_offset_len(dev, alen);
@@ -770,7 +770,7 @@
 	crc = 0;
 	err = 0;
 	while (count-- > 0) {
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 		ret = dm_i2c_read(dev, addr, &byte, 1);
 #else
 		ret = i2c_read(chip, addr, alen, &byte, 1);
@@ -814,7 +814,7 @@
 	int	size = 1;
 	int	nbytes;
 	int ret;
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	struct udevice *dev;
 #endif
 
@@ -851,7 +851,7 @@
 			return CMD_RET_USAGE;
 	}
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	ret = i2c_get_cur_bus_chip(chip, &dev);
 	if (!ret && alen != -1)
 		ret = i2c_set_chip_offset_len(dev, alen);
@@ -865,7 +865,7 @@
 	 */
 	do {
 		printf("%08lx:", addr);
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 		ret = dm_i2c_read(dev, addr, (uchar *)&data, size);
 #else
 		ret = i2c_read(chip, addr, alen, (uchar *)&data, size);
@@ -912,7 +912,7 @@
 				 * good enough to not time out
 				 */
 				bootretry_reset_cmd_timeout();
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 				ret = dm_i2c_write(dev, addr, (uchar *)&data,
 						   size);
 #else
@@ -964,7 +964,7 @@
 	unsigned int bus = GET_BUS_NUM;
 #endif	/* NOPROBES */
 	int ret;
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	struct udevice *bus, *dev;
 
 	if (i2c_get_cur_bus(&bus))
@@ -990,7 +990,7 @@
 		if (skip)
 			continue;
 #endif
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 		ret = dm_i2c_probe(bus, j, 0, &dev);
 #else
 		ret = i2c_probe(j);
@@ -1039,7 +1039,7 @@
 	u_char	bytes[16];
 	int	delay;
 	int ret;
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	struct udevice *dev;
 #endif
 
@@ -1058,7 +1058,7 @@
 	alen = get_alen(argv[2], DEFAULT_ADDR_LEN);
 	if (alen > 3)
 		return CMD_RET_USAGE;
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	ret = i2c_get_cur_bus_chip(chip, &dev);
 	if (!ret && alen != -1)
 		ret = i2c_set_chip_offset_len(dev, alen);
@@ -1084,7 +1084,7 @@
 	 * Run the loop...
 	 */
 	while (1) {
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 		ret = dm_i2c_read(dev, addr, bytes, length);
 #else
 		ret = i2c_read(chip, addr, alen, bytes, length);
@@ -1165,7 +1165,7 @@
 	u_char	data[128];
 	u_char	cksum;
 	int	j, ret;
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	struct udevice *dev;
 #endif
 
@@ -1221,7 +1221,7 @@
 	 */
 	chip = simple_strtoul (argv[1], NULL, 16);
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	ret = i2c_get_cur_bus_chip(chip, &dev);
 	if (!ret)
 		ret = dm_i2c_read(dev, 0, data, sizeof(data));
@@ -1664,7 +1664,7 @@
 	uint chip;
 	struct edid1_info edid;
 	int ret;
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	struct udevice *dev;
 #endif
 
@@ -1674,7 +1674,7 @@
 	}
 
 	chip = simple_strtoul(argv[1], NULL, 16);
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	ret = i2c_get_cur_bus_chip(chip, &dev);
 	if (!ret)
 		ret = dm_i2c_read(dev, 0, (uchar *)&edid, sizeof(edid));
@@ -1695,7 +1695,7 @@
 }
 #endif /* CONFIG_I2C_EDID */
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 static void show_bus(struct udevice *bus)
 {
 	struct udevice *dev;
@@ -1725,13 +1725,13 @@
  *
  * Returns zero always.
  */
-#if defined(CONFIG_SYS_I2C) || defined(CONFIG_DM_I2C)
+#if defined(CONFIG_SYS_I2C) || CONFIG_IS_ENABLED(DM_I2C)
 static int do_i2c_show_bus(struct cmd_tbl *cmdtp, int flag, int argc,
 			   char *const argv[])
 {
 	if (argc == 1) {
 		/* show all busses */
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 		struct udevice *bus;
 		struct uclass *uc;
 		int ret;
@@ -1766,7 +1766,7 @@
 
 		/* show specific bus */
 		i = simple_strtoul(argv[1], NULL, 10);
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 		struct udevice *bus;
 		int ret;
 
@@ -1812,7 +1812,7 @@
  * on error.
  */
 #if defined(CONFIG_SYS_I2C) || defined(CONFIG_I2C_MULTI_BUS) || \
-		defined(CONFIG_DM_I2C)
+		CONFIG_IS_ENABLED(DM_I2C)
 static int do_i2c_bus_num(struct cmd_tbl *cmdtp, int flag, int argc,
 			  char *const argv[])
 {
@@ -1821,7 +1821,7 @@
 
 	if (argc == 1) {
 		/* querying current setting */
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 		struct udevice *bus;
 
 		if (!i2c_get_cur_bus(&bus))
@@ -1841,7 +1841,7 @@
 		}
 #endif
 		printf("Setting bus to %d\n", bus_no);
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 		ret = cmd_i2c_set_bus_num(bus_no);
 #else
 		ret = i2c_set_bus_num(bus_no);
@@ -1869,14 +1869,14 @@
 {
 	int speed, ret=0;
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	struct udevice *bus;
 
 	if (i2c_get_cur_bus(&bus))
 		return 1;
 #endif
 	if (argc == 1) {
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 		speed = dm_i2c_get_bus_speed(bus);
 #else
 		speed = i2c_get_bus_speed();
@@ -1886,7 +1886,7 @@
 	} else {
 		speed = simple_strtoul(argv[1], NULL, 10);
 		printf("Setting bus speed to %d Hz\n", speed);
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 		ret = dm_i2c_set_bus_speed(bus, speed);
 #else
 		ret = i2c_set_bus_speed(speed);
@@ -1942,7 +1942,7 @@
 static int do_i2c_reset(struct cmd_tbl *cmdtp, int flag, int argc,
 			char *const argv[])
 {
-#if defined(CONFIG_DM_I2C)
+#if CONFIG_IS_ENABLED(DM_I2C)
 	struct udevice *bus;
 
 	if (i2c_get_cur_bus(&bus))
@@ -1960,12 +1960,12 @@
 }
 
 static struct cmd_tbl cmd_i2c_sub[] = {
-#if defined(CONFIG_SYS_I2C) || defined(CONFIG_DM_I2C)
+#if defined(CONFIG_SYS_I2C) || CONFIG_IS_ENABLED(DM_I2C)
 	U_BOOT_CMD_MKENT(bus, 1, 1, do_i2c_show_bus, "", ""),
 #endif
 	U_BOOT_CMD_MKENT(crc32, 3, 1, do_i2c_crc, "", ""),
 #if defined(CONFIG_SYS_I2C) || \
-	defined(CONFIG_I2C_MULTI_BUS) || defined(CONFIG_DM_I2C)
+	defined(CONFIG_I2C_MULTI_BUS) || CONFIG_IS_ENABLED(DM_I2C)
 	U_BOOT_CMD_MKENT(dev, 1, 1, do_i2c_bus_num, "", ""),
 #endif  /* CONFIG_I2C_MULTI_BUS */
 #if defined(CONFIG_I2C_EDID)
@@ -1979,7 +1979,7 @@
 	U_BOOT_CMD_MKENT(probe, 0, 1, do_i2c_probe, "", ""),
 	U_BOOT_CMD_MKENT(read, 5, 1, do_i2c_read, "", ""),
 	U_BOOT_CMD_MKENT(write, 6, 0, do_i2c_write, "", ""),
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	U_BOOT_CMD_MKENT(flags, 2, 1, do_i2c_flags, "", ""),
 	U_BOOT_CMD_MKENT(olen, 2, 1, do_i2c_olen, "", ""),
 #endif
@@ -2036,13 +2036,13 @@
 /***************************************************/
 #ifdef CONFIG_SYS_LONGHELP
 static char i2c_help_text[] =
-#if defined(CONFIG_SYS_I2C) || defined(CONFIG_DM_I2C)
+#if defined(CONFIG_SYS_I2C) || CONFIG_IS_ENABLED(DM_I2C)
 	"bus [muxtype:muxaddr:muxchannel] - show I2C bus info\n"
 	"i2c " /* That's the prefix for the crc32 command below. */
 #endif
 	"crc32 chip address[.0, .1, .2] count - compute CRC32 checksum\n"
 #if defined(CONFIG_SYS_I2C) || \
-	defined(CONFIG_I2C_MULTI_BUS) || defined(CONFIG_DM_I2C)
+	defined(CONFIG_I2C_MULTI_BUS) || CONFIG_IS_ENABLED(DM_I2C)
 	"i2c dev [dev] - show or set current I2C bus\n"
 #endif  /* CONFIG_I2C_MULTI_BUS */
 #if defined(CONFIG_I2C_EDID)
@@ -2057,7 +2057,7 @@
 	"i2c read chip address[.0, .1, .2] length memaddress - read to memory\n"
 	"i2c write memaddress chip address[.0, .1, .2] length [-s] - write memory\n"
 	"          to I2C; the -s option selects bulk write in a single transaction\n"
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	"i2c flags chip [flags] - set or get chip flags\n"
 	"i2c olen chip [offset_length] - set or get chip offset length\n"
 #endif
diff --git a/cmd/mmc.c b/cmd/mmc.c
index 1529a3e..cb6b59f 100644
--- a/cmd/mmc.c
+++ b/cmd/mmc.c
@@ -1017,13 +1017,13 @@
 	"  Power cycling is required to initialize partitions after set to complete.\n"
 #endif
 #ifdef CONFIG_SUPPORT_EMMC_BOOT
-	"mmc bootbus dev boot_bus_width reset_boot_bus_width boot_mode\n"
+	"mmc bootbus <dev> <boot_bus_width> <reset_boot_bus_width> <boot_mode>\n"
 	" - Set the BOOT_BUS_WIDTH field of the specified device\n"
 	"mmc bootpart-resize <dev> <boot part size MB> <RPMB part size MB>\n"
 	" - Change sizes of boot and RPMB partitions of specified device\n"
-	"mmc partconf dev [boot_ack boot_partition partition_access]\n"
+	"mmc partconf <dev> [boot_ack boot_partition partition_access]\n"
 	" - Show or change the bits of the PARTITION_CONFIG field of the specified device\n"
-	"mmc rst-function dev value\n"
+	"mmc rst-function <dev> <value>\n"
 	" - Change the RST_n_FUNCTION field of the specified device\n"
 	"   WARNING: This is a write-once field and 0 / 1 / 2 are the only valid values.\n"
 #endif
diff --git a/common/console.c b/common/console.c
index 567273a..561cdf3 100644
--- a/common/console.c
+++ b/common/console.c
@@ -233,9 +233,10 @@
 struct stdio_dev **console_devices[MAX_FILES];
 int cd_count[MAX_FILES];
 
-static void __maybe_unused console_devices_set(int file, struct stdio_dev *dev)
+static void console_devices_set(int file, struct stdio_dev *dev)
 {
 	console_devices[file][0] = dev;
+	cd_count[file] = 1;
 }
 
 /**
@@ -251,15 +252,14 @@
  */
 static bool console_needs_start_stop(int file, struct stdio_dev *sdev)
 {
-	int i, j;
+	int i;
 
 	for (i = 0; i < ARRAY_SIZE(cd_count); i++) {
 		if (i == file)
 			continue;
 
-		for (j = 0; j < cd_count[i]; j++)
-			if (console_devices[i][j] == sdev)
-				return false;
+		if (iomux_match_device(console_devices[i], cd_count[i], sdev) >= 0)
+			return false;
 	}
 	return true;
 }
@@ -293,8 +293,7 @@
 	int prev;
 
 	prev = disable_ctrlc(1);
-	for (i = 0; i < cd_count[file]; i++) {
-		dev = console_devices[file][i];
+	for_each_console_dev(i, file, dev) {
 		if (dev->tstc != NULL) {
 			ret = dev->tstc(dev);
 			if (ret > 0) {
@@ -314,8 +313,7 @@
 	int i;
 	struct stdio_dev *dev;
 
-	for (i = 0; i < cd_count[file]; i++) {
-		dev = console_devices[file][i];
+	for_each_console_dev(i, file, dev) {
 		if (dev->putc != NULL)
 			dev->putc(dev, c);
 	}
@@ -334,11 +332,9 @@
 	int i;
 	struct stdio_dev *dev;
 
-	for (i = 0; i < cd_count[file]; i++) {
-		bool is_serial;
+	for_each_console_dev(i, file, dev) {
+		bool is_serial = console_dev_is_serial(dev);
 
-		dev = console_devices[file][i];
-		is_serial = console_dev_is_serial(dev);
 		if (dev->puts && serial_only == is_serial)
 			dev->puts(dev, s);
 	}
@@ -354,8 +350,7 @@
 	int i;
 	struct stdio_dev *dev;
 
-	for (i = 0; i < cd_count[file]; i++) {
-		dev = console_devices[file][i];
+	for_each_console_dev(i, file, dev) {
 		if (dev->puts != NULL)
 			dev->puts(dev, s);
 	}
@@ -369,7 +364,7 @@
 #endif
 #else
 
-static void __maybe_unused console_devices_set(int file, struct stdio_dev *dev)
+static void console_devices_set(int file, struct stdio_dev *dev)
 {
 }
 
@@ -417,6 +412,12 @@
 #endif
 #endif /* CONIFIG_IS_ENABLED(CONSOLE_MUX) */
 
+static void __maybe_unused console_setfile_and_devices(int file, struct stdio_dev *dev)
+{
+	console_setfile(file, dev);
+	console_devices_set(file, dev);
+}
+
 int console_start(int file, struct stdio_dev *sdev)
 {
 	int error;
@@ -855,17 +856,9 @@
 	struct stdio_dev *dev;
 
 	/* Check for valid file */
-	switch (file) {
-	case stdin:
-		flag = DEV_FLAGS_INPUT;
-		break;
-	case stdout:
-	case stderr:
-		flag = DEV_FLAGS_OUTPUT;
-		break;
-	default:
-		return -1;
-	}
+	flag = stdio_file_to_flags(file);
+	if (flag < 0)
+		return flag;
 
 	/* Check for valid device name */
 
@@ -1079,17 +1072,13 @@
 
 	/* Initializes output console first */
 	if (outputdev != NULL) {
-		console_setfile(stdout, outputdev);
-		console_setfile(stderr, outputdev);
-		console_devices_set(stdout, outputdev);
-		console_devices_set(stderr, outputdev);
+		console_setfile_and_devices(stdout, outputdev);
+		console_setfile_and_devices(stderr, outputdev);
 	}
 
 	/* Initializes input console */
-	if (inputdev != NULL) {
-		console_setfile(stdin, inputdev);
-		console_devices_set(stdin, inputdev);
-	}
+	if (inputdev != NULL)
+		console_setfile_and_devices(stdin, inputdev);
 
 	if (!IS_ENABLED(CONFIG_SYS_CONSOLE_INFO_QUIET))
 		stdio_print_current_devices();
diff --git a/common/fdt_support.c b/common/fdt_support.c
index 638eca9..08d540b 100644
--- a/common/fdt_support.c
+++ b/common/fdt_support.c
@@ -127,16 +127,9 @@
 	return offset;
 }
 
-/* rename to CONFIG_OF_STDOUT_PATH ? */
-#if defined(OF_STDOUT_PATH)
+#if defined(CONFIG_OF_STDOUT_VIA_ALIAS) && defined(CONFIG_CONS_INDEX)
 static int fdt_fixup_stdout(void *fdt, int chosenoff)
 {
-	return fdt_setprop(fdt, chosenoff, "linux,stdout-path",
-			      OF_STDOUT_PATH, strlen(OF_STDOUT_PATH) + 1);
-}
-#elif defined(CONFIG_OF_STDOUT_VIA_ALIAS) && defined(CONFIG_CONS_INDEX)
-static int fdt_fixup_stdout(void *fdt, int chosenoff)
-{
 	int err;
 	int aliasoff;
 	char sername[9] = { 0 };
@@ -1344,6 +1337,79 @@
 	return __of_translate_address(blob, node_offset, in_addr, "dma-ranges");
 }
 
+int fdt_get_dma_range(const void *blob, int node, phys_addr_t *cpu,
+		      dma_addr_t *bus, u64 *size)
+{
+	bool found_dma_ranges = false;
+	struct of_bus *bus_node;
+	const fdt32_t *ranges;
+	int na, ns, pna, pns;
+	int parent = node;
+	int ret = 0;
+	int len;
+
+	/* Find the closest dma-ranges property */
+	while (parent >= 0) {
+		ranges = fdt_getprop(blob, parent, "dma-ranges", &len);
+
+		/* Ignore empty ranges, they imply no translation required */
+		if (ranges && len > 0)
+			break;
+
+		/* Once we find 'dma-ranges', then a missing one is an error */
+		if (found_dma_ranges && !ranges) {
+			ret = -EINVAL;
+			goto out;
+		}
+
+		if (ranges)
+			found_dma_ranges = true;
+
+		parent = fdt_parent_offset(blob, parent);
+	}
+
+	if (!ranges || parent < 0) {
+		debug("no dma-ranges found for node %s\n",
+		      fdt_get_name(blob, node, NULL));
+		ret = -ENOENT;
+		goto out;
+	}
+
+	/* switch to that node */
+	node = parent;
+	parent = fdt_parent_offset(blob, node);
+	if (parent < 0) {
+		printf("Found dma-ranges in root node, shoudln't happen\n");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	/* Get the address sizes both for the bus and its parent */
+	bus_node = of_match_bus(blob, node);
+	bus_node->count_cells(blob, node, &na, &ns);
+	if (!OF_CHECK_COUNTS(na, ns)) {
+		printf("%s: Bad cell count for %s\n", __FUNCTION__,
+		       fdt_get_name(blob, node, NULL));
+		return -EINVAL;
+		goto out;
+	}
+
+	bus_node = of_match_bus(blob, parent);
+	bus_node->count_cells(blob, parent, &pna, &pns);
+	if (!OF_CHECK_COUNTS(pna, pns)) {
+		printf("%s: Bad cell count for %s\n", __FUNCTION__,
+		       fdt_get_name(blob, parent, NULL));
+		return -EINVAL;
+		goto out;
+	}
+
+	*bus = fdt_read_number(ranges, na);
+	*cpu = fdt_translate_dma_address(blob, node, ranges + na);
+	*size = fdt_read_number(ranges + na + pna, ns);
+out:
+	return ret;
+}
+
 /**
  * fdt_node_offset_by_compat_reg: Find a node that matches compatiable and
  * who's reg property matches a physical cpu address
diff --git a/common/iomux.c b/common/iomux.c
index 15bf533..b9088aa 100644
--- a/common/iomux.c
+++ b/common/iomux.c
@@ -15,18 +15,26 @@
 	int i;
 	struct stdio_dev *dev;
 
-	for (i = 0; i < cd_count[console]; i++) {
-		dev = console_devices[console][i];
+	for_each_console_dev(i, console, dev)
 		printf("%s ", dev->name);
-	}
 	printf("\n");
 }
 
+int iomux_match_device(struct stdio_dev **set, const int n, struct stdio_dev *sdev)
+{
+	int i;
+
+	for (i = 0; i < n; i++)
+		if (sdev == set[i])
+			return i;
+	return -ENOENT;
+}
+
 /* This tries to preserve the old list if an error occurs. */
 int iomux_doenv(const int console, const char *arg)
 {
 	char *console_args, *temp, **start;
-	int i, j, k, io_flag, cs_idx, repeat;
+	int i, j, io_flag, cs_idx, repeat;
 	struct stdio_dev **cons_set, **old_set;
 	struct stdio_dev *dev;
 
@@ -75,15 +83,8 @@
 		return 1;
 	}
 
-	switch (console) {
-	case stdin:
-		io_flag = DEV_FLAGS_INPUT;
-		break;
-	case stdout:
-	case stderr:
-		io_flag = DEV_FLAGS_OUTPUT;
-		break;
-	default:
+	io_flag = stdio_file_to_flags(console);
+	if (io_flag < 0) {
 		free(start);
 		free(console_args);
 		free(cons_set);
@@ -103,14 +104,8 @@
 		/*
 		 * Prevent multiple entries for a device.
 		 */
-		 repeat = 0;
-		 for (k = 0; k < cs_idx; k++) {
-			if (dev == cons_set[k]) {
-				repeat++;
-				break;
-			}
-		 }
-		 if (repeat)
+		 repeat = iomux_match_device(cons_set, cs_idx, dev);
+		 if (repeat >= 0)
 			continue;
 		/*
 		 * Try assigning the specified device.
@@ -136,10 +131,7 @@
 
 	/* Stop dropped consoles */
 	for (i = 0; i < repeat; i++) {
-		for (j = 0; j < cs_idx; j++) {
-			if (old_set[i] == cons_set[j])
-				break;
-		}
+		j = iomux_match_device(cons_set, cs_idx, old_set[i]);
 		if (j == cs_idx)
 			console_stop(console, old_set[i]);
 	}
@@ -147,4 +139,37 @@
 	free(old_set);
 	return 0;
 }
+
+int iomux_replace_device(const int console, const char *old, const char *new)
+{
+	struct stdio_dev *dev;
+	char *arg = NULL;	/* Initial empty list */
+	int size = 1;		/* For NUL terminator */
+	int i, ret;
+
+	for_each_console_dev(i, console, dev) {
+		const char *name = strcmp(dev->name, old) ? dev->name : new;
+		char *tmp;
+
+		/* Append name with a ',' (comma) separator */
+		tmp = realloc(arg, size + strlen(name) + 1);
+		if (!tmp) {
+			free(arg);
+			return -ENOMEM;
+		}
+
+		strcat(tmp, ",");
+		strcat(tmp, name);
+
+		arg = tmp;
+		size = strlen(tmp) + 1;
+	}
+
+	ret = iomux_doenv(console, arg);
+	if (ret)
+		ret = -EINVAL;
+
+	free(arg);
+	return ret;
+}
 #endif /* CONSOLE_MUX */
diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c
index a2612b4..75c8ff0 100644
--- a/common/spl/spl_fit.c
+++ b/common/spl/spl_fit.c
@@ -27,7 +27,14 @@
 #define CONFIG_SYS_BOOTM_LEN	(64 << 20)
 #endif
 
-__weak void board_spl_fit_post_load(ulong load_addr, size_t length)
+struct spl_fit_info {
+	const void *fit;	/* Pointer to a valid FIT blob */
+	size_t ext_data_offset;	/* Offset to FIT external data (end of FIT) */
+	int images_node;	/* FDT offset to "/images" node */
+	int conf_node;		/* FDT offset to selected configuration node */
+};
+
+__weak void board_spl_fit_post_load(const void *fit)
 {
 }
 
@@ -71,32 +78,17 @@
  *
  * Return:	0 on success, or a negative error number
  */
-static int spl_fit_get_image_name(const void *fit, int images,
+static int spl_fit_get_image_name(const struct spl_fit_info *ctx,
 				  const char *type, int index,
 				  const char **outname)
 {
 	struct udevice *sysinfo;
 	const char *name, *str;
 	__maybe_unused int node;
-	int conf_node;
 	int len, i;
 	bool found = true;
 
-	conf_node = fit_find_config_node(fit);
-	if (conf_node < 0) {
-#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
-		printf("No matching DT out of these options:\n");
-		for (node = fdt_first_subnode(fit, conf_node);
-		     node >= 0;
-		     node = fdt_next_subnode(fit, node)) {
-			name = fdt_getprop(fit, node, "description", &len);
-			printf("   %s\n", name);
-		}
-#endif
-		return conf_node;
-	}
-
-	name = fdt_getprop(fit, conf_node, type, &len);
+	name = fdt_getprop(ctx->fit, ctx->conf_node, type, &len);
 	if (!name) {
 		debug("cannot find property '%s': %d\n", type, len);
 		return -EINVAL;
@@ -130,11 +122,11 @@
 			 * node name.
 			 */
 			int node;
-			int images = fdt_path_offset(fit, FIT_IMAGES_PATH);
+			int images = fdt_path_offset(ctx->fit, FIT_IMAGES_PATH);
 
-			node = find_node_from_desc(fit, images, str);
+			node = find_node_from_desc(ctx->fit, images, str);
 			if (node > 0)
-				str = fdt_get_name(fit, node, NULL);
+				str = fdt_get_name(ctx->fit, node, NULL);
 
 			found = true;
 		}
@@ -161,20 +153,20 @@
  * Return:	the node offset of the respective image node or a negative
  *		error number.
  */
-static int spl_fit_get_image_node(const void *fit, int images,
+static int spl_fit_get_image_node(const struct spl_fit_info *ctx,
 				  const char *type, int index)
 {
 	const char *str;
 	int err;
 	int node;
 
-	err = spl_fit_get_image_name(fit, images, type, index, &str);
+	err = spl_fit_get_image_name(ctx, type, index, &str);
 	if (err)
 		return err;
 
 	debug("%s: '%s'\n", type, str);
 
-	node = fdt_subnode_offset(fit, images, str);
+	node = fdt_subnode_offset(ctx->fit, ctx->images_node, str);
 	if (node < 0) {
 		pr_err("cannot find image node '%s': %d\n", str, node);
 		return -EINVAL;
@@ -225,10 +217,7 @@
  * spl_load_fit_image(): load the image described in a certain FIT node
  * @info:	points to information about the device to load data from
  * @sector:	the start sector of the FIT image on the device
- * @fit:	points to the flattened device tree blob describing the FIT
- *		image
- * @base_offset: the beginning of the data area containing the actual
- *		image data, relative to the beginning of the FIT
+ * @ctx:	points to the FIT context structure
  * @node:	offset of the DT node describing the image to load (relative
  *		to @fit)
  * @image_info:	will be filled with information about the loaded image
@@ -239,7 +228,7 @@
  * Return:	0 on success or a negative error number.
  */
 static int spl_load_fit_image(struct spl_load_info *info, ulong sector,
-			      void *fit, ulong base_offset, int node,
+			      const struct spl_fit_info *ctx, int node,
 			      struct spl_image_info *image_info)
 {
 	int offset;
@@ -253,6 +242,7 @@
 	int align_len = ARCH_DMA_MINALIGN - 1;
 	uint8_t image_comp = -1, type = -1;
 	const void *data;
+	const void *fit = ctx->fit;
 	bool external_data = false;
 
 	if (IS_ENABLED(CONFIG_SPL_FPGA) ||
@@ -274,7 +264,7 @@
 	if (!fit_image_get_data_position(fit, node, &offset)) {
 		external_data = true;
 	} else if (!fit_image_get_data_offset(fit, node, &offset)) {
-		offset += base_offset;
+		offset += ctx->ext_data_offset;
 		external_data = true;
 	}
 
@@ -308,18 +298,16 @@
 		src = (void *)data;
 	}
 
-#ifdef CONFIG_SPL_FIT_SIGNATURE
-	printf("## Checking hash(es) for Image %s ... ",
-	       fit_get_name(fit, node, NULL));
-	if (!fit_image_verify_with_data(fit, node,
-					 src, length))
-		return -EPERM;
-	puts("OK\n");
-#endif
+	if (CONFIG_IS_ENABLED(FIT_SIGNATURE)) {
+		printf("## Checking hash(es) for Image %s ... ",
+		       fit_get_name(fit, node, NULL));
+		if (!fit_image_verify_with_data(fit, node, src, length))
+			return -EPERM;
+		puts("OK\n");
+	}
 
-#ifdef CONFIG_SPL_FIT_IMAGE_POST_PROCESS
-	board_fit_image_post_process(&src, &length);
-#endif
+	if (CONFIG_IS_ENABLED(FIT_IMAGE_POST_PROCESS))
+		board_fit_image_post_process(&src, &length);
 
 	if (IS_ENABLED(CONFIG_SPL_GZIP) && image_comp == IH_COMP_GZIP) {
 		size = length;
@@ -348,9 +336,21 @@
 	return 0;
 }
 
+static bool os_takes_devicetree(uint8_t os)
+{
+	switch (os) {
+	case IH_OS_U_BOOT:
+		return true;
+	case IH_OS_LINUX:
+		return IS_ENABLED(CONFIG_SPL_OS_BOOT);
+	default:
+		return false;
+	}
+}
+
 static int spl_fit_append_fdt(struct spl_image_info *spl_image,
 			      struct spl_load_info *info, ulong sector,
-			      void *fit, int images, ulong base_offset)
+			      const struct spl_fit_info *ctx)
 {
 	struct spl_image_info image_info;
 	int node, ret = 0, index = 0;
@@ -362,7 +362,7 @@
 	image_info.load_addr = spl_image->load_addr + spl_image->size;
 
 	/* Figure out which device tree the board wants to use */
-	node = spl_fit_get_image_node(fit, images, FIT_FDT_PROP, index++);
+	node = spl_fit_get_image_node(ctx, FIT_FDT_PROP, index++);
 	if (node < 0) {
 		debug("%s: cannot find FDT node\n", __func__);
 
@@ -376,7 +376,7 @@
 		else
 			return node;
 	} else {
-		ret = spl_load_fit_image(info, sector, fit, base_offset, node,
+		ret = spl_load_fit_image(info, sector, ctx, node,
 					 &image_info);
 		if (ret < 0)
 			return ret;
@@ -384,13 +384,14 @@
 
 	/* Make the load-address of the FDT available for the SPL framework */
 	spl_image->fdt_addr = (void *)image_info.load_addr;
-#if !CONFIG_IS_ENABLED(FIT_IMAGE_TINY)
+	if (CONFIG_IS_ENABLED(FIT_IMAGE_TINY))
+		return 0;
+
 	if (CONFIG_IS_ENABLED(LOAD_FIT_APPLY_OVERLAY)) {
 		void *tmpbuffer = NULL;
 
 		for (; ; index++) {
-			node = spl_fit_get_image_node(fit, images, FIT_FDT_PROP,
-						      index);
+			node = spl_fit_get_image_node(ctx, FIT_FDT_PROP, index);
 			if (node == -E2BIG) {
 				debug("%s: No additional FDT node\n", __func__);
 				break;
@@ -413,7 +414,7 @@
 					      __func__);
 			}
 			image_info.load_addr = (ulong)tmpbuffer;
-			ret = spl_load_fit_image(info, sector, fit, base_offset,
+			ret = spl_load_fit_image(info, sector, ctx,
 						 node, &image_info);
 			if (ret < 0)
 				break;
@@ -428,12 +429,12 @@
 							(void *)image_info.load_addr);
 			if (ret) {
 				pr_err("failed to apply DT overlay %s\n",
-				       fit_get_name(fit, node, NULL));
+				       fit_get_name(ctx->fit, node, NULL));
 				break;
 			}
 
 			debug("%s: DT overlay %s applied\n", __func__,
-			      fit_get_name(fit, node, NULL));
+			      fit_get_name(ctx->fit, node, NULL));
 		}
 		free(tmpbuffer);
 		if (ret)
@@ -443,39 +444,39 @@
 	ret = fdt_shrink_to_minimum(spl_image->fdt_addr, 8192);
 	if (ret < 0)
 		return ret;
-#endif
 
 	return ret;
 }
 
-static int spl_fit_record_loadable(const void *fit, int images, int index,
+static int spl_fit_record_loadable(const struct spl_fit_info *ctx, int index,
 				   void *blob, struct spl_image_info *image)
 {
 	int ret = 0;
-#if !CONFIG_IS_ENABLED(FIT_IMAGE_TINY)
 	const char *name;
 	int node;
 
-	ret = spl_fit_get_image_name(fit, images, "loadables",
-				     index, &name);
+	if (CONFIG_IS_ENABLED(FIT_IMAGE_TINY))
+		return 0;
+
+	ret = spl_fit_get_image_name(ctx, "loadables", index, &name);
 	if (ret < 0)
 		return ret;
 
-	node = spl_fit_get_image_node(fit, images, "loadables", index);
+	node = spl_fit_get_image_node(ctx, "loadables", index);
 
 	ret = fdt_record_loadable(blob, index, name, image->load_addr,
 				  image->size, image->entry_point,
-				  fdt_getprop(fit, node, "type", NULL),
-				  fdt_getprop(fit, node, "os", NULL));
-#endif
+				  fdt_getprop(ctx->fit, node, "type", NULL),
+				  fdt_getprop(ctx->fit, node, "os", NULL));
 	return ret;
 }
 
 static int spl_fit_image_get_os(const void *fit, int noffset, uint8_t *os)
 {
-#if CONFIG_IS_ENABLED(FIT_IMAGE_TINY) && !defined(CONFIG_SPL_OS_BOOT)
-	const char *name = fdt_getprop(fit, noffset, FIT_OS_PROP, NULL);
+	if (!CONFIG_IS_ENABLED(FIT_IMAGE_TINY) || CONFIG_IS_ENABLED(OS_BOOT))
+		return fit_image_get_os(fit, noffset, os);
 
+	const char *name = fdt_getprop(fit, noffset, FIT_OS_PROP, NULL);
 	if (!name)
 		return -ENOENT;
 
@@ -490,9 +491,6 @@
 		*os = IH_OS_INVALID;
 
 	return 0;
-#else
-	return fit_image_get_os(fit, noffset, os);
-#endif
 }
 
 /*
@@ -522,28 +520,22 @@
 	return false;
 }
 
-int spl_load_simple_fit(struct spl_image_info *spl_image,
-			struct spl_load_info *info, ulong sector, void *fit)
+static int spl_simple_fit_read(struct spl_fit_info *ctx,
+			       struct spl_load_info *info, ulong sector,
+			       const void *fit_header)
 {
+	unsigned long count, size;
 	int sectors;
-	ulong size, hsize;
-	unsigned long count;
-	struct spl_image_info image_info;
-	int node = -1;
-	int images, ret;
-	int base_offset;
-	int index = 0;
-	int firmware_node;
+	void *buf;
 
 	/*
 	 * For FIT with external data, figure out where the external images
 	 * start. This is the base for the data-offset properties in each
 	 * image.
 	 */
-	size = fdt_totalsize(fit);
-	size = (size + 3) & ~3;
+	size = ALIGN(fdt_totalsize(fit_header), 4);
 	size = board_spl_fit_size_align(size);
-	base_offset = (size + 3) & ~3;
+	ctx->ext_data_offset = ALIGN(size, 4);
 
 	/*
 	 * So far we only have one block of data from the FIT. Read the entire
@@ -553,42 +545,69 @@
 	 * For FIT with external data, data is not loaded in this step.
 	 */
 	sectors = get_aligned_image_size(info, size, 0);
-	hsize = sectors * info->bl_len;
-	fit = spl_get_fit_load_buffer(hsize);
-	count = info->read(info, sector, sectors, fit);
+	buf = spl_get_fit_load_buffer(sectors * info->bl_len);
+
+	count = info->read(info, sector, sectors, buf);
+	ctx->fit = buf;
 	debug("fit read sector %lx, sectors=%d, dst=%p, count=%lu, size=0x%lx\n",
-	      sector, sectors, fit, count, size);
+	      sector, sectors, buf, count, size);
 
-	if (count == 0)
-		return -EIO;
+	return (count == 0) ? -EIO : 0;
+}
 
-	/* skip further processing if requested to enable load-only use cases */
-	if (spl_load_simple_fit_skip_processing())
-		return 0;
+static int spl_simple_fit_parse(struct spl_fit_info *ctx)
+{
+	/* Find the correct subnode under "/configurations" */
+	ctx->conf_node = fit_find_config_node(ctx->fit);
+	if (ctx->conf_node < 0)
+		return -EINVAL;
 
 	if (IS_ENABLED(CONFIG_SPL_FIT_SIGNATURE)) {
-		int conf_offset = fit_find_config_node(fit);
-
 		printf("## Checking hash(es) for config %s ... ",
-		       fit_get_name(fit, conf_offset, NULL));
-		if (fit_config_verify(fit, conf_offset))
+		       fit_get_name(ctx->fit, ctx->conf_node, NULL));
+		if (fit_config_verify(ctx->fit, ctx->conf_node))
 			return -EPERM;
 		puts("OK\n");
 	}
 
 	/* find the node holding the images information */
-	images = fdt_path_offset(fit, FIT_IMAGES_PATH);
-	if (images < 0) {
-		debug("%s: Cannot find /images node: %d\n", __func__, images);
-		return -1;
+	ctx->images_node = fdt_path_offset(ctx->fit, FIT_IMAGES_PATH);
+	if (ctx->images_node < 0) {
+		debug("%s: Cannot find /images node: %d\n", __func__,
+		      ctx->images_node);
+		return -EINVAL;
 	}
 
+	return 0;
+}
+
+int spl_load_simple_fit(struct spl_image_info *spl_image,
+			struct spl_load_info *info, ulong sector, void *fit)
+{
+	struct spl_image_info image_info;
+	struct spl_fit_info ctx;
+	int node = -1;
+	int ret;
+	int index = 0;
+	int firmware_node;
+
+	ret = spl_simple_fit_read(&ctx, info, sector, fit);
+	if (ret < 0)
+		return ret;
+
+	/* skip further processing if requested to enable load-only use cases */
+	if (spl_load_simple_fit_skip_processing())
+		return 0;
+
+	ret = spl_simple_fit_parse(&ctx);
+	if (ret < 0)
+		return ret;
+
 #ifdef CONFIG_SPL_FPGA
-	node = spl_fit_get_image_node(fit, images, "fpga", 0);
+	node = spl_fit_get_image_node(&ctx, "fpga", 0);
 	if (node >= 0) {
 		/* Load the image and set up the spl_image structure */
-		ret = spl_load_fit_image(info, sector, fit, base_offset, node,
-					 spl_image);
+		ret = spl_load_fit_image(info, sector, &ctx, node, spl_image);
 		if (ret) {
 			printf("%s: Cannot load the FPGA: %i\n", __func__, ret);
 			return ret;
@@ -617,15 +636,14 @@
 	 *   - fall back to using the first 'loadables' entry
 	 */
 	if (node < 0)
-		node = spl_fit_get_image_node(fit, images, FIT_FIRMWARE_PROP,
-					      0);
-#ifdef CONFIG_SPL_OS_BOOT
-	if (node < 0)
-		node = spl_fit_get_image_node(fit, images, FIT_KERNEL_PROP, 0);
-#endif
+		node = spl_fit_get_image_node(&ctx, FIT_FIRMWARE_PROP, 0);
+
+	if (node < 0 && IS_ENABLED(CONFIG_SPL_OS_BOOT))
+		node = spl_fit_get_image_node(&ctx, FIT_KERNEL_PROP, 0);
+
 	if (node < 0) {
 		debug("could not find firmware image, trying loadables...\n");
-		node = spl_fit_get_image_node(fit, images, "loadables", 0);
+		node = spl_fit_get_image_node(&ctx, "loadables", 0);
 		/*
 		 * If we pick the U-Boot image from "loadables", start at
 		 * the second image when later loading additional images.
@@ -639,8 +657,7 @@
 	}
 
 	/* Load the image and set up the spl_image structure */
-	ret = spl_load_fit_image(info, sector, fit, base_offset, node,
-				 spl_image);
+	ret = spl_load_fit_image(info, sector, &ctx, node, spl_image);
 	if (ret)
 		return ret;
 
@@ -648,21 +665,18 @@
 	 * For backward compatibility, we treat the first node that is
 	 * as a U-Boot image, if no OS-type has been declared.
 	 */
-	if (!spl_fit_image_get_os(fit, node, &spl_image->os))
+	if (!spl_fit_image_get_os(ctx.fit, node, &spl_image->os))
 		debug("Image OS is %s\n", genimg_get_os_name(spl_image->os));
-#if !defined(CONFIG_SPL_OS_BOOT)
-	else
+	else if (!IS_ENABLED(CONFIG_SPL_OS_BOOT))
 		spl_image->os = IH_OS_U_BOOT;
-#endif
 
 	/*
 	 * Booting a next-stage U-Boot may require us to append the FDT.
 	 * We allow this to fail, as the U-Boot image might embed its FDT.
 	 */
-	if (spl_image->os == IH_OS_U_BOOT) {
-		ret = spl_fit_append_fdt(spl_image, info, sector, fit,
-					 images, base_offset);
-		if (!IS_ENABLED(CONFIG_OF_EMBED) && ret < 0)
+	if (os_takes_devicetree(spl_image->os)) {
+		ret = spl_fit_append_fdt(spl_image, info, sector, &ctx);
+		if (ret < 0 && spl_image->os != IH_OS_U_BOOT)
 			return ret;
 	}
 
@@ -671,7 +685,7 @@
 	for (; ; index++) {
 		uint8_t os_type = IH_OS_INVALID;
 
-		node = spl_fit_get_image_node(fit, images, "loadables", index);
+		node = spl_fit_get_image_node(&ctx, "loadables", index);
 		if (node < 0)
 			break;
 
@@ -683,20 +697,18 @@
 		if (firmware_node == node)
 			continue;
 
-		ret = spl_load_fit_image(info, sector, fit, base_offset, node,
-					 &image_info);
+		ret = spl_load_fit_image(info, sector, &ctx, node, &image_info);
 		if (ret < 0) {
 			printf("%s: can't load image loadables index %d (ret = %d)\n",
 			       __func__, index, ret);
 			return ret;
 		}
 
-		if (!spl_fit_image_get_os(fit, node, &os_type))
+		if (!spl_fit_image_get_os(ctx.fit, node, &os_type))
 			debug("Loadable is %s\n", genimg_get_os_name(os_type));
 
-		if (os_type == IH_OS_U_BOOT) {
-			spl_fit_append_fdt(&image_info, info, sector,
-					   fit, images, base_offset);
+		if (os_takes_devicetree(os_type)) {
+			spl_fit_append_fdt(&image_info, info, sector, &ctx);
 			spl_image->fdt_addr = image_info.fdt_addr;
 		}
 
@@ -710,7 +722,7 @@
 
 		/* Record our loadables into the FDT */
 		if (spl_image->fdt_addr)
-			spl_fit_record_loadable(fit, images, index,
+			spl_fit_record_loadable(&ctx, index,
 						spl_image->fdt_addr,
 						&image_info);
 	}
@@ -725,9 +737,8 @@
 
 	spl_image->flags |= SPL_FIT_FOUND;
 
-#ifdef CONFIG_IMX_HAB
-	board_spl_fit_post_load((ulong)fit, size);
-#endif
+	if (IS_ENABLED(CONFIG_IMX_HAB))
+		board_spl_fit_post_load(ctx.fit);
 
 	return 0;
 }
diff --git a/common/splash_source.c b/common/splash_source.c
index d7f179e..3cf926d 100644
--- a/common/splash_source.c
+++ b/common/splash_source.c
@@ -37,7 +37,7 @@
 			return -ENODEV;
 	}
 
-	return spi_flash_read(sf, offset, read_size, (void *)bmp_load_addr);
+	return spi_flash_read(sf, offset, read_size, (void *)(uintptr_t)bmp_load_addr);
 }
 #else
 static int splash_sf_read_raw(u32 bmp_load_addr, int offset, size_t read_size)
@@ -98,7 +98,7 @@
 	if (res < 0)
 		return res;
 
-	bmp_hdr = (struct bmp_header *)bmp_load_addr;
+	bmp_hdr = (struct bmp_header *)(uintptr_t)bmp_load_addr;
 	bmp_size = le32_to_cpu(bmp_hdr->file_size);
 
 	if (bmp_load_addr + bmp_size >= gd->start_addr_sp)
diff --git a/common/stdio.c b/common/stdio.c
index 2b883fd..d4acc52 100644
--- a/common/stdio.c
+++ b/common/stdio.c
@@ -28,6 +28,20 @@
 struct stdio_dev *stdio_devices[] = { NULL, NULL, NULL };
 char *stdio_names[MAX_FILES] = { "stdin", "stdout", "stderr" };
 
+int stdio_file_to_flags(const int file)
+{
+	switch (file) {
+	case stdin:
+		return DEV_FLAGS_INPUT;
+	case stdout:
+	case stderr:
+		return DEV_FLAGS_OUTPUT;
+	default:
+		return -EINVAL;
+	}
+}
+
+#if CONFIG_IS_ENABLED(SYS_DEVICE_NULLDEV)
 static void nulldev_putc(struct stdio_dev *dev, const char c)
 {
 	/* nulldev is empty! */
@@ -44,6 +58,25 @@
 	return 0;
 }
 
+static void nulldev_register(void)
+{
+	struct stdio_dev dev;
+
+	memset(&dev, '\0', sizeof(dev));
+
+	strcpy(dev.name, "nulldev");
+	dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT;
+	dev.putc = nulldev_putc;
+	dev.puts = nulldev_puts;
+	dev.getc = nulldev_input;
+	dev.tstc = nulldev_input;
+
+	stdio_register(&dev);
+}
+#else
+static inline void nulldev_register(void) {}
+#endif	/* SYS_DEVICE_NULLDEV */
+
 static void stdio_serial_putc(struct stdio_dev *dev, const char c)
 {
 	serial_putc(c);
@@ -83,18 +116,7 @@
 	dev.tstc = stdio_serial_tstc;
 	stdio_register (&dev);
 
-	if (CONFIG_IS_ENABLED(SYS_DEVICE_NULLDEV)) {
-		memset(&dev, '\0', sizeof(dev));
-
-		strcpy(dev.name, "nulldev");
-		dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT;
-		dev.putc = nulldev_putc;
-		dev.puts = nulldev_puts;
-		dev.getc = nulldev_input;
-		dev.tstc = nulldev_input;
-
-		stdio_register(&dev);
-	}
+	nulldev_register();
 }
 
 /**************************************************************************
@@ -261,17 +283,6 @@
 	return 0;
 }
 
-int stdio_deregister(const char *devname, int force)
-{
-	struct stdio_dev *dev;
-
-	dev = stdio_get_by_name(devname);
-	if (!dev) /* device not found */
-		return -ENODEV;
-
-	return stdio_deregister_dev(dev, force);
-}
-
 int stdio_init_tables(void)
 {
 #if defined(CONFIG_NEEDS_MANUAL_RELOC)
diff --git a/common/usb_kbd.c b/common/usb_kbd.c
index b316807..60c6027 100644
--- a/common/usb_kbd.c
+++ b/common/usb_kbd.c
@@ -617,12 +617,12 @@
 	if (dev) {
 		usb_kbd_dev = (struct usb_device *)dev->priv;
 		data = usb_kbd_dev->privptr;
-		if (stdio_deregister_dev(dev, force) != 0)
-			return 1;
 #if CONFIG_IS_ENABLED(CONSOLE_MUX)
-		if (iomux_doenv(stdin, env_get("stdin")) != 0)
+		if (iomux_replace_device(stdin, DEVNAME, force ? "nulldev" : ""))
 			return 1;
 #endif
+		if (stdio_deregister_dev(dev, force) != 0)
+			return 1;
 #ifdef CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE
 		destroy_int_queue(usb_kbd_dev, data->intq);
 #endif
@@ -660,16 +660,16 @@
 		goto err;
 	}
 	data = udev->privptr;
-	if (stdio_deregister_dev(sdev, true)) {
-		ret = -EPERM;
-		goto err;
-	}
 #if CONFIG_IS_ENABLED(CONSOLE_MUX)
-	if (iomux_doenv(stdin, env_get("stdin"))) {
+	if (iomux_replace_device(stdin, DEVNAME, "nulldev")) {
 		ret = -ENOLINK;
 		goto err;
 	}
 #endif
+	if (stdio_deregister_dev(sdev, true)) {
+		ret = -EPERM;
+		goto err;
+	}
 #ifdef CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE
 	destroy_int_queue(udev, data->intq);
 #endif
diff --git a/configs/MPC837XERDB_defconfig b/configs/MPC837XERDB_defconfig
index 0d8ec8e..0e61c59 100644
--- a/configs/MPC837XERDB_defconfig
+++ b/configs/MPC837XERDB_defconfig
@@ -161,7 +161,11 @@
 CONFIG_CMD_EXT2=y
 CONFIG_CMD_FAT=y
 CONFIG_ENV_OVERWRITE=y
+CONFIG_OF_CONTROL=y
+CONFIG_DEFAULT_DEVICE_TREE="mpc8379erdb"
 CONFIG_ENV_ADDR=0xFE080000
+CONFIG_DM=y
+CONFIG_DM_MMC=y
 CONFIG_FSL_SATA=y
 CONFIG_FSL_ESDHC=y
 CONFIG_MTD_NOR_FLASH=y
@@ -183,4 +187,3 @@
 CONFIG_USB=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_STORAGE=y
-CONFIG_OF_LIBFDT=y
diff --git a/configs/chromebit_mickey_defconfig b/configs/chromebit_mickey_defconfig
index ba1215b..c09b63b 100644
--- a/configs/chromebit_mickey_defconfig
+++ b/configs/chromebit_mickey_defconfig
@@ -63,6 +63,7 @@
 CONFIG_CROS_EC=y
 CONFIG_CROS_EC_SPI=y
 CONFIG_PWRSEQ=y
+CONFIG_MMC_PWRSEQ=y
 # CONFIG_SPL_DM_MMC is not set
 CONFIG_MMC_DW=y
 CONFIG_MMC_DW_ROCKCHIP=y
diff --git a/configs/chromebook_bob_defconfig b/configs/chromebook_bob_defconfig
index 73635f0..a846b64 100644
--- a/configs/chromebook_bob_defconfig
+++ b/configs/chromebook_bob_defconfig
@@ -55,6 +55,7 @@
 CONFIG_CROS_EC=y
 CONFIG_CROS_EC_SPI=y
 CONFIG_PWRSEQ=y
+CONFIG_MMC_PWRSEQ=y
 CONFIG_MMC_DW=y
 CONFIG_MMC_DW_ROCKCHIP=y
 CONFIG_MMC_SDHCI=y
diff --git a/configs/chromebook_jerry_defconfig b/configs/chromebook_jerry_defconfig
index dada557..692b630 100644
--- a/configs/chromebook_jerry_defconfig
+++ b/configs/chromebook_jerry_defconfig
@@ -65,6 +65,7 @@
 CONFIG_CROS_EC=y
 CONFIG_CROS_EC_SPI=y
 CONFIG_PWRSEQ=y
+CONFIG_MMC_PWRSEQ=y
 # CONFIG_SPL_DM_MMC is not set
 CONFIG_MMC_DW=y
 CONFIG_MMC_DW_ROCKCHIP=y
diff --git a/configs/chromebook_minnie_defconfig b/configs/chromebook_minnie_defconfig
index 985ca94..ae55842 100644
--- a/configs/chromebook_minnie_defconfig
+++ b/configs/chromebook_minnie_defconfig
@@ -65,6 +65,7 @@
 CONFIG_CROS_EC=y
 CONFIG_CROS_EC_SPI=y
 CONFIG_PWRSEQ=y
+CONFIG_MMC_PWRSEQ=y
 # CONFIG_SPL_DM_MMC is not set
 CONFIG_MMC_DW=y
 CONFIG_MMC_DW_ROCKCHIP=y
diff --git a/configs/chromebook_speedy_defconfig b/configs/chromebook_speedy_defconfig
index e3d4c30..4b460ee 100644
--- a/configs/chromebook_speedy_defconfig
+++ b/configs/chromebook_speedy_defconfig
@@ -64,6 +64,7 @@
 CONFIG_CROS_EC=y
 CONFIG_CROS_EC_SPI=y
 CONFIG_PWRSEQ=y
+CONFIG_MMC_PWRSEQ=y
 # CONFIG_SPL_DM_MMC is not set
 CONFIG_MMC_DW=y
 CONFIG_MMC_DW_ROCKCHIP=y
diff --git a/configs/imx8mp_evk_defconfig b/configs/imx8mp_evk_defconfig
index e70c430..47a52ee 100644
--- a/configs/imx8mp_evk_defconfig
+++ b/configs/imx8mp_evk_defconfig
@@ -69,6 +69,7 @@
 CONFIG_MXC_GPIO=y
 CONFIG_DM_PCA953X=y
 CONFIG_DM_I2C=y
+# CONFIG_SPL_DM_I2C is not set
 CONFIG_SYS_I2C_MXC=y
 CONFIG_LED=y
 CONFIG_LED_GPIO=y
diff --git a/configs/kmeter1_defconfig b/configs/kmeter1_defconfig
index 3812776..aadcbf47 100644
--- a/configs/kmeter1_defconfig
+++ b/configs/kmeter1_defconfig
@@ -1,5 +1,6 @@
 CONFIG_PPC=y
 CONFIG_SYS_TEXT_BASE=0xF0000000
+CONFIG_SYS_MALLOC_F_LEN=0x800
 CONFIG_KM_DEF_NETDEV="eth2"
 CONFIG_ENV_SIZE=0x4000
 CONFIG_ENV_SECT_SIZE=0x20000
@@ -60,6 +61,12 @@
 CONFIG_BAT3_DCACHE_GUARDED=y
 CONFIG_BAT3_USER_MODE_VALID=y
 CONFIG_BAT3_SUPERVISOR_MODE_VALID=y
+CONFIG_BAT4=y
+CONFIG_BAT4_NAME="STACK_IN_DCACHE"
+CONFIG_BAT4_BASE=0xE6000000
+CONFIG_BAT4_ACCESS_RW=y
+CONFIG_BAT4_USER_MODE_VALID=y
+CONFIG_BAT4_SUPERVISOR_MODE_VALID=y
 CONFIG_BAT5=y
 CONFIG_BAT5_NAME="PAXE"
 CONFIG_BAT5_BASE=0xA0000000
diff --git a/configs/kontron_sl28_defconfig b/configs/kontron_sl28_defconfig
index 1759d5e..d567096 100644
--- a/configs/kontron_sl28_defconfig
+++ b/configs/kontron_sl28_defconfig
@@ -84,6 +84,9 @@
 CONFIG_PHY_GIGE=y
 CONFIG_E1000=y
 CONFIG_FSL_ENETC=y
+CONFIG_PHY_FIXED=y
+CONFIG_DM_DSA=y
+CONFIG_MSCC_FELIX_SWITCH=y
 CONFIG_NVME=y
 CONFIG_PCI=y
 CONFIG_DM_PCI=y
diff --git a/configs/ls1021atwr_sdcard_ifc_SECURE_BOOT_defconfig b/configs/ls1021atwr_sdcard_ifc_SECURE_BOOT_defconfig
index 4f11196..d721729 100644
--- a/configs/ls1021atwr_sdcard_ifc_SECURE_BOOT_defconfig
+++ b/configs/ls1021atwr_sdcard_ifc_SECURE_BOOT_defconfig
@@ -52,6 +52,7 @@
 CONFIG_DM=y
 CONFIG_SPL_DM=y
 CONFIG_DM_I2C=y
+# CONFIG_SPL_DM_I2C is not set
 CONFIG_FSL_ESDHC=y
 CONFIG_MTD=y
 CONFIG_MTD_NOR_FLASH=y
diff --git a/configs/ls1028aqds_tfa_SECURE_BOOT_defconfig b/configs/ls1028aqds_tfa_SECURE_BOOT_defconfig
index eaf903f..93b13b4 100644
--- a/configs/ls1028aqds_tfa_SECURE_BOOT_defconfig
+++ b/configs/ls1028aqds_tfa_SECURE_BOOT_defconfig
@@ -62,6 +62,9 @@
 CONFIG_E1000=y
 CONFIG_FSL_ENETC=y
 CONFIG_MDIO_MUX_I2CREG=y
+CONFIG_PHY_FIXED=y
+CONFIG_DM_DSA=y
+CONFIG_MSCC_FELIX_SWITCH=y
 CONFIG_NVME=y
 CONFIG_PCI=y
 CONFIG_DM_PCI=y
diff --git a/configs/ls1028aqds_tfa_defconfig b/configs/ls1028aqds_tfa_defconfig
index 248c640..c915069 100644
--- a/configs/ls1028aqds_tfa_defconfig
+++ b/configs/ls1028aqds_tfa_defconfig
@@ -68,6 +68,9 @@
 CONFIG_E1000=y
 CONFIG_FSL_ENETC=y
 CONFIG_MDIO_MUX_I2CREG=y
+CONFIG_PHY_FIXED=y
+CONFIG_DM_DSA=y
+CONFIG_MSCC_FELIX_SWITCH=y
 CONFIG_NVME=y
 CONFIG_PCI=y
 CONFIG_DM_PCI=y
diff --git a/configs/ls1028ardb_tfa_SECURE_BOOT_defconfig b/configs/ls1028ardb_tfa_SECURE_BOOT_defconfig
index 240e420..45d9f40 100644
--- a/configs/ls1028ardb_tfa_SECURE_BOOT_defconfig
+++ b/configs/ls1028ardb_tfa_SECURE_BOOT_defconfig
@@ -59,6 +59,9 @@
 CONFIG_PHY_GIGE=y
 CONFIG_E1000=y
 CONFIG_FSL_ENETC=y
+CONFIG_PHY_FIXED=y
+CONFIG_DM_DSA=y
+CONFIG_MSCC_FELIX_SWITCH=y
 CONFIG_NVME=y
 CONFIG_PCI=y
 CONFIG_DM_PCI=y
diff --git a/configs/ls1028ardb_tfa_defconfig b/configs/ls1028ardb_tfa_defconfig
index 493fe7c..cff68a3 100644
--- a/configs/ls1028ardb_tfa_defconfig
+++ b/configs/ls1028ardb_tfa_defconfig
@@ -65,6 +65,9 @@
 CONFIG_PHY_GIGE=y
 CONFIG_E1000=y
 CONFIG_FSL_ENETC=y
+CONFIG_PHY_FIXED=y
+CONFIG_DM_DSA=y
+CONFIG_MSCC_FELIX_SWITCH=y
 CONFIG_NVME=y
 CONFIG_PCI=y
 CONFIG_DM_PCI=y
diff --git a/configs/ls1046ardb_sdcard_SECURE_BOOT_defconfig b/configs/ls1046ardb_sdcard_SECURE_BOOT_defconfig
index 5e7dd46..54f489d 100644
--- a/configs/ls1046ardb_sdcard_SECURE_BOOT_defconfig
+++ b/configs/ls1046ardb_sdcard_SECURE_BOOT_defconfig
@@ -50,6 +50,7 @@
 CONFIG_DM=y
 CONFIG_SPL_DM=y
 CONFIG_DM_I2C=y
+# CONFIG_SPL_DM_I2C is not set
 CONFIG_FSL_ESDHC=y
 CONFIG_MTD=y
 CONFIG_MTD_RAW_NAND=y
diff --git a/configs/phycore-imx8mp_defconfig b/configs/phycore-imx8mp_defconfig
index 3d662e8..d09841a 100644
--- a/configs/phycore-imx8mp_defconfig
+++ b/configs/phycore-imx8mp_defconfig
@@ -63,6 +63,7 @@
 CONFIG_CLK_IMX8MP=y
 CONFIG_MXC_GPIO=y
 CONFIG_DM_I2C=y
+# CONFIG_SPL_DM_I2C is not set
 CONFIG_SYS_I2C_MXC=y
 CONFIG_MISC=y
 CONFIG_I2C_EEPROM=y
diff --git a/configs/rcar3_salvator-x_defconfig b/configs/rcar3_salvator-x_defconfig
index ff6e0e9..6109a23 100644
--- a/configs/rcar3_salvator-x_defconfig
+++ b/configs/rcar3_salvator-x_defconfig
@@ -71,6 +71,7 @@
 CONFIG_RENESAS_RAVB=y
 CONFIG_PCI=y
 CONFIG_DM_PCI=y
+CONFIG_PCI_REGION_MULTI_ENTRY=y
 CONFIG_PCI_RCAR_GEN3=y
 CONFIG_DM_REGULATOR=y
 CONFIG_DM_REGULATOR_FIXED=y
diff --git a/configs/rpi_4_32b_defconfig b/configs/rpi_4_32b_defconfig
index 5ddd838..0a5d3ff 100644
--- a/configs/rpi_4_32b_defconfig
+++ b/configs/rpi_4_32b_defconfig
@@ -22,6 +22,7 @@
 CONFIG_ENV_FAT_DEVICE_AND_PART="0:1"
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+CONFIG_DM_DMA=y
 CONFIG_DFU_MMC=y
 CONFIG_DM_KEYBOARD=y
 CONFIG_DM_MMC=y
diff --git a/configs/rpi_4_defconfig b/configs/rpi_4_defconfig
index 2590d0a..cb6ee77 100644
--- a/configs/rpi_4_defconfig
+++ b/configs/rpi_4_defconfig
@@ -22,6 +22,7 @@
 CONFIG_ENV_FAT_DEVICE_AND_PART="0:1"
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+CONFIG_DM_DMA=y
 CONFIG_DFU_MMC=y
 CONFIG_DM_KEYBOARD=y
 CONFIG_DM_MMC=y
@@ -36,6 +37,8 @@
 CONFIG_PINCTRL=y
 # CONFIG_PINCTRL_GENERIC is not set
 CONFIG_DM_RESET=y
+CONFIG_DM_RNG=y
+CONFIG_RNG_IPROC200=y
 # CONFIG_REQUIRE_SERIAL_CONSOLE is not set
 CONFIG_USB=y
 CONFIG_DM_USB=y
diff --git a/configs/rpi_arm64_defconfig b/configs/rpi_arm64_defconfig
index 2639219..4d69026 100644
--- a/configs/rpi_arm64_defconfig
+++ b/configs/rpi_arm64_defconfig
@@ -20,6 +20,7 @@
 CONFIG_OF_BOARD=y
 CONFIG_ENV_FAT_DEVICE_AND_PART="0:1"
 CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+CONFIG_DM_DMA=y
 CONFIG_DM_KEYBOARD=y
 CONFIG_DM_MMC=y
 CONFIG_MMC_SDHCI=y
@@ -33,6 +34,8 @@
 CONFIG_PINCTRL=y
 # CONFIG_PINCTRL_GENERIC is not set
 CONFIG_DM_RESET=y
+CONFIG_DM_RNG=y
+CONFIG_RNG_IPROC200=y
 # CONFIG_REQUIRE_SERIAL_CONSOLE is not set
 CONFIG_USB=y
 CONFIG_DM_USB=y
diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig
index 4e67819..634c195 100644
--- a/configs/sandbox64_defconfig
+++ b/configs/sandbox64_defconfig
@@ -94,6 +94,7 @@
 CONFIG_BOOTP_SEND_HOSTNAME=y
 CONFIG_NETCONSOLE=y
 CONFIG_IP_DEFRAG=y
+CONFIG_DM_DMA=y
 CONFIG_REGMAP=y
 CONFIG_SYSCON=y
 CONFIG_DEVRES=y
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 0c7674e..fc1df31 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -108,6 +108,7 @@
 CONFIG_BOOTP_SEND_HOSTNAME=y
 CONFIG_NETCONSOLE=y
 CONFIG_IP_DEFRAG=y
+CONFIG_DM_DMA=y
 CONFIG_REGMAP=y
 CONFIG_SYSCON=y
 CONFIG_DEVRES=y
diff --git a/configs/sandbox_flattree_defconfig b/configs/sandbox_flattree_defconfig
index 96465c5..4401f33 100644
--- a/configs/sandbox_flattree_defconfig
+++ b/configs/sandbox_flattree_defconfig
@@ -75,6 +75,7 @@
 CONFIG_BOOTP_SEND_HOSTNAME=y
 CONFIG_NETCONSOLE=y
 CONFIG_IP_DEFRAG=y
+CONFIG_DM_DMA=y
 CONFIG_REGMAP=y
 CONFIG_SYSCON=y
 CONFIG_DEVRES=y
diff --git a/configs/sandbox_spl_defconfig b/configs/sandbox_spl_defconfig
index 61dae34..c011870 100644
--- a/configs/sandbox_spl_defconfig
+++ b/configs/sandbox_spl_defconfig
@@ -95,6 +95,7 @@
 CONFIG_NETCONSOLE=y
 CONFIG_IP_DEFRAG=y
 CONFIG_SPL_DM=y
+CONFIG_DM_DMA=y
 CONFIG_REGMAP=y
 CONFIG_SPL_REGMAP=y
 CONFIG_SYSCON=y
diff --git a/doc/README.distro b/doc/README.distro
index cc1c41e..c4f041c 100644
--- a/doc/README.distro
+++ b/doc/README.distro
@@ -259,10 +259,10 @@
 
 kernel_comp_addr_r:
   Optional. This is only required if user wants to boot Linux from a compressed
-  Image(.gz, .bz2, .lzma, .lzo) using booti command. It represents the location
-  in RAM where the compressed Image will be decompressed temporarily. Once the
-  decompression is complete, decompressed data will be moved kernel_addr_r for
-  booting.
+  Image(.gz, .bz2, .lzma, .lzo) using the booti command. It represents the
+  location in RAM where the compressed Image will be decompressed temporarily.
+  Once the decompression is complete, the decompressed data will be moved to
+  kernel_addr_r for booting.
 
 kernel_comp_size:
   Optional. This is only required if user wants to boot Linux from a compressed
diff --git a/doc/conf.py b/doc/conf.py
index 3f456a1..eb74b86 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -147,9 +147,9 @@
 master_doc = 'index'
 
 # General information about the project.
-project = 'The Linux Kernel'
-copyright = 'The kernel development community'
-author = 'The kernel development community'
+project = 'Das U-Boot'
+copyright = 'The U-Boot development community'
+author = 'The U-Boot development community'
 
 # The version info for the project you're documenting, acts as replacement for
 # |version| and |release|, also used in various other places throughout the
@@ -260,7 +260,7 @@
 
 # The name of an image file (relative to this directory) to place at the top
 # of the sidebar.
-#html_logo = None
+html_logo = '../tools/logos/u-boot_logo.svg'
 
 # The name of an image file (within the static path) to use as favicon of the
 # docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
@@ -340,7 +340,7 @@
 #html_search_scorer = 'scorer.js'
 
 # Output file base name for HTML help builder.
-htmlhelp_basename = 'TheLinuxKerneldoc'
+htmlhelp_basename = 'TheUBootdoc'
 
 # -- Options for LaTeX output ---------------------------------------------
 
@@ -470,6 +470,8 @@
 #  author, documentclass [howto, manual, or own class]).
 # Sorted in alphabetical order
 latex_documents = [
+    ('index', 'u-boot-hacker-manual.tex', 'U-Boot Hacker Manual',
+     'The U-Boot development community', 'manual'),
 ]
 
 # Add all other index files from Documentation/ subdirectories
@@ -483,8 +485,8 @@
                 break
         if not has:
             latex_documents.append((doc, fn + '.tex',
-                                    'Linux %s Documentation' % fn.capitalize(),
-                                    'The kernel development community',
+                                    'U-Boot %s Documentation' % fn.capitalize(),
+                                    'The U-Boot development community',
                                     'manual'))
 
 # The name of an image file (relative to this directory) to place at the top of
@@ -513,7 +515,7 @@
 # One entry per manual page. List of tuples
 # (source start file, name, description, authors, manual section).
 man_pages = [
-    (master_doc, 'thelinuxkernel', 'The Linux Kernel Documentation',
+    (master_doc, 'dasuboot', 'The U-Boot Documentation',
      [author], 1)
 ]
 
@@ -527,8 +529,8 @@
 # (source start file, target name, title, author,
 #  dir menu entry, description, category)
 texinfo_documents = [
-    (master_doc, 'TheLinuxKernel', 'The Linux Kernel Documentation',
-     author, 'TheLinuxKernel', 'One line description of project.',
+    (master_doc, 'DasUBoot', 'The U-Boot Documentation',
+     author, 'DasUBoot', 'One line description of project.',
      'Miscellaneous'),
 ]
 
@@ -626,7 +628,7 @@
 # multiple PDF files here actually tries to get the cross-referencing right
 # *between* PDF files.
 pdf_documents = [
-    ('kernel-documentation', u'Kernel', u'Kernel', u'J. Random Bozo'),
+    ('uboot-documentation', u'U-Boot', u'U-Boot', u'J. Random Bozo'),
 ]
 
 # kernel-doc extension configuration for running Sphinx directly (e.g. by Read
diff --git a/doc/driver-model/i2c-howto.rst b/doc/driver-model/i2c-howto.rst
index 938b707..27e7440 100644
--- a/doc/driver-model/i2c-howto.rst
+++ b/doc/driver-model/i2c-howto.rst
@@ -25,7 +25,7 @@
 Here is a suggested approach for converting your I2C driver over to driver
 model. Please feel free to update this file with your ideas and suggestions.
 
-- #ifdef out all your own I2C driver code (#ifndef CONFIG_DM_I2C)
+- #ifdef out all your own I2C driver code (#if !CONFIG_IS_ENABLED(DM_I2C))
 - Define CONFIG_DM_I2C for your board, vendor or architecture
 - If the board does not already use driver model, you need CONFIG_DM also
 - Your board should then build, but will not work fully since there will be
diff --git a/doc/usage/booti.rst b/doc/usage/booti.rst
new file mode 100644
index 0000000..d631fb5
--- /dev/null
+++ b/doc/usage/booti.rst
@@ -0,0 +1,114 @@
+.. SPDX-License-Identifier: GPL-2.0+:
+
+booti command
+=============
+
+Synopsis
+--------
+
+::
+
+    booti [<addr> [<initrd>[:<size>]] [<fdt>]]
+
+Description
+-----------
+
+The booti command is used to boot a Linux kernel in flat or compressed
+'Image' format. Which compressed formats are supported is configurable.
+
+addr
+    address of kernel image, defaults to CONFIG_SYS_LOAD_ADDR.
+
+initrd
+    address of the initial RAM disk. Use '-' to boot a kernel with a device
+    tree but without an initial RAM disk.
+
+size
+    size of the initial RAM disk. This parameter must be specified for raw
+    initial RAM disks.
+
+fdt
+    address of the device tree.
+
+To support compressed Image files the following environment variables must be
+set:
+
+kernel_comp_addr_r
+    start of memory area used for decompression
+
+kernel_comp_size
+    size of the compressed file. The value has to be at least the size of
+    loaded image for decompression to succeed. For the booti command the
+    maximum decompressed size is 10 times this value.
+
+Example
+-------
+
+This is the boot log of an Odroid C2 board:
+
+::
+
+    => load mmc 0:1 $fdt_addr_r dtb-5.10.0-3-arm64
+    27530 bytes read in 7 ms (3.7 MiB/s)
+    => load mmc 0:1 $kernel_addr_r vmlinuz-5.10.0-3-arm64
+    26990448 bytes read in 1175 ms (21.9 MiB/s)
+    => load mmc 0:1 $ramdisk_addr_r initrd.img-5.10.0-3-arm64
+    27421776 bytes read in 1209 ms (21.6 MiB/s)
+    => booti $kernel_addr_r $ramdisk_addr_r:$filesize $fdt_addr_r
+    Moving Image from 0x8080000 to 0x8200000, end=9c60000
+    ## Flattened Device Tree blob at 08008000
+       Booting using the fdt blob at 0x8008000
+       Loading Ramdisk to 7a52a000, end 7bf50c50 ... OK
+       Loading Device Tree to 000000007a520000, end 000000007a529b89 ... OK
+
+    Starting kernel ...
+
+The kernel can be compressed with gzip:
+
+.. code-block:: bash
+
+    cd /boot
+    gzip -k vmlinuz-5.10.0-3-arm64
+
+Here is the boot log for the compressed kernel:
+
+::
+
+    => setenv kernel_comp_addr_r 0x50000000
+    => setenv kernel_comp_size 0x04000000
+    => load mmc 0:1 $fdt_addr_r dtb-5.10.0-3-arm64
+    27530 bytes read in 6 ms (4.4 MiB/s)
+    => load mmc 0:1 $kernel_addr_r vmlinuz-5.10.0-3-arm64.gz
+    9267730 bytes read in 402 ms (22 MiB/s)
+    => load mmc 0:1 $ramdisk_addr_r initrd.img-5.10.0-3-arm64
+    27421776 bytes read in 1181 ms (22.1 MiB/s)
+    => booti $kernel_addr_r $ramdisk_addr_r:$filesize $fdt_addr_r
+       Uncompressing Kernel Image
+    Moving Image from 0x8080000 to 0x8200000, end=9c60000
+    ## Flattened Device Tree blob at 08008000
+       Booting using the fdt blob at 0x8008000
+       Loading Ramdisk to 7a52a000, end 7bf50c50 ... OK
+       Loading Device Tree to 000000007a520000, end 000000007a529b89 ... OK
+
+    Starting kernel ...
+
+Configuration
+-------------
+
+The booti command is only available if CONFIG_CMD_BOOTI=y.
+
+Which compression types are supported depends on:
+
+* CONFIG_BZIP2
+* CONFIG_GZIP
+* CONFIG_LZ4
+* CONFIG_LZMA
+* CONFIG_LZO
+* CONFIG_ZSTD
+
+Return value
+------------
+
+Normally this command does not return. If an error occurs, the return value $?
+is set to 1 (false). If the operating system returns to U-Boot, the system is
+reset.
diff --git a/doc/usage/index.rst b/doc/usage/index.rst
index 5754958..a8842bf 100644
--- a/doc/usage/index.rst
+++ b/doc/usage/index.rst
@@ -15,6 +15,7 @@
 
    base
    bootefi
+   booti
    bootmenu
    button
    conitrace
@@ -27,5 +28,6 @@
    loady
    mbr
    pstore
+   qfw
    sbi
    true
diff --git a/doc/usage/qfw.rst b/doc/usage/qfw.rst
new file mode 100644
index 0000000..87463e1
--- /dev/null
+++ b/doc/usage/qfw.rst
@@ -0,0 +1,89 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+qfw command
+===========
+
+Synopsis
+--------
+
+::
+
+    qfw list
+    qfw cpus
+    qfw load [kernel_addr [initrd_addr]]
+
+Description
+-----------
+
+The *qfw* command is used to retrieve information form the QEMU firmware.
+
+The *qfw list* sub-command displays the QEMU firmware files.
+
+The *qfw cpus* sub-command displays the available CPUs.
+
+The *qfw load* command is used to load a kernel and an initial RAM disk.
+
+kernel_addr
+    address to which the file specified by the -kernel parameter of QEMU shall
+    be loaded. Defaults to environment variable *loadaddr* and further to
+    the value of *CONFIG_LOADADDR*.
+
+initrd_addr
+    address to which the file specified by the -initrd parameter of QEMU shall
+    be loaded. Defaults to environment variable *ramdiskaddr* and further to
+    the value of *CONFIG_RAMDISK_ADDR*.
+
+Examples
+--------
+
+QEMU firmware files are listed via the *qfw list* command:
+
+::
+
+    => qfw list
+    etc/boot-fail-wait
+    etc/smbios/smbios-tables
+    etc/smbios/smbios-anchor
+    etc/e820
+    genroms/kvmvapic.bin
+    genroms/linuxboot.bin
+    etc/system-states
+    etc/acpi/tables
+    etc/table-loader
+    etc/tpm/log
+    etc/acpi/rsdp
+    bootorder
+
+The available CPUs can be shown via the *qfw cpus* command:
+
+::
+
+    => qfw cpu
+    2 cpu(s) online
+
+The *-kernel* and *-initrd* parameters allow to specify a kernel and an
+initial RAM disk for QEMU:
+
+.. code-block:: bash
+
+   $ qemu-system-x86_64 -machine pc-i440fx-2.5 -bios u-boot.rom -m 1G \
+       -nographic -kernel vmlinuz -initrd initrd
+
+Now the kernel and the initial RAM disk can be loaded to the U-Boot memory via
+the *qfw load* command and booted thereafter.
+
+::
+
+    => qfw load ${kernel_addr_r} ${ramdisk_addr_r}
+    loading kernel to address 0000000001000000 size 5048f0 initrd 0000000004000000 size 3c94891
+    => zboot 1000000 5048f0 4000000 3c94891
+    Valid Boot Flag
+    Magic signature found
+    Linux kernel version 4.19.0-14-amd64 (debian-kernel@lists.debian.org) #1 SMP Debian 4.19.171-2 (2021-01-30)
+    Building boot_params at 0x00090000
+    Loading bzImage at address 100000 (5260160 bytes)
+
+Configuration
+-------------
+
+The qfw command is only available if CONFIG_CMD_QFW=y.
diff --git a/drivers/core/Kconfig b/drivers/core/Kconfig
index dbfe51c..00554af 100644
--- a/drivers/core/Kconfig
+++ b/drivers/core/Kconfig
@@ -129,6 +129,16 @@
 	  This applies to several ofnode functions (see ofnode.h) which are
 	  seldom used. Inlining them can help reduce code size.
 
+config DM_DMA
+	bool "Support per-device DMA constraints"
+	depends on DM
+	default n
+	help
+	  Enable this to extract per-device DMA constraints, only supported on
+	  device-tree systems for now. This is needed in order translate
+	  addresses on systems where different buses have different views of
+	  the physical address space.
+
 config REGMAP
 	bool "Support register maps"
 	depends on DM
diff --git a/drivers/core/device.c b/drivers/core/device.c
index 82a0098..6251349 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -422,6 +422,43 @@
 	return ret;
 }
 
+/**
+ * device_get_dma_constraints() - Populate device's DMA constraints
+ *
+ * Gets a device's DMA constraints from firmware. This information is later
+ * used by drivers to translate physcal addresses to the device's bus address
+ * space. For now only device-tree is supported.
+ *
+ * @dev: Pointer to target device
+ * Return: 0 if OK or if no DMA constraints were found, error otherwise
+ */
+static int device_get_dma_constraints(struct udevice *dev)
+{
+	struct udevice *parent = dev->parent;
+	phys_addr_t cpu = 0;
+	dma_addr_t bus = 0;
+	u64 size = 0;
+	int ret;
+
+	if (!CONFIG_IS_ENABLED(DM_DMA) || !parent || !dev_has_ofnode(parent))
+		return 0;
+
+	/*
+	 * We start parsing for dma-ranges from the device's bus node. This is
+	 * specially important on nested buses.
+	 */
+	ret = dev_get_dma_range(parent, &cpu, &bus, &size);
+	/* Don't return an error if no 'dma-ranges' were found */
+	if (ret && ret != -ENOENT) {
+		dm_warn("%s: failed to get DMA range, %d\n", dev->name, ret);
+		return ret;
+	}
+
+	dev_set_dma_offset(dev, cpu - bus);
+
+	return 0;
+}
+
 int device_probe(struct udevice *dev)
 {
 	const struct driver *drv;
@@ -484,6 +521,10 @@
 			goto fail;
 	}
 
+	ret = device_get_dma_constraints(dev);
+	if (ret)
+		goto fail;
+
 	ret = uclass_pre_probe_device(dev);
 	if (ret)
 		goto fail;
diff --git a/drivers/core/of_addr.c b/drivers/core/of_addr.c
index bbe8013..5bc6ca1 100644
--- a/drivers/core/of_addr.c
+++ b/drivers/core/of_addr.c
@@ -318,6 +318,84 @@
 	return __of_translate_address(dev, in_addr, "dma-ranges");
 }
 
+int of_get_dma_range(const struct device_node *dev, phys_addr_t *cpu,
+		     dma_addr_t *bus, u64 *size)
+{
+	bool found_dma_ranges = false;
+	struct device_node *parent;
+	struct of_bus *bus_node;
+	int na, ns, pna, pns;
+	const __be32 *ranges;
+	int ret = 0;
+	int len;
+
+	/* Find the closest dma-ranges property */
+	dev = of_node_get(dev);
+	while (dev) {
+		ranges = of_get_property(dev, "dma-ranges", &len);
+
+		/* Ignore empty ranges, they imply no translation required */
+		if (ranges && len > 0)
+			break;
+
+		/* Once we find 'dma-ranges', then a missing one is an error */
+		if (found_dma_ranges && !ranges) {
+			ret = -EINVAL;
+			goto out;
+		}
+
+		if (ranges)
+			found_dma_ranges = true;
+
+		parent = of_get_parent(dev);
+		of_node_put(dev);
+		dev = parent;
+	}
+
+	if (!dev || !ranges) {
+		debug("no dma-ranges found for node %s\n",
+		      of_node_full_name(dev));
+		ret = -ENOENT;
+		goto out;
+	}
+
+	/* switch to that node */
+	parent = of_get_parent(dev);
+	if (!parent) {
+		printf("Found dma-ranges in root node, shoudln't happen\n");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	/* Get the address sizes both for the bus and its parent */
+	bus_node = of_match_bus((struct device_node*)dev);
+	bus_node->count_cells(dev, &na, &ns);
+	if (!OF_CHECK_COUNTS(na, ns)) {
+		printf("Bad cell count for %s\n", of_node_full_name(dev));
+		return -EINVAL;
+		goto out_parent;
+	}
+
+	bus_node = of_match_bus(parent);
+	bus_node->count_cells(parent, &pna, &pns);
+	if (!OF_CHECK_COUNTS(pna, pns)) {
+		printf("Bad cell count for %s\n", of_node_full_name(parent));
+		return -EINVAL;
+		goto out_parent;
+	}
+
+	*bus = of_read_number(ranges, na);
+	*cpu = of_translate_dma_address(dev, ranges + na);
+	*size = of_read_number(ranges + na + pna, ns);
+
+out_parent:
+	of_node_put(parent);
+out:
+	of_node_put(dev);
+	return ret;
+}
+
+
 static int __of_address_to_resource(const struct device_node *dev,
 		const __be32 *addrp, u64 size, unsigned int flags,
 		const char *name, struct resource *r)
diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c
index 26c9d04..fa0bd2a 100644
--- a/drivers/core/ofnode.c
+++ b/drivers/core/ofnode.c
@@ -927,6 +927,15 @@
 		return fdt_translate_dma_address(gd->fdt_blob, ofnode_to_offset(node), in_addr);
 }
 
+int ofnode_get_dma_range(ofnode node, phys_addr_t *cpu, dma_addr_t *bus, u64 *size)
+{
+	if (ofnode_is_np(node))
+		return of_get_dma_range(ofnode_to_np(node), cpu, bus, size);
+	else
+		return fdt_get_dma_range(gd->fdt_blob, ofnode_to_offset(node),
+					 cpu, bus, size);
+}
+
 int ofnode_device_is_compatible(ofnode node, const char *compat)
 {
 	if (ofnode_is_np(node))
diff --git a/drivers/core/read.c b/drivers/core/read.c
index 14fd121..4307ca4 100644
--- a/drivers/core/read.c
+++ b/drivers/core/read.c
@@ -341,6 +341,12 @@
 	return ofnode_translate_dma_address(dev_ofnode(dev), in_addr);
 }
 
+int dev_get_dma_range(const struct udevice *dev, phys_addr_t *cpu,
+		      dma_addr_t *bus, u64 *size)
+{
+	return ofnode_get_dma_range(dev_ofnode(dev), cpu, bus, size);
+}
+
 int dev_read_alias_highest_id(const char *stem)
 {
 	if (of_live_active())
diff --git a/drivers/ddr/fsl/main.c b/drivers/ddr/fsl/main.c
index c02badd..8e14716 100644
--- a/drivers/ddr/fsl/main.c
+++ b/drivers/ddr/fsl/main.c
@@ -86,7 +86,7 @@
 
 #endif
 
-#if defined(CONFIG_DM_I2C)
+#if CONFIG_IS_ENABLED(DM_I2C)
 #define DEV_TYPE struct udevice
 #else
 /* Local udevice */
@@ -106,7 +106,7 @@
 {
 	int ret;
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	ret = dm_i2c_read(dev, 0, buf, len);
 #else
 	ret = i2c_read(dev->chip, addr, alen, buf, len);
@@ -120,7 +120,7 @@
 {
 	uint8_t buf = 0;
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	struct udevice *dev;
 	int ret;
 
@@ -146,7 +146,7 @@
 	int ret;
 	DEV_TYPE *dev;
 
-#if defined(CONFIG_DM_I2C)
+#if CONFIG_IS_ENABLED(DM_I2C)
 	ret = i2c_get_chip_for_busnum(CONFIG_SYS_SPD_BUS_NUM, i2c_address,
 				      1, &dev);
 	if (ret) {
diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
index f79b50f..1844941 100644
--- a/drivers/i2c/Kconfig
+++ b/drivers/i2c/Kconfig
@@ -14,6 +14,17 @@
 	  device (bus child) info is kept as parent plat. The interface
 	  is defined in include/i2c.h.
 
+config SPL_DM_I2C
+	bool "Enable Driver Model for I2C drivers in SPL"
+	depends on SPL_DM && DM_I2C
+	default y
+	help
+	  Enable driver model for I2C. The I2C uclass interface: probe, read,
+	  write and speed, is implemented with the bus drivers operations,
+	  which provide methods for bus setting and data transfer. Each chip
+	  device (bus child) info is kept as parent platdata. The interface
+	  is defined in include/i2c.h.
+
 config I2C_CROS_EC_TUNNEL
 	tristate "Chrome OS EC tunnel I2C bus"
 	depends on CROS_EC
@@ -61,6 +72,16 @@
 	  bindings are supported.
 	  Binding info: doc/device-tree-bindings/i2c/i2c-gpio.txt
 
+config SPL_DM_I2C_GPIO
+	bool "Enable Driver Model for software emulated I2C bus driver in SPL"
+	depends on SPL_DM && DM_I2C_GPIO && SPL_DM_GPIO && SPL_GPIO_SUPPORT
+	default y
+	help
+	  Enable the i2c bus driver emulation by using the GPIOs. The bus GPIO
+	  configuration is given by the device tree. Kernel-style device tree
+	  bindings are supported.
+	  Binding info: doc/device-tree-bindings/i2c/i2c-gpio.txt
+
 config SYS_I2C_AT91
 	bool "Atmel I2C driver"
 	depends on DM_I2C && ARCH_AT91
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
index 29aab0f..acd27ac 100644
--- a/drivers/i2c/Makefile
+++ b/drivers/i2c/Makefile
@@ -2,9 +2,9 @@
 #
 # (C) Copyright 2000-2007
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
-obj-$(CONFIG_DM_I2C) += i2c-uclass.o
+obj-$(CONFIG_$(SPL_)DM_I2C) += i2c-uclass.o
 ifdef CONFIG_ACPIGEN
-obj-$(CONFIG_DM_I2C) += acpi_i2c.o
+obj-$(CONFIG_$(SPL_)DM_I2C) += acpi_i2c.o
 endif
 obj-$(CONFIG_$(SPL_)DM_I2C_GPIO) += i2c-gpio.o
 obj-$(CONFIG_$(SPL_)I2C_CROS_EC_TUNNEL) += cros_ec_tunnel.o
diff --git a/drivers/i2c/at91_i2c.c b/drivers/i2c/at91_i2c.c
index aca8de9..6b4c0e4 100644
--- a/drivers/i2c/at91_i2c.c
+++ b/drivers/i2c/at91_i2c.c
@@ -51,6 +51,10 @@
 	u32 i;
 	int ret = 0;
 
+	/* if there is no message to send/receive, just exit quietly */
+	if (msg->len == 0)
+		return ret;
+
 	readl(&reg->sr);
 	if (is_read) {
 		writel(TWI_CR_START, &reg->cr);
diff --git a/drivers/i2c/davinci_i2c.c b/drivers/i2c/davinci_i2c.c
index 7811aba..a4abd25 100644
--- a/drivers/i2c/davinci_i2c.c
+++ b/drivers/i2c/davinci_i2c.c
@@ -21,7 +21,7 @@
 #include <linux/delay.h>
 #include "davinci_i2c.h"
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 /* Information about i2c controller */
 struct i2c_bus {
 	int			id;
@@ -340,7 +340,7 @@
 	return rc;
 }
 
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 static struct i2c_regs *davinci_get_base(struct i2c_adapter *adap)
 {
 	switch (adap->hwadapnr) {
diff --git a/drivers/i2c/designware_i2c.c b/drivers/i2c/designware_i2c.c
index 60111b8..0728036 100644
--- a/drivers/i2c/designware_i2c.c
+++ b/drivers/i2c/designware_i2c.c
@@ -598,7 +598,7 @@
 	writel(IC_RX_TL, &i2c_base->ic_rx_tl);
 	writel(IC_TX_TL, &i2c_base->ic_tx_tl);
 	writel(IC_STOP_DET, &i2c_base->ic_intr_mask);
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	_dw_i2c_set_bus_speed(NULL, i2c_base, speed, IC_CLK);
 	writel(slaveaddr, &i2c_base->ic_sar);
 #endif
@@ -611,7 +611,7 @@
 	return 0;
 }
 
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 /*
  * The legacy I2C functions. These need to get removed once
  * all users of this driver are converted to DM.
diff --git a/drivers/i2c/fsl_i2c.c b/drivers/i2c/fsl_i2c.c
index 5283575..2200303 100644
--- a/drivers/i2c/fsl_i2c.c
+++ b/drivers/i2c/fsl_i2c.c
@@ -40,7 +40,7 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 static const struct fsl_i2c_base *i2c_base[4] = {
 	(struct fsl_i2c_base *)(CONFIG_SYS_IMMR + CONFIG_SYS_FSL_I2C_OFFSET),
 #ifdef CONFIG_SYS_FSL_I2C2_OFFSET
@@ -203,7 +203,7 @@
 	return speed;
 }
 
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 static uint get_i2c_clock(int bus)
 {
 	if (bus)
@@ -497,7 +497,7 @@
 	return 0;
 }
 
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 static void fsl_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd)
 {
 	__i2c_init(i2c_base[adap->hwadapnr], speed, slaveadd,
diff --git a/drivers/i2c/i2c-gpio.c b/drivers/i2c/i2c-gpio.c
index 387f00b..a301a44 100644
--- a/drivers/i2c/i2c-gpio.c
+++ b/drivers/i2c/i2c-gpio.c
@@ -50,9 +50,10 @@
 	struct gpio_desc *sda = &bus->gpios[PIN_SDA];
 
 	if (bit)
-		dm_gpio_set_dir_flags(sda, GPIOD_IS_IN);
+		sda->flags = (sda->flags & ~GPIOD_IS_OUT) | GPIOD_IS_IN;
 	else
-		dm_gpio_set_dir_flags(sda, GPIOD_IS_OUT);
+		sda->flags = (sda->flags & (~GPIOD_IS_IN & ~GPIOD_IS_OUT_ACTIVE)) | GPIOD_IS_OUT;
+	dm_gpio_set_dir(sda);
 }
 
 static void i2c_gpio_scl_set(struct i2c_gpio_bus *bus, int bit)
@@ -61,14 +62,16 @@
 	int count = 0;
 
 	if (bit) {
-		dm_gpio_set_dir_flags(scl, GPIOD_IS_IN);
+		scl->flags = (scl->flags & ~GPIOD_IS_OUT) | GPIOD_IS_IN;
+		dm_gpio_set_dir(scl);
 		while (!dm_gpio_get_value(scl) && count++ < 100000)
 			udelay(1);
 
 		if (!dm_gpio_get_value(scl))
 			pr_err("timeout waiting on slave to release scl\n");
 	} else {
-		dm_gpio_set_dir_flags(scl, GPIOD_IS_OUT);
+		scl->flags = (scl->flags & (~GPIOD_IS_IN & ~GPIOD_IS_OUT_ACTIVE)) | GPIOD_IS_OUT;
+		dm_gpio_set_dir(scl);
 	}
 }
 
@@ -76,11 +79,11 @@
 static void i2c_gpio_scl_set_output_only(struct i2c_gpio_bus *bus, int bit)
 {
 	struct gpio_desc *scl = &bus->gpios[PIN_SCL];
-	ulong flags = GPIOD_IS_OUT;
+	scl->flags = (scl->flags & (~GPIOD_IS_IN & ~GPIOD_IS_OUT_ACTIVE)) | GPIOD_IS_OUT;
 
 	if (bit)
-		flags |= GPIOD_IS_OUT_ACTIVE;
-	dm_gpio_set_dir_flags(scl, flags);
+		scl->flags |= GPIOD_IS_OUT_ACTIVE;
+	dm_gpio_set_dir(scl);
 }
 
 static void i2c_gpio_write_bit(struct i2c_gpio_bus *bus, int delay, uchar bit)
diff --git a/drivers/i2c/ihs_i2c.c b/drivers/i2c/ihs_i2c.c
index ba78174..02f0144 100644
--- a/drivers/i2c/ihs_i2c.c
+++ b/drivers/i2c/ihs_i2c.c
@@ -6,7 +6,7 @@
 
 #include <common.h>
 #include <i2c.h>
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 #include <dm.h>
 #include <regmap.h>
 #else
@@ -18,7 +18,7 @@
 #include <linux/bitops.h>
 #include <linux/delay.h>
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 struct ihs_i2c_priv {
 	uint speed;
 	struct regmap *map;
@@ -91,7 +91,7 @@
 	I2COP_READ = 1,
 };
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 static int wait_for_int(struct udevice *dev, int read)
 #else
 static int wait_for_int(bool read)
@@ -99,11 +99,11 @@
 {
 	u16 val;
 	uint ctr = 0;
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	struct ihs_i2c_priv *priv = dev_get_priv(dev);
 #endif
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	ihs_i2c_get(priv->map, interrupt_status, &val);
 #else
 	I2C_GET_REG(interrupt_status, &val);
@@ -116,7 +116,7 @@
 			debug("%s: timed out\n", __func__);
 			return -ETIMEDOUT;
 		}
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 		ihs_i2c_get(priv->map, interrupt_status, &val);
 #else
 		I2C_GET_REG(interrupt_status, &val);
@@ -126,7 +126,7 @@
 	return (val & I2CINT_ERROR_EV) ? -EIO : 0;
 }
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 static int ihs_i2c_transfer(struct udevice *dev, uchar chip,
 			    uchar *buffer, int len, int read, bool is_last)
 #else
@@ -137,13 +137,13 @@
 	u16 val;
 	u16 data;
 	int res;
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	struct ihs_i2c_priv *priv = dev_get_priv(dev);
 #endif
 
 	/* Clear interrupt status */
 	data = I2CINT_ERROR_EV | I2CINT_RECEIVE_EV | I2CINT_TRANSMIT_EV;
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	ihs_i2c_set(priv->map, interrupt_status, data);
 	ihs_i2c_get(priv->map, interrupt_status, &val);
 #else
@@ -157,7 +157,7 @@
 
 		if (len > 1)
 			val |= buffer[1] << 8;
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 		ihs_i2c_set(priv->map, write_mailbox_ext, val);
 #else
 		I2C_SET_REG(write_mailbox_ext, val);
@@ -170,13 +170,13 @@
 	       | ((len > 1) ? I2CMB_2BYTE : 0)
 	       | (is_last ? 0 : I2CMB_HOLD_BUS);
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	ihs_i2c_set(priv->map, write_mailbox, data);
 #else
 	I2C_SET_REG(write_mailbox, data);
 #endif
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	res = wait_for_int(dev, read);
 #else
 	res = wait_for_int(read);
@@ -190,7 +190,7 @@
 
 	/* If we want to read, get the bytes from the mailbox */
 	if (read) {
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 		ihs_i2c_get(priv->map, read_mailbox_ext, &val);
 #else
 		I2C_GET_REG(read_mailbox_ext, &val);
@@ -203,7 +203,7 @@
 	return 0;
 }
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 static int ihs_i2c_send_buffer(struct udevice *dev, uchar chip, u8 *data, int len, bool hold_bus, int read)
 #else
 static int ihs_i2c_send_buffer(uchar chip, u8 *data, int len, bool hold_bus,
@@ -216,7 +216,7 @@
 		int transfer = min(len, 2);
 		bool is_last = len <= transfer;
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 		res = ihs_i2c_transfer(dev, chip, data, transfer, read,
 				       hold_bus ? false : is_last);
 #else
@@ -233,21 +233,21 @@
 	return 0;
 }
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 static int ihs_i2c_address(struct udevice *dev, uchar chip, u8 *addr, int alen,
 			   bool hold_bus)
 #else
 static int ihs_i2c_address(uchar chip, u8 *addr, int alen, bool hold_bus)
 #endif
 {
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	return ihs_i2c_send_buffer(dev, chip, addr, alen, hold_bus, I2COP_WRITE);
 #else
 	return ihs_i2c_send_buffer(chip, addr, alen, hold_bus, I2COP_WRITE);
 #endif
 }
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 static int ihs_i2c_access(struct udevice *dev, uchar chip, u8 *addr,
 			  int alen, uchar *buffer, int len, int read)
 #else
@@ -261,7 +261,7 @@
 	if (len <= 0)
 		return -EINVAL;
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	res = ihs_i2c_address(dev, chip, addr, alen, len);
 #else
 	res = ihs_i2c_address(chip, addr, alen, len);
@@ -269,14 +269,14 @@
 	if (res)
 		return res;
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	return ihs_i2c_send_buffer(dev, chip, buffer, len, false, read);
 #else
 	return ihs_i2c_send_buffer(chip, buffer, len, false, read);
 #endif
 }
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 
 int ihs_i2c_probe(struct udevice *bus)
 {
diff --git a/drivers/i2c/lpc32xx_i2c.c b/drivers/i2c/lpc32xx_i2c.c
index ad11e97..f89f795 100644
--- a/drivers/i2c/lpc32xx_i2c.c
+++ b/drivers/i2c/lpc32xx_i2c.c
@@ -42,7 +42,7 @@
 #define LPC32XX_I2C_STAT_NAI		0x00000004
 #define LPC32XX_I2C_STAT_TDI		0x00000001
 
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 static struct lpc32xx_i2c_base *lpc32xx_i2c[] = {
 	(struct lpc32xx_i2c_base *)I2C1_BASE,
 	(struct lpc32xx_i2c_base *)I2C2_BASE,
@@ -224,7 +224,7 @@
 	return 0;
 }
 
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 static void lpc32xx_i2c_init(struct i2c_adapter *adap,
 			     int requested_speed, int slaveadd)
 {
diff --git a/drivers/i2c/mv_i2c.c b/drivers/i2c/mv_i2c.c
index ef1007d..20c5de0 100644
--- a/drivers/i2c/mv_i2c.c
+++ b/drivers/i2c/mv_i2c.c
@@ -370,7 +370,7 @@
 	return 0;
 }
 
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 
 static struct mv_i2c *base_glob;
 
diff --git a/drivers/i2c/mvtwsi.c b/drivers/i2c/mvtwsi.c
index 5df69f1..d33e2c7 100644
--- a/drivers/i2c/mvtwsi.c
+++ b/drivers/i2c/mvtwsi.c
@@ -16,7 +16,7 @@
 #include <asm/io.h>
 #include <linux/bitops.h>
 #include <linux/compat.h>
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 #include <dm.h>
 #endif
 
@@ -27,7 +27,7 @@
  * settings
  */
 
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 #if defined(CONFIG_ARCH_ORION5X)
 #include <asm/arch/orion5x.h>
 #elif (defined(CONFIG_ARCH_KIRKWOOD) || defined(CONFIG_ARCH_MVEBU))
@@ -43,7 +43,7 @@
  * On SUNXI, we get CONFIG_SYS_TCLK from this include, so we want to
  * always have it.
  */
-#if defined(CONFIG_DM_I2C) && defined(CONFIG_ARCH_SUNXI)
+#if CONFIG_IS_ENABLED(DM_I2C) && defined(CONFIG_ARCH_SUNXI)
 #include <asm/arch/i2c.h>
 #endif
 
@@ -83,7 +83,7 @@
 
 #endif
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 struct mvtwsi_i2c_dev {
 	/* TWSI Register base for the device */
 	struct mvtwsi_registers *base;
@@ -184,7 +184,7 @@
 	return (1000000000u / speed) + 100;
 }
 
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 
 /*
  * twsi_get_base() - Get controller register base for specified adapter
@@ -481,7 +481,7 @@
 	writel(baud, &twsi->baudrate);
 
 	/* Wait for controller for one tick */
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	ndelay(calc_tick(highest_speed));
 #else
 	ndelay(10000);
@@ -516,7 +516,7 @@
 	writel(slaveadd, &twsi->slave_address);
 	writel(0, &twsi->xtnd_slave_addr);
 	/* Assert STOP, but don't care for the result */
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	(void) twsi_stop(twsi, calc_tick(*actual_speed));
 #else
 	(void) twsi_stop(twsi, 10000);
@@ -683,7 +683,7 @@
 	return status != 0 ? status : stop_status;
 }
 
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 static void twsi_i2c_init(struct i2c_adapter *adap, int speed,
 			  int slaveadd)
 {
diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c
index 3c91515..003aa33 100644
--- a/drivers/i2c/mxc_i2c.c
+++ b/drivers/i2c/mxc_i2c.c
@@ -394,7 +394,7 @@
 #endif
 };
 
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 int i2c_idle_bus(struct mxc_i2c_bus *i2c_bus)
 {
 	if (i2c_bus && i2c_bus->idle_bus_fn)
@@ -646,7 +646,7 @@
 int enable_i2c_clk(unsigned char enable, unsigned int i2c_num)
 	__attribute__((weak, alias("__enable_i2c_clk")));
 
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 /*
  * Read data from I2C device
  *
diff --git a/drivers/i2c/omap24xx_i2c.c b/drivers/i2c/omap24xx_i2c.c
index 1355dc2..71f6f5f 100644
--- a/drivers/i2c/omap24xx_i2c.c
+++ b/drivers/i2c/omap24xx_i2c.c
@@ -836,7 +836,7 @@
 	return i2c_error;
 }
 
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 /*
  * The legacy I2C functions. These need to get removed once
  * all users of this driver are converted to DM.
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index d737203..1a49396 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -17,7 +17,7 @@
 obj-$(CONFIG_SANDBOX) += swap_case.o
 endif
 
-ifdef CONFIG_DM_I2C
+ifdef CONFIG_$(SPL_)DM_I2C
 ifndef CONFIG_SPL_BUILD
 obj-$(CONFIG_SANDBOX) += i2c_eeprom_emul.o
 endif
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index f8ea921..f8ca52e 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -18,6 +18,13 @@
 	help
 	  Enable write access to MMC and SD Cards
 
+config MMC_PWRSEQ
+	bool "HW reset support for eMMC"
+	depends on PWRSEQ
+	help
+	  Ths select Hardware reset support aka pwrseq-emmc for eMMC
+	  devices.
+
 config MMC_BROKEN_CD
 	bool "Poll for broken card detection case"
 	help
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index 1c849cb..89d6af3 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -6,6 +6,7 @@
 obj-y += mmc.o
 obj-$(CONFIG_$(SPL_)DM_MMC) += mmc-uclass.o
 obj-$(CONFIG_$(SPL_)MMC_WRITE) += mmc_write.o
+obj-$(CONFIG_MMC_PWRSEQ) += mmc-pwrseq.o
 obj-$(CONFIG_MMC_SDHCI_ADMA_HELPERS) += sdhci-adma.o
 
 ifndef CONFIG_$(SPL_)BLK
diff --git a/drivers/mmc/meson_gx_mmc.c b/drivers/mmc/meson_gx_mmc.c
index 8b6dfa3..fcf4f03 100644
--- a/drivers/mmc/meson_gx_mmc.c
+++ b/drivers/mmc/meson_gx_mmc.c
@@ -265,10 +265,6 @@
 	uint32_t val;
 	int ret;
 
-#ifdef CONFIG_PWRSEQ
-	struct udevice *pwr_dev;
-#endif
-
 	/* Enable the clocks feeding the MMC controller */
 	ret = clk_get_bulk(dev, &clocks);
 	if (ret)
@@ -292,12 +288,11 @@
 
 	mmc_set_clock(mmc, cfg->f_min, MMC_CLK_ENABLE);
 
-#ifdef CONFIG_PWRSEQ
+#ifdef CONFIG_MMC_PWRSEQ
 	/* Enable power if needed */
-	ret = uclass_get_device_by_phandle(UCLASS_PWRSEQ, dev, "mmc-pwrseq",
-					   &pwr_dev);
+	ret = mmc_pwrseq_get_power(dev, cfg);
 	if (!ret) {
-		ret = pwrseq_set_power(pwr_dev, true);
+		ret = pwrseq_set_power(cfg->pwr_dev, true);
 		if (ret)
 			return ret;
 	}
@@ -342,37 +337,3 @@
 	.of_to_plat = meson_mmc_of_to_plat,
 	.plat_auto	= sizeof(struct meson_mmc_plat),
 };
-
-#ifdef CONFIG_PWRSEQ
-static int meson_mmc_pwrseq_set_power(struct udevice *dev, bool enable)
-{
-	struct gpio_desc reset;
-	int ret;
-
-	ret = gpio_request_by_name(dev, "reset-gpios", 0, &reset, GPIOD_IS_OUT);
-	if (ret)
-		return ret;
-	dm_gpio_set_value(&reset, 1);
-	udelay(1);
-	dm_gpio_set_value(&reset, 0);
-	udelay(200);
-
-	return 0;
-}
-
-static const struct pwrseq_ops meson_mmc_pwrseq_ops = {
-	.set_power	= meson_mmc_pwrseq_set_power,
-};
-
-static const struct udevice_id meson_mmc_pwrseq_ids[] = {
-	{ .compatible = "mmc-pwrseq-emmc" },
-	{ }
-};
-
-U_BOOT_DRIVER(meson_mmc_pwrseq_drv) = {
-	.name		= "mmc_pwrseq_emmc",
-	.id		= UCLASS_PWRSEQ,
-	.of_match	= meson_mmc_pwrseq_ids,
-	.ops		= &meson_mmc_pwrseq_ops,
-};
-#endif
diff --git a/drivers/mmc/mmc-pwrseq.c b/drivers/mmc/mmc-pwrseq.c
new file mode 100644
index 0000000..2539f61
--- /dev/null
+++ b/drivers/mmc/mmc-pwrseq.c
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2021 SAMSUNG Electronics
+ * Jaehoon Chung <jh80.chung@samsung.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <mmc.h>
+#include <pwrseq.h>
+#include <asm/gpio.h>
+#include <linux/delay.h>
+
+int mmc_pwrseq_get_power(struct udevice *dev, struct mmc_config *cfg)
+{
+	/* Enable power if needed */
+	return uclass_get_device_by_phandle(UCLASS_PWRSEQ, dev, "mmc-pwrseq",
+					   &cfg->pwr_dev);
+}
+
+static int mmc_pwrseq_set_power(struct udevice *dev, bool enable)
+{
+	struct gpio_desc reset;
+	int ret;
+
+	ret = gpio_request_by_name(dev, "reset-gpios", 0, &reset, GPIOD_IS_OUT);
+	if (ret)
+		return ret;
+	dm_gpio_set_value(&reset, 1);
+	udelay(1);
+	dm_gpio_set_value(&reset, 0);
+	udelay(200);
+
+	return 0;
+}
+
+static const struct pwrseq_ops mmc_pwrseq_ops = {
+	.set_power	= mmc_pwrseq_set_power,
+};
+
+static const struct udevice_id mmc_pwrseq_ids[] = {
+	{ .compatible = "mmc-pwrseq-emmc" },
+	{ }
+};
+
+U_BOOT_DRIVER(mmc_pwrseq_drv) = {
+	.name		= "mmc_pwrseq_emmc",
+	.id		= UCLASS_PWRSEQ,
+	.of_match	= mmc_pwrseq_ids,
+	.ops		= &mmc_pwrseq_ops,
+};
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 36aab50..b4c8e7f 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -841,7 +841,8 @@
 				 value);
 			return -EIO;
 		}
-		if (!ret && (status & MMC_STATUS_RDY_FOR_DATA))
+		if (!ret && (status & MMC_STATUS_RDY_FOR_DATA) &&
+		    (status & MMC_STATUS_CURR_STATE) == MMC_STATE_TRANS)
 			return 0;
 		udelay(100);
 	} while (get_timer(start) < timeout_ms);
@@ -2062,7 +2063,7 @@
 
 static int mmc_select_mode_and_width(struct mmc *mmc, uint card_caps)
 {
-	int err;
+	int err = 0;
 	const struct mode_width_tuning *mwt;
 	const struct ext_csd_bus_width *ecbw;
 
diff --git a/drivers/mmc/mmc_spi.c b/drivers/mmc/mmc_spi.c
index 46800bb..e2d7879 100644
--- a/drivers/mmc/mmc_spi.c
+++ b/drivers/mmc/mmc_spi.c
@@ -37,7 +37,8 @@
 #define SPI_RESPONSE_CRC_ERR		((5 << 1)|1)
 #define SPI_RESPONSE_WRITE_ERR		((6 << 1)|1)
 
-/* Read and write blocks start with these tokens and end with crc;
+/*
+ * Read and write blocks start with these tokens and end with crc;
  * on error, read tokens act like a subset of R2_SPI_* values.
  */
 /* single block write multiblock read */
@@ -70,6 +71,20 @@
 	struct spi_slave *spi;
 };
 
+/**
+ * mmc_spi_sendcmd() - send a command to the SD card
+ *
+ * @dev:	mmc_spi device
+ * @cmdidx:	command index
+ * @cmdarg:	command argument
+ * @resp_type:	card response type
+ * @resp:	buffer to store the card response
+ * @resp_size:	size of the card response
+ * @resp_match:	if true, compare each of received bytes with @resp_match_value
+ * @resp_match_value:	a value to be compared with each of received bytes
+ * @r1b:	if true, receive additional bytes for busy signal token
+ * @return 0 if OK, -ETIMEDOUT if no card response is received, -ve on error
+ */
 static int mmc_spi_sendcmd(struct udevice *dev,
 			   ushort cmdidx, u32 cmdarg, u32 resp_type,
 			   u8 *resp, u32 resp_size,
@@ -78,6 +93,9 @@
 	int i, rpos = 0, ret = 0;
 	u8 cmdo[7], r;
 
+	if (!resp || !resp_size)
+		return 0;
+
 	debug("%s: cmd%d cmdarg=0x%x resp_type=0x%x "
 	      "resp_size=%d resp_match=%d resp_match_value=0x%x\n",
 	      __func__, cmdidx, cmdarg, resp_type,
@@ -98,34 +116,33 @@
 	if (ret)
 		return ret;
 
-	if (!resp || !resp_size)
-		return 0;
-
 	debug("%s: cmd%d", __func__, cmdidx);
 
-	if (resp_match) {
+	if (resp_match)
 		r = ~resp_match_value;
-		i = CMD_TIMEOUT;
-		while (i) {
-			ret = dm_spi_xfer(dev, 1 * 8, NULL, &r, 0);
-			if (ret)
-				return ret;
-			debug(" resp%d=0x%x", rpos, r);
-			rpos++;
-			i--;
+	i = CMD_TIMEOUT;
+	while (i) {
+		ret = dm_spi_xfer(dev, 1 * 8, NULL, &r, 0);
+		if (ret)
+			return ret;
+		debug(" resp%d=0x%x", rpos, r);
+		rpos++;
+		i--;
 
+		if (resp_match) {
 			if (r == resp_match_value)
 				break;
+		} else {
+			if (!(r & 0x80))
+				break;
 		}
-		if (!i && (r != resp_match_value))
+
+		if (!i)
 			return -ETIMEDOUT;
 	}
 
-	for (i = 0; i < resp_size; i++) {
-		if (i == 0 && resp_match) {
-			resp[i] = resp_match_value;
-			continue;
-		}
+	resp[0] = r;
+	for (i = 1; i < resp_size; i++) {
 		ret = dm_spi_xfer(dev, 1 * 8, NULL, &r, 0);
 		if (ret)
 			return ret;
@@ -157,6 +174,15 @@
 	return 0;
 }
 
+/**
+ * mmc_spi_readdata() - read data block(s) from the SD card
+ *
+ * @dev:	mmc_spi device
+ * @xbuf:	buffer of the actual data (excluding token and crc) to read
+ * @bcnt:	number of data blocks to transfer
+ * @bsize:	size of the actual data (excluding token and crc) in bytes
+ * @return 0 if OK, -ECOMM if crc error, -ETIMEDOUT on other errors
+ */
 static int mmc_spi_readdata(struct udevice *dev,
 			    void *xbuf, u32 bcnt, u32 bsize)
 {
@@ -181,8 +207,10 @@
 			if (ret)
 				return ret;
 #ifdef CONFIG_MMC_SPI_CRC_ON
-			if (be16_to_cpu(crc16_ccitt(0, buf, bsize)) != crc) {
-				debug("%s: data crc error\n", __func__);
+			u16 crc_ok = be16_to_cpu(crc16_ccitt(0, buf, bsize));
+			if (crc_ok != crc) {
+				debug("%s: data crc error, expected %04x got %04x\n",
+				      __func__, crc_ok, crc);
 				r1 = R1_SPI_COM_CRC;
 				break;
 			}
@@ -203,6 +231,16 @@
 	return ret;
 }
 
+/**
+ * mmc_spi_writedata() - write data block(s) to the SD card
+ *
+ * @dev:	mmc_spi device
+ * @xbuf:	buffer of the actual data (excluding token and crc) to write
+ * @bcnt:	number of data blocks to transfer
+ * @bsize:	size of actual data (excluding token and crc) in bytes
+ * @multi:	indicate a transfer by multiple block write command (CMD25)
+ * @return 0 if OK, -ECOMM if crc error, -ETIMEDOUT on other errors
+ */
 static int mmc_spi_writedata(struct udevice *dev, const void *xbuf,
 			     u32 bcnt, u32 bsize, int multi)
 {
diff --git a/drivers/mmc/rockchip_dw_mmc.c b/drivers/mmc/rockchip_dw_mmc.c
index 1be3c17..d7d5361 100644
--- a/drivers/mmc/rockchip_dw_mmc.c
+++ b/drivers/mmc/rockchip_dw_mmc.c
@@ -105,7 +105,6 @@
 	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
 	struct rockchip_dwmmc_priv *priv = dev_get_priv(dev);
 	struct dwmci_host *host = &priv->host;
-	struct udevice *pwr_dev __maybe_unused;
 	int ret;
 
 #if CONFIG_IS_ENABLED(OF_PLATDATA)
@@ -136,12 +135,11 @@
 
 	host->fifo_mode = priv->fifo_mode;
 
-#ifdef CONFIG_PWRSEQ
+#ifdef CONFIG_MMC_PWRSEQ
 	/* Enable power if needed */
-	ret = uclass_get_device_by_phandle(UCLASS_PWRSEQ, dev, "mmc-pwrseq",
-					   &pwr_dev);
+	ret = mmc_pwrseq_get_power(dev, &plat->cfg);
 	if (!ret) {
-		ret = pwrseq_set_power(pwr_dev, true);
+		ret = pwrseq_set_power(plat->cfg.pwr_dev, true);
 		if (ret)
 			return ret;
 	}
@@ -182,37 +180,3 @@
 
 DM_DRIVER_ALIAS(rockchip_rk3288_dw_mshc, rockchip_rk3328_dw_mshc)
 DM_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)
-{
-	struct gpio_desc reset;
-	int ret;
-
-	ret = gpio_request_by_name(dev, "reset-gpios", 0, &reset, GPIOD_IS_OUT);
-	if (ret)
-		return ret;
-	dm_gpio_set_value(&reset, 1);
-	udelay(1);
-	dm_gpio_set_value(&reset, 0);
-	udelay(200);
-
-	return 0;
-}
-
-static const struct pwrseq_ops rockchip_dwmmc_pwrseq_ops = {
-	.set_power	= rockchip_dwmmc_pwrseq_set_power,
-};
-
-static const struct udevice_id rockchip_dwmmc_pwrseq_ids[] = {
-	{ .compatible = "mmc-pwrseq-emmc" },
-	{ }
-};
-
-U_BOOT_DRIVER(rockchip_dwmmc_pwrseq_drv) = {
-	.name		= "mmc_pwrseq_emmc",
-	.id		= UCLASS_PWRSEQ,
-	.of_match	= rockchip_dwmmc_pwrseq_ids,
-	.ops		= &rockchip_dwmmc_pwrseq_ops,
-};
-#endif
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index ed0dc17..d9ab6a0 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -74,6 +74,7 @@
 static void sdhci_prepare_dma(struct sdhci_host *host, struct mmc_data *data,
 			      int *is_aligned, int trans_bytes)
 {
+	dma_addr_t dma_addr;
 	unsigned char ctrl;
 	void *buf;
 
@@ -104,8 +105,8 @@
 					  mmc_get_dma_dir(data));
 
 	if (host->flags & USE_SDMA) {
-		sdhci_writel(host, phys_to_bus((ulong)host->start_addr),
-				SDHCI_DMA_ADDRESS);
+		dma_addr = dev_phys_to_bus(mmc_to_dev(host->mmc), host->start_addr);
+		sdhci_writel(host, dma_addr, SDHCI_DMA_ADDRESS);
 	}
 #if CONFIG_IS_ENABLED(MMC_SDHCI_ADMA)
 	else if (host->flags & (USE_ADMA | USE_ADMA64)) {
@@ -163,8 +164,9 @@
 				start_addr &=
 				~(SDHCI_DEFAULT_BOUNDARY_SIZE - 1);
 				start_addr += SDHCI_DEFAULT_BOUNDARY_SIZE;
-				sdhci_writel(host, phys_to_bus((ulong)start_addr),
-					     SDHCI_DMA_ADDRESS);
+				start_addr = dev_phys_to_bus(mmc_to_dev(host->mmc),
+							     start_addr);
+				sdhci_writel(host, start_addr, SDHCI_DMA_ADDRESS);
 			}
 		}
 		if (timeout-- > 0)
@@ -175,8 +177,10 @@
 		}
 	} while (!(stat & SDHCI_INT_DATA_END));
 
+#if (defined(CONFIG_MMC_SDHCI_SDMA) || CONFIG_IS_ENABLED(MMC_SDHCI_ADMA))
 	dma_unmap_single(host->start_addr, data->blocks * data->blocksize,
 			 mmc_get_dma_dir(data));
+#endif
 
 	return 0;
 }
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 971a572..0e84c22 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -37,6 +37,21 @@
 	  This is currently implemented in net/mdio-mux-uclass.c
 	  Look in include/miiphy.h for details.
 
+config DM_DSA
+	bool "Enable Driver Model for DSA switches"
+	depends on DM_ETH && DM_MDIO
+	depends on PHY_FIXED
+	help
+	  Enable driver model for DSA switches
+
+	  Adds UCLASS_DSA class supporting switches that follow the Distributed
+	  Switch Architecture (DSA).  These switches rely on the presence of a
+	  management switch port connected to an Ethernet controller capable of
+	  receiving frames from the switch.  This host Ethernet controller is
+	  called the "master" Ethernet interface in DSA terminology.
+	  This is currently implemented in net/dsa-uclass.c, refer to
+	  include/net/dsa.h for API details.
+
 config MDIO_SANDBOX
 	depends on DM_MDIO && SANDBOX
 	default y
diff --git a/drivers/net/fsl_enetc.h b/drivers/net/fsl_enetc.h
index 37e7e85..110c1d7 100644
--- a/drivers/net/fsl_enetc.h
+++ b/drivers/net/fsl_enetc.h
@@ -201,6 +201,11 @@
 /* PCS replicator block for USXGMII */
 #define ENETC_PCS_DEVAD_REPL		0x1f
 
+#define ENETC_PCS_REPL_LINK_TIMER_1	0x12
+#define  ENETC_PCS_REPL_LINK_TIMER_1_DEF	0x0003
+#define ENETC_PCS_REPL_LINK_TIMER_2	0x13
+#define  ENETC_PCS_REPL_LINK_TIMER_2_DEF	0x06a0
+
 /* ENETC external MDIO registers */
 #define ENETC_MDIO_BASE		0x1c00
 #define ENETC_MDIO_CFG		0x00
diff --git a/drivers/net/mscc_eswitch/Kconfig b/drivers/net/mscc_eswitch/Kconfig
index 80dd22f..ccf7822 100644
--- a/drivers/net/mscc_eswitch/Kconfig
+++ b/drivers/net/mscc_eswitch/Kconfig
@@ -36,3 +36,11 @@
 	select PHYLIB
 	help
 	  This driver supports the Serval network switch device.
+
+config MSCC_FELIX_SWITCH
+	bool "Felix switch driver"
+	depends on DM_DSA && DM_PCI
+	select FSL_ENETC
+	help
+	  This driver supports the Ethernet switch integrated in the
+	  NXP LS1028A SoC.
diff --git a/drivers/net/mscc_eswitch/Makefile b/drivers/net/mscc_eswitch/Makefile
index d583fe9..22342ed 100644
--- a/drivers/net/mscc_eswitch/Makefile
+++ b/drivers/net/mscc_eswitch/Makefile
@@ -4,3 +4,4 @@
 obj-$(CONFIG_MSCC_JR2_SWITCH) += jr2_switch.o mscc_xfer.o mscc_miim.o
 obj-$(CONFIG_MSCC_SERVALT_SWITCH) += servalt_switch.o mscc_xfer.o mscc_miim.o
 obj-$(CONFIG_MSCC_SERVAL_SWITCH) += serval_switch.o mscc_xfer.o mscc_mac_table.o mscc_miim.o
+obj-$(CONFIG_MSCC_FELIX_SWITCH) += felix_switch.o
diff --git a/drivers/net/mscc_eswitch/felix_switch.c b/drivers/net/mscc_eswitch/felix_switch.c
new file mode 100644
index 0000000..f20e84e
--- /dev/null
+++ b/drivers/net/mscc_eswitch/felix_switch.c
@@ -0,0 +1,414 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * Felix (VSC9959) Ethernet switch driver
+ * Copyright 2018-2021 NXP Semiconductors
+ */
+
+/*
+ * This driver is used for the Ethernet switch integrated into NXP LS1028A.
+ * Felix switch is derived from Microsemi Ocelot but there are several NXP
+ * adaptations that makes the two U-Boot drivers largely incompatible.
+ *
+ * Felix on LS1028A has 4 front panel ports and two internal ports, connected
+ * to ENETC interfaces.  We're using one of the ENETC interfaces to push traffic
+ * into the switch.  Injection/extraction headers are used to identify
+ * egress/ingress ports in the switch for Tx/Rx.
+ */
+
+#include <dm/device_compat.h>
+#include <linux/delay.h>
+#include <net/dsa.h>
+#include <asm/io.h>
+#include <miiphy.h>
+#include <pci.h>
+
+/* defines especially around PCS are reused from enetc */
+#include "../fsl_enetc.h"
+
+#define PCI_DEVICE_ID_FELIX_ETHSW	0xEEF0
+
+/* Felix has in fact 6 ports, but we don't use the last internal one */
+#define FELIX_PORT_COUNT		5
+/* Front panel port mask */
+#define FELIX_FP_PORT_MASK		0xf
+
+/* Register map for BAR4 */
+#define FELIX_SYS			0x010000
+#define FELIX_ES0			0x040000
+#define FELIX_IS1			0x050000
+#define FELIX_IS2			0x060000
+#define FELIX_GMII(port)		(0x100000 + (port) * 0x10000)
+#define FELIX_QSYS			0x200000
+
+#define FELIX_SYS_SYSTEM		(FELIX_SYS + 0x00000E00)
+#define  FELIX_SYS_SYSTEM_EN		BIT(0)
+#define FELIX_SYS_RAM_CTRL		(FELIX_SYS + 0x00000F24)
+#define  FELIX_SYS_RAM_CTRL_INIT	BIT(1)
+#define FELIX_SYS_SYSTEM_PORT_MODE(a)	(FELIX_SYS_SYSTEM + 0xC + (a) * 4)
+#define  FELIX_SYS_SYSTEM_PORT_MODE_CPU	0x0000001e
+
+#define FELIX_ES0_TCAM_CTRL		(FELIX_ES0 + 0x000003C0)
+#define  FELIX_ES0_TCAM_CTRL_EN		BIT(0)
+#define FELIX_IS1_TCAM_CTRL		(FELIX_IS1 + 0x000003C0)
+#define  FELIX_IS1_TCAM_CTRL_EN		BIT(0)
+#define FELIX_IS2_TCAM_CTRL		(FELIX_IS2 + 0x000003C0)
+#define  FELIX_IS2_TCAM_CTRL_EN		BIT(0)
+
+#define FELIX_GMII_CLOCK_CFG(port)	(FELIX_GMII(port) + 0x00000000)
+#define  FELIX_GMII_CLOCK_CFG_LINK_1G	1
+#define  FELIX_GMII_CLOCK_CFG_LINK_100M	2
+#define  FELIX_GMII_CLOCK_CFG_LINK_10M	3
+#define FELIX_GMII_MAC_ENA_CFG(port)	(FELIX_GMII(port) + 0x0000001C)
+#define  FELIX_GMII_MAX_ENA_CFG_TX	BIT(0)
+#define  FELIX_GMII_MAX_ENA_CFG_RX	BIT(4)
+#define FELIX_GMII_MAC_IFG_CFG(port)	(FELIX_GMII(port) + 0x0000001C + 0x14)
+#define  FELIX_GMII_MAC_IFG_CFG_DEF	0x515
+
+#define FELIX_QSYS_SYSTEM		(FELIX_QSYS + 0x0000F460)
+#define FELIX_QSYS_SYSTEM_SW_PORT_MODE(a)	\
+					(FELIX_QSYS_SYSTEM + 0x20 + (a) * 4)
+#define  FELIX_QSYS_SYSTEM_SW_PORT_ENA		BIT(14)
+#define  FELIX_QSYS_SYSTEM_SW_PORT_LOSSY	BIT(9)
+#define  FELIX_QSYS_SYSTEM_SW_PORT_SCH(a)	(((a) & 0x3800) << 11)
+#define FELIX_QSYS_SYSTEM_EXT_CPU_CFG	(FELIX_QSYS_SYSTEM + 0x80)
+#define  FELIX_QSYS_SYSTEM_EXT_CPU_PORT(a)	(((a) & 0xf) << 8 | 0xff)
+
+/* internal MDIO in BAR0 */
+#define FELIX_PM_IMDIO_BASE		0x8030
+
+/* Serdes block on LS1028A */
+#define FELIX_SERDES_BASE		0x1ea0000L
+#define FELIX_SERDES_LNATECR0(lane)	(FELIX_SERDES_BASE + 0x818 + \
+					 (lane) * 0x40)
+#define  FELIX_SERDES_LNATECR0_ADPT_EQ	0x00003000
+#define FELIX_SERDES_SGMIICR1(lane)	(FELIX_SERDES_BASE + 0x1804 + \
+					 (lane) * 0x10)
+#define  FELIX_SERDES_SGMIICR1_SGPCS	BIT(11)
+#define  FELIX_SERDES_SGMIICR1_MDEV(a)	(((a) & 0x1f) << 27)
+
+#define FELIX_PCS_CTRL			0
+#define  FELIX_PCS_CTRL_RST		BIT(15)
+
+/*
+ * The long prefix format used here contains two dummy MAC addresses, a magic
+ * value in place of a VLAN tag followed by the extraction/injection header and
+ * the original L2 frame.  Out of all this we only use the port ID.
+ */
+#define FELIX_DSA_TAG_LEN		sizeof(struct felix_dsa_tag)
+#define FELIX_DSA_TAG_MAGIC		0x0a008088
+#define FELIX_DSA_TAG_INJ_PORT		7
+#define  FELIX_DSA_TAG_INJ_PORT_SET(a)	(0x1 << ((a) & FELIX_FP_PORT_MASK))
+#define FELIX_DSA_TAG_EXT_PORT		10
+#define  FELIX_DSA_TAG_EXT_PORT_GET(a)	((a) >> 3)
+
+struct felix_dsa_tag {
+	uchar d_mac[6];
+	uchar s_mac[6];
+	u32   magic;
+	uchar meta[16];
+};
+
+struct felix_priv {
+	void *regs_base;
+	void *imdio_base;
+	struct mii_dev imdio;
+};
+
+/* MDIO wrappers, we're using these to drive internal MDIO to get to serdes */
+static int felix_mdio_read(struct mii_dev *bus, int addr, int devad, int reg)
+{
+	struct enetc_mdio_priv priv;
+
+	priv.regs_base = bus->priv;
+	return enetc_mdio_read_priv(&priv, addr, devad, reg);
+}
+
+static int felix_mdio_write(struct mii_dev *bus, int addr, int devad, int reg,
+			    u16 val)
+{
+	struct enetc_mdio_priv priv;
+
+	priv.regs_base = bus->priv;
+	return enetc_mdio_write_priv(&priv, addr, devad, reg, val);
+}
+
+/* set up serdes for SGMII */
+static void felix_init_sgmii(struct mii_dev *imdio, int pidx, bool an)
+{
+	u16 reg;
+
+	/* set up PCS lane address */
+	out_le32(FELIX_SERDES_SGMIICR1(pidx), FELIX_SERDES_SGMIICR1_SGPCS |
+		 FELIX_SERDES_SGMIICR1_MDEV(pidx));
+
+	/*
+	 * Set to SGMII mode, for 1Gbps enable AN, for 2.5Gbps set fixed speed.
+	 * Although fixed speed is 1Gbps, we could be running at 2.5Gbps based
+	 * on PLL configuration.  Setting 1G for 2.5G here is counter intuitive
+	 * but intentional.
+	 */
+	reg = ENETC_PCS_IF_MODE_SGMII;
+	reg |= an ? ENETC_PCS_IF_MODE_SGMII_AN : ENETC_PCS_IF_MODE_SPEED_1G;
+	felix_mdio_write(imdio, pidx, MDIO_DEVAD_NONE,
+			 ENETC_PCS_IF_MODE, reg);
+
+	/* Dev ability - SGMII */
+	felix_mdio_write(imdio, pidx, MDIO_DEVAD_NONE,
+			 ENETC_PCS_DEV_ABILITY, ENETC_PCS_DEV_ABILITY_SGMII);
+
+	/* Adjust link timer for SGMII */
+	felix_mdio_write(imdio, pidx, MDIO_DEVAD_NONE,
+			 ENETC_PCS_LINK_TIMER1, ENETC_PCS_LINK_TIMER1_VAL);
+	felix_mdio_write(imdio, pidx, MDIO_DEVAD_NONE,
+			 ENETC_PCS_LINK_TIMER2, ENETC_PCS_LINK_TIMER2_VAL);
+
+	reg = ENETC_PCS_CR_DEF_VAL;
+	reg |= an ? ENETC_PCS_CR_RESET_AN : ENETC_PCS_CR_RST;
+	/* restart PCS AN */
+	felix_mdio_write(imdio, pidx, MDIO_DEVAD_NONE,
+			 ENETC_PCS_CR, reg);
+}
+
+/* set up MAC and serdes for (Q)SXGMII */
+static int felix_init_sxgmii(struct mii_dev *imdio, int pidx)
+{
+	int timeout = 1000;
+
+	/* set up transit equalization control on serdes lane */
+	out_le32(FELIX_SERDES_LNATECR0(1), FELIX_SERDES_LNATECR0_ADPT_EQ);
+
+	/*reset lane */
+	felix_mdio_write(imdio, pidx, MDIO_MMD_PCS, FELIX_PCS_CTRL,
+			 FELIX_PCS_CTRL_RST);
+	while (felix_mdio_read(imdio, pidx, MDIO_MMD_PCS,
+			       FELIX_PCS_CTRL) & FELIX_PCS_CTRL_RST &&
+			--timeout) {
+		mdelay(10);
+	}
+	if (felix_mdio_read(imdio, pidx, MDIO_MMD_PCS,
+			    FELIX_PCS_CTRL) & FELIX_PCS_CTRL_RST)
+		return -ETIME;
+
+	/* Dev ability - SXGMII */
+	felix_mdio_write(imdio, pidx, ENETC_PCS_DEVAD_REPL,
+			 ENETC_PCS_DEV_ABILITY, ENETC_PCS_DEV_ABILITY_SXGMII);
+
+	/* Restart PCS AN */
+	felix_mdio_write(imdio, pidx, ENETC_PCS_DEVAD_REPL, ENETC_PCS_CR,
+			 ENETC_PCS_CR_RST | ENETC_PCS_CR_RESET_AN);
+	felix_mdio_write(imdio, pidx, ENETC_PCS_DEVAD_REPL,
+			 ENETC_PCS_REPL_LINK_TIMER_1,
+			 ENETC_PCS_REPL_LINK_TIMER_1_DEF);
+	felix_mdio_write(imdio, pidx, ENETC_PCS_DEVAD_REPL,
+			 ENETC_PCS_REPL_LINK_TIMER_2,
+			 ENETC_PCS_REPL_LINK_TIMER_2_DEF);
+
+	return 0;
+}
+
+/* Apply protocol specific configuration to MAC, serdes as needed */
+static void felix_start_pcs(struct udevice *dev, int port,
+			    struct phy_device *phy, struct mii_dev *imdio)
+{
+	bool autoneg = true;
+
+	if (phy->phy_id == PHY_FIXED_ID ||
+	    phy->interface == PHY_INTERFACE_MODE_SGMII_2500)
+		autoneg = false;
+
+	switch (phy->interface) {
+	case PHY_INTERFACE_MODE_SGMII:
+	case PHY_INTERFACE_MODE_SGMII_2500:
+	case PHY_INTERFACE_MODE_QSGMII:
+		felix_init_sgmii(imdio, port, autoneg);
+		break;
+	case PHY_INTERFACE_MODE_XGMII:
+	case PHY_INTERFACE_MODE_XFI:
+	case PHY_INTERFACE_MODE_USXGMII:
+		if (felix_init_sxgmii(imdio, port))
+			dev_err(dev, "PCS reset timeout on port %d\n", port);
+		break;
+	default:
+		break;
+	}
+}
+
+void felix_init(struct udevice *dev)
+{
+	struct dsa_pdata *pdata = dev_get_uclass_plat(dev);
+	struct felix_priv *priv = dev_get_priv(dev);
+	void *base = priv->regs_base;
+	int timeout = 100;
+
+	/* Init core memories */
+	out_le32(base + FELIX_SYS_RAM_CTRL, FELIX_SYS_RAM_CTRL_INIT);
+	while (in_le32(base + FELIX_SYS_RAM_CTRL) & FELIX_SYS_RAM_CTRL_INIT &&
+	       --timeout)
+		udelay(10);
+	if (in_le32(base + FELIX_SYS_RAM_CTRL) & FELIX_SYS_RAM_CTRL_INIT)
+		dev_err(dev, "Timeout waiting for switch memories\n");
+
+	/* Start switch core, set up ES0, IS1, IS2 */
+	out_le32(base + FELIX_SYS_SYSTEM, FELIX_SYS_SYSTEM_EN);
+	out_le32(base + FELIX_ES0_TCAM_CTRL, FELIX_ES0_TCAM_CTRL_EN);
+	out_le32(base + FELIX_IS1_TCAM_CTRL, FELIX_IS1_TCAM_CTRL_EN);
+	out_le32(base + FELIX_IS2_TCAM_CTRL, FELIX_IS2_TCAM_CTRL_EN);
+	udelay(20);
+
+	priv->imdio.read = felix_mdio_read;
+	priv->imdio.write = felix_mdio_write;
+	priv->imdio.priv = priv->imdio_base + FELIX_PM_IMDIO_BASE;
+	strncpy(priv->imdio.name, dev->name, MDIO_NAME_LEN);
+
+	/* set up CPU port */
+	out_le32(base + FELIX_QSYS_SYSTEM_EXT_CPU_CFG,
+		 FELIX_QSYS_SYSTEM_EXT_CPU_PORT(pdata->cpu_port));
+	out_le32(base + FELIX_SYS_SYSTEM_PORT_MODE(pdata->cpu_port),
+		 FELIX_SYS_SYSTEM_PORT_MODE_CPU);
+}
+
+/*
+ * Probe Felix:
+ * - enable the PCI function
+ * - map BAR 4
+ * - init switch core and port registers
+ */
+static int felix_probe(struct udevice *dev)
+{
+	struct felix_priv *priv = dev_get_priv(dev);
+
+	if (ofnode_valid(dev_ofnode(dev)) &&
+	    !ofnode_is_available(dev_ofnode(dev))) {
+		dev_dbg(dev, "switch disabled\n");
+		return -ENODEV;
+	}
+
+	priv->imdio_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, 0);
+	if (!priv->imdio_base) {
+		dev_err(dev, "failed to map BAR0\n");
+		return -EINVAL;
+	}
+
+	priv->regs_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_4, 0);
+	if (!priv->regs_base) {
+		dev_err(dev, "failed to map BAR4\n");
+		return -EINVAL;
+	}
+
+	/* register internal MDIO for debug */
+	if (!miiphy_get_dev_by_name(dev->name)) {
+		struct mii_dev *mii_bus;
+
+		mii_bus = mdio_alloc();
+		mii_bus->read = felix_mdio_read;
+		mii_bus->write = felix_mdio_write;
+		mii_bus->priv = priv->imdio_base + FELIX_PM_IMDIO_BASE;
+		strncpy(mii_bus->name, dev->name, MDIO_NAME_LEN);
+		mdio_register(mii_bus);
+	}
+
+	dm_pci_clrset_config16(dev, PCI_COMMAND, 0, PCI_COMMAND_MEMORY);
+
+	dsa_set_tagging(dev, FELIX_DSA_TAG_LEN, 0);
+
+	/* set up registers */
+	felix_init(dev);
+
+	return 0;
+}
+
+static int felix_port_enable(struct udevice *dev, int port,
+			     struct phy_device *phy)
+{
+	int supported = PHY_GBIT_FEATURES | SUPPORTED_2500baseX_Full;
+	struct felix_priv *priv = dev_get_priv(dev);
+	void *base = priv->regs_base;
+
+	/* Set up MAC registers */
+	out_le32(base + FELIX_GMII_CLOCK_CFG(port),
+		 FELIX_GMII_CLOCK_CFG_LINK_1G);
+
+	out_le32(base + FELIX_GMII_MAC_IFG_CFG(port),
+		 FELIX_GMII_MAC_IFG_CFG_DEF);
+
+	out_le32(base + FELIX_GMII_MAC_ENA_CFG(port),
+		 FELIX_GMII_MAX_ENA_CFG_TX | FELIX_GMII_MAX_ENA_CFG_RX);
+
+	out_le32(base + FELIX_QSYS_SYSTEM_SW_PORT_MODE(port),
+		 FELIX_QSYS_SYSTEM_SW_PORT_ENA |
+		 FELIX_QSYS_SYSTEM_SW_PORT_LOSSY |
+		 FELIX_QSYS_SYSTEM_SW_PORT_SCH(1));
+
+	felix_start_pcs(dev, port, phy, &priv->imdio);
+
+	phy->supported &= supported;
+	phy->advertising &= supported;
+	phy_config(phy);
+
+	phy_startup(phy);
+
+	return 0;
+}
+
+static void felix_port_disable(struct udevice *dev, int pidx,
+			       struct phy_device *phy)
+{
+	struct felix_priv *priv = dev_get_priv(dev);
+	void *base = priv->regs_base;
+
+	out_le32(base + FELIX_GMII_MAC_ENA_CFG(pidx), 0);
+
+	out_le32(base + FELIX_QSYS_SYSTEM_SW_PORT_MODE(pidx),
+		 FELIX_QSYS_SYSTEM_SW_PORT_LOSSY |
+		 FELIX_QSYS_SYSTEM_SW_PORT_SCH(1));
+
+	/*
+	 * we don't call phy_shutdown here to avoid waiting next time we use
+	 * the port, but the downside is that remote side will think we're
+	 * actively processing traffic although we are not.
+	 */
+}
+
+static int felix_xmit(struct udevice *dev, int pidx, void *packet, int length)
+{
+	struct felix_dsa_tag *tag = packet;
+
+	tag->magic = FELIX_DSA_TAG_MAGIC;
+	tag->meta[FELIX_DSA_TAG_INJ_PORT] = FELIX_DSA_TAG_INJ_PORT_SET(pidx);
+
+	return 0;
+}
+
+static int felix_rcv(struct udevice *dev, int *pidx, void *packet, int length)
+{
+	struct felix_dsa_tag *tag = packet;
+
+	if (tag->magic != FELIX_DSA_TAG_MAGIC)
+		return -EINVAL;
+
+	*pidx = FELIX_DSA_TAG_EXT_PORT_GET(tag->meta[FELIX_DSA_TAG_EXT_PORT]);
+
+	return 0;
+}
+
+static const struct dsa_ops felix_dsa_ops = {
+	.port_enable	= felix_port_enable,
+	.port_disable	= felix_port_disable,
+	.xmit		= felix_xmit,
+	.rcv		= felix_rcv,
+};
+
+U_BOOT_DRIVER(felix_ethsw) = {
+	.name		= "felix-switch",
+	.id		= UCLASS_DSA,
+	.probe		= felix_probe,
+	.ops		= &felix_dsa_ops,
+	.priv_auto	= sizeof(struct felix_priv),
+};
+
+static struct pci_device_id felix_ethsw_ids[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, PCI_DEVICE_ID_FELIX_ETHSW) },
+	{}
+};
+
+U_BOOT_PCI_DEVICE(felix_ethsw, felix_ethsw_ids);
diff --git a/drivers/net/phy/fixed.c b/drivers/net/phy/fixed.c
index 3228672..1a38c29 100644
--- a/drivers/net/phy/fixed.c
+++ b/drivers/net/phy/fixed.c
@@ -24,7 +24,8 @@
 	/* check for mandatory properties within fixed-link node */
 	val = fdt_getprop_u32_default_node(gd->fdt_blob,
 					   ofnode, 0, "speed", 0);
-	if (val != SPEED_10 && val != SPEED_100 && val != SPEED_1000) {
+	if (val != SPEED_10 && val != SPEED_100 && val != SPEED_1000 &&
+	    val != SPEED_2500 && val != SPEED_10000) {
 		printf("ERROR: no/invalid speed given in fixed-link node!");
 		return -EINVAL;
 	}
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index a2be398..89e3076 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -977,6 +977,37 @@
 #endif
 
 #ifdef CONFIG_PHY_FIXED
+/**
+ * fixed_phy_create() - create an unconnected fixed-link pseudo-PHY device
+ * @node: OF node for the container of the fixed-link node
+ *
+ * Description: Creates a struct phy_device based on a fixed-link of_node
+ * description. Can be used without phy_connect by drivers which do not expose
+ * a UCLASS_ETH udevice.
+ */
+struct phy_device *fixed_phy_create(ofnode node)
+{
+	phy_interface_t interface = PHY_INTERFACE_MODE_NONE;
+	const char *if_str;
+	ofnode subnode;
+
+	if_str = ofnode_read_string(node, "phy-mode");
+	if (!if_str) {
+		if_str = ofnode_read_string(node, "phy-interface-type");
+	}
+	if (if_str) {
+		interface = phy_get_interface_by_name(if_str);
+	}
+
+	subnode = ofnode_find_subnode(node, "fixed-link");
+	if (!ofnode_valid(subnode)) {
+		return NULL;
+	}
+
+	return phy_device_create(NULL, ofnode_to_offset(subnode), PHY_FIXED_ID,
+				 false, interface);
+}
+
 #ifdef CONFIG_DM_ETH
 static struct phy_device *phy_connect_fixed(struct mii_dev *bus,
 					    struct udevice *dev,
diff --git a/drivers/net/qe/dm_qe_uec.c b/drivers/net/qe/dm_qe_uec.c
index b08c792..eb0501b 100644
--- a/drivers/net/qe/dm_qe_uec.c
+++ b/drivers/net/qe/dm_qe_uec.c
@@ -172,8 +172,8 @@
 			break;
 		default:
 			return -EINVAL;
-	}
-	break;
+		}
+		break;
 	case SPEED_1000:
 		maccfg2 |= MACCFG2_INTERFACE_MODE_BYTE;
 		switch (enet_if_mode) {
diff --git a/drivers/net/qe/uec.h b/drivers/net/qe/uec.h
index 7cd4b87..32b7d3e 100644
--- a/drivers/net/qe/uec.h
+++ b/drivers/net/qe/uec.h
@@ -678,7 +678,7 @@
 	int				grace_stopped_tx;
 	int				grace_stopped_rx;
 	int				the_first_run;
-#if !defined(COFIG_DM)
+#if !defined(CONFIG_DM)
 	/* PHY specific */
 	struct uec_mii_info		*mii_info;
 	int				oldspeed;
diff --git a/drivers/pci/pci-rcar-gen3.c b/drivers/pci/pci-rcar-gen3.c
index 0d5b01f..34a561e 100644
--- a/drivers/pci/pci-rcar-gen3.c
+++ b/drivers/pci/pci-rcar-gen3.c
@@ -23,6 +23,7 @@
 #include <pci.h>
 #include <wait_bit.h>
 #include <linux/bitops.h>
+#include <linux/log2.h>
 
 #define PCIECAR			0x000010
 #define PCIECCTLR		0x000018
@@ -151,6 +152,16 @@
 	struct rcar_gen3_pcie_priv *priv = dev_get_plat(udev);
 	u32 reg = where & ~3;
 
+	/* Root bus */
+	if (PCI_DEV(bdf) == 0) {
+		if (access_type == RCAR_PCI_ACCESS_READ)
+			*data = readl(priv->regs + PCICONF(where / 4));
+		else
+			writel(*data, priv->regs + PCICONF(where / 4));
+
+		return 0;
+	}
+
 	/* Clear errors */
 	clrbits_le32(priv->regs + PCIEERRFR, 0);
 
@@ -187,11 +198,14 @@
 {
 	u32 slot;
 
+	if (PCI_BUS(d))
+		return -EINVAL;
+
 	if (PCI_FUNC(d))
 		return -EINVAL;
 
 	slot = PCI_DEV(d);
-	if (slot != 1)
+	if (slot > 1)
 		return -EINVAL;
 
 	return 0;
@@ -334,17 +348,19 @@
 		if (hose->regions[i].phys_start == 0)
 			continue;
 
-		mask = (hose->regions[i].size - 1) & ~0xf;
+		mask = (roundup_pow_of_two(hose->regions[i].size) - 1) & ~0xf;
 		mask |= LAR_ENABLE;
-		writel(hose->regions[i].phys_start, priv->regs + PCIEPRAR(0));
-		writel(hose->regions[i].phys_start, priv->regs + PCIELAR(0));
+		writel(rounddown_pow_of_two(hose->regions[i].phys_start),
+			priv->regs + PCIEPRAR(0));
+		writel(rounddown_pow_of_two(hose->regions[i].phys_start),
+			priv->regs + PCIELAR(0));
 		writel(mask, priv->regs + PCIELAMR(0));
 		break;
 	}
 
-	writel(0, priv->regs + PCIEPRAR(4));
-	writel(0, priv->regs + PCIELAR(4));
-	writel(0, priv->regs + PCIELAMR(4));
+	writel(0, priv->regs + PCIEPRAR(1));
+	writel(0, priv->regs + PCIELAR(1));
+	writel(0, priv->regs + PCIELAMR(1));
 
 	ret = rcar_gen3_pcie_hw_init(dev);
 	if (ret)
diff --git a/drivers/pci/pcie_brcmstb.c b/drivers/pci/pcie_brcmstb.c
index dd2a4ef..90225f6 100644
--- a/drivers/pci/pcie_brcmstb.c
+++ b/drivers/pci/pcie_brcmstb.c
@@ -432,6 +432,7 @@
 	struct pci_controller *hose = dev_get_uclass_priv(ctlr);
 	struct brcm_pcie *pcie = dev_get_priv(dev);
 	void __iomem *base = pcie->base;
+	struct pci_region region;
 	bool ssc_good = false;
 	int num_out_wins = 0;
 	u64 rc_bar2_offset, rc_bar2_size;
@@ -468,13 +469,10 @@
 			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;
+
+	pci_get_dma_regions(dev, &region, 0);
+	rc_bar2_offset = region.bus_start - region.phys_start;
+	rc_bar2_size = 1ULL << fls64(region.size - 1);
 
 	tmp = lower_32_bits(rc_bar2_offset);
 	u32p_replace_bits(&tmp, brcm_pcie_encode_ibar_size(rc_bar2_size),
@@ -579,6 +577,24 @@
 	return 0;
 }
 
+static int brcm_pcie_remove(struct udevice *dev)
+{
+	struct brcm_pcie *pcie = dev_get_priv(dev);
+	void __iomem *base = pcie->base;
+
+	/* Assert fundamental reset */
+	setbits_le32(base + PCIE_RGR1_SW_INIT_1, RGR1_SW_INIT_1_PERST_MASK);
+
+	/* Turn off SerDes */
+	setbits_le32(base + PCIE_MISC_HARD_PCIE_HARD_DEBUG,
+		     PCIE_HARD_DEBUG_SERDES_IDDQ_MASK);
+
+	/* Shutdown bridge */
+	setbits_le32(base + PCIE_RGR1_SW_INIT_1, RGR1_SW_INIT_1_INIT_MASK);
+
+	return 0;
+}
+
 static int brcm_pcie_of_to_plat(struct udevice *dev)
 {
 	struct brcm_pcie *pcie = dev_get_priv(dev);
@@ -618,6 +634,8 @@
 	.ops			= &brcm_pcie_ops,
 	.of_match		= brcm_pcie_ids,
 	.probe			= brcm_pcie_probe,
+	.remove			= brcm_pcie_remove,
 	.of_to_plat	= brcm_pcie_of_to_plat,
 	.priv_auto	= sizeof(struct brcm_pcie),
+	.flags		= DM_FLAG_OS_PREPARE,
 };
diff --git a/drivers/power/palmas.c b/drivers/power/palmas.c
index 2584bea..bf91739 100644
--- a/drivers/power/palmas.c
+++ b/drivers/power/palmas.c
@@ -176,7 +176,7 @@
 	return err;
 }
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 int palmas_i2c_write_u8(u8 chip_no, u8 reg, u8 val)
 {
 	struct udevice *dev;
diff --git a/drivers/power/pmic/pmic_tps62362.c b/drivers/power/pmic/pmic_tps62362.c
index c3977fc..76fd14d 100644
--- a/drivers/power/pmic/pmic_tps62362.c
+++ b/drivers/power/pmic/pmic_tps62362.c
@@ -10,7 +10,7 @@
 #include <power/pmic.h>
 #include <power/tps62362.h>
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 struct udevice *tps62362_dev __attribute__((section(".data"))) = NULL;
 #endif
 
@@ -26,7 +26,7 @@
 	if (reg > TPS62362_NUM_REGS)
 		return 1;
 
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	return i2c_write(TPS62362_I2C_ADDR, reg, 1, &volt_sel, 1);
 #else
 	if (!tps62362_dev)
@@ -35,7 +35,7 @@
 #endif
 }
 
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 int power_tps62362_init(unsigned char bus)
 {
 	static const char name[] = "TPS62362";
diff --git a/drivers/power/pmic/pmic_tps65217.c b/drivers/power/pmic/pmic_tps65217.c
index c839e31..54b5bed 100644
--- a/drivers/power/pmic/pmic_tps65217.c
+++ b/drivers/power/pmic/pmic_tps65217.c
@@ -18,7 +18,7 @@
  */
 int tps65217_reg_read(uchar src_reg, uchar *src_val)
 {
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	return i2c_read(TPS65217_CHIP_PM, src_reg, 1, src_val, 1);
 #else
 	return dm_i2c_read(tps65217_dev, src_reg,  src_val, 1);
@@ -52,7 +52,7 @@
 	 * mask
 	 */
 	if (mask != TPS65217_MASK_ALL_BITS) {
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 		ret = i2c_read(TPS65217_CHIP_PM, dest_reg, 1, &read_val, 1);
 #else
 		ret = dm_i2c_read(tps65217_dev, dest_reg, &read_val, 1);
@@ -67,7 +67,7 @@
 
 	if (prot_level > 0) {
 		xor_reg = dest_reg ^ TPS65217_PASSWORD_UNLOCK;
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 		ret = i2c_write(TPS65217_CHIP_PM, TPS65217_PASSWORD, 1,
 				&xor_reg, 1);
 #else
@@ -77,7 +77,7 @@
 		if (ret)
 			return ret;
 	}
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	ret = i2c_write(TPS65217_CHIP_PM, dest_reg, 1, &dest_val, 1);
 #else
 	ret = dm_i2c_write(tps65217_dev, dest_reg, &dest_val, 1);
@@ -86,7 +86,7 @@
 		return ret;
 
 	if (prot_level == TPS65217_PROT_LEVEL_2) {
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 		ret = i2c_write(TPS65217_CHIP_PM, TPS65217_PASSWORD, 1,
 				&xor_reg, 1);
 #else
@@ -96,7 +96,7 @@
 		if (ret)
 			return ret;
 
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 		ret = i2c_write(TPS65217_CHIP_PM, dest_reg, 1, &dest_val, 1);
 #else
 		ret = dm_i2c_write(tps65217_dev, dest_reg, &dest_val, 1);
@@ -137,7 +137,7 @@
 
 int power_tps65217_init(unsigned char bus)
 {
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	struct udevice *dev = NULL;
 	int rc;
 
diff --git a/drivers/power/pmic/pmic_tps65218.c b/drivers/power/pmic/pmic_tps65218.c
index 7c95e5e..f8bae45 100644
--- a/drivers/power/pmic/pmic_tps65218.c
+++ b/drivers/power/pmic/pmic_tps65218.c
@@ -10,7 +10,7 @@
 #include <power/pmic.h>
 #include <power/tps65218.h>
 
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 int tps65218_reg_read(uchar dest_reg, uchar *dest_val)
 {
 	uchar read_val;
@@ -225,7 +225,7 @@
 	return 0;
 }
 
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 int power_tps65218_init(unsigned char bus)
 {
 	static const char name[] = "TPS65218_PMIC";
diff --git a/drivers/power/pmic/pmic_tps65910.c b/drivers/power/pmic/pmic_tps65910.c
index 4772de1..84a58c2 100644
--- a/drivers/power/pmic/pmic_tps65910.c
+++ b/drivers/power/pmic/pmic_tps65910.c
@@ -12,7 +12,7 @@
 
 static inline int tps65910_read_reg(int addr, uchar *buf)
 {
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	return i2c_read(TPS65910_CTRL_I2C_ADDR, addr, 1, buf, 1);
 #else
 	int rc;
@@ -27,7 +27,7 @@
 
 static inline int tps65910_write_reg(int addr, uchar *buf)
 {
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	return i2c_write(TPS65910_CTRL_I2C_ADDR, addr, 1, buf, 1);
 #else
 	return dm_i2c_reg_write(tps65910_dev, addr, *buf);
@@ -36,7 +36,7 @@
 
 int power_tps65910_init(unsigned char bus)
 {
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	struct udevice *dev = NULL;
 	int rc;
 
diff --git a/drivers/power/twl4030.c b/drivers/power/twl4030.c
index f48af84..d3e8949 100644
--- a/drivers/power/twl4030.c
+++ b/drivers/power/twl4030.c
@@ -182,7 +182,7 @@
 }
 #endif
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 int twl4030_i2c_write_u8(u8 chip_no, u8 reg, u8 val)
 {
 	struct udevice *dev;
diff --git a/drivers/power/twl6030.c b/drivers/power/twl6030.c
index 60a5aaa..2b50a56 100644
--- a/drivers/power/twl6030.c
+++ b/drivers/power/twl6030.c
@@ -270,7 +270,7 @@
 	twl6030_i2c_write_u8(TWL6030_CHIP_PM, TWL6030_MISC2, value);
 }
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 int twl6030_i2c_write_u8(u8 chip_no, u8 reg, u8 val)
 {
 	struct udevice *dev;
diff --git a/drivers/rng/Kconfig b/drivers/rng/Kconfig
index 11001c8..94915d4 100644
--- a/drivers/rng/Kconfig
+++ b/drivers/rng/Kconfig
@@ -46,4 +46,10 @@
 	  Enable random number generator for rockchip.This driver is
 	  support rng module of crypto v1 and crypto v2.
 
+config RNG_IPROC200
+	bool "Broadcom iProc RNG200 random number generator"
+	depends on DM_RNG
+	default n
+	help
+	  Enable random number generator for RPI4.
 endif
diff --git a/drivers/rng/Makefile b/drivers/rng/Makefile
index 8953406..39f7ee3 100644
--- a/drivers/rng/Makefile
+++ b/drivers/rng/Makefile
@@ -9,3 +9,4 @@
 obj-$(CONFIG_RNG_MSM) += msm_rng.o
 obj-$(CONFIG_RNG_STM32MP1) += stm32mp1_rng.o
 obj-$(CONFIG_RNG_ROCKCHIP) += rockchip_rng.o
+obj-$(CONFIG_RNG_IPROC200) += iproc_rng200.o
diff --git a/drivers/rng/iproc_rng200.c b/drivers/rng/iproc_rng200.c
new file mode 100644
index 0000000..f71f285
--- /dev/null
+++ b/drivers/rng/iproc_rng200.c
@@ -0,0 +1,185 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright 2020, Matthias Brugger <mbrugger@suse.com>
+ *
+ * Driver for Raspberry Pi hardware random number generator
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <linux/delay.h>
+#include <rng.h>
+#include <asm/io.h>
+
+#define usleep_range(a, b) udelay((b))
+
+#define RNG_CTRL_OFFSET					0x00
+#define RNG_CTRL_RNG_RBGEN_MASK				0x00001FFF
+#define RNG_CTRL_RNG_RBGEN_ENABLE			0x00000001
+#define RNG_CTRL_RNG_RBGEN_DISABLE			0x00000000
+
+#define RNG_SOFT_RESET_OFFSET				0x04
+#define RNG_SOFT_RESET					0x00000001
+
+#define RBG_SOFT_RESET_OFFSET				0x08
+#define RBG_SOFT_RESET					0x00000001
+
+#define RNG_INT_STATUS_OFFSET				0x18
+#define RNG_INT_STATUS_MASTER_FAIL_LOCKOUT_IRQ_MASK	0x80000000
+#define RNG_INT_STATUS_NIST_FAIL_IRQ_MASK		0x00000020
+
+#define RNG_FIFO_DATA_OFFSET				0x20
+
+#define RNG_FIFO_COUNT_OFFSET				0x24
+#define RNG_FIFO_COUNT_RNG_FIFO_COUNT_MASK		0x000000FF
+
+struct iproc_rng200_platdata {
+	fdt_addr_t base;
+};
+
+static void iproc_rng200_enable(struct iproc_rng200_platdata *pdata, bool enable)
+{
+	fdt_addr_t rng_base = pdata->base;
+	u32 val;
+
+	val = readl(rng_base + RNG_CTRL_OFFSET);
+	val &= ~RNG_CTRL_RNG_RBGEN_MASK;
+	if (enable)
+		val |= RNG_CTRL_RNG_RBGEN_ENABLE;
+	else
+		val &= ~RNG_CTRL_RNG_RBGEN_ENABLE;
+
+	writel(val, rng_base + RNG_CTRL_OFFSET);
+}
+
+static void iproc_rng200_restart(struct iproc_rng200_platdata *pdata)
+{
+	fdt_addr_t rng_base = pdata->base;
+	u32 val;
+
+	iproc_rng200_enable(pdata, false);
+
+	/* Clear all interrupt status */
+	writel(0xFFFFFFFFUL, rng_base + RNG_INT_STATUS_OFFSET);
+
+	/* Reset RNG and RBG */
+	val = readl(rng_base + RBG_SOFT_RESET_OFFSET);
+	val |= RBG_SOFT_RESET;
+	writel(val, rng_base + RBG_SOFT_RESET_OFFSET);
+
+	val = readl(rng_base + RNG_SOFT_RESET_OFFSET);
+	val |= RNG_SOFT_RESET;
+	writel(val, rng_base + RNG_SOFT_RESET_OFFSET);
+
+	val = readl(rng_base + RNG_SOFT_RESET_OFFSET);
+	val &= ~RNG_SOFT_RESET;
+	writel(val, rng_base + RNG_SOFT_RESET_OFFSET);
+
+	val = readl(rng_base + RBG_SOFT_RESET_OFFSET);
+	val &= ~RBG_SOFT_RESET;
+	writel(val, rng_base + RBG_SOFT_RESET_OFFSET);
+
+	iproc_rng200_enable(pdata, true);
+}
+
+static int iproc_rng200_read(struct udevice *dev, void *data, size_t len)
+{
+	struct iproc_rng200_platdata *priv = dev_get_plat(dev);
+	char *buf = (char *)data;
+	u32 num_remaining = len;
+	u32 status;
+
+	#define MAX_RESETS_PER_READ	1
+	u32 num_resets = 0;
+
+	while (num_remaining > 0) {
+
+		/* Is RNG sane? If not, reset it. */
+		status = readl(priv->base + RNG_INT_STATUS_OFFSET);
+		if ((status & (RNG_INT_STATUS_MASTER_FAIL_LOCKOUT_IRQ_MASK |
+			RNG_INT_STATUS_NIST_FAIL_IRQ_MASK)) != 0) {
+
+			if (num_resets >= MAX_RESETS_PER_READ)
+				return len - num_remaining;
+
+			iproc_rng200_restart(priv);
+			num_resets++;
+		}
+
+		/* Are there any random numbers available? */
+		if ((readl(priv->base + RNG_FIFO_COUNT_OFFSET) &
+				RNG_FIFO_COUNT_RNG_FIFO_COUNT_MASK) > 0) {
+
+			if (num_remaining >= sizeof(u32)) {
+				/* Buffer has room to store entire word */
+				*(u32 *)buf = readl(priv->base +
+							RNG_FIFO_DATA_OFFSET);
+				buf += sizeof(u32);
+				num_remaining -= sizeof(u32);
+			} else {
+				/* Buffer can only store partial word */
+				u32 rnd_number = readl(priv->base +
+							RNG_FIFO_DATA_OFFSET);
+				memcpy(buf, &rnd_number, num_remaining);
+				buf += num_remaining;
+				num_remaining = 0;
+			}
+
+		} else {
+			/* Can wait, give others chance to run */
+			usleep_range(min(num_remaining * 10, 500U), 500);
+		}
+	}
+
+	return 0;
+}
+
+static int iproc_rng200_probe(struct udevice *dev)
+{
+	struct iproc_rng200_platdata *priv = dev_get_plat(dev);
+
+	iproc_rng200_enable(priv, true);
+
+	return 0;
+}
+
+static int iproc_rng200_remove(struct udevice *dev)
+{
+	struct iproc_rng200_platdata *priv = dev_get_plat(dev);
+
+	iproc_rng200_enable(priv, false);
+
+	return 0;
+}
+
+static int iproc_rng200_ofdata_to_platdata(struct udevice *dev)
+{
+	struct iproc_rng200_platdata *pdata = dev_get_plat(dev);
+
+	pdata->base = dev_read_addr(dev);
+	if (!pdata->base)
+		return -ENODEV;
+
+	return 0;
+}
+
+static const struct dm_rng_ops iproc_rng200_ops = {
+	.read = iproc_rng200_read,
+};
+
+static const struct udevice_id iproc_rng200_rng_match[] = {
+	{ .compatible = "brcm,bcm2711-rng200", },
+	{ .compatible = "brcm,iproc-rng200", },
+	{},
+};
+
+U_BOOT_DRIVER(iproc_rng200_rng) = {
+	.name = "iproc_rng200-rng",
+	.id = UCLASS_RNG,
+	.of_match = iproc_rng200_rng_match,
+	.ops = &iproc_rng200_ops,
+	.probe = iproc_rng200_probe,
+	.remove = iproc_rng200_remove,
+	.plat_auto = sizeof(struct iproc_rng200_platdata),
+	.of_to_plat = iproc_rng200_ofdata_to_platdata,
+};
diff --git a/drivers/tee/Makefile b/drivers/tee/Makefile
index 5c8ffdb..ff84419 100644
--- a/drivers/tee/Makefile
+++ b/drivers/tee/Makefile
@@ -2,5 +2,7 @@
 
 obj-y += tee-uclass.o
 obj-$(CONFIG_SANDBOX) += sandbox.o
+obj-$(CONFIG_OPTEE_TA_RPC_TEST) += optee/supplicant.o
+obj-$(CONFIG_OPTEE_TA_RPC_TEST) += optee/i2c.o
 obj-$(CONFIG_OPTEE) += optee/
 obj-y += broadcom/
diff --git a/drivers/tee/optee/Kconfig b/drivers/tee/optee/Kconfig
index d489834..65622f3 100644
--- a/drivers/tee/optee/Kconfig
+++ b/drivers/tee/optee/Kconfig
@@ -22,6 +22,15 @@
 	  The TA can support the "avb" subcommands "read_rb", "write"rb"
 	  and "is_unlocked".
 
+config OPTEE_TA_RPC_TEST
+	bool "Support RPC TEST TA"
+	depends on SANDBOX_TEE
+	default y
+	help
+	  Enables support for RPC test trusted application emulation, which
+	  permits to test reverse RPC calls to TEE supplicant. Should
+	  be used only in sandbox env.
+
 endmenu
 
 endif
diff --git a/drivers/tee/optee/Makefile b/drivers/tee/optee/Makefile
index 928d3f8..068c6e7 100644
--- a/drivers/tee/optee/Makefile
+++ b/drivers/tee/optee/Makefile
@@ -2,4 +2,5 @@
 
 obj-y += core.o
 obj-y += supplicant.o
+obj-$(CONFIG_DM_I2C) += i2c.o
 obj-$(CONFIG_SUPPORT_EMMC_RPMB) += rpmb.o
diff --git a/drivers/tee/optee/i2c.c b/drivers/tee/optee/i2c.c
new file mode 100644
index 0000000..ef4e10f
--- /dev/null
+++ b/drivers/tee/optee/i2c.c
@@ -0,0 +1,90 @@
+// SPDX-License-Identifier: BSD-2-Clause
+/*
+ * Copyright (c) 2020 Foundries.io Ltd
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <i2c.h>
+#include <tee.h>
+#include "optee_msg.h"
+#include "optee_private.h"
+
+static int check_xfer_flags(struct udevice *chip, uint tee_flags)
+{
+	uint flags;
+	int ret;
+
+	ret = i2c_get_chip_flags(chip, &flags);
+	if (ret)
+		return ret;
+
+	if (tee_flags & OPTEE_MSG_RPC_CMD_I2C_FLAGS_TEN_BIT) {
+		if (!(flags & DM_I2C_CHIP_10BIT))
+			return -EINVAL;
+	} else {
+		if (flags & DM_I2C_CHIP_10BIT)
+			return -EINVAL;
+	}
+
+	return 0;
+}
+
+void optee_suppl_cmd_i2c_transfer(struct optee_msg_arg *arg)
+{
+	const u8 attr[] = {
+		OPTEE_MSG_ATTR_TYPE_VALUE_INPUT,
+		OPTEE_MSG_ATTR_TYPE_VALUE_INPUT,
+		OPTEE_MSG_ATTR_TYPE_RMEM_INOUT,
+		OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT,
+	};
+	struct udevice *chip_dev;
+	struct tee_shm *shm;
+	u8 *buf;
+	int ret;
+
+	if (arg->num_params != ARRAY_SIZE(attr) ||
+	    arg->params[0].attr != attr[0] ||
+	    arg->params[1].attr != attr[1] ||
+	    arg->params[2].attr != attr[2] ||
+	    arg->params[3].attr != attr[3]) {
+		goto bad;
+	}
+
+	shm = (struct tee_shm *)(unsigned long)arg->params[2].u.rmem.shm_ref;
+	buf = shm->addr;
+	if (!buf)
+		goto bad;
+
+	if (i2c_get_chip_for_busnum((int)arg->params[0].u.value.b,
+				    (int)arg->params[0].u.value.c,
+				    0, &chip_dev))
+		goto bad;
+
+	if (check_xfer_flags(chip_dev, arg->params[1].u.value.a))
+		goto bad;
+
+	switch (arg->params[0].u.value.a) {
+	case OPTEE_MSG_RPC_CMD_I2C_TRANSFER_RD:
+		ret = dm_i2c_read(chip_dev, 0, buf,
+				  (size_t)arg->params[2].u.rmem.size);
+		break;
+	case OPTEE_MSG_RPC_CMD_I2C_TRANSFER_WR:
+		ret = dm_i2c_write(chip_dev, 0, buf,
+				   (size_t)arg->params[2].u.rmem.size);
+		break;
+	default:
+		goto bad;
+	}
+
+	if (ret) {
+		arg->ret = TEE_ERROR_COMMUNICATION;
+	} else {
+		arg->params[3].u.value.a = arg->params[2].u.rmem.size;
+		arg->ret = TEE_SUCCESS;
+	}
+
+	return;
+bad:
+	arg->ret = TEE_ERROR_BAD_PARAMETERS;
+}
diff --git a/drivers/tee/optee/optee_msg.h b/drivers/tee/optee/optee_msg.h
index 24c6096..8d40ce6 100644
--- a/drivers/tee/optee/optee_msg.h
+++ b/drivers/tee/optee/optee_msg.h
@@ -422,4 +422,25 @@
  */
 #define OPTEE_MSG_RPC_CMD_SHM_FREE	7
 
+/*
+ * Access a device on an i2c bus
+ *
+ * [in]  param[0].u.value.a		mode: RD(0), WR(1)
+ * [in]  param[0].u.value.b		i2c adapter
+ * [in]  param[0].u.value.c		i2c chip
+ *
+ * [in]  param[1].u.value.a		i2c control flags
+ *
+ * [in/out] memref[2]			buffer to exchange the transfer data
+ *					with the secure world
+ *
+ * [out]  param[3].u.value.a		bytes transferred by the driver
+ */
+#define OPTEE_MSG_RPC_CMD_I2C_TRANSFER 21
+/* I2C master transfer modes */
+#define OPTEE_MSG_RPC_CMD_I2C_TRANSFER_RD 0
+#define OPTEE_MSG_RPC_CMD_I2C_TRANSFER_WR 1
+/* I2C master control flags */
+#define OPTEE_MSG_RPC_CMD_I2C_FLAGS_TEN_BIT  BIT(0)
+
 #endif /* _OPTEE_MSG_H */
diff --git a/drivers/tee/optee/optee_msg_supplicant.h b/drivers/tee/optee/optee_msg_supplicant.h
index a0fb806..963cfd4 100644
--- a/drivers/tee/optee/optee_msg_supplicant.h
+++ b/drivers/tee/optee/optee_msg_supplicant.h
@@ -148,6 +148,11 @@
 #define OPTEE_MSG_RPC_CMD_SHM_FREE	7
 
 /*
+ * I2C bus access
+ */
+#define OPTEE_MSG_RPC_CMD_I2C_TRANSFER 21
+
+/*
  * Was OPTEE_MSG_RPC_CMD_SQL_FS, which isn't supported any longer
  */
 #define OPTEE_MSG_RPC_CMD_SQL_FS_RESERVED	8
diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h
index 9442d1c..1f07a27 100644
--- a/drivers/tee/optee/optee_private.h
+++ b/drivers/tee/optee/optee_private.h
@@ -60,6 +60,23 @@
 }
 #endif
 
+#ifdef CONFIG_DM_I2C
+/**
+ * optee_suppl_cmd_i2c_transfer() - route I2C requests to an I2C chip
+ * @arg:	OP-TEE message (layout specified in optee_msg.h) defining the
+ *		transfer mode (read/write), adapter, chip and control flags.
+ *
+ * Handles OP-TEE requests to transfer data to the I2C chip on the I2C adapter.
+ */
+void optee_suppl_cmd_i2c_transfer(struct optee_msg_arg *arg);
+#else
+static inline void optee_suppl_cmd_i2c_transfer(struct optee_msg_arg *arg)
+{
+	debug("OPTEE_MSG_RPC_CMD_I2C_TRANSFER not implemented\n");
+	arg->ret = TEE_ERROR_NOT_IMPLEMENTED;
+}
+#endif
+
 void *optee_alloc_and_init_page_list(void *buf, ulong len, u64 *phys_buf_ptr);
 
 #endif /* __OPTEE_PRIVATE_H */
diff --git a/drivers/tee/optee/supplicant.c b/drivers/tee/optee/supplicant.c
index ae042b9..f9dd874 100644
--- a/drivers/tee/optee/supplicant.c
+++ b/drivers/tee/optee/supplicant.c
@@ -89,6 +89,9 @@
 	case OPTEE_MSG_RPC_CMD_RPMB:
 		optee_suppl_cmd_rpmb(dev, arg);
 		break;
+	case OPTEE_MSG_RPC_CMD_I2C_TRANSFER:
+		optee_suppl_cmd_i2c_transfer(arg);
+		break;
 	default:
 		arg->ret = TEE_ERROR_NOT_IMPLEMENTED;
 	}
diff --git a/drivers/tee/sandbox.c b/drivers/tee/sandbox.c
index e1ba027..3a1d34d 100644
--- a/drivers/tee/sandbox.c
+++ b/drivers/tee/sandbox.c
@@ -7,11 +7,15 @@
 #include <sandboxtee.h>
 #include <tee.h>
 #include <tee/optee_ta_avb.h>
+#include <tee/optee_ta_rpc_test.h>
+
+#include "optee/optee_msg.h"
+#include "optee/optee_private.h"
 
 /*
  * The sandbox tee driver tries to emulate a generic Trusted Exectution
- * Environment (TEE) with the Trusted Application (TA) OPTEE_TA_AVB
- * available.
+ * Environment (TEE) with the Trusted Applications (TA) OPTEE_TA_AVB and
+ * OPTEE_TA_RPC_TEST available.
  */
 
 static const u32 pstorage_max = 16;
@@ -32,7 +36,38 @@
 			   struct tee_param *params);
 };
 
-#ifdef CONFIG_OPTEE_TA_AVB
+static int get_msg_arg(struct udevice *dev, uint num_params,
+		       struct tee_shm **shmp, struct optee_msg_arg **msg_arg)
+{
+	int rc;
+	struct optee_msg_arg *ma;
+
+	rc = __tee_shm_add(dev, OPTEE_MSG_NONCONTIG_PAGE_SIZE, NULL,
+			   OPTEE_MSG_GET_ARG_SIZE(num_params), TEE_SHM_ALLOC,
+			   shmp);
+	if (rc)
+		return rc;
+
+	ma = (*shmp)->addr;
+	memset(ma, 0, OPTEE_MSG_GET_ARG_SIZE(num_params));
+	ma->num_params = num_params;
+	*msg_arg = ma;
+
+	return 0;
+}
+
+void *optee_alloc_and_init_page_list(void *buf, ulong len,
+				     u64 *phys_buf_ptr)
+{
+	/*
+	 * An empty stub is added just to fix linking issues.
+	 * This function isn't supposed to be called in sandbox
+	 * setup, otherwise replace this with a proper
+	 * implementation from optee/core.c
+	 */
+	return NULL;
+}
+
 static u32 get_attr(uint n, uint num_params, struct tee_param *params)
 {
 	if (n >= num_params)
@@ -63,6 +98,7 @@
 	return TEE_ERROR_BAD_PARAMETERS;
 }
 
+#ifdef CONFIG_OPTEE_TA_AVB
 static u32 ta_avb_open_session(struct udevice *dev, uint num_params,
 			       struct tee_param *params)
 {
@@ -214,7 +250,99 @@
 		return TEE_ERROR_NOT_SUPPORTED;
 	}
 }
+#endif /* OPTEE_TA_AVB */
+
+#ifdef CONFIG_OPTEE_TA_RPC_TEST
+static u32 ta_rpc_test_open_session(struct udevice *dev, uint num_params,
+				    struct tee_param *params)
+{
+	/*
+	 * We don't expect additional parameters when opening a session to
+	 * this TA.
+	 */
+	return check_params(TEE_PARAM_ATTR_TYPE_NONE, TEE_PARAM_ATTR_TYPE_NONE,
+			    TEE_PARAM_ATTR_TYPE_NONE, TEE_PARAM_ATTR_TYPE_NONE,
+			    num_params, params);
+}
-#endif /*OPTEE_TA_AVB*/
+
+static void fill_i2c_rpc_params(struct optee_msg_arg *msg_arg, u64 bus_num,
+				u64 chip_addr, u64 xfer_flags, u64 op,
+				struct tee_param_memref memref)
+{
+	msg_arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT;
+	msg_arg->params[1].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT;
+	msg_arg->params[2].attr = OPTEE_MSG_ATTR_TYPE_RMEM_INOUT;
+	msg_arg->params[3].attr = OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT;
+
+	/* trigger I2C services of TEE supplicant */
+	msg_arg->cmd = OPTEE_MSG_RPC_CMD_I2C_TRANSFER;
+
+	msg_arg->params[0].u.value.a = op;
+	msg_arg->params[0].u.value.b = bus_num;
+	msg_arg->params[0].u.value.c = chip_addr;
+	msg_arg->params[1].u.value.a = xfer_flags;
+
+	/* buffer to read/write data */
+	msg_arg->params[2].u.rmem.shm_ref = (ulong)memref.shm;
+	msg_arg->params[2].u.rmem.size = memref.size;
+	msg_arg->params[2].u.rmem.offs = memref.shm_offs;
+
+	msg_arg->num_params = 4;
+}
+
+static u32 ta_rpc_test_invoke_func(struct udevice *dev, u32 func,
+				   uint num_params,
+				   struct tee_param *params)
+{
+	struct tee_shm *shm;
+	struct tee_param_memref memref_data;
+	struct optee_msg_arg *msg_arg;
+	int chip_addr, bus_num, op, xfer_flags;
+	int res;
+
+	res = check_params(TEE_PARAM_ATTR_TYPE_VALUE_INPUT,
+			   TEE_PARAM_ATTR_TYPE_MEMREF_INOUT,
+			   TEE_PARAM_ATTR_TYPE_NONE,
+			   TEE_PARAM_ATTR_TYPE_NONE,
+			   num_params, params);
+	if (res)
+		return TEE_ERROR_BAD_PARAMETERS;
+
+	bus_num = params[0].u.value.a;
+	chip_addr = params[0].u.value.b;
+	xfer_flags = params[0].u.value.c;
+	memref_data = params[1].u.memref;
+
+	switch (func) {
+	case TA_RPC_TEST_CMD_I2C_READ:
+		op = OPTEE_MSG_RPC_CMD_I2C_TRANSFER_RD;
+		break;
+	case TA_RPC_TEST_CMD_I2C_WRITE:
+		op = OPTEE_MSG_RPC_CMD_I2C_TRANSFER_WR;
+		break;
+	default:
+		return TEE_ERROR_NOT_SUPPORTED;
+	}
+
+	/*
+	 * Fill params for an RPC call to tee supplicant
+	 */
+	res = get_msg_arg(dev, 4, &shm, &msg_arg);
+	if (res)
+		goto out;
+
+	fill_i2c_rpc_params(msg_arg, bus_num, chip_addr, xfer_flags, op,
+			    memref_data);
+
+	/* Make an RPC call to tee supplicant */
+	optee_suppl_cmd(dev, shm, 0);
+	res = msg_arg->ret;
+out:
+	tee_shm_free(shm);
+
+	return res;
+}
+#endif /* CONFIG_OPTEE_TA_RPC_TEST */
 
 static const struct ta_entry ta_entries[] = {
 #ifdef CONFIG_OPTEE_TA_AVB
@@ -223,6 +351,12 @@
 	  .invoke_func = ta_avb_invoke_func,
 	},
 #endif
+#ifdef CONFIG_OPTEE_TA_RPC_TEST
+	{ .uuid = TA_RPC_TEST_UUID,
+	  .open_session = ta_rpc_test_open_session,
+	  .invoke_func = ta_rpc_test_invoke_func,
+	},
+#endif
 };
 
 static void sandbox_tee_get_version(struct udevice *dev,
diff --git a/drivers/tpm/tpm_atmel_twi.c b/drivers/tpm/tpm_atmel_twi.c
index d9e4877..2dcc2af 100644
--- a/drivers/tpm/tpm_atmel_twi.c
+++ b/drivers/tpm/tpm_atmel_twi.c
@@ -81,7 +81,7 @@
 	print_buffer(0, (void *)sendbuf, 1, send_size, 0);
 #endif
 
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	res = i2c_write(0x29, 0, 0, (uchar *)sendbuf, send_size);
 #else
 	res = dm_i2c_write(dev, 0, sendbuf, send_size);
@@ -92,7 +92,7 @@
 	}
 
 	start = get_timer(0);
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	while ((res = i2c_read(0x29, 0, 0, recvbuf, 10)))
 #else
 	while ((res = dm_i2c_read(dev, 0, recvbuf, 10)))
@@ -116,7 +116,7 @@
 			return -1;
 		} else {
 			*recv_len = hdr_recv_len;
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 			res = i2c_read(0x29, 0, 0, recvbuf, *recv_len);
 #else
 			res = dm_i2c_read(dev, 0, recvbuf, *recv_len);
diff --git a/drivers/usb/host/ohci-lpc32xx.c b/drivers/usb/host/ohci-lpc32xx.c
index afb9e29..3be0b31 100644
--- a/drivers/usb/host/ohci-lpc32xx.c
+++ b/drivers/usb/host/ohci-lpc32xx.c
@@ -86,7 +86,7 @@
 
 static int isp1301_set_value(struct udevice *dev, int reg, u8 value)
 {
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	return i2c_write(ISP1301_I2C_ADDR, reg, 1, &value, 1);
 #else
 	return dm_i2c_write(dev, reg, &value, 1);
@@ -95,7 +95,7 @@
 
 static void isp1301_configure(struct udevice *dev)
 {
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 	i2c_set_bus_num(I2C_2);
 #endif
 
@@ -160,7 +160,7 @@
 	u32 ret;
 	struct udevice *dev = NULL;
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	ret = i2c_get_chip_for_busnum(I2C_2, ISP1301_I2C_ADDR, 1, &dev);
 	if (ret) {
 		debug("%s: No bus %d\n", __func__, I2C_2);
@@ -216,7 +216,7 @@
 	struct udevice *dev = NULL;
 	int ret = 0;
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 	ret = i2c_get_chip_for_busnum(I2C_2, ISP1301_I2C_ADDR, 1, &dev);
 	if (ret) {
 		debug("%s: No bus %d\n", __func__, I2C_2);
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index b002d6f..83147d5 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -110,7 +110,7 @@
 
 	ctrl->dcbaa->dev_context_ptrs[0] = 0;
 
-	free((void *)(uintptr_t)le64_to_cpu(ctrl->scratchpad->sp_array[0]));
+	free(xhci_bus_to_virt(ctrl, le64_to_cpu(ctrl->scratchpad->sp_array[0])));
 	free(ctrl->scratchpad->sp_array);
 	free(ctrl->scratchpad);
 	ctrl->scratchpad = NULL;
@@ -216,8 +216,8 @@
  * @param link_trbs	flag to indicate whether to link the trbs or NOT
  * @return none
  */
-static void xhci_link_segments(struct xhci_segment *prev,
-				struct xhci_segment *next, bool link_trbs)
+static void xhci_link_segments(struct xhci_ctrl *ctrl, struct xhci_segment *prev,
+			       struct xhci_segment *next, bool link_trbs)
 {
 	u32 val;
 	u64 val_64 = 0;
@@ -226,7 +226,7 @@
 		return;
 	prev->next = next;
 	if (link_trbs) {
-		val_64 = virt_to_phys(next->trbs);
+		val_64 = xhci_virt_to_bus(ctrl, next->trbs);
 		prev->trbs[TRBS_PER_SEGMENT-1].link.segment_ptr =
 			cpu_to_le64(val_64);
 
@@ -304,7 +304,8 @@
  * @param link_trbs	flag to indicate whether to link the trbs or NOT
  * @return pointer to the newly created RING
  */
-struct xhci_ring *xhci_ring_alloc(unsigned int num_segs, bool link_trbs)
+struct xhci_ring *xhci_ring_alloc(struct xhci_ctrl *ctrl, unsigned int num_segs,
+				  bool link_trbs)
 {
 	struct xhci_ring *ring;
 	struct xhci_segment *prev;
@@ -327,12 +328,12 @@
 		next = xhci_segment_alloc();
 		BUG_ON(!next);
 
-		xhci_link_segments(prev, next, link_trbs);
+		xhci_link_segments(ctrl, prev, next, link_trbs);
 
 		prev = next;
 		num_segs--;
 	}
-	xhci_link_segments(prev, ring->first_seg, link_trbs);
+	xhci_link_segments(ctrl, prev, ring->first_seg, link_trbs);
 	if (link_trbs) {
 		/* See section 4.9.2.1 and 6.4.4.1 */
 		prev->trbs[TRBS_PER_SEGMENT-1].link.control |=
@@ -354,6 +355,7 @@
 	struct xhci_hccr *hccr = ctrl->hccr;
 	struct xhci_hcor *hcor = ctrl->hcor;
 	struct xhci_scratchpad *scratchpad;
+	uint64_t val_64;
 	int num_sp;
 	uint32_t page_size;
 	void *buf;
@@ -371,8 +373,9 @@
 	scratchpad->sp_array = xhci_malloc(num_sp * sizeof(u64));
 	if (!scratchpad->sp_array)
 		goto fail_sp2;
-	ctrl->dcbaa->dev_context_ptrs[0] =
-		cpu_to_le64((uintptr_t)scratchpad->sp_array);
+
+	val_64 = xhci_virt_to_bus(ctrl, scratchpad->sp_array);
+	ctrl->dcbaa->dev_context_ptrs[0] = cpu_to_le64(val_64);
 
 	xhci_flush_cache((uintptr_t)&ctrl->dcbaa->dev_context_ptrs[0],
 		sizeof(ctrl->dcbaa->dev_context_ptrs[0]));
@@ -393,8 +396,8 @@
 	xhci_flush_cache((uintptr_t)buf, num_sp * page_size);
 
 	for (i = 0; i < num_sp; i++) {
-		uintptr_t ptr = (uintptr_t)buf + i * page_size;
-		scratchpad->sp_array[i] = cpu_to_le64(ptr);
+		val_64 = xhci_virt_to_bus(ctrl, buf + i * page_size);
+		scratchpad->sp_array[i] = cpu_to_le64(val_64);
 	}
 
 	xhci_flush_cache((uintptr_t)scratchpad->sp_array,
@@ -484,9 +487,9 @@
 	}
 
 	/* Allocate endpoint 0 ring */
-	virt_dev->eps[0].ring = xhci_ring_alloc(1, true);
+	virt_dev->eps[0].ring = xhci_ring_alloc(ctrl, 1, true);
 
-	byte_64 = virt_to_phys(virt_dev->out_ctx->bytes);
+	byte_64 = xhci_virt_to_bus(ctrl, virt_dev->out_ctx->bytes);
 
 	/* Point to output device context in dcbaa. */
 	ctrl->dcbaa->dev_context_ptrs[slot_id] = cpu_to_le64(byte_64);
@@ -522,15 +525,15 @@
 		return -ENOMEM;
 	}
 
-	val_64 = virt_to_phys(ctrl->dcbaa);
+	val_64 = xhci_virt_to_bus(ctrl, ctrl->dcbaa);
 	/* Set the pointer in DCBAA register */
 	xhci_writeq(&hcor->or_dcbaap, val_64);
 
 	/* Command ring control pointer register initialization */
-	ctrl->cmd_ring = xhci_ring_alloc(1, true);
+	ctrl->cmd_ring = xhci_ring_alloc(ctrl, 1, true);
 
 	/* Set the address in the Command Ring Control register */
-	trb_64 = virt_to_phys(ctrl->cmd_ring->first_seg->trbs);
+	trb_64 = xhci_virt_to_bus(ctrl, ctrl->cmd_ring->first_seg->trbs);
 	val_64 = xhci_readq(&hcor->or_crcr);
 	val_64 = (val_64 & (u64) CMD_RING_RSVD_BITS) |
 		(trb_64 & (u64) ~CMD_RING_RSVD_BITS) |
@@ -551,7 +554,7 @@
 	ctrl->ir_set = &ctrl->run_regs->ir_set[0];
 
 	/* Event ring does not maintain link TRB */
-	ctrl->event_ring = xhci_ring_alloc(ERST_NUM_SEGS, false);
+	ctrl->event_ring = xhci_ring_alloc(ctrl, ERST_NUM_SEGS, false);
 	ctrl->erst.entries = xhci_malloc(sizeof(struct xhci_erst_entry) *
 					 ERST_NUM_SEGS);
 
@@ -560,8 +563,8 @@
 	for (val = 0, seg = ctrl->event_ring->first_seg;
 			val < ERST_NUM_SEGS;
 			val++) {
-		trb_64 = virt_to_phys(seg->trbs);
 		struct xhci_erst_entry *entry = &ctrl->erst.entries[val];
+		trb_64 = xhci_virt_to_bus(ctrl, seg->trbs);
 		entry->seg_addr = cpu_to_le64(trb_64);
 		entry->seg_size = cpu_to_le32(TRBS_PER_SEGMENT);
 		entry->rsvd = 0;
@@ -570,7 +573,7 @@
 	xhci_flush_cache((uintptr_t)ctrl->erst.entries,
 			 ERST_NUM_SEGS * sizeof(struct xhci_erst_entry));
 
-	deq = virt_to_phys(ctrl->event_ring->dequeue);
+	deq = xhci_virt_to_bus(ctrl, ctrl->event_ring->dequeue);
 
 	/* Update HC event ring dequeue pointer */
 	xhci_writeq(&ctrl->ir_set->erst_dequeue,
@@ -585,7 +588,7 @@
 	/* this is the event ring segment table pointer */
 	val_64 = xhci_readq(&ctrl->ir_set->erst_base);
 	val_64 &= ERST_PTR_MASK;
-	val_64 |= virt_to_phys(ctrl->erst.entries) & ~ERST_PTR_MASK;
+	val_64 |= xhci_virt_to_bus(ctrl, ctrl->erst.entries) & ~ERST_PTR_MASK;
 
 	xhci_writeq(&ctrl->ir_set->erst_base, val_64);
 
@@ -848,7 +851,7 @@
 	/* EP 0 can handle "burst" sizes of 1, so Max Burst Size field is 0 */
 	ep0_ctx->ep_info2 |= cpu_to_le32(MAX_BURST(0) | ERROR_COUNT(3));
 
-	trb_64 = virt_to_phys(virt_dev->eps[0].ring->first_seg->trbs);
+	trb_64 = xhci_virt_to_bus(ctrl, virt_dev->eps[0].ring->first_seg->trbs);
 	ep0_ctx->deq = cpu_to_le64(trb_64 | virt_dev->eps[0].ring->cycle_state);
 
 	/*
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 6c5024d..aaa243f 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -70,7 +70,7 @@
 	.ops	= &xhci_usb_ops,
 	.plat_auto	= sizeof(struct usb_plat),
 	.priv_auto	= sizeof(struct xhci_ctrl),
-	.flags	= DM_FLAG_ALLOC_PRIV_DMA,
+	.flags	= DM_FLAG_OS_PREPARE | DM_FLAG_ALLOC_PRIV_DMA,
 };
 
 static struct pci_device_id xhci_pci_supported[] = {
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index d6c47d5..46c137f 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -275,10 +275,13 @@
 			u32 ep_index, trb_type cmd)
 {
 	u32 fields[4];
-	u64 val_64 = virt_to_phys(ptr);
+	u64 val_64 = 0;
 
 	BUG_ON(prepare_ring(ctrl, ctrl->cmd_ring, EP_STATE_RUNNING));
 
+	if (ptr)
+		val_64 = xhci_virt_to_bus(ctrl, ptr);
+
 	fields[0] = lower_32_bits(val_64);
 	fields[1] = upper_32_bits(val_64);
 	fields[2] = 0;
@@ -401,7 +404,7 @@
 
 	/* Inform the hardware */
 	xhci_writeq(&ctrl->ir_set->erst_dequeue,
-		    virt_to_phys(ctrl->event_ring->dequeue) | ERST_EHB);
+		    xhci_virt_to_bus(ctrl, ctrl->event_ring->dequeue) | ERST_EHB);
 }
 
 /**
@@ -579,7 +582,7 @@
 	u64 addr;
 	int ret;
 	u32 trb_fields[4];
-	u64 val_64 = virt_to_phys(buffer);
+	u64 val_64 = xhci_virt_to_bus(ctrl, buffer);
 	void *last_transfer_trb_addr;
 	int available_length;
 
@@ -724,7 +727,7 @@
 	}
 
 	if ((uintptr_t)(le64_to_cpu(event->trans_event.buffer)) !=
-	    (uintptr_t)virt_to_phys(last_transfer_trb_addr)) {
+	    (uintptr_t)xhci_virt_to_bus(ctrl, last_transfer_trb_addr)) {
 		available_length -=
 			(int)EVENT_TRB_LEN(le32_to_cpu(event->trans_event.transfer_len));
 		xhci_acknowledge_event(ctrl);
@@ -884,7 +887,7 @@
 	if (length > 0) {
 		if (req->requesttype & USB_DIR_IN)
 			field |= TRB_DIR_IN;
-		buf_64 = virt_to_phys(buffer);
+		buf_64 = xhci_virt_to_bus(ctrl, buffer);
 
 		trb_fields[0] = lower_32_bits(buf_64);
 		trb_fields[1] = upper_32_bits(buf_64);
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 7080f8f..d27ac01 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -604,7 +604,7 @@
 		ep_ctx[ep_index] = xhci_get_ep_ctx(ctrl, in_ctx, ep_index);
 
 		/* Allocate the ep rings */
-		virt_dev->eps[ep_index].ring = xhci_ring_alloc(1, true);
+		virt_dev->eps[ep_index].ring = xhci_ring_alloc(ctrl, 1, true);
 		if (!virt_dev->eps[ep_index].ring)
 			return -ENOMEM;
 
@@ -628,7 +628,7 @@
 			cpu_to_le32(MAX_BURST(max_burst) |
 			ERROR_COUNT(err_count));
 
-		trb_64 = virt_to_phys(virt_dev->eps[ep_index].ring->enqueue);
+		trb_64 = xhci_virt_to_bus(ctrl, virt_dev->eps[ep_index].ring->enqueue);
 		ep_ctx[ep_index]->deq = cpu_to_le64(trb_64 |
 				virt_dev->eps[ep_index].ring->cycle_state);
 
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index d782eb8..667157c 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -30,7 +30,7 @@
 	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
+	  struct video_uc_plat. That memory is then reserved for use after
 	  relocation. But PCI drivers cannot be bound before relocation unless
 	  they are mentioned in the devicetree.
 
@@ -51,7 +51,7 @@
 	  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.
+	  struct video_uc_plat.
 
 config BACKLIGHT_PWM
 	bool "Generic PWM based Backlight Driver"
@@ -160,6 +160,16 @@
 	  With this option you can adjust the text size and use a variety of
 	  fonts. Note that this is noticeably slower than with normal console.
 
+config DM_PANEL_HX8238D
+	bool "Enable Himax HX-8238D LCD driver"
+	depends on DM_VIDEO
+	help
+	  Support for HX-8238D LCD Panel
+	  The  HX8238-D is a single chip controller and driver LSI that
+	  integrates the power circuit.
+	  It can drive a maximum 960x240 dot graphics on a-TFT panel
+	  displays in 16M colors with dithering.
+
 config CONSOLE_TRUETYPE_SIZE
 	int "TrueType font size"
 	depends on CONSOLE_TRUETYPE
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 494e414..933f06e 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -15,6 +15,7 @@
 obj-$(CONFIG_DM_VIDEO) += video-uclass.o vidconsole-uclass.o
 obj-$(CONFIG_DM_VIDEO) += video_bmp.o
 obj-$(CONFIG_PANEL) += panel-uclass.o
+obj-$(CONFIG_PANEL_HX8238D) += hx8238d.o
 obj-$(CONFIG_SIMPLE_PANEL) += simple_panel.o
 endif
 
@@ -57,7 +58,6 @@
 obj-$(CONFIG_VIDEO_LCD_RAYDIUM_RM68200) += raydium-rm68200.o
 obj-$(CONFIG_VIDEO_LCD_SSD2828) += ssd2828.o
 obj-$(CONFIG_VIDEO_LCD_TDO_TL070WSH30) += tdo-tl070wsh30.o
-obj-$(CONFIG_VIDEO_MB862xx) += mb862xx.o videomodes.o
 obj-${CONFIG_VIDEO_MESON} += meson/
 obj-${CONFIG_VIDEO_MIPI_DSI} += mipi_dsi.o
 obj-$(CONFIG_VIDEO_MVEBU) += mvebu_lcd.o
diff --git a/drivers/video/bcm2835.c b/drivers/video/bcm2835.c
index 9326999..c296293 100644
--- a/drivers/video/bcm2835.c
+++ b/drivers/video/bcm2835.c
@@ -52,6 +52,7 @@
 
 static const struct udevice_id bcm2835_video_ids[] = {
 	{ .compatible = "brcm,bcm2835-hdmi" },
+	{ .compatible = "brcm,bcm2711-hdmi0" },
 	{ .compatible = "brcm,bcm2708-fb" },
 	{ }
 };
diff --git a/drivers/video/hx8238d.c b/drivers/video/hx8238d.c
new file mode 100644
index 0000000..f7e7753
--- /dev/null
+++ b/drivers/video/hx8238d.c
@@ -0,0 +1,197 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copied from simple-panel
+ * Copyright (c) 2016 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ * Copyright (c) 2018 Sjoerd Simons <sjoerd.simons@collabora.co.uk>
+ * Modified by Moses Christopher <BollavarapuMoses.Christopher@in.bosch.com>
+ *
+ * Panel Initialization for HX8238D panel from Himax
+ * Resolution: 320x240
+ * Color-Mode: RGB
+ *
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <panel.h>
+#include <spi.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* Register Address */
+#define HX8238D_OUTPUT_CTRL_ADDR        0x01
+#define HX8238D_LCD_AC_CTRL_ADDR        0x02
+#define HX8238D_POWER_CTRL_1_ADDR       0x03
+#define HX8238D_DATA_CLR_CTRL_ADDR      0X04
+#define HX8238D_FUNCTION_CTRL_ADDR      0x05
+#define HX8238D_LED_CTRL_ADDR           0x08
+#define HX8238D_CONT_BRIGHT_CTRL_ADDR   0x0A
+#define HX8238D_FRAME_CYCLE_CTRL_ADDR   0x0B
+#define HX8238D_POWER_CTRL_2_ADDR       0x0D
+#define HX8238D_POWER_CTRL_3_ADDR       0x0E
+#define HX8238D_GATE_SCAN_POS_ADDR      0x0F
+#define HX8238D_HORIZONTAL_PORCH_ADDR   0x16
+#define HX8238D_VERTICAL_PORCH_ADDR     0x17
+#define HX8238D_POWER_CTRL_4_ADDR       0x1E
+#define HX8238D_GAMMA_CTRL_1_ADDR       0x30
+#define HX8238D_GAMMA_CTRL_2_ADDR       0x31
+#define HX8238D_GAMMA_CTRL_3_ADDR       0x32
+#define HX8238D_GAMMA_CTRL_4_ADDR       0x33
+#define HX8238D_GAMMA_CTRL_5_ADDR       0x34
+#define HX8238D_GAMMA_CTRL_6_ADDR       0x35
+#define HX8238D_GAMMA_CTRL_7_ADDR       0x36
+#define HX8238D_GAMMA_CTRL_8_ADDR       0x37
+#define HX8238D_GAMMA_CTRL_9_ADDR       0x3A
+#define HX8238D_GAMMA_CTRL_10_ADDR      0x3B
+
+/* Register Data */
+#define HX8238D_OUTPUT_CTRL             0x6300
+#define HX8238D_LCD_AC_CTRL             0x0200
+#define HX8238D_POWER_CTRL_1            0x6564
+#define HX8238D_DATA_CLR_CTRL           0x04C7
+#define HX8238D_FUNCTION_CTRL           0xA884
+#define HX8238D_LED_CTRL                0x00CE
+#define HX8238D_CONT_BRIGHT_CTRL        0x4008
+#define HX8238D_FRAME_CYCLE_CTRL        0xD400
+#define HX8238D_POWER_CTRL_2            0x3229
+#define HX8238D_POWER_CTRL_3            0x1200
+#define HX8238D_GATE_SCAN_POS           0x0000
+#define HX8238D_HORIZONTAL_PORCH        0x9F80
+#define HX8238D_VERTICAL_PORCH          0x3F02
+#define HX8238D_POWER_CTRL_4            0x005C
+
+/* Gamma Control */
+#define HX8238D_GAMMA_CTRL_1            0x0103
+#define HX8238D_GAMMA_CTRL_2            0x0407
+#define HX8238D_GAMMA_CTRL_3            0x0705
+#define HX8238D_GAMMA_CTRL_4            0x0002
+#define HX8238D_GAMMA_CTRL_5            0x0505
+#define HX8238D_GAMMA_CTRL_6            0x0303
+#define HX8238D_GAMMA_CTRL_7            0x0707
+#define HX8238D_GAMMA_CTRL_8            0x0100
+#define HX8238D_GAMMA_CTRL_9            0x1F00
+#define HX8238D_GAMMA_CTRL_10           0x000F
+
+/* Primary SPI register identification, 011100 */
+/* Select register, RS=0, RS=0 */
+/* Write  register, RS=1, RW=0 */
+#define HX8238D_PRIMARY_SELECT_REG 0x70
+#define HX8238D_PRIMARY_WRITE_REG  (HX8238D_PRIMARY_SELECT_REG | (0x1 << 1))
+
+#define HX8238D_REG_BIT_LEN        24
+
+struct hx8238d_priv {
+	struct spi_slave *spi;
+};
+
+static int hx8238d_ofdata_to_platdata(struct udevice *dev)
+{
+	struct hx8238d_priv *priv = dev_get_priv(dev);
+
+	priv->spi = dev_get_parent_priv(dev);
+
+	return 0;
+}
+
+/* data[0] => REGISTER ADDRESS */
+/* data[1] => REGISTER VALUE   */
+struct hx8238d_command {
+	u16 data[2];
+};
+
+static struct hx8238d_command hx8238d_init_commands[] = {
+	{ .data = { HX8238D_OUTPUT_CTRL_ADDR,      HX8238D_OUTPUT_CTRL } },
+	{ .data = { HX8238D_LCD_AC_CTRL_ADDR,      HX8238D_LCD_AC_CTRL } },
+	{ .data = { HX8238D_POWER_CTRL_1_ADDR,     HX8238D_POWER_CTRL_1 } },
+	{ .data = { HX8238D_DATA_CLR_CTRL_ADDR,    HX8238D_DATA_CLR_CTRL } },
+	{ .data = { HX8238D_FUNCTION_CTRL_ADDR,    HX8238D_FUNCTION_CTRL } },
+	{ .data = { HX8238D_LED_CTRL_ADDR,         HX8238D_LED_CTRL } },
+	{ .data = { HX8238D_CONT_BRIGHT_CTRL_ADDR, HX8238D_CONT_BRIGHT_CTRL } },
+	{ .data = { HX8238D_FRAME_CYCLE_CTRL_ADDR, HX8238D_FRAME_CYCLE_CTRL } },
+	{ .data = { HX8238D_POWER_CTRL_2_ADDR,     HX8238D_POWER_CTRL_2 } },
+	{ .data = { HX8238D_POWER_CTRL_3_ADDR,     HX8238D_POWER_CTRL_3 } },
+	{ .data = { HX8238D_GATE_SCAN_POS_ADDR,    HX8238D_GATE_SCAN_POS } },
+	{ .data = { HX8238D_HORIZONTAL_PORCH_ADDR, HX8238D_HORIZONTAL_PORCH } },
+	{ .data = { HX8238D_VERTICAL_PORCH_ADDR,   HX8238D_VERTICAL_PORCH } },
+	{ .data = { HX8238D_POWER_CTRL_4_ADDR,     HX8238D_POWER_CTRL_4 } },
+	{ .data = { HX8238D_GAMMA_CTRL_1_ADDR,     HX8238D_GAMMA_CTRL_1 } },
+	{ .data = { HX8238D_GAMMA_CTRL_2_ADDR,     HX8238D_GAMMA_CTRL_2 } },
+	{ .data = { HX8238D_GAMMA_CTRL_3_ADDR,     HX8238D_GAMMA_CTRL_3 } },
+	{ .data = { HX8238D_GAMMA_CTRL_4_ADDR,     HX8238D_GAMMA_CTRL_4 } },
+	{ .data = { HX8238D_GAMMA_CTRL_5_ADDR,     HX8238D_GAMMA_CTRL_5 } },
+	{ .data = { HX8238D_GAMMA_CTRL_6_ADDR,     HX8238D_GAMMA_CTRL_6 } },
+	{ .data = { HX8238D_GAMMA_CTRL_7_ADDR,     HX8238D_GAMMA_CTRL_7 } },
+	{ .data = { HX8238D_GAMMA_CTRL_8_ADDR,     HX8238D_GAMMA_CTRL_8 } },
+	{ .data = { HX8238D_GAMMA_CTRL_9_ADDR,     HX8238D_GAMMA_CTRL_9 } },
+	{ .data = { HX8238D_GAMMA_CTRL_10_ADDR,    HX8238D_GAMMA_CTRL_10 } },
+};
+
+/*
+ * Generate Primary Register Buffer for Register Select and Register Write
+ * First 6 MSB bits of Primary Register is represented with 011100
+ *
+ */
+static void hx8238d_generate_reg_buffers(struct hx8238d_command command,
+					 u8 *sr_buf, uint8_t *wr_buf)
+{
+	struct hx8238d_command cmd = command;
+
+	sr_buf[0] = HX8238D_PRIMARY_SELECT_REG;
+	sr_buf[1] = (cmd.data[0] >> 8) & 0xff;
+	sr_buf[2] = (cmd.data[0]) & 0xff;
+
+	wr_buf[0] = HX8238D_PRIMARY_WRITE_REG;
+	wr_buf[1] = (cmd.data[1] >> 8) & 0xff;
+	wr_buf[2] = (cmd.data[1]) & 0xff;
+}
+
+static int hx8238d_probe(struct udevice *dev)
+{
+	struct hx8238d_priv *priv = dev_get_priv(dev);
+	int ret;
+
+	ret = spi_claim_bus(priv->spi);
+	if (ret) {
+		debug("Failed to claim bus: %d\n", ret);
+		return ret;
+	}
+
+	for (int i = 0; i < ARRAY_SIZE(hx8238d_init_commands); i++) {
+		u8 sr_buf[3], wr_buf[3];
+		const struct hx8238d_command cmd = hx8238d_init_commands[i];
+
+		hx8238d_generate_reg_buffers(cmd, sr_buf, wr_buf);
+		ret = spi_xfer(priv->spi, HX8238D_REG_BIT_LEN, sr_buf, NULL,
+			       SPI_XFER_BEGIN | SPI_XFER_END);
+		if (ret) {
+			debug("Failed to select register %d\n", ret);
+			goto free;
+		}
+
+		ret = spi_xfer(priv->spi, HX8238D_REG_BIT_LEN, wr_buf, NULL,
+			       SPI_XFER_BEGIN | SPI_XFER_END);
+		if (ret) {
+			debug("Failed to write value %d\n", ret);
+			goto free;
+		}
+	}
+
+free:
+	spi_release_bus(priv->spi);
+	return ret;
+}
+
+static const struct udevice_id hx8238d_ids[] = {
+	{ .compatible = "himax,hx8238d" },
+	{ }
+};
+
+U_BOOT_DRIVER(hx8238d) = {
+	.name = "hx8238d",
+	.id = UCLASS_PANEL,
+	.of_match = hx8238d_ids,
+	.ofdata_to_platdata = hx8238d_ofdata_to_platdata,
+	.probe = hx8238d_probe,
+	.priv_auto_alloc_size = sizeof(struct hx8238d_priv),
+};
diff --git a/drivers/video/mb862xx.c b/drivers/video/mb862xx.c
deleted file mode 100644
index 04e435f..0000000
--- a/drivers/video/mb862xx.c
+++ /dev/null
@@ -1,486 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * (C) Copyright 2007
- * DENX Software Engineering, Anatolij Gustschin, agust@denx.de
- */
-
-/*
- * mb862xx.c - Graphic interface for Fujitsu CoralP/Lime
- * PCI and video mode code was derived from smiLynxEM driver.
- */
-
-#include <common.h>
-#include <linux/delay.h>
-
-#include <asm/io.h>
-#include <env.h>
-#include <pci.h>
-#include <video_fb.h>
-#include "videomodes.h"
-#include <mb862xx.h>
-
-#if defined(CONFIG_POST)
-#include <post.h>
-#endif
-
-/*
- * Graphic Device
- */
-GraphicDevice mb862xx;
-
-/*
- * 32MB external RAM - 256K Chip MMIO = 0x1FC0000 ;
- */
-#define VIDEO_MEM_SIZE	0x01FC0000
-
-#if defined(CONFIG_PCI)
-#if defined(CONFIG_VIDEO_CORALP)
-
-static struct pci_device_id supported[] = {
-	{ PCI_VENDOR_ID_FUJITSU, PCI_DEVICE_ID_CORAL_P },
-	{ PCI_VENDOR_ID_FUJITSU, PCI_DEVICE_ID_CORAL_PA },
-	{ }
-};
-
-/* Internal clock frequency divider table, index is mode number */
-unsigned int fr_div[] = { 0x00000f00, 0x00000900, 0x00000500 };
-#endif
-#endif
-
-#if defined(CONFIG_VIDEO_CORALP)
-#define	rd_io		in32r
-#define	wr_io		out32r
-#else
-#define	rd_io(addr)	in_be32((volatile unsigned *)(addr))
-#define	wr_io(addr, val)	out_be32((volatile unsigned *)(addr), (val))
-#endif
-
-#define HOST_RD_REG(off)	rd_io((dev->frameAdrs + GC_HOST_BASE + (off)))
-#define HOST_WR_REG(off, val)	wr_io((dev->frameAdrs + GC_HOST_BASE + (off)), \
-				      (val))
-#define DISP_RD_REG(off)	rd_io((dev->frameAdrs + GC_DISP_BASE + (off)))
-#define DISP_WR_REG(off, val)	wr_io((dev->frameAdrs + GC_DISP_BASE + (off)), \
-				      (val))
-#define DE_RD_REG(off)		rd_io((dev->dprBase + (off)))
-#define DE_WR_REG(off, val)	wr_io((dev->dprBase + (off)), (val))
-
-#if defined(CONFIG_VIDEO_CORALP)
-#define DE_WR_FIFO(val)		wr_io((dev->dprBase + (GC_GEO_FIFO)), (val))
-#else
-#define DE_WR_FIFO(val)		wr_io((dev->dprBase + (GC_FIFO)), (val))
-#endif
-
-#define L0PAL_WR_REG(idx, val)	wr_io((dev->frameAdrs + \
-				       (GC_DISP_BASE | GC_L0PAL0) + \
-				       ((idx) << 2)), (val))
-
-#if defined(CONFIG_VIDEO_MB862xx_ACCEL)
-static void gdc_sw_reset (void)
-{
-	GraphicDevice *dev = &mb862xx;
-
-	HOST_WR_REG (GC_SRST, 0x1);
-	udelay(500);
-	video_hw_init ();
-}
-
-
-static void de_wait (void)
-{
-	GraphicDevice *dev = &mb862xx;
-	int lc = 0x10000;
-
-	/*
-	 * Sync with software writes to framebuffer,
-	 * try to reset if engine locked
-	 */
-	while (DE_RD_REG (GC_CTR) & 0x00000131)
-		if (lc-- < 0) {
-			gdc_sw_reset ();
-			puts ("gdc reset done after drawing engine lock.\n");
-			break;
-		}
-}
-
-static void de_wait_slots (int slots)
-{
-	GraphicDevice *dev = &mb862xx;
-	int lc = 0x10000;
-
-	/* Wait for free fifo slots */
-	while (DE_RD_REG (GC_IFCNT) < slots)
-		if (lc-- < 0) {
-			gdc_sw_reset ();
-			puts ("gdc reset done after drawing engine lock.\n");
-			break;
-		}
-}
-#endif
-
-#if !defined(CONFIG_VIDEO_CORALP)
-static void board_disp_init (void)
-{
-	GraphicDevice *dev = &mb862xx;
-	const gdc_regs *regs = board_get_regs ();
-
-	while (regs->index) {
-		DISP_WR_REG (regs->index, regs->value);
-		regs++;
-	}
-}
-#endif
-
-/*
- * Init drawing engine if accel enabled.
- * Also clears visible framebuffer.
- */
-static void de_init (void)
-{
-	GraphicDevice *dev = &mb862xx;
-#if defined(CONFIG_VIDEO_MB862xx_ACCEL)
-	int cf = (dev->gdfBytesPP == 1) ? 0x0000 : 0x8000;
-
-	dev->dprBase = dev->frameAdrs + GC_DRAW_BASE;
-
-	/* Setup mode and fbbase, xres, fg, bg */
-	de_wait_slots (2);
-	DE_WR_FIFO (0xf1010108);
-	DE_WR_FIFO (cf | 0x0300);
-	DE_WR_REG (GC_FBR, 0x0);
-	DE_WR_REG (GC_XRES, dev->winSizeX);
-	DE_WR_REG (GC_FC, 0x0);
-	DE_WR_REG (GC_BC, 0x0);
-	/* Reset clipping */
-	DE_WR_REG (GC_CXMIN, 0x0);
-	DE_WR_REG (GC_CXMAX, dev->winSizeX);
-	DE_WR_REG (GC_CYMIN, 0x0);
-	DE_WR_REG (GC_CYMAX, dev->winSizeY);
-
-	/* Clear framebuffer using drawing engine */
-	de_wait_slots (3);
-	DE_WR_FIFO (0x09410000);
-	DE_WR_FIFO (0x00000000);
-	DE_WR_FIFO (dev->winSizeY << 16 | dev->winSizeX);
-	/* sync with SW access to framebuffer */
-	de_wait ();
-#else
-	unsigned int i, *p;
-
-	i = dev->winSizeX * dev->winSizeY;
-	p = (unsigned int *)dev->frameAdrs;
-	while (i--)
-		*p++ = 0;
-#endif
-}
-
-#if defined(CONFIG_VIDEO_CORALP)
-/* use CCF and MMR parameters for Coral-P Eval. Board as default */
-#ifndef CONFIG_SYS_MB862xx_CCF
-#define CONFIG_SYS_MB862xx_CCF	0x00090000
-#endif
-#ifndef CONFIG_SYS_MB862xx_MMR
-#define CONFIG_SYS_MB862xx_MMR	0x11d7fa13
-#endif
-
-unsigned int pci_video_init (void)
-{
-	GraphicDevice *dev = &mb862xx;
-	pci_dev_t devbusfn;
-	u16 device;
-
-	if ((devbusfn = pci_find_devices (supported, 0)) < 0) {
-		puts("controller not present\n");
-		return 0;
-	}
-
-	/* PCI setup */
-	pci_write_config_dword (devbusfn, PCI_COMMAND,
-				(PCI_COMMAND_MEMORY | PCI_COMMAND_IO));
-	pci_read_config_dword (devbusfn, PCI_BASE_ADDRESS_0, &dev->frameAdrs);
-	dev->frameAdrs = pci_mem_to_phys (devbusfn, dev->frameAdrs);
-
-	if (dev->frameAdrs == 0) {
-		puts ("PCI config: failed to get base address\n");
-		return 0;
-	}
-
-	dev->pciBase = dev->frameAdrs;
-
-	puts("Coral-");
-
-	pci_read_config_word(devbusfn, PCI_DEVICE_ID, &device);
-	switch (device) {
-	case PCI_DEVICE_ID_CORAL_P:
-		puts("P\n");
-		break;
-	case PCI_DEVICE_ID_CORAL_PA:
-		puts("PA\n");
-		break;
-	default:
-		puts("Unknown\n");
-		return 0;
-	}
-
-	/* Setup clocks and memory mode for Coral-P(A) */
-	HOST_WR_REG(GC_CCF, CONFIG_SYS_MB862xx_CCF);
-	udelay(200);
-	HOST_WR_REG(GC_MMR, CONFIG_SYS_MB862xx_MMR);
-	udelay(100);
-	return dev->frameAdrs;
-}
-
-unsigned int card_init (void)
-{
-	GraphicDevice *dev = &mb862xx;
-	unsigned int cf, videomode, div = 0;
-	unsigned long t1, hsync, vsync;
-	char *penv;
-	int tmp, i, bpp;
-	struct ctfb_res_modes *res_mode;
-	struct ctfb_res_modes var_mode;
-
-	memset (dev, 0, sizeof (GraphicDevice));
-
-	if (!pci_video_init ())
-		return 0;
-
-	tmp = 0;
-	videomode = 0x310;
-	/* get video mode via environment */
-	penv = env_get("videomode");
-	if (penv) {
-		/* decide if it is a string */
-		if (penv[0] <= '9') {
-			videomode = (int) simple_strtoul (penv, NULL, 16);
-			tmp = 1;
-		}
-	} else {
-		tmp = 1;
-	}
-
-	if (tmp) {
-		/* parameter are vesa modes, search params */
-		for (i = 0; i < VESA_MODES_COUNT; i++) {
-			if (vesa_modes[i].vesanr == videomode)
-				break;
-		}
-		if (i == VESA_MODES_COUNT) {
-			printf ("\tno VESA Mode found, fallback to mode 0x%x\n",
-				videomode);
-			i = 0;
-		}
-		res_mode = (struct ctfb_res_modes *)
-			   &res_mode_init[vesa_modes[i].resindex];
-		if (vesa_modes[i].resindex > 2) {
-			puts ("\tUnsupported resolution, using default\n");
-			bpp = vesa_modes[1].bits_per_pixel;
-			div = fr_div[1];
-		}
-		bpp = vesa_modes[i].bits_per_pixel;
-		div = fr_div[vesa_modes[i].resindex];
-	} else {
-		res_mode = (struct ctfb_res_modes *) &var_mode;
-		bpp = video_get_params (res_mode, penv);
-	}
-
-	/* calculate hsync and vsync freq (info only) */
-	t1 = (res_mode->left_margin + res_mode->xres +
-	      res_mode->right_margin + res_mode->hsync_len) / 8;
-	t1 *= 8;
-	t1 *= res_mode->pixclock;
-	t1 /= 1000;
-	hsync = 1000000000L / t1;
-	t1 *= (res_mode->upper_margin + res_mode->yres +
-	       res_mode->lower_margin + res_mode->vsync_len);
-	t1 /= 1000;
-	vsync = 1000000000L / t1;
-
-	/* fill in Graphic device struct */
-	sprintf (dev->modeIdent, "%dx%dx%d %ldkHz %ldHz", res_mode->xres,
-		 res_mode->yres, bpp, (hsync / 1000), (vsync / 1000));
-	printf ("\t%s\n", dev->modeIdent);
-	dev->winSizeX = res_mode->xres;
-	dev->winSizeY = res_mode->yres;
-	dev->memSize = VIDEO_MEM_SIZE;
-
-	switch (bpp) {
-	case 8:
-		dev->gdfIndex = GDF__8BIT_INDEX;
-		dev->gdfBytesPP = 1;
-		break;
-	case 15:
-	case 16:
-		dev->gdfIndex = GDF_15BIT_555RGB;
-		dev->gdfBytesPP = 2;
-		break;
-	default:
-		printf ("\t%d bpp configured, but only 8,15 and 16 supported\n",
-			bpp);
-		puts ("\tfallback to 15bpp\n");
-		dev->gdfIndex = GDF_15BIT_555RGB;
-		dev->gdfBytesPP = 2;
-	}
-
-	/* Setup dot clock (internal pll, division rate) */
-	DISP_WR_REG (GC_DCM1, div);
-	/* L0 init */
-	cf = (dev->gdfBytesPP == 1) ? 0x00000000 : 0x80000000;
-	DISP_WR_REG (GC_L0M, ((dev->winSizeX * dev->gdfBytesPP) / 64) << 16 |
-			     (dev->winSizeY - 1) | cf);
-	DISP_WR_REG (GC_L0OA0, 0x0);
-	DISP_WR_REG (GC_L0DA0, 0x0);
-	DISP_WR_REG (GC_L0DY_L0DX, 0x0);
-	DISP_WR_REG (GC_L0EM, 0x0);
-	DISP_WR_REG (GC_L0WY_L0WX, 0x0);
-	DISP_WR_REG (GC_L0WH_L0WW, (dev->winSizeY - 1) << 16 | dev->winSizeX);
-
-	/* Display timing init */
-	DISP_WR_REG (GC_HTP_A, (dev->winSizeX +
-				res_mode->left_margin +
-				res_mode->right_margin +
-				res_mode->hsync_len - 1) << 16);
-	DISP_WR_REG (GC_HDB_HDP_A, (dev->winSizeX - 1) << 16 |
-				   (dev->winSizeX - 1));
-	DISP_WR_REG (GC_VSW_HSW_HSP_A,  (res_mode->vsync_len - 1) << 24 |
-					(res_mode->hsync_len - 1) << 16 |
-					(dev->winSizeX +
-					 res_mode->right_margin - 1));
-	DISP_WR_REG (GC_VTR_A, (dev->winSizeY + res_mode->lower_margin +
-				res_mode->upper_margin +
-				res_mode->vsync_len - 1) << 16);
-	DISP_WR_REG (GC_VDP_VSP_A, (dev->winSizeY-1) << 16 |
-				   (dev->winSizeY +
-				    res_mode->lower_margin - 1));
-	DISP_WR_REG (GC_WY_WX, 0x0);
-	DISP_WR_REG (GC_WH_WW, dev->winSizeY << 16 | dev->winSizeX);
-	/* Display enable, L0 layer */
-	DISP_WR_REG (GC_DCM1, 0x80010000 | div);
-
-	return dev->frameAdrs;
-}
-#endif
-
-
-#if !defined(CONFIG_VIDEO_CORALP)
-int mb862xx_probe(unsigned int addr)
-{
-	GraphicDevice *dev = &mb862xx;
-	unsigned int reg;
-
-	dev->frameAdrs = addr;
-	dev->dprBase = dev->frameAdrs + GC_DRAW_BASE;
-
-	/* Try to access GDC ID/Revision registers */
-	reg = HOST_RD_REG (GC_CID);
-	reg = HOST_RD_REG (GC_CID);
-	if (reg == 0x303) {
-		reg = DE_RD_REG(GC_REV);
-		reg = DE_RD_REG(GC_REV);
-		if ((reg & ~0xff) == 0x20050100)
-			return MB862XX_TYPE_LIME;
-	}
-
-	return 0;
-}
-#endif
-
-void *video_hw_init (void)
-{
-	GraphicDevice *dev = &mb862xx;
-
-	puts ("Video: Fujitsu ");
-
-	memset (dev, 0, sizeof (GraphicDevice));
-
-#if defined(CONFIG_VIDEO_CORALP)
-	if (card_init () == 0)
-		return NULL;
-#else
-	/*
-	 * Preliminary init of the onboard graphic controller,
-	 * retrieve base address
-	 */
-	if ((dev->frameAdrs = board_video_init ()) == 0) {
-		puts ("Controller not found!\n");
-		return NULL;
-	} else {
-		puts ("Lime\n");
-
-		/* Set Change of Clock Frequency Register */
-		HOST_WR_REG (GC_CCF, CONFIG_SYS_MB862xx_CCF);
-		/* Delay required */
-		udelay(300);
-		/* Set Memory I/F Mode Register) */
-		HOST_WR_REG (GC_MMR, CONFIG_SYS_MB862xx_MMR);
-	}
-#endif
-
-	de_init ();
-
-#if !defined(CONFIG_VIDEO_CORALP)
-	board_disp_init ();
-#endif
-
-#if (defined(CONFIG_LWMON5) || \
-     defined(CONFIG_SOCRATES)) && !(CONFIG_POST & CONFIG_SYS_POST_SYSMON)
-	/* Lamp on */
-	board_backlight_switch (1);
-#endif
-
-	return dev;
-}
-
-/*
- * Set a RGB color in the LUT
- */
-void video_set_lut (unsigned int index, unsigned char r,
-		    unsigned char g, unsigned char b)
-{
-	GraphicDevice *dev = &mb862xx;
-
-	L0PAL_WR_REG (index, (r << 16) | (g << 8) | (b));
-}
-
-#if defined(CONFIG_VIDEO_MB862xx_ACCEL)
-/*
- * Drawing engine Fill and BitBlt screen region
- */
-void video_hw_rectfill (unsigned int bpp, unsigned int dst_x,
-			unsigned int dst_y, unsigned int dim_x,
-			unsigned int dim_y, unsigned int color)
-{
-	GraphicDevice *dev = &mb862xx;
-
-	de_wait_slots (3);
-	DE_WR_REG (GC_FC, color);
-	DE_WR_FIFO (0x09410000);
-	DE_WR_FIFO ((dst_y << 16) | dst_x);
-	DE_WR_FIFO ((dim_y << 16) | dim_x);
-	de_wait ();
-}
-
-void video_hw_bitblt (unsigned int bpp, unsigned int src_x,
-		      unsigned int src_y, unsigned int dst_x,
-		      unsigned int dst_y, unsigned int width,
-		      unsigned int height)
-{
-	GraphicDevice *dev = &mb862xx;
-	unsigned int ctrl = 0x0d000000L;
-
-	if (src_x >= dst_x && src_y >= dst_y)
-		ctrl |= 0x00440000L;
-	else if (src_x >= dst_x && src_y <= dst_y)
-		ctrl |= 0x00460000L;
-	else if (src_x <= dst_x && src_y >= dst_y)
-		ctrl |= 0x00450000L;
-	else
-		ctrl |= 0x00470000L;
-
-	de_wait_slots (4);
-	DE_WR_FIFO (ctrl);
-	DE_WR_FIFO ((src_y << 16) | src_x);
-	DE_WR_FIFO ((dst_y << 16) | dst_x);
-	DE_WR_FIFO ((height << 16) | width);
-	de_wait (); /* sync */
-}
-#endif
diff --git a/drivers/video/nexell_display.c b/drivers/video/nexell_display.c
index b47bef3..c7621ef 100644
--- a/drivers/video/nexell_display.c
+++ b/drivers/video/nexell_display.c
@@ -15,7 +15,7 @@
 #include <malloc.h>
 #include <linux/compat.h>
 #include <linux/err.h>
-#include <video.h>		/* For struct video_uc_platdata */
+#include <video.h>		/* For struct video_uc_plat */
 #include <video_fb.h>
 #include <lcd.h>
 #include <asm/global_data.h>
diff --git a/drivers/video/simple_panel.c b/drivers/video/simple_panel.c
index 59e17f8..c8f7022 100644
--- a/drivers/video/simple_panel.c
+++ b/drivers/video/simple_panel.c
@@ -108,6 +108,8 @@
 	{ .compatible = "auo,b133htn01" },
 	{ .compatible = "boe,nv140fhmn49" },
 	{ .compatible = "lg,lb070wv8" },
+	{ .compatible = "sharp,lq123p1jx31" },
+	{ .compatible = "boe,nv101wxmn51" },
 	{ }
 };
 
diff --git a/include/_exports.h b/include/_exports.h
index aeb666c..8030d70 100644
--- a/include/_exports.h
+++ b/include/_exports.h
@@ -40,7 +40,7 @@
 	EXPORT_FUNC(simple_strtol, long, simple_strtol,
 		    const char *, char **, unsigned int)
 	EXPORT_FUNC(strcmp, int, strcmp, const char *cs, const char *ct)
-#if defined(CONFIG_CMD_I2C) && !defined(CONFIG_DM_I2C)
+#if defined(CONFIG_CMD_I2C) && !CONFIG_IS_ENABLED(DM_I2C)
 	EXPORT_FUNC(i2c_write, int, i2c_write, uchar, uint, int , uchar * , int)
 	EXPORT_FUNC(i2c_read, int, i2c_read, uchar, uint, int , uchar * , int)
 #else
diff --git a/include/config_fallbacks.h b/include/config_fallbacks.h
index c18f19a..a318926 100644
--- a/include/config_fallbacks.h
+++ b/include/config_fallbacks.h
@@ -46,7 +46,7 @@
 #define CONFIG_SYS_MAXARGS	16
 #endif
 
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
 # ifdef CONFIG_SYS_I2C
 #  error "Cannot define CONFIG_SYS_I2C when CONFIG_DM_I2C is used"
 # endif
diff --git a/include/configs/MPC8548CDS.h b/include/configs/MPC8548CDS.h
index 4efc182..0605f70 100644
--- a/include/configs/MPC8548CDS.h
+++ b/include/configs/MPC8548CDS.h
@@ -296,7 +296,7 @@
 /*
  * I2C
  */
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 #define CONFIG_SYS_I2C
 #define CONFIG_SYS_FSL_I2C_SPEED	400000
 #define CONFIG_SYS_FSL_I2C_SLAVE	0x7F
diff --git a/include/configs/P1010RDB.h b/include/configs/P1010RDB.h
index 806d154..1b68fd1 100644
--- a/include/configs/P1010RDB.h
+++ b/include/configs/P1010RDB.h
@@ -525,7 +525,7 @@
 #define CONFIG_SYS_NS16550_COM2	(CONFIG_SYS_CCSRBAR+0x4600)
 
 /* I2C */
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 #define CONFIG_SYS_I2C
 #define CONFIG_SYS_FSL_I2C_SPEED	400000
 #define CONFIG_SYS_FSL_I2C_SLAVE	0x7F
diff --git a/include/configs/P2041RDB.h b/include/configs/P2041RDB.h
index 65d3dfa..3895c2d 100644
--- a/include/configs/P2041RDB.h
+++ b/include/configs/P2041RDB.h
@@ -259,7 +259,7 @@
 #define CONFIG_SYS_NS16550_COM4	(CONFIG_SYS_CCSRBAR+0x11D600)
 
 /* I2C */
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 #define CONFIG_SYS_I2C
 #define CONFIG_SYS_FSL_I2C_SPEED	400000
 #define CONFIG_SYS_FSL_I2C_SLAVE	0x7F
diff --git a/include/configs/T102xRDB.h b/include/configs/T102xRDB.h
index 201da87..35b11ad 100644
--- a/include/configs/T102xRDB.h
+++ b/include/configs/T102xRDB.h
@@ -422,7 +422,7 @@
 #endif
 
 /* I2C */
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 #define CONFIG_SYS_I2C
 #define CONFIG_SYS_FSL_I2C_SPEED	50000	/* I2C speed in Hz */
 #define CONFIG_SYS_FSL_I2C_SLAVE	0x7F
diff --git a/include/configs/T104xRDB.h b/include/configs/T104xRDB.h
index aee00a8..ea239f7 100644
--- a/include/configs/T104xRDB.h
+++ b/include/configs/T104xRDB.h
@@ -30,7 +30,6 @@
 #define CONFIG_SPL_SKIP_RELOCATE
 #define CONFIG_SPL_COMMON_INIT_DDR
 #define CONFIG_SYS_CCSR_DO_NOT_RELOCATE
-#undef CONFIG_DM_I2C
 #endif
 #define RESET_VECTOR_OFFSET		0x27FFC
 #define BOOT_PAGE_OFFSET		0x27000
@@ -453,7 +452,7 @@
 #endif
 
 /* I2C */
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 #define CONFIG_SYS_I2C
 #define CONFIG_SYS_FSL_I2C_SPEED	400000	/* I2C speed in Hz */
 #define CONFIG_SYS_FSL_I2C2_SPEED	400000
diff --git a/include/configs/T208xQDS.h b/include/configs/T208xQDS.h
index 1735b17..f0ef365 100644
--- a/include/configs/T208xQDS.h
+++ b/include/configs/T208xQDS.h
@@ -377,7 +377,7 @@
 /*
  * I2C
  */
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 #define CONFIG_SYS_I2C
 #define CONFIG_SYS_FSL_I2C_SLAVE   0x7F
 #define CONFIG_SYS_FSL_I2C2_SLAVE  0x7F
diff --git a/include/configs/T208xRDB.h b/include/configs/T208xRDB.h
index 30e3844..e467ef4 100644
--- a/include/configs/T208xRDB.h
+++ b/include/configs/T208xRDB.h
@@ -322,7 +322,7 @@
 /*
  * I2C
  */
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 #define CONFIG_SYS_I2C
 #define CONFIG_SYS_FSL_I2C_SLAVE   0x7F
 #define CONFIG_SYS_FSL_I2C2_SLAVE  0x7F
diff --git a/include/configs/T4240RDB.h b/include/configs/T4240RDB.h
index 7f831fb..a04d913 100644
--- a/include/configs/T4240RDB.h
+++ b/include/configs/T4240RDB.h
@@ -154,7 +154,7 @@
 #define CONFIG_SYS_NS16550_COM4	(CONFIG_SYS_CCSRBAR+0x11D600)
 
 /* I2C */
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 #define CONFIG_SYS_I2C
 #define CONFIG_SYS_FSL_I2C_SLAVE	0x7F
 #define CONFIG_SYS_FSL_I2C_OFFSET	0x118000
diff --git a/include/configs/am43xx_evm.h b/include/configs/am43xx_evm.h
index 8355b4a..6df6b49 100644
--- a/include/configs/am43xx_evm.h
+++ b/include/configs/am43xx_evm.h
@@ -26,7 +26,7 @@
 #define CONFIG_SYS_I2C_EEPROM_ADDR_LEN	2
 
 /* Power */
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 #define CONFIG_POWER
 #define CONFIG_POWER_I2C
 #endif
diff --git a/include/configs/corenet_ds.h b/include/configs/corenet_ds.h
index 731f884..d0843c2 100644
--- a/include/configs/corenet_ds.h
+++ b/include/configs/corenet_ds.h
@@ -269,7 +269,7 @@
 #define CONFIG_SYS_NS16550_COM4	(CONFIG_SYS_CCSRBAR+0x11D600)
 
 /* I2C */
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 #define CONFIG_SYS_I2C
 #define CONFIG_SYS_FSL_I2C_SPEED	400000
 #define CONFIG_SYS_FSL_I2C_SLAVE	0x7F
diff --git a/include/configs/imx8mp_evk.h b/include/configs/imx8mp_evk.h
index 4850b1b..61a5c6f 100644
--- a/include/configs/imx8mp_evk.h
+++ b/include/configs/imx8mp_evk.h
@@ -37,7 +37,6 @@
 #define CONFIG_POWER_I2C
 #define CONFIG_POWER_PCA9450
 
-#undef CONFIG_DM_I2C
 #define CONFIG_SYS_I2C
 
 #endif
diff --git a/include/configs/ls1012a_common.h b/include/configs/ls1012a_common.h
index f6b5d47..a908b0a 100644
--- a/include/configs/ls1012a_common.h
+++ b/include/configs/ls1012a_common.h
@@ -55,7 +55,7 @@
 						CONFIG_SYS_SCSI_MAX_LUN)
 
 /* I2C */
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 #define CONFIG_SYS_I2C
 #else
 #define CONFIG_I2C_SET_DEFAULT_BUS_NUM
diff --git a/include/configs/ls1021aiot.h b/include/configs/ls1021aiot.h
index cf4d60a..e2ae6e4 100644
--- a/include/configs/ls1021aiot.h
+++ b/include/configs/ls1021aiot.h
@@ -98,7 +98,7 @@
  * I2C
  */
 
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 #define CONFIG_SYS_I2C
 #else
 #define CONFIG_I2C_SET_DEFAULT_BUS_NUM
diff --git a/include/configs/ls1021aqds.h b/include/configs/ls1021aqds.h
index b4c7033..7f65845 100644
--- a/include/configs/ls1021aqds.h
+++ b/include/configs/ls1021aqds.h
@@ -330,7 +330,7 @@
 /*
  * I2C
  */
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 #define CONFIG_SYS_I2C
 #else
 #define CONFIG_I2C_SET_DEFAULT_BUS_NUM
diff --git a/include/configs/ls1021atsn.h b/include/configs/ls1021atsn.h
index 996c970..f76d5a1 100644
--- a/include/configs/ls1021atsn.h
+++ b/include/configs/ls1021atsn.h
@@ -104,7 +104,7 @@
 #define CONFIG_SYS_NS16550_CLK		get_serial_clock()
 
 /* I2C */
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 #define CONFIG_SYS_I2C
 #else
 #define CONFIG_I2C_SET_DEFAULT_BUS_NUM
diff --git a/include/configs/ls1021atwr.h b/include/configs/ls1021atwr.h
index dfb5643..d6783db 100644
--- a/include/configs/ls1021atwr.h
+++ b/include/configs/ls1021atwr.h
@@ -208,7 +208,7 @@
 /*
  * I2C
  */
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 #define CONFIG_SYS_I2C
 #else
 #define CONFIG_I2C_SET_DEFAULT_BUS_NUM
@@ -442,7 +442,6 @@
 
 #ifdef CONFIG_SPL_BUILD
 #define CONFIG_SYS_MONITOR_BASE CONFIG_SPL_TEXT_BASE
-#undef CONFIG_DM_I2C
 #else
 #define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE    /* start of monitor */
 #endif
diff --git a/include/configs/ls1028a_common.h b/include/configs/ls1028a_common.h
index 1c4af7d..31fcdae 100644
--- a/include/configs/ls1028a_common.h
+++ b/include/configs/ls1028a_common.h
@@ -44,7 +44,7 @@
 #endif
 
 /* I2C */
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 #define CONFIG_SYS_I2C
 #endif
 
diff --git a/include/configs/ls1043a_common.h b/include/configs/ls1043a_common.h
index 4e3e1a9..29a3790 100644
--- a/include/configs/ls1043a_common.h
+++ b/include/configs/ls1043a_common.h
@@ -149,7 +149,7 @@
 #endif
 
 /* I2C */
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 #define CONFIG_SYS_I2C
 #define CONFIG_SYS_I2C_MXC_I2C1		/* enable I2C bus 1 */
 #define CONFIG_SYS_I2C_MXC_I2C2		/* enable I2C bus 2 */
diff --git a/include/configs/ls1046a_common.h b/include/configs/ls1046a_common.h
index 32658cf..0c3978a 100644
--- a/include/configs/ls1046a_common.h
+++ b/include/configs/ls1046a_common.h
@@ -16,7 +16,6 @@
 #define SPL_NO_QSPI
 #define SPL_NO_USB
 #define SPL_NO_SATA
-#undef CONFIG_DM_I2C
 #endif
 #if defined(CONFIG_SPL_BUILD) && \
 	(defined(CONFIG_NAND_BOOT) || defined(CONFIG_QSPI_BOOT))
@@ -134,7 +133,7 @@
 #endif
 
 /* I2C */
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 #define CONFIG_SYS_I2C
 #define CONFIG_SYS_I2C_MXC_I2C1		/* enable I2C bus 1 */
 #define CONFIG_SYS_I2C_MXC_I2C2		/* enable I2C bus 2 */
diff --git a/include/configs/ls1088a_common.h b/include/configs/ls1088a_common.h
index b9a956b..d574e7e 100644
--- a/include/configs/ls1088a_common.h
+++ b/include/configs/ls1088a_common.h
@@ -61,7 +61,7 @@
 #endif
 
 /* I2C */
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 #define CONFIG_SYS_I2C
 #endif
 
diff --git a/include/configs/ls1088aqds.h b/include/configs/ls1088aqds.h
index 1626e65..0dcf844 100644
--- a/include/configs/ls1088aqds.h
+++ b/include/configs/ls1088aqds.h
@@ -26,7 +26,7 @@
 #define CONFIG_DDR_CLK_FREQ		100000000
 #else
 #define CONFIG_QIXIS_I2C_ACCESS
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 #define CONFIG_SYS_I2C_EARLY_INIT
 #endif
 #define CONFIG_SYS_CLK_FREQ		get_board_sys_clk()
diff --git a/include/configs/ls2080a_common.h b/include/configs/ls2080a_common.h
index 1042555..2ed6584 100644
--- a/include/configs/ls2080a_common.h
+++ b/include/configs/ls2080a_common.h
@@ -74,7 +74,7 @@
 #endif
 
 /* I2C */
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 #define CONFIG_SYS_I2C
 #endif
 
diff --git a/include/configs/ls2080aqds.h b/include/configs/ls2080aqds.h
index 9e174af..b3fce1b 100644
--- a/include/configs/ls2080aqds.h
+++ b/include/configs/ls2080aqds.h
@@ -16,7 +16,7 @@
 
 #ifdef CONFIG_FSL_QSPI
 #define CONFIG_QIXIS_I2C_ACCESS
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 #define CONFIG_SYS_I2C_EARLY_INIT
 #endif
 #define CONFIG_SYS_I2C_IFDR_DIV		0x7e
diff --git a/include/configs/ls2080ardb.h b/include/configs/ls2080ardb.h
index ab4214c..8626a1d 100644
--- a/include/configs/ls2080ardb.h
+++ b/include/configs/ls2080ardb.h
@@ -13,7 +13,7 @@
 #ifdef CONFIG_TARGET_LS2081ARDB
 #define CONFIG_QIXIS_I2C_ACCESS
 #endif
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 #define CONFIG_SYS_I2C_EARLY_INIT
 #endif
 #endif
diff --git a/include/configs/p1_p2_rdb_pc.h b/include/configs/p1_p2_rdb_pc.h
index a9bf213..066311a 100644
--- a/include/configs/p1_p2_rdb_pc.h
+++ b/include/configs/p1_p2_rdb_pc.h
@@ -463,7 +463,7 @@
 #define CONFIG_SYS_NS16550_COM2	(CONFIG_SYS_CCSRBAR+0x4600)
 
 /* I2C */
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 #define CONFIG_SYS_I2C
 #define CONFIG_SYS_FSL_I2C_SPEED	400000
 #define CONFIG_SYS_FSL_I2C_SLAVE	0x7F
diff --git a/include/configs/phycore_imx8mp.h b/include/configs/phycore_imx8mp.h
index 889dd36..0490049 100644
--- a/include/configs/phycore_imx8mp.h
+++ b/include/configs/phycore_imx8mp.h
@@ -33,7 +33,6 @@
 #define CONFIG_POWER_I2C
 #define CONFIG_POWER_PCA9450
 
-#undef CONFIG_DM_I2C
 #define CONFIG_SYS_I2C
 
 #endif
diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
index 000f386..7b602dd 100644
--- a/include/configs/sunxi-common.h
+++ b/include/configs/sunxi-common.h
@@ -134,11 +134,6 @@
 #define CONFIG_BOARD_SIZE_LIMIT		0x7e000
 #endif
 
-#if CONFIG_MMC_SUNXI_SLOT_EXTRA != -1
-/* If we have two devices (most likely eMMC + MMC), favour the eMMC */
-#else
-/* Otherwise, use the only device we have */
-#endif
 #define CONFIG_SYS_MMC_MAX_DEVICE	4
 #endif
 
@@ -199,15 +194,11 @@
 
 
 /* I2C */
-#if defined CONFIG_AXP152_POWER || defined CONFIG_AXP209_POWER || \
-    defined CONFIG_SY8106A_POWER
-#endif
-
 #if defined CONFIG_I2C0_ENABLE || defined CONFIG_I2C1_ENABLE || \
     defined CONFIG_I2C2_ENABLE || defined CONFIG_I2C3_ENABLE || \
     defined CONFIG_I2C4_ENABLE || defined CONFIG_R_I2C_ENABLE
 #define CONFIG_SYS_I2C_MVTWSI
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 #define CONFIG_SYS_I2C
 #define CONFIG_SYS_I2C_SPEED		400000
 #define CONFIG_SYS_I2C_SLAVE		0x7f
@@ -231,30 +222,6 @@
 #define CONFIG_SYS_SPD_BUS_NUM		0 /* The axp209 i2c bus is bus 0 */
 #define CONFIG_VIDEO_LCD_I2C_BUS	-1 /* NA, but necessary to compile */
 #endif
-
-/* PMU */
-#if defined CONFIG_AXP152_POWER || defined CONFIG_AXP209_POWER || \
-    defined CONFIG_AXP221_POWER || defined CONFIG_AXP818_POWER || \
-    defined CONFIG_SY8106A_POWER
-#endif
-
-#ifdef CONFIG_REQUIRE_SERIAL_CONSOLE
-#if CONFIG_CONS_INDEX == 1
-#ifdef CONFIG_MACH_SUN9I
-#define OF_STDOUT_PATH		"/soc/serial@07000000:115200"
-#else
-#define OF_STDOUT_PATH		"/soc@01c00000/serial@01c28000:115200"
-#endif
-#elif CONFIG_CONS_INDEX == 2 && defined(CONFIG_MACH_SUN5I)
-#define OF_STDOUT_PATH		"/soc@01c00000/serial@01c28400:115200"
-#elif CONFIG_CONS_INDEX == 3 && defined(CONFIG_MACH_SUN8I)
-#define OF_STDOUT_PATH		"/soc@01c00000/serial@01c28800:115200"
-#elif CONFIG_CONS_INDEX == 5 && defined(CONFIG_MACH_SUN8I)
-#define OF_STDOUT_PATH		"/soc@01c00000/serial@01f02800:115200"
-#else
-#error Unsupported console port nr. Please fix stdout-path in sunxi-common.h.
-#endif
-#endif /* ifdef CONFIG_REQUIRE_SERIAL_CONSOLE */
 
 #ifdef CONFIG_VIDEO_SUNXI
 /*
diff --git a/include/configs/ti_armv7_common.h b/include/configs/ti_armv7_common.h
index 0c9856a..f13e9e5 100644
--- a/include/configs/ti_armv7_common.h
+++ b/include/configs/ti_armv7_common.h
@@ -87,7 +87,7 @@
 #define CONFIG_SYS_PTV			2	/* Divisor: 2^(PTV+1) => 8 */
 
 /* If DM_I2C, enable non-DM I2C support */
-#if !defined(CONFIG_DM_I2C)
+#if !CONFIG_IS_ENABLED(DM_I2C)
 #define CONFIG_I2C
 #define CONFIG_SYS_I2C
 #endif
diff --git a/include/dm/device.h b/include/dm/device.h
index 28533ce..bb9faa0 100644
--- a/include/dm/device.h
+++ b/include/dm/device.h
@@ -159,6 +159,8 @@
  *		When CONFIG_DEVRES is enabled, devm_kmalloc() and friends will
  *		add to this list. Memory so-allocated will be freed
  *		automatically when the device is removed / unbound
+ * @dma_offset: Offset between the physical address space (CPU's) and the
+ *		device's bus address space
  */
 struct udevice {
 	const struct driver *driver;
@@ -183,6 +185,9 @@
 #ifdef CONFIG_DEVRES
 	struct list_head devres_head;
 #endif
+#if CONFIG_IS_ENABLED(DM_DMA)
+	ulong dma_offset;
+#endif
 };
 
 /* Maximum sequence number supported */
@@ -224,6 +229,14 @@
 /* Returns non-zero if the device is active (probed and not removed) */
 #define device_active(dev)	(dev_get_flags(dev) & DM_FLAG_ACTIVATED)
 
+#if CONFIG_IS_ENABLED(DM_DMA)
+#define dev_set_dma_offset(_dev, _offset)	_dev->dma_offset = _offset
+#define dev_get_dma_offset(_dev)		_dev->dma_offset
+#else
+#define dev_set_dma_offset(_dev, _offset)
+#define dev_get_dma_offset(_dev)		0
+#endif
+
 static inline int dev_of_offset(const struct udevice *dev)
 {
 #if !CONFIG_IS_ENABLED(OF_PLATDATA)
diff --git a/include/dm/of_addr.h b/include/dm/of_addr.h
index 3fa1ffc..ee21d5c 100644
--- a/include/dm/of_addr.h
+++ b/include/dm/of_addr.h
@@ -44,6 +44,23 @@
  */
 u64 of_translate_dma_address(const struct device_node *no, const __be32 *in_addr);
 
+
+/**
+ * of_get_dma_range() - get dma-ranges for a specific DT node
+ *
+ * Get DMA ranges for a specifc node, this is useful to perform bus->cpu and
+ * cpu->bus address translations
+ *
+ * @param blob		Pointer to device tree blob
+ * @param node_offset	Node DT offset
+ * @param cpu		Pointer to variable storing the range's cpu address
+ * @param bus		Pointer to variable storing the range's bus address
+ * @param size		Pointer to variable storing the range's size
+ * @return translated DMA address or OF_BAD_ADDR on error
+ */
+int of_get_dma_range(const struct device_node *dev, phys_addr_t *cpu,
+		     dma_addr_t *bus, u64 *size);
+
 /**
  * of_get_address() - obtain an address from a node
  *
diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h
index 5318d65..2c0597c 100644
--- a/include/dm/ofnode.h
+++ b/include/dm/ofnode.h
@@ -999,6 +999,22 @@
 u64 ofnode_translate_dma_address(ofnode node, const fdt32_t *in_addr);
 
 /**
+ * ofnode_get_dma_range() - get dma-ranges for a specific DT node
+ *
+ * Get DMA ranges for a specifc node, this is useful to perform bus->cpu and
+ * cpu->bus address translations
+ *
+ * @param blob		Pointer to device tree blob
+ * @param node_offset	Node DT offset
+ * @param cpu		Pointer to variable storing the range's cpu address
+ * @param bus		Pointer to variable storing the range's bus address
+ * @param size		Pointer to variable storing the range's size
+ * @return translated DMA address or OF_BAD_ADDR on error
+ */
+int ofnode_get_dma_range(ofnode node, phys_addr_t *cpu, dma_addr_t *bus,
+			 u64 *size);
+
+/**
  * ofnode_device_is_compatible() - check if the node is compatible with compat
  *
  * This allows to check whether the node is comaptible with the compat.
diff --git a/include/dm/read.h b/include/dm/read.h
index 97575bc..5bf3405 100644
--- a/include/dm/read.h
+++ b/include/dm/read.h
@@ -648,6 +648,21 @@
 			      const fdt32_t *in_addr);
 
 /**
+ * dev_get_dma_range() - Get a device's DMA constraints
+ *
+ * Provide the address bases and size of the linear mapping between the CPU and
+ * a device's BUS address space.
+ *
+ * @dev: device giving the context in which to translate the DMA address
+ * @cpu: base address for CPU's view of memory
+ * @bus: base address for BUS's view of memory
+ * @size: size of the address space
+ * @return 0 if ok, negative on error
+ */
+int dev_get_dma_range(const struct udevice *dev, phys_addr_t *cpu,
+		      dma_addr_t *bus, u64 *size);
+
+/**
  * dev_read_alias_highest_id - Get highest alias id for the given stem
  * @stem:	Alias stem to be examined
  *
@@ -1005,6 +1020,12 @@
 	return ofnode_translate_dma_address(dev_ofnode(dev), in_addr);
 }
 
+static inline int dev_get_dma_range(const struct udevice *dev, phys_addr_t *cpu,
+				    dma_addr_t *bus, u64 *size)
+{
+	return ofnode_get_dma_range(dev_ofnode(dev), cpu, bus, size);
+}
+
 static inline int dev_read_alias_highest_id(const char *stem)
 {
 	if (!CONFIG_IS_ENABLED(OF_LIBFDT) || !gd->fdt_blob)
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index ae4425d..d75de36 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -46,6 +46,7 @@
 	UCLASS_DISPLAY,		/* Display (e.g. DisplayPort, HDMI) */
 	UCLASS_DSI_HOST,	/* Display Serial Interface host */
 	UCLASS_DMA,		/* Direct Memory Access */
+	UCLASS_DSA,		/* Distributed (Ethernet) Switch Architecture */
 	UCLASS_EFI,		/* EFI managed devices */
 	UCLASS_ETH,		/* Ethernet device */
 	UCLASS_ETH_PHY,		/* Ethernet PHY device */
diff --git a/include/exports.h b/include/exports.h
index 99436e4..550cafd 100644
--- a/include/exports.h
+++ b/include/exports.h
@@ -49,7 +49,7 @@
 int strcmp(const char *cs, const char *ct);
 unsigned long ustrtoul(const char *cp, char **endp, unsigned int base);
 unsigned long long ustrtoull(const char *cp, char **endp, unsigned int base);
-#if defined(CONFIG_CMD_I2C) && !defined(CONFIG_DM_I2C)
+#if defined(CONFIG_CMD_I2C) && !CONFIG_IS_ENABLED(DM_I2C)
 int i2c_write (uchar, uint, int , uchar* , int);
 int i2c_read (uchar, uint, int , uchar* , int);
 #endif
diff --git a/include/fdt_support.h b/include/fdt_support.h
index dbbac0f..46eb1db 100644
--- a/include/fdt_support.h
+++ b/include/fdt_support.h
@@ -260,6 +260,20 @@
 u64 fdt_translate_dma_address(const void *blob, int node_offset,
 			      const __be32 *in_addr);
 
+/**
+ * Get DMA ranges for a specifc node, this is useful to perform bus->cpu and
+ * cpu->bus address translations
+ *
+ * @param blob		Pointer to device tree blob
+ * @param node_offset	Node DT offset
+ * @param cpu		Pointer to variable storing the range's cpu address
+ * @param bus		Pointer to variable storing the range's bus address
+ * @param size		Pointer to variable storing the range's size
+ * @return translated DMA address or OF_BAD_ADDR on error
+ */
+int fdt_get_dma_range(const void *blob, int node_offset, phys_addr_t *cpu,
+		      dma_addr_t *bus, u64 *size);
+
 int fdt_node_offset_by_compat_reg(void *blob, const char *compat,
 					phys_addr_t compat_off);
 int fdt_alloc_phandle(void *blob);
diff --git a/include/i2c.h b/include/i2c.h
index e45e33f..7ae0c42 100644
--- a/include/i2c.h
+++ b/include/i2c.h
@@ -581,7 +581,7 @@
  */
 int acpi_i2c_of_to_plat(struct udevice *dev);
 
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 
 /*
  * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
diff --git a/include/image.h b/include/image.h
index d5a9403..138c83d 100644
--- a/include/image.h
+++ b/include/image.h
@@ -1556,8 +1556,6 @@
  */
 int board_fit_config_name_match(const char *name);
 
-#if defined(CONFIG_SPL_FIT_IMAGE_POST_PROCESS) || \
-	defined(CONFIG_FIT_IMAGE_POST_PROCESS)
 /**
  * board_fit_image_post_process() - Do any post-process on FIT binary data
  *
@@ -1572,11 +1570,6 @@
  * @return no return value (failure should be handled internally)
  */
 void board_fit_image_post_process(void **p_image, size_t *p_size);
-#else
-static inline void board_fit_image_post_process(void **p_image, size_t *p_size)
-{
-}
-#endif /* CONFIG_SPL_FIT_IMAGE_POST_PROCESS */
 
 #define FDT_ERROR	((ulong)(-1))
 
diff --git a/include/iomux.h b/include/iomux.h
index da7ff69..37f5f6d 100644
--- a/include/iomux.h
+++ b/include/iomux.h
@@ -24,7 +24,14 @@
  */
 extern int cd_count[MAX_FILES];
 
+#define for_each_console_dev(i, file, dev)		\
+	for (i = 0, dev = console_devices[file][i];	\
+	     i < cd_count[file];			\
+	     i++, dev = console_devices[file][i])
+
+int iomux_match_device(struct stdio_dev **, const int, struct stdio_dev *);
 int iomux_doenv(const int, const char *);
+int iomux_replace_device(const int, const char *, const char *);
 void iomux_printdevs(const int);
 
 #endif /* _IO_MUX_H */
diff --git a/include/mb862xx.h b/include/mb862xx.h
deleted file mode 100644
index 54c8c75..0000000
--- a/include/mb862xx.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * (C) Copyright 2007
- * DENX Software Engineering, Anatolij Gustschin, agust@denx.de
- */
-
-/*
- * mb862xx.h - Graphic interface for Fujitsu CoralP/Lime
- */
-
-#ifndef _MB862XX_H_
-#define _MB862XX_H_
-
-#define PCI_VENDOR_ID_FUJITSU	0x10CF
-#define PCI_DEVICE_ID_CORAL_P	0x2019
-#define PCI_DEVICE_ID_CORAL_PA	0x201E
-
-#define MB862XX_TYPE_LIME	0x1
-
-#define GC_HOST_BASE		0x01fc0000
-#define GC_DISP_BASE		0x01fd0000
-#define GC_DRAW_BASE		0x01ff0000
-
-/* Host interface registers */
-#define GC_SRST			0x0000002c
-#define GC_CCF			0x00000038
-#define GC_CID			0x000000f0
-#define GC_MMR			0x0000fffc
-
-/*
- * Display Controller registers
- * _A means the offset is aligned, we use these for boards
- * with 8-/16-bit GDC access not working or buggy.
- */
-#define GC_DCM0			0x00000000
-#define GC_HTP_A		0x00000004
-#define GC_HTP			0x00000006
-#define GC_HDB_HDP_A		0x00000008
-#define GC_HDP			0x00000008
-#define GC_HDB			0x0000000a
-#define GC_VSW_HSW_HSP_A	0x0000000c
-#define GC_HSP			0x0000000c
-#define GC_HSW			0x0000000e
-#define GC_VSW			0x0000000f
-#define GC_VTR_A		0x00000010
-#define GC_VTR			0x00000012
-#define GC_VDP_VSP_A		0x00000014
-#define GC_VSP			0x00000014
-#define GC_VDP			0x00000016
-#define GC_WY_WX		0x00000018
-#define GC_WH_WW		0x0000001c
-#define GC_L0M			0x00000020
-#define GC_L0OA0		0x00000024
-#define GC_L0DA0		0x00000028
-#define GC_L0DY_L0DX		0x0000002c
-#define GC_L2M			0x00000040
-#define GC_L2OA0		0x00000044
-#define GC_L2DA0		0x00000048
-#define GC_L2OA1		0x0000004c
-#define GC_L2DA1		0x00000050
-#define GC_L2DX			0x00000054
-#define GC_L2DY			0x00000056
-#define GC_DCM1			0x00000100
-#define GC_DCM2			0x00000104
-#define GC_DCM3			0x00000108
-#define GC_L0EM			0x00000110
-#define GC_L0WY_L0WX		0x00000114
-#define GC_L0WH_L0WW		0x00000118
-#define GC_L2EM			0x00000130
-#define GC_L2WX			0x00000134
-#define GC_L2WY			0x00000136
-#define GC_L2WW			0x00000138
-#define GC_L2WH			0x0000013a
-#define GC_L0PAL0		0x00000400
-
-/* Drawing registers */
-#define GC_CTR			0x00000400
-#define GC_IFCNT		0x00000408
-#define GC_FBR			0x00000440
-#define GC_XRES			0x00000444
-#define GC_CXMIN		0x00000454
-#define GC_CXMAX		0x00000458
-#define GC_CYMIN		0x0000045c
-#define GC_CYMAX		0x00000460
-#define GC_FC			0x00000480
-#define GC_BC			0x00000484
-#define GC_FIFO			0x000004a0
-#define GC_REV			0x00008084
-#define GC_GEO_FIFO		0x00008400
-
-typedef struct {
-	unsigned int index;
-	unsigned int value;
-} gdc_regs;
-
-int mb862xx_probe(unsigned int addr);
-const gdc_regs *board_get_regs (void);
-unsigned int board_video_init (void);
-void board_backlight_switch(int);
-
-#endif /* _MB862XX_H_ */
diff --git a/include/mmc.h b/include/mmc.h
index 1d377e0..8600881 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -178,6 +178,7 @@
 #define MMC_STATUS_ERROR	(1 << 19)
 
 #define MMC_STATE_PRG		(7 << 9)
+#define MMC_STATE_TRANS		(4 << 9)
 
 #define MMC_VDD_165_195		0x00000080	/* VDD voltage 1.65 - 1.95 */
 #define MMC_VDD_20_21		0x00000100	/* VDD voltage 2.0 ~ 2.1 */
@@ -591,6 +592,9 @@
 	uint f_max;
 	uint b_max;
 	unsigned char part_type;
+#ifdef CONFIG_MMC_PWRSEQ
+	struct udevice *pwr_dev;
+#endif
 };
 
 struct sd_ssr {
@@ -736,6 +740,12 @@
 	u8 hs400_tuning;
 };
 
+#if CONFIG_IS_ENABLED(DM_MMC)
+#define mmc_to_dev(_mmc)	_mmc->dev
+#else
+#define mmc_to_dev(_mmc)	NULL
+#endif
+
 struct mmc_hwpart_conf {
 	struct {
 		uint enh_start;	/* in 512-byte sectors */
@@ -801,6 +811,17 @@
  */
 int mmc_of_parse(struct udevice *dev, struct mmc_config *cfg);
 
+#ifdef CONFIG_MMC_PWRSEQ
+/**
+ * mmc_pwrseq_get_power() - get a power device from device tree
+ *
+ * @dev:	MMC device
+ * @cfg:	MMC configuration
+ * @return 0 if OK, -ve on error
+ */
+int mmc_pwrseq_get_power(struct udevice *dev, struct mmc_config *cfg);
+#endif
+
 int mmc_read(struct mmc *mmc, u64 src, uchar *dst, int size);
 
 /**
diff --git a/include/net.h b/include/net.h
index 13da69b..b95d6a6 100644
--- a/include/net.h
+++ b/include/net.h
@@ -499,7 +499,13 @@
  * maximum packet size and multiple of 32 bytes =  1536
  */
 #define PKTSIZE			1522
+#ifndef CONFIG_DM_DSA
 #define PKTSIZE_ALIGN		1536
+#else
+/* Maximum DSA tagging overhead (headroom and/or tailroom) */
+#define DSA_MAX_OVR		256
+#define PKTSIZE_ALIGN		(1536 + DSA_MAX_OVR)
+#endif
 
 /*
  * Maximum receive ring size; that is, the number of packets
diff --git a/include/net/dsa.h b/include/net/dsa.h
new file mode 100644
index 0000000..0f31a90
--- /dev/null
+++ b/include/net/dsa.h
@@ -0,0 +1,165 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2019-2021 NXP Semiconductors
+ */
+
+#ifndef __DSA_H__
+#define __DSA_H__
+
+#include <phy.h>
+#include <net.h>
+
+/**
+ * DSA stands for Distributed Switch Architecture and it is infrastructure
+ * intended to support drivers for Switches that rely on an intermediary
+ * Ethernet device for I/O.  These switches may support cascading allowing
+ * them to be arranged as a tree.
+ * DSA is documented in detail in the Linux kernel documentation under
+ * Documentation/networking/dsa/dsa.txt
+ * The network layout of such a switch is shown below:
+ *
+ *                      |------|
+ *                      | eth0 | <--- master eth device (regular eth driver)
+ *                      |------|
+ *                        ^  |
+ * tag added by switch -->|  |
+ *                        |  |
+ *                        |  |<-- tag added by DSA driver
+ *                        |  v
+ *      |--------------------------------------|
+ *      |             | CPU port |             | <-- DSA (switch) device
+ *      |             ------------             |     (DSA driver)
+ *      | _________  _________       _________ |
+ *      | | port0 |  | port1 |  ...  | portn | | <-- ports as eth devices
+ *      |-+-------+--+-------+-------+-------+-|     ('dsa-port' eth driver)
+ *
+ * In U-Boot the intent is to allow access to front panel ports (shown at the
+ * bottom of the picture) through the master Ethernet dev (eth0 in the picture).
+ * Front panel ports are presented as regular Ethernet devices in U-Boot and
+ * they are expected to support the typical networking commands.
+ * In general DSA switches require the use of tags, extra headers added both by
+ * software on Tx and by the switch on Rx.  These tags carry at a minimum port
+ * information and switch information for cascaded set-ups.
+ * In U-Boot these tags are inserted and parsed by the DSA switch driver, the
+ * class code helps with headroom/tailroom for the extra headers.
+ *
+ * TODO:
+ * - handle switch cascading, for now U-Boot only supports stand-alone switches.
+ * - Add support to probe DSA switches connected to a MDIO bus, this is needed
+ * to convert switch drivers that are now under drivers/net/phy.
+ */
+
+#define DSA_PORT_NAME_LENGTH	16
+
+/* Maximum number of ports each DSA device can have */
+#define DSA_MAX_PORTS		12
+
+/**
+ * struct dsa_ops - DSA operations
+ *
+ * @port_enable:  Initialize a switch port for I/O.
+ * @port_disable: Disable I/O for a port.
+ * @xmit:         Insert the DSA tag for transmission.
+ *                DSA drivers receive a copy of the packet with headroom and
+ *                tailroom reserved and set to 0. 'packet' points to headroom
+ *                and 'length' is updated to include both head and tailroom.
+ * @rcv:          Process the DSA tag on reception and return the port index
+ *                from the h/w provided tag. Return the index via 'portp'.
+ *                'packet' and 'length' describe the frame as received from
+ *                master including any additional headers.
+ */
+struct dsa_ops {
+	int (*port_enable)(struct udevice *dev, int port,
+			   struct phy_device *phy);
+	void (*port_disable)(struct udevice *dev, int port,
+			     struct phy_device *phy);
+	int (*xmit)(struct udevice *dev, int port, void *packet, int length);
+	int (*rcv)(struct udevice *dev, int *portp, void *packet, int length);
+};
+
+#define dsa_get_ops(dev) ((struct dsa_ops *)(dev)->driver->ops)
+
+/**
+ * struct dsa_port_pdata - DSA port platform data
+ *
+ * @phy:   PHY device associated with this port.
+ *         The uclass code attempts to set this field for all ports except CPU
+ *         port, based on DT information.  It may be NULL.
+ * @index: Port index in the DSA switch, set by the uclass code.
+ * @name:  Name of the port Eth device.  If a label property is present in the
+ *         port DT node, it is used as name.
+ */
+struct dsa_port_pdata {
+	struct phy_device *phy;
+	u32 index;
+	char name[DSA_PORT_NAME_LENGTH];
+};
+
+/**
+ * struct dsa_pdata - Per-device platform data for DSA DM
+ *
+ * @num_ports:   Number of ports the device has, must be <= DSA_MAX_PORTS.
+ *		 This number is extracted from the DT 'ports' node of this
+ *		 DSA device, and it counts the CPU port and all the other
+ *		 port subnodes including the disabled ones.
+ * @cpu_port:    Index of the switch port linked to the master Ethernet.
+ *		 The uclass code sets this based on DT information.
+ * @master_node: OF node of the host Ethernet controller.
+ * @cpu_port_node: DT node of the switch's CPU port.
+ */
+struct dsa_pdata {
+	int num_ports;
+	u32 cpu_port;
+	ofnode master_node;
+	ofnode cpu_port_node;
+};
+
+/**
+ * dsa_set_tagging() - Configure the headroom and/or tailroom sizes
+ *
+ * The DSA class code allocates headroom and tailroom on Tx before
+ * calling the DSA driver's xmit function.
+ * All drivers must call this at probe time.
+ *
+ * @dev:	DSA device pointer
+ * @headroom:	Size, in bytes, of headroom needed for the DSA tag.
+ * @tailroom:	Size, in bytes, of tailroom needed for the DSA tag.
+ *		Total headroom and tailroom size should not exceed
+ *		DSA_MAX_OVR.
+ * @return 0 if OK, -ve on error
+ */
+int dsa_set_tagging(struct udevice *dev, ushort headroom, ushort tailroom);
+
+/* DSA helpers */
+
+/**
+ * dsa_get_master() - Return a reference to the master Ethernet device
+ *
+ * Can be called at driver probe time or later.
+ *
+ * @dev:	DSA device pointer
+ * @return Master Eth 'udevice' pointer if OK, NULL on error
+ */
+struct udevice *dsa_get_master(struct udevice *dev);
+
+/**
+ * dsa_port_get_pdata() - Helper that returns the platdata of an active
+ *			(non-CPU) DSA port device.
+ *
+ * Can be called at driver probe time or later.
+ *
+ * @pdev:	DSA port device pointer
+ * @return 'dsa_port_pdata' pointer if OK, NULL on error
+ */
+static inline struct dsa_port_pdata *
+	dsa_port_get_pdata(struct udevice *pdev)
+{
+	struct eth_pdata *eth = dev_get_plat(pdev);
+
+	if (!eth)
+		return NULL;
+
+	return eth->priv_pdata;
+}
+
+#endif /* __DSA_H__ */
diff --git a/include/palmas.h b/include/palmas.h
index 20c7e48..e259a4d 100644
--- a/include/palmas.h
+++ b/include/palmas.h
@@ -117,7 +117,7 @@
 #define BB_VSEL_VBAT		(3 << 1)
 #define BB_CHRG_EN		(1 << 0)
 
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 /*
  * Functions to read and write from TPS659038/TWL6035/TWL6037
  * or other Palmas family of TI PMICs
diff --git a/include/phy.h b/include/phy.h
index 7750efd..2754421 100644
--- a/include/phy.h
+++ b/include/phy.h
@@ -402,6 +402,27 @@
 struct phy_device *phy_find_by_mask(struct mii_dev *bus, unsigned phy_mask,
 		phy_interface_t interface);
 
+#ifdef CONFIG_PHY_FIXED
+
+/**
+ * fixed_phy_create() - create an unconnected fixed-link pseudo-PHY device
+ * @node: OF node for the container of the fixed-link node
+ *
+ * Description: Creates a struct phy_device based on a fixed-link of_node
+ * description. Can be used without phy_connect by drivers which do not expose
+ * a UCLASS_ETH udevice.
+ */
+struct phy_device *fixed_phy_create(ofnode node);
+
+#else
+
+static inline struct phy_device *fixed_phy_create(ofnode node)
+{
+	return NULL;
+}
+
+#endif
+
 #ifdef CONFIG_DM_ETH
 
 /**
diff --git a/include/phys2bus.h b/include/phys2bus.h
index dc9b8e5..866b8b5 100644
--- a/include/phys2bus.h
+++ b/include/phys2bus.h
@@ -21,4 +21,21 @@
 }
 #endif
 
+#if CONFIG_IS_ENABLED(DM)
+#include <dm/device.h>
+
+static inline dma_addr_t dev_phys_to_bus(struct udevice *dev, phys_addr_t phys)
+{
+	return phys - dev_get_dma_offset(dev);
+}
+
+static inline phys_addr_t dev_bus_to_phys(struct udevice *dev, dma_addr_t bus)
+{
+	return bus + dev_get_dma_offset(dev);
+}
+#else
+#define dev_phys_to_bus(_, _addr)	_addr
+#define dev_bus_to_phys(_, _addr)	_addr
+#endif
+
 #endif
diff --git a/include/spl.h b/include/spl.h
index e172500..0d13458 100644
--- a/include/spl.h
+++ b/include/spl.h
@@ -701,9 +701,9 @@
 
 /**
  * board_spl_fit_post_load - allow process images after loading finished
- *
+ * @fit: Pointer to a valid Flattened Image Tree blob
  */
-void board_spl_fit_post_load(ulong load_addr, size_t length);
+void board_spl_fit_post_load(const void *fit);
 
 /**
  * board_spl_fit_size_align - specific size align before processing payload
diff --git a/include/stdio_dev.h b/include/stdio_dev.h
index 48871a6..8fb9a12 100644
--- a/include/stdio_dev.h
+++ b/include/stdio_dev.h
@@ -18,6 +18,8 @@
 #define DEV_FLAGS_OUTPUT 0x00000002	/* Device can be used as output console */
 #define DEV_FLAGS_DM     0x00000004	/* Device priv is a struct udevice * */
 
+int stdio_file_to_flags(const int file);
+
 /* Device information */
 struct stdio_dev {
 	int	flags;			/* Device flags: input/output/system	*/
@@ -83,7 +85,6 @@
 int stdio_init(void);
 
 void stdio_print_current_devices(void);
-int stdio_deregister(const char *devname, int force);
 
 /**
  * stdio_deregister_dev() - deregister the device "devname".
diff --git a/include/tee/optee_ta_rpc_test.h b/include/tee/optee_ta_rpc_test.h
new file mode 100644
index 0000000..9491fba
--- /dev/null
+++ b/include/tee/optee_ta_rpc_test.h
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+/* Copyright (c) 2020 Foundries Ltd */
+
+#ifndef __TA_RPC_TEST_H
+#define __TA_RPC_TEST_H
+
+#define TA_RPC_TEST_UUID { 0x48420575, 0x96ca, 0x401a, \
+		      { 0x89, 0x91, 0x1e, 0xfd, 0xce, 0xbd, 0x7d, 0x04 } }
+
+/*
+ * Does a reverse RPC call for I2C read
+ *
+ * in		params[0].value.a:	bus number
+ * in		params[0].value.b:	chip address
+ * in		params[0].value.c:	control flags
+ * inout	params[1].u.memref:	buffer to read data
+ */
+#define TA_RPC_TEST_CMD_I2C_READ	0
+
+/*
+ * Does a reverse RPC call for I2C write
+ *
+ * in		params[0].value.a:	bus number
+ * in		params[0].value.b:	chip address
+ * in		params[0].value.c:	control flags
+ * inout	params[1].u.memref:	buffer with data to write
+ */
+#define TA_RPC_TEST_CMD_I2C_WRITE	1
+
+#endif /* __TA_RPC_TEST_H */
diff --git a/include/twl4030.h b/include/twl4030.h
index ef05193..0a6d85a 100644
--- a/include/twl4030.h
+++ b/include/twl4030.h
@@ -648,7 +648,7 @@
  *   examples are TWL4030_PM_RECEIVER_VMMC1_DEV_GRP and
  *   TWL4030_LED_LEDEN.
  */
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 static inline int twl4030_i2c_write_u8(u8 chip_no, u8 reg, u8 val)
 {
 	return i2c_write(chip_no, reg, 1, &val, 1);
diff --git a/include/twl6030.h b/include/twl6030.h
index 41f17de..05d476f 100644
--- a/include/twl6030.h
+++ b/include/twl6030.h
@@ -186,7 +186,7 @@
 };
 
 /* Functions to read and write from TWL6030 */
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
 static inline int twl6030_i2c_write_u8(u8 chip_no, u8 reg, u8 val)
 {
 	return i2c_write(chip_no, reg, 1, &val, 1);
diff --git a/include/usb/xhci.h b/include/usb/xhci.h
index e1d3823..8d95e21 100644
--- a/include/usb/xhci.h
+++ b/include/usb/xhci.h
@@ -16,6 +16,7 @@
 #ifndef HOST_XHCI_H_
 #define HOST_XHCI_H_
 
+#include <phys2bus.h>
 #include <reset.h>
 #include <asm/types.h>
 #include <asm/cache.h>
@@ -1221,6 +1222,12 @@
 #define XHCI_MTK_HOST		BIT(0)
 };
 
+#if CONFIG_IS_ENABLED(DM_USB)
+#define xhci_to_dev(_ctrl)	_ctrl->dev
+#else
+#define xhci_to_dev(_ctrl)	NULL
+#endif
+
 unsigned long trb_addr(struct xhci_segment *seg, union xhci_trb *trb);
 struct xhci_input_control_ctx
 		*xhci_get_input_control_ctx(struct xhci_container_ctx *ctx);
@@ -1250,7 +1257,8 @@
 void xhci_flush_cache(uintptr_t addr, u32 type_len);
 void xhci_inval_cache(uintptr_t addr, u32 type_len);
 void xhci_cleanup(struct xhci_ctrl *ctrl);
-struct xhci_ring *xhci_ring_alloc(unsigned int num_segs, bool link_trbs);
+struct xhci_ring *xhci_ring_alloc(struct xhci_ctrl *ctrl, unsigned int num_segs,
+				  bool link_trbs);
 int xhci_alloc_virt_device(struct xhci_ctrl *ctrl, unsigned int slot_id);
 int xhci_mem_init(struct xhci_ctrl *ctrl, struct xhci_hccr *hccr,
 		  struct xhci_hcor *hcor);
@@ -1278,4 +1286,14 @@
 
 struct xhci_ctrl *xhci_get_ctrl(struct usb_device *udev);
 
+static inline dma_addr_t xhci_virt_to_bus(struct xhci_ctrl *ctrl, void *addr)
+{
+	return dev_phys_to_bus(xhci_to_dev(ctrl), virt_to_phys(addr));
+}
+
+static inline void *xhci_bus_to_virt(struct xhci_ctrl *ctrl, dma_addr_t addr)
+{
+	return phys_to_virt(dev_bus_to_phys(xhci_to_dev(ctrl), addr));
+}
+
 #endif /* HOST_XHCI_H_ */
diff --git a/lib/efi_loader/efi_device_path_to_text.c b/lib/efi_loader/efi_device_path_to_text.c
index 1aaa9f9..81b8ac2 100644
--- a/lib/efi_loader/efi_device_path_to_text.c
+++ b/lib/efi_loader/efi_device_path_to_text.c
@@ -369,11 +369,18 @@
 
 	if (!device_path)
 		goto out;
-	while (device_path &&
-	       str + MAX_NODE_LEN < buffer + MAX_PATH_LEN) {
-		*str++ = '/';
-		str = efi_convert_single_device_node_to_text(str, device_path);
-		device_path = efi_dp_next(device_path);
+	while (device_path && str + MAX_NODE_LEN < buffer + MAX_PATH_LEN) {
+		if (device_path->type == DEVICE_PATH_TYPE_END) {
+			if (device_path->sub_type !=
+			    DEVICE_PATH_SUB_TYPE_INSTANCE_END)
+				break;
+			*str++ = ',';
+		} else {
+			*str++ = '/';
+			str = efi_convert_single_device_node_to_text(
+							str, device_path);
+		}
+		*(u8 **)&device_path += device_path->length;
 	}
 
 	text = efi_str_to_u16(buffer);
diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c
index 1f6b817..307d5d7 100644
--- a/lib/efi_loader/efi_disk.c
+++ b/lib/efi_loader/efi_disk.c
@@ -148,7 +148,7 @@
 	    (uintptr_t)buffer & (this->media->io_align - 1))
 		return EFI_INVALID_PARAMETER;
 	if (lba * this->media->block_size + buffer_size >
-	    this->media->last_block * this->media->block_size)
+	    (this->media->last_block + 1) * this->media->block_size)
 		return EFI_INVALID_PARAMETER;
 
 #ifdef CONFIG_EFI_LOADER_BOUNCE_BUFFER
@@ -216,7 +216,7 @@
 	    (uintptr_t)buffer & (this->media->io_align - 1))
 		return EFI_INVALID_PARAMETER;
 	if (lba * this->media->block_size + buffer_size >
-	    this->media->last_block * this->media->block_size)
+	    (this->media->last_block + 1) * this->media->block_size)
 		return EFI_INVALID_PARAMETER;
 
 #ifdef CONFIG_EFI_LOADER_BOUNCE_BUFFER
diff --git a/lib/efi_selftest/Makefile b/lib/efi_selftest/Makefile
index 7d6ea30..b02fd56 100644
--- a/lib/efi_selftest/Makefile
+++ b/lib/efi_selftest/Makefile
@@ -8,7 +8,7 @@
 asflags-y += -DHOST_ARCH="$(HOST_ARCH)"
 ccflags-y += -DHOST_ARCH="$(HOST_ARCH)"
 
-CFLAGS_dtbdump_exit.o := $(CFLAGS_EFI) -Os -ffreestanding
+CFLAGS_dtbdump.o := $(CFLAGS_EFI) -Os -ffreestanding
 CFLAGS_REMOVE_dtbdump.o := $(CFLAGS_NON_EFI)
 CFLAGS_efi_selftest_miniapp_exit.o := $(CFLAGS_EFI) -Os -ffreestanding
 CFLAGS_REMOVE_efi_selftest_miniapp_exit.o := $(CFLAGS_NON_EFI)
diff --git a/lib/efi_selftest/efi_selftest_devicepath.c b/lib/efi_selftest/efi_selftest_devicepath.c
index 4ce3fad..d87b9f7 100644
--- a/lib/efi_selftest/efi_selftest_devicepath.c
+++ b/lib/efi_selftest/efi_selftest_devicepath.c
@@ -45,6 +45,55 @@
 static u8 *dp2;
 static u8 *dp3;
 
+static struct {
+	struct efi_device_path_sd_mmc_path sd1;
+	struct efi_device_path sep1;
+	struct efi_device_path_sd_mmc_path sd2;
+	struct efi_device_path sep2;
+	struct efi_device_path_sd_mmc_path sd3;
+	struct efi_device_path end;
+} multi_part_dp = {
+	{
+		{
+			DEVICE_PATH_TYPE_MESSAGING_DEVICE,
+			DEVICE_PATH_SUB_TYPE_MSG_SD,
+			sizeof(struct efi_device_path_sd_mmc_path),
+		},
+		0,
+	},
+	{
+		DEVICE_PATH_TYPE_END,
+		DEVICE_PATH_SUB_TYPE_INSTANCE_END,
+		sizeof(struct efi_device_path),
+	},
+	{
+		{
+			DEVICE_PATH_TYPE_MESSAGING_DEVICE,
+			DEVICE_PATH_SUB_TYPE_MSG_SD,
+			sizeof(struct efi_device_path_sd_mmc_path),
+		},
+		1,
+	},
+	{
+		DEVICE_PATH_TYPE_END,
+		DEVICE_PATH_SUB_TYPE_INSTANCE_END,
+		sizeof(struct efi_device_path),
+	},
+	{
+		{
+			DEVICE_PATH_TYPE_MESSAGING_DEVICE,
+			DEVICE_PATH_SUB_TYPE_MSG_SD,
+			sizeof(struct efi_device_path_sd_mmc_path),
+		},
+		2,
+	},
+	{
+		DEVICE_PATH_TYPE_END,
+		DEVICE_PATH_SUB_TYPE_END,
+		sizeof(struct efi_device_path),
+	},
+};
+
 struct efi_device_path_to_text_protocol *device_path_to_text;
 
 /*
@@ -340,6 +389,22 @@
 		return EFI_ST_FAILURE;
 	}
 
+	string = device_path_to_text->convert_device_path_to_text(
+			(struct efi_device_path *)&multi_part_dp, true, false);
+	if (efi_st_strcmp_16_8(
+		string,
+		"/SD(0),/SD(1),/SD(2)")
+	    ) {
+		efi_st_printf("multi_part_dp: %ps\n", string);
+		efi_st_error("Incorrect text from ConvertDevicePathToText\n");
+		return EFI_ST_FAILURE;
+	}
+	ret = boottime->free_pool(string);
+	if (ret != EFI_SUCCESS) {
+		efi_st_error("FreePool failed\n");
+		return EFI_ST_FAILURE;
+	}
+
 	/* Test ConvertDeviceNodeToText */
 	string = device_path_to_text->convert_device_node_to_text(
 			(struct efi_device_path *)&dp_node, true, false);
diff --git a/net/Makefile b/net/Makefile
index 76527f7..fb3eba8 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -9,6 +9,7 @@
 obj-$(CONFIG_CMD_BOOTP) += bootp.o
 obj-$(CONFIG_CMD_CDP)  += cdp.o
 obj-$(CONFIG_CMD_DNS)  += dns.o
+obj-$(CONFIG_DM_DSA)   += dsa-uclass.o
 ifdef CONFIG_DM_ETH
 obj-$(CONFIG_NET)      += eth-uclass.o
 else
diff --git a/net/dsa-uclass.c b/net/dsa-uclass.c
new file mode 100644
index 0000000..2ce9ddb
--- /dev/null
+++ b/net/dsa-uclass.c
@@ -0,0 +1,478 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2019-2021 NXP
+ */
+
+#include <net/dsa.h>
+#include <dm/lists.h>
+#include <dm/device_compat.h>
+#include <dm/device-internal.h>
+#include <dm/uclass-internal.h>
+#include <linux/bitmap.h>
+#include <miiphy.h>
+
+#define DSA_PORT_CHILD_DRV_NAME "dsa-port"
+
+/* per-device internal state structure */
+struct dsa_priv {
+	struct phy_device *cpu_port_fixed_phy;
+	struct udevice *master_dev;
+	int num_ports;
+	u32 cpu_port;
+	int headroom;
+	int tailroom;
+};
+
+/* external API */
+int dsa_set_tagging(struct udevice *dev, ushort headroom, ushort tailroom)
+{
+	struct dsa_priv *priv;
+
+	if (!dev || !dev_get_uclass_priv(dev))
+		return -ENODEV;
+
+	if (headroom + tailroom > DSA_MAX_OVR)
+		return -EINVAL;
+
+	priv = dev_get_uclass_priv(dev);
+
+	if (headroom > 0)
+		priv->headroom = headroom;
+	if (tailroom > 0)
+		priv->tailroom = tailroom;
+
+	return 0;
+}
+
+/* returns the DSA master Ethernet device */
+struct udevice *dsa_get_master(struct udevice *dev)
+{
+	struct dsa_priv *priv = dev_get_uclass_priv(dev);
+
+	if (!priv)
+		return NULL;
+
+	return priv->master_dev;
+}
+
+/*
+ * Start the desired port, the CPU port and the master Eth interface.
+ * TODO: if cascaded we may need to _start ports in other switches too
+ */
+static int dsa_port_start(struct udevice *pdev)
+{
+	struct udevice *dev = dev_get_parent(pdev);
+	struct dsa_priv *priv = dev_get_uclass_priv(dev);
+	struct udevice *master = dsa_get_master(dev);
+	struct dsa_ops *ops = dsa_get_ops(dev);
+	int err;
+
+	if (!priv)
+		return -ENODEV;
+
+	if (!master) {
+		dev_err(pdev, "DSA master Ethernet device not found!\n");
+		return -EINVAL;
+	}
+
+	if (ops->port_enable) {
+		struct dsa_port_pdata *port_pdata;
+
+		port_pdata = dev_get_parent_plat(pdev);
+		err = ops->port_enable(dev, port_pdata->index,
+				       port_pdata->phy);
+		if (err)
+			return err;
+
+		err = ops->port_enable(dev, priv->cpu_port,
+				       priv->cpu_port_fixed_phy);
+		if (err)
+			return err;
+	}
+
+	return eth_get_ops(master)->start(master);
+}
+
+/* Stop the desired port, the CPU port and the master Eth interface */
+static void dsa_port_stop(struct udevice *pdev)
+{
+	struct udevice *dev = dev_get_parent(pdev);
+	struct dsa_priv *priv = dev_get_uclass_priv(dev);
+	struct udevice *master = dsa_get_master(dev);
+	struct dsa_ops *ops = dsa_get_ops(dev);
+
+	if (!priv)
+		return;
+
+	if (ops->port_disable) {
+		struct dsa_port_pdata *port_pdata;
+
+		port_pdata = dev_get_parent_plat(pdev);
+		ops->port_disable(dev, port_pdata->index, port_pdata->phy);
+		ops->port_disable(dev, priv->cpu_port, NULL);
+	}
+
+	/*
+	 * stop master only if it's active, don't probe it otherwise.
+	 * Under normal usage it would be active because we're using it, but
+	 * during tear-down it may have been removed ahead of us.
+	 */
+	if (master && device_active(master))
+		eth_get_ops(master)->stop(master);
+}
+
+/*
+ * Insert a DSA tag and call master Ethernet send on the resulting packet
+ * We copy the frame to a stack buffer where we have reserved headroom and
+ * tailroom space.  Headroom and tailroom are set to 0.
+ */
+static int dsa_port_send(struct udevice *pdev, void *packet, int length)
+{
+	struct udevice *dev = dev_get_parent(pdev);
+	struct dsa_priv *priv = dev_get_uclass_priv(dev);
+	int head = priv->headroom, tail = priv->tailroom;
+	struct udevice *master = dsa_get_master(dev);
+	struct dsa_ops *ops = dsa_get_ops(dev);
+	uchar dsa_packet_tmp[PKTSIZE_ALIGN];
+	struct dsa_port_pdata *port_pdata;
+	int err;
+
+	if (!master)
+		return -EINVAL;
+
+	if (length + head + tail > PKTSIZE_ALIGN)
+		return -EINVAL;
+
+	memset(dsa_packet_tmp, 0, head);
+	memset(dsa_packet_tmp + head + length, 0, tail);
+	memcpy(dsa_packet_tmp + head, packet, length);
+	length += head + tail;
+	/* copy back to preserve original buffer alignment */
+	memcpy(packet, dsa_packet_tmp, length);
+
+	port_pdata = dev_get_parent_plat(pdev);
+	err = ops->xmit(dev, port_pdata->index, packet, length);
+	if (err)
+		return err;
+
+	return eth_get_ops(master)->send(master, packet, length);
+}
+
+/* Receive a frame from master Ethernet, process it and pass it on */
+static int dsa_port_recv(struct udevice *pdev, int flags, uchar **packetp)
+{
+	struct udevice *dev = dev_get_parent(pdev);
+	struct dsa_priv *priv = dev_get_uclass_priv(dev);
+	int head = priv->headroom, tail = priv->tailroom;
+	struct udevice *master = dsa_get_master(dev);
+	struct dsa_ops *ops = dsa_get_ops(dev);
+	struct dsa_port_pdata *port_pdata;
+	int length, port_index, err;
+
+	if (!master)
+		return -EINVAL;
+
+	length = eth_get_ops(master)->recv(master, flags, packetp);
+	if (length <= 0)
+		return length;
+
+	/*
+	 * If we receive frames from a different port or frames that DSA driver
+	 * doesn't like we discard them here.
+	 * In case of discard we return with no frame and expect to be called
+	 * again instead of looping here, so upper layer can deal with timeouts.
+	 */
+	port_pdata = dev_get_parent_plat(pdev);
+	err = ops->rcv(dev, &port_index, *packetp, length);
+	if (err || port_index != port_pdata->index || (length <= head + tail)) {
+		if (eth_get_ops(master)->free_pkt)
+			eth_get_ops(master)->free_pkt(master, *packetp, length);
+		return -EAGAIN;
+	}
+
+	/*
+	 * We move the pointer over headroom here to avoid a copy.  If free_pkt
+	 * gets called we move the pointer back before calling master free_pkt.
+	 */
+	*packetp += head;
+
+	return length - head - tail;
+}
+
+static int dsa_port_free_pkt(struct udevice *pdev, uchar *packet, int length)
+{
+	struct udevice *dev = dev_get_parent(pdev);
+	struct udevice *master = dsa_get_master(dev);
+	struct dsa_priv *priv;
+
+	if (!master)
+		return -EINVAL;
+
+	priv = dev_get_uclass_priv(dev);
+	if (eth_get_ops(master)->free_pkt) {
+		/* return the original pointer and length to master Eth */
+		packet -= priv->headroom;
+		length += priv->headroom - priv->tailroom;
+
+		return eth_get_ops(master)->free_pkt(master, packet, length);
+	}
+
+	return 0;
+}
+
+static int dsa_port_of_to_pdata(struct udevice *pdev)
+{
+	struct dsa_port_pdata *port_pdata;
+	struct dsa_pdata *dsa_pdata;
+	struct eth_pdata *eth_pdata;
+	struct udevice *dev;
+	const char *label;
+	u32 index;
+	int err;
+
+	if (!pdev)
+		return -ENODEV;
+
+	err = ofnode_read_u32(dev_ofnode(pdev), "reg", &index);
+	if (err)
+		return err;
+
+	dev = dev_get_parent(pdev);
+	dsa_pdata = dev_get_uclass_plat(dev);
+
+	port_pdata = dev_get_parent_plat(pdev);
+	port_pdata->index = index;
+
+	label = ofnode_read_string(dev_ofnode(pdev), "label");
+	if (label)
+		strncpy(port_pdata->name, label, DSA_PORT_NAME_LENGTH);
+
+	eth_pdata = dev_get_plat(pdev);
+	eth_pdata->priv_pdata = port_pdata;
+
+	dev_dbg(pdev, "port %d node %s\n", port_pdata->index,
+		ofnode_get_name(dev_ofnode(pdev)));
+
+	return 0;
+}
+
+static const struct eth_ops dsa_port_ops = {
+	.start		= dsa_port_start,
+	.send		= dsa_port_send,
+	.recv		= dsa_port_recv,
+	.stop		= dsa_port_stop,
+	.free_pkt	= dsa_port_free_pkt,
+};
+
+static int dsa_port_probe(struct udevice *pdev)
+{
+	struct udevice *dev = dev_get_parent(pdev);
+	struct eth_pdata *eth_pdata, *master_pdata;
+	unsigned char env_enetaddr[ARP_HLEN];
+	struct dsa_port_pdata *port_pdata;
+	struct dsa_priv *dsa_priv;
+	struct udevice *master;
+
+	port_pdata = dev_get_parent_plat(pdev);
+	dsa_priv = dev_get_uclass_priv(dev);
+
+	port_pdata->phy = dm_eth_phy_connect(pdev);
+	if (!port_pdata->phy)
+		return -ENODEV;
+
+	/*
+	 * Inherit port's hwaddr from the DSA master, unless the port already
+	 * has a unique MAC address specified in the environment.
+	 */
+	eth_env_get_enetaddr_by_index("eth", dev_seq(pdev), env_enetaddr);
+	if (!is_zero_ethaddr(env_enetaddr))
+		return 0;
+
+	master = dsa_get_master(dev);
+	if (!master)
+		return 0;
+
+	master_pdata = dev_get_plat(master);
+	eth_pdata = dev_get_plat(pdev);
+	memcpy(eth_pdata->enetaddr, master_pdata->enetaddr, ARP_HLEN);
+	eth_env_set_enetaddr_by_index("eth", dev_seq(pdev),
+				      master_pdata->enetaddr);
+
+	return 0;
+}
+
+static int dsa_port_remove(struct udevice *pdev)
+{
+	struct udevice *dev = dev_get_parent(pdev);
+	struct dsa_port_pdata *port_pdata;
+	struct dsa_priv *dsa_priv;
+
+	port_pdata = dev_get_parent_plat(pdev);
+	dsa_priv = dev_get_uclass_priv(dev);
+
+	port_pdata->phy = NULL;
+
+	return 0;
+}
+
+U_BOOT_DRIVER(dsa_port) = {
+	.name	= DSA_PORT_CHILD_DRV_NAME,
+	.id	= UCLASS_ETH,
+	.ops	= &dsa_port_ops,
+	.probe	= dsa_port_probe,
+	.remove	= dsa_port_remove,
+	.of_to_plat = dsa_port_of_to_pdata,
+	.plat_auto = sizeof(struct eth_pdata),
+};
+
+/*
+ * This function mostly deals with pulling information out of the device tree
+ * into the pdata structure.
+ * It goes through the list of switch ports, registers an eth device for each
+ * front panel port and identifies the cpu port connected to master eth device.
+ * TODO: support cascaded switches
+ */
+static int dsa_post_bind(struct udevice *dev)
+{
+	struct dsa_pdata *pdata = dev_get_uclass_plat(dev);
+	ofnode node = dev_ofnode(dev), pnode;
+	int i, err, first_err = 0;
+
+	if (!pdata || !ofnode_valid(node))
+		return -ENODEV;
+
+	pdata->master_node = ofnode_null();
+
+	node = ofnode_find_subnode(node, "ports");
+	if (!ofnode_valid(node))
+		node = ofnode_find_subnode(node, "ethernet-ports");
+	if (!ofnode_valid(node)) {
+		dev_err(dev, "ports node is missing under DSA device!\n");
+		return -EINVAL;
+	}
+
+	pdata->num_ports = ofnode_get_child_count(node);
+	if (pdata->num_ports <= 0 || pdata->num_ports > DSA_MAX_PORTS) {
+		dev_err(dev, "invalid number of ports (%d)\n",
+			pdata->num_ports);
+		return -EINVAL;
+	}
+
+	/* look for the CPU port */
+	ofnode_for_each_subnode(pnode, node) {
+		u32 ethernet;
+
+		if (ofnode_read_u32(pnode, "ethernet", &ethernet))
+			continue;
+
+		pdata->master_node = ofnode_get_by_phandle(ethernet);
+		pdata->cpu_port_node = pnode;
+		break;
+	}
+
+	if (!ofnode_valid(pdata->master_node)) {
+		dev_err(dev, "master eth node missing!\n");
+		return -EINVAL;
+	}
+
+	if (ofnode_read_u32(pnode, "reg", &pdata->cpu_port)) {
+		dev_err(dev, "CPU port node not valid!\n");
+		return -EINVAL;
+	}
+
+	dev_dbg(dev, "master node %s on port %d\n",
+		ofnode_get_name(pdata->master_node), pdata->cpu_port);
+
+	for (i = 0; i < pdata->num_ports; i++) {
+		char name[DSA_PORT_NAME_LENGTH];
+		struct udevice *pdev;
+
+		/*
+		 * If this is the CPU port don't register it as an ETH device,
+		 * we skip it on purpose since I/O to/from it from the CPU
+		 * isn't useful.
+		 */
+		if (i == pdata->cpu_port)
+			continue;
+
+		/*
+		 * Set up default port names.  If present, DT port labels
+		 * will override the default port names.
+		 */
+		snprintf(name, DSA_PORT_NAME_LENGTH, "%s@%d", dev->name, i);
+
+		ofnode_for_each_subnode(pnode, node) {
+			u32 reg;
+
+			if (ofnode_read_u32(pnode, "reg", &reg))
+				continue;
+
+			if (reg == i)
+				break;
+		}
+
+		/*
+		 * skip registration if port id not found or if the port
+		 * is explicitly disabled in DT
+		 */
+		if (!ofnode_valid(pnode) || !ofnode_is_available(pnode))
+			continue;
+
+		err = device_bind_driver_to_node(dev, DSA_PORT_CHILD_DRV_NAME,
+						 name, pnode, &pdev);
+		if (pdev) {
+			struct dsa_port_pdata *port_pdata;
+
+			port_pdata = dev_get_parent_plat(pdev);
+			strncpy(port_pdata->name, name, DSA_PORT_NAME_LENGTH);
+			pdev->name = port_pdata->name;
+		}
+
+		/* try to bind all ports but keep 1st error */
+		if (err && !first_err)
+			first_err = err;
+	}
+
+	if (first_err)
+		return first_err;
+
+	dev_dbg(dev, "DSA ports successfully bound\n");
+
+	return 0;
+}
+
+/**
+ * Initialize the uclass per device internal state structure (priv).
+ * TODO: pick up references to other switch devices here, if we're cascaded.
+ */
+static int dsa_pre_probe(struct udevice *dev)
+{
+	struct dsa_pdata *pdata = dev_get_uclass_plat(dev);
+	struct dsa_priv *priv = dev_get_uclass_priv(dev);
+
+	if (!pdata || !priv)
+		return -ENODEV;
+
+	priv->num_ports = pdata->num_ports;
+	priv->cpu_port = pdata->cpu_port;
+	priv->cpu_port_fixed_phy = fixed_phy_create(pdata->cpu_port_node);
+	if (!priv->cpu_port_fixed_phy) {
+		dev_err(dev, "Failed to register fixed-link for CPU port\n");
+		return -ENODEV;
+	}
+
+	uclass_find_device_by_ofnode(UCLASS_ETH, pdata->master_node,
+				     &priv->master_dev);
+	return 0;
+}
+
+UCLASS_DRIVER(dsa) = {
+	.id = UCLASS_DSA,
+	.name = "dsa",
+	.post_bind = dsa_post_bind,
+	.pre_probe = dsa_pre_probe,
+	.per_device_auto = sizeof(struct dsa_priv),
+	.per_device_plat_auto = sizeof(struct dsa_pdata),
+	.per_child_plat_auto = sizeof(struct dsa_port_pdata),
+	.flags = DM_UC_FLAG_SEQ_ALIAS,
+};
diff --git a/net/mdio-uclass.c b/net/mdio-uclass.c
index 697e5f8..5da984c 100644
--- a/net/mdio-uclass.c
+++ b/net/mdio-uclass.c
@@ -139,6 +139,12 @@
 	struct ofnode_phandle_args phandle = {.node = ofnode_null()};
 	int i;
 
+	if (CONFIG_IS_ENABLED(PHY_FIXED) &&
+	    ofnode_valid(dev_read_subnode(ethdev, "fixed-link"))) {
+		phy = phy_connect(NULL, -1, ethdev, interface);
+		goto out;
+	}
+
 	for (i = 0; i < PHY_HANDLE_STR_CNT; i++)
 		if (!dev_read_phandle_with_args(ethdev, phy_handle_str[i], NULL,
 						0, 0, &phandle))
@@ -168,6 +174,7 @@
 
 	phy = dm_mdio_phy_connect(mdiodev, phy_addr, ethdev, interface);
 
+out:
 	if (phy)
 		phy->node = phandle.node;
 
diff --git a/net/tftp.c b/net/tftp.c
index d8cb121..00ab7ca 100644
--- a/net/tftp.c
+++ b/net/tftp.c
@@ -669,6 +669,12 @@
 			break;
 		}
 
+		if (len < tftp_block_size) {
+			tftp_send();
+			tftp_complete();
+			break;
+		}
+
 		/*
 		 *	Acknowledge the block just received, which will prompt
 		 *	the remote for the next one.
@@ -677,11 +683,6 @@
 			tftp_send();
 			tftp_next_ack += tftp_windowsize;
 		}
-
-		if (len < tftp_block_size) {
-			tftp_send();
-			tftp_complete();
-		}
 		break;
 
 	case TFTP_ERROR:
diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt
index c09d303..c8c8790 100644
--- a/scripts/config_whitelist.txt
+++ b/scripts/config_whitelist.txt
@@ -1172,7 +1172,6 @@
 CONFIG_ODROID_REV_AIN
 CONFIG_OFF_PADCONF
 CONFIG_OF_
-CONFIG_OF_STDOUT_PATH
 CONFIG_OMAP_EHCI_PHY1_RESET_GPIO
 CONFIG_OMAP_EHCI_PHY2_RESET_GPIO
 CONFIG_OMAP_EHCI_PHY3_RESET_GPIO
@@ -4005,8 +4004,6 @@
 CONFIG_VIDEO_FONT_4X6
 CONFIG_VIDEO_LCD_I2C_BUS
 CONFIG_VIDEO_LOGO
-CONFIG_VIDEO_MB862xx
-CONFIG_VIDEO_MB862xx_ACCEL
 CONFIG_VIDEO_MXS
 CONFIG_VIDEO_MXS_MODE_SYSTEM
 CONFIG_VIDEO_STD_TIMINGS
diff --git a/test/dm/Makefile b/test/dm/Makefile
index e70e50f..6275ec5 100644
--- a/test/dm/Makefile
+++ b/test/dm/Makefile
@@ -15,6 +15,8 @@
 obj-$(CONFIG_UT_DM) += test-uclass.o
 
 obj-$(CONFIG_UT_DM) += core.o
+obj-$(CONFIG_UT_DM) += read.o
+obj-$(CONFIG_UT_DM) += phys2bus.o
 ifneq ($(CONFIG_SANDBOX),)
 obj-$(CONFIG_ACPIGEN) += acpi.o
 obj-$(CONFIG_ACPIGEN) += acpigen.o
diff --git a/test/dm/core.c b/test/dm/core.c
index ce31d86..35ca689 100644
--- a/test/dm/core.c
+++ b/test/dm/core.c
@@ -1180,3 +1180,33 @@
 	return 0;
 }
 DM_TEST(dm_test_all_have_seq, UT_TESTF_SCAN_PDATA);
+
+static int dm_test_dma_offset(struct unit_test_state *uts)
+{
+       struct udevice *dev;
+       ofnode node;
+
+       /* Make sure the bus's dma-ranges aren't taken into account here */
+       node = ofnode_path("/mmio-bus@0");
+       ut_assert(ofnode_valid(node));
+       ut_assertok(uclass_get_device_by_ofnode(UCLASS_TEST_BUS, node, &dev));
+       ut_asserteq_64(0, dev->dma_offset);
+
+       /* Device behind a bus with dma-ranges */
+       node = ofnode_path("/mmio-bus@0/subnode@0");
+       ut_assert(ofnode_valid(node));
+       ut_assertok(uclass_get_device_by_ofnode(UCLASS_TEST_FDT, node, &dev));
+       ut_asserteq_64(-0x10000000ULL, dev->dma_offset);
+
+       /* This one has no dma-ranges */
+       node = ofnode_path("/mmio-bus@1");
+       ut_assert(ofnode_valid(node));
+       ut_assertok(uclass_get_device_by_ofnode(UCLASS_TEST_BUS, node, &dev));
+       node = ofnode_path("/mmio-bus@1/subnode@0");
+       ut_assert(ofnode_valid(node));
+       ut_assertok(uclass_get_device_by_ofnode(UCLASS_TEST_FDT, node, &dev));
+       ut_asserteq_64(0, dev->dma_offset);
+
+       return 0;
+}
+DM_TEST(dm_test_dma_offset, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
diff --git a/test/dm/phys2bus.c b/test/dm/phys2bus.c
new file mode 100644
index 0000000..342f2fa
--- /dev/null
+++ b/test/dm/phys2bus.c
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2020 Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <mapmem.h>
+#include <phys2bus.h>
+#include <dm/device.h>
+#include <dm/ofnode.h>
+#include <dm/root.h>
+#include <dm/test.h>
+#include <dm/uclass-internal.h>
+#include <test/ut.h>
+
+static int dm_test_phys_to_bus(struct unit_test_state *uts)
+{
+	struct udevice *dev;
+	ofnode node;
+
+	node = ofnode_path("/mmio-bus@0");
+	ut_assert(ofnode_valid(node));
+	ut_assertok(uclass_get_device_by_ofnode(UCLASS_TEST_BUS, node, &dev));
+	/* In this case it should be transparent, no dma-ranges in parent bus */
+	ut_asserteq_addr((void*)0xfffffULL, (void*)dev_phys_to_bus(dev, 0xfffff));
+	ut_asserteq_addr((void*)0xfffffULL, (void*)(ulong)dev_bus_to_phys(dev, 0xfffff));
+
+	node = ofnode_path("/mmio-bus@0/subnode@0");
+	ut_assert(ofnode_valid(node));
+	ut_assertok(uclass_get_device_by_ofnode(UCLASS_TEST_FDT, node, &dev));
+	ut_asserteq_addr((void*)0x100fffffULL, (void*)dev_phys_to_bus(dev, 0xfffff));
+	ut_asserteq_addr((void*)0xfffffULL, (void*)(ulong)dev_bus_to_phys(dev, 0x100fffff));
+
+	return 0;
+}
+DM_TEST(dm_test_phys_to_bus, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
diff --git a/test/dm/read.c b/test/dm/read.c
new file mode 100644
index 0000000..7768aa2
--- /dev/null
+++ b/test/dm/read.c
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2020 Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm/device.h>
+#include <dm/ofnode.h>
+#include <dm/root.h>
+#include <dm/test.h>
+#include <dm/uclass-internal.h>
+#include <test/ut.h>
+
+static int dm_test_dma_ranges(struct unit_test_state *uts)
+{
+	struct udevice *dev;
+	phys_addr_t cpu;
+	dma_addr_t bus;
+	ofnode node;
+	u64 size;
+
+	/* dma-ranges are on the device's node */
+	node = ofnode_path("/mmio-bus@0");
+	ut_assert(ofnode_valid(node));
+	ut_assertok(uclass_get_device_by_ofnode(UCLASS_TEST_BUS, node, &dev));
+	ut_assertok(dev_get_dma_range(dev, &cpu, &bus, &size));
+	ut_asserteq_64(0x40000, size);
+	ut_asserteq_64(0x0, cpu);
+	ut_asserteq_64(0x10000000, bus);
+
+	/* dma-ranges are on the bus' node */
+	node = ofnode_path("/mmio-bus@0/subnode@0");
+	ut_assert(ofnode_valid(node));
+	ut_assertok(uclass_get_device_by_ofnode(UCLASS_TEST_FDT, node, &dev));
+	ut_assertok(dev_get_dma_range(dev, &cpu, &bus, &size));
+	ut_asserteq_64(0x40000, size);
+	ut_asserteq_64(0x0, cpu);
+	ut_asserteq_64(0x10000000, bus);
+
+	/* No dma-ranges available */
+	node = ofnode_path("/mmio-bus@1");
+	ut_assert(ofnode_valid(node));
+	ut_assertok(uclass_get_device_by_ofnode(UCLASS_TEST_BUS, node, &dev));
+	ut_asserteq(-ENOENT, dev_get_dma_range(dev, &cpu, &bus, &size));
+
+	return 0;
+}
+DM_TEST(dm_test_dma_ranges, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
diff --git a/test/dm/tee.c b/test/dm/tee.c
index ddbdcfb..7a11bf8 100644
--- a/test/dm/tee.c
+++ b/test/dm/tee.c
@@ -13,15 +13,16 @@
 #include <test/test.h>
 #include <test/ut.h>
 #include <tee/optee_ta_avb.h>
+#include <tee/optee_ta_rpc_test.h>
 
-static int open_session(struct udevice *dev, u32 *session)
+static int open_session(struct udevice *dev, u32 *session,
+			struct tee_optee_ta_uuid *uuid)
 {
 	struct tee_open_session_arg arg;
-	const struct tee_optee_ta_uuid uuid = TA_AVB_UUID;
 	int rc;
 
 	memset(&arg, 0, sizeof(arg));
-	tee_optee_ta_uuid_to_octets(arg.uuid, &uuid);
+	tee_optee_ta_uuid_to_octets(arg.uuid, uuid);
 	rc = tee_open_session(dev, &arg, 0, NULL);
 	if (rc)
 		return rc;
@@ -32,7 +33,7 @@
 	return 0;
 }
 
-static int invoke_func(struct udevice *dev, u32 session)
+static int invoke_func_avb(struct udevice *dev, u32 session)
 {
 	struct tee_param param = { .attr = TEE_PARAM_ATTR_TYPE_VALUE_OUTPUT };
 	struct tee_invoke_arg arg;
@@ -47,6 +48,48 @@
 	return 0;
 }
 
+static int invoke_func_rpc_test(struct udevice *dev, u32 session,
+				u64 op, u64 busnum, u64 chip_addr,
+				u64 xfer_flags, u8 *buf, size_t buf_size)
+{
+	struct tee_param param[2];
+	struct tee_invoke_arg arg;
+	struct tee_shm *shm_buf;
+	int rc;
+
+	memset(&arg, 0, sizeof(arg));
+	arg.session = session;
+	arg.func = op;
+
+	rc = tee_shm_alloc(dev, buf_size,
+			   TEE_SHM_ALLOC, &shm_buf);
+	if (rc)
+		return rc;
+
+	if (op == TA_RPC_TEST_CMD_I2C_WRITE)
+		memcpy(shm_buf->addr, buf, buf_size);
+
+	memset(param, 0, sizeof(param));
+	param[0].attr = TEE_PARAM_ATTR_TYPE_VALUE_INPUT;
+	param[0].u.value.a = busnum;
+	param[0].u.value.b = chip_addr;
+	param[0].u.value.c = xfer_flags;
+	param[1].attr = TEE_PARAM_ATTR_TYPE_MEMREF_INOUT;
+	param[1].u.memref.shm = shm_buf;
+	param[1].u.memref.size = buf_size;
+
+	if (tee_invoke_func(dev, &arg, 2, param) || arg.ret) {
+		rc = -1;
+		goto out;
+	}
+
+	if (op == TA_RPC_TEST_CMD_I2C_READ)
+		memcpy(buf, shm_buf->addr, buf_size);
+out:
+	tee_shm_free(shm_buf);
+	return rc;
+}
+
 static int match(struct tee_version_data *vers, const void *data)
 {
 	return vers->gen_caps & TEE_GEN_CAP_GP;
@@ -62,6 +105,7 @@
 	struct tee_version_data vers;
 	struct udevice *dev;
 	struct sandbox_tee_state *state;
+	struct tee_optee_ta_uuid avb_uuid = TA_AVB_UUID;
 	u32 session = 0;
 	int rc;
 	u8 data[128];
@@ -71,11 +115,11 @@
 	state = dev_get_priv(dev);
 	ut_assert(!state->session);
 
-	rc = open_session(dev, &session);
+	rc = open_session(dev, &session, &avb_uuid);
 	ut_assert(!rc);
 	ut_assert(session == state->session);
 
-	rc = invoke_func(dev, session);
+	rc = invoke_func_avb(dev, session);
 	ut_assert(!rc);
 
 	rc = tee_close_session(dev, session);
@@ -100,14 +144,72 @@
 	vars->alloc_shm = NULL;
 	ut_assert(!state->num_shms);
 
-	return 0;
+	return rc;
 }
 
+#define I2C_BUF_SIZE 64
+
+static int test_tee_rpc(struct unit_test_state *uts)
+{
+	struct tee_version_data vers;
+	struct udevice *dev;
+	struct sandbox_tee_state *state;
+	struct tee_optee_ta_uuid rpc_test_uuid = TA_RPC_TEST_UUID;
+	u32 session = 0;
+	int rc;
+
+	char *test_str = "Test string";
+	u8 data[I2C_BUF_SIZE] = {0};
+	u8 data_from_eeprom[I2C_BUF_SIZE] = {0};
+
+	/* Use sandbox I2C EEPROM emulation; bus: 0, chip: 0x2c */
+	u64 bus = 0;
+	u64 chip = 0x2c;
+	u64 xfer_flags = 0;
+
+	dev = tee_find_device(NULL, match, NULL, &vers);
+	ut_assert(dev);
+	state = dev_get_priv(dev);
+	ut_assert(!state->session);
+
+	/* Test RPC call asking for I2C service */
+	rc = open_session(dev, &session, &rpc_test_uuid);
+	ut_assert(!rc);
+	ut_assert(session == state->session);
+
+	/* Write buffer */
+	strncpy((char *)data, test_str, strlen(test_str));
+	rc = invoke_func_rpc_test(dev, session, TA_RPC_TEST_CMD_I2C_WRITE,
+				  bus, chip, xfer_flags, data, sizeof(data));
+	ut_assert(!rc);
+
+	/* Read buffer */
+	rc = invoke_func_rpc_test(dev, session, TA_RPC_TEST_CMD_I2C_READ,
+				  bus, chip, xfer_flags, data_from_eeprom,
+				  sizeof(data_from_eeprom));
+	ut_assert(!rc);
+
+	/* Compare */
+	ut_assert(!memcmp(data, data_from_eeprom, sizeof(data)));
+
+	rc = tee_close_session(dev, session);
+	ut_assert(!rc);
+	ut_assert(!state->session);
+
+	return rc;
+}
+
 static int dm_test_tee(struct unit_test_state *uts)
 {
 	struct test_tee_vars vars = { NULL, NULL };
 	int rc = test_tee(uts, &vars);
 
+	if (rc)
+		goto out;
+
+	if (IS_ENABLED(CONFIG_OPTEE_TA_RPC_TEST))
+		rc = test_tee_rpc(uts);
+out:
 	/* In case test_tee() asserts these may still remain allocated */
 	tee_shm_free(vars.reg_shm);
 	tee_shm_free(vars.alloc_shm);
diff --git a/test/py/requirements.txt b/test/py/requirements.txt
index cf25118..926bcca 100644
--- a/test/py/requirements.txt
+++ b/test/py/requirements.txt
@@ -10,6 +10,8 @@
 pbr==5.4.3
 pluggy==0.13.0
 py==1.8.0
+pyelftools==0.27
+pygit2==1.4.0
 pyparsing==2.4.2
 pytest==5.2.1
 python-mimeparse==1.6.0