Merge https://gitlab.denx.de/u-boot/custodians/u-boot-fsl-qoriq

- Bug fixes and updates on vid, ls1088a lx2160a and other layerscape
  platforms.
- Add optee_rpmb support for LX2 & Kontron sl28 support
diff --git a/Kconfig b/Kconfig
index 520679f..c94b10e 100644
--- a/Kconfig
+++ b/Kconfig
@@ -196,11 +196,11 @@
 	hex "Size of malloc() pool before relocation"
 	depends on SYS_MALLOC_F
 	default 0x1000 if AM33XX
-	default 0x2800 if SANDBOX
+	default 0x4000 if SANDBOX
 	default 0x2000 if (ARCH_IMX8 || ARCH_IMX8M || ARCH_MX7 || \
 			   ARCH_MX7ULP || ARCH_MX6 || ARCH_MX5 || \
 			   ARCH_LS1012A || ARCH_LS1021A || ARCH_LS1043A || \
-			   ARCH_LS1046A || ARCH_QEMU)
+			   ARCH_LS1046A || ARCH_QEMU || ARCH_SUNXI)
 	default 0x400
 	help
 	  Before relocation, memory is very limited on many platforms. Still,
diff --git a/MAINTAINERS b/MAINTAINERS
index fc4fad4..d9f8032 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -678,6 +678,7 @@
 T:	git https://gitlab.denx.de/u-boot/custodians/u-boot-efi.git
 F:	doc/api/efi.rst
 F:	doc/uefi/*
+F:	drivers/rtc/emul_rtc.c
 F:	include/capitalization.h
 F:	include/charset.h
 F:	include/cp1250.h
@@ -938,6 +939,8 @@
 T:	git https://gitlab.denx.de/u-boot/custodians/u-boot-riscv.git
 F:	arch/riscv/
 F:	cmd/riscv/
+F:	drivers/timer/andes_plmt_timer.c
+F:	drivers/timer/sifive_clint_timer.c
 F:	tools/prelink-riscv.c
 
 RISC-V KENDRYTE
diff --git a/Makefile b/Makefile
index cb28cf6..5b80eb2 100644
--- a/Makefile
+++ b/Makefile
@@ -1,9 +1,9 @@
 # SPDX-License-Identifier: GPL-2.0+
 
-VERSION = 2020
-PATCHLEVEL = 10
+VERSION = 2021
+PATCHLEVEL = 01
 SUBLEVEL =
-EXTRAVERSION =
+EXTRAVERSION = -rc1
 NAME =
 
 # *DOCUMENTATION*
@@ -885,7 +885,7 @@
 	tools/relocate-rela $(3) $(4) $$start $$end
 else
 quiet_cmd_static_rela =
-cmd_static_rela =
+cmd_static_rela = true
 endif
 
 # Always append INPUTS so that arch config.mk's can add custom ones
@@ -1309,9 +1309,13 @@
 	fi
 endif
 
+shell_cmd = { $(echo-cmd) $(cmd_$(1)); }
+
+quiet_cmd_objcopy_uboot = OBJCOPY $@
+cmd_objcopy_uboot = $(cmd_objcopy) && $(call shell_cmd,static_rela,$<,$@,$(CONFIG_SYS_TEXT_BASE)) || rm -f $@
+
 u-boot-nodtb.bin: u-boot FORCE
-	$(call if_changed,objcopy)
-	$(call cmd,static_rela,$<,$@,$(CONFIG_SYS_TEXT_BASE))
+	$(call if_changed,objcopy_uboot)
 	$(BOARD_SIZE_CHECK)
 
 u-boot.ldr:	u-boot
@@ -1332,6 +1336,7 @@
 		-I arch/$(ARCH)/dts -a of-list=$(CONFIG_OF_LIST) \
 		-a atf-bl31-path=${BL31} \
 		-a default-dt=$(default_dt) \
+		-a scp-path=$(SCP) \
 		$(BINMAN_$(@F))
 
 OBJCOPYFLAGS_u-boot.ldr.hex := -I binary -O ihex
@@ -1441,11 +1446,13 @@
 MKIMAGEFLAGS_u-boot.itb = -E
 endif
 
+ifdef U_BOOT_ITS
 u-boot.itb: u-boot-nodtb.bin \
 		$(if $(CONFIG_OF_SEPARATE)$(CONFIG_OF_EMBED)$(CONFIG_OF_HOSTFILE),dts/dt.dtb) \
 		$(U_BOOT_ITS) FORCE
 	$(call if_changed,mkfitimage)
 	$(BOARD_SIZE_CHECK)
+endif
 
 u-boot-spl.kwb: u-boot.img spl/u-boot-spl.bin FORCE
 	$(call if_changed,mkimage)
@@ -1863,6 +1870,7 @@
 			LC_ALL=C $${DATE} -u -d "$${SOURCE_DATE}" +'#define U_BOOT_TZ "%z"'; \
 			LC_ALL=C $${DATE} -u -d "$${SOURCE_DATE}" +'#define U_BOOT_DMI_DATE "%m/%d/%Y"'; \
 			LC_ALL=C $${DATE} -u -d "$${SOURCE_DATE}" +'#define U_BOOT_BUILD_DATE 0x%Y%m%d'; \
+			LC_ALL=C $${DATE} -u -d "$${SOURCE_DATE}" +'#define U_BOOT_EPOCH %s'; \
 		else \
 			return 42; \
 		fi; \
@@ -1872,6 +1880,7 @@
 		LC_ALL=C date +'#define U_BOOT_TZ "%z"'; \
 		LC_ALL=C date +'#define U_BOOT_DMI_DATE "%m/%d/%Y"'; \
 		LC_ALL=C date +'#define U_BOOT_BUILD_DATE 0x%Y%m%d'; \
+		LC_ALL=C date +'#define U_BOOT_EPOCH %s'; \
 	fi)
 endef
 
diff --git a/arch/arm/dts/sunxi-u-boot.dtsi b/arch/arm/dts/sunxi-u-boot.dtsi
index c97943b..c77cf7c 100644
--- a/arch/arm/dts/sunxi-u-boot.dtsi
+++ b/arch/arm/dts/sunxi-u-boot.dtsi
@@ -1,5 +1,13 @@
 #include <config.h>
 
+#ifdef CONFIG_MACH_SUN50I_H6
+#define BL31_ADDR 0x104000
+#define  SCP_ADDR 0x114000
+#else
+#define BL31_ADDR  0x44000
+#define  SCP_ADDR  0x50000
+#endif
+
 / {
 	aliases {
 		mmc1 = &mmc2;
@@ -14,9 +22,11 @@
 	u-boot-sunxi-with-spl {
 		filename = "u-boot-sunxi-with-spl.bin";
 		pad-byte = <0xff>;
+
 		blob {
 			filename = "spl/sunxi-spl.bin";
 		};
+
 #ifdef CONFIG_ARM64
 		fit {
 			description = "Configuration to load ATF before U-Boot";
@@ -27,6 +37,7 @@
 				uboot {
 					description = "U-Boot (64-bit)";
 					type = "standalone";
+					os = "u-boot";
 					arch = "arm64";
 					compression = "none";
 					load = <0x4a000000>;
@@ -34,24 +45,35 @@
 					u-boot-nodtb {
 					};
 				};
+
 				atf {
 					description = "ARM Trusted Firmware";
 					type = "firmware";
+					os = "arm-trusted-firmware";
 					arch = "arm64";
 					compression = "none";
-/* TODO: Do this with an overwrite in this board's dtb? */
-#ifdef CONFIG_MACH_SUN50I_H6
-					load = <0x104000>;
-					entry = <0x104000>;
-#else
-					load = <0x44000>;
-					entry = <0x44000>;
-#endif
+					load = <BL31_ADDR>;
+					entry = <BL31_ADDR>;
+
 					atf-bl31 {
+						filename = "bl31.bin";
 						missing-msg = "atf-bl31-sunxi";
 					};
 				};
 
+				scp {
+					description = "SCP firmware";
+					type = "firmware";
+					arch = "or1k";
+					compression = "none";
+					load = <SCP_ADDR>;
+
+					scp {
+						filename = "scp.bin";
+						missing-msg = "scp-sunxi";
+					};
+				};
+
 				@fdt-SEQ {
 					description = "NAME";
 					type = "flat_dt";
@@ -61,10 +83,11 @@
 
 			configurations {
 				default = "config-1";
+
 				@config-SEQ {
 					description = "NAME";
-					firmware = "uboot";
-					loadables = "atf";
+					firmware = "atf";
+					loadables = "scp", "uboot";
 					fdt = "fdt-SEQ";
 				};
 			};
diff --git a/arch/arm/include/asm/arch-sunxi/cpu.h b/arch/arm/include/asm/arch-sunxi/cpu.h
index 4c399b0..8b57d24 100644
--- a/arch/arm/include/asm/arch-sunxi/cpu.h
+++ b/arch/arm/include/asm/arch-sunxi/cpu.h
@@ -16,6 +16,7 @@
 
 #define SOCID_A64	0x1689
 #define SOCID_H3	0x1680
+#define SOCID_V3S	0x1681
 #define SOCID_H5	0x1718
 #define SOCID_R40	0x1701
 
diff --git a/arch/arm/include/asm/xen/hypercall.h b/arch/arm/include/asm/xen/hypercall.h
index 121ccfc..a4fd077 100644
--- a/arch/arm/include/asm/xen/hypercall.h
+++ b/arch/arm/include/asm/xen/hypercall.h
@@ -19,10 +19,4 @@
 int HYPERVISOR_event_channel_op(int cmd, void *arg);
 unsigned long HYPERVISOR_hvm_op(int op, void *arg);
 int HYPERVISOR_memory_op(unsigned int cmd, void *arg);
-
-static inline void xen_debug_putc(int c)
-{
-	register int v __asm__ ("x0") = c;
-	__asm__ __volatile__("hvc 0xfffe" : "=r" (v) : "0" (v));
-}
 #endif /* _ASM_ARM_XEN_HYPERCALL_H */
diff --git a/arch/arm/mach-sunxi/dram_sunxi_dw.c b/arch/arm/mach-sunxi/dram_sunxi_dw.c
index a462538..d060001 100644
--- a/arch/arm/mach-sunxi/dram_sunxi_dw.c
+++ b/arch/arm/mach-sunxi/dram_sunxi_dw.c
@@ -63,6 +63,8 @@
 	MBUS_PORT_CSI           = 5,
 	MBUS_PORT_NAND          = 6,
 	MBUS_PORT_SS            = 7,
+	MBUS_PORT_DE_V3S        = 8,
+	MBUS_PORT_DE_CFD_V3S    = 9,
 	MBUS_PORT_TS            = 8,
 	MBUS_PORT_DI            = 9,
 	MBUS_PORT_DE            = 10,
@@ -134,6 +136,29 @@
 	MBUS_CONF(DE_CFD,  true,    HIGH, 0, 1024,  288,   64);
 }
 
+static void mctl_set_master_priority_v3s(void)
+{
+	struct sunxi_mctl_com_reg * const mctl_com =
+			(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
+
+	/* enable bandwidth limit windows and set windows size 1us */
+	writel((1 << 16) | (400 << 0), &mctl_com->bwcr);
+
+	/* set cpu high priority */
+	writel(0x00000001, &mctl_com->mapr);
+
+	MBUS_CONF(       CPU,  true, HIGHEST, 0,  160,  100,   80);
+	MBUS_CONF(       GPU,  true,    HIGH, 0, 1792, 1536,    0);
+	MBUS_CONF(    UNUSED,  true, HIGHEST, 0,  256,  128,   80);
+	MBUS_CONF(       DMA,  true,    HIGH, 0,  256,  100,    0);
+	MBUS_CONF(        VE,  true,    HIGH, 0, 2048, 1600,    0);
+	MBUS_CONF(       CSI,  true, HIGHEST, 0,  384,  256,    0);
+	MBUS_CONF(      NAND,  true,    HIGH, 0,  100,   50,    0);
+	MBUS_CONF(        SS,  true,    HIGH, 0,  384,  256,    0);
+	MBUS_CONF(    DE_V3S, false,    HIGH, 0, 8192, 4096,    0);
+	MBUS_CONF(DE_CFD_V3S,  true,    HIGH, 0,  640,  256,    0);
+}
+
 static void mctl_set_master_priority_a64(void)
 {
 	struct sunxi_mctl_com_reg * const mctl_com =
@@ -231,6 +256,9 @@
 	case SOCID_H3:
 		mctl_set_master_priority_h3();
 		return;
+	case SOCID_V3S:
+		mctl_set_master_priority_v3s();
+		return;
 	case SOCID_A64:
 		mctl_set_master_priority_a64();
 		return;
@@ -334,6 +362,28 @@
 	}
 }
 
+static void mctl_v3s_zq_calibration_quirk(struct dram_para *para)
+{
+	struct sunxi_mctl_ctl_reg * const mctl_ctl =
+			(struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
+
+	u32 reg_val;
+
+	clrsetbits_le32(&mctl_ctl->zqcr, 0xffffff,
+			CONFIG_DRAM_ZQ & 0xffffff);
+	mctl_phy_init(PIR_ZCAL);
+
+	reg_val = readl(&mctl_ctl->zqdr[0]);
+	reg_val &= (0x1f << 16) | (0x1f << 0);
+	reg_val |= reg_val << 8;
+	writel(reg_val, &mctl_ctl->zqdr[0]);
+
+	reg_val = readl(&mctl_ctl->zqdr[1]);
+	reg_val &= (0x1f << 16) | (0x1f << 0);
+	reg_val |= reg_val << 8;
+	writel(reg_val, &mctl_ctl->zqdr[1]);
+}
+
 static void mctl_set_cr(uint16_t socid, struct dram_para *para)
 {
 	struct sunxi_mctl_com_reg * const mctl_com =
@@ -391,7 +441,7 @@
 				CCM_DRAMCLK_CFG_DIV(1) |
 				CCM_DRAMCLK_CFG_SRC_PLL11 |
 				CCM_DRAMCLK_CFG_UPD);
-	} else if (socid == SOCID_H3 || socid == SOCID_H5) {
+	} else if (socid == SOCID_H3 || socid == SOCID_H5 || socid == SOCID_V3S) {
 		clock_set_pll5(CONFIG_DRAM_CLK * 2 * 1000000, false);
 		clrsetbits_le32(&ccm->dram_clk_cfg,
 				CCM_DRAMCLK_CFG_DIV_MASK |
@@ -474,6 +524,13 @@
 		/* dphy & aphy phase select 270 degree */
 		clrsetbits_le32(&mctl_ctl->pgcr[2], (0x3 << 10) | (0x3 << 8),
 				(0x1 << 10) | (0x2 << 8));
+	} else if (socid == SOCID_V3S) {
+		/* dx ddr_clk & hdr_clk dynamic mode */
+		clrbits_le32(&mctl_ctl->pgcr[0], (0x3 << 14) | (0x3 << 12));
+
+		/* dphy & aphy phase select 270 degree */
+		clrsetbits_le32(&mctl_ctl->pgcr[2], (0x3 << 10) | (0x3 << 8),
+				(0x1 << 10) | (0x1 << 8));
 	} else if (socid == SOCID_A64 || socid == SOCID_H5) {
 		/* dphy & aphy phase select ? */
 		clrsetbits_le32(&mctl_ctl->pgcr[2], (0x3 << 10) | (0x3 << 8),
@@ -506,7 +563,12 @@
 	mctl_set_bit_delays(para);
 	udelay(50);
 
-	if (socid == SOCID_H3) {
+	if (socid == SOCID_V3S) {
+		mctl_v3s_zq_calibration_quirk(para);
+
+		mctl_phy_init(PIR_PLLINIT | PIR_DCAL | PIR_PHYRST |
+			      PIR_DRAMRST | PIR_DRAMINIT | PIR_QSGATE);
+	} else if (socid == SOCID_H3) {
 		mctl_h3_zq_calibration_quirk(para);
 
 		mctl_phy_init(PIR_PLLINIT | PIR_DCAL | PIR_PHYRST |
@@ -570,7 +632,7 @@
 	udelay(10);
 
 	/* set PGCR3, CKE polarity */
-	if (socid == SOCID_H3)
+	if (socid == SOCID_H3 || socid == SOCID_V3S)
 		writel(0x00aa0060, &mctl_ctl->pgcr[3]);
 	else if (socid == SOCID_A64 || socid == SOCID_H5 || socid == SOCID_R40)
 		writel(0xc0aa0060, &mctl_ctl->pgcr[3]);
@@ -636,6 +698,22 @@
 	   0,  0,  0,  0,  0,  0,  0,  0,			\
 	   0,  0,  0,  0,  0,  0,  0      }
 
+#define SUN8I_V3S_DX_READ_DELAYS					\
+	{{  8,  8,  8,  8,  8,  8,  8,  8,  8,  0,  0 },	\
+	 {  7,  7,  7,  7,  7,  7,  7,  7,  7,  0,  0 },	\
+	 {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 },	\
+	 {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 }}
+#define SUN8I_V3S_DX_WRITE_DELAYS				\
+	{{  0,  0,  0,  0,  0,  0,  0,  0,  0,  4,  4 },	\
+	 {  0,  0,  0,  0,  0,  0,  0,  0,  0,  2,  2 },	\
+	 {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 },	\
+	 {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 }}
+#define SUN8I_V3S_AC_DELAYS					\
+	{  0,  0,  0,  0,  0,  0,  0,  0,			\
+	   0,  0,  0,  0,  0,  0,  0,  0,			\
+	   0,  0,  0,  0,  0,  0,  0,  0,			\
+	   0,  0,  0,  0,  0,  0,  0      }
+
 #define SUN8I_R40_DX_READ_DELAYS				\
 	{{ 14, 14, 14, 14, 14, 14, 14, 14, 14,  0,  0 },	\
 	 { 14, 14, 14, 14, 14, 14, 14, 14, 14,  0,  0 },	\
@@ -702,6 +780,10 @@
 		.dx_read_delays  = SUN8I_H3_DX_READ_DELAYS,
 		.dx_write_delays = SUN8I_H3_DX_WRITE_DELAYS,
 		.ac_delays	 = SUN8I_H3_AC_DELAYS,
+#elif defined(CONFIG_MACH_SUN8I_V3S)
+		.dx_read_delays  = SUN8I_V3S_DX_READ_DELAYS,
+		.dx_write_delays = SUN8I_V3S_DX_WRITE_DELAYS,
+		.ac_delays	 = SUN8I_V3S_AC_DELAYS,
 #elif defined(CONFIG_MACH_SUN8I_R40)
 		.dx_read_delays  = SUN8I_R40_DX_READ_DELAYS,
 		.dx_write_delays = SUN8I_R40_DX_WRITE_DELAYS,
@@ -728,8 +810,7 @@
 	/* Currently we cannot support R40 with dual rank memory */
 	para.dual_rank = 0;
 #elif defined(CONFIG_MACH_SUN8I_V3S)
-	/* TODO: set delays and mbus priority for V3s */
-	uint16_t socid = SOCID_H3;
+	uint16_t socid = SOCID_V3S;
 #elif defined(CONFIG_MACH_SUN50I)
 	uint16_t socid = SOCID_A64;
 #elif defined(CONFIG_MACH_SUN50I_H5)
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index aaa3b83..30b0540 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -170,13 +170,6 @@
 	  The Andes PLIC block holds memory-mapped claim and pending registers
 	  associated with software interrupt.
 
-config ANDES_PLMT
-	bool
-	depends on RISCV_MMODE || SPL_RISCV_MMODE
-	help
-	  The Andes PLMT block holds memory-mapped mtime register
-	  associated with timer tick.
-
 config SYS_MALLOC_F_LEN
 	default 0x1000
 
@@ -272,6 +265,6 @@
 	default 14
 
 config OF_BOARD_FIXUP
-	default y if OF_SEPARATE
+	default y if OF_SEPARATE && RISCV_SMODE
 
 endmenu
diff --git a/arch/riscv/cpu/ax25/Kconfig b/arch/riscv/cpu/ax25/Kconfig
index 5cb5bb5..327b74e 100644
--- a/arch/riscv/cpu/ax25/Kconfig
+++ b/arch/riscv/cpu/ax25/Kconfig
@@ -5,7 +5,7 @@
 	imply CPU_RISCV
 	imply RISCV_TIMER if (RISCV_SMODE || SPL_RISCV_SMODE)
 	imply ANDES_PLIC if (RISCV_MMODE || SPL_RISCV_MMODE)
-	imply ANDES_PLMT if (RISCV_MMODE || SPL_RISCV_MMODE)
+	imply ANDES_PLMT_TIMER if (RISCV_MMODE || SPL_RISCV_MMODE)
 	imply SPL_CPU_SUPPORT
 	imply SPL_OPENSBI
 	imply SPL_LOAD_FIT
diff --git a/arch/riscv/dts/fu540-c000-u-boot.dtsi b/arch/riscv/dts/fu540-c000-u-boot.dtsi
index a06e1b1..b7cd600 100644
--- a/arch/riscv/dts/fu540-c000-u-boot.dtsi
+++ b/arch/riscv/dts/fu540-c000-u-boot.dtsi
@@ -62,7 +62,7 @@
 					       &cpu2_intc 3 &cpu2_intc 7
 					       &cpu3_intc 3 &cpu3_intc 7
 					       &cpu4_intc 3 &cpu4_intc 7>;
-			reg = <0x0 0x2000000 0x0 0xc0000>;
+			reg = <0x0 0x2000000 0x0 0x10000>;
 			u-boot,dm-spl;
 		};
 		prci: clock-controller@10000000 {
diff --git a/arch/riscv/dts/k210.dtsi b/arch/riscv/dts/k210.dtsi
index 7605c01..81ef8ca 100644
--- a/arch/riscv/dts/k210.dtsi
+++ b/arch/riscv/dts/k210.dtsi
@@ -200,8 +200,8 @@
 			dma-channels = <6>;
 			snps,dma-masters = <2>;
 			snps,data-width = <5>;
-			snps,block-size = <0x400000 0x400000 0x400000
-					   0x400000 0x400000 0x400000>;
+			snps,block-size = <0x200000 0x200000 0x200000
+					   0x200000 0x200000 0x200000>;
 			snps,axi-max-burst-len = <256>;
 			status = "disabled";
 		};
diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
index 10ac5b0..12c14f2 100644
--- a/arch/riscv/lib/Makefile
+++ b/arch/riscv/lib/Makefile
@@ -13,7 +13,6 @@
 ifeq ($(CONFIG_$(SPL_)RISCV_MMODE),y)
 obj-$(CONFIG_SIFIVE_CLINT) += sifive_clint.o
 obj-$(CONFIG_ANDES_PLIC) += andes_plic.o
-obj-$(CONFIG_ANDES_PLMT) += andes_plmt.o
 else
 obj-$(CONFIG_SBI) += sbi.o
 obj-$(CONFIG_SBI_IPI) += sbi_ipi.o
diff --git a/arch/riscv/lib/sifive_clint.c b/arch/riscv/lib/sifive_clint.c
index a5572cb..c8079dc 100644
--- a/arch/riscv/lib/sifive_clint.c
+++ b/arch/riscv/lib/sifive_clint.c
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
+ * Copyright (C) 2020, Sean Anderson <seanga2@gmail.com>
  * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
  *
  * U-Boot syscon driver for SiFive's Core Local Interruptor (CLINT).
@@ -8,19 +9,13 @@
  */
 
 #include <common.h>
-#include <clk.h>
 #include <dm.h>
-#include <timer.h>
 #include <asm/io.h>
-#include <asm/syscon.h>
+#include <asm/smp.h>
 #include <linux/err.h>
 
 /* MSIP registers */
 #define MSIP_REG(base, hart)		((ulong)(base) + (hart) * 4)
-/* mtime compare register */
-#define MTIMECMP_REG(base, hart)	((ulong)(base) + 0x4000 + (hart) * 8)
-/* mtime register */
-#define MTIME_REG(base)			((ulong)(base) + 0xbff8)
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -61,35 +56,3 @@
 
 	return 0;
 }
-
-static u64 sifive_clint_get_count(struct udevice *dev)
-{
-	return readq((void __iomem *)MTIME_REG(dev->priv));
-}
-
-static const struct timer_ops sifive_clint_ops = {
-	.get_count = sifive_clint_get_count,
-};
-
-static int sifive_clint_probe(struct udevice *dev)
-{
-	dev->priv = dev_read_addr_ptr(dev);
-	if (!dev->priv)
-		return -EINVAL;
-
-	return timer_timebase_fallback(dev);
-}
-
-static const struct udevice_id sifive_clint_ids[] = {
-	{ .compatible = "riscv,clint0" },
-	{ }
-};
-
-U_BOOT_DRIVER(sifive_clint) = {
-	.name		= "sifive_clint",
-	.id		= UCLASS_TIMER,
-	.of_match	= sifive_clint_ids,
-	.probe		= sifive_clint_probe,
-	.ops		= &sifive_clint_ops,
-	.flags		= DM_FLAG_PRE_RELOC,
-};
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index fa84b2c..70ccb49 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -3,6 +3,7 @@
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/gpio/sandbox-gpio.h>
 #include <dt-bindings/pinctrl/sandbox-pinmux.h>
+#include <dt-bindings/mux/mux.h>
 
 / {
 	model = "sandbox";
@@ -133,6 +134,12 @@
 		interrupts-extended = <&irq 3 0>;
 		acpi,name = "GHIJ";
 		phandle-value = <&gpio_c 10>, <0xFFFFFFFF 20>, <&gpio_a 30>;
+
+		mux-controls = <&muxcontroller0 0>, <&muxcontroller0 1>,
+			       <&muxcontroller0 2>, <&muxcontroller0 3>,
+			       <&muxcontroller1>;
+		mux-control-names = "mux0", "mux1", "mux2", "mux3", "mux4";
+		mux-syscon = <&syscon3>;
 	};
 
 	junk {
@@ -170,6 +177,9 @@
 		compatible = "denx,u-boot-fdt-test";
 		ping-expect = <3>;
 		ping-add = <3>;
+
+		mux-controls = <&muxcontroller0 0>;
+		mux-control-names = "mux0";
 	};
 
 	phy_provider0: gen_phy@0 {
@@ -884,6 +894,29 @@
 			0x58 8>;
 	};
 
+	syscon3: syscon@3 {
+		compatible = "simple-mfd", "syscon";
+		reg = <0x000100 0x10>;
+
+		muxcontroller0: a-mux-controller {
+			compatible = "mmio-mux";
+			#mux-control-cells = <1>;
+
+			mux-reg-masks = <0x0 0x30>, /* 0: reg 0x0, bits 5:4 */
+					<0xc 0x1E>, /* 1: reg 0xc, bits 4:1 */
+					<0x4 0xFF>; /* 2: reg 0x4, bits 7:0 */
+			idle-states = <MUX_IDLE_AS_IS>, <0x02>, <0x73>;
+			u-boot,mux-autoprobe;
+		};
+	};
+
+	muxcontroller1: emul-mux-controller {
+		compatible = "mux-emul";
+		#mux-control-cells = <0>;
+		u-boot,mux-autoprobe;
+		idle-state = <0xabcd>;
+	};
+
 	timer@0 {
 		compatible = "sandbox,timer";
 		clock-frequency = <1000000>;
diff --git a/board/BuS/eb_cpu5282/eb_cpu5282.c b/board/BuS/eb_cpu5282/eb_cpu5282.c
index 1d05e40..f5e4de3 100644
--- a/board/BuS/eb_cpu5282/eb_cpu5282.c
+++ b/board/BuS/eb_cpu5282/eb_cpu5282.c
@@ -20,7 +20,7 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-#ifdef CONFIG_VIDEO
+#if IS_ENABLED(CONFIG_VIDEO_VCXK)
 unsigned long display_width;
 unsigned long display_height;
 #endif
@@ -183,8 +183,7 @@
 		MCFGPTA_GPTPORT &= ~(1 << 3);
 }
 
-#if defined(CONFIG_VIDEO)
-
+#if IS_ENABLED(CONFIG_VIDEO_VCXK)
 int drv_video_init(void)
 {
 	char *s;
@@ -225,7 +224,7 @@
 
 /*---------------------------------------------------------------------------*/
 
-#ifdef CONFIG_VIDEO
+#if IS_ENABLED(CONFIG_VIDEO_VCXK)
 int do_brightness(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
 {
 	int rcode = 0;
diff --git a/board/samsung/common/board.c b/board/samsung/common/board.c
index 752d84e..470531f 100644
--- a/board/samsung/common/board.c
+++ b/board/samsung/common/board.c
@@ -304,7 +304,6 @@
 	int mmcbootdev = get_boot_mmc_dev();
 	char mmcbootdev_str[16];
 
-	stdio_print_current_devices();
 	ret = uclass_first_device_err(UCLASS_CROS_EC, &dev);
 	if (ret && ret != -ENODEV) {
 		/* Force console on */
diff --git a/board/sunxi/README.sunxi64 b/board/sunxi/README.sunxi64
index 258921a..4803bc9 100644
--- a/board/sunxi/README.sunxi64
+++ b/board/sunxi/README.sunxi64
@@ -14,8 +14,12 @@
 - Build the ARM Trusted Firmware binary (see "ARM Trusted Firmware (ATF)" below)
   $ cd /src/arm-trusted-firmware
   $ make PLAT=sun50i_a64 DEBUG=1 bl31
+- Build the SCP firmware binary (see "SCP firmware (Crust)" below)
+  $ cd /src/crust
+  $ make pine64_plus_defconfig && make -j5 scp
 - Build U-Boot (see "SPL/U-Boot" below)
   $ export BL31=/path/to/bl31.bin
+  $ export SCP=/src/crust/build/scp/scp.bin
   $ make pine64_plus_defconfig && make -j5
 - Transfer to an uSD card (see "microSD card" below)
   $ dd if=u-boot-sunxi-with-spl.bin of=/dev/sdx bs=8k seek=1
@@ -24,13 +28,17 @@
 Building the firmware
 =====================
 
-The Allwinner A64/H5 firmware consists of three parts: U-Boot's SPL, an
-ARM Trusted Firmware (ATF) build and the U-Boot proper.
-The SPL will load both ATF and U-Boot proper along with the right device
-tree blob (.dtb) and will pass execution to ATF (in EL3), which in turn will
-drop into the U-Boot proper (in EL2).
-As the ATF binary will become part of the U-Boot image file, you will need
-to build it first.
+The Allwinner A64/H5/H6 firmware consists of several parts: U-Boot's SPL,
+ARM Trusted Firmware (ATF), optional System Control Processor (SCP) firmware
+(e.g. Crust), and the U-Boot proper.
+
+The SPL will load all of the other firmware binaries into RAM, along with the
+right device tree blob (.dtb), and will pass execution to ATF (in EL3). If SCP
+firmware was loaded, ATF will power on the SCP and wait for it to boot.
+ATF will then drop into U-Boot proper (in EL2).
+
+As the ATF binary and SCP firmware will become part of the U-Boot image file,
+you will need to build them first.
 
  ARM Trusted Firmware (ATF)
 ----------------------------
@@ -53,6 +61,31 @@
 or if you can't be bothered with building ATF, there are known working
 binaries in the firmware repository[3], purely for convenience reasons.
 
+ SCP firmware (Crust)
+----------------------
+SCP firmware is responsible for implementing system suspend/resume, and (on
+boards without a PMIC) soft poweroff/on. ATF contains fallback code for CPU
+power control, so SCP firmware is optional if you don't need either of these
+features. It runs on the AR100, with is an or1k CPU, not ARM, so it needs a
+different cross toolchain.
+
+There is one SCP firmware implementation currently available, Crust:
+$ git clone https://github.com/crust-firmware/crust
+$ cd crust
+$ export CROSS_COMPILE=or1k-linux-musl-
+$ make pine64_plus_defconfig
+$ make scp
+
+The same configuration generally works on any board with the same SoC (A64, H5,
+or H6), so if there is no config for your board, use one for a similar board.
+
+Like for ATF, U-Boot finds the SCP firmware binary via an environment variable:
+$ export SCP=/src/crust/build/scp/scp.bin
+
+If you do not want to use SCP firmware, you can silence the warning from binman
+by pointing it to an empty file:
+$ export SCP=/dev/null
+
  SPL/U-Boot
 ------------
 Both U-Boot proper and the SPL are using the 64-bit mode. As the boot ROM
diff --git a/cmd/Kconfig b/cmd/Kconfig
index 860c00f..9f36290 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -1025,6 +1025,14 @@
 	  Print list of available block device drivers, and for each, the list
 	  of known block devices.
 
+config CMD_MISC
+	bool "misc"
+	depends on MISC
+	help
+	  Enable the command "misc" for accessing miscellaneous devices with
+	  a MISC uclass driver. The command provides listing all MISC devices
+	  as well as read and write functionalities via their drivers.
+
 config CMD_MMC
 	bool "mmc"
 	help
@@ -1081,6 +1089,12 @@
 	help
 	  MTD commands support.
 
+config CMD_MUX
+	bool "mux"
+	depends on MULTIPLEXER
+	help
+	 List, select, and deselect mux controllers on the fly.
+
 config CMD_NAND
 	bool "nand"
 	default y if NAND_SUNXI
@@ -1716,8 +1730,7 @@
 	help
 	  Print bytes from the hardware random number generator.
 
-# TODO: rename to CMD_SLEEP
-config CMD_MISC
+config CMD_SLEEP
 	bool "sleep"
 	default y
 	help
diff --git a/cmd/Makefile b/cmd/Makefile
index a1eee43..dd86675 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -94,8 +94,9 @@
 obj-$(CONFIG_CMD_IO) += io.o
 obj-$(CONFIG_CMD_MFSL) += mfsl.o
 obj-$(CONFIG_CMD_MII) += mii.o
-obj-$(CONFIG_CMD_MDIO) += mdio.o
 obj-$(CONFIG_CMD_MISC) += misc.o
+obj-$(CONFIG_CMD_MDIO) += mdio.o
+obj-$(CONFIG_CMD_SLEEP) += sleep.o
 obj-$(CONFIG_CMD_MMC) += mmc.o
 obj-$(CONFIG_CMD_OPTEE_RPMB) += optee_rpmb.o
 obj-$(CONFIG_MP) += mp.o
@@ -105,6 +106,7 @@
 ifneq ($(CONFIG_CMD_NAND)$(CONFIG_CMD_SF),)
 obj-y += legacy-mtd-utils.o
 endif
+obj-$(CONFIG_CMD_MUX) += mux.o
 obj-$(CONFIG_CMD_NAND) += nand.o
 obj-$(CONFIG_CMD_NET) += net.o
 obj-$(CONFIG_CMD_NVEDIT_EFI) += nvedit_efi.o
@@ -142,6 +144,7 @@
 obj-$(CONFIG_CMD_SYSBOOT) += sysboot.o pxe_utils.o
 obj-$(CONFIG_CMD_TERMINAL) += terminal.o
 obj-$(CONFIG_CMD_TIME) += time.o
+obj-$(CONFIG_CMD_TIMER) += timer.o
 obj-$(CONFIG_CMD_TRACE) += trace.o
 obj-$(CONFIG_HUSH_PARSER) += test.o
 obj-$(CONFIG_CMD_TPM) += tpm-common.o
diff --git a/cmd/fat.c b/cmd/fat.c
index b438ce1..69ce1fa 100644
--- a/cmd/fat.c
+++ b/cmd/fat.c
@@ -98,48 +98,7 @@
 static int do_fat_fswrite(struct cmd_tbl *cmdtp, int flag, int argc,
 			  char *const argv[])
 {
-	loff_t size;
-	int ret;
-	unsigned long addr;
-	unsigned long count;
-	long offset;
-	struct blk_desc *dev_desc = NULL;
-	struct disk_partition info;
-	int dev = 0;
-	int part = 1;
-	void *buf;
-
-	if (argc < 5)
-		return cmd_usage(cmdtp);
-
-	part = blk_get_device_part_str(argv[1], argv[2], &dev_desc, &info, 1);
-	if (part < 0)
-		return 1;
-
-	dev = dev_desc->devnum;
-
-	if (fat_set_blk_dev(dev_desc, &info) != 0) {
-		printf("\n** Unable to use %s %d:%d for fatwrite **\n",
-			argv[1], dev, part);
-		return 1;
-	}
-	addr = simple_strtoul(argv[3], NULL, 16);
-	count = (argc <= 5) ? 0 : simple_strtoul(argv[5], NULL, 16);
-	/* offset should be a hex, but "-1" is allowed */
-	offset = (argc <= 6) ? 0 : simple_strtol(argv[6], NULL, 16);
-
-	buf = map_sysmem(addr, count);
-	ret = file_fat_write(argv[4], buf, offset, count, &size);
-	unmap_sysmem(buf);
-	if (ret < 0) {
-		printf("\n** Unable to write \"%s\" from %s %d:%d **\n",
-			argv[4], argv[1], dev, part);
-		return 1;
-	}
-
-	printf("%llu bytes written\n", size);
-
-	return 0;
+	return do_save(cmdtp, flag, argc, argv, FS_TYPE_FAT);
 }
 
 U_BOOT_CMD(
diff --git a/cmd/misc.c b/cmd/misc.c
index 20ab943..653deed 100644
--- a/cmd/misc.c
+++ b/cmd/misc.c
@@ -1,88 +1,134 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- * (C) Copyright 2001
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ * Copyright (c) 2020 Wind River Systems, Inc.
+ *
+ * Author:
+ *   Bin Meng <bin.meng@windriver.com>
+ *
+ * A command interface to access misc devices with MISC uclass driver APIs.
  */
 
-/*
- * Misc functions
- */
 #include <common.h>
 #include <command.h>
-#include <console.h>
-#include <linux/delay.h>
+#include <dm.h>
+#include <errno.h>
+#include <misc.h>
 
-static int do_sleep(struct cmd_tbl *cmdtp, int flag, int argc,
-		    char *const argv[])
+enum misc_op {
+	MISC_OP_READ,
+	MISC_OP_WRITE
+};
+
+static char *misc_op_str[] = {
+	"read",
+	"write"
+};
+
+static int do_misc_list(struct cmd_tbl *cmdtp, int flag,
+			int argc, char *const argv[])
 {
-	ulong start = get_timer(0);
-	ulong mdelay = 0;
-	ulong delay;
-	char *frpart;
+	struct udevice *dev;
 
-	if (argc != 2)
-		return CMD_RET_USAGE;
+	printf("Device               Index     Driver\n");
+	printf("-------------------------------------\n");
+	for (uclass_first_device(UCLASS_MISC, &dev);
+	     dev;
+	     uclass_next_device(&dev)) {
+		printf("%-20s %5d %10s\n", dev->name, dev->seq,
+		       dev->driver->name);
+	}
 
-	delay = simple_strtoul(argv[1], NULL, 10) * CONFIG_SYS_HZ;
+	return 0;
+}
 
-	frpart = strchr(argv[1], '.');
+static int do_misc_op(struct cmd_tbl *cmdtp, int flag,
+		      int argc, char *const argv[], enum misc_op op)
+{
+	int (*misc_op)(struct udevice *, int, void *, int);
+	struct udevice *dev;
+	int offset;
+	void *buf;
+	int size;
+	int ret;
 
-	if (frpart) {
-		uint mult = CONFIG_SYS_HZ / 10;
-		for (frpart++; *frpart != '\0' && mult > 0; frpart++) {
-			if (*frpart < '0' || *frpart > '9') {
-				mdelay = 0;
-				break;
-			}
-			mdelay += (*frpart - '0') * mult;
-			mult /= 10;
+	ret = uclass_get_device_by_name(UCLASS_MISC, argv[0], &dev);
+	if (ret) {
+		printf("Unable to find device %s\n", argv[0]);
+		return ret;
+	}
+
+	offset = simple_strtoul(argv[1], NULL, 16);
+	buf = (void *)simple_strtoul(argv[2], NULL, 16);
+	size = simple_strtoul(argv[3], NULL, 16);
+
+	if (op == MISC_OP_READ)
+		misc_op = misc_read;
+	else
+		misc_op = misc_write;
+
+	ret = misc_op(dev, offset, buf, size);
+	if (ret < 0) {
+		if (ret == -ENOSYS) {
+			printf("The device does not support %s\n",
+			       misc_op_str[op]);
+			ret = 0;
 		}
+	} else {
+		if (ret == size)
+			ret = 0;
+		else
+			printf("Partially %s %d bytes\n", misc_op_str[op], ret);
 	}
 
-	delay += mdelay;
-
-	while (get_timer(start) < delay) {
-		if (ctrlc())
-			return (-1);
-
-		udelay(100);
-	}
-
-	return 0;
+	return ret;
 }
 
-U_BOOT_CMD(
-	sleep ,    2,    1,     do_sleep,
-	"delay execution for some time",
-	"N\n"
-	"    - delay execution for N seconds (N is _decimal_ and can be\n"
-	"      fractional)"
-);
-
-#ifdef CONFIG_CMD_TIMER
-static int do_timer(struct cmd_tbl *cmdtp, int flag, int argc,
-		    char *const argv[])
+static int do_misc_read(struct cmd_tbl *cmdtp, int flag,
+			int argc, char *const argv[])
 {
-	static ulong start;
+	return do_misc_op(cmdtp, flag, argc, argv, MISC_OP_READ);
+}
 
-	if (argc != 2)
+static int do_misc_write(struct cmd_tbl *cmdtp, int flag,
+			 int argc, char *const argv[])
+{
+	return do_misc_op(cmdtp, flag, argc, argv, MISC_OP_WRITE);
+}
+
+static struct cmd_tbl misc_commands[] = {
+	U_BOOT_CMD_MKENT(list, 0, 1, do_misc_list, "", ""),
+	U_BOOT_CMD_MKENT(read, 4, 1, do_misc_read, "", ""),
+	U_BOOT_CMD_MKENT(write, 4, 1, do_misc_write, "", ""),
+};
+
+static int do_misc(struct cmd_tbl *cmdtp, int flag,
+		   int argc, char *const argv[])
+{
+	struct cmd_tbl *misc_cmd;
+	int ret;
+
+	if (argc < 2)
+		return CMD_RET_USAGE;
+	misc_cmd = find_cmd_tbl(argv[1], misc_commands,
+				ARRAY_SIZE(misc_commands));
+	argc -= 2;
+	argv += 2;
+	if (!misc_cmd || argc != misc_cmd->maxargs)
 		return CMD_RET_USAGE;
 
-	if (!strcmp(argv[1], "start"))
-		start = get_timer(0);
+	ret = misc_cmd->cmd(misc_cmd, flag, argc, argv);
 
-	if (!strcmp(argv[1], "get")) {
-		ulong msecs = get_timer(start) * 1000 / CONFIG_SYS_HZ;
-		printf("%ld.%03d\n", msecs / 1000, (int)(msecs % 1000));
-	}
-
-	return 0;
+	return cmd_process_error(misc_cmd, ret);
 }
 
 U_BOOT_CMD(
-	timer,    2,    1,     do_timer,
-	"access the system timer",
-	"start - Reset the timer reference.\n"
-	"timer get   - Print the time since 'start'."
+	misc,	6,	1,	do_misc,
+	"Access miscellaneous devices with MISC uclass driver APIs",
+	"list                       - list all miscellaneous devices\n"
+	"misc read  name offset addr len - read `len' bytes starting at\n"
+	"				  `offset' of device `name'\n"
+	"				  to memory at `addr'\n"
+	"misc write name offset addr len - write `len' bytes starting at\n"
+	"				  `offset' of device `name'\n"
+	"				  from memory at `addr'"
 );
-#endif
diff --git a/cmd/mux.c b/cmd/mux.c
new file mode 100644
index 0000000..833266f
--- /dev/null
+++ b/cmd/mux.c
@@ -0,0 +1,184 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * List, select, and deselect mux controllers on the fly.
+ *
+ * Copyright (c) 2020 Texas Instruments Inc.
+ * Author: Pratyush Yadav <p.yadav@ti.com>
+ */
+
+#include <common.h>
+#include <command.h>
+#include <errno.h>
+#include <dm.h>
+#include <dm/device_compat.h>
+#include <mux.h>
+#include <mux-internal.h>
+#include <linux/err.h>
+#include <dt-bindings/mux/mux.h>
+
+#define COLUMN_SIZE 16
+
+/*
+ * Print a member of a column. The total size of the text printed, including
+ * trailing whitespace, will always be COLUMN_SIZE.
+ */
+#define PRINT_COLUMN(fmt, args...) do {					\
+	char buf[COLUMN_SIZE + 1];					\
+	snprintf(buf, COLUMN_SIZE + 1, fmt, ##args);			\
+	printf("%-*s", COLUMN_SIZE, buf);				\
+} while (0)
+
+/*
+ * Find a mux based on its device name in argv[1] and index in the chip in
+ * argv[2].
+ */
+static struct mux_control *cmd_mux_find(char *const argv[])
+{
+	struct udevice *dev;
+	struct mux_chip *chip;
+	int ret;
+	unsigned long id;
+
+	ret = strict_strtoul(argv[2], 10, &id);
+	if (ret)
+		return ERR_PTR(ret);
+
+	ret = uclass_get_device_by_name(UCLASS_MUX, argv[1], &dev);
+	if (ret)
+		return ERR_PTR(ret);
+
+	chip = dev_get_uclass_priv(dev);
+	if (!chip)
+		return ERR_PTR(ret);
+
+	if (id >= chip->controllers)
+		return ERR_PTR(-EINVAL);
+
+	return &chip->mux[id];
+}
+
+/*
+ * Print the details of a mux. The columns printed correspond to: "Selected",
+ * "Current State", "Idle State", and "Num States".
+ */
+static void print_mux(struct mux_control *mux)
+{
+	PRINT_COLUMN("%s", mux->in_use ? "yes" : "no");
+
+	if (mux->cached_state == MUX_IDLE_AS_IS)
+		PRINT_COLUMN("%s", "unknown");
+	else
+		PRINT_COLUMN("0x%x", mux->cached_state);
+
+	if (mux->idle_state == MUX_IDLE_AS_IS)
+		PRINT_COLUMN("%s", "as-is");
+	else if (mux->idle_state == MUX_IDLE_DISCONNECT)
+		PRINT_COLUMN("%s", "disconnect");
+	else
+		PRINT_COLUMN("0x%x", mux->idle_state);
+
+	PRINT_COLUMN("0x%x", mux->states);
+
+	printf("\n");
+}
+
+static int do_mux_list(struct cmd_tbl *cmdtp, int flag, int argc,
+		       char *const argv[])
+{
+	struct udevice *dev;
+	struct mux_chip *chip;
+	int j;
+
+	for (uclass_first_device(UCLASS_MUX, &dev);
+	     dev;
+	     uclass_next_device(&dev)) {
+		chip = dev_get_uclass_priv(dev);
+		if (!chip) {
+			dev_err(dev, "can't find mux chip\n");
+			continue;
+		}
+
+		printf("%s:\n", dev->name);
+
+		printf("    ");
+		PRINT_COLUMN("ID");
+		PRINT_COLUMN("Selected");
+		PRINT_COLUMN("Current State");
+		PRINT_COLUMN("Idle State");
+		PRINT_COLUMN("Num States");
+		printf("\n");
+		for (j = 0; j < chip->controllers; j++) {
+			printf("    ");
+			PRINT_COLUMN("%d", j);
+			print_mux(&chip->mux[j]);
+		}
+		printf("\n");
+	}
+
+	return 0;
+}
+
+static int do_mux_select(struct cmd_tbl *cmdtp, int flag, int argc,
+			 char *const argv[])
+{
+	struct mux_control *mux;
+	int ret;
+	unsigned long state;
+
+	if (argc != 4)
+		return CMD_RET_USAGE;
+
+	mux = cmd_mux_find(argv);
+	if (IS_ERR_OR_NULL(mux)) {
+		printf("Failed to find the specified mux\n");
+		return CMD_RET_FAILURE;
+	}
+
+	ret = strict_strtoul(argv[3], 16, &state);
+	if (ret) {
+		printf("Invalid state\n");
+		return CMD_RET_FAILURE;
+	}
+
+	ret = mux_control_select(mux, state);
+	if (ret) {
+		printf("Failed to select requested state\n");
+		return CMD_RET_FAILURE;
+	}
+
+	return CMD_RET_SUCCESS;
+}
+
+static int do_mux_deselect(struct cmd_tbl *cmdtp, int flag, int argc,
+			   char *const argv[])
+{
+	struct mux_control *mux;
+	int ret;
+
+	if (argc != 3)
+		return CMD_RET_USAGE;
+
+	mux = cmd_mux_find(argv);
+	if (IS_ERR_OR_NULL(mux)) {
+		printf("Failed to find the specified mux\n");
+		return CMD_RET_FAILURE;
+	}
+
+	ret = mux_control_deselect(mux);
+	if (ret) {
+		printf("Failed to deselect mux\n");
+		return CMD_RET_FAILURE;
+	}
+
+	return CMD_RET_SUCCESS;
+}
+
+static char mux_help_text[] =
+	"list - List all Muxes and their states\n"
+	"select <chip> <id> <state> - Select the given mux state\n"
+	"deselect <chip> <id> - Deselect the given mux and reset it to its idle state";
+
+U_BOOT_CMD_WITH_SUBCMDS(mux, "List, select, and deselect muxes", mux_help_text,
+			U_BOOT_SUBCMD_MKENT(list, 1, 1, do_mux_list),
+			U_BOOT_SUBCMD_MKENT(select, 4, 0, do_mux_select),
+			U_BOOT_SUBCMD_MKENT(deselect, 3, 0, do_mux_deselect));
diff --git a/cmd/sleep.c b/cmd/sleep.c
new file mode 100644
index 0000000..f0c78a8
--- /dev/null
+++ b/cmd/sleep.c
@@ -0,0 +1,57 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2001
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ */
+
+#include <common.h>
+#include <command.h>
+#include <console.h>
+#include <linux/delay.h>
+
+static int do_sleep(struct cmd_tbl *cmdtp, int flag, int argc,
+		    char *const argv[])
+{
+	ulong start = get_timer(0);
+	ulong mdelay = 0;
+	ulong delay;
+	char *frpart;
+
+	if (argc != 2)
+		return CMD_RET_USAGE;
+
+	delay = simple_strtoul(argv[1], NULL, 10) * CONFIG_SYS_HZ;
+
+	frpart = strchr(argv[1], '.');
+
+	if (frpart) {
+		uint mult = CONFIG_SYS_HZ / 10;
+		for (frpart++; *frpart != '\0' && mult > 0; frpart++) {
+			if (*frpart < '0' || *frpart > '9') {
+				mdelay = 0;
+				break;
+			}
+			mdelay += (*frpart - '0') * mult;
+			mult /= 10;
+		}
+	}
+
+	delay += mdelay;
+
+	while (get_timer(start) < delay) {
+		if (ctrlc())
+			return (-1);
+
+		udelay(100);
+	}
+
+	return 0;
+}
+
+U_BOOT_CMD(
+	sleep ,    2,    1,     do_sleep,
+	"delay execution for some time",
+	"N\n"
+	"    - delay execution for N seconds (N is _decimal_ and can be\n"
+	"      fractional)"
+);
diff --git a/cmd/timer.c b/cmd/timer.c
new file mode 100644
index 0000000..551be5d
--- /dev/null
+++ b/cmd/timer.c
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2001
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ */
+
+#include <common.h>
+#include <command.h>
+
+static int do_timer(struct cmd_tbl *cmdtp, int flag, int argc,
+		    char *const argv[])
+{
+	static ulong start;
+
+	if (argc != 2)
+		return CMD_RET_USAGE;
+
+	if (!strcmp(argv[1], "start"))
+		start = get_timer(0);
+
+	if (!strcmp(argv[1], "get")) {
+		ulong msecs = get_timer(start) * 1000 / CONFIG_SYS_HZ;
+		printf("%ld.%03d\n", msecs / 1000, (int)(msecs % 1000));
+	}
+
+	return 0;
+}
+
+U_BOOT_CMD(
+	timer,    2,    1,     do_timer,
+	"access the system timer",
+	"start - Reset the timer reference.\n"
+	"timer get   - Print the time since 'start'."
+);
diff --git a/common/board_r.c b/common/board_r.c
index 9b2fec7..b9217b2 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -46,6 +46,7 @@
 #include <miiphy.h>
 #endif
 #include <mmc.h>
+#include <mux.h>
 #include <nand.h>
 #include <of_live.h>
 #include <onenand_uboot.h>
@@ -341,6 +342,17 @@
 			return ret;
 	}
 
+	if (IS_ENABLED(CONFIG_MULTIPLEXER)) {
+		/*
+		 * Initialize the multiplexer controls to their default state.
+		 * This must be done early as other drivers may unknowingly
+		 * rely on it.
+		 */
+		ret = dm_mux_init();
+		if (ret)
+			return ret;
+	}
+
 	return 0;
 }
 
diff --git a/common/bootm.c b/common/bootm.c
index b337749..167eea4 100644
--- a/common/bootm.c
+++ b/common/bootm.c
@@ -256,9 +256,11 @@
 
 	/* check if ramdisk overlaps OS image */
 	if (images.rd_start && (((ulong)images.rd_start >= start &&
-				 (ulong)images.rd_start <= start + size) ||
-				((ulong)images.rd_end >= start &&
-				 (ulong)images.rd_end <= start + size))) {
+				 (ulong)images.rd_start < start + size) ||
+				((ulong)images.rd_end > start &&
+				 (ulong)images.rd_end <= start + size) ||
+				((ulong)images.rd_start < start &&
+				 (ulong)images.rd_end >= start + size))) {
 		printf("ERROR: RD image overlaps OS image (OS=0x%lx..0x%lx)\n",
 		       start, start + size);
 		return 1;
diff --git a/common/log.c b/common/log.c
index b7a6ebe..9f98e9a 100644
--- a/common/log.c
+++ b/common/log.c
@@ -13,7 +13,7 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-static const char *log_cat_name[LOGC_COUNT - LOGC_NONE] = {
+static const char *log_cat_name[] = {
 	"none",
 	"arch",
 	"board",
@@ -28,7 +28,10 @@
 	"acpi",
 };
 
-static const char *log_level_name[LOGL_COUNT] = {
+_Static_assert(ARRAY_SIZE(log_cat_name) == LOGC_COUNT - LOGC_NONE,
+	       "log_cat_name size");
+
+static const char *log_level_name[] = {
 	"EMERG",
 	"ALERT",
 	"CRIT",
@@ -41,6 +44,9 @@
 	"IO",
 };
 
+_Static_assert(ARRAY_SIZE(log_level_name) == LOGL_COUNT, "log_level_name size");
+
+/* All error responses MUST begin with '<' */
 const char *log_get_cat_name(enum log_category_t cat)
 {
 	const char *name;
@@ -191,32 +197,33 @@
  * log_dispatch() - Send a log record to all log devices for processing
  *
  * The log record is sent to each log device in turn, skipping those which have
- * filters which block the record
+ * filters which block the record.
  *
- * @rec: Log record to dispatch
- * @return 0 (meaning success)
+ * All log messages created while processing log record @rec are ignored.
+ *
+ * @rec:	log record to dispatch
+ * Return:	0 msg sent, 1 msg not sent while already dispatching another msg
  */
 static int log_dispatch(struct log_rec *rec)
 {
 	struct log_device *ldev;
-	static int processing_msg;
 
 	/*
 	 * When a log driver writes messages (e.g. via the network stack) this
 	 * may result in further generated messages. We cannot process them here
 	 * as this might result in infinite recursion.
 	 */
-	if (processing_msg)
-		return 0;
+	if (gd->processing_msg)
+		return 1;
 
 	/* Emit message */
-	processing_msg = 1;
+	gd->processing_msg = true;
 	list_for_each_entry(ldev, &gd->log_head, sibling_node) {
 		if ((ldev->flags & LOGDF_ENABLE) &&
 		    log_passes_filters(ldev, rec))
 			ldev->drv->emit(ldev, rec);
 	}
-	processing_msg = 0;
+	gd->processing_msg = false;
 	return 0;
 }
 
@@ -227,6 +234,12 @@
 	struct log_rec rec;
 	va_list args;
 
+	/* Check for message continuation */
+	if (cat == LOGC_CONT)
+		cat = gd->logc_prev;
+	if (level == LOGL_CONT)
+		level = gd->logl_prev;
+
 	rec.cat = cat;
 	rec.level = level & LOGL_LEVEL_MASK;
 	rec.force_debug = level & LOGL_FORCE_DEBUG;
@@ -242,7 +255,10 @@
 			gd->log_drop_count++;
 		return -ENOSYS;
 	}
-	log_dispatch(&rec);
+	if (!log_dispatch(&rec)) {
+		gd->logc_prev = cat;
+		gd->logl_prev = level;
+	}
 
 	return 0;
 }
@@ -382,6 +398,8 @@
 	if (!gd->default_log_level)
 		gd->default_log_level = CONFIG_LOG_DEFAULT_LEVEL;
 	gd->log_fmt = log_get_default_format();
+	gd->logc_prev = LOGC_NONE;
+	gd->logl_prev = LOGL_INFO;
 
 	return 0;
 }
diff --git a/common/spl/Kconfig b/common/spl/Kconfig
index af47f5c..d8086bd 100644
--- a/common/spl/Kconfig
+++ b/common/spl/Kconfig
@@ -465,9 +465,7 @@
 	  Enable this to reduce the size of the FIT image loading code
 	  in SPL, if space for the SPL binary is very tight.
 
-	  This removes the detection of image types (which forces the
-	  first image to be treated as having a U-Boot style calling
-	  convention) and skips the recording of each loaded payload
+	  This skips the recording of each loaded payload
 	  (i.e. loadable) into the FDT (modifying the loaded FDT to
 	  ensure this information is available to the next image
 	  invoked).
diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c
index a90d821..fd6086a 100644
--- a/common/spl/spl_fit.c
+++ b/common/spl/spl_fit.c
@@ -466,7 +466,22 @@
 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)
-	return -ENOTSUPP;
+	const char *name = fdt_getprop(fit, noffset, FIT_OS_PROP, NULL);
+
+	if (!name)
+		return -ENOENT;
+
+	/*
+	 * We don't care what the type of the image actually is,
+	 * only whether or not it is U-Boot. This saves some
+	 * space by omitting the large table of OS types.
+	 */
+	if (!strcmp(name, "u-boot"))
+		*os = IH_OS_U_BOOT;
+	else
+		*os = IH_OS_INVALID;
+
+	return 0;
 #else
 	return fit_image_get_os(fit, noffset, os);
 #endif
diff --git a/common/stdio.c b/common/stdio.c
index 84c36a7..a15f308 100644
--- a/common/stdio.c
+++ b/common/stdio.c
@@ -356,7 +356,9 @@
 	} else {
 		if (IS_ENABLED(CONFIG_LCD))
 			drv_lcd_init();
-		if (IS_ENABLED(CONFIG_VIDEO) || IS_ENABLED(CONFIG_CFB_CONSOLE))
+		if (IS_ENABLED(CONFIG_VIDEO) ||
+		    IS_ENABLED(CONFIG_CFB_CONSOLE) ||
+		    IS_ENABLED(CONFIG_VIDEO_VCXK))
 			drv_video_init();
 	}
 
diff --git a/configs/A20-OLinuXino-Lime2-eMMC_defconfig b/configs/A20-OLinuXino-Lime2-eMMC_defconfig
index b1a38d7..f9f8f14 100644
--- a/configs/A20-OLinuXino-Lime2-eMMC_defconfig
+++ b/configs/A20-OLinuXino-Lime2-eMMC_defconfig
@@ -19,6 +19,8 @@
 CONFIG_SCSI_AHCI=y
 CONFIG_DFU_RAM=y
 CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
+CONFIG_PHY_MICREL=y
+CONFIG_PHY_MICREL_KSZ90X1=y
 CONFIG_PHY_REALTEK=y
 CONFIG_ETH_DESIGNWARE=y
 CONFIG_RGMII=y
diff --git a/configs/MCR3000_defconfig b/configs/MCR3000_defconfig
index 8ddda59..924ab16 100644
--- a/configs/MCR3000_defconfig
+++ b/configs/MCR3000_defconfig
@@ -66,7 +66,7 @@
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
-# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_SLEEP is not set
 CONFIG_OF_CONTROL=y
 CONFIG_ENV_OVERWRITE=y
 CONFIG_ENV_IS_IN_FLASH=y
diff --git a/configs/MigoR_defconfig b/configs/MigoR_defconfig
index 5945e1d..f29f1ec 100644
--- a/configs/MigoR_defconfig
+++ b/configs/MigoR_defconfig
@@ -22,7 +22,7 @@
 # CONFIG_CMD_SOURCE is not set
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_CMD_PING=y
-# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_SLEEP is not set
 CONFIG_ENV_OVERWRITE=y
 CONFIG_ENV_IS_IN_FLASH=y
 CONFIG_ENV_ADDR=0xA0020000
diff --git a/configs/armadillo-800eva_defconfig b/configs/armadillo-800eva_defconfig
index ab84978..e06ef7d 100644
--- a/configs/armadillo-800eva_defconfig
+++ b/configs/armadillo-800eva_defconfig
@@ -31,7 +31,7 @@
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
-# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_SLEEP is not set
 CONFIG_ENV_OVERWRITE=y
 CONFIG_ENV_IS_IN_FLASH=y
 CONFIG_ENV_ADDR=0x40000
diff --git a/configs/at91sam9261ek_dataflash_cs0_defconfig b/configs/at91sam9261ek_dataflash_cs0_defconfig
index 422b8ae..9d4e5b5 100644
--- a/configs/at91sam9261ek_dataflash_cs0_defconfig
+++ b/configs/at91sam9261ek_dataflash_cs0_defconfig
@@ -59,4 +59,4 @@
 CONFIG_ATMEL_PIT_TIMER=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
-CONFIG_LCD=y
+# CONFIG_LCD is not set
diff --git a/configs/at91sam9261ek_dataflash_cs3_defconfig b/configs/at91sam9261ek_dataflash_cs3_defconfig
index 4494970..3a0bb10 100644
--- a/configs/at91sam9261ek_dataflash_cs3_defconfig
+++ b/configs/at91sam9261ek_dataflash_cs3_defconfig
@@ -59,4 +59,4 @@
 CONFIG_ATMEL_PIT_TIMER=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
-CONFIG_LCD=y
+# CONFIG_LCD is not set
diff --git a/configs/at91sam9261ek_nandflash_defconfig b/configs/at91sam9261ek_nandflash_defconfig
index 2381199..abdf223 100644
--- a/configs/at91sam9261ek_nandflash_defconfig
+++ b/configs/at91sam9261ek_nandflash_defconfig
@@ -56,4 +56,4 @@
 CONFIG_ATMEL_PIT_TIMER=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
-CONFIG_LCD=y
+# CONFIG_LCD is not set
diff --git a/configs/at91sam9263ek_dataflash_cs0_defconfig b/configs/at91sam9263ek_dataflash_cs0_defconfig
index b458aec..564b781 100644
--- a/configs/at91sam9263ek_dataflash_cs0_defconfig
+++ b/configs/at91sam9263ek_dataflash_cs0_defconfig
@@ -67,4 +67,4 @@
 CONFIG_USB=y
 CONFIG_DM_USB=y
 CONFIG_USB_STORAGE=y
-CONFIG_LCD=y
+# CONFIG_LCD is not set
diff --git a/configs/at91sam9263ek_dataflash_defconfig b/configs/at91sam9263ek_dataflash_defconfig
index b458aec..564b781 100644
--- a/configs/at91sam9263ek_dataflash_defconfig
+++ b/configs/at91sam9263ek_dataflash_defconfig
@@ -67,4 +67,4 @@
 CONFIG_USB=y
 CONFIG_DM_USB=y
 CONFIG_USB_STORAGE=y
-CONFIG_LCD=y
+# CONFIG_LCD is not set
diff --git a/configs/at91sam9263ek_nandflash_defconfig b/configs/at91sam9263ek_nandflash_defconfig
index a7a372d..32b2fff 100644
--- a/configs/at91sam9263ek_nandflash_defconfig
+++ b/configs/at91sam9263ek_nandflash_defconfig
@@ -64,4 +64,4 @@
 CONFIG_USB=y
 CONFIG_DM_USB=y
 CONFIG_USB_STORAGE=y
-CONFIG_LCD=y
+# CONFIG_LCD is not set
diff --git a/configs/at91sam9263ek_norflash_boot_defconfig b/configs/at91sam9263ek_norflash_boot_defconfig
index 7aea097..2955b05 100644
--- a/configs/at91sam9263ek_norflash_boot_defconfig
+++ b/configs/at91sam9263ek_norflash_boot_defconfig
@@ -67,4 +67,4 @@
 CONFIG_USB=y
 CONFIG_DM_USB=y
 CONFIG_USB_STORAGE=y
-CONFIG_LCD=y
+# CONFIG_LCD is not set
diff --git a/configs/at91sam9263ek_norflash_defconfig b/configs/at91sam9263ek_norflash_defconfig
index 7f4de53..56355f6 100644
--- a/configs/at91sam9263ek_norflash_defconfig
+++ b/configs/at91sam9263ek_norflash_defconfig
@@ -67,4 +67,4 @@
 CONFIG_USB=y
 CONFIG_DM_USB=y
 CONFIG_USB_STORAGE=y
-CONFIG_LCD=y
+# CONFIG_LCD is not set
diff --git a/configs/at91sam9g10ek_dataflash_cs0_defconfig b/configs/at91sam9g10ek_dataflash_cs0_defconfig
index 3e5632c..a5a493d 100644
--- a/configs/at91sam9g10ek_dataflash_cs0_defconfig
+++ b/configs/at91sam9g10ek_dataflash_cs0_defconfig
@@ -57,4 +57,4 @@
 CONFIG_DM_SPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
-CONFIG_LCD=y
+# CONFIG_LCD is not set
diff --git a/configs/at91sam9g10ek_dataflash_cs3_defconfig b/configs/at91sam9g10ek_dataflash_cs3_defconfig
index 31ce87e..85c4c50 100644
--- a/configs/at91sam9g10ek_dataflash_cs3_defconfig
+++ b/configs/at91sam9g10ek_dataflash_cs3_defconfig
@@ -57,4 +57,4 @@
 CONFIG_DM_SPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
-CONFIG_LCD=y
+# CONFIG_LCD is not set
diff --git a/configs/at91sam9g10ek_nandflash_defconfig b/configs/at91sam9g10ek_nandflash_defconfig
index bf820d7..609b9eb 100644
--- a/configs/at91sam9g10ek_nandflash_defconfig
+++ b/configs/at91sam9g10ek_nandflash_defconfig
@@ -54,4 +54,4 @@
 CONFIG_DM_SPI=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
-CONFIG_LCD=y
+# CONFIG_LCD is not set
diff --git a/configs/at91sam9m10g45ek_mmc_defconfig b/configs/at91sam9m10g45ek_mmc_defconfig
index 8181269..2885e12 100644
--- a/configs/at91sam9m10g45ek_mmc_defconfig
+++ b/configs/at91sam9m10g45ek_mmc_defconfig
@@ -58,4 +58,4 @@
 CONFIG_DM_USB=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_STORAGE=y
-CONFIG_LCD=y
+# CONFIG_LCD is not set
diff --git a/configs/at91sam9m10g45ek_nandflash_defconfig b/configs/at91sam9m10g45ek_nandflash_defconfig
index 636cab1..f89bf1e 100644
--- a/configs/at91sam9m10g45ek_nandflash_defconfig
+++ b/configs/at91sam9m10g45ek_nandflash_defconfig
@@ -58,4 +58,4 @@
 CONFIG_DM_USB=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_STORAGE=y
-CONFIG_LCD=y
+# CONFIG_LCD is not set
diff --git a/configs/at91sam9n12ek_mmc_defconfig b/configs/at91sam9n12ek_mmc_defconfig
index 23be41e..15a4335 100644
--- a/configs/at91sam9n12ek_mmc_defconfig
+++ b/configs/at91sam9n12ek_mmc_defconfig
@@ -62,4 +62,4 @@
 CONFIG_DM_USB=y
 CONFIG_USB_STORAGE=y
 CONFIG_ATMEL_HLCD=y
-CONFIG_LCD=y
+# CONFIG_LCD is not set
diff --git a/configs/at91sam9n12ek_nandflash_defconfig b/configs/at91sam9n12ek_nandflash_defconfig
index 35c1b4a..5f3c256 100644
--- a/configs/at91sam9n12ek_nandflash_defconfig
+++ b/configs/at91sam9n12ek_nandflash_defconfig
@@ -63,4 +63,4 @@
 CONFIG_DM_USB=y
 CONFIG_USB_STORAGE=y
 CONFIG_ATMEL_HLCD=y
-CONFIG_LCD=y
+# CONFIG_LCD is not set
diff --git a/configs/at91sam9n12ek_spiflash_defconfig b/configs/at91sam9n12ek_spiflash_defconfig
index aea633d..65c8926 100644
--- a/configs/at91sam9n12ek_spiflash_defconfig
+++ b/configs/at91sam9n12ek_spiflash_defconfig
@@ -64,4 +64,4 @@
 CONFIG_DM_USB=y
 CONFIG_USB_STORAGE=y
 CONFIG_ATMEL_HLCD=y
-CONFIG_LCD=y
+# CONFIG_LCD is not set
diff --git a/configs/at91sam9rlek_dataflash_defconfig b/configs/at91sam9rlek_dataflash_defconfig
index 9f314b3..f037a8d 100644
--- a/configs/at91sam9rlek_dataflash_defconfig
+++ b/configs/at91sam9rlek_dataflash_defconfig
@@ -60,4 +60,4 @@
 CONFIG_DM_SPI=y
 CONFIG_TIMER=y
 CONFIG_ATMEL_PIT_TIMER=y
-CONFIG_LCD=y
+# CONFIG_LCD is not set
diff --git a/configs/at91sam9rlek_mmc_defconfig b/configs/at91sam9rlek_mmc_defconfig
index 9b22c55..3477350 100644
--- a/configs/at91sam9rlek_mmc_defconfig
+++ b/configs/at91sam9rlek_mmc_defconfig
@@ -56,4 +56,4 @@
 CONFIG_DM_SPI=y
 CONFIG_TIMER=y
 CONFIG_ATMEL_PIT_TIMER=y
-CONFIG_LCD=y
+# CONFIG_LCD is not set
diff --git a/configs/at91sam9rlek_nandflash_defconfig b/configs/at91sam9rlek_nandflash_defconfig
index 38c18f9..ad8fcdf 100644
--- a/configs/at91sam9rlek_nandflash_defconfig
+++ b/configs/at91sam9rlek_nandflash_defconfig
@@ -57,4 +57,4 @@
 CONFIG_DM_SPI=y
 CONFIG_TIMER=y
 CONFIG_ATMEL_PIT_TIMER=y
-CONFIG_LCD=y
+# CONFIG_LCD is not set
diff --git a/configs/bcm968380gerg_ram_defconfig b/configs/bcm968380gerg_ram_defconfig
index 8dd507d..b1f8bf5 100644
--- a/configs/bcm968380gerg_ram_defconfig
+++ b/configs/bcm968380gerg_ram_defconfig
@@ -30,7 +30,7 @@
 CONFIG_CMD_GPIO=y
 # CONFIG_CMD_LOADS is not set
 CONFIG_CMD_NAND=y
-# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_SLEEP is not set
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 # CONFIG_NET is not set
 # CONFIG_DM_DEVICE_REMOVE is not set
diff --git a/configs/comtrend_ar5315u_ram_defconfig b/configs/comtrend_ar5315u_ram_defconfig
index e9d1c08..bb9c0b8 100644
--- a/configs/comtrend_ar5315u_ram_defconfig
+++ b/configs/comtrend_ar5315u_ram_defconfig
@@ -32,7 +32,7 @@
 CONFIG_CMD_USB=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
-# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_SLEEP is not set
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_NET_RANDOM_ETHADDR=y
 # CONFIG_DM_DEVICE_REMOVE is not set
diff --git a/configs/comtrend_ar5387un_ram_defconfig b/configs/comtrend_ar5387un_ram_defconfig
index 8d1de33..80bafb0 100644
--- a/configs/comtrend_ar5387un_ram_defconfig
+++ b/configs/comtrend_ar5387un_ram_defconfig
@@ -32,7 +32,7 @@
 CONFIG_CMD_USB=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
-# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_SLEEP is not set
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_NET_RANDOM_ETHADDR=y
 # CONFIG_DM_DEVICE_REMOVE is not set
diff --git a/configs/comtrend_ct5361_ram_defconfig b/configs/comtrend_ct5361_ram_defconfig
index 9394ce0..36dcf2c 100644
--- a/configs/comtrend_ct5361_ram_defconfig
+++ b/configs/comtrend_ct5361_ram_defconfig
@@ -30,7 +30,7 @@
 CONFIG_CMD_USB=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
-# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_SLEEP is not set
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_NET_RANDOM_ETHADDR=y
 # CONFIG_DM_DEVICE_REMOVE is not set
diff --git a/configs/comtrend_vr3032u_ram_defconfig b/configs/comtrend_vr3032u_ram_defconfig
index 33665e1..1c2eeed 100644
--- a/configs/comtrend_vr3032u_ram_defconfig
+++ b/configs/comtrend_vr3032u_ram_defconfig
@@ -32,7 +32,7 @@
 CONFIG_CMD_USB=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
-# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_SLEEP is not set
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_NET_RANDOM_ETHADDR=y
 # CONFIG_DM_DEVICE_REMOVE is not set
diff --git a/configs/comtrend_wap5813n_ram_defconfig b/configs/comtrend_wap5813n_ram_defconfig
index 997caf6..fda61ec 100644
--- a/configs/comtrend_wap5813n_ram_defconfig
+++ b/configs/comtrend_wap5813n_ram_defconfig
@@ -30,7 +30,7 @@
 CONFIG_CMD_USB=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
-# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_SLEEP is not set
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_NET_RANDOM_ETHADDR=y
 # CONFIG_DM_DEVICE_REMOVE is not set
diff --git a/configs/eb_cpu5282_defconfig b/configs/eb_cpu5282_defconfig
index bc0f72f..1f89342 100644
--- a/configs/eb_cpu5282_defconfig
+++ b/configs/eb_cpu5282_defconfig
@@ -32,6 +32,5 @@
 CONFIG_DM_ETH=y
 CONFIG_MCFFEC=y
 CONFIG_MII=y
-CONFIG_VIDEO=y
-# CONFIG_CFB_CONSOLE is not set
+CONFIG_VIDEO_VCXK=y
 CONFIG_SPLASH_SCREEN=y
diff --git a/configs/eb_cpu5282_internal_defconfig b/configs/eb_cpu5282_internal_defconfig
index 72e34ba..ad7b7d5 100644
--- a/configs/eb_cpu5282_internal_defconfig
+++ b/configs/eb_cpu5282_internal_defconfig
@@ -31,6 +31,5 @@
 CONFIG_DM_ETH=y
 CONFIG_MCFFEC=y
 CONFIG_MII=y
-CONFIG_VIDEO=y
-# CONFIG_CFB_CONSOLE is not set
+CONFIG_VIDEO_VCXK=y
 CONFIG_SPLASH_SCREEN=y
diff --git a/configs/evb-px30_defconfig b/configs/evb-px30_defconfig
index 5b930a5..d2fdfef 100644
--- a/configs/evb-px30_defconfig
+++ b/configs/evb-px30_defconfig
@@ -46,7 +46,7 @@
 CONFIG_CMD_USB_MASS_STORAGE=y
 # CONFIG_CMD_ITEST is not set
 # CONFIG_CMD_SETEXPR is not set
-# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_SLEEP is not set
 # CONFIG_SPL_DOS_PARTITION is not set
 # CONFIG_ISO_PARTITION is not set
 CONFIG_EFI_PARTITION_ENTRIES_NUMBERS=64
diff --git a/configs/evb-rk3308_defconfig b/configs/evb-rk3308_defconfig
index 7c7d222..9230983 100644
--- a/configs/evb-rk3308_defconfig
+++ b/configs/evb-rk3308_defconfig
@@ -33,7 +33,7 @@
 CONFIG_CMD_USB_MASS_STORAGE=y
 # CONFIG_CMD_ITEST is not set
 # CONFIG_CMD_SETEXPR is not set
-# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_SLEEP is not set
 # CONFIG_DOS_PARTITION is not set
 # CONFIG_ISO_PARTITION is not set
 CONFIG_EFI_PARTITION_ENTRIES_NUMBERS=64
diff --git a/configs/firefly-px30_defconfig b/configs/firefly-px30_defconfig
index a8b24cc..6487615 100644
--- a/configs/firefly-px30_defconfig
+++ b/configs/firefly-px30_defconfig
@@ -47,7 +47,7 @@
 CONFIG_CMD_USB_MASS_STORAGE=y
 # CONFIG_CMD_ITEST is not set
 # CONFIG_CMD_SETEXPR is not set
-# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_SLEEP is not set
 # CONFIG_SPL_DOS_PARTITION is not set
 # CONFIG_ISO_PARTITION is not set
 CONFIG_EFI_PARTITION_ENTRIES_NUMBERS=64
diff --git a/configs/huawei_hg556a_ram_defconfig b/configs/huawei_hg556a_ram_defconfig
index 6aba660..0029004 100644
--- a/configs/huawei_hg556a_ram_defconfig
+++ b/configs/huawei_hg556a_ram_defconfig
@@ -30,7 +30,7 @@
 CONFIG_CMD_USB=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
-# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_SLEEP is not set
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_NET_RANDOM_ETHADDR=y
 # CONFIG_DM_DEVICE_REMOVE is not set
diff --git a/configs/ls1021aqds_ddr4_nor_defconfig b/configs/ls1021aqds_ddr4_nor_defconfig
index 789bb5a..7585f2b 100644
--- a/configs/ls1021aqds_ddr4_nor_defconfig
+++ b/configs/ls1021aqds_ddr4_nor_defconfig
@@ -70,8 +70,8 @@
 CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_XHCI_DWC3=y
 CONFIG_USB_STORAGE=y
-CONFIG_VIDEO_FSL_DCU_FB=y
-CONFIG_VIDEO=y
+# CONFIG_VIDEO_FSL_DCU_FB is not set
+# CONFIG_VIDEO is not set
 # CONFIG_VIDEO_SW_CURSOR is not set
 CONFIG_CMD_NVME=y
 CONFIG_NVME=y
diff --git a/configs/ls1021aqds_ddr4_nor_lpuart_defconfig b/configs/ls1021aqds_ddr4_nor_lpuart_defconfig
index 9c36d2a..0f45df1 100644
--- a/configs/ls1021aqds_ddr4_nor_lpuart_defconfig
+++ b/configs/ls1021aqds_ddr4_nor_lpuart_defconfig
@@ -70,8 +70,8 @@
 CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_XHCI_DWC3=y
 CONFIG_USB_STORAGE=y
-CONFIG_VIDEO_FSL_DCU_FB=y
-CONFIG_VIDEO=y
+# CONFIG_VIDEO_FSL_DCU_FB is not set
+# CONFIG_VIDEO is not set
 # CONFIG_VIDEO_SW_CURSOR is not set
 CONFIG_CMD_NVME=y
 CONFIG_NVME=y
diff --git a/configs/ls1021aqds_nand_defconfig b/configs/ls1021aqds_nand_defconfig
index f6adc52..1cd6696 100644
--- a/configs/ls1021aqds_nand_defconfig
+++ b/configs/ls1021aqds_nand_defconfig
@@ -85,8 +85,8 @@
 CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_XHCI_DWC3=y
 CONFIG_USB_STORAGE=y
-CONFIG_VIDEO_FSL_DCU_FB=y
-CONFIG_VIDEO=y
+# CONFIG_VIDEO_FSL_DCU_FB is not set
+# CONFIG_VIDEO is not set
 # CONFIG_VIDEO_SW_CURSOR is not set
 CONFIG_CMD_NVME=y
 CONFIG_NVME=y
diff --git a/configs/ls1021aqds_nor_SECURE_BOOT_defconfig b/configs/ls1021aqds_nor_SECURE_BOOT_defconfig
index 91fb32a..f136cb1 100644
--- a/configs/ls1021aqds_nor_SECURE_BOOT_defconfig
+++ b/configs/ls1021aqds_nor_SECURE_BOOT_defconfig
@@ -67,8 +67,8 @@
 CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_XHCI_DWC3=y
 CONFIG_USB_STORAGE=y
-CONFIG_VIDEO_FSL_DCU_FB=y
-CONFIG_VIDEO=y
+# CONFIG_VIDEO_FSL_DCU_FB is not set
+# CONFIG_VIDEO is not set
 # CONFIG_VIDEO_SW_CURSOR is not set
 CONFIG_RSA=y
 CONFIG_SPL_RSA=y
diff --git a/configs/ls1021aqds_nor_defconfig b/configs/ls1021aqds_nor_defconfig
index 4e7e25a..e20fcf5 100644
--- a/configs/ls1021aqds_nor_defconfig
+++ b/configs/ls1021aqds_nor_defconfig
@@ -71,8 +71,8 @@
 CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_XHCI_DWC3=y
 CONFIG_USB_STORAGE=y
-CONFIG_VIDEO_FSL_DCU_FB=y
-CONFIG_VIDEO=y
+# CONFIG_VIDEO_FSL_DCU_FB is not set
+# CONFIG_VIDEO is not set
 # CONFIG_VIDEO_SW_CURSOR is not set
 CONFIG_CMD_NVME=y
 CONFIG_NVME=y
diff --git a/configs/ls1021aqds_nor_lpuart_defconfig b/configs/ls1021aqds_nor_lpuart_defconfig
index b50946c..52bdb8d 100644
--- a/configs/ls1021aqds_nor_lpuart_defconfig
+++ b/configs/ls1021aqds_nor_lpuart_defconfig
@@ -71,8 +71,8 @@
 CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_XHCI_DWC3=y
 CONFIG_USB_STORAGE=y
-CONFIG_VIDEO_FSL_DCU_FB=y
-CONFIG_VIDEO=y
+# CONFIG_VIDEO_FSL_DCU_FB is not set
+# CONFIG_VIDEO is not set
 # CONFIG_VIDEO_SW_CURSOR is not set
 CONFIG_CMD_NVME=y
 CONFIG_NVME=y
diff --git a/configs/ls1021aqds_qspi_defconfig b/configs/ls1021aqds_qspi_defconfig
index e470e63..b68041d 100644
--- a/configs/ls1021aqds_qspi_defconfig
+++ b/configs/ls1021aqds_qspi_defconfig
@@ -70,8 +70,8 @@
 CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_XHCI_DWC3=y
 CONFIG_USB_STORAGE=y
-CONFIG_VIDEO_FSL_DCU_FB=y
-CONFIG_VIDEO=y
+# CONFIG_VIDEO_FSL_DCU_FB is not set
+# CONFIG_VIDEO is not set
 # CONFIG_VIDEO_SW_CURSOR is not set
 CONFIG_CMD_NVME=y
 CONFIG_NVME=y
diff --git a/configs/ls1021aqds_sdcard_ifc_defconfig b/configs/ls1021aqds_sdcard_ifc_defconfig
index 58775c0..431d53f 100644
--- a/configs/ls1021aqds_sdcard_ifc_defconfig
+++ b/configs/ls1021aqds_sdcard_ifc_defconfig
@@ -84,8 +84,8 @@
 CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_XHCI_DWC3=y
 CONFIG_USB_STORAGE=y
-CONFIG_VIDEO_FSL_DCU_FB=y
-CONFIG_VIDEO=y
+# CONFIG_VIDEO_FSL_DCU_FB is not set
+# CONFIG_VIDEO is not set
 # CONFIG_VIDEO_SW_CURSOR is not set
 CONFIG_CMD_NVME=y
 CONFIG_NVME=y
diff --git a/configs/ls1021aqds_sdcard_qspi_defconfig b/configs/ls1021aqds_sdcard_qspi_defconfig
index 0be05b6..ba9d499 100644
--- a/configs/ls1021aqds_sdcard_qspi_defconfig
+++ b/configs/ls1021aqds_sdcard_qspi_defconfig
@@ -82,8 +82,8 @@
 CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_XHCI_DWC3=y
 CONFIG_USB_STORAGE=y
-CONFIG_VIDEO_FSL_DCU_FB=y
-CONFIG_VIDEO=y
+# CONFIG_VIDEO_FSL_DCU_FB is not set
+# CONFIG_VIDEO is not set
 # CONFIG_VIDEO_SW_CURSOR is not set
 CONFIG_CMD_NVME=y
 CONFIG_NVME=y
diff --git a/configs/ls1021atwr_nor_SECURE_BOOT_defconfig b/configs/ls1021atwr_nor_SECURE_BOOT_defconfig
index b67a636..3828d6d 100644
--- a/configs/ls1021atwr_nor_SECURE_BOOT_defconfig
+++ b/configs/ls1021atwr_nor_SECURE_BOOT_defconfig
@@ -61,8 +61,8 @@
 CONFIG_DM_USB=y
 CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_XHCI_DWC3=y
-CONFIG_VIDEO_FSL_DCU_FB=y
-CONFIG_VIDEO=y
+# CONFIG_VIDEO_FSL_DCU_FB is not set
+# CONFIG_VIDEO is not set
 # CONFIG_VIDEO_SW_CURSOR is not set
 CONFIG_RSA=y
 CONFIG_SPL_RSA=y
diff --git a/configs/ls1021atwr_nor_defconfig b/configs/ls1021atwr_nor_defconfig
index b53185e..c91fa0b 100644
--- a/configs/ls1021atwr_nor_defconfig
+++ b/configs/ls1021atwr_nor_defconfig
@@ -65,8 +65,8 @@
 CONFIG_DM_USB=y
 CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_XHCI_DWC3=y
-CONFIG_VIDEO_FSL_DCU_FB=y
-CONFIG_VIDEO=y
+# CONFIG_VIDEO_FSL_DCU_FB is not set
+# CONFIG_VIDEO is not set
 # CONFIG_VIDEO_SW_CURSOR is not set
 CONFIG_CMD_NVME=y
 CONFIG_NVME=y
diff --git a/configs/ls1021atwr_nor_lpuart_defconfig b/configs/ls1021atwr_nor_lpuart_defconfig
index 028cc23..b59ec99 100644
--- a/configs/ls1021atwr_nor_lpuart_defconfig
+++ b/configs/ls1021atwr_nor_lpuart_defconfig
@@ -66,8 +66,8 @@
 CONFIG_DM_USB=y
 CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_XHCI_DWC3=y
-CONFIG_VIDEO_FSL_DCU_FB=y
-CONFIG_VIDEO=y
+# CONFIG_VIDEO_FSL_DCU_FB is not set
+# CONFIG_VIDEO is not set
 # CONFIG_VIDEO_SW_CURSOR is not set
 CONFIG_CMD_NVME=y
 CONFIG_NVME=y
diff --git a/configs/ls1021atwr_qspi_defconfig b/configs/ls1021atwr_qspi_defconfig
index 2899d1b..e8e1aa3 100644
--- a/configs/ls1021atwr_qspi_defconfig
+++ b/configs/ls1021atwr_qspi_defconfig
@@ -68,8 +68,8 @@
 CONFIG_DM_USB=y
 CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_XHCI_DWC3=y
-CONFIG_VIDEO_FSL_DCU_FB=y
-CONFIG_VIDEO=y
+# CONFIG_VIDEO_FSL_DCU_FB is not set
+# CONFIG_VIDEO is not set
 # CONFIG_VIDEO_SW_CURSOR is not set
 CONFIG_CMD_NVME=y
 CONFIG_NVME=y
diff --git a/configs/ls1021atwr_sdcard_ifc_SECURE_BOOT_defconfig b/configs/ls1021atwr_sdcard_ifc_SECURE_BOOT_defconfig
index f8a1635..2b4ebef 100644
--- a/configs/ls1021atwr_sdcard_ifc_SECURE_BOOT_defconfig
+++ b/configs/ls1021atwr_sdcard_ifc_SECURE_BOOT_defconfig
@@ -75,8 +75,8 @@
 CONFIG_DM_USB=y
 CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_XHCI_DWC3=y
-CONFIG_VIDEO_FSL_DCU_FB=y
-CONFIG_VIDEO=y
+# CONFIG_VIDEO_FSL_DCU_FB is not set
+# CONFIG_VIDEO is not set
 # CONFIG_VIDEO_SW_CURSOR is not set
 CONFIG_RSA=y
 CONFIG_SPL_RSA=y
diff --git a/configs/ls1021atwr_sdcard_ifc_defconfig b/configs/ls1021atwr_sdcard_ifc_defconfig
index 15d9203..fccdc72 100644
--- a/configs/ls1021atwr_sdcard_ifc_defconfig
+++ b/configs/ls1021atwr_sdcard_ifc_defconfig
@@ -78,8 +78,8 @@
 CONFIG_DM_USB=y
 CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_XHCI_DWC3=y
-CONFIG_VIDEO_FSL_DCU_FB=y
-CONFIG_VIDEO=y
+# CONFIG_VIDEO_FSL_DCU_FB is not set
+# CONFIG_VIDEO is not set
 # CONFIG_VIDEO_SW_CURSOR is not set
 CONFIG_CMD_NVME=y
 CONFIG_NVME=y
diff --git a/configs/ls1021atwr_sdcard_qspi_defconfig b/configs/ls1021atwr_sdcard_qspi_defconfig
index 4edfdb5..9611349 100644
--- a/configs/ls1021atwr_sdcard_qspi_defconfig
+++ b/configs/ls1021atwr_sdcard_qspi_defconfig
@@ -79,8 +79,8 @@
 CONFIG_DM_USB=y
 CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_XHCI_DWC3=y
-CONFIG_VIDEO_FSL_DCU_FB=y
-CONFIG_VIDEO=y
+# CONFIG_VIDEO_FSL_DCU_FB is not set
+# CONFIG_VIDEO is not set
 # CONFIG_VIDEO_SW_CURSOR is not set
 CONFIG_CMD_NVME=y
 CONFIG_NVME=y
diff --git a/configs/ls2080a_emu_defconfig b/configs/ls2080a_emu_defconfig
index 4e37781..c42f012 100644
--- a/configs/ls2080a_emu_defconfig
+++ b/configs/ls2080a_emu_defconfig
@@ -24,7 +24,7 @@
 # CONFIG_CMD_SETEXPR is not set
 # CONFIG_CMD_NFS is not set
 CONFIG_CMD_CACHE=y
-# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_SLEEP is not set
 CONFIG_MP=y
 # CONFIG_DOS_PARTITION is not set
 # CONFIG_ISO_PARTITION is not set
diff --git a/configs/ls2080a_simu_defconfig b/configs/ls2080a_simu_defconfig
index 599c250..2aabb77 100644
--- a/configs/ls2080a_simu_defconfig
+++ b/configs/ls2080a_simu_defconfig
@@ -26,7 +26,7 @@
 # CONFIG_CMD_SETEXPR is not set
 # CONFIG_CMD_NFS is not set
 CONFIG_CMD_CACHE=y
-# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_SLEEP is not set
 CONFIG_MP=y
 # CONFIG_ISO_PARTITION is not set
 # CONFIG_EFI_PARTITION is not set
diff --git a/configs/mx23evk_defconfig b/configs/mx23evk_defconfig
index a5f7cc7..73d7e9b 100644
--- a/configs/mx23evk_defconfig
+++ b/configs/mx23evk_defconfig
@@ -37,7 +37,7 @@
 CONFIG_USB=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_STORAGE=y
-CONFIG_VIDEO=y
+# CONFIG_VIDEO is not set
 CONFIG_SPLASH_SCREEN=y
 CONFIG_VIDEO_BMP_GZIP=y
 CONFIG_VIDEO_BMP_RLE8=y
diff --git a/configs/mx6sxsabresd_defconfig b/configs/mx6sxsabresd_defconfig
index 584e795..a33ec49 100644
--- a/configs/mx6sxsabresd_defconfig
+++ b/configs/mx6sxsabresd_defconfig
@@ -73,7 +73,7 @@
 CONFIG_USB_STORAGE=y
 CONFIG_USB_HOST_ETHER=y
 CONFIG_USB_ETHER_ASIX=y
-CONFIG_VIDEO=y
+# CONFIG_VIDEO is not set
 CONFIG_SPLASH_SCREEN=y
 CONFIG_SPLASH_SCREEN_ALIGN=y
 CONFIG_VIDEO_BMP_RLE8=y
diff --git a/configs/mx7dsabresd_defconfig b/configs/mx7dsabresd_defconfig
index 9e2e249..9b4bbf3 100644
--- a/configs/mx7dsabresd_defconfig
+++ b/configs/mx7dsabresd_defconfig
@@ -84,7 +84,7 @@
 CONFIG_USB_GADGET_DOWNLOAD=y
 CONFIG_USB_HOST_ETHER=y
 CONFIG_USB_ETHER_ASIX=y
-CONFIG_VIDEO=y
+# CONFIG_VIDEO is not set
 CONFIG_SPLASH_SCREEN=y
 CONFIG_SPLASH_SCREEN_ALIGN=y
 CONFIG_VIDEO_BMP_RLE8=y
diff --git a/configs/mx7dsabresd_qspi_defconfig b/configs/mx7dsabresd_qspi_defconfig
index 7f73956..fa5deb8 100644
--- a/configs/mx7dsabresd_qspi_defconfig
+++ b/configs/mx7dsabresd_qspi_defconfig
@@ -91,7 +91,7 @@
 CONFIG_USB_GADGET_DOWNLOAD=y
 CONFIG_USB_HOST_ETHER=y
 CONFIG_USB_ETHER_ASIX=y
-CONFIG_VIDEO=y
+# CONFIG_VIDEO is not set
 CONFIG_SPLASH_SCREEN=y
 CONFIG_SPLASH_SCREEN_ALIGN=y
 CONFIG_VIDEO_BMP_RLE8=y
diff --git a/configs/netgear_cg3100d_ram_defconfig b/configs/netgear_cg3100d_ram_defconfig
index 7a73738..538056c 100644
--- a/configs/netgear_cg3100d_ram_defconfig
+++ b/configs/netgear_cg3100d_ram_defconfig
@@ -28,7 +28,7 @@
 # CONFIG_CMD_FLASH is not set
 # CONFIG_CMD_LOADS is not set
 CONFIG_CMD_SPI=y
-# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_SLEEP is not set
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 # CONFIG_NET is not set
 # CONFIG_DM_DEVICE_REMOVE is not set
diff --git a/configs/netgear_dgnd3700v2_ram_defconfig b/configs/netgear_dgnd3700v2_ram_defconfig
index 31ab144..333652d 100644
--- a/configs/netgear_dgnd3700v2_ram_defconfig
+++ b/configs/netgear_dgnd3700v2_ram_defconfig
@@ -31,7 +31,7 @@
 CONFIG_CMD_USB=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
-# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_SLEEP is not set
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_NET_RANDOM_ETHADDR=y
 # CONFIG_DM_DEVICE_REMOVE is not set
diff --git a/configs/nokia_rx51_defconfig b/configs/nokia_rx51_defconfig
index e249dff..1d35352 100644
--- a/configs/nokia_rx51_defconfig
+++ b/configs/nokia_rx51_defconfig
@@ -10,6 +10,7 @@
 CONFIG_AUTOBOOT_MENU_SHOW=y
 CONFIG_USE_PREBOOT=y
 CONFIG_PREBOOT="run preboot"
+CONFIG_CONSOLE_MUX=y
 CONFIG_HUSH_PARSER=y
 CONFIG_SYS_PROMPT="Nokia RX-51 # "
 # CONFIG_CMD_BDI is not set
@@ -54,7 +55,7 @@
 CONFIG_USB_MUSB_UDC=y
 CONFIG_USB_OMAP3=y
 CONFIG_TWL4030_USB=y
-CONFIG_VIDEO=y
+CONFIG_CFB_CONSOLE=y
 CONFIG_CFB_CONSOLE_ANSI=y
 # CONFIG_VGA_AS_SINGLE_DEVICE is not set
 CONFIG_SPLASH_SCREEN=y
diff --git a/configs/odroid-go2_defconfig b/configs/odroid-go2_defconfig
index d1f7a0f..8538909 100644
--- a/configs/odroid-go2_defconfig
+++ b/configs/odroid-go2_defconfig
@@ -52,7 +52,7 @@
 CONFIG_CMD_USB=y
 CONFIG_CMD_USB_MASS_STORAGE=y
 # CONFIG_CMD_ITEST is not set
-# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_SLEEP is not set
 # CONFIG_SPL_DOS_PARTITION is not set
 # CONFIG_ISO_PARTITION is not set
 CONFIG_EFI_PARTITION_ENTRIES_NUMBERS=64
diff --git a/configs/odroid_defconfig b/configs/odroid_defconfig
index 25c7e98..9f2b0b2 100644
--- a/configs/odroid_defconfig
+++ b/configs/odroid_defconfig
@@ -32,7 +32,7 @@
 CONFIG_CMD_USB_MASS_STORAGE=y
 # CONFIG_CMD_NFS is not set
 CONFIG_CMD_CACHE=y
-# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_SLEEP is not set
 CONFIG_CMD_PMIC=y
 CONFIG_CMD_REGULATOR=y
 CONFIG_CMD_EXT4_WRITE=y
diff --git a/configs/origen_defconfig b/configs/origen_defconfig
index 3f1c7b1..4c4dc1a 100644
--- a/configs/origen_defconfig
+++ b/configs/origen_defconfig
@@ -25,7 +25,7 @@
 CONFIG_CMD_USB_MASS_STORAGE=y
 # CONFIG_CMD_NET is not set
 CONFIG_CMD_CACHE=y
-# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_SLEEP is not set
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_OF_CONTROL=y
 CONFIG_ENV_OVERWRITE=y
diff --git a/configs/picosam9g45_defconfig b/configs/picosam9g45_defconfig
index 5ffbee8..081c2a9 100644
--- a/configs/picosam9g45_defconfig
+++ b/configs/picosam9g45_defconfig
@@ -44,7 +44,7 @@
 CONFIG_USB=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_STORAGE=y
-CONFIG_LCD=y
+# CONFIG_LCD is not set
 CONFIG_WDT=y
 CONFIG_WDT_AT91=y
 CONFIG_OF_LIBFDT=y
diff --git a/configs/pine_h64_defconfig b/configs/pine_h64_defconfig
index 328849d..07ad31e 100644
--- a/configs/pine_h64_defconfig
+++ b/configs/pine_h64_defconfig
@@ -11,5 +11,6 @@
 CONFIG_DEFAULT_DEVICE_TREE="sun50i-h6-pine-h64"
 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
 CONFIG_SUN8I_EMAC=y
+CONFIG_MACPWR="PC16"
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_OHCI_HCD=y
diff --git a/configs/pumpkin_defconfig b/configs/pumpkin_defconfig
index 3d6af03..ab50124 100644
--- a/configs/pumpkin_defconfig
+++ b/configs/pumpkin_defconfig
@@ -42,7 +42,7 @@
 # CONFIG_CMD_SOURCE is not set
 # CONFIG_CMD_SETEXPR is not set
 # CONFIG_CMD_BLOCK_CACHE is not set
-# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_SLEEP is not set
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 # CONFIG_NET is not set
diff --git a/configs/r7780mp_defconfig b/configs/r7780mp_defconfig
index 44bf3a7..ed89aa9 100644
--- a/configs/r7780mp_defconfig
+++ b/configs/r7780mp_defconfig
@@ -26,7 +26,7 @@
 # CONFIG_CMD_SOURCE is not set
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_CMD_PING=y
-# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_SLEEP is not set
 CONFIG_CMD_EXT2=y
 CONFIG_DOS_PARTITION=y
 CONFIG_ENV_OVERWRITE=y
diff --git a/configs/roc-cc-rk3308_defconfig b/configs/roc-cc-rk3308_defconfig
index f40c197..2d02e29 100644
--- a/configs/roc-cc-rk3308_defconfig
+++ b/configs/roc-cc-rk3308_defconfig
@@ -33,7 +33,7 @@
 CONFIG_CMD_USB_MASS_STORAGE=y
 # CONFIG_CMD_ITEST is not set
 # CONFIG_CMD_SETEXPR is not set
-# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_SLEEP is not set
 # CONFIG_DOS_PARTITION is not set
 # CONFIG_ISO_PARTITION is not set
 CONFIG_EFI_PARTITION_ENTRIES_NUMBERS=64
diff --git a/configs/s5p_goni_defconfig b/configs/s5p_goni_defconfig
index a9c1fce..28d8be6 100644
--- a/configs/s5p_goni_defconfig
+++ b/configs/s5p_goni_defconfig
@@ -26,7 +26,7 @@
 CONFIG_CMD_USB_MASS_STORAGE=y
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_CMD_CACHE=y
-# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_SLEEP is not set
 CONFIG_CMD_EXT4=y
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
diff --git a/configs/s5pc210_universal_defconfig b/configs/s5pc210_universal_defconfig
index db1d64c..759034a 100644
--- a/configs/s5pc210_universal_defconfig
+++ b/configs/s5pc210_universal_defconfig
@@ -25,7 +25,7 @@
 CONFIG_CMD_USB_MASS_STORAGE=y
 # CONFIG_CMD_NET is not set
 CONFIG_CMD_CACHE=y
-# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_SLEEP is not set
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_MTDPARTS_DEFAULT="mtdparts=samsung-onenand:128k(s-boot),896k(bootloader),256k(params),2816k(config),8m(csa),7m(kernel),1m(log),12m(modem),60m(qboot),-(UBI)"
 CONFIG_OF_CONTROL=y
diff --git a/configs/sagem_f@st1704_ram_defconfig b/configs/sagem_f@st1704_ram_defconfig
index 13f7775..efd23b4 100644
--- a/configs/sagem_f@st1704_ram_defconfig
+++ b/configs/sagem_f@st1704_ram_defconfig
@@ -31,7 +31,7 @@
 CONFIG_CMD_SPI=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
-# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_SLEEP is not set
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_NET_RANDOM_ETHADDR=y
 # CONFIG_DM_DEVICE_REMOVE is not set
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index b15b188..3043208 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -55,6 +55,7 @@
 CONFIG_CMD_IDE=y
 CONFIG_CMD_I2C=y
 CONFIG_CMD_LSBLK=y
+CONFIG_CMD_MUX=y
 CONFIG_CMD_OSD=y
 CONFIG_CMD_PCI=y
 CONFIG_CMD_READ=y
@@ -179,6 +180,8 @@
 CONFIG_SPI_FLASH_STMICRO=y
 CONFIG_SPI_FLASH_SST=y
 CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_MULTIPLEXER=y
+CONFIG_MUX_MMIO=y
 CONFIG_DM_ETH=y
 CONFIG_NVME=y
 CONFIG_PCI=y
diff --git a/configs/sansa_fuze_plus_defconfig b/configs/sansa_fuze_plus_defconfig
index 0c32960..7a41f99 100644
--- a/configs/sansa_fuze_plus_defconfig
+++ b/configs/sansa_fuze_plus_defconfig
@@ -44,5 +44,5 @@
 CONFIG_CI_UDC=y
 CONFIG_USB_ETHER=y
 CONFIG_USB_ETH_CDC=y
-CONFIG_VIDEO=y
+# CONFIG_VIDEO is not set
 CONFIG_OF_LIBFDT=y
diff --git a/configs/sfr_nb4-ser_ram_defconfig b/configs/sfr_nb4-ser_ram_defconfig
index 00a79ee..6cf0740 100644
--- a/configs/sfr_nb4-ser_ram_defconfig
+++ b/configs/sfr_nb4-ser_ram_defconfig
@@ -31,7 +31,7 @@
 CONFIG_CMD_USB=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
-# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_SLEEP is not set
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_NET_RANDOM_ETHADDR=y
 # CONFIG_DM_DEVICE_REMOVE is not set
diff --git a/configs/sh7752evb_defconfig b/configs/sh7752evb_defconfig
index 3e35553..bc174f4 100644
--- a/configs/sh7752evb_defconfig
+++ b/configs/sh7752evb_defconfig
@@ -23,7 +23,7 @@
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
-# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_SLEEP is not set
 CONFIG_CMD_EXT2=y
 CONFIG_MAC_PARTITION=y
 CONFIG_DOS_PARTITION=y
diff --git a/configs/sh7753evb_defconfig b/configs/sh7753evb_defconfig
index 0b14847..c199660 100644
--- a/configs/sh7753evb_defconfig
+++ b/configs/sh7753evb_defconfig
@@ -22,7 +22,7 @@
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
-# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_SLEEP is not set
 CONFIG_CMD_EXT2=y
 CONFIG_MAC_PARTITION=y
 CONFIG_DOS_PARTITION=y
diff --git a/configs/sh7757lcr_defconfig b/configs/sh7757lcr_defconfig
index 14e569c..4e5bfea 100644
--- a/configs/sh7757lcr_defconfig
+++ b/configs/sh7757lcr_defconfig
@@ -25,7 +25,7 @@
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
-# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_SLEEP is not set
 CONFIG_CMD_EXT2=y
 CONFIG_MAC_PARTITION=y
 CONFIG_DOS_PARTITION=y
diff --git a/configs/sh7763rdp_defconfig b/configs/sh7763rdp_defconfig
index fc07bfd..072202e 100644
--- a/configs/sh7763rdp_defconfig
+++ b/configs/sh7763rdp_defconfig
@@ -25,7 +25,7 @@
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
-# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_SLEEP is not set
 CONFIG_CMD_JFFS2=y
 CONFIG_ENV_OVERWRITE=y
 CONFIG_ENV_IS_IN_FLASH=y
diff --git a/configs/smdkv310_defconfig b/configs/smdkv310_defconfig
index eec30b6..9d4cf35 100644
--- a/configs/smdkv310_defconfig
+++ b/configs/smdkv310_defconfig
@@ -18,7 +18,7 @@
 CONFIG_CMD_MMC=y
 # CONFIG_CMD_NFS is not set
 CONFIG_CMD_CACHE=y
-# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_SLEEP is not set
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_ENV_OVERWRITE=y
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
diff --git a/configs/teres_i_defconfig b/configs/teres_i_defconfig
index 1eba20e..ee07f86 100644
--- a/configs/teres_i_defconfig
+++ b/configs/teres_i_defconfig
@@ -7,6 +7,7 @@
 CONFIG_MMC_SUNXI_SLOT_EXTRA=2
 CONFIG_USB1_VBUS_PIN="PL7"
 CONFIG_I2C0_ENABLE=y
+CONFIG_PREBOOT="setenv usb_pgood_delay 2000; usb start"
 CONFIG_DEFAULT_DEVICE_TREE="sun50i-a64-teres-i"
 CONFIG_DM_REGULATOR=y
 CONFIG_DM_REGULATOR_FIXED=y
diff --git a/configs/total_compute_defconfig b/configs/total_compute_defconfig
index 3b04f94..6348b31 100644
--- a/configs/total_compute_defconfig
+++ b/configs/total_compute_defconfig
@@ -34,7 +34,7 @@
 # CONFIG_CMD_ITEST is not set
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_CMD_CACHE=y
-# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_SLEEP is not set
 CONFIG_CMD_AVB=y
 CONFIG_CMD_UBI=y
 # CONFIG_ISO_PARTITION is not set
diff --git a/configs/trats2_defconfig b/configs/trats2_defconfig
index e8950e3..8439ddc 100644
--- a/configs/trats2_defconfig
+++ b/configs/trats2_defconfig
@@ -27,7 +27,7 @@
 CONFIG_CMD_USB_MASS_STORAGE=y
 # CONFIG_CMD_NET is not set
 CONFIG_CMD_CACHE=y
-# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_SLEEP is not set
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_OF_CONTROL=y
 CONFIG_ENV_OVERWRITE=y
diff --git a/configs/trats_defconfig b/configs/trats_defconfig
index 1323e18..931c69b 100644
--- a/configs/trats_defconfig
+++ b/configs/trats_defconfig
@@ -26,7 +26,7 @@
 CONFIG_CMD_USB_MASS_STORAGE=y
 # CONFIG_CMD_NET is not set
 CONFIG_CMD_CACHE=y
-# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_SLEEP is not set
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_OF_CONTROL=y
 CONFIG_ENV_OVERWRITE=y
diff --git a/configs/uniphier_ld4_sld8_defconfig b/configs/uniphier_ld4_sld8_defconfig
index a35aa85..acc6d7d 100644
--- a/configs/uniphier_ld4_sld8_defconfig
+++ b/configs/uniphier_ld4_sld8_defconfig
@@ -27,7 +27,7 @@
 CONFIG_CMD_TFTPPUT=y
 CONFIG_CMD_CACHE=y
 CONFIG_CMD_TIME=y
-# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_SLEEP is not set
 CONFIG_CMD_MTDPARTS=y
 CONFIG_MTDIDS_DEFAULT="nand0=uniphier-nand.0"
 CONFIG_MTDPARTS_DEFAULT="mtdparts=uniphier-nand.0:1m(firmware),-(UBI)"
diff --git a/configs/uniphier_v7_defconfig b/configs/uniphier_v7_defconfig
index a7dbbdc..e989b84 100644
--- a/configs/uniphier_v7_defconfig
+++ b/configs/uniphier_v7_defconfig
@@ -28,7 +28,7 @@
 CONFIG_CMD_TFTPPUT=y
 CONFIG_CMD_CACHE=y
 CONFIG_CMD_TIME=y
-# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_SLEEP is not set
 CONFIG_CMD_MTDPARTS=y
 CONFIG_MTDIDS_DEFAULT="nand0=uniphier-nand.0"
 CONFIG_MTDPARTS_DEFAULT="mtdparts=uniphier-nand.0:1m(firmware),-(UBI)"
diff --git a/configs/uniphier_v8_defconfig b/configs/uniphier_v8_defconfig
index c69a07a..3d2a98e 100644
--- a/configs/uniphier_v8_defconfig
+++ b/configs/uniphier_v8_defconfig
@@ -25,7 +25,7 @@
 CONFIG_CMD_TFTPPUT=y
 CONFIG_CMD_CACHE=y
 CONFIG_CMD_TIME=y
-# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_SLEEP is not set
 CONFIG_CMD_MTDPARTS=y
 CONFIG_MTDIDS_DEFAULT="nand0=uniphier-nand.0"
 CONFIG_MTDPARTS_DEFAULT="mtdparts=uniphier-nand.0:1m(firmware),-(UBI)"
diff --git a/configs/vexpress_aemv8a_juno_defconfig b/configs/vexpress_aemv8a_juno_defconfig
index c368425..005d3d1 100644
--- a/configs/vexpress_aemv8a_juno_defconfig
+++ b/configs/vexpress_aemv8a_juno_defconfig
@@ -29,7 +29,7 @@
 # CONFIG_CMD_SETEXPR is not set
 # CONFIG_CMD_NFS is not set
 CONFIG_CMD_CACHE=y
-# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_SLEEP is not set
 CONFIG_CMD_UBI=y
 CONFIG_OF_BOARD=y
 CONFIG_ENV_IS_IN_FLASH=y
diff --git a/configs/vexpress_aemv8a_semi_defconfig b/configs/vexpress_aemv8a_semi_defconfig
index 4a17ce0..ee41ec3 100644
--- a/configs/vexpress_aemv8a_semi_defconfig
+++ b/configs/vexpress_aemv8a_semi_defconfig
@@ -28,7 +28,7 @@
 # CONFIG_CMD_SETEXPR is not set
 # CONFIG_CMD_NFS is not set
 CONFIG_CMD_CACHE=y
-# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_SLEEP is not set
 CONFIG_CMD_UBI=y
 # CONFIG_ISO_PARTITION is not set
 # CONFIG_EFI_PARTITION is not set
diff --git a/configs/vexpress_ca15_tc2_defconfig b/configs/vexpress_ca15_tc2_defconfig
index 330b95c..e8e401b 100644
--- a/configs/vexpress_ca15_tc2_defconfig
+++ b/configs/vexpress_ca15_tc2_defconfig
@@ -19,7 +19,7 @@
 # CONFIG_CMD_ITEST is not set
 # CONFIG_CMD_SETEXPR is not set
 # CONFIG_CMD_NFS is not set
-# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_SLEEP is not set
 CONFIG_CMD_UBI=y
 CONFIG_ENV_OVERWRITE=y
 CONFIG_ENV_IS_IN_FLASH=y
diff --git a/configs/vexpress_ca5x2_defconfig b/configs/vexpress_ca5x2_defconfig
index 44f40d0..88027b9 100644
--- a/configs/vexpress_ca5x2_defconfig
+++ b/configs/vexpress_ca5x2_defconfig
@@ -18,7 +18,7 @@
 # CONFIG_CMD_ITEST is not set
 # CONFIG_CMD_SETEXPR is not set
 # CONFIG_CMD_NFS is not set
-# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_SLEEP is not set
 CONFIG_CMD_UBI=y
 CONFIG_ENV_OVERWRITE=y
 CONFIG_ENV_IS_IN_FLASH=y
diff --git a/configs/vexpress_ca9x4_defconfig b/configs/vexpress_ca9x4_defconfig
index 8772ac3..7b14845 100644
--- a/configs/vexpress_ca9x4_defconfig
+++ b/configs/vexpress_ca9x4_defconfig
@@ -19,7 +19,7 @@
 # CONFIG_CMD_ITEST is not set
 # CONFIG_CMD_SETEXPR is not set
 # CONFIG_CMD_NFS is not set
-# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_SLEEP is not set
 CONFIG_CMD_UBI=y
 CONFIG_ENV_OVERWRITE=y
 CONFIG_ENV_IS_IN_FLASH=y
diff --git a/configs/xenguest_arm64_defconfig b/configs/xenguest_arm64_defconfig
index 042ea79..e170761 100644
--- a/configs/xenguest_arm64_defconfig
+++ b/configs/xenguest_arm64_defconfig
@@ -28,7 +28,7 @@
 # CONFIG_CMD_SOURCE is not set
 # CONFIG_CMD_SETEXPR is not set
 # CONFIG_CMD_NET is not set
-# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_SLEEP is not set
 CONFIG_CMD_EXT4=y
 CONFIG_CMD_FAT=y
 CONFIG_OF_BOARD=y
diff --git a/configs/xfi3_defconfig b/configs/xfi3_defconfig
index a943354..9d895f8 100644
--- a/configs/xfi3_defconfig
+++ b/configs/xfi3_defconfig
@@ -41,5 +41,5 @@
 CONFIG_CI_UDC=y
 CONFIG_USB_ETHER=y
 CONFIG_USB_ETH_CDC=y
-CONFIG_VIDEO=y
+# CONFIG_VIDEO is not set
 CONFIG_OF_LIBFDT=y
diff --git a/configs/xilinx_versal_mini_defconfig b/configs/xilinx_versal_mini_defconfig
index 3d1cba3..e72cef9 100644
--- a/configs/xilinx_versal_mini_defconfig
+++ b/configs/xilinx_versal_mini_defconfig
@@ -47,7 +47,7 @@
 # CONFIG_CMD_ITEST is not set
 # CONFIG_CMD_SOURCE is not set
 # CONFIG_CMD_SETEXPR is not set
-# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_SLEEP is not set
 # CONFIG_PARTITIONS is not set
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 # CONFIG_NET is not set
diff --git a/configs/xilinx_zynqmp_mini_defconfig b/configs/xilinx_zynqmp_mini_defconfig
index c029f59..9e63533 100644
--- a/configs/xilinx_zynqmp_mini_defconfig
+++ b/configs/xilinx_zynqmp_mini_defconfig
@@ -45,7 +45,7 @@
 # CONFIG_CMD_SOURCE is not set
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_CMD_CACHE=y
-# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_SLEEP is not set
 # CONFIG_PARTITIONS is not set
 CONFIG_OF_EMBED=y
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
diff --git a/configs/xilinx_zynqmp_mini_qspi_defconfig b/configs/xilinx_zynqmp_mini_qspi_defconfig
index 83458f9..15cba60 100644
--- a/configs/xilinx_zynqmp_mini_qspi_defconfig
+++ b/configs/xilinx_zynqmp_mini_qspi_defconfig
@@ -44,7 +44,7 @@
 # CONFIG_CMD_ITEST is not set
 # CONFIG_CMD_SOURCE is not set
 # CONFIG_CMD_SETEXPR is not set
-# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_SLEEP is not set
 CONFIG_SPL_OF_CONTROL=y
 CONFIG_OF_EMBED=y
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
diff --git a/configs/zynq_cse_nand_defconfig b/configs/zynq_cse_nand_defconfig
index 342a64d..b36fd4a4 100644
--- a/configs/zynq_cse_nand_defconfig
+++ b/configs/zynq_cse_nand_defconfig
@@ -45,7 +45,7 @@
 # CONFIG_CMD_ITEST is not set
 # CONFIG_CMD_SOURCE is not set
 # CONFIG_CMD_SETEXPR is not set
-# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_SLEEP is not set
 CONFIG_OF_EMBED=y
 CONFIG_ENV_OVERWRITE=y
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
diff --git a/configs/zynq_cse_nor_defconfig b/configs/zynq_cse_nor_defconfig
index 4e3196b..3e614df 100644
--- a/configs/zynq_cse_nor_defconfig
+++ b/configs/zynq_cse_nor_defconfig
@@ -44,7 +44,7 @@
 # CONFIG_CMD_ITEST is not set
 # CONFIG_CMD_SOURCE is not set
 # CONFIG_CMD_SETEXPR is not set
-# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_SLEEP is not set
 CONFIG_OF_EMBED=y
 CONFIG_ENV_OVERWRITE=y
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
diff --git a/configs/zynq_cse_qspi_defconfig b/configs/zynq_cse_qspi_defconfig
index fcef6fb..7cb1d61 100644
--- a/configs/zynq_cse_qspi_defconfig
+++ b/configs/zynq_cse_qspi_defconfig
@@ -53,7 +53,7 @@
 # CONFIG_CMD_ITEST is not set
 # CONFIG_CMD_SOURCE is not set
 # CONFIG_CMD_SETEXPR is not set
-# CONFIG_CMD_MISC is not set
+# CONFIG_CMD_SLEEP is not set
 CONFIG_OF_EMBED=y
 CONFIG_ENV_OVERWRITE=y
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
diff --git a/doc/develop/logging.rst b/doc/develop/logging.rst
index 28340a4..528280c 100644
--- a/doc/develop/logging.rst
+++ b/doc/develop/logging.rst
@@ -38,6 +38,9 @@
 * LOGL_DEBUG_CONTENT - Debug message showing full message content
 * LOGL_DEBUG_IO - Debug message showing hardware I/O access
 
+To continue a log message in a separate call of function log() use
+
+* LOGL_CONT - Use same log level as in previous call
 
 Logging category
 ----------------
@@ -56,6 +59,9 @@
 * LOGC_DT - Related to device tree control
 * LOGC_EFI - Related to EFI implementation
 
+To continue a log message in a separate call of function log() use
+
+* LOGC_CONT - Use same category as in previous call
 
 Enabling logging
 ----------------
diff --git a/doc/git-mailrc b/doc/git-mailrc
index 31595a7..bbca3a9 100644
--- a/doc/git-mailrc
+++ b/doc/git-mailrc
@@ -36,7 +36,7 @@
 alias mariosix       Mario Six <mario.six@gdsys.cc>
 alias masahiro       Masahiro Yamada <yamada.masahiro@socionext.com>
 alias mateusz        Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
-alias maxime         Maxime Ripard <maxime.ripard@free-electrons.com>
+alias maxime         Maxime Ripard <mripard@kernel.org>
 alias mbrugger       Matthias Brugger <mbrugger@suse.com>
 alias monstr         Michal Simek <monstr@monstr.eu>
 alias prom           Minkyu Kang <mk7.kang@samsung.com>
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 613669c..ed8a39c 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -64,6 +64,8 @@
 
 source "drivers/mtd/Kconfig"
 
+source "drivers/mux/Kconfig"
+
 source "drivers/net/Kconfig"
 
 source "drivers/nvme/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index 9eb5145..33f1d53 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -14,6 +14,7 @@
 obj-$(CONFIG_$(SPL_TPL_)LED) += led/
 obj-$(CONFIG_$(SPL_TPL_)MMC_SUPPORT) += mmc/
 obj-y += mtd/
+obj-$(CONFIG_$(SPL_)MULTIPLEXER) += mux/
 obj-$(CONFIG_$(SPL_TPL_)PCH_SUPPORT) += pch/
 obj-$(CONFIG_$(SPL_TPL_)PCI) += pci/
 obj-$(CONFIG_$(SPL_TPL_)PHY) += phy/
diff --git a/drivers/clk/kendryte/clk.c b/drivers/clk/kendryte/clk.c
index bb19696..4b95940 100644
--- a/drivers/clk/kendryte/clk.c
+++ b/drivers/clk/kendryte/clk.c
@@ -471,8 +471,7 @@
 cleanup_div:
 	free(div);
 cleanup_mux:
-	if (mux)
-		free(mux);
+	free(mux);
 	return comp;
 }
 
diff --git a/drivers/i2c/i2c-gpio.c b/drivers/i2c/i2c-gpio.c
index cfdeadc..381938c 100644
--- a/drivers/i2c/i2c-gpio.c
+++ b/drivers/i2c/i2c-gpio.c
@@ -18,8 +18,6 @@
 #define I2C_ACK		0
 #define I2C_NOACK	1
 
-DECLARE_GLOBAL_DATA_PTR;
-
 enum {
 	PIN_SDA = 0,
 	PIN_SCL,
@@ -334,8 +332,6 @@
 static int i2c_gpio_ofdata_to_platdata(struct udevice *dev)
 {
 	struct i2c_gpio_bus *bus = dev_get_priv(dev);
-	const void *blob = gd->fdt_blob;
-	int node = dev_of_offset(dev);
 	int ret;
 
 	ret = gpio_request_list_by_name(dev, "gpios", bus->gpios,
@@ -343,12 +339,12 @@
 	if (ret < 0)
 		goto error;
 
-	bus->udelay = fdtdec_get_int(blob, node, "i2c-gpio,delay-us",
-				     DEFAULT_UDELAY);
+	bus->udelay = dev_read_u32_default(dev, "i2c-gpio,delay-us",
+					   DEFAULT_UDELAY);
 
 	bus->get_sda = i2c_gpio_sda_get;
 	bus->set_sda = i2c_gpio_sda_set;
-	if (fdtdec_get_bool(blob, node, "i2c-gpio,scl-output-only"))
+	if (dev_read_bool(dev, "i2c-gpio,scl-output-only"))
 		bus->set_scl = i2c_gpio_scl_set_output_only;
 	else
 		bus->set_scl = i2c_gpio_scl_set;
diff --git a/drivers/mux/Kconfig b/drivers/mux/Kconfig
new file mode 100644
index 0000000..f15ee4f
--- /dev/null
+++ b/drivers/mux/Kconfig
@@ -0,0 +1,25 @@
+menu "Multiplexer drivers"
+
+config MULTIPLEXER
+	bool "Multiplexer Support"
+	depends on DM
+	help
+	 The mux framework is a minimalistic subsystem that handles multiplexer
+	 controllers. It provides the same API as Linux and mux drivers should
+	 be portable with a minimum effort.
+
+if MULTIPLEXER
+
+config MUX_MMIO
+	bool "MMIO register bitfield-controlled Multiplexer"
+	depends on MULTIPLEXER && SYSCON
+	help
+	  MMIO register bitfield-controlled Multiplexer controller.
+
+	  The driver builds multiplexer controllers for bitfields in a syscon
+	  register. For N bit wide bitfields, there will be 2^N possible
+	  multiplexer states.
+
+endif
+
+endmenu
diff --git a/drivers/mux/Makefile b/drivers/mux/Makefile
new file mode 100644
index 0000000..78ebf04
--- /dev/null
+++ b/drivers/mux/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# (C) Copyright 2019
+# Jean-Jacques Hiblot <jjhiblot@ti.com>
+
+obj-$(CONFIG_$(SPL_)MULTIPLEXER) += mux-uclass.o
+obj-$(CONFIG_$(SPL_)MUX_MMIO) += mmio.o
diff --git a/drivers/mux/mmio.c b/drivers/mux/mmio.c
new file mode 100644
index 0000000..b986850
--- /dev/null
+++ b/drivers/mux/mmio.c
@@ -0,0 +1,142 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MMIO register bitfield-controlled multiplexer driver
+ * Based on the linux mmio multiplexer driver
+ *
+ * Copyright (C) 2017 Pengutronix, Philipp Zabel <kernel@pengutronix.de>
+ * Copyright (C) 2019 Texas Instrument, Jean-jacques Hiblot <jjhiblot@ti.com>
+ */
+#include <common.h>
+#include <dm.h>
+#include <mux-internal.h>
+#include <regmap.h>
+#include <syscon.h>
+#include <dm/device.h>
+#include <dm/device_compat.h>
+#include <dm/read.h>
+#include <dm/devres.h>
+#include <dt-bindings/mux/mux.h>
+#include <linux/bitops.h>
+
+static int mux_mmio_set(struct mux_control *mux, int state)
+{
+	struct regmap_field **fields = dev_get_priv(mux->dev);
+
+	return regmap_field_write(fields[mux_control_get_index(mux)], state);
+}
+
+static const struct mux_control_ops mux_mmio_ops = {
+	.set = mux_mmio_set,
+};
+
+static const struct udevice_id mmio_mux_of_match[] = {
+	{ .compatible = "mmio-mux" },
+	{ /* sentinel */ },
+};
+
+static int mmio_mux_probe(struct udevice *dev)
+{
+	struct regmap_field **fields;
+	struct mux_chip *mux_chip = dev_get_uclass_priv(dev);
+	struct regmap *regmap;
+	u32 *mux_reg_masks;
+	u32 *idle_states;
+	int num_fields;
+	int ret;
+	int i;
+
+	regmap = syscon_node_to_regmap(dev_ofnode(dev->parent));
+	if (IS_ERR(regmap)) {
+		ret = PTR_ERR(regmap);
+		dev_err(dev, "failed to get regmap: %d\n", ret);
+		return ret;
+	}
+
+	num_fields = dev_read_size(dev, "mux-reg-masks");
+	if (num_fields < 0)
+		return log_msg_ret("mux-reg-masks missing", -EINVAL);
+
+	num_fields /= sizeof(u32);
+	if (num_fields == 0 || num_fields % 2)
+		ret = -EINVAL;
+	num_fields = num_fields / 2;
+
+	ret = mux_alloc_controllers(dev, num_fields);
+	if (ret < 0)
+		return log_msg_ret("mux_alloc_controllers", ret);
+
+	fields = devm_kmalloc(dev, num_fields * sizeof(*fields), __GFP_ZERO);
+	if (!fields)
+		return -ENOMEM;
+	dev->priv = fields;
+
+	mux_reg_masks = devm_kmalloc(dev, num_fields * 2 * sizeof(u32),
+				     __GFP_ZERO);
+	if (!mux_reg_masks)
+		return -ENOMEM;
+
+	ret = dev_read_u32_array(dev, "mux-reg-masks", mux_reg_masks,
+				 num_fields * 2);
+	if (ret < 0)
+		return log_msg_ret("mux-reg-masks read", ret);
+
+	idle_states = devm_kmalloc(dev, num_fields * sizeof(u32), __GFP_ZERO);
+	if (!idle_states)
+		return -ENOMEM;
+
+	ret = dev_read_u32_array(dev, "idle-states", idle_states, num_fields);
+	if (ret < 0) {
+		log_err("idle-states");
+		devm_kfree(dev, idle_states);
+		idle_states = NULL;
+	}
+
+	for (i = 0; i < num_fields; i++) {
+		struct mux_control *mux = &mux_chip->mux[i];
+		struct reg_field field;
+		u32 reg, mask;
+		int bits;
+
+		reg = mux_reg_masks[2 * i];
+		mask = mux_reg_masks[2 * i + 1];
+
+		field.reg = reg;
+		field.msb = fls(mask) - 1;
+		field.lsb = ffs(mask) - 1;
+
+		if (mask != GENMASK(field.msb, field.lsb))
+			return log_msg_ret("invalid mask", -EINVAL);
+
+		fields[i] = devm_regmap_field_alloc(dev, regmap, field);
+		if (IS_ERR(fields[i])) {
+			ret = PTR_ERR(fields[i]);
+			return log_msg_ret("regmap_field_alloc", ret);
+		}
+
+		bits = 1 + field.msb - field.lsb;
+		mux->states = 1 << bits;
+
+		if (!idle_states)
+			continue;
+
+		if (idle_states[i] != MUX_IDLE_AS_IS &&
+		    idle_states[i] >= mux->states)
+			return log_msg_ret("idle-states range", -EINVAL);
+
+		mux->idle_state = idle_states[i];
+	}
+
+	devm_kfree(dev, mux_reg_masks);
+	if (idle_states)
+		devm_kfree(dev, idle_states);
+
+	return 0;
+}
+
+U_BOOT_DRIVER(mmio_mux) = {
+	.name = "mmio-mux",
+	.id = UCLASS_MUX,
+	.of_match = mmio_mux_of_match,
+	.probe = mmio_mux_probe,
+	.ops = &mux_mmio_ops,
+};
diff --git a/drivers/mux/mux-uclass.c b/drivers/mux/mux-uclass.c
new file mode 100644
index 0000000..a35c3d9
--- /dev/null
+++ b/drivers/mux/mux-uclass.c
@@ -0,0 +1,335 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Multiplexer subsystem
+ *
+ * Based on the linux multiplexer framework
+ *
+ * Copyright (C) 2017 Axentia Technologies AB
+ * Author: Peter Rosin <peda@axentia.se>
+ *
+ * Copyright (C) 2017-2018 Texas Instruments Incorporated - http://www.ti.com/
+ * Jean-Jacques Hiblot <jjhiblot@ti.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <mux-internal.h>
+#include <dm/device-internal.h>
+#include <dm/device_compat.h>
+#include <dm/devres.h>
+#include <dt-bindings/mux/mux.h>
+#include <linux/bug.h>
+
+/*
+ * The idle-as-is "state" is not an actual state that may be selected, it
+ * only implies that the state should not be changed. So, use that state
+ * as indication that the cached state of the multiplexer is unknown.
+ */
+#define MUX_CACHE_UNKNOWN MUX_IDLE_AS_IS
+
+/**
+ * mux_control_ops() - Get the mux_control ops.
+ * @dev: The client device.
+ *
+ * Return: A pointer to the 'mux_control_ops' of the device.
+ */
+static inline const struct mux_control_ops *mux_dev_ops(struct udevice *dev)
+{
+	return (const struct mux_control_ops *)dev->driver->ops;
+}
+
+/**
+ * mux_control_set() - Set the state of the given mux controller.
+ * @mux: A multiplexer control
+ * @state: The new requested state.
+ *
+ * Return: 0 if OK, or a negative error code.
+ */
+static int mux_control_set(struct mux_control *mux, int state)
+{
+	int ret = mux_dev_ops(mux->dev)->set(mux, state);
+
+	mux->cached_state = ret < 0 ? MUX_CACHE_UNKNOWN : state;
+
+	return ret;
+}
+
+unsigned int mux_control_states(struct mux_control *mux)
+{
+	return mux->states;
+}
+
+/**
+ * __mux_control_select() - Select the given multiplexer state.
+ * @mux: The mux-control to request a change of state from.
+ * @state: The new requested state.
+ *
+ * Try to set the mux to the requested state. If not, try to revert if
+ * appropriate.
+ */
+static int __mux_control_select(struct mux_control *mux, int state)
+{
+	int ret;
+
+	if (WARN_ON(state < 0 || state >= mux->states))
+		return -EINVAL;
+
+	if (mux->cached_state == state)
+		return 0;
+
+	ret = mux_control_set(mux, state);
+	if (ret >= 0)
+		return 0;
+
+	/* The mux update failed, try to revert if appropriate... */
+	if (mux->idle_state != MUX_IDLE_AS_IS)
+		mux_control_set(mux, mux->idle_state);
+
+	return ret;
+}
+
+int mux_control_select(struct mux_control *mux, unsigned int state)
+{
+	int ret;
+
+	if (mux->in_use)
+		return -EBUSY;
+
+	ret = __mux_control_select(mux, state);
+
+	if (ret < 0)
+		return ret;
+
+	mux->in_use = true;
+
+	return 0;
+}
+
+int mux_control_deselect(struct mux_control *mux)
+{
+	int ret = 0;
+
+	if (mux->idle_state != MUX_IDLE_AS_IS &&
+	    mux->idle_state != mux->cached_state)
+		ret = mux_control_set(mux, mux->idle_state);
+
+	mux->in_use = false;
+
+	return ret;
+}
+
+static int mux_of_xlate_default(struct mux_chip *mux_chip,
+				struct ofnode_phandle_args *args,
+				struct mux_control **muxp)
+{
+	struct mux_control *mux;
+	int id;
+
+	log_debug("%s(muxp=%p)\n", __func__, muxp);
+
+	if (args->args_count > 1) {
+		debug("Invaild args_count: %d\n", args->args_count);
+		return -EINVAL;
+	}
+
+	if (args->args_count)
+		id = args->args[0];
+	else
+		id = 0;
+
+	if (id >= mux_chip->controllers) {
+		pr_err("bad mux controller %u specified in %s\n",
+			id, ofnode_get_name(args->node));
+		return -ERANGE;
+	}
+
+	mux = &mux_chip->mux[id];
+	mux->id = id;
+	*muxp = mux;
+	return 0;
+}
+
+/**
+ * mux_get_by_indexed_prop() - Get a mux control by integer index
+ * @dev: The client device.
+ * @prop_name: Name of the device tree property.
+ * @index: The index of the mux to get
+ * @mux: A pointer to the 'mux_control' struct to initialize.
+ *
+ * Return: 0 of OK, -errno otherwise.
+ */
+static int mux_get_by_indexed_prop(struct udevice *dev, const char *prop_name,
+				   int index, struct mux_control **mux)
+{
+	int ret;
+	struct ofnode_phandle_args args;
+	struct udevice *dev_mux;
+	const struct mux_control_ops *ops;
+	struct mux_chip *mux_chip;
+
+	log_debug("%s(dev=%p, index=%d, mux=%p)\n", __func__, dev, index, mux);
+
+	ret = dev_read_phandle_with_args(dev, prop_name, "#mux-control-cells",
+					 0, index, &args);
+	if (ret) {
+		debug("%s: fdtdec_parse_phandle_with_args failed: err=%d\n",
+		      __func__, ret);
+		return ret;
+	}
+
+	ret = uclass_get_device_by_ofnode(UCLASS_MUX, args.node, &dev_mux);
+	if (ret) {
+		debug("%s: uclass_get_device_by_ofnode failed: err=%d\n",
+		      __func__, ret);
+		return ret;
+	}
+
+	mux_chip = dev_get_uclass_priv(dev_mux);
+
+	ops = mux_dev_ops(dev_mux);
+	if (ops->of_xlate)
+		ret = ops->of_xlate(mux_chip, &args, mux);
+	else
+		ret = mux_of_xlate_default(mux_chip, &args, mux);
+	if (ret) {
+		debug("of_xlate() failed: %d\n", ret);
+		return ret;
+	}
+	(*mux)->dev = dev_mux;
+
+	return 0;
+}
+
+int mux_get_by_index(struct udevice *dev, int index, struct mux_control **mux)
+{
+	return mux_get_by_indexed_prop(dev, "mux-controls", index, mux);
+}
+
+int mux_control_get(struct udevice *dev, const char *name,
+		    struct mux_control **mux)
+{
+	int index;
+
+	debug("%s(dev=%p, name=%s, mux=%p)\n", __func__, dev, name, mux);
+
+	index = dev_read_stringlist_search(dev, "mux-control-names", name);
+	if (index < 0) {
+		debug("fdt_stringlist_search() failed: %d\n", index);
+		return index;
+	}
+
+	return mux_get_by_index(dev, index, mux);
+}
+
+void mux_control_put(struct mux_control *mux)
+{
+	mux_control_deselect(mux);
+}
+
+/**
+ * devm_mux_control_release() - Release the given managed mux.
+ * @dev: The client device.
+ * @res: Pointer to the mux to be released.
+ *
+ * This function is called by devres to release the mux. It reverses the
+ * effects of mux_control_get().
+ */
+static void devm_mux_control_release(struct udevice *dev, void *res)
+{
+	mux_control_put(*(struct mux_control **)res);
+}
+
+struct mux_control *devm_mux_control_get(struct udevice *dev, const char *id)
+{
+	int rc;
+	struct mux_control **mux;
+
+	mux = devres_alloc(devm_mux_control_release,
+			   sizeof(struct mux_control *), __GFP_ZERO);
+	if (unlikely(!mux))
+		return ERR_PTR(-ENOMEM);
+
+	rc = mux_control_get(dev, id, mux);
+	if (rc)
+		return ERR_PTR(rc);
+
+	devres_add(dev, mux);
+	return *mux;
+}
+
+int mux_alloc_controllers(struct udevice *dev, unsigned int controllers)
+{
+	int i;
+	struct mux_chip *mux_chip = dev_get_uclass_priv(dev);
+
+	mux_chip->mux = devm_kmalloc(dev,
+				     sizeof(struct mux_control) * controllers,
+				     __GFP_ZERO);
+	if (!mux_chip->mux)
+		return -ENOMEM;
+
+	mux_chip->controllers = controllers;
+
+	for (i = 0; i < mux_chip->controllers; ++i) {
+		struct mux_control *mux = &mux_chip->mux[i];
+
+		mux->dev = dev;
+		mux->cached_state = MUX_CACHE_UNKNOWN;
+		mux->idle_state = MUX_IDLE_AS_IS;
+		mux->in_use = false;
+		mux->id = i;
+	}
+
+	return 0;
+}
+
+static int mux_uclass_post_probe(struct udevice *dev)
+{
+	int i, ret;
+	struct mux_chip *mux_chip = dev_get_uclass_priv(dev);
+
+	/* Set all mux controllers to their idle state. */
+	for (i = 0; i < mux_chip->controllers; ++i) {
+		struct mux_control *mux = &mux_chip->mux[i];
+
+		if (mux->idle_state == mux->cached_state)
+			continue;
+
+		ret = mux_control_set(mux, mux->idle_state);
+		if (ret < 0) {
+			dev_err(dev, "unable to set idle state\n");
+			return ret;
+		}
+	}
+	return 0;
+}
+
+int dm_mux_init(void)
+{
+	struct uclass *uc;
+	struct udevice *dev;
+	int ret;
+
+	ret = uclass_get(UCLASS_MUX, &uc);
+	if (ret < 0) {
+		log_debug("unable to get MUX uclass\n");
+		return ret;
+	}
+	uclass_foreach_dev(dev, uc) {
+		if (dev_read_bool(dev, "u-boot,mux-autoprobe")) {
+			ret = device_probe(dev);
+			if (ret)
+				log_debug("unable to probe device %s\n",
+					  dev->name);
+		}
+	}
+
+	return 0;
+}
+
+UCLASS_DRIVER(mux) = {
+	.id		= UCLASS_MUX,
+	.name		= "mux",
+	.post_probe	= mux_uclass_post_probe,
+	.per_device_auto_alloc_size = sizeof(struct mux_chip),
+};
diff --git a/drivers/net/sun8i_emac.c b/drivers/net/sun8i_emac.c
index 1dae81c..4524604 100644
--- a/drivers/net/sun8i_emac.c
+++ b/drivers/net/sun8i_emac.c
@@ -29,6 +29,7 @@
 #include <net.h>
 #include <reset.h>
 #include <dt-bindings/pinctrl/sun4i-a10.h>
+#include <wait_bit.h>
 #if CONFIG_IS_ENABLED(DM_GPIO)
 #include <asm-generic/gpio.h>
 #endif
@@ -40,6 +41,11 @@
 #define MDIO_CMD_MII_PHY_REG_ADDR_SHIFT	4
 #define MDIO_CMD_MII_PHY_ADDR_MASK	0x0001f000
 #define MDIO_CMD_MII_PHY_ADDR_SHIFT	12
+#define MDIO_CMD_MII_CLK_CSR_DIV_16	0x0
+#define MDIO_CMD_MII_CLK_CSR_DIV_32	0x1
+#define MDIO_CMD_MII_CLK_CSR_DIV_64	0x2
+#define MDIO_CMD_MII_CLK_CSR_DIV_128	0x3
+#define MDIO_CMD_MII_CLK_CSR_SHIFT	20
 
 #define CONFIG_TX_DESCR_NUM	32
 #define CONFIG_RX_DESCR_NUM	32
@@ -84,15 +90,32 @@
 
 /* H3/A64 EMAC Register's offset */
 #define EMAC_CTL0		0x00
+#define EMAC_CTL0_FULL_DUPLEX		BIT(0)
+#define EMAC_CTL0_SPEED_MASK		GENMASK(3, 2)
+#define EMAC_CTL0_SPEED_10		(0x2 << 2)
+#define EMAC_CTL0_SPEED_100		(0x3 << 2)
+#define EMAC_CTL0_SPEED_1000		(0x0 << 2)
 #define EMAC_CTL1		0x04
+#define EMAC_CTL1_SOFT_RST		BIT(0)
+#define EMAC_CTL1_BURST_LEN_SHIFT	24
 #define EMAC_INT_STA		0x08
 #define EMAC_INT_EN		0x0c
 #define EMAC_TX_CTL0		0x10
+#define	EMAC_TX_CTL0_TX_EN		BIT(31)
 #define EMAC_TX_CTL1		0x14
+#define	EMAC_TX_CTL1_TX_MD		BIT(1)
+#define	EMAC_TX_CTL1_TX_DMA_EN		BIT(30)
+#define	EMAC_TX_CTL1_TX_DMA_START	BIT(31)
 #define EMAC_TX_FLOW_CTL	0x1c
 #define EMAC_TX_DMA_DESC	0x20
 #define EMAC_RX_CTL0		0x24
+#define	EMAC_RX_CTL0_RX_EN		BIT(31)
 #define EMAC_RX_CTL1		0x28
+#define	EMAC_RX_CTL1_RX_MD		BIT(1)
+#define	EMAC_RX_CTL1_RX_RUNT_FRM	BIT(2)
+#define	EMAC_RX_CTL1_RX_ERR_FRM		BIT(3)
+#define	EMAC_RX_CTL1_RX_DMA_EN		BIT(30)
+#define	EMAC_RX_CTL1_RX_DMA_START	BIT(31)
 #define EMAC_RX_DMA_DESC	0x34
 #define EMAC_MII_CMD		0x48
 #define EMAC_MII_DATA		0x4c
@@ -104,6 +127,13 @@
 #define EMAC_RX_DMA_STA		0xc0
 #define EMAC_RX_CUR_DESC	0xc4
 
+#define EMAC_DESC_OWN_DMA	BIT(31)
+#define EMAC_DESC_LAST_DESC	BIT(30)
+#define EMAC_DESC_FIRST_DESC	BIT(29)
+#define EMAC_DESC_CHAIN_SECOND	BIT(24)
+
+#define EMAC_DESC_RX_ERROR_MASK	0x400068db
+
 DECLARE_GLOBAL_DATA_PTR;
 
 enum emac_variant {
@@ -116,7 +146,7 @@
 
 struct emac_dma_desc {
 	u32 status;
-	u32 st;
+	u32 ctl_size;
 	u32 buf_addr;
 	u32 next;
 } __aligned(ARCH_DMA_MINALIGN);
@@ -166,32 +196,31 @@
 {
 	struct udevice *dev = bus->priv;
 	struct emac_eth_dev *priv = dev_get_priv(dev);
-	ulong start;
-	u32 miiaddr = 0;
-	int timeout = CONFIG_MDIO_TIMEOUT;
+	u32 mii_cmd;
+	int ret;
 
-	miiaddr &= ~MDIO_CMD_MII_WRITE;
-	miiaddr &= ~MDIO_CMD_MII_PHY_REG_ADDR_MASK;
-	miiaddr |= (reg << MDIO_CMD_MII_PHY_REG_ADDR_SHIFT) &
+	mii_cmd = (reg << MDIO_CMD_MII_PHY_REG_ADDR_SHIFT) &
 		MDIO_CMD_MII_PHY_REG_ADDR_MASK;
-
-	miiaddr &= ~MDIO_CMD_MII_PHY_ADDR_MASK;
-
-	miiaddr |= (addr << MDIO_CMD_MII_PHY_ADDR_SHIFT) &
+	mii_cmd |= (addr << MDIO_CMD_MII_PHY_ADDR_SHIFT) &
 		MDIO_CMD_MII_PHY_ADDR_MASK;
 
-	miiaddr |= MDIO_CMD_MII_BUSY;
+	/*
+	 * The EMAC clock is either 200 or 300 MHz, so we need a divider
+	 * of 128 to get the MDIO frequency below the required 2.5 MHz.
+	 */
+	mii_cmd |= MDIO_CMD_MII_CLK_CSR_DIV_128 << MDIO_CMD_MII_CLK_CSR_SHIFT;
 
-	writel(miiaddr, priv->mac_reg + EMAC_MII_CMD);
+	mii_cmd |= MDIO_CMD_MII_BUSY;
 
-	start = get_timer(0);
-	while (get_timer(start) < timeout) {
-		if (!(readl(priv->mac_reg + EMAC_MII_CMD) & MDIO_CMD_MII_BUSY))
-			return readl(priv->mac_reg + EMAC_MII_DATA);
-		udelay(10);
-	};
+	writel(mii_cmd, priv->mac_reg + EMAC_MII_CMD);
 
-	return -1;
+	ret = wait_for_bit_le32(priv->mac_reg + EMAC_MII_CMD,
+				MDIO_CMD_MII_BUSY, false,
+				CONFIG_MDIO_TIMEOUT, true);
+	if (ret < 0)
+		return ret;
+
+	return readl(priv->mac_reg + EMAC_MII_DATA);
 }
 
 static int sun8i_mdio_write(struct mii_dev *bus, int addr, int devad, int reg,
@@ -199,39 +228,35 @@
 {
 	struct udevice *dev = bus->priv;
 	struct emac_eth_dev *priv = dev_get_priv(dev);
-	ulong start;
-	u32 miiaddr = 0;
-	int ret = -1, timeout = CONFIG_MDIO_TIMEOUT;
+	u32 mii_cmd;
 
-	miiaddr &= ~MDIO_CMD_MII_PHY_REG_ADDR_MASK;
-	miiaddr |= (reg << MDIO_CMD_MII_PHY_REG_ADDR_SHIFT) &
+	mii_cmd = (reg << MDIO_CMD_MII_PHY_REG_ADDR_SHIFT) &
 		MDIO_CMD_MII_PHY_REG_ADDR_MASK;
-
-	miiaddr &= ~MDIO_CMD_MII_PHY_ADDR_MASK;
-	miiaddr |= (addr << MDIO_CMD_MII_PHY_ADDR_SHIFT) &
+	mii_cmd |= (addr << MDIO_CMD_MII_PHY_ADDR_SHIFT) &
 		MDIO_CMD_MII_PHY_ADDR_MASK;
 
-	miiaddr |= MDIO_CMD_MII_WRITE;
-	miiaddr |= MDIO_CMD_MII_BUSY;
+	/*
+	 * The EMAC clock is either 200 or 300 MHz, so we need a divider
+	 * of 128 to get the MDIO frequency below the required 2.5 MHz.
+	 */
+	mii_cmd |= MDIO_CMD_MII_CLK_CSR_DIV_128 << MDIO_CMD_MII_CLK_CSR_SHIFT;
+
+	mii_cmd |= MDIO_CMD_MII_WRITE;
+	mii_cmd |= MDIO_CMD_MII_BUSY;
 
 	writel(val, priv->mac_reg + EMAC_MII_DATA);
-	writel(miiaddr, priv->mac_reg + EMAC_MII_CMD);
+	writel(mii_cmd, priv->mac_reg + EMAC_MII_CMD);
 
-	start = get_timer(0);
-	while (get_timer(start) < timeout) {
-		if (!(readl(priv->mac_reg + EMAC_MII_CMD) &
-					MDIO_CMD_MII_BUSY)) {
-			ret = 0;
-			break;
-		}
-		udelay(10);
-	};
-
-	return ret;
+	return wait_for_bit_le32(priv->mac_reg + EMAC_MII_CMD,
+				 MDIO_CMD_MII_BUSY, false,
+				 CONFIG_MDIO_TIMEOUT, true);
 }
 
-static int _sun8i_write_hwaddr(struct emac_eth_dev *priv, u8 *mac_id)
+static int sun8i_eth_write_hwaddr(struct udevice *dev)
 {
+	struct emac_eth_dev *priv = dev_get_priv(dev);
+	struct eth_pdata *pdata = dev_get_platdata(dev);
+	uchar *mac_id = pdata->enetaddr;
 	u32 macid_lo, macid_hi;
 
 	macid_lo = mac_id[0] + (mac_id[1] << 8) + (mac_id[2] << 16) +
@@ -252,21 +277,21 @@
 	v = readl(priv->mac_reg + EMAC_CTL0);
 
 	if (phydev->duplex)
-		v |= BIT(0);
+		v |= EMAC_CTL0_FULL_DUPLEX;
 	else
-		v &= ~BIT(0);
+		v &= ~EMAC_CTL0_FULL_DUPLEX;
 
-	v &= ~0x0C;
+	v &= ~EMAC_CTL0_SPEED_MASK;
 
 	switch (phydev->speed) {
 	case 1000:
+		v |= EMAC_CTL0_SPEED_1000;
 		break;
 	case 100:
-		v |= BIT(2);
-		v |= BIT(3);
+		v |= EMAC_CTL0_SPEED_100;
 		break;
 	case 10:
-		v |= BIT(3);
+		v |= EMAC_CTL0_SPEED_10;
 		break;
 	}
 	writel(v, priv->mac_reg + EMAC_CTL0);
@@ -372,24 +397,36 @@
 	return 0;
 }
 
+#define cache_clean_descriptor(desc)					\
+	flush_dcache_range((uintptr_t)(desc), 				\
+			   (uintptr_t)(desc) + sizeof(struct emac_dma_desc))
+
+#define cache_inv_descriptor(desc)					\
+	invalidate_dcache_range((uintptr_t)(desc),			\
+			       (uintptr_t)(desc) + sizeof(struct emac_dma_desc))
+
 static void rx_descs_init(struct emac_eth_dev *priv)
 {
 	struct emac_dma_desc *desc_table_p = &priv->rx_chain[0];
 	char *rxbuffs = &priv->rxbuffer[0];
 	struct emac_dma_desc *desc_p;
-	u32 idx;
+	int i;
 
-	/* flush Rx buffers */
-	flush_dcache_range((uintptr_t)rxbuffs, (ulong)rxbuffs +
-			RX_TOTAL_BUFSIZE);
+	/*
+	 * Make sure we don't have dirty cache lines around, which could
+	 * be cleaned to DRAM *after* the MAC has already written data to it.
+	 */
+	invalidate_dcache_range((uintptr_t)desc_table_p,
+			      (uintptr_t)desc_table_p + sizeof(priv->rx_chain));
+	invalidate_dcache_range((uintptr_t)rxbuffs,
+				(uintptr_t)rxbuffs + sizeof(priv->rxbuffer));
 
-	for (idx = 0; idx < CONFIG_RX_DESCR_NUM; idx++) {
-		desc_p = &desc_table_p[idx];
-		desc_p->buf_addr = (uintptr_t)&rxbuffs[idx * CONFIG_ETH_BUFSIZE]
-			;
-		desc_p->next = (uintptr_t)&desc_table_p[idx + 1];
-		desc_p->st |= CONFIG_ETH_RXSIZE;
-		desc_p->status = BIT(31);
+	for (i = 0; i < CONFIG_RX_DESCR_NUM; i++) {
+		desc_p = &desc_table_p[i];
+		desc_p->buf_addr = (uintptr_t)&rxbuffs[i * CONFIG_ETH_BUFSIZE];
+		desc_p->next = (uintptr_t)&desc_table_p[i + 1];
+		desc_p->ctl_size = CONFIG_ETH_RXSIZE;
+		desc_p->status = EMAC_DESC_OWN_DMA;
 	}
 
 	/* Correcting the last pointer of the chain */
@@ -408,87 +445,74 @@
 	struct emac_dma_desc *desc_table_p = &priv->tx_chain[0];
 	char *txbuffs = &priv->txbuffer[0];
 	struct emac_dma_desc *desc_p;
-	u32 idx;
+	int i;
 
-	for (idx = 0; idx < CONFIG_TX_DESCR_NUM; idx++) {
-		desc_p = &desc_table_p[idx];
-		desc_p->buf_addr = (uintptr_t)&txbuffs[idx * CONFIG_ETH_BUFSIZE]
-			;
-		desc_p->next = (uintptr_t)&desc_table_p[idx + 1];
-		desc_p->status = (1 << 31);
-		desc_p->st = 0;
+	for (i = 0; i < CONFIG_TX_DESCR_NUM; i++) {
+		desc_p = &desc_table_p[i];
+		desc_p->buf_addr = (uintptr_t)&txbuffs[i * CONFIG_ETH_BUFSIZE];
+		desc_p->next = (uintptr_t)&desc_table_p[i + 1];
+		desc_p->ctl_size = 0;
+		desc_p->status = 0;
 	}
 
 	/* Correcting the last pointer of the chain */
 	desc_p->next =  (uintptr_t)&desc_table_p[0];
 
-	/* Flush all Tx buffer descriptors */
-	flush_dcache_range((uintptr_t)priv->tx_chain,
-			   (uintptr_t)priv->tx_chain +
-			sizeof(priv->tx_chain));
+	/* Flush the first TX buffer descriptor we will tell the MAC about. */
+	cache_clean_descriptor(desc_table_p);
 
 	writel((uintptr_t)&desc_table_p[0], priv->mac_reg + EMAC_TX_DMA_DESC);
 	priv->tx_currdescnum = 0;
 }
 
-static int _sun8i_emac_eth_init(struct emac_eth_dev *priv, u8 *enetaddr)
+static int sun8i_emac_eth_start(struct udevice *dev)
 {
-	u32 reg, v;
-	int timeout = 100;
+	struct emac_eth_dev *priv = dev_get_priv(dev);
+	int ret;
 
-	reg = readl((priv->mac_reg + EMAC_CTL1));
-
-	if (!(reg & 0x1)) {
-		/* Soft reset MAC */
-		setbits_le32((priv->mac_reg + EMAC_CTL1), 0x1);
-		do {
-			reg = readl(priv->mac_reg + EMAC_CTL1);
-		} while ((reg & 0x01) != 0 &&  (--timeout));
-		if (!timeout) {
-			printf("%s: Timeout\n", __func__);
-			return -1;
-		}
+	/* Soft reset MAC */
+	writel(EMAC_CTL1_SOFT_RST, priv->mac_reg + EMAC_CTL1);
+	ret = wait_for_bit_le32(priv->mac_reg + EMAC_CTL1,
+				EMAC_CTL1_SOFT_RST, false, 10, true);
+	if (ret) {
+		printf("%s: Timeout\n", __func__);
+		return ret;
 	}
 
 	/* Rewrite mac address after reset */
-	_sun8i_write_hwaddr(priv, enetaddr);
+	sun8i_eth_write_hwaddr(dev);
 
-	v = readl(priv->mac_reg + EMAC_TX_CTL1);
-	/* TX_MD Transmission starts after a full frame located in TX DMA FIFO*/
-	v |= BIT(1);
-	writel(v, priv->mac_reg + EMAC_TX_CTL1);
+	/* transmission starts after the full frame arrived in TX DMA FIFO */
+	setbits_le32(priv->mac_reg + EMAC_TX_CTL1, EMAC_TX_CTL1_TX_MD);
 
-	v = readl(priv->mac_reg + EMAC_RX_CTL1);
-	/* RX_MD RX DMA reads data from RX DMA FIFO to host memory after a
+	/*
+	 * RX DMA reads data from RX DMA FIFO to host memory after a
 	 * complete frame has been written to RX DMA FIFO
 	 */
-	v |= BIT(1);
-	writel(v, priv->mac_reg + EMAC_RX_CTL1);
+	setbits_le32(priv->mac_reg + EMAC_RX_CTL1, EMAC_RX_CTL1_RX_MD);
 
-	/* DMA */
-	writel(8 << 24, priv->mac_reg + EMAC_CTL1);
+	/* DMA burst length */
+	writel(8 << EMAC_CTL1_BURST_LEN_SHIFT, priv->mac_reg + EMAC_CTL1);
 
 	/* Initialize rx/tx descriptors */
 	rx_descs_init(priv);
 	tx_descs_init(priv);
 
 	/* PHY Start Up */
-	phy_startup(priv->phydev);
+	ret = phy_startup(priv->phydev);
+	if (ret)
+		return ret;
 
 	sun8i_adjust_link(priv, priv->phydev);
 
-	/* Start RX DMA */
-	v = readl(priv->mac_reg + EMAC_RX_CTL1);
-	v |= BIT(30);
-	writel(v, priv->mac_reg + EMAC_RX_CTL1);
-	/* Start TX DMA */
-	v = readl(priv->mac_reg + EMAC_TX_CTL1);
-	v |= BIT(30);
-	writel(v, priv->mac_reg + EMAC_TX_CTL1);
+	/* Start RX/TX DMA */
+	setbits_le32(priv->mac_reg + EMAC_RX_CTL1, EMAC_RX_CTL1_RX_DMA_EN |
+		     EMAC_RX_CTL1_RX_ERR_FRM | EMAC_RX_CTL1_RX_RUNT_FRM);
+	setbits_le32(priv->mac_reg + EMAC_TX_CTL1, EMAC_TX_CTL1_TX_DMA_EN);
 
 	/* Enable RX/TX */
-	setbits_le32(priv->mac_reg + EMAC_RX_CTL0, BIT(31));
-	setbits_le32(priv->mac_reg + EMAC_TX_CTL0, BIT(31));
+	setbits_le32(priv->mac_reg + EMAC_RX_CTL0, EMAC_RX_CTL0_RX_EN);
+	setbits_le32(priv->mac_reg + EMAC_TX_CTL0, EMAC_TX_CTL0_TX_EN);
 
 	return 0;
 }
@@ -558,88 +582,71 @@
 	return 0;
 }
 
-static int _sun8i_eth_recv(struct emac_eth_dev *priv, uchar **packetp)
+static int sun8i_emac_eth_recv(struct udevice *dev, int flags, uchar **packetp)
 {
+	struct emac_eth_dev *priv = dev_get_priv(dev);
 	u32 status, desc_num = priv->rx_currdescnum;
 	struct emac_dma_desc *desc_p = &priv->rx_chain[desc_num];
-	int length = -EAGAIN;
-	int good_packet = 1;
-	uintptr_t desc_start = (uintptr_t)desc_p;
-	uintptr_t desc_end = desc_start +
-		roundup(sizeof(*desc_p), ARCH_DMA_MINALIGN);
-
-	ulong data_start = (uintptr_t)desc_p->buf_addr;
-	ulong data_end;
+	uintptr_t data_start = (uintptr_t)desc_p->buf_addr;
+	int length;
 
 	/* Invalidate entire buffer descriptor */
-	invalidate_dcache_range(desc_start, desc_end);
+	cache_inv_descriptor(desc_p);
 
 	status = desc_p->status;
 
 	/* Check for DMA own bit */
-	if (!(status & BIT(31))) {
-		length = (desc_p->status >> 16) & 0x3FFF;
+	if (status & EMAC_DESC_OWN_DMA)
+		return -EAGAIN;
 
-		if (length < 0x40) {
-			good_packet = 0;
-			debug("RX: Bad Packet (runt)\n");
-		}
+	length = (status >> 16) & 0x3fff;
 
-		data_end = data_start + length;
-		/* Invalidate received data */
-		invalidate_dcache_range(rounddown(data_start,
-						  ARCH_DMA_MINALIGN),
-					roundup(data_end,
-						ARCH_DMA_MINALIGN));
-		if (good_packet) {
-			if (length > CONFIG_ETH_RXSIZE) {
-				printf("Received packet is too big (len=%d)\n",
-				       length);
-				return -EMSGSIZE;
-			}
-			*packetp = (uchar *)(ulong)desc_p->buf_addr;
-			return length;
-		}
+	/* make sure we read from DRAM, not our cache */
+	invalidate_dcache_range(data_start,
+				data_start + roundup(length, ARCH_DMA_MINALIGN));
+
+	if (status & EMAC_DESC_RX_ERROR_MASK) {
+		debug("RX: packet error: 0x%x\n",
+		      status & EMAC_DESC_RX_ERROR_MASK);
+		return 0;
 	}
+	if (length < 0x40) {
+		debug("RX: Bad Packet (runt)\n");
+		return 0;
+	}
+
+	if (length > CONFIG_ETH_RXSIZE) {
+		debug("RX: Too large packet (%d bytes)\n", length);
+		return 0;
+	}
+
+	*packetp = (uchar *)(ulong)desc_p->buf_addr;
 
 	return length;
 }
 
-static int _sun8i_emac_eth_send(struct emac_eth_dev *priv, void *packet,
-				int len)
+static int sun8i_emac_eth_send(struct udevice *dev, void *packet, int length)
 {
-	u32 v, desc_num = priv->tx_currdescnum;
+	struct emac_eth_dev *priv = dev_get_priv(dev);
+	u32 desc_num = priv->tx_currdescnum;
 	struct emac_dma_desc *desc_p = &priv->tx_chain[desc_num];
-	uintptr_t desc_start = (uintptr_t)desc_p;
-	uintptr_t desc_end = desc_start +
-		roundup(sizeof(*desc_p), ARCH_DMA_MINALIGN);
-
 	uintptr_t data_start = (uintptr_t)desc_p->buf_addr;
 	uintptr_t data_end = data_start +
-		roundup(len, ARCH_DMA_MINALIGN);
+		roundup(length, ARCH_DMA_MINALIGN);
 
-	/* Invalidate entire buffer descriptor */
-	invalidate_dcache_range(desc_start, desc_end);
+	desc_p->ctl_size = length | EMAC_DESC_CHAIN_SECOND;
 
-	desc_p->st = len;
-	/* Mandatory undocumented bit */
-	desc_p->st |= BIT(24);
-
-	memcpy((void *)data_start, packet, len);
+	memcpy((void *)data_start, packet, length);
 
 	/* Flush data to be sent */
 	flush_dcache_range(data_start, data_end);
 
-	/* frame end */
-	desc_p->st |= BIT(30);
-	desc_p->st |= BIT(31);
+	/* frame begin and end */
+	desc_p->ctl_size |= EMAC_DESC_LAST_DESC | EMAC_DESC_FIRST_DESC;
+	desc_p->status = EMAC_DESC_OWN_DMA;
 
-	/*frame begin */
-	desc_p->st |= BIT(29);
-	desc_p->status = BIT(31);
-
-	/*Descriptors st and status field has changed, so FLUSH it */
-	flush_dcache_range(desc_start, desc_end);
+	/* make sure the MAC reads the actual data from DRAM */
+	cache_clean_descriptor(desc_p);
 
 	/* Move to next Descriptor and wrap around */
 	if (++desc_num >= CONFIG_TX_DESCR_NUM)
@@ -647,22 +654,16 @@
 	priv->tx_currdescnum = desc_num;
 
 	/* Start the DMA */
-	v = readl(priv->mac_reg + EMAC_TX_CTL1);
-	v |= BIT(31);/* mandatory */
-	v |= BIT(30);/* mandatory */
-	writel(v, priv->mac_reg + EMAC_TX_CTL1);
+	setbits_le32(priv->mac_reg + EMAC_TX_CTL1, EMAC_TX_CTL1_TX_DMA_START);
+
+	/*
+	 * Since we copied the data above, we return here without waiting
+	 * for the packet to be actually send out.
+	 */
 
 	return 0;
 }
 
-static int sun8i_eth_write_hwaddr(struct udevice *dev)
-{
-	struct eth_pdata *pdata = dev_get_platdata(dev);
-	struct emac_eth_dev *priv = dev_get_priv(dev);
-
-	return _sun8i_write_hwaddr(priv, pdata->enetaddr);
-}
-
 static int sun8i_emac_board_setup(struct udevice *dev,
 				  struct emac_eth_dev *priv)
 {
@@ -760,40 +761,18 @@
 	return  mdio_register(bus);
 }
 
-static int sun8i_emac_eth_start(struct udevice *dev)
-{
-	struct eth_pdata *pdata = dev_get_platdata(dev);
-
-	return _sun8i_emac_eth_init(dev->priv, pdata->enetaddr);
-}
-
-static int sun8i_emac_eth_send(struct udevice *dev, void *packet, int length)
+static int sun8i_eth_free_pkt(struct udevice *dev, uchar *packet,
+			      int length)
 {
 	struct emac_eth_dev *priv = dev_get_priv(dev);
-
-	return _sun8i_emac_eth_send(priv, packet, length);
-}
-
-static int sun8i_emac_eth_recv(struct udevice *dev, int flags, uchar **packetp)
-{
-	struct emac_eth_dev *priv = dev_get_priv(dev);
-
-	return _sun8i_eth_recv(priv, packetp);
-}
-
-static int _sun8i_free_pkt(struct emac_eth_dev *priv)
-{
 	u32 desc_num = priv->rx_currdescnum;
 	struct emac_dma_desc *desc_p = &priv->rx_chain[desc_num];
-	uintptr_t desc_start = (uintptr_t)desc_p;
-	uintptr_t desc_end = desc_start +
-		roundup(sizeof(u32), ARCH_DMA_MINALIGN);
 
-	/* Make the current descriptor valid again */
-	desc_p->status |= BIT(31);
+	/* give the current descriptor back to the MAC */
+	desc_p->status |= EMAC_DESC_OWN_DMA;
 
 	/* Flush Status field of descriptor */
-	flush_dcache_range(desc_start, desc_end);
+	cache_clean_descriptor(desc_p);
 
 	/* Move to next desc and wrap-around condition. */
 	if (++desc_num >= CONFIG_RX_DESCR_NUM)
@@ -803,24 +782,17 @@
 	return 0;
 }
 
-static int sun8i_eth_free_pkt(struct udevice *dev, uchar *packet,
-			      int length)
-{
-	struct emac_eth_dev *priv = dev_get_priv(dev);
-
-	return _sun8i_free_pkt(priv);
-}
-
 static void sun8i_emac_eth_stop(struct udevice *dev)
 {
 	struct emac_eth_dev *priv = dev_get_priv(dev);
 
 	/* Stop Rx/Tx transmitter */
-	clrbits_le32(priv->mac_reg + EMAC_RX_CTL0, BIT(31));
-	clrbits_le32(priv->mac_reg + EMAC_TX_CTL0, BIT(31));
+	clrbits_le32(priv->mac_reg + EMAC_RX_CTL0, EMAC_RX_CTL0_RX_EN);
+	clrbits_le32(priv->mac_reg + EMAC_TX_CTL0, EMAC_TX_CTL0_TX_EN);
 
-	/* Stop TX DMA */
-	clrbits_le32(priv->mac_reg + EMAC_TX_CTL1, BIT(30));
+	/* Stop RX/TX DMA */
+	clrbits_le32(priv->mac_reg + EMAC_TX_CTL1, EMAC_TX_CTL1_TX_DMA_EN);
+	clrbits_le32(priv->mac_reg + EMAC_RX_CTL1, EMAC_RX_CTL1_RX_DMA_EN);
 
 	phy_shutdown(priv->phydev);
 }
@@ -855,47 +827,30 @@
 	.stop                   = sun8i_emac_eth_stop,
 };
 
-static int sun8i_get_ephy_nodes(struct udevice *dev, struct emac_eth_dev *priv)
+static int sun8i_handle_internal_phy(struct udevice *dev, struct emac_eth_dev *priv)
 {
-	int emac_node, ephy_node, ret, ephy_handle;
+	struct ofnode_phandle_args phandle;
+	int ret;
 
-	emac_node = fdt_path_offset(gd->fdt_blob,
-				    "/soc/ethernet@1c30000");
-	if (emac_node < 0) {
-		debug("failed to get emac node\n");
-		return emac_node;
-	}
-	ephy_handle = fdtdec_lookup_phandle(gd->fdt_blob,
-					    emac_node, "phy-handle");
+	ret = ofnode_parse_phandle_with_args(dev_ofnode(dev), "phy-handle",
+					     NULL, 0, 0, &phandle);
+	if (ret)
+		return ret;
 
-	/* look for mdio-mux node for internal PHY node */
-	ephy_node = fdt_path_offset(gd->fdt_blob,
-				    "/soc/ethernet@1c30000/mdio-mux/mdio@1/ethernet-phy@1");
-	if (ephy_node < 0) {
-		debug("failed to get mdio-mux with internal PHY\n");
-		return ephy_node;
-	}
-
-	/* This is not the phy we are looking for */
-	if (ephy_node != ephy_handle)
+	/* If the PHY node is not a child of the internal MDIO bus, we are
+	 * using some external PHY.
+	 */
+	if (!ofnode_device_is_compatible(ofnode_get_parent(phandle.node),
+					 "allwinner,sun8i-h3-mdio-internal"))
 		return 0;
 
-	ret = fdt_node_check_compatible(gd->fdt_blob, ephy_node,
-					"allwinner,sun8i-h3-mdio-internal");
-	if (ret < 0) {
-		debug("failed to find mdio-internal node\n");
-		return ret;
-	}
-
-	ret = clk_get_by_index_nodev(offset_to_ofnode(ephy_node), 0,
-				     &priv->ephy_clk);
+	ret = clk_get_by_index_nodev(phandle.node, 0, &priv->ephy_clk);
 	if (ret) {
 		dev_err(dev, "failed to get EPHY TX clock\n");
 		return ret;
 	}
 
-	ret = reset_get_by_index_nodev(offset_to_ofnode(ephy_node), 0,
-				       &priv->ephy_rst);
+	ret = reset_get_by_index_nodev(phandle.node, 0, &priv->ephy_rst);
 	if (ret) {
 		dev_err(dev, "failed to get EPHY TX reset\n");
 		return ret;
@@ -987,7 +942,7 @@
 	}
 
 	if (priv->variant == H3_EMAC) {
-		ret = sun8i_get_ephy_nodes(dev, priv);
+		ret = sun8i_handle_internal_phy(dev, priv);
 		if (ret)
 			return ret;
 	}
diff --git a/drivers/phy/nop-phy.c b/drivers/phy/nop-phy.c
index a5eed20..ba71785 100644
--- a/drivers/phy/nop-phy.c
+++ b/drivers/phy/nop-phy.c
@@ -4,17 +4,50 @@
  * Written by Jean-Jacques Hiblot  <jjhiblot@ti.com>
  */
 
+#include <clk.h>
 #include <common.h>
 #include <dm.h>
 #include <dm/device.h>
+#include <dm/device_compat.h>
 #include <generic-phy.h>
 
+struct nop_phy_priv {
+	struct clk_bulk bulk;
+};
+
+static int nop_phy_init(struct phy *phy)
+{
+	struct nop_phy_priv *priv = dev_get_priv(phy->dev);
+
+	if (CONFIG_IS_ENABLED(CLK))
+		return clk_enable_bulk(&priv->bulk);
+
+	return 0;
+}
+
+static int nop_phy_probe(struct udevice *dev)
+{
+	struct nop_phy_priv *priv = dev_get_priv(dev);
+	int ret;
+
+	if (CONFIG_IS_ENABLED(CLK)) {
+		ret = clk_get_bulk(dev, &priv->bulk);
+		if (ret < 0) {
+			dev_err(dev, "Failed to get clk: %d\n", ret);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
 static const struct udevice_id nop_phy_ids[] = {
 	{ .compatible = "nop-phy" },
 	{ }
 };
 
 static struct phy_ops nop_phy_ops = {
+	.init = nop_phy_init,
 };
 
 U_BOOT_DRIVER(nop_phy) = {
@@ -22,4 +55,6 @@
 	.id	= UCLASS_PHY,
 	.of_match = nop_phy_ids,
 	.ops = &nop_phy_ops,
+	.probe = nop_phy_probe,
+	.priv_auto_alloc_size = sizeof(struct nop_phy_priv),
 };
diff --git a/drivers/power/regulator/gpio-regulator.c b/drivers/power/regulator/gpio-regulator.c
index 947f812..28c9e22 100644
--- a/drivers/power/regulator/gpio-regulator.c
+++ b/drivers/power/regulator/gpio-regulator.c
@@ -18,8 +18,6 @@
 
 #define GPIO_REGULATOR_MAX_STATES	2
 
-DECLARE_GLOBAL_DATA_PTR;
-
 struct gpio_regulator_platdata {
 	struct regulator_common_platdata common;
 	struct gpio_desc gpio; /* GPIO for regulator voltage control */
@@ -32,10 +30,8 @@
 	struct dm_regulator_uclass_platdata *uc_pdata;
 	struct gpio_regulator_platdata *dev_pdata;
 	struct gpio_desc *gpio;
-	const void *blob = gd->fdt_blob;
-	int node = dev_of_offset(dev);
 	int ret, count, i, j;
-	u32 states_array[8];
+	u32 states_array[GPIO_REGULATOR_MAX_STATES * 2];
 
 	dev_pdata = dev_get_platdata(dev);
 	uc_pdata = dev_get_uclass_platdata(dev);
@@ -57,11 +53,20 @@
 	if (ret)
 		debug("regulator gpio - not found! Error: %d", ret);
 
-	count = fdtdec_get_int_array_count(blob, node, "states",
-					   states_array, 8);
+	ret = dev_read_size(dev, "states");
+	if (ret < 0)
+		return ret;
 
-	if (!count)
-		return -EINVAL;
+	count = ret / sizeof(states_array[0]);
+	if (count > ARRAY_SIZE(states_array)) {
+		debug("regulator gpio - to many states (%d > %d)",
+		      count / 2, GPIO_REGULATOR_MAX_STATES);
+		count = ARRAY_SIZE(states_array);
+	}
+
+	ret = dev_read_u32_array(dev, "states", states_array, count);
+	if (ret < 0)
+		return ret;
 
 	for (i = 0, j = 0; i < count; i += 2) {
 		dev_pdata->voltages[j] = states_array[i];
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 6366200..d06d272 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -63,6 +63,17 @@
 	  Support for Dallas Semiconductor (now Maxim) DS3232 compatible
 	  Real Time Clock devices.
 
+config RTC_EMULATION
+	bool "Enable emulated RTC"
+	depends on DM_RTC
+	help
+	  On a board without hardware clock this software real time clock can be
+	  used. The build time is used to initialize the RTC. So you will have
+	  to adjust the time either manually using the 'date' command  or use
+	  the 'sntp' to update the RTC with the time from a network time server.
+	  See CONFIG_CMD_SNTP and CONFIG_BOOTP_NTPSERVER. The RTC time is
+	  advanced according to CPU ticks.
+
 config RTC_ISL1208
 	bool "Enable ISL1208 driver"
 	depends on DM_RTC
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 12eb449..ef66dc4 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -22,6 +22,7 @@
 obj-$(CONFIG_RTC_DS174x) += ds174x.o
 obj-$(CONFIG_RTC_DS3231) += ds3231.o
 obj-$(CONFIG_RTC_DS3232) += ds3232.o
+obj-$(CONFIG_RTC_EMULATION) += emul_rtc.o
 obj-$(CONFIG_RTC_FTRTC010) += ftrtc010.o
 obj-$(CONFIG_SANDBOX) += i2c_rtc_emul.o
 obj-$(CONFIG_RTC_IMXDI) += imxdi.o
diff --git a/drivers/rtc/emul_rtc.c b/drivers/rtc/emul_rtc.c
new file mode 100644
index 0000000..c98c24b
--- /dev/null
+++ b/drivers/rtc/emul_rtc.c
@@ -0,0 +1,80 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2020, Heinrich Schuchardt <xypron.glpk@gmx.de>
+ *
+ * This driver emulates a real time clock based on timer ticks.
+ */
+
+#include <common.h>
+#include <div64.h>
+#include <dm.h>
+#include <generated/timestamp_autogenerated.h>
+#include <rtc.h>
+
+/**
+ * struct emul_rtc - private data for emulated RTC driver
+ */
+struct emul_rtc {
+	/**
+	 * @offset_us: microseconds from 1970-01-01 to timer_get_us() base
+	 */
+	u64 offset_us;
+	/**
+	 * @isdst: daylight saving time
+	 */
+	int isdst;
+};
+
+static int emul_rtc_get(struct udevice *dev, struct rtc_time *time)
+{
+	struct emul_rtc *priv = dev_get_priv(dev);
+	u64 now;
+
+	if (!priv->offset_us) {
+		/* Use the build date as initial time */
+		priv->offset_us = U_BOOT_EPOCH * 1000000ULL - timer_get_us();
+		priv->isdst = -1;
+	}
+
+	now = timer_get_us() + priv->offset_us;
+	do_div(now, 1000000);
+	rtc_to_tm(now, time);
+	time->tm_isdst = priv->isdst;
+
+	return 0;
+}
+
+static int emul_rtc_set(struct udevice *dev, const struct rtc_time *time)
+{
+	struct emul_rtc *priv = dev_get_priv(dev);
+
+	if (time->tm_year < 1970)
+		return -EINVAL;
+
+	priv->offset_us = rtc_mktime(time) * 1000000ULL - timer_get_us();
+
+	if (time->tm_isdst > 0)
+		priv->isdst = 1;
+	else if (time->tm_isdst < 0)
+		priv->isdst = -1;
+	else
+		priv->isdst = 0;
+
+	return 0;
+}
+
+static const struct rtc_ops emul_rtc_ops = {
+	.get = emul_rtc_get,
+	.set = emul_rtc_set,
+};
+
+U_BOOT_DRIVER(rtc_emul) = {
+	.name	= "rtc_emul",
+	.id	= UCLASS_RTC,
+	.ops	= &emul_rtc_ops,
+	.priv_auto_alloc_size = sizeof(struct emul_rtc),
+};
+
+U_BOOT_DEVICE(rtc_emul) = {
+	.name	= "rtc_emul",
+};
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index b6ba702..b4805a2 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -401,19 +401,11 @@
 	  driver will be available until the real driver model serial is
 	  running.
 
-config DEBUG_UART_XEN
-	bool "XEN Hypervisor Console"
-	depends on XEN_SERIAL
-	help
-	  Select this to enable a debug UART using the serial_xen driver. You
-	  will not have to provide any parameters to make this work. The driver
-          will be available until the real driver-model serial is running.
-
 endchoice
 
 config DEBUG_UART_BASE
 	hex "Base address of UART"
-	depends on DEBUG_UART && !DEBUG_UART_XEN
+	depends on DEBUG_UART
 	default 0 if DEBUG_UART_SANDBOX
 	help
 	  This is the base address of your UART for memory-mapped UARTs.
@@ -423,7 +415,7 @@
 
 config DEBUG_UART_CLOCK
 	int "UART input clock"
-	depends on DEBUG_UART && !DEBUG_UART_XEN
+	depends on DEBUG_UART
 	default 0 if DEBUG_UART_SANDBOX
 	help
 	  The UART input clock determines the speed of the internal UART
@@ -435,7 +427,7 @@
 
 config DEBUG_UART_SHIFT
 	int "UART register shift"
-	depends on DEBUG_UART && !DEBUG_UART_XEN
+	depends on DEBUG_UART
 	default 0 if DEBUG_UART
 	help
 	  Some UARTs (notably ns16550) support different register layouts
diff --git a/drivers/serial/serial_xen.c b/drivers/serial/serial_xen.c
index 34c90ec..ba6504b 100644
--- a/drivers/serial/serial_xen.c
+++ b/drivers/serial/serial_xen.c
@@ -5,7 +5,6 @@
  */
 #include <common.h>
 #include <cpu_func.h>
-#include <debug_uart.h>
 #include <dm.h>
 #include <serial.h>
 #include <watchdog.h>
@@ -16,14 +15,11 @@
 #include <xen/events.h>
 
 #include <xen/interface/sched.h>
-#include <xen/interface/xen.h>
 #include <xen/interface/hvm/hvm_op.h>
 #include <xen/interface/hvm/params.h>
 #include <xen/interface/io/console.h>
 #include <xen/interface/io/ring.h>
 
-#include <asm/xen/hypercall.h>
-
 DECLARE_GLOBAL_DATA_PTR;
 
 u32 console_evtchn;
@@ -179,22 +175,8 @@
 	.priv_auto_alloc_size	= sizeof(struct xen_uart_priv),
 	.probe			= xen_serial_probe,
 	.ops			= &xen_serial_ops,
+#if !CONFIG_IS_ENABLED(OF_CONTROL)
 	.flags			= DM_FLAG_PRE_RELOC,
+#endif
 };
 
-#if defined(CONFIG_DEBUG_UART_XEN)
-static inline void _debug_uart_init(void) {}
-
-static inline void _debug_uart_putc(int c)
-{
-#if CONFIG_IS_ENABLED(ARM)
-	xen_debug_putc(c);
-#else
-	/* the type cast should work on LE only */
-	HYPERVISOR_console_io(CONSOLEIO_write, 1, (char *)&ch);
-#endif
-}
-
-DEBUG_UART_FUNCS
-
-#endif
diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig
index f8fa4aa..80743a2 100644
--- a/drivers/timer/Kconfig
+++ b/drivers/timer/Kconfig
@@ -53,6 +53,13 @@
 	  Select this to enable a timer for Altera devices. Please find
 	  details on the "Embedded Peripherals IP User Guide" of Altera.
 
+config ANDES_PLMT_TIMER
+	bool
+	depends on RISCV_MMODE || SPL_RISCV_MMODE
+	help
+	  The Andes PLMT block holds memory-mapped mtime register
+	  associated with timer tick.
+
 config ARC_TIMER
 	bool "ARC timer support"
 	depends on TIMER && ARC && CLK
diff --git a/drivers/timer/Makefile b/drivers/timer/Makefile
index 3a4d74b..eb5c48c 100644
--- a/drivers/timer/Makefile
+++ b/drivers/timer/Makefile
@@ -5,6 +5,7 @@
 obj-y += timer-uclass.o
 obj-$(CONFIG_AG101P_TIMER) += ag101p_timer.o
 obj-$(CONFIG_ALTERA_TIMER)	+= altera_timer.o
+obj-$(CONFIG_ANDES_PLMT_TIMER) += andes_plmt_timer.o
 obj-$(CONFIG_ARC_TIMER)	+= arc_timer.o
 obj-$(CONFIG_AST_TIMER)	+= ast_timer.o
 obj-$(CONFIG_ATCPIT100_TIMER) += atcpit100_timer.o
@@ -18,6 +19,7 @@
 obj-$(CONFIG_RISCV_TIMER) += riscv_timer.o
 obj-$(CONFIG_ROCKCHIP_TIMER) += rockchip_timer.o
 obj-$(CONFIG_SANDBOX_TIMER)	+= sandbox_timer.o
+obj-$(CONFIG_SIFIVE_CLINT) += sifive_clint_timer.o
 obj-$(CONFIG_STI_TIMER)		+= sti-timer.o
 obj-$(CONFIG_STM32_TIMER)	+= stm32_timer.o
 obj-$(CONFIG_X86_TSC_TIMER)	+= tsc_timer.o
diff --git a/arch/riscv/lib/andes_plmt.c b/drivers/timer/andes_plmt_timer.c
similarity index 100%
rename from arch/riscv/lib/andes_plmt.c
rename to drivers/timer/andes_plmt_timer.c
diff --git a/drivers/timer/sifive_clint_timer.c b/drivers/timer/sifive_clint_timer.c
new file mode 100644
index 0000000..00ce0f0
--- /dev/null
+++ b/drivers/timer/sifive_clint_timer.c
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2020, Sean Anderson <seanga2@gmail.com>
+ * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <timer.h>
+#include <asm/io.h>
+#include <linux/err.h>
+
+/* mtime register */
+#define MTIME_REG(base)			((ulong)(base) + 0xbff8)
+
+static u64 sifive_clint_get_count(struct udevice *dev)
+{
+	return readq((void __iomem *)MTIME_REG(dev->priv));
+}
+
+static const struct timer_ops sifive_clint_ops = {
+	.get_count = sifive_clint_get_count,
+};
+
+static int sifive_clint_probe(struct udevice *dev)
+{
+	dev->priv = dev_read_addr_ptr(dev);
+	if (!dev->priv)
+		return -EINVAL;
+
+	return timer_timebase_fallback(dev);
+}
+
+static const struct udevice_id sifive_clint_ids[] = {
+	{ .compatible = "riscv,clint0" },
+	{ }
+};
+
+U_BOOT_DRIVER(sifive_clint) = {
+	.name		= "sifive_clint",
+	.id		= UCLASS_TIMER,
+	.of_match	= sifive_clint_ids,
+	.probe		= sifive_clint_probe,
+	.ops		= &sifive_clint_ops,
+	.flags		= DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index b1cb745..998271b 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -665,7 +665,7 @@
 
 config CFB_CONSOLE
 	bool "Enable colour frame buffer console"
-	depends on VIDEO
+	depends on VIDEO || ARCH_OMAP2PLUS
 	default y if VIDEO
 	help
 	  Enables the colour frame buffer driver. This supports colour
@@ -972,4 +972,11 @@
 	help
 	  Support display of bitmaps file with 32-bit-per-pixel.
 
+config VIDEO_VCXK
+	bool "Enable VCXK video controller driver support"
+	default n
+	help
+	  This enables VCXK driver which can be used with VC2K, VC4K
+	  and VC8K devices on various boards from BuS Elektronik GmbH.
+
 endmenu
diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h
index ebb740d..0157af1 100644
--- a/include/asm-generic/global_data.h
+++ b/include/asm-generic/global_data.h
@@ -363,6 +363,26 @@
 	 * &enum log_fmt defines the bits of the bit mask.
 	 */
 	int log_fmt;
+
+	/**
+	 * @processing_msg: a log message is being processed
+	 *
+	 * This flag is used to suppress the creation of additional messages
+	 * while another message is being processed.
+	 */
+	bool processing_msg;
+	/**
+	 * @logc_prev: logging category of previous message
+	 *
+	 * This value is used as logging category for continuation messages.
+	 */
+	int logc_prev;
+	/**
+	 * @logl_pref: logging level of the previous message
+	 *
+	 * This value is used as logging level for continuation messages.
+	 */
+	int logl_prev;
 #endif
 #if CONFIG_IS_ENABLED(BLOBLIST)
 	/**
diff --git a/include/configs/arndale.h b/include/configs/arndale.h
index 79e7418..5109f7d 100644
--- a/include/configs/arndale.h
+++ b/include/configs/arndale.h
@@ -18,8 +18,6 @@
 #define CONFIG_EXYNOS_SPL
 
 /* Miscellaneous configurable options */
-#define CONFIG_DEFAULT_CONSOLE		"console=ttySAC2,115200n8\0"
-
 #define CONFIG_IRAM_STACK	0x02050000
 
 #define CONFIG_SYS_INIT_SP_ADDR	CONFIG_IRAM_STACK
diff --git a/include/configs/eb_cpu5282.h b/include/configs/eb_cpu5282.h
index db92bbd..ab9daa4 100644
--- a/include/configs/eb_cpu5282.h
+++ b/include/configs/eb_cpu5282.h
@@ -212,9 +212,6 @@
  * VIDEO configuration
  */
 
-#ifdef CONFIG_VIDEO
-#define CONFIG_VIDEO_VCXK			1
-
 #define CONFIG_SYS_VCXK_DEFAULT_LINEALIGN	2
 #define	CONFIG_SYS_VCXK_DOUBLEBUFFERED		1
 #define CONFIG_SYS_VCXK_BASE			CONFIG_SYS_CS2_BASE
@@ -235,6 +232,5 @@
 #define CONFIG_SYS_VCXK_INVERT_DDR		MCFGPIO_DDRE
 #define CONFIG_SYS_VCXK_INVERT_PIN		MCFGPIO_PORT2
 
-#endif /* CONFIG_VIDEO */
 #endif	/* _CONFIG_M5282EVB_H */
 /*---------------------------------------------------------------------*/
diff --git a/include/configs/espresso7420.h b/include/configs/espresso7420.h
index 5aeb009..2495db9 100644
--- a/include/configs/espresso7420.h
+++ b/include/configs/espresso7420.h
@@ -18,9 +18,6 @@
 #define CONFIG_SPL_STACK		CONFIG_IRAM_END
 #define CONFIG_SYS_INIT_SP_ADDR		CONFIG_IRAM_END
 
-/* select serial console configuration */
-#define CONFIG_DEFAULT_CONSOLE	"console=ttySAC1,115200n8\0"
-
 /* DRAM Memory Banks */
 #define SDRAM_BANK_SIZE		(256UL << 20UL)	/* 256 MB */
 
diff --git a/include/configs/odroid.h b/include/configs/odroid.h
index befb9f9..1367d13 100644
--- a/include/configs/odroid.h
+++ b/include/configs/odroid.h
@@ -33,12 +33,7 @@
 
 #include <linux/sizes.h>
 
-/* select serial console configuration */
-
-/* Console configuration */
-
 #define CONFIG_BOOTCOMMAND		"run distro_bootcmd ; run autoboot"
-#define CONFIG_DEFAULT_CONSOLE		"console=ttySAC1,115200n8\0"
 
 #define CONFIG_SYS_INIT_SP_ADDR	(CONFIG_SYS_LOAD_ADDR \
 					- GENERATED_GBL_DATA_SIZE)
@@ -149,7 +144,7 @@
 		"elif test -e mmc ${mmcbootdev} uImage; then; " \
 			"run boot_uimg;" \
 		"fi;\0" \
-	"console=" CONFIG_DEFAULT_CONSOLE \
+	"console=console=ttySAC1,115200n8\0" \
 	"mmcbootdev=0\0" \
 	"mmcbootpart=1\0" \
 	"mmcrootdev=0\0" \
diff --git a/include/configs/odroid_xu3.h b/include/configs/odroid_xu3.h
index 564319c..0c86196 100644
--- a/include/configs/odroid_xu3.h
+++ b/include/configs/odroid_xu3.h
@@ -14,8 +14,6 @@
 
 #define CONFIG_SYS_SDRAM_BASE		0x40000000
 
-/* select serial console configuration */
-
 #define TZPC_BASE_OFFSET		0x10000
 
 #define SDRAM_BANK_SIZE			(256UL << 20UL)	/* 256 MB */
@@ -25,8 +23,6 @@
 
 #define CONFIG_SYS_INIT_SP_ADDR		(CONFIG_SYS_LOAD_ADDR - 0x1000000)
 
-#define CONFIG_DEFAULT_CONSOLE		"console=ttySAC2,115200n8\0"
-
 /* USB */
 #define CONFIG_USB_EHCI_EXYNOS
 
@@ -97,7 +93,7 @@
 	MEM_LAYOUT_ENV_SETTINGS \
 	BOOTENV \
 	"rootfstype=ext4\0" \
-	"console=" CONFIG_DEFAULT_CONSOLE \
+	"console=console=ttySAC2,115200n8\0" \
 	"fdtfile=exynos5422-odroidxu3.dtb\0" \
 	"board_name=odroidxu3\0" \
 	"mmcbootdev=0\0" \
diff --git a/include/configs/origen.h b/include/configs/origen.h
index 24b0338..8a0e145 100644
--- a/include/configs/origen.h
+++ b/include/configs/origen.h
@@ -24,11 +24,6 @@
 
 #define CONFIG_MACH_TYPE		MACH_TYPE_ORIGEN
 
-/* select serial console configuration */
-
-/* Console configuration */
-#define CONFIG_DEFAULT_CONSOLE		"console=ttySAC1,115200n8\0"
-
 #define CONFIG_SYS_MEM_TOP_HIDE	(1 << 20)	/* ram console */
 
 #define CONFIG_SYS_MONITOR_BASE	0x00000000
diff --git a/include/configs/peach-pi.h b/include/configs/peach-pi.h
index a732e06..ba82aaf 100644
--- a/include/configs/peach-pi.h
+++ b/include/configs/peach-pi.h
@@ -23,9 +23,6 @@
 #define CONFIG_SYS_SDRAM_BASE	0x20000000
 #define CONFIG_SYS_INIT_SP_ADDR	(CONFIG_IRAM_TOP - 0x800)
 
-/* select serial console configuration */
-#define CONFIG_DEFAULT_CONSOLE	"console=ttySAC1,115200n8\0"
-
 /* Display */
 #ifdef CONFIG_LCD
 #define CONFIG_EXYNOS_FB
diff --git a/include/configs/peach-pit.h b/include/configs/peach-pit.h
index 6c5960c..16fb2f3 100644
--- a/include/configs/peach-pit.h
+++ b/include/configs/peach-pit.h
@@ -23,9 +23,6 @@
 #define CONFIG_SYS_SDRAM_BASE	0x20000000
 #define CONFIG_SYS_INIT_SP_ADDR	(CONFIG_IRAM_TOP - 0x800)
 
-/* select serial console configuration */
-#define CONFIG_DEFAULT_CONSOLE	"console=ttySAC1,115200n8\0"
-
 /* DRAM Memory Banks */
 #define SDRAM_BANK_SIZE		(512UL << 20UL)	/* 512 MB */
 
diff --git a/include/configs/s5p_goni.h b/include/configs/s5p_goni.h
index d6d07a95..9688bdc 100644
--- a/include/configs/s5p_goni.h
+++ b/include/configs/s5p_goni.h
@@ -34,10 +34,6 @@
 /* Size of malloc() pool before and after relocation */
 #define CONFIG_SYS_MALLOC_LEN		(CONFIG_ENV_SIZE + (80 << 20))
 
-/*
- * select serial console configuration
- */
-
 /* MMC */
 #define SDHCI_MAX_HOSTS		4
 
@@ -85,8 +81,6 @@
 
 #define CONFIG_BOOTCOMMAND	"run mmcboot"
 
-#define CONFIG_DEFAULT_CONSOLE	"console=ttySAC2,115200n8\0"
-
 #define CONFIG_RAMDISK_BOOT	"root=/dev/ram0 rw rootfstype=ext4" \
 		" ${console} ${meminfo}"
 
@@ -131,7 +125,7 @@
 	"bootchart=set opts init=/sbin/bootchartd; run bootcmd\0" \
 	"verify=n\0" \
 	"rootfstype=ext4\0" \
-	"console=" CONFIG_DEFAULT_CONSOLE \
+	"console=console=ttySAC2,115200n8\0" \
 	"meminfo=mem=80M mem=256M@0x40000000 mem=128M@0x50000000\0" \
 	"loaduimage=ext4load mmc ${mmcdev}:${mmcbootpart} 0x30007FC0 uImage\0" \
 	"mmcdev=0\0" \
diff --git a/include/configs/s5pc210_universal.h b/include/configs/s5pc210_universal.h
index 86c90d9..0b679f4 100644
--- a/include/configs/s5pc210_universal.h
+++ b/include/configs/s5pc210_universal.h
@@ -22,12 +22,7 @@
 
 #define SDRAM_BANK_SIZE			(256 << 20)	/* 256 MB */
 
-/* select serial console configuration */
-
-/* Console configuration */
-
 #define CONFIG_BOOTCOMMAND		"run mmcboot"
-#define CONFIG_DEFAULT_CONSOLE		"console=ttySAC1,115200n8\0"
 
 #define CONFIG_SYS_INIT_SP_ADDR	(CONFIG_SYS_LOAD_ADDR \
 					- GENERATED_GBL_DATA_SIZE)
@@ -102,7 +97,7 @@
 	"mmcoops=mmc read 0 0x40000000 0x40 8; md 0x40000000 0x400\0" \
 	"verify=n\0" \
 	"rootfstype=ext4\0" \
-	"console=" CONFIG_DEFAULT_CONSOLE \
+	"console=console=ttySAC1,115200n8\0" \
 	"mtdparts=" CONFIG_MTDPARTS_DEFAULT \
 	"mbrparts=" MBRPARTS_DEFAULT \
 	"meminfo=crashkernel=32M@0x50000000\0" \
diff --git a/include/configs/smdk5250.h b/include/configs/smdk5250.h
index 82251b3..3af1367 100644
--- a/include/configs/smdk5250.h
+++ b/include/configs/smdk5250.h
@@ -18,6 +18,4 @@
 
 #define CONFIG_BOARD_COMMON
 
-#define CONFIG_DEFAULT_CONSOLE		"console=ttySAC1,115200n8\0"
-
 #endif	/* __CONFIG_SMDK_H */
diff --git a/include/configs/smdk5420.h b/include/configs/smdk5420.h
index 14ec099..d06dfe4 100644
--- a/include/configs/smdk5420.h
+++ b/include/configs/smdk5420.h
@@ -24,11 +24,6 @@
 #define CONFIG_SYS_SDRAM_BASE	0x20000000
 #define CONFIG_SYS_INIT_SP_ADDR	(CONFIG_IRAM_TOP - 0x800)
 
-/* select serial console configuration */
-#define CONFIG_DEFAULT_CONSOLE	"console=ttySAC1,115200n8\0"
-
-#define CONFIG_DEFAULT_CONSOLE		"console=ttySAC1,115200n8\0"
-
 /* USB */
 #define CONFIG_USB_XHCI_EXYNOS
 
diff --git a/include/configs/smdkv310.h b/include/configs/smdkv310.h
index b970e4b..fc2f6ec 100644
--- a/include/configs/smdkv310.h
+++ b/include/configs/smdkv310.h
@@ -27,17 +27,12 @@
 #define S5P_CHECK_DIDLE			0xBAD00000
 #define S5P_CHECK_LPA			0xABAD0000
 
-/* select serial console configuration */
-#define EXYNOS4_DEFAULT_UART_OFFSET	0x010000
-
 /* MMC SPL */
 #define CONFIG_SKIP_LOWLEVEL_INIT
 #define COPY_BL2_FNPTR_ADDR	0x00002488
 
 #define CONFIG_BOOTCOMMAND	"fatload mmc 0 40007000 uImage; bootm 40007000"
 
-/* Miscellaneous configurable options */
-#define CONFIG_DEFAULT_CONSOLE		"console=ttySAC2,115200n8\0"
 /* memtest works on */
 #define CONFIG_SYS_LOAD_ADDR		(CONFIG_SYS_SDRAM_BASE + 0x3E00000)
 
diff --git a/include/configs/snow.h b/include/configs/snow.h
index c546a5a..c082b2d8 100644
--- a/include/configs/snow.h
+++ b/include/configs/snow.h
@@ -17,6 +17,4 @@
 
 #define CONFIG_BOARD_COMMON
 
-#define CONFIG_DEFAULT_CONSOLE		"console=ttySAC1,115200n8\0"
-
 #endif	/* __CONFIG_SNOW_H */
diff --git a/include/configs/spring.h b/include/configs/spring.h
index 272622a..0b05245 100644
--- a/include/configs/spring.h
+++ b/include/configs/spring.h
@@ -12,6 +12,4 @@
 
 #define CONFIG_BOARD_COMMON
 
-#define CONFIG_DEFAULT_CONSOLE		"console=ttySAC1,115200n8\0"
-
 #endif	/* __CONFIG_SPRING_H */
diff --git a/include/configs/trats.h b/include/configs/trats.h
index 3c71f08..a44792d 100644
--- a/include/configs/trats.h
+++ b/include/configs/trats.h
@@ -29,12 +29,9 @@
 /* memtest works on */
 #define CONFIG_SYS_LOAD_ADDR		(CONFIG_SYS_SDRAM_BASE + 0x4800000)
 
-/* select serial console configuration */
-
 #define CONFIG_MACH_TYPE		MACH_TYPE_TRATS
 
 #define CONFIG_BOOTCOMMAND		"run autoboot"
-#define CONFIG_DEFAULT_CONSOLE		"console=ttySAC2,115200n8\0"
 
 #define CONFIG_SYS_INIT_SP_ADDR	(CONFIG_SYS_LOAD_ADDR \
 					- GENERATED_GBL_DATA_SIZE)
@@ -112,7 +109,7 @@
 	"mmcoops=mmc read 0 0x40000000 0x40 8; md 0x40000000 0x400\0" \
 	"verify=n\0" \
 	"rootfstype=ext4\0" \
-	"console=" CONFIG_DEFAULT_CONSOLE \
+	"console=console=ttySAC2,115200n8\0" \
 	"meminfo=crashkernel=32M@0x50000000\0" \
 	"nfsroot=/nfsroot/arm\0" \
 	"bootblock=" CONFIG_BOOTBLOCK "\0" \
diff --git a/include/configs/trats2.h b/include/configs/trats2.h
index d53b855..4b1eff0 100644
--- a/include/configs/trats2.h
+++ b/include/configs/trats2.h
@@ -27,12 +27,7 @@
 /* memtest works on */
 #define CONFIG_SYS_LOAD_ADDR		(CONFIG_SYS_SDRAM_BASE + 0x3E00000)
 
-/* select serial console configuration */
-
-/* Console configuration */
-
 #define CONFIG_BOOTCOMMAND		"run autoboot"
-#define CONFIG_DEFAULT_CONSOLE		"console=ttySAC2,115200n8\0"
 
 #define CONFIG_SYS_INIT_SP_ADDR	(CONFIG_SYS_LOAD_ADDR \
 					- GENERATED_GBL_DATA_SIZE)
@@ -95,7 +90,7 @@
 	"boottrace=setenv opts initcall_debug; run bootcmd\0" \
 	"verify=n\0" \
 	"rootfstype=ext4\0" \
-	"console=" CONFIG_DEFAULT_CONSOLE \
+	"console=console=ttySAC2,115200n8\0" \
 	"kernelname=uImage\0" \
 	"loaduimage=ext4load mmc ${mmcdev}:${mmcbootpart} 0x40007FC0 " \
 		"${kernelname}\0" \
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index 88f10c4..17542de 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -71,6 +71,7 @@
 	UCLASS_MMC,		/* SD / MMC card or chip */
 	UCLASS_MOD_EXP,		/* RSA Mod Exp device */
 	UCLASS_MTD,		/* Memory Technology Device (MTD) device */
+	UCLASS_MUX,		/* Multiplexer device */
 	UCLASS_NOP,		/* No-op devices */
 	UCLASS_NORTHBRIDGE,	/* Intel Northbridge / SDRAM controller */
 	UCLASS_NVME,		/* NVM Express device */
diff --git a/include/dt-bindings/mux/mux.h b/include/dt-bindings/mux/mux.h
new file mode 100644
index 0000000..0427192
--- /dev/null
+++ b/include/dt-bindings/mux/mux.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * This header provides constants for most Multiplexer bindings.
+ *
+ * Most Multiplexer bindings specify an idle state. In most cases, the
+ * the multiplexer can be left as is when idle, and in some cases it can
+ * disconnect the input/output and leave the multiplexer in a high
+ * impedance state.
+ */
+
+#ifndef _DT_BINDINGS_MUX_MUX_H
+#define _DT_BINDINGS_MUX_MUX_H
+
+#define MUX_IDLE_AS_IS      (-1)
+#define MUX_IDLE_DISCONNECT (-2)
+
+#endif
diff --git a/include/log.h b/include/log.h
index 6de5e61..58787a3 100644
--- a/include/log.h
+++ b/include/log.h
@@ -38,6 +38,7 @@
 
 	LOGL_FIRST = LOGL_EMERG,
 	LOGL_MAX = LOGL_DEBUG_IO,
+	LOGL_CONT = -1,		/* Use same log level as in previous call */
 };
 
 /**
@@ -65,6 +66,7 @@
 
 	LOGC_COUNT,	/* Number of log categories */
 	LOGC_END,	/* Sentinel value for a list of log categories */
+	LOGC_CONT = -1,	/* Use same category as in previous call */
 };
 
 /* Helper to cast a uclass ID to a log category */
diff --git a/include/mux-internal.h b/include/mux-internal.h
new file mode 100644
index 0000000..93e3a5c
--- /dev/null
+++ b/include/mux-internal.h
@@ -0,0 +1,109 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Based on the linux multiplexer framework
+ *
+ * Copyright (C) 2017 Axentia Technologies AB
+ * Author: Peter Rosin <peda@axentia.se>
+ *
+ * Copyright (C) 2017-2018 Texas Instruments Incorporated - http://www.ti.com/
+ * Jean-Jacques Hiblot <jjhiblot@ti.com>
+ */
+
+#ifndef _MUX_INTERNAL_H
+#define _MUX_INTERNAL_H
+
+/* See mux.h for background documentation. */
+
+struct ofnode_phandle_args;
+
+/**
+ * struct mux_chip -	Represents a chip holding mux controllers.
+ * @controllers:	Number of mux controllers handled by the chip.
+ * @mux:		Array of mux controllers that are handled.
+ *
+ * This a per-device uclass-private data.
+ */
+struct mux_chip {
+	unsigned int controllers;
+	struct mux_control *mux;
+};
+
+/**
+ * struct mux_control_ops -	Mux controller operations for a mux chip.
+ * @set:			Set the state of the given mux controller.
+ */
+struct mux_control_ops {
+	/**
+	 * set - Apply a state to a multiplexer control
+	 *
+	 * @mux:	A multiplexer control
+	 * @return 0 if OK, or a negative error code.
+	 */
+	int (*set)(struct mux_control *mux, int state);
+
+	/**
+	 * of_xlate - Translate a client's device-tree (OF) multiplexer
+	 * specifier.
+	 *
+	 * If this function pointer is set to NULL, the multiplexer core will
+	 * use a default implementation, which assumes #mux-control-cells = <1>
+	 * and that the DT cell contains a simple integer channel ID.
+	 *
+	 * @dev_mux:	The multiplexer device. A single device may handle
+	 *              several multiplexer controls.
+	 * @args:	The multiplexer specifier values from device tree.
+	 * @muxp:	(out) A multiplexer control
+	 * @return 0 if OK, or a negative error code.
+	 */
+	int (*of_xlate)(struct mux_chip *dev_mux,
+			struct ofnode_phandle_args *args,
+			struct mux_control **muxp);
+};
+
+/**
+ * struct mux_control -	Represents a mux controller.
+ * @in_use:		Whether the mux controller is in use or not.
+ * @dev:		The client device.
+ * @cached_state:	The current mux controller state, or -1 if none.
+ * @states:		The number of mux controller states.
+ * @idle_state:		The mux controller state to use when inactive, or one
+ *			of MUX_IDLE_AS_IS and MUX_IDLE_DISCONNECT.
+ * @id:			The index of the mux controller within the mux chip
+ *			it is a part of.
+ *
+ * Mux drivers may only change @states and @idle_state, and may only do so
+ * between allocation and registration of the mux controller. Specifically,
+ * @cached_state is internal to the mux core and should never be written by
+ * mux drivers.
+ */
+struct mux_control {
+	bool	in_use;
+	struct udevice *dev;
+	int cached_state;
+	unsigned int states;
+	int idle_state;
+	int id;
+};
+
+/**
+ * mux_control_get_index() - Get the index of the given mux controller
+ * @mux:		The mux-control to get the index for.
+ *
+ * Return: The index of the mux controller within the mux chip the mux
+ * controller is a part of.
+ */
+static inline unsigned int mux_control_get_index(struct mux_control *mux)
+{
+	return mux->id;
+}
+
+/**
+ * mux_alloc_controllers() - Allocate the given number of mux controllers.
+ * @dev:		The client device.
+ * controllers:		Number of controllers to allocate.
+ *
+ * Return: 0 of OK, -errno otherwise.
+ */
+int mux_alloc_controllers(struct udevice *dev, unsigned int controllers);
+
+#endif
diff --git a/include/mux.h b/include/mux.h
new file mode 100644
index 0000000..23844f4
--- /dev/null
+++ b/include/mux.h
@@ -0,0 +1,159 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Based on the linux multiplexer framework
+ *
+ * At its core, a multiplexer (or mux), also known as a data selector, is a
+ * device that selects between several analog or digital input signals and
+ * forwards it to a single output line. This notion can be extended to work
+ * with buses, like a I2C bus multiplexer for example.
+ *
+ * Copyright (C) 2017 Axentia Technologies AB
+ * Author: Peter Rosin <peda@axentia.se>
+ *
+ * Copyright (C) 2017-2018 Texas Instruments Incorporated - http://www.ti.com/
+ * Jean-Jacques Hiblot <jjhiblot@ti.com>
+ */
+
+#ifndef _MUX_H_
+#define _MUX_H_
+
+#include <linux/errno.h>
+#include <linux/types.h>
+
+struct udevice;
+struct mux_control;
+
+#if CONFIG_IS_ENABLED(MULTIPLEXER)
+/**
+ * mux_control_states() - Query the number of multiplexer states.
+ * @mux: The mux-control to query.
+ *
+ * Return: The number of multiplexer states.
+ */
+unsigned int mux_control_states(struct mux_control *mux);
+
+/**
+ * mux_control_select() - Select the given multiplexer state.
+ * @mux: The mux-control to request a change of state from.
+ * @state: The new requested state.
+ *
+ * On successfully selecting the mux-control state, it will be locked until
+ * there is a call to mux_control_deselect(). If the mux-control is already
+ * selected when mux_control_select() is called, the function will indicate
+ * -EBUSY
+ *
+ * Therefore, make sure to call mux_control_deselect() when the operation is
+ * complete and the mux-control is free for others to use, but do not call
+ * mux_control_deselect() if mux_control_select() fails.
+ *
+ * Return: 0 when the mux-control state has the requested state or a negative
+ * errno on error.
+ */
+int __must_check mux_control_select(struct mux_control *mux,
+				    unsigned int state);
+#define mux_control_try_select(mux) mux_control_select(mux)
+
+/**
+ * mux_control_deselect() - Deselect the previously selected multiplexer state.
+ * @mux: The mux-control to deselect.
+ *
+ * It is required that a single call is made to mux_control_deselect() for
+ * each and every successful call made to either of mux_control_select() or
+ * mux_control_try_select().
+ *
+ * Return: 0 on success and a negative errno on error. An error can only
+ * occur if the mux has an idle state. Note that even if an error occurs, the
+ * mux-control is unlocked and is thus free for the next access.
+ */
+int mux_control_deselect(struct mux_control *mux);
+
+/**
+ * mux_get_by_index() = Get a mux by integer index.
+ * @dev: The client device.
+ * @index: The index of the mux to get.
+ * @mux: A pointer to the 'mux_control' struct to initialize.
+ *
+ * This looks up and initializes a mux. The index is relative to the client
+ * device.
+ *
+ * Return: 0 if OK, or a negative error code.
+ */
+int mux_get_by_index(struct udevice *dev, int index, struct mux_control **mux);
+
+/**
+ * mux_control_get() - Get the mux-control for a device.
+ * @dev: The device that needs a mux-control.
+ * @mux_name: The name identifying the mux-control.
+ * @mux: A pointer to the mux-control pointer.
+ *
+ * Return: 0 of OK, or a negative error code.
+ */
+int mux_control_get(struct udevice *dev, const char *name,
+		    struct mux_control **mux);
+
+/**
+ * mux_control_put() - Put away the mux-control for good.
+ * @mux: The mux-control to put away.
+ *
+ * mux_control_put() reverses the effects of mux_control_get().
+ */
+void mux_control_put(struct mux_control *mux);
+
+/**
+ * devm_mux_control_get() - Get the mux-control for a device, with resource
+ *			    management.
+ * @dev: The device that needs a mux-control.
+ * @mux_name: The name identifying the mux-control.
+ *
+ * Return: Pointer to the mux-control, or an ERR_PTR with a negative errno.
+ */
+struct mux_control *devm_mux_control_get(struct udevice *dev,
+					 const char *mux_name);
+/**
+ * dm_mux_init() - Initialize the multiplexer controls to their default state.
+ *
+ * Return: 0 if OK, -errno otherwise.
+ */
+int dm_mux_init(void);
+
+#else
+unsigned int mux_control_states(struct mux_control *mux)
+{
+	return -ENOSYS;
+}
+
+int __must_check mux_control_select(struct mux_control *mux,
+				    unsigned int state)
+{
+	return -ENOSYS;
+}
+
+#define mux_control_try_select(mux) mux_control_select(mux)
+
+int mux_control_deselect(struct mux_control *mux)
+{
+	return -ENOSYS;
+}
+
+struct mux_control *mux_control_get(struct udevice *dev, const char *mux_name)
+{
+	return NULL;
+}
+
+void mux_control_put(struct mux_control *mux)
+{
+}
+
+struct mux_control *devm_mux_control_get(struct udevice *dev,
+					 const char *mux_name)
+{
+	return NULL;
+}
+
+int dm_mux_init(void)
+{
+	return -ENOSYS;
+}
+#endif
+
+#endif
diff --git a/include/power/regulator.h b/include/power/regulator.h
index 74938dd..7f278e8 100644
--- a/include/power/regulator.h
+++ b/include/power/regulator.h
@@ -264,6 +264,7 @@
 	int (*set_mode)(struct udevice *dev, int mode_id);
 };
 
+#if CONFIG_IS_ENABLED(DM_REGULATOR)
 /**
  * regulator_mode: returns a pointer to the array of regulator mode info
  *
@@ -524,5 +525,118 @@
  */
 int device_get_supply_regulator(struct udevice *dev, const char *supply_name,
 				struct udevice **devp);
+#else
+static inline int regulator_mode(struct udevice *dev, struct dm_regulator_mode **modep)
+{
+	return -ENOSYS;
+}
+
+static inline int regulator_get_value(struct udevice *dev)
+{
+	return -ENOSYS;
+}
+
+static inline int regulator_set_value(struct udevice *dev, int uV)
+{
+	return -ENOSYS;
+}
+
+static inline int regulator_set_suspend_value(struct udevice *dev, int uV)
+{
+	return -ENOSYS;
+}
+
+static inline int regulator_get_suspend_value(struct udevice *dev)
+{
+	return -ENOSYS;
+}
+
+static inline int regulator_set_value_force(struct udevice *dev, int uV)
+{
+	return -ENOSYS;
+}
+
+static inline int regulator_get_current(struct udevice *dev)
+{
+	return -ENOSYS;
+}
+
+static inline int regulator_set_current(struct udevice *dev, int uA)
+{
+	return -ENOSYS;
+}
+
+static inline int regulator_get_enable(struct udevice *dev)
+{
+	return -ENOSYS;
+}
+
+static inline int regulator_set_enable(struct udevice *dev, bool enable)
+{
+	return -ENOSYS;
+}
+
+static inline int regulator_set_enable_if_allowed(struct udevice *dev, bool enable)
+{
+	return -ENOSYS;
+}
+
+static inline int regulator_set_suspend_enable(struct udevice *dev, bool enable)
+{
+	return -ENOSYS;
+}
+
+static inline int regulator_get_suspend_enable(struct udevice *dev)
+{
+	return -ENOSYS;
+}
+
+static inline int regulator_get_mode(struct udevice *dev)
+{
+	return -ENOSYS;
+}
+
+static inline int regulator_set_mode(struct udevice *dev, int mode_id)
+{
+	return -ENOSYS;
+}
+
+static inline int regulators_enable_boot_on(bool verbose)
+{
+	return -ENOSYS;
+}
+
+static inline int regulator_autoset(struct udevice *dev)
+{
+	return -ENOSYS;
+}
+
+static inline int regulator_autoset_by_name(const char *platname, struct udevice **devp)
+{
+	return -ENOSYS;
+}
+
+static inline int regulator_list_autoset(const char *list_platname[], struct udevice *list_devp[],
+					 bool verbose)
+{
+	return -ENOSYS;
+}
+
+static inline int regulator_get_by_devname(const char *devname, struct udevice **devp)
+{
+	return -ENOSYS;
+}
+
+static inline int regulator_get_by_platname(const char *platname, struct udevice **devp)
+{
+	return -ENOSYS;
+}
+
+static inline int device_get_supply_regulator(struct udevice *dev, const char *supply_name,
+					       struct udevice **devp)
+{
+	return -ENOSYS;
+}
+#endif
 
 #endif /* _INCLUDE_REGULATOR_H_ */
diff --git a/include/xen/interface/xen.h b/include/xen/interface/xen.h
index a7c8ed7..eec8ab7 100644
--- a/include/xen/interface/xen.h
+++ b/include/xen/interface/xen.h
@@ -76,12 +76,6 @@
 #define __HYPERVISOR_arch_6               54
 #define __HYPERVISOR_arch_7               55
 
-/*
- * Commands to HYPERVISOR_console_io().
- */
-#define CONSOLEIO_write         0
-#define CONSOLEIO_read          1
-
 #ifndef __ASSEMBLY__
 
 typedef u16 domid_t;
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index bf78176..b26ac9f 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -6,18 +6,20 @@
  */
 
 #include <common.h>
+#include <bootm.h>
 #include <div64.h>
+#include <dm/device.h>
+#include <dm/root.h>
 #include <efi_loader.h>
 #include <irq_func.h>
 #include <log.h>
 #include <malloc.h>
-#include <time.h>
-#include <linux/libfdt_env.h>
-#include <u-boot/crc.h>
-#include <bootm.h>
 #include <pe.h>
+#include <time.h>
 #include <u-boot/crc.h>
+#include <usb.h>
 #include <watchdog.h>
+#include <linux/libfdt_env.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -1994,7 +1996,10 @@
 			list_del(&evt->link);
 	}
 
+	if IS_ENABLED(CONFIG_USB_DEVICE)
+		udc_disconnect();
 	board_quiesce_devices();
+	dm_remove_devices_flags(DM_REMOVE_ACTIVE_ALL);
 
 	/* Patch out unsupported runtime function */
 	efi_runtime_detach();
diff --git a/lib/efi_loader/efi_runtime.c b/lib/efi_loader/efi_runtime.c
index dea2b4e..1fa1595 100644
--- a/lib/efi_loader/efi_runtime.c
+++ b/lib/efi_loader/efi_runtime.c
@@ -266,9 +266,13 @@
 	time->hour = tm.tm_hour;
 	time->minute = tm.tm_min;
 	time->second = tm.tm_sec;
-	if (tm.tm_isdst)
+	if (tm.tm_isdst > 0)
 		time->daylight =
 			EFI_TIME_ADJUST_DAYLIGHT | EFI_TIME_IN_DAYLIGHT;
+	else if (!tm.tm_isdst)
+		time->daylight = EFI_TIME_ADJUST_DAYLIGHT;
+	else
+		time->daylight = 0;
 	time->timezone = EFI_UNSPECIFIED_TIMEZONE;
 
 	if (capabilities) {
@@ -347,8 +351,17 @@
 	tm.tm_hour = time->hour;
 	tm.tm_min = time->minute;
 	tm.tm_sec = time->second;
-	tm.tm_isdst = time->daylight ==
-		      (EFI_TIME_ADJUST_DAYLIGHT | EFI_TIME_IN_DAYLIGHT);
+	switch (time->daylight) {
+	case EFI_TIME_ADJUST_DAYLIGHT:
+		tm.tm_isdst = 0;
+		break;
+	case EFI_TIME_ADJUST_DAYLIGHT | EFI_TIME_IN_DAYLIGHT:
+		tm.tm_isdst = 1;
+		break;
+	default:
+		tm.tm_isdst = -1;
+		break;
+	}
 	/* Calculate day of week */
 	rtc_calc_weekday(&tm);
 
diff --git a/lib/trace.c b/lib/trace.c
index 831283c..defc971 100644
--- a/lib/trace.c
+++ b/lib/trace.c
@@ -57,7 +57,7 @@
 	return offset / FUNC_SITE_SIZE;
 }
 
-#if defined(CONFIG_EFI_LOADER) && defined(CONFIG_ARM)
+#if defined(CONFIG_EFI_LOADER) && (defined(CONFIG_ARM) || defined(CONFIG_RISCV))
 
 /**
  * trace_gd - the value of the gd register
diff --git a/post/post.c b/post/post.c
index 6687e0b..0f1fe8d 100644
--- a/post/post.c
+++ b/post/post.c
@@ -189,7 +189,7 @@
 		last = 0;
 		name = list;
 		while (!last) {
-			while (*name && *name == ' ')
+			while (*name == ' ')
 				name++;
 			if (*name == 0)
 				break;
diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt
index dabe329..a950844 100644
--- a/scripts/config_whitelist.txt
+++ b/scripts/config_whitelist.txt
@@ -287,7 +287,6 @@
 CONFIG_DEBUG_WRITECOUNT
 CONFIG_DEEP_SLEEP
 CONFIG_DEFAULT
-CONFIG_DEFAULT_CONSOLE
 CONFIG_DEFAULT_IMMR
 CONFIG_DESIGNWARE_ETH
 CONFIG_DEVELOP
@@ -4068,7 +4067,6 @@
 CONFIG_VIDEO_MXS
 CONFIG_VIDEO_MXS_MODE_SYSTEM
 CONFIG_VIDEO_STD_TIMINGS
-CONFIG_VIDEO_VCXK
 CONFIG_VID_FLS_ENV
 CONFIG_VM86
 CONFIG_VOIPAC_LCD
diff --git a/test/dm/Makefile b/test/dm/Makefile
index e2b0798..8b3d77e 100644
--- a/test/dm/Makefile
+++ b/test/dm/Makefile
@@ -34,6 +34,7 @@
 obj-$(CONFIG_LED) += led.o
 obj-$(CONFIG_DM_MAILBOX) += mailbox.o
 obj-$(CONFIG_DM_MMC) += mmc.o
+obj-$(CONFIG_CMD_MUX) += mux-cmd.o
 obj-y += fdtdec.o
 obj-y += ofnode.o
 obj-y += ofread.o
@@ -57,6 +58,8 @@
 obj-$(CONFIG_SMEM) += smem.o
 obj-$(CONFIG_DM_SPI) += spi.o
 obj-y += syscon.o
+obj-$(CONFIG_MUX_MMIO) += mux-mmio.o
+obj-$(CONFIG_MULTIPLEXER) += mux-emul.o
 obj-$(CONFIG_DM_USB) += usb.o
 obj-$(CONFIG_DM_PMIC) += pmic.o
 obj-$(CONFIG_DM_REGULATOR) += regulator.o
diff --git a/test/dm/mux-cmd.c b/test/dm/mux-cmd.c
new file mode 100644
index 0000000..11c237b
--- /dev/null
+++ b/test/dm/mux-cmd.c
@@ -0,0 +1,177 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 Texas Instruments Inc.
+ * Pratyush Yadav <p.yadav@ti.com>
+ */
+#include <common.h>
+#include <dm.h>
+#include <mux.h>
+#include <mux-internal.h>
+#include <dt-bindings/mux/mux.h>
+#include <asm/test.h>
+#include <dm/test.h>
+#include <test/ut.h>
+#include <console.h>
+#include <rand.h>
+
+#define BUF_SIZE		256
+
+/* Test 'mux list' */
+static int dm_test_cmd_mux_list(struct unit_test_state *uts)
+{
+	char str[BUF_SIZE], *tok;
+	struct udevice *dev;
+	struct mux_chip *chip;
+	struct mux_control *mux;
+	int i;
+	unsigned long val;
+
+	sandbox_set_enable_memio(true);
+
+	ut_assertok(uclass_get_device_by_name(UCLASS_MUX, "a-mux-controller",
+					      &dev));
+	chip = dev_get_uclass_priv(dev);
+	ut_assertnonnull(chip);
+
+	run_command("mux list", 0);
+	ut_assert_nextline("a-mux-controller:");
+
+	/*
+	 * Check the table header to make sure we are not out of sync with the
+	 * code in the command. If we are, catch it early.
+	 */
+	console_record_readline(str, BUF_SIZE);
+	tok = strtok(str, " ");
+	ut_asserteq_str("ID", tok);
+
+	tok = strtok(NULL, " ");
+	ut_asserteq_str("Selected", tok);
+
+	tok = strtok(NULL, " ");
+	ut_asserteq_str("Current", tok);
+	tok = strtok(NULL, " ");
+	ut_asserteq_str("State", tok);
+
+	tok = strtok(NULL, " ");
+	ut_asserteq_str("Idle", tok);
+	tok = strtok(NULL, " ");
+	ut_asserteq_str("State", tok);
+
+	tok = strtok(NULL, " ");
+	ut_asserteq_str("Num", tok);
+	tok = strtok(NULL, " ");
+	ut_asserteq_str("States", tok);
+
+	for (i = 0; i < chip->controllers; i++) {
+		mux = &chip->mux[i];
+
+		console_record_readline(str, BUF_SIZE);
+
+		/*
+		 * Check if the ID printed matches with the ID of the chip we
+		 * have.
+		 */
+		tok = strtok(str, " ");
+		ut_assertok(strict_strtoul(tok, 10, &val));
+		ut_asserteq(i, val);
+
+		/* Check if mux selection state matches. */
+		tok = strtok(NULL, " ");
+		if (mux->in_use) {
+			ut_asserteq_str("yes", tok);
+		} else {
+			ut_asserteq_str("no", tok);
+		}
+
+		/* Check if the current state matches. */
+		tok = strtok(NULL, " ");
+		if (mux->cached_state == MUX_IDLE_AS_IS) {
+			ut_asserteq_str("unknown", tok);
+		} else {
+			ut_assertok(strict_strtoul(tok, 16, &val));
+			ut_asserteq(mux->cached_state, val);
+		}
+
+		/* Check if the idle state matches */
+		tok = strtok(NULL, " ");
+		if (mux->idle_state == MUX_IDLE_AS_IS) {
+			ut_asserteq_str("as-is", tok);
+		} else {
+			ut_assertok(strict_strtoul(tok, 16, &val));
+			ut_asserteq(mux->idle_state, val);
+		}
+
+		/* Check if the number of states matches */
+		tok = strtok(NULL, " ");
+		ut_assertok(strict_strtoul(tok, 16, &val));
+		ut_asserteq(mux->states, val);
+	}
+
+	return 0;
+}
+DM_TEST(dm_test_cmd_mux_list, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
+
+static int dm_test_cmd_mux_select(struct unit_test_state *uts)
+{
+	struct udevice *dev;
+	struct mux_chip *chip;
+	struct mux_control *mux;
+	char cmd[BUF_SIZE];
+	unsigned int i, state;
+
+	sandbox_set_enable_memio(true);
+
+	ut_assertok(uclass_get_device_by_name(UCLASS_MUX, "a-mux-controller",
+					      &dev));
+	chip = dev_get_uclass_priv(dev);
+	ut_assertnonnull(chip);
+
+	srand(get_ticks() + rand());
+	for (i = 0; i < chip->controllers; i++) {
+		mux = &chip->mux[i];
+
+		state = rand() % mux->states;
+
+		snprintf(cmd, BUF_SIZE, "mux select a-mux-controller %x %x", i,
+			 state);
+		run_command(cmd, 0);
+		ut_asserteq(!!mux->in_use, true);
+		ut_asserteq(state, mux->cached_state);
+
+		ut_assertok(mux_control_deselect(mux));
+	}
+
+	return 0;
+}
+DM_TEST(dm_test_cmd_mux_select, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
+
+static int dm_test_cmd_mux_deselect(struct unit_test_state *uts)
+{
+	struct udevice *dev;
+	struct mux_chip *chip;
+	struct mux_control *mux;
+	char cmd[BUF_SIZE];
+	unsigned int i, state;
+
+	sandbox_set_enable_memio(true);
+
+	ut_assertok(uclass_get_device_by_name(UCLASS_MUX, "a-mux-controller",
+					      &dev));
+	chip = dev_get_uclass_priv(dev);
+	ut_assertnonnull(chip);
+
+	srand(get_ticks() + rand());
+	for (i = 0; i < chip->controllers; i++) {
+		mux = &chip->mux[i];
+
+		state = rand() % mux->states;
+		ut_assertok(mux_control_select(mux, state));
+
+		snprintf(cmd, BUF_SIZE, "mux deselect a-mux-controller %d", i);
+		run_command(cmd, 0);
+		ut_asserteq(!!mux->in_use, false);
+	}
+
+	return 0;
+}
+DM_TEST(dm_test_cmd_mux_deselect, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
diff --git a/test/dm/mux-emul.c b/test/dm/mux-emul.c
new file mode 100644
index 0000000..141fd4d
--- /dev/null
+++ b/test/dm/mux-emul.c
@@ -0,0 +1,105 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/
+ * Pratyush Yadav <p.yadav@ti.com>
+ */
+#include <common.h>
+#include <dm.h>
+#include <mux.h>
+#include <mux-internal.h>
+#include <dm/test.h>
+#include <test/ut.h>
+
+struct mux_emul_priv {
+	u32 state;
+};
+
+static int mux_emul_set(struct mux_control *mux, int state)
+{
+	struct mux_emul_priv *priv = dev_get_priv(mux->dev);
+
+	priv->state = state;
+	return 0;
+}
+
+static int mux_emul_probe(struct udevice *dev)
+{
+	struct mux_chip *mux_chip = dev_get_uclass_priv(dev);
+	struct mux_control *mux;
+	u32 idle_state;
+	int ret;
+
+	ret = mux_alloc_controllers(dev, 1);
+	if (ret < 0)
+		return ret;
+
+	mux = &mux_chip->mux[0];
+
+	ret = dev_read_u32(dev, "idle-state", &idle_state);
+	if (ret)
+		return ret;
+
+	mux->idle_state = idle_state;
+	mux->states = 0x100000;
+
+	return 0;
+}
+
+static const struct mux_control_ops mux_emul_ops = {
+	.set = mux_emul_set,
+};
+
+static const struct udevice_id mux_emul_of_match[] = {
+	{ .compatible = "mux-emul" },
+	{ /* sentinel */ },
+};
+
+U_BOOT_DRIVER(emul_mux) = {
+	.name = "mux-emul",
+	.id = UCLASS_MUX,
+	.of_match = mux_emul_of_match,
+	.ops = &mux_emul_ops,
+	.probe = mux_emul_probe,
+	.priv_auto_alloc_size = sizeof(struct mux_emul_priv),
+};
+
+static int dm_test_mux_emul_default_state(struct unit_test_state *uts)
+{
+	struct udevice *dev;
+	struct mux_control *mux;
+	struct mux_emul_priv *priv;
+
+	ut_assertok(uclass_get_device_by_name(UCLASS_TEST_FDT, "a-test",
+					      &dev));
+	ut_assertok(mux_control_get(dev, "mux4", &mux));
+
+	priv = dev_get_priv(mux->dev);
+
+	ut_asserteq(0xabcd, priv->state);
+
+	return 0;
+}
+DM_TEST(dm_test_mux_emul_default_state, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
+
+static int dm_test_mux_emul_select_deselect(struct unit_test_state *uts)
+{
+	struct udevice *dev;
+	struct mux_control *mux;
+	struct mux_emul_priv *priv;
+
+	gd->flags &= ~(GD_FLG_SILENT | GD_FLG_RECORD);
+	ut_assertok(uclass_get_device_by_name(UCLASS_TEST_FDT, "a-test",
+					      &dev));
+	ut_assertok(mux_control_get(dev, "mux4", &mux));
+
+	priv = dev_get_priv(mux->dev);
+
+	ut_assertok(mux_control_select(mux, 0x1234));
+	ut_asserteq(priv->state, 0x1234);
+
+	ut_assertok(mux_control_deselect(mux));
+	ut_asserteq(priv->state, 0xabcd);
+
+	return 0;
+}
+DM_TEST(dm_test_mux_emul_select_deselect, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
diff --git a/test/dm/mux-mmio.c b/test/dm/mux-mmio.c
new file mode 100644
index 0000000..fd353d8
--- /dev/null
+++ b/test/dm/mux-mmio.c
@@ -0,0 +1,138 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2017-2018 Texas Instruments Incorporated - http://www.ti.com/
+ * Jean-Jacques Hiblot <jjhiblot@ti.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <mux.h>
+#include <regmap.h>
+#include <syscon.h>
+#include <asm/test.h>
+#include <dm/test.h>
+#include <dm/device-internal.h>
+#include <test/ut.h>
+
+static int dm_test_mux_mmio_select(struct unit_test_state *uts)
+{
+	struct udevice *dev, *dev_b;
+	struct regmap *map;
+	struct mux_control *ctl0_a, *ctl0_b;
+	struct mux_control *ctl1;
+	struct mux_control *ctl_err;
+	u32 val;
+	int i;
+
+	sandbox_set_enable_memio(true);
+
+	ut_assertok(uclass_get_device_by_name(UCLASS_TEST_FDT, "a-test",
+					      &dev));
+	ut_assertok(uclass_get_device_by_name(UCLASS_TEST_FDT, "b-test",
+					      &dev_b));
+	map = syscon_regmap_lookup_by_phandle(dev, "mux-syscon");
+	ut_assertok_ptr(map);
+	ut_assert(map);
+
+	ut_assertok(mux_control_get(dev, "mux0", &ctl0_a));
+	ut_assertok(mux_control_get(dev, "mux1", &ctl1));
+	ut_asserteq(-ERANGE, mux_control_get(dev, "mux3", &ctl_err));
+	ut_asserteq(-ENODATA, mux_control_get(dev, "dummy", &ctl_err));
+	ut_assertok(mux_control_get(dev_b, "mux0", &ctl0_b));
+
+	for (i = 0; i < mux_control_states(ctl0_a); i++) {
+		/* Select a new state and verify the value in the regmap. */
+		ut_assertok(mux_control_select(ctl0_a, i));
+		ut_assertok(regmap_read(map, 0, &val));
+		ut_asserteq(i, (val & 0x30) >> 4);
+		/*
+		 * Deselect the mux and verify that the value in the regmap
+		 * reflects the idle state (fixed to MUX_IDLE_AS_IS).
+		 */
+		ut_assertok(mux_control_deselect(ctl0_a));
+		ut_assertok(regmap_read(map, 0, &val));
+		ut_asserteq(i, (val & 0x30) >> 4);
+	}
+
+	for (i = 0; i < mux_control_states(ctl1); i++) {
+		/* Select a new state and verify the value in the regmap. */
+		ut_assertok(mux_control_select(ctl1, i));
+		ut_assertok(regmap_read(map, 0xc, &val));
+		ut_asserteq(i, (val & 0x1E) >> 1);
+		/*
+		 * Deselect the mux and verify that the value in the regmap
+		 * reflects the idle state (fixed to 2).
+		 */
+		ut_assertok(mux_control_deselect(ctl1));
+		ut_assertok(regmap_read(map, 0xc, &val));
+		ut_asserteq(2, (val & 0x1E) >> 1);
+	}
+
+	/* Try unbalanced selection/deselection. */
+	ut_assertok(mux_control_select(ctl0_a, 0));
+	ut_asserteq(-EBUSY, mux_control_select(ctl0_a, 1));
+	ut_asserteq(-EBUSY, mux_control_select(ctl0_a, 0));
+	ut_assertok(mux_control_deselect(ctl0_a));
+
+	/* Try concurrent selection. */
+	ut_assertok(mux_control_select(ctl0_a, 0));
+	ut_assert(mux_control_select(ctl0_b, 0));
+	ut_assertok(mux_control_deselect(ctl0_a));
+	ut_assertok(mux_control_select(ctl0_b, 0));
+	ut_assert(mux_control_select(ctl0_a, 0));
+	ut_assertok(mux_control_deselect(ctl0_b));
+	ut_assertok(mux_control_select(ctl0_a, 0));
+	ut_assertok(mux_control_deselect(ctl0_a));
+
+	return 0;
+}
+DM_TEST(dm_test_mux_mmio_select, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
+
+/* Test that managed API for mux work correctly */
+static int dm_test_devm_mux_mmio(struct unit_test_state *uts)
+{
+	struct udevice *dev, *dev_b;
+	struct mux_control *ctl0_a, *ctl0_b;
+	struct mux_control *ctl1;
+	struct mux_control *ctl_err;
+
+	sandbox_set_enable_memio(true);
+
+	ut_assertok(uclass_get_device_by_name(UCLASS_TEST_FDT, "a-test",
+					      &dev));
+	ut_assertok(uclass_get_device_by_name(UCLASS_TEST_FDT, "b-test",
+					      &dev_b));
+
+	ctl0_a = devm_mux_control_get(dev, "mux0");
+	ut_assertok_ptr(ctl0_a);
+	ut_assert(ctl0_a);
+	ctl1 = devm_mux_control_get(dev, "mux1");
+	ut_assertok_ptr(ctl1);
+	ut_assert(ctl1);
+	ctl_err = devm_mux_control_get(dev, "mux3");
+	ut_asserteq(-ERANGE, PTR_ERR(ctl_err));
+	ctl_err = devm_mux_control_get(dev, "dummy");
+	ut_asserteq(-ENODATA, PTR_ERR(ctl_err));
+
+	ctl0_b = devm_mux_control_get(dev_b, "mux0");
+	ut_assertok_ptr(ctl0_b);
+	ut_assert(ctl0_b);
+
+	/* Try concurrent selection. */
+	ut_assertok(mux_control_select(ctl0_a, 0));
+	ut_assert(mux_control_select(ctl0_b, 0));
+	ut_assertok(mux_control_deselect(ctl0_a));
+	ut_assertok(mux_control_select(ctl0_b, 0));
+	ut_assert(mux_control_select(ctl0_a, 0));
+	ut_assertok(mux_control_deselect(ctl0_b));
+
+	/* Remove one device and check that the mux is released. */
+	ut_assertok(mux_control_select(ctl0_a, 0));
+	ut_assert(mux_control_select(ctl0_b, 0));
+	device_remove(dev, DM_REMOVE_NORMAL);
+	ut_assertok(mux_control_select(ctl0_b, 0));
+
+	device_remove(dev_b, DM_REMOVE_NORMAL);
+	return 0;
+}
+DM_TEST(dm_test_devm_mux_mmio, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
diff --git a/test/lib/Makefile b/test/lib/Makefile
index 22236f8..15cd512 100644
--- a/test/lib/Makefile
+++ b/test/lib/Makefile
@@ -7,6 +7,7 @@
 obj-$(CONFIG_EFI_SECURE_BOOT) += efi_image_region.o
 obj-y += hexdump.o
 obj-y += lmb.o
+obj-y += test_print.o
 obj-$(CONFIG_SSCANF) += sscanf.o
 obj-y += string.o
 obj-$(CONFIG_ERRNO_STR) += test_errno_str.o
diff --git a/test/lib/test_print.c b/test/lib/test_print.c
new file mode 100644
index 0000000..1d497d0
--- /dev/null
+++ b/test/lib/test_print.c
@@ -0,0 +1,71 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Tests for print functions
+ *
+ * Copyright 2020, Heinrich Schuchadt <xypron.glpk@gmx.de>
+ */
+
+#include <common.h>
+#include <command.h>
+#include <display_options.h>
+#include <test/lib.h>
+#include <test/test.h>
+#include <test/ut.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static int test_print_freq(struct unit_test_state *uts,
+			   uint64_t freq, char *expected)
+{
+	console_record_reset_enable();
+	print_freq(freq, ";\n");
+	gd->flags &= ~GD_FLG_RECORD;
+	console_record_readline(uts->actual_str, sizeof(uts->actual_str));
+	ut_asserteq_str(expected, uts->actual_str);
+	ut_assertok(ut_check_console_end(uts));
+	return 0;
+}
+
+static int lib_test_print_freq(struct unit_test_state *uts)
+{
+	ut_assertok(test_print_freq(uts, 321, "321 Hz;"));
+	ut_assertok(test_print_freq(uts, 4321, "4.32 kHz;"));
+	ut_assertok(test_print_freq(uts, 54321, "54.32 kHz;"));
+	ut_assertok(test_print_freq(uts, 654321, "654.32 kHz;"));
+	ut_assertok(test_print_freq(uts, 7654321, "7.66 MHz;"));
+	ut_assertok(test_print_freq(uts, 87654321, "87.66 MHz;"));
+	ut_assertok(test_print_freq(uts, 987654321, "987.66 MHz;"));
+	ut_assertok(test_print_freq(uts, 1987654321, "1.99 GHz;"));
+	ut_assertok(test_print_freq(uts, 54321987654321, "54321.99 GHz;"));
+	return 0;
+}
+
+LIB_TEST(lib_test_print_freq, 0);
+
+static int test_print_size(struct unit_test_state *uts,
+			   uint64_t freq, char *expected)
+{
+	console_record_reset_enable();
+	print_size(freq, ";\n");
+	gd->flags &= ~GD_FLG_RECORD;
+	console_record_readline(uts->actual_str, sizeof(uts->actual_str));
+	ut_asserteq_str(expected, uts->actual_str);
+	ut_assertok(ut_check_console_end(uts));
+	return 0;
+}
+
+static int lib_test_print_size(struct unit_test_state *uts)
+{
+	ut_assertok(test_print_size(uts, 321, "321 Bytes;"));
+	ut_assertok(test_print_size(uts, 4321, "4.2 KiB;"));
+	ut_assertok(test_print_size(uts, 54321, "53 KiB;"));
+	ut_assertok(test_print_size(uts, 654321, "639 KiB;"));
+	ut_assertok(test_print_size(uts, 7654321, "7.3 MiB;"));
+	ut_assertok(test_print_size(uts, 87654321, "83.6 MiB;"));
+	ut_assertok(test_print_size(uts, 987654321, "941.9 MiB;"));
+	ut_assertok(test_print_size(uts, 1987654321, "1.9 GiB;"));
+	ut_assertok(test_print_size(uts, 54321987654321, "49.4 TiB;"));
+	return 0;
+}
+
+LIB_TEST(lib_test_print_size, 0);
diff --git a/test/log/Makefile b/test/log/Makefile
index 52e2f7b..fdf5295 100644
--- a/test/log/Makefile
+++ b/test/log/Makefile
@@ -13,7 +13,9 @@
 obj-$(CONFIG_LOG_SYSLOG) += syslog_test_ndebug.o
 endif
 
-ifndef CONFIG_LOG
+ifdef CONFIG_LOG
+obj-$(CONFIG_CONSOLE_RECORD) += cont_test.o
+else
 obj-$(CONFIG_CONSOLE_RECORD) += nolog_test.o
 endif
 
diff --git a/test/log/cont_test.c b/test/log/cont_test.c
new file mode 100644
index 0000000..68ca1d2
--- /dev/null
+++ b/test/log/cont_test.c
@@ -0,0 +1,52 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2020, Heinrich Schuchardt <xypron.glpk@gmx.de>
+ *
+ * Test continuation of log messages.
+ */
+
+#include <common.h>
+#include <console.h>
+#include <test/log.h>
+#include <test/test.h>
+#include <test/suites.h>
+#include <test/ut.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define BUFFSIZE 64
+
+static int log_test_cont(struct unit_test_state *uts)
+{
+	int log_fmt;
+	int log_level;
+
+	log_fmt = gd->log_fmt;
+	log_level = gd->default_log_level;
+
+	/* Write two messages, the second continuing the first */
+	gd->log_fmt = (1 << LOGF_CAT) | (1 << LOGF_LEVEL) | (1 << LOGF_MSG);
+	gd->default_log_level = LOGL_INFO;
+	console_record_reset_enable();
+	log(LOGC_ARCH, LOGL_ERR, "ea%d ", 1);
+	log(LOGC_CONT, LOGL_CONT, "cc%d\n", 2);
+	gd->default_log_level = log_level;
+	gd->log_fmt = log_fmt;
+	gd->flags &= ~GD_FLG_RECORD;
+	ut_assertok(ut_check_console_line(uts, "ERR.arch, ea1 ERR.arch, cc2"));
+	ut_assertok(ut_check_console_end(uts));
+
+	/* Write a third message which is not a continuation */
+	gd->log_fmt = (1 << LOGF_CAT) | (1 << LOGF_LEVEL) | (1 << LOGF_MSG);
+	gd->default_log_level = LOGL_INFO;
+	console_record_reset_enable();
+	log(LOGC_EFI, LOGL_INFO, "ie%d\n", 3);
+	gd->default_log_level = log_level;
+	gd->log_fmt = log_fmt;
+	gd->flags &= ~GD_FLG_RECORD;
+	ut_assertok(ut_check_console_line(uts, "INFO.efi, ie3"));
+	ut_assertok(ut_check_console_end(uts));
+
+	return 0;
+}
+LOG_TEST(log_test_cont);
diff --git a/test/py/tests/test_fs/test_ext.py b/test/py/tests/test_fs/test_ext.py
index 6b7fc48..dba874f 100644
--- a/test/py/tests/test_fs/test_ext.py
+++ b/test/py/tests/test_fs/test_ext.py
@@ -74,7 +74,7 @@
                 '%sload host 0:0 %x /%s' % (fs_type, ADDR, MIN_FILE),
                 '%swrite host 0:0 %x /dir1/none/%s.w3 $filesize'
                     % (fs_type, ADDR, MIN_FILE)])
-            assert('Unable to write "/dir1/none/' in ''.join(output))
+            assert('Unable to write file /dir1/none/' in ''.join(output))
             assert_fs_integrity(fs_type, fs_img)
 
     def test_fs_ext4(self, u_boot_console, fs_obj_ext):
@@ -216,7 +216,7 @@
             output = u_boot_console.run_command(
                 '%swrite host 0:0 %x /dir1/%s.w8 0x1400 %x'
                     % (fs_type, ADDR, MIN_FILE, 0x100000 + 0x1400))
-            assert('Unable to write "/dir1' in output)
+            assert('Unable to write file /dir1' in output)
             assert_fs_integrity(fs_type, fs_img)
 
     def test_fs_ext9(self, u_boot_console, fs_obj_ext):
@@ -231,7 +231,7 @@
                 '%sload host 0:0 %x /%s' % (fs_type, ADDR, MIN_FILE),
                 '%swrite host 0:0 %x /dir1/%s.w9 0x1400 0x1400'
                     % (fs_type, ADDR, MIN_FILE)])
-            assert('Unable to write "/dir1' in ''.join(output))
+            assert('Unable to write file /dir1' in ''.join(output))
             assert_fs_integrity(fs_type, fs_img)
 
     def test_fs_ext10(self, u_boot_console, fs_obj_ext):
diff --git a/tools/binman/README.entries b/tools/binman/README.entries
index c1d4365..bdb4fd6 100644
--- a/tools/binman/README.entries
+++ b/tools/binman/README.entries
@@ -385,8 +385,8 @@
         default = "@config-DEFAULT-SEQ";
         @config-SEQ {
             description = "NAME";
-            firmware = "uboot";
-            loadables = "atf";
+            firmware = "atf";
+            loadables = "uboot";
             fdt = "fdt-SEQ";
         };
     };
diff --git a/tools/binman/etype/fit.py b/tools/binman/etype/fit.py
index de4745c..1a7cbd7 100644
--- a/tools/binman/etype/fit.py
+++ b/tools/binman/etype/fit.py
@@ -73,8 +73,8 @@
             default = "@config-DEFAULT-SEQ";
             @config-SEQ {
                 description = "NAME";
-                firmware = "uboot";
-                loadables = "atf";
+                firmware = "atf";
+                loadables = "uboot";
                 fdt = "fdt-SEQ";
             };
         };
@@ -205,10 +205,10 @@
                                         b'SEQ', tools.ToBytes(str(seq + 1)))
                                     fsw.property(pname, val)
 
-                                    # Add data for 'fdt' nodes (but not 'config')
-                                    if depth == 1 and in_images:
-                                        fsw.property('data',
-                                                     tools.ReadFile(fname))
+                                # Add data for 'fdt' nodes (but not 'config')
+                                if depth == 1 and in_images:
+                                    fsw.property('data',
+                                                 tools.ReadFile(fname))
                     else:
                         if self._fdts is None:
                             if self._fit_list_prop:
diff --git a/tools/binman/etype/scp.py b/tools/binman/etype/scp.py
new file mode 100644
index 0000000..93f8787
--- /dev/null
+++ b/tools/binman/etype/scp.py
@@ -0,0 +1,19 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright 2020 Samuel Holland <samuel@sholland.org>
+#
+# Entry-type module for System Control Processor (SCP) firmware blob
+#
+
+from binman.etype.blob_named_by_arg import Entry_blob_named_by_arg
+
+class Entry_scp(Entry_blob_named_by_arg):
+    """Entry containing a System Control Processor (SCP) firmware blob
+
+    Properties / Entry arguments:
+        - scp-path: Filename of file to read into the entry, typically scp.bin
+
+    This entry holds firmware for an external platform-specific coprocessor.
+    """
+    def __init__(self, section, etype, node):
+        super().__init__(section, etype, node, 'scp')
+        self.external = True
diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
index b771b9d..75f6ca3 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -75,6 +75,7 @@
 FSP_S_DATA            = b'fsp_s'
 FSP_T_DATA            = b'fsp_t'
 ATF_BL31_DATA         = b'bl31'
+SCP_DATA              = b'scp'
 TEST_FDT1_DATA        = b'fdt1'
 TEST_FDT2_DATA        = b'test-fdt2'
 ENV_DATA              = b'var1=1\nvar2="2"'
@@ -175,6 +176,7 @@
 
         TestFunctional._MakeInputFile('compress', COMPRESS_DATA)
         TestFunctional._MakeInputFile('bl31.bin', ATF_BL31_DATA)
+        TestFunctional._MakeInputFile('scp.bin', SCP_DATA)
 
         # Add a few .dtb files for testing
         TestFunctional._MakeInputFile('%s/test-fdt1.dtb' % TEST_FDT_SUBDIR,
@@ -3578,6 +3580,11 @@
         data = self._DoReadFile('169_atf_bl31.dts')
         self.assertEqual(ATF_BL31_DATA, data[:len(ATF_BL31_DATA)])
 
+    def testPackScp(self):
+        """Test that an image with an SCP binary can be created"""
+        data = self._DoReadFile('172_scp.dts')
+        self.assertEqual(SCP_DATA, data[:len(SCP_DATA)])
+
     def testFitFdt(self):
         """Test an image with an FIT with multiple FDT images"""
         def _CheckFdt(seq, expected_data):
diff --git a/tools/binman/missing-blob-help b/tools/binman/missing-blob-help
index 7cf1c34..f7bc80e 100644
--- a/tools/binman/missing-blob-help
+++ b/tools/binman/missing-blob-help
@@ -13,3 +13,7 @@
 atf-bl31-sunxi:
 Please read the section on ARM Trusted Firmware (ATF) in
 board/sunxi/README.sunxi64
+
+scp-sunxi:
+SCP firmware is required for system suspend, but is otherwise optional.
+Please read the section on SCP firmware in board/sunxi/README.sunxi64
diff --git a/tools/binman/test/172_scp.dts b/tools/binman/test/172_scp.dts
new file mode 100644
index 0000000..354e4ef
--- /dev/null
+++ b/tools/binman/test/172_scp.dts
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	binman {
+		size = <16>;
+
+		scp {
+			filename = "scp.bin";
+		};
+	};
+};