Merge tag 'u-boot-at91-2024.04-a' of https://source.denx.de/u-boot/custodians/u-boot-at91

First set of u-boot-at91 features for the 2024.04 cycle:

This set includes some DT alignments and solves a compile issue for
custom nand defconfigs.
diff --git a/Makefile b/Makefile
index 7a3209b..3afe314 100644
--- a/Makefile
+++ b/Makefile
@@ -1,9 +1,9 @@
 # SPDX-License-Identifier: GPL-2.0+
 
 VERSION = 2024
-PATCHLEVEL = 01
+PATCHLEVEL = 04
 SUBLEVEL =
-EXTRAVERSION =
+EXTRAVERSION = -rc1
 NAME =
 
 # *DOCUMENTATION*
diff --git a/arch/Kconfig b/arch/Kconfig
index c23d57e..b6fb9e9 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -149,6 +149,7 @@
 	select GZIP_COMPRESSED
 	select IO_TRACE
 	select LZO
+	select MTD
 	select OF_BOARD_SETUP
 	select PCI_ENDPOINT
 	select SPI
@@ -254,6 +255,7 @@
 	imply DM_RTC
 	imply SCSI
 	imply DM_SERIAL
+	imply MTD
 	imply DM_SPI
 	imply DM_SPI_FLASH
 	imply DM_USB
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index efb7053..59e4d4d 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -614,6 +614,7 @@
 	select DM_SPI
 	select DM_SPI_FLASH
 	select GPIO_EXTRA_HEADER
+	select MTD
 	select SPL_DM_SPI if SPL
 	select SPL_DM_SPI_FLASH if SPL
 	select SPL_TIMER if SPL
@@ -639,6 +640,7 @@
 	select DM_SPI_FLASH
 	select GPIO_EXTRA_HEADER
 	select PL01X_SERIAL
+	select MTD
 	select SPI
 	select SPI_FLASH
 	imply CMD_DM
@@ -724,6 +726,7 @@
 	select DM_SERIAL
 	select DM_SPI
 	select DM_SPI_FLASH
+	select MTD
 	select SPI
 	select GPIO_EXTRA_HEADER
 	imply SYS_THUMB_BUILD
@@ -1008,6 +1011,7 @@
 	select VIDEO
 	select IOMMU
 	select LINUX_KERNEL_IMAGE_HEADER
+	select MTD
 	select OF_BOARD_SETUP
 	select OF_CONTROL
 	select PCI
@@ -1120,6 +1124,7 @@
 	imply DM_SPI
 	imply DM_SPI_FLASH
 	imply FAT_WRITE
+	imply MTD
 	imply SPL
 	imply SPL_DM
 	imply SPL_DM_SPI
@@ -1143,7 +1148,7 @@
 	select DM_GPIO
 	select DM_I2C if I2C
 	select DM_SPI if SPI
-	select DM_SPI_FLASH if SPI
+	select DM_SPI_FLASH if SPI && MTD
 	select DM_KEYBOARD
 	select DM_MMC if MMC
 	select DM_SERIAL
@@ -1155,14 +1160,14 @@
 	select SPL_SEPARATE_BSS if SPL
 	select SPL_STACK_R if SPL
 	select SPL_SYS_MALLOC_SIMPLE if SPL
-	select SPL_SYS_THUMB_BUILD if !ARM64
+	select SPL_SYS_THUMB_BUILD if SPL && !ARM64
 	select SUNXI_GPIO
 	select SYS_NS16550
 	select SYS_THUMB_BUILD if !ARM64
 	select USB if DISTRO_DEFAULTS
 	select USB_KEYBOARD if DISTRO_DEFAULTS && USB_HOST
 	select USB_STORAGE if DISTRO_DEFAULTS && USB_HOST
-	select SPL_USE_TINY_PRINTF
+	select SPL_USE_TINY_PRINTF if SPL
 	select USE_PREBOOT
 	select SYS_RELOC_GD_ENV_ADDR
 	imply BOARD_LATE_INIT
@@ -1261,6 +1266,7 @@
 	select DM_SPI
 	select DM_SPI_FLASH
 	select OF_CONTROL
+	select MTD
 	select SPI
 	select SPL_BOARD_INIT if SPL
 	select SPL_CLK if SPL
@@ -1299,6 +1305,7 @@
 	imply DM_MAILBOX
 	select DM_MMC if MMC
 	select DM_SERIAL
+	select MTD
 	select DM_SPI if SPI
 	select DM_SPI_FLASH if DM_SPI
 	imply FIRMWARE
@@ -1845,6 +1852,7 @@
 	select DM_GPIO
 	select DM_I2C
 	select DM_MMC
+	select MTD
 	select DM_SPI_FLASH
 	select DM_MDIO
 	select PCI
@@ -1989,6 +1997,7 @@
 	select DM_USB_GADGET if USB_DWC3_GADGET
 	select ENABLE_ARM_SOC_BOOT0_HOOK
 	select OF_CONTROL
+	select MTD
 	select SPI
 	select SPL_DM if SPL
 	select SPL_DM_SPI if SPL
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index b5c588c..50f35e3 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -838,6 +838,7 @@
 dtb-$(CONFIG_MACH_SUN50I_H616) += \
 	sun50i-h616-orangepi-zero2.dtb \
 	sun50i-h618-orangepi-zero3.dtb \
+	sun50i-h618-transpeed-8k618-t.dtb \
 	sun50i-h616-x96-mate.dtb
 dtb-$(CONFIG_MACH_SUN50I) += \
 	sun50i-a64-amarula-relic.dtb \
diff --git a/arch/arm/dts/imx6qdl-wandboard-u-boot.dtsi b/arch/arm/dts/imx6qdl-wandboard-u-boot.dtsi
index 46c4b3b..80921e8 100644
--- a/arch/arm/dts/imx6qdl-wandboard-u-boot.dtsi
+++ b/arch/arm/dts/imx6qdl-wandboard-u-boot.dtsi
@@ -6,4 +6,14 @@
 	aliases {
 		mmc0 = &usdhc3;
 	};
+
+	wdt-reboot {
+		compatible = "wdt-reboot";
+		wdt = <&wdog1>;
+		bootph-pre-ram;
+	};
+};
+
+&wdog1 {
+	bootph-pre-ram;
 };
diff --git a/arch/arm/dts/socfpga_agilex.dtsi b/arch/arm/dts/socfpga_agilex.dtsi
index c3ead2d..712304d 100644
--- a/arch/arm/dts/socfpga_agilex.dtsi
+++ b/arch/arm/dts/socfpga_agilex.dtsi
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier:     GPL-2.0
 /*
- * Copyright (C) 2019, Intel Corporation
+ * Copyright (C) 2019-2023 Intel Corporation <www.intel.com>
  */
 
 /dts-v1/;
@@ -20,7 +20,7 @@
 
 		service_reserved: svcbuffer@0 {
 			compatible = "shared-dma-pool";
-			reg = <0x0 0x0 0x0 0x1000000>;
+			reg = <0x0 0x0 0x0 0x2000000>;
 			alignment = <0x1000>;
 			no-map;
 		};
diff --git a/arch/arm/dts/sun50i-h616-bigtreetech-cb1-manta.dts b/arch/arm/dts/sun50i-h616-bigtreetech-cb1-manta.dts
new file mode 100644
index 0000000..dbce61b
--- /dev/null
+++ b/arch/arm/dts/sun50i-h616-bigtreetech-cb1-manta.dts
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: (GPL-2.0+ or MIT)
+/*
+ * Copyright (C) 2023 Martin Botka <martin.botka@somainline.org>.
+ */
+
+/dts-v1/;
+
+#include "sun50i-h616-bigtreetech-cb1.dtsi"
+
+/ {
+	model = "BigTreeTech CB1";
+	compatible = "bigtreetech,cb1-manta", "bigtreetech,cb1", "allwinner,sun50i-h616";
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+};
+
+&ehci1 {
+	status = "okay";
+};
+
+&ohci1 {
+	status = "okay";
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_ph_pins>;
+	status = "okay";
+};
diff --git a/arch/arm/dts/sun50i-h616-bigtreetech-cb1.dtsi b/arch/arm/dts/sun50i-h616-bigtreetech-cb1.dtsi
new file mode 100644
index 0000000..1fed2b4
--- /dev/null
+++ b/arch/arm/dts/sun50i-h616-bigtreetech-cb1.dtsi
@@ -0,0 +1,138 @@
+// SPDX-License-Identifier: (GPL-2.0+ or MIT)
+/*
+ * Copyright (C) 2023 Martin Botka <martin.botka@somainline.org>.
+ */
+
+/dts-v1/;
+
+#include "sun50i-h616.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+	aliases {
+		ethernet0 = &rtl8189ftv;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led-0 {
+			function = LED_FUNCTION_STATUS;
+			color = <LED_COLOR_ID_GREEN>;
+			gpios = <&pio 7 5 GPIO_ACTIVE_HIGH>; /* PH5 */
+		};
+	};
+
+	reg_vcc5v: regulator-vcc5v {
+		/* board wide 5V supply from carrier boards */
+		compatible = "regulator-fixed";
+		regulator-name = "vcc-5v";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-always-on;
+	};
+
+	reg_vcc33_wifi: vcc33-wifi {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc33-wifi";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-always-on;
+		vin-supply = <&reg_vcc5v>;
+	};
+
+	reg_vcc_wifi_io: vcc-wifi-io {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc-wifi-io";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		regulator-always-on;
+		vin-supply = <&reg_vcc33_wifi>;
+	};
+
+	wifi_pwrseq: wifi-pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		clocks = <&rtc 1>;
+		clock-names = "ext_clock";
+		reset-gpios = <&pio 6 18 GPIO_ACTIVE_LOW>; /* PG18 */
+		post-power-on-delay-ms = <200>;
+	};
+};
+
+&mmc0 {
+	vmmc-supply = <&reg_dldo1>;
+	/* Card detection pin is not connected */
+	broken-cd;
+	bus-width = <4>;
+	status = "okay";
+};
+
+&mmc1 {
+	vmmc-supply = <&reg_vcc33_wifi>;
+	vqmmc-supply = <&reg_vcc_wifi_io>;
+	mmc-pwrseq = <&wifi_pwrseq>;
+	bus-width = <4>;
+	non-removable;
+	mmc-ddr-1_8v;
+	status = "okay";
+
+	rtl8189ftv: wifi@1 {
+		reg = <1>;
+	};
+};
+
+&r_i2c {
+	status = "okay";
+
+	axp313a: pmic@36 {
+		compatible = "x-powers,axp313a";
+		reg = <0x36>;
+		interrupt-controller;
+		#interrupt-cells = <1>;
+
+		regulators{
+			reg_dcdc1: dcdc1 {
+				regulator-name = "vdd-gpu-sys";
+				regulator-min-microvolt = <810000>;
+				regulator-max-microvolt = <990000>;
+				regulator-always-on;
+			};
+
+			reg_dcdc2: dcdc2 {
+				regulator-name = "vdd-cpu";
+				regulator-min-microvolt = <810000>;
+				regulator-max-microvolt = <1100000>;
+				regulator-ramp-delay = <200>;
+				regulator-always-on;
+			};
+
+			reg_dcdc3: dcdc3 {
+				regulator-name = "vcc-dram";
+				regulator-min-microvolt = <1350000>;
+				regulator-max-microvolt = <1500000>;
+				regulator-always-on;
+			};
+
+			reg_aldo1: aldo1 {
+				regulator-name = "vcc-1v8-pll";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
+			};
+
+			reg_dldo1: dldo1 {
+				regulator-name = "vcc-3v3-io";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-always-on;
+			};
+		};
+	};
+};
+
+&usbphy {
+	status = "okay";
+};
diff --git a/arch/arm/dts/sun50i-h616-bigtreetech-pi.dts b/arch/arm/dts/sun50i-h616-bigtreetech-pi.dts
new file mode 100644
index 0000000..832f08b
--- /dev/null
+++ b/arch/arm/dts/sun50i-h616-bigtreetech-pi.dts
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: (GPL-2.0+ or MIT)
+/*
+ * Copyright (C) 2023 Martin Botka <martin@biqu3d.com>.
+ */
+
+/dts-v1/;
+
+#include "sun50i-h616-bigtreetech-cb1.dtsi"
+
+/ {
+	model = "BigTreeTech Pi";
+	compatible = "bigtreetech,pi", "allwinner,sun50i-h616";
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+};
+
+&ehci0 {
+	status = "okay";
+};
+
+&ehci1 {
+	status = "okay";
+};
+
+&ehci2 {
+	status = "okay";
+};
+
+&ehci3 {
+	status = "okay";
+};
+
+&ir {
+	status = "okay";
+};
+
+&ohci0 {
+	status = "okay";
+};
+
+&ohci1 {
+	status = "okay";
+};
+
+&ohci2 {
+	status = "okay";
+};
+
+&ohci3 {
+	status = "okay";
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_ph_pins>;
+	status = "okay";
+};
diff --git a/arch/arm/dts/sun50i-h616.dtsi b/arch/arm/dts/sun50i-h616.dtsi
index 74aed0d..d549d27 100644
--- a/arch/arm/dts/sun50i-h616.dtsi
+++ b/arch/arm/dts/sun50i-h616.dtsi
@@ -133,6 +133,13 @@
 			#reset-cells = <1>;
 		};
 
+		sid: efuse@3006000 {
+			compatible = "allwinner,sun50i-h616-sid", "allwinner,sun50i-a64-sid";
+			reg = <0x03006000 0x1000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+		};
+
 		watchdog: watchdog@30090a0 {
 			compatible = "allwinner,sun50i-h616-wdt",
 				     "allwinner,sun6i-a31-wdt";
diff --git a/arch/arm/dts/sun50i-h618-orangepi-zero2w.dts b/arch/arm/dts/sun50i-h618-orangepi-zero2w.dts
new file mode 100644
index 0000000..21ca197
--- /dev/null
+++ b/arch/arm/dts/sun50i-h618-orangepi-zero2w.dts
@@ -0,0 +1,176 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2023 Arm Ltd.
+ */
+
+/dts-v1/;
+
+#include "sun50i-h616.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+	model = "OrangePi Zero 2W";
+	compatible = "xunlong,orangepi-zero2w", "allwinner,sun50i-h618";
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led-0 {
+			function = LED_FUNCTION_STATUS;
+			color = <LED_COLOR_ID_GREEN>;
+			gpios = <&pio 2 13 GPIO_ACTIVE_HIGH>; /* PC13 */
+		};
+	};
+
+	reg_vcc5v: vcc5v {
+		/* board wide 5V supply directly from the USB-C socket */
+		compatible = "regulator-fixed";
+		regulator-name = "vcc-5v";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-always-on;
+	};
+
+	reg_vcc3v3: vcc3v3 {
+		/* SY8089 DC/DC converter */
+		compatible = "regulator-fixed";
+		regulator-name = "vcc-3v3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&reg_vcc5v>;
+		regulator-always-on;
+	};
+};
+
+&ehci1 {
+	status = "okay";
+};
+
+/* USB 2 & 3 are on the FPC connector (or the exansion board) */
+
+&mmc0 {
+	cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>;	/* PF6 */
+	bus-width = <4>;
+	vmmc-supply = <&reg_vcc3v3>;
+	status = "okay";
+};
+
+&ohci1 {
+	status = "okay";
+};
+
+&pio {
+	vcc-pc-supply = <&reg_dldo1>;
+	vcc-pf-supply = <&reg_dldo1>;	/* internally via VCC-IO */
+	vcc-pg-supply = <&reg_aldo1>;
+	vcc-ph-supply = <&reg_dldo1>;	/* internally via VCC-IO */
+	vcc-pi-supply = <&reg_dldo1>;
+};
+
+&r_i2c {
+	status = "okay";
+
+	axp313: pmic@36 {
+		compatible = "x-powers,axp313a";
+		reg = <0x36>;
+		#interrupt-cells = <1>;
+		interrupt-controller;
+		interrupt-parent = <&pio>;
+		interrupts = <2 9 IRQ_TYPE_LEVEL_LOW>;	/* PC9 */
+
+		vin1-supply = <&reg_vcc5v>;
+		vin2-supply = <&reg_vcc5v>;
+		vin3-supply = <&reg_vcc5v>;
+
+		regulators {
+			/* Supplies VCC-PLL and DRAM */
+			reg_aldo1: aldo1 {
+				regulator-always-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vcc1v8";
+			};
+
+			/* Supplies VCC-IO, so needs to be always on. */
+			reg_dldo1: dldo1 {
+				regulator-always-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-name = "vcc3v3";
+			};
+
+			reg_dcdc1: dcdc1 {
+				regulator-always-on;
+				regulator-min-microvolt = <810000>;
+				regulator-max-microvolt = <990000>;
+				regulator-name = "vdd-gpu-sys";
+			};
+
+			reg_dcdc2: dcdc2 {
+				regulator-always-on;
+				regulator-min-microvolt = <810000>;
+				regulator-max-microvolt = <1100000>;
+				regulator-name = "vdd-cpu";
+			};
+
+			reg_dcdc3: dcdc3 {
+				regulator-always-on;
+				regulator-min-microvolt = <1100000>;
+				regulator-max-microvolt = <1100000>;
+				regulator-name = "vdd-dram";
+			};
+		};
+	};
+};
+
+&spi0  {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi0_pins>, <&spi0_cs0_pin>;
+
+	flash@0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <40000000>;
+	};
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_ph_pins>;
+	status = "okay";
+};
+
+&usbotg {
+	/*
+	 * PHY0 pins are connected to a USB-C socket, but a role switch
+	 * is not implemented: both CC pins are pulled to GND.
+	 * The VBUS pins power the device, so a fixed peripheral mode
+	 * is the best choice.
+	 * The board can be powered via GPIOs, in this case port0 *can*
+	 * act as a host (with a cable/adapter ignoring CC), as VBUS is
+	 * then provided by the GPIOs. Any user of this setup would
+	 * need to adjust the DT accordingly: dr_mode set to "host",
+	 * enabling OHCI0 and EHCI0.
+	 */
+	dr_mode = "peripheral";
+	status = "okay";
+};
+
+&usbphy {
+	usb1_vbus-supply = <&reg_vcc5v>;
+	status = "okay";
+};
diff --git a/arch/arm/dts/sun50i-h618-transpeed-8k618-t.dts b/arch/arm/dts/sun50i-h618-transpeed-8k618-t.dts
new file mode 100644
index 0000000..8ea1fd4
--- /dev/null
+++ b/arch/arm/dts/sun50i-h618-transpeed-8k618-t.dts
@@ -0,0 +1,161 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2023 Arm Ltd.
+ */
+
+/dts-v1/;
+
+#include "sun50i-h616.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+	model = "Transpeed 8K618-T";
+	compatible = "transpeed,8k618-t", "allwinner,sun50i-h618";
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	reg_vcc5v: vcc5v {
+		/* board wide 5V supply directly from the DC input */
+		compatible = "regulator-fixed";
+		regulator-name = "vcc-5v";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-always-on;
+	};
+
+	reg_vcc3v3: vcc3v3 {
+		/* discrete 3.3V regulator */
+		compatible = "regulator-fixed";
+		regulator-name = "vcc-3v3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-always-on;
+	};
+};
+
+&ehci0 {
+	status = "okay";
+};
+
+&ehci1 {
+	status = "okay";
+};
+
+&ir {
+	status = "okay";
+};
+
+&mmc0 {
+	vmmc-supply = <&reg_dldo1>;
+	cd-gpios = <&pio 8 16 GPIO_ACTIVE_LOW>;	/* PI16 */
+	bus-width = <4>;
+	status = "okay";
+};
+
+&mmc2 {
+	vmmc-supply = <&reg_dldo1>;
+	vqmmc-supply = <&reg_aldo1>;
+	bus-width = <8>;
+	non-removable;
+	cap-mmc-hw-reset;
+	mmc-ddr-1_8v;
+	mmc-hs200-1_8v;
+	status = "okay";
+};
+
+&ohci0 {
+	status = "okay";
+};
+
+&ohci1 {
+	status = "okay";
+};
+
+&r_i2c {
+	status = "okay";
+
+	axp313: pmic@36 {
+		compatible = "x-powers,axp313a";
+		reg = <0x36>;
+		#interrupt-cells = <1>;
+		interrupt-controller;
+
+		vin1-supply = <&reg_vcc5v>;
+		vin2-supply = <&reg_vcc5v>;
+		vin3-supply = <&reg_vcc5v>;
+
+		regulators {
+			reg_aldo1: aldo1 {
+				regulator-always-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vcc-1v8-pll";
+			};
+
+			reg_dldo1: dldo1 {
+				regulator-always-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-name = "vcc-3v3-io-mmc";
+			};
+
+			reg_dcdc1: dcdc1 {
+				regulator-always-on;
+				regulator-min-microvolt = <810000>;
+				regulator-max-microvolt = <990000>;
+				regulator-name = "vdd-gpu-sys";
+			};
+
+			reg_dcdc2: dcdc2 {
+				regulator-always-on;
+				regulator-min-microvolt = <810000>;
+				regulator-max-microvolt = <1100000>;
+				regulator-name = "vdd-cpu";
+			};
+
+			reg_dcdc3: dcdc3 {
+				regulator-always-on;
+				regulator-min-microvolt = <1360000>;
+				regulator-max-microvolt = <1360000>;
+				regulator-name = "vdd-dram";
+			};
+		};
+	};
+};
+
+&pio {
+	vcc-pc-supply = <&reg_aldo1>;
+	vcc-pg-supply = <&reg_dldo1>;
+	vcc-ph-supply = <&reg_dldo1>;
+	vcc-pi-supply = <&reg_dldo1>;
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_ph_pins>;
+	status = "okay";
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>;
+	uart-has-rtscts;
+	status = "okay";
+};
+
+&usbotg {
+	dr_mode = "host";	/* USB A type receptable */
+	status = "okay";
+};
+
+&usbphy {
+	status = "okay";
+};
diff --git a/arch/arm/dts/sun8i-r40.dtsi b/arch/arm/dts/sun8i-r40.dtsi
index 4ef26d8..a5b1f1e 100644
--- a/arch/arm/dts/sun8i-r40.dtsi
+++ b/arch/arm/dts/sun8i-r40.dtsi
@@ -338,6 +338,8 @@
 			resets = <&ccu RST_BUS_VE>;
 			interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
 			allwinner,sram = <&ve_sram 1>;
+			interconnects = <&mbus 4>;
+			interconnect-names = "dma-mem";
 		};
 
 		mmc0: mmc@1c0f000 {
diff --git a/arch/arm/dts/sun8i-v3s-anbernic-rg-nano.dts b/arch/arm/dts/sun8i-v3s-anbernic-rg-nano.dts
new file mode 100644
index 0000000..f34dfdf
--- /dev/null
+++ b/arch/arm/dts/sun8i-v3s-anbernic-rg-nano.dts
@@ -0,0 +1,276 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+/dts-v1/;
+#include <dt-bindings/input/linux-event-codes.h>
+#include "sun8i-v3s.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+/ {
+	model = "Anbernic RG Nano";
+	compatible = "anbernic,rg-nano", "allwinner,sun8i-v3s";
+
+	aliases {
+		rtc0 = &pcf8563;
+		rtc1 = &rtc;
+		serial0 = &uart0;
+	};
+
+	backlight: backlight {
+		compatible = "pwm-backlight";
+		brightness-levels = <0 1 2 3 8 14 21 32 46 60 80 100>;
+		default-brightness-level = <11>;
+		power-supply = <&reg_vcc5v0>;
+		pwms = <&pwm 0 40000 1>;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	gpio_keys: gpio-keys {
+		compatible = "gpio-keys";
+
+		button-a {
+			gpios = <&gpio_expander 12 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
+			label = "BTN-A";
+			linux,code = <BTN_EAST>;
+		};
+
+		button-b {
+			gpios = <&gpio_expander 14 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
+			label = "BTN-B";
+			linux,code = <BTN_SOUTH>;
+		};
+
+		button-down {
+			gpios = <&gpio_expander 1 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
+			label = "DPAD-DOWN";
+			linux,code = <BTN_DPAD_DOWN>;
+		};
+
+		button-left {
+			gpios = <&gpio_expander 4 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
+			label = "DPAD-LEFT";
+			linux,code = <BTN_DPAD_LEFT>;
+		};
+
+		button-right {
+			gpios = <&gpio_expander 0 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
+			label = "DPAD-RIGHT";
+			linux,code = <BTN_DPAD_RIGHT>;
+		};
+
+		button-se {
+			gpios = <&gpio_expander 7 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
+			label = "BTN-SELECT";
+			linux,code = <BTN_SELECT>;
+		};
+
+		button-st {
+			gpios = <&gpio_expander 6 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
+			label = "BTN-START";
+			linux,code = <BTN_START>;
+		};
+
+		button-tl {
+			gpios = <&gpio_expander 2 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
+			label = "BTN-L";
+			linux,code = <BTN_TL>;
+		};
+
+		button-tr {
+			gpios = <&gpio_expander 15 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
+			label = "BTN-R";
+			linux,code = <BTN_TR>;
+		};
+
+		button-up {
+			gpios = <&gpio_expander 3 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
+			label = "DPAD-UP";
+			linux,code = <BTN_DPAD_UP>;
+		};
+
+		button-x {
+			gpios = <&gpio_expander 11 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
+			label = "BTN-X";
+			linux,code = <BTN_NORTH>;
+		};
+
+		button-y {
+			gpios = <&gpio_expander 13 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
+			label = "BTN-Y";
+			linux,code = <BTN_WEST>;
+		};
+	};
+};
+
+&codec {
+	allwinner,audio-routing = "Speaker", "HP",
+				  "MIC1", "Mic",
+				  "Mic", "HBIAS";
+	allwinner,pa-gpios = <&pio 5 6 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>; /* PF6 */
+	status = "okay";
+};
+
+&ehci {
+	status = "okay";
+};
+
+&i2c0 {
+	status = "okay";
+
+	gpio_expander: gpio@20 {
+		compatible = "nxp,pcal6416";
+		reg = <0x20>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		#interrupt-cells = <2>;
+		interrupt-controller;
+		interrupt-parent = <&pio>;
+		interrupts = <1 3 IRQ_TYPE_EDGE_BOTH>; /* PB3/EINT3 */
+		vcc-supply = <&reg_vcc3v3>;
+	};
+
+	axp209: pmic@34 {
+		reg = <0x34>;
+		interrupt-parent = <&pio>;
+		interrupts = <1 5 IRQ_TYPE_EDGE_FALLING>; /* PB5/EINT5 */
+	};
+
+	pcf8563: rtc@51 {
+		compatible = "nxp,pcf8563";
+		reg = <0x51>;
+	};
+};
+
+#include "axp209.dtsi"
+
+&battery_power_supply {
+	status = "okay";
+};
+
+&mmc0 {
+	broken-cd;
+	bus-width = <4>;
+	disable-wp;
+	vmmc-supply = <&reg_vcc3v3>;
+	vqmmc-supply = <&reg_vcc3v3>;
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
+
+&pio {
+	vcc-pb-supply = <&reg_vcc3v3>;
+	vcc-pc-supply = <&reg_vcc3v3>;
+	vcc-pf-supply = <&reg_vcc3v3>;
+	vcc-pg-supply = <&reg_vcc3v3>;
+
+	spi0_no_miso_pins: spi0-no-miso-pins {
+		pins = "PC1", "PC2", "PC3";
+		function = "spi0";
+	};
+};
+
+&pwm {
+	pinctrl-0 = <&pwm0_pin>;
+	pinctrl-names = "default";
+	status = "okay";
+};
+
+/* DCDC2 wired into vdd-cpu, vdd-sys, and vdd-ephy. */
+&reg_dcdc2 {
+	regulator-always-on;
+	regulator-max-microvolt = <1250000>;
+	regulator-min-microvolt = <1250000>;
+	regulator-name = "vdd-cpu";
+};
+
+/* DCDC3 wired into every 3.3v input that isn't the RTC. */
+&reg_dcdc3 {
+	regulator-always-on;
+	regulator-max-microvolt = <3300000>;
+	regulator-min-microvolt = <3300000>;
+	regulator-name = "vcc-io";
+};
+
+/* LDO1 wired into RTC, voltage is hard-wired at 3.3v. */
+&reg_ldo1 {
+	regulator-always-on;
+	regulator-name = "vcc-rtc";
+};
+
+/* LDO2 wired into VCC-PLL and audio codec. */
+&reg_ldo2 {
+	regulator-always-on;
+	regulator-max-microvolt = <3000000>;
+	regulator-min-microvolt = <3000000>;
+	regulator-name = "vcc-pll";
+};
+
+/* LDO3, LDO4, and LDO5 unused. */
+&reg_ldo3 {
+	status = "disabled";
+};
+
+&reg_ldo4 {
+	status = "disabled";
+};
+
+/* RTC uses internal oscillator */
+&rtc {
+	/delete-property/ clocks;
+};
+
+&spi0 {
+	pinctrl-0 = <&spi0_no_miso_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+
+	display@0 {
+		compatible = "saef,sftc154b", "panel-mipi-dbi-spi";
+		reg = <0>;
+		backlight = <&backlight>;
+		dc-gpios = <&pio 2 0 GPIO_ACTIVE_HIGH>; /* PC0 */
+		reset-gpios = <&pio 1 2 GPIO_ACTIVE_HIGH>; /* PB2 */
+		spi-max-frequency = <100000000>;
+
+		height-mm = <39>;
+		width-mm = <39>;
+
+		/* Set hb-porch to compensate for non-visible area */
+		panel-timing {
+			hactive = <240>;
+			vactive = <240>;
+			hback-porch = <80>;
+			vback-porch = <0>;
+			clock-frequency = <0>;
+			hfront-porch = <0>;
+			hsync-len = <0>;
+			vfront-porch = <0>;
+			vsync-len = <0>;
+		};
+	};
+};
+
+&uart0 {
+	pinctrl-0 = <&uart0_pb_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+};
+
+&usb_otg {
+	dr_mode = "otg";
+	status = "okay";
+};
+
+&usb_power_supply {
+	status = "okay";
+};
+
+&usbphy {
+	usb0_id_det-gpios = <&pio 6 5 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; /* PG5 */
+	status = "okay";
+};
diff --git a/arch/arm/dts/sun8i-v3s.dtsi b/arch/arm/dts/sun8i-v3s.dtsi
index 3b9a282..e8a0447 100644
--- a/arch/arm/dts/sun8i-v3s.dtsi
+++ b/arch/arm/dts/sun8i-v3s.dtsi
@@ -319,6 +319,29 @@
 			#phy-cells = <1>;
 		};
 
+		ehci: usb@1c1a000 {
+			compatible = "allwinner,sun8i-v3s-ehci", "generic-ehci";
+			reg = <0x01c1a000 0x100>;
+			interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_EHCI0>, <&ccu CLK_BUS_OHCI0>;
+			resets = <&ccu RST_BUS_EHCI0>, <&ccu RST_BUS_OHCI0>;
+			phys = <&usbphy 0>;
+			phy-names = "usb";
+			status = "disabled";
+		};
+
+		ohci: usb@1c1a400 {
+			compatible = "allwinner,sun8i-v3s-ohci", "generic-ohci";
+			reg = <0x01c1a400 0x100>;
+			interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_EHCI0>, <&ccu CLK_BUS_OHCI0>,
+				 <&ccu CLK_USB_OHCI0>;
+			resets = <&ccu RST_BUS_EHCI0>, <&ccu RST_BUS_OHCI0>;
+			phys = <&usbphy 0>;
+			phy-names = "usb";
+			status = "disabled";
+		};
+
 		ccu: clock@1c20000 {
 			compatible = "allwinner,sun8i-v3s-ccu";
 			reg = <0x01c20000 0x400>;
@@ -414,6 +437,18 @@
 				bias-pull-up;
 			};
 
+			/omit-if-no-ref/
+			pwm0_pin: pwm0-pin {
+				pins = "PB4";
+				function = "pwm0";
+			};
+
+			/omit-if-no-ref/
+			pwm1_pin: pwm1-pin {
+				pins = "PB5";
+				function = "pwm1";
+			};
+
 			spi0_pins: spi0-pins {
 				pins = "PC0", "PC1", "PC2", "PC3";
 				function = "spi0";
diff --git a/arch/arm/dts/sunxi-u-boot.dtsi b/arch/arm/dts/sunxi-u-boot.dtsi
index a0c8abb..0909a67 100644
--- a/arch/arm/dts/sunxi-u-boot.dtsi
+++ b/arch/arm/dts/sunxi-u-boot.dtsi
@@ -1,13 +1,9 @@
 #include <config.h>
 
-#ifdef CONFIG_MACH_SUN50I_H6
-#define BL31_ADDR 0x104000
-#define  SCP_ADDR 0x114000
-#elif defined(CONFIG_MACH_SUN50I_H616)
-#define BL31_ADDR 0x40000000
+#ifdef CONFIG_ARM64
+#define ARCH "arm64"
 #else
-#define BL31_ADDR  0x44000
-#define  SCP_ADDR  0x50000
+#define ARCH "arm"
 #endif
 
 / {
@@ -44,47 +40,52 @@
 			filename = "spl/sunxi-spl.bin";
 		};
 
-#ifdef CONFIG_ARM64
+#ifdef CONFIG_SPL_LOAD_FIT
 		fit {
-			description = "Configuration to load ATF before U-Boot";
+			description = "Configuration to load U-Boot and firmware";
 			#address-cells = <1>;
 			fit,fdt-list = "of-list";
 
 			images {
 				uboot {
-					description = "U-Boot (64-bit)";
+					description = "U-Boot";
 					type = "standalone";
 					os = "u-boot";
-					arch = "arm64";
+					arch = ARCH;
 					compression = "none";
 					load = <CONFIG_TEXT_BASE>;
+#if CONFIG_SUNXI_BL31_BASE == 0
+					entry = <CONFIG_TEXT_BASE>;
+#endif
 
 					u-boot-nodtb {
 					};
 				};
 
+#if CONFIG_SUNXI_BL31_BASE
 				atf {
 					description = "ARM Trusted Firmware";
 					type = "firmware";
 					os = "arm-trusted-firmware";
-					arch = "arm64";
+					arch = ARCH;
 					compression = "none";
-					load = <BL31_ADDR>;
-					entry = <BL31_ADDR>;
+					load = <CONFIG_SUNXI_BL31_BASE>;
+					entry = <CONFIG_SUNXI_BL31_BASE>;
 
 					atf-bl31 {
 						filename = "bl31.bin";
 						missing-msg = "atf-bl31-sunxi";
 					};
 				};
+#endif
 
-#ifdef SCP_ADDR
+#if CONFIG_SUNXI_SCP_BASE
 				scp {
 					description = "SCP firmware";
 					type = "firmware";
 					arch = "or1k";
 					compression = "none";
-					load = <SCP_ADDR>;
+					load = <CONFIG_SUNXI_SCP_BASE>;
 
 					scp {
 						filename = "scp.bin";
@@ -105,11 +106,15 @@
 
 				@config-SEQ {
 					description = "NAME";
+#if CONFIG_SUNXI_BL31_BASE
 					firmware = "atf";
-#ifndef SCP_ADDR
-					loadables = "uboot";
 #else
+					firmware = "uboot";
+#endif
+#if CONFIG_SUNXI_SCP_BASE
 					loadables = "scp", "uboot";
+#else
+					loadables = "uboot";
 #endif
 					fdt = "fdt-SEQ";
 				};
diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
index 3daee2f..f023a4c 100644
--- a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
+++ b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
@@ -36,58 +36,20 @@
 
 #define SUNXI_SRAMC_BASE		0x01c00000
 #define SUNXI_DRAMC_BASE		0x01c01000
-#define SUNXI_DMA_BASE			0x01c02000
 #define SUNXI_NFC_BASE			0x01c03000
-#define SUNXI_TS_BASE			0x01c04000
-#define SUNXI_SPI0_BASE			0x01c05000
-#define SUNXI_SPI1_BASE			0x01c06000
-#define SUNXI_MS_BASE			0x01c07000
-#define SUNXI_TVD_BASE			0x01c08000
-#define SUNXI_CSI0_BASE			0x01c09000
 #ifndef CONFIG_MACH_SUNXI_H3_H5
 #define SUNXI_TVE0_BASE			0x01c0a000
 #endif
-#define SUNXI_EMAC_BASE			0x01c0b000
 #define SUNXI_LCD0_BASE			0x01c0C000
 #define SUNXI_LCD1_BASE			0x01c0d000
-#define SUNXI_VE_BASE			0x01c0e000
 #define SUNXI_MMC0_BASE			0x01c0f000
 #define SUNXI_MMC1_BASE			0x01c10000
 #define SUNXI_MMC2_BASE			0x01c11000
 #define SUNXI_MMC3_BASE			0x01c12000
-#ifdef CONFIG_SUNXI_GEN_SUN4I
-#define SUNXI_USB0_BASE			0x01c13000
-#define SUNXI_USB1_BASE			0x01c14000
-#endif
 #define SUNXI_SS_BASE			0x01c15000
 #if !defined(CONFIG_MACH_SUNXI_H3_H5) && !defined(CONFIG_MACH_SUN50I)
 #define SUNXI_HDMI_BASE			0x01c16000
 #endif
-#define SUNXI_SPI2_BASE			0x01c17000
-#define SUNXI_SATA_BASE			0x01c18000
-#ifdef CONFIG_SUNXI_GEN_SUN4I
-#define SUNXI_PATA_BASE			0x01c19000
-#define SUNXI_ACE_BASE			0x01c1a000
-#define SUNXI_TVE1_BASE			0x01c1b000
-#define SUNXI_USB2_BASE			0x01c1c000
-#endif
-#ifdef CONFIG_SUNXI_GEN_SUN6I
-#if defined(CONFIG_MACH_SUNXI_H3_H5) || defined(CONFIG_MACH_SUN50I)
-#define SUNXI_USBPHY_BASE		0x01c19000
-#define SUNXI_USB0_BASE			SUNXI_USBPHY_BASE
-#define SUNXI_USB1_BASE			0x01c1a000
-#define SUNXI_USB2_BASE			0x01c1b000
-#define SUNXI_USB3_BASE			0x01c1c000
-#define SUNXI_USB4_BASE			0x01c1d000
-#else
-#define SUNXI_USB0_BASE			0x01c19000
-#define SUNXI_USB1_BASE			0x01c1a000
-#define SUNXI_USB2_BASE			0x01c1b000
-#endif
-#endif
-#define SUNXI_CSI1_BASE			0x01c1d000
-#define SUNXI_TZASC_BASE		0x01c1e000
-#define SUNXI_SPI3_BASE			0x01c1f000
 
 #define SUNXI_CCM_BASE			0x01c20000
 #define SUNXI_INTC_BASE			0x01c20400
@@ -177,8 +139,6 @@
 #else
 #define SUNXI_TVE0_BASE			0x01e40000
 #endif
-#define SUNXI_MP_BASE			0x01e80000
-#define SUNXI_AVG_BASE			0x01ea0000
 
 #if defined(CONFIG_MACH_SUNXI_H3_H5) || defined(CONFIG_MACH_SUN50I)
 #define SUNXI_HDMI_BASE			0x01ee0000
@@ -197,13 +157,6 @@
 #define SUN6I_P2WI_BASE			0x01f03400
 #define SUNXI_RSB_BASE			0x01f03400
 
-/* CoreSight Debug Module */
-#define SUNXI_CSDM_BASE			0x3f500000
-
-#define SUNXI_DDRII_DDRIII_BASE		0x40000000	/* 2 GiB */
-
-#define SUNXI_BROM_BASE			0xffff0000	/* 32 kiB */
-
 #define SUNXI_CPU_CFG			(SUNXI_TIMER_BASE + 0x13c)
 
 /* SS bonding ids used for cpu identification */
diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h b/arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h
index 15ee092..8a3f465 100644
--- a/arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h
+++ b/arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h
@@ -7,25 +7,14 @@
 #ifndef _SUNXI_CPU_SUN50I_H6_H
 #define _SUNXI_CPU_SUN50I_H6_H
 
-#define SUNXI_SRAM_A1_BASE		CONFIG_SUNXI_SRAM_ADDRESS
-#define SUNXI_SRAM_C_BASE		0x00028000
-#define SUNXI_SRAM_A2_BASE		0x00100000
-
-#define SUNXI_DE3_BASE			0x01000000
-#define SUNXI_SS_BASE			0x01904000
-#define SUNXI_EMCE_BASE			0x01905000
-
 #define SUNXI_SRAMC_BASE		0x03000000
 #define SUNXI_CCM_BASE			0x03001000
-#define SUNXI_DMA_BASE			0x03002000
 /* SID address space starts at 0x03006000, but e-fuse is at offset 0x200 */
 #define SUNXI_SIDC_BASE			0x03006000
 #define SUNXI_SID_BASE			0x03006200
 #define SUNXI_TIMER_BASE		0x03009000
-#define SUNXI_PSI_BASE			0x0300C000
 
 #define SUNXI_GIC400_BASE		0x03020000
-#define SUNXI_IOMMU_BASE		0x030F0000
 
 #ifdef CONFIG_MACH_SUN50I_H6
 #define SUNXI_DRAM_COM_BASE		0x04002000
@@ -46,18 +35,8 @@
 #define SUNXI_TWI1_BASE			0x05002400
 #define SUNXI_TWI2_BASE			0x05002800
 #define SUNXI_TWI3_BASE			0x05002C00
-#define SUNXI_SPI0_BASE			0x05010000
-#define SUNXI_SPI1_BASE			0x05011000
-#define SUNXI_GMAC_BASE			0x05020000
-#define SUNXI_USB0_BASE			0x05100000
-#define SUNXI_XHCI_BASE			0x05200000
-#define SUNXI_USB3_BASE			0x05311000
-#define SUNXI_PCIE_BASE			0x05400000
 
 #define SUNXI_HDMI_BASE			0x06000000
-#define SUNXI_TCON_TOP_BASE		0x06510000
-#define SUNXI_TCON_LCD0_BASE		0x06511000
-#define SUNXI_TCON_TV0_BASE		0x06515000
 
 #define SUNXI_RTC_BASE			0x07000000
 #define SUNXI_R_CPUCFG_BASE		0x07000400
diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun9i.h b/arch/arm/include/asm/arch-sunxi/cpu_sun9i.h
index 2bf2675..73de470 100644
--- a/arch/arm/include/asm/arch-sunxi/cpu_sun9i.h
+++ b/arch/arm/include/asm/arch-sunxi/cpu_sun9i.h
@@ -20,7 +20,6 @@
 
 /* AHB0 Module */
 #define SUNXI_NFC_BASE			(REGS_AHB0_BASE + 0x3000)
-#define SUNXI_TSC_BASE			(REGS_AHB0_BASE + 0x4000)
 
 #define SUNXI_GTBUS_BASE		(REGS_AHB0_BASE + 0x9000)
 /* SID address space starts at 0x01ce000, but e-fuse is at offset 0x200 */
@@ -32,14 +31,7 @@
 #define SUNXI_MMC3_BASE			(REGS_AHB0_BASE + 0x12000)
 #define SUNXI_MMC_COMMON_BASE		(REGS_AHB0_BASE + 0x13000)
 
-#define SUNXI_SPI0_BASE			(REGS_AHB0_BASE + 0x1A000)
-#define SUNXI_SPI1_BASE			(REGS_AHB0_BASE + 0x1B000)
-#define SUNXI_SPI2_BASE			(REGS_AHB0_BASE + 0x1C000)
-#define SUNXI_SPI3_BASE			(REGS_AHB0_BASE + 0x1D000)
-
 #define SUNXI_GIC400_BASE		(REGS_AHB0_BASE + 0x40000)
-#define SUNXI_ARMA9_GIC_BASE		(REGS_AHB0_BASE + 0x41000)
-#define SUNXI_ARMA9_CPUIF_BASE		(REGS_AHB0_BASE + 0x42000)
 
 #define SUNXI_DRAM_COM_BASE		(REGS_AHB0_BASE + 0x62000)
 #define SUNXI_DRAM_CTL0_BASE		(REGS_AHB0_BASE + 0x63000)
@@ -47,59 +39,26 @@
 #define SUNXI_DRAM_PHY0_BASE		(REGS_AHB0_BASE + 0x65000)
 #define SUNXI_DRAM_PHY1_BASE		(REGS_AHB0_BASE + 0x66000)
 
-/* AHB1 Module */
-#define SUNXI_DMA_BASE			(REGS_AHB1_BASE + 0x002000)
-#define SUNXI_USBOTG_BASE		(REGS_AHB1_BASE + 0x100000)
-#define SUNXI_USBEHCI0_BASE		(REGS_AHB1_BASE + 0x200000)
-#define SUNXI_USBEHCI1_BASE		(REGS_AHB1_BASE + 0x201000)
-#define SUNXI_USBEHCI2_BASE		(REGS_AHB1_BASE + 0x202000)
-
-/* AHB2 Module */
-#define SUNXI_DE_SYS_BASE		(REGS_AHB2_BASE + 0x000000)
-#define SUNXI_DISP_SYS_BASE		(REGS_AHB2_BASE + 0x010000)
 #define SUNXI_DE_FE0_BASE		(REGS_AHB2_BASE + 0x100000)
-#define SUNXI_DE_FE1_BASE		(REGS_AHB2_BASE + 0x140000)
-#define SUNXI_DE_FE2_BASE		(REGS_AHB2_BASE + 0x180000)
-
 #define SUNXI_DE_BE0_BASE		(REGS_AHB2_BASE + 0x200000)
-#define SUNXI_DE_BE1_BASE		(REGS_AHB2_BASE + 0x240000)
-#define SUNXI_DE_BE2_BASE		(REGS_AHB2_BASE + 0x280000)
-
-#define SUNXI_DE_DEU0_BASE		(REGS_AHB2_BASE + 0x300000)
-#define SUNXI_DE_DEU1_BASE		(REGS_AHB2_BASE + 0x340000)
-#define SUNXI_DE_DRC0_BASE		(REGS_AHB2_BASE + 0x400000)
-#define SUNXI_DE_DRC1_BASE		(REGS_AHB2_BASE + 0x440000)
-
 #define SUNXI_LCD0_BASE			(REGS_AHB2_BASE + 0xC00000)
 #define SUNXI_LCD1_BASE			(REGS_AHB2_BASE + 0xC10000)
 #define SUNXI_LCD2_BASE			(REGS_AHB2_BASE + 0xC20000)
-#define SUNXI_MIPI_DSI0_BASE		(REGS_AHB2_BASE + 0xC40000)
-/* Also seen as SUNXI_MIPI_DSI0_DPHY_BASE 0x01ca1000 */
-#define SUNXI_MIPI_DSI0_DPHY_BASE	(REGS_AHB2_BASE + 0xC40100)
 #define SUNXI_HDMI_BASE			(REGS_AHB2_BASE + 0xD00000)
 
 /* APB0 Module */
 #define SUNXI_CCM_BASE			(REGS_APB0_BASE + 0x0000)
-#define SUNXI_CCMMODULE_BASE		(REGS_APB0_BASE + 0x0400)
 #define SUNXI_TIMER_BASE		(REGS_APB0_BASE + 0x0C00)
 #define SUNXI_PWM_BASE			(REGS_APB0_BASE + 0x1400)
-#define SUNXI_LRADC_BASE		(REGS_APB0_BASE + 0x1800)
 
 /* APB1 Module */
 #define SUNXI_TWI0_BASE			(REGS_APB1_BASE + 0x2800)
 #define SUNXI_TWI1_BASE			(REGS_APB1_BASE + 0x2C00)
-#define SUNXI_TWI2_BASE			(REGS_APB1_BASE + 0x3000)
-#define SUNXI_TWI3_BASE			(REGS_APB1_BASE + 0x3400)
-#define SUNXI_TWI4_BASE			(REGS_APB1_BASE + 0x3800)
 
 /* RCPUS Module */
 #define SUNXI_PRCM_BASE			(REGS_RCPUS_BASE + 0x1400)
 #define SUNXI_RSB_BASE			(REGS_RCPUS_BASE + 0x3400)
 
-/* Misc. */
-#define SUNXI_BROM_BASE			0xFFFF0000 /* 32K */
-#define SUNXI_CPU_CFG			(SUNXI_TIMER_BASE + 0x13c)
-
 #ifndef __ASSEMBLY__
 void sunxi_board_init(void);
 void sunxi_reset(void);
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 37ef2d6..c5fd869 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -88,6 +88,7 @@
 	select DM_GPIO
 	select DM_SERIAL
 	select DM_SPI
+	select MTD
 	select SPI
 	imply CMD_DM
 
@@ -294,6 +295,7 @@
 	select DM_GPIO
 	select DM_SERIAL
 	select DM_SPI
+	select MTD
 	select SPI
 	select SUPPORT_SPL
 	imply CMD_DM
@@ -312,6 +314,7 @@
 	bool "Support VINCO"
 	select DM
 	select DM_SPI
+	select MTD
 	select SAMA5D4
 	select SPI
 	select SUPPORT_SPL
diff --git a/arch/arm/mach-imx/imx8m/Kconfig b/arch/arm/mach-imx/imx8m/Kconfig
index b193719..328c3e3 100644
--- a/arch/arm/mach-imx/imx8m/Kconfig
+++ b/arch/arm/mach-imx/imx8m/Kconfig
@@ -5,6 +5,7 @@
 	select BINMAN
 	select GICV3 if ARMV8_PSCI
 	select HAS_CAAM
+	select LTO
 	select ROM_UNIFIED_SECTIONS
 	select ARMV8_CRYPTO
 
diff --git a/arch/arm/mach-imx/mx6/Kconfig b/arch/arm/mach-imx/mx6/Kconfig
index 50a9c3e..114cce4 100644
--- a/arch/arm/mach-imx/mx6/Kconfig
+++ b/arch/arm/mach-imx/mx6/Kconfig
@@ -201,6 +201,7 @@
 	select DM_SPI
 	select DM_GPIO
 	select DM_SERIAL
+	select MTD
 	select SUPPORT_SPL
 	imply CMD_DM
 
@@ -261,6 +262,7 @@
 	select DM_SERIAL
 	select DM_I2C
 	select DM_SPI
+	select MTD
 	imply CMD_DM
 
 config TARGET_MX6CUBOXI
@@ -602,6 +604,7 @@
 	imply DM
 	imply DM_GPIO
 	imply DM_MMC
+	imply MTD
 	imply DM_SPI
 	imply DM_SPI_FLASH
 	imply DM_I2C
diff --git a/arch/arm/mach-k3/am625_fdt.c b/arch/arm/mach-k3/am625_fdt.c
index 3780690..970dd34 100644
--- a/arch/arm/mach-k3/am625_fdt.c
+++ b/arch/arm/mach-k3/am625_fdt.c
@@ -38,29 +38,6 @@
 		fdt_del_node_path(blob, "/bus@f0000/pruss@30040000");
 }
 
-static int k3_get_core_nr(void)
-{
-	u32 full_devid = readl(CTRLMMR_WKUP_JTAG_DEVICE_ID);
-
-	return (full_devid & JTAG_DEV_CORE_NR_MASK) >> JTAG_DEV_CORE_NR_SHIFT;
-}
-
-static int k3_has_pru(void)
-{
-	u32 full_devid = readl(CTRLMMR_WKUP_JTAG_DEVICE_ID);
-	u32 feature_mask = (full_devid & JTAG_DEV_FEATURES_MASK) >>
-			   JTAG_DEV_FEATURES_SHIFT;
-
-	return !(feature_mask & JTAG_DEV_FEATURE_NO_PRU);
-}
-
-static int k3_has_gpu(void)
-{
-	u32 full_devid = readl(CTRLMMR_WKUP_JTAG_DEVICE_ID);
-
-	return (full_devid & JTAG_DEV_GPU_MASK) >> JTAG_DEV_GPU_SHIFT;
-}
-
 int ft_system_setup(void *blob, struct bd_info *bd)
 {
 	fdt_fixup_cores_nodes_am625(blob, k3_get_core_nr());
diff --git a/arch/arm/mach-k3/common.c b/arch/arm/mach-k3/common.c
index d5db805..f411366 100644
--- a/arch/arm/mach-k3/common.c
+++ b/arch/arm/mach-k3/common.c
@@ -525,19 +525,26 @@
 void spl_enable_cache(void)
 {
 #if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF))
-	phys_addr_t ram_top = CFG_SYS_SDRAM_BASE;
+	gd->ram_top = CFG_SYS_SDRAM_BASE;
+	int ret = 0;
 
 	dram_init();
 
 	/* reserve TLB table */
 	gd->arch.tlb_size = PGTABLE_SIZE;
 
-	ram_top += get_effective_memsize();
+	gd->ram_top += get_effective_memsize();
 	/* keep ram_top in the 32-bit address space */
-	if (ram_top >= 0x100000000)
-		ram_top = (phys_addr_t) 0x100000000;
+	if (gd->ram_top >= 0x100000000)
+		gd->ram_top = (phys_addr_t)0x100000000;
+
+	gd->relocaddr = gd->ram_top;
+
+	ret = spl_reserve_video_from_ram_top();
+	if (ret)
+		panic("Failed to reserve framebuffer memory (%d)\n", ret);
 
-	gd->arch.tlb_addr = ram_top - gd->arch.tlb_size;
+	gd->arch.tlb_addr = gd->relocaddr - gd->arch.tlb_size;
 	gd->arch.tlb_addr &= ~(0x10000 - 1);
 	debug("TLB table from %08lx to %08lx\n", gd->arch.tlb_addr,
 	      gd->arch.tlb_addr + gd->arch.tlb_size);
diff --git a/arch/arm/mach-k3/include/mach/am62_hardware.h b/arch/arm/mach-k3/include/mach/am62_hardware.h
index acd2d10..54380f3 100644
--- a/arch/arm/mach-k3/include/mach/am62_hardware.h
+++ b/arch/arm/mach-k3/include/mach/am62_hardware.h
@@ -79,6 +79,45 @@
 
 #define TI_SRAM_SCRATCH_BOARD_EEPROM_START	0x43c30000
 
+static inline int k3_get_core_nr(void)
+{
+	u32 full_devid = readl(CTRLMMR_WKUP_JTAG_DEVICE_ID);
+
+	return (full_devid & JTAG_DEV_CORE_NR_MASK) >> JTAG_DEV_CORE_NR_SHIFT;
+}
+
+static inline char k3_get_speed_grade(void)
+{
+	u32 full_devid = readl(CTRLMMR_WKUP_JTAG_DEVICE_ID);
+	u32 speed_grade = (full_devid & JTAG_DEV_SPEED_MASK) >>
+			   JTAG_DEV_SPEED_SHIFT;
+
+	return 'A' - 1 + speed_grade;
+}
+
+static inline int k3_get_temp_grade(void)
+{
+	u32 full_devid = readl(CTRLMMR_WKUP_JTAG_DEVICE_ID);
+
+	return (full_devid & JTAG_DEV_TEMP_MASK) >> JTAG_DEV_TEMP_SHIFT;
+}
+
+static inline int k3_has_pru(void)
+{
+	u32 full_devid = readl(CTRLMMR_WKUP_JTAG_DEVICE_ID);
+	u32 feature_mask = (full_devid & JTAG_DEV_FEATURES_MASK) >>
+			   JTAG_DEV_FEATURES_SHIFT;
+
+	return !(feature_mask & JTAG_DEV_FEATURE_NO_PRU);
+}
+
+static inline int k3_has_gpu(void)
+{
+	u32 full_devid = readl(CTRLMMR_WKUP_JTAG_DEVICE_ID);
+
+	return (full_devid & JTAG_DEV_GPU_MASK) >> JTAG_DEV_GPU_SHIFT;
+}
+
 #if defined(CONFIG_SYS_K3_SPL_ATF) && !defined(__ASSEMBLY__)
 
 static const u32 put_device_ids[] = {};
diff --git a/arch/arm/mach-omap2/am33xx/Kconfig b/arch/arm/mach-omap2/am33xx/Kconfig
index bd5129b..46abf07 100644
--- a/arch/arm/mach-omap2/am33xx/Kconfig
+++ b/arch/arm/mach-omap2/am33xx/Kconfig
@@ -204,6 +204,7 @@
 	imply DM_I2C
 	imply DM_SPI
 	imply DM_SPI_FLASH
+	imply MTD
 	imply SPL_ENV_SUPPORT
 	imply SPL_FS_EXT4
 	imply SPL_FS_FAT
diff --git a/arch/arm/mach-omap2/omap3/Kconfig b/arch/arm/mach-omap2/omap3/Kconfig
index bd524f8..850ee76 100644
--- a/arch/arm/mach-omap2/omap3/Kconfig
+++ b/arch/arm/mach-omap2/omap3/Kconfig
@@ -144,6 +144,7 @@
 
 config SPL_OMAP3_ID_NAND
 	bool "Support OMAP3-specific ID and MFR function"
+	depends on NAND_OMAP_GPMC
 	help
 	  Support for an OMAP3-specific set of functions to return the
 	  ID and MFR of the first attached NAND chip, if present.
diff --git a/arch/arm/mach-rockchip/rk3288/rk3288.c b/arch/arm/mach-rockchip/rk3288/rk3288.c
index 26c7e41..d9f782e 100644
--- a/arch/arm/mach-rockchip/rk3288/rk3288.c
+++ b/arch/arm/mach-rockchip/rk3288/rk3288.c
@@ -184,8 +184,6 @@
 
 		rate = clk_get_rate(&clk);
 		printf("%s: %lu\n", clks[i].name, rate);
-
-		clk_free(&clk);
 	}
 
 	return 0;
diff --git a/arch/arm/mach-socfpga/clock_manager_agilex.c b/arch/arm/mach-socfpga/clock_manager_agilex.c
index e035c09..28f593b 100644
--- a/arch/arm/mach-socfpga/clock_manager_agilex.c
+++ b/arch/arm/mach-socfpga/clock_manager_agilex.c
@@ -37,8 +37,6 @@
 
 	rate = clk_get_rate(&clk);
 
-	clk_free(&clk);
-
 	if ((rate == (unsigned long)-ENOSYS) ||
 	    (rate == (unsigned long)-ENXIO) ||
 	    (rate == (unsigned long)-EIO)) {
diff --git a/arch/arm/mach-socfpga/clock_manager_arria10.c b/arch/arm/mach-socfpga/clock_manager_arria10.c
index b48a2b4..8ab18f6 100644
--- a/arch/arm/mach-socfpga/clock_manager_arria10.c
+++ b/arch/arm/mach-socfpga/clock_manager_arria10.c
@@ -962,7 +962,6 @@
 	struct uclass *uc;
 	struct udevice *dev = NULL;
 	struct clk clk = { 0 };
-	ulong rate;
 	int ret;
 
 	/* Device addresses start at 1 */
@@ -982,11 +981,7 @@
 	if (ret)
 		return 0;
 
-	rate = clk_get_rate(&clk);
-
-	clk_free(&clk);
-
-	return rate;
+	return clk_get_rate(&clk);
 }
 
 static u32 cm_get_rate_dm_khz(char *name)
diff --git a/arch/arm/mach-socfpga/clock_manager_n5x.c b/arch/arm/mach-socfpga/clock_manager_n5x.c
index 4f09853..0ed480d 100644
--- a/arch/arm/mach-socfpga/clock_manager_n5x.c
+++ b/arch/arm/mach-socfpga/clock_manager_n5x.c
@@ -36,8 +36,6 @@
 
 	rate = clk_get_rate(&clk);
 
-	clk_free(&clk);
-
 	if ((rate == (unsigned long)-ENXIO) ||
 	    (rate == (unsigned long)-EIO)) {
 		debug("%s id %u: clk_get_rate err: %ld\n",
diff --git a/arch/arm/mach-socfpga/clock_manager_s10.c b/arch/arm/mach-socfpga/clock_manager_s10.c
index 4b4f074..4530033 100644
--- a/arch/arm/mach-socfpga/clock_manager_s10.c
+++ b/arch/arm/mach-socfpga/clock_manager_s10.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Copyright (C) 2016-2018 Intel Corporation <www.intel.com>
+ * Copyright (C) 2016-2023 Intel Corporation <www.intel.com>
  *
  */
 
@@ -399,6 +399,21 @@
 	return cm_get_l3_main_clk_hz() / 4;
 }
 
+/*
+ * Override weak dw_spi_get_clk implementation in designware_spi.c driver
+ */
+
+int dw_spi_get_clk(struct udevice *bus, ulong *rate)
+{
+	*rate = cm_get_spi_controller_clk_hz();
+	if (!*rate) {
+		printf("SPI: clock rate is zero");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 void cm_print_clock_quick_summary(void)
 {
 	printf("MPU         %d kHz\n", (u32)(cm_get_mpu_clk_hz() / 1000));
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index a4a8d8e..fe89aec 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -161,6 +161,23 @@
 	for all other SoCs, so the content of the SRAM_VER_REG becomes
 	irrelevant there, and we can use the same code.
 
+config SUNXI_BL31_BASE
+	hex
+	default 0x00044000 if MACH_SUN50I || MACH_SUN50I_H5
+	default 0x00104000 if MACH_SUN50I_H6
+	default 0x40000000 if MACH_SUN50I_H616
+	default 0x0
+	help
+	  Address where BL31 (TF-A) is loaded, or zero if BL31 is not used.
+
+config SUNXI_SCP_BASE
+	hex
+	default 0x00050000 if MACH_SUN50I || MACH_SUN50I_H5
+	default 0x00114000 if MACH_SUN50I_H6
+	default 0x0
+	help
+	  Address where SCP firmware is loaded, or zero if it is not used.
+
 config SUNXI_A64_TIMER_ERRATUM
 	bool
 
@@ -182,7 +199,7 @@
 config SUN50I_GEN_H6
 	bool
 	select FIT
-	select SPL_LOAD_FIT
+	select SPL_LOAD_FIT if SPL
 	select MMC_SUNXI_HAS_NEW_MODE
 	select SUPPORT_SPL
 	---help---
@@ -272,7 +289,7 @@
 	select ARCH_SUPPORT_PSCI
 	select SPL_ARMV7_SET_CORTEX_SMPEN
 	select DRAM_SUN6I
-	select SPL_I2C
+	select SPL_I2C if SPL
 	select SUN6I_PRCM
 	select SUNXI_GEN_SUN6I
 	select SUPPORT_SPL
@@ -300,7 +317,7 @@
 	select CPU_V7_HAS_VIRT
 	select ARCH_SUPPORT_PSCI
 	select DRAM_SUN8I_A23
-	select SPL_I2C
+	select SPL_I2C if SPL
 	select SUNXI_GEN_SUN6I
 	select SUPPORT_SPL
 	select SYS_I2C_SUN8I_RSB
@@ -313,7 +330,7 @@
 	select CPU_V7_HAS_VIRT
 	select ARCH_SUPPORT_PSCI
 	select DRAM_SUN8I_A33
-	select SPL_I2C
+	select SPL_I2C if SPL
 	select SUNXI_GEN_SUN6I
 	select SUPPORT_SPL
 	select SYS_I2C_SUN8I_RSB
@@ -323,7 +340,7 @@
 	bool "sun8i (Allwinner A83T)"
 	select CPU_V7A
 	select DRAM_SUN8I_A83T
-	select SPL_I2C
+	select SPL_I2C if SPL
 	select SUNXI_GEN_SUN6I
 	select MMC_SUNXI_HAS_NEW_MODE
 	select MMC_SUNXI_HAS_MODE_SWITCH
@@ -382,7 +399,7 @@
 	select CPU_V7A
 	select SPL_ARMV7_SET_CORTEX_SMPEN
 	select DRAM_SUN9I
-	select SPL_I2C
+	select SPL_I2C if SPL
 	select SUN6I_PRCM
 	select SUNXI_GEN_SUN6I
 	select SUPPORT_SPL
@@ -398,7 +415,7 @@
 	select SUNXI_DRAM_DW
 	select SUNXI_DRAM_DW_32BIT
 	select FIT
-	select SPL_LOAD_FIT
+	select SPL_LOAD_FIT if SPL
 	select SUNXI_A64_TIMER_ERRATUM
 
 config MACH_SUN50I_H5
@@ -407,7 +424,7 @@
 	select MACH_SUNXI_H3_H5
 	select MMC_SUNXI_HAS_NEW_MODE
 	select FIT
-	select SPL_LOAD_FIT
+	select SPL_LOAD_FIT if SPL
 
 config MACH_SUN50I_H6
 	bool "sun50i (Allwinner H6)"
diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c
index 11a4941..f4dbb2a 100644
--- a/arch/arm/mach-sunxi/board.c
+++ b/arch/arm/mach-sunxi/board.c
@@ -9,7 +9,6 @@
  * Some init for sunxi platform.
  */
 
-#include <common.h>
 #include <cpu_func.h>
 #include <init.h>
 #include <log.h>
diff --git a/arch/arm/mach-sunxi/clock.c b/arch/arm/mach-sunxi/clock.c
index da3a0eb..b6c68c9 100644
--- a/arch/arm/mach-sunxi/clock.c
+++ b/arch/arm/mach-sunxi/clock.c
@@ -7,7 +7,6 @@
  * (C) Copyright 2013 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
  */
 
-#include <common.h>
 #include <asm/io.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/prcm.h>
diff --git a/arch/arm/mach-sunxi/clock_sun4i.c b/arch/arm/mach-sunxi/clock_sun4i.c
index 4716097..8f1d1b6 100644
--- a/arch/arm/mach-sunxi/clock_sun4i.c
+++ b/arch/arm/mach-sunxi/clock_sun4i.c
@@ -9,7 +9,6 @@
  * (C) Copyright 2013 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
  */
 
-#include <common.h>
 #include <asm/io.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/sys_proto.h>
diff --git a/arch/arm/mach-sunxi/clock_sun50i_h6.c b/arch/arm/mach-sunxi/clock_sun50i_h6.c
index bea91c7..dac3663 100644
--- a/arch/arm/mach-sunxi/clock_sun50i_h6.c
+++ b/arch/arm/mach-sunxi/clock_sun50i_h6.c
@@ -1,4 +1,3 @@
-#include <common.h>
 #include <asm/io.h>
 #include <asm/arch/cpu.h>
 #include <asm/arch/clock.h>
diff --git a/arch/arm/mach-sunxi/clock_sun6i.c b/arch/arm/mach-sunxi/clock_sun6i.c
index 6bd75a1..aad9df2 100644
--- a/arch/arm/mach-sunxi/clock_sun6i.c
+++ b/arch/arm/mach-sunxi/clock_sun6i.c
@@ -9,7 +9,6 @@
  * (C) Copyright 2013 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
  */
 
-#include <common.h>
 #include <asm/io.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/prcm.h>
diff --git a/arch/arm/mach-sunxi/clock_sun8i_a83t.c b/arch/arm/mach-sunxi/clock_sun8i_a83t.c
index 31e4281..198fe9d 100644
--- a/arch/arm/mach-sunxi/clock_sun8i_a83t.c
+++ b/arch/arm/mach-sunxi/clock_sun8i_a83t.c
@@ -9,7 +9,6 @@
  * (C) Copyright 2015 Vishnu Patekar <vishnupatekar0510@gmail.com>
  */
 
-#include <common.h>
 #include <asm/io.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/prcm.h>
diff --git a/arch/arm/mach-sunxi/clock_sun9i.c b/arch/arm/mach-sunxi/clock_sun9i.c
index 8ba4802..edaff9a 100644
--- a/arch/arm/mach-sunxi/clock_sun9i.c
+++ b/arch/arm/mach-sunxi/clock_sun9i.c
@@ -9,7 +9,6 @@
  *                    Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
  */
 
-#include <common.h>
 #include <asm/io.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/prcm.h>
diff --git a/arch/arm/mach-sunxi/cpu_info.c b/arch/arm/mach-sunxi/cpu_info.c
index 7fecc3b..310dca0 100644
--- a/arch/arm/mach-sunxi/cpu_info.c
+++ b/arch/arm/mach-sunxi/cpu_info.c
@@ -5,7 +5,6 @@
  * Tom Cubie <tangliang@allwinnertech.com>
  */
 
-#include <common.h>
 #include <init.h>
 #include <asm/io.h>
 #include <asm/arch/cpu.h>
diff --git a/arch/arm/mach-sunxi/dram_helpers.c b/arch/arm/mach-sunxi/dram_helpers.c
index cdf2750..4a867df 100644
--- a/arch/arm/mach-sunxi/dram_helpers.c
+++ b/arch/arm/mach-sunxi/dram_helpers.c
@@ -5,8 +5,9 @@
  * (C) Copyright 2015 Hans de Goede <hdegoede@redhat.com>
  */
 
-#include <common.h>
+#include <config.h>
 #include <time.h>
+#include <vsprintf.h>
 #include <asm/barriers.h>
 #include <asm/io.h>
 #include <asm/arch/dram.h>
diff --git a/arch/arm/mach-sunxi/dram_sun4i.c b/arch/arm/mach-sunxi/dram_sun4i.c
index 80a6c4b..2cce381 100644
--- a/arch/arm/mach-sunxi/dram_sun4i.c
+++ b/arch/arm/mach-sunxi/dram_sun4i.c
@@ -20,7 +20,6 @@
  * rather undocumented and full of magic.
  */
 
-#include <common.h>
 #include <init.h>
 #include <asm/io.h>
 #include <asm/arch/clock.h>
diff --git a/arch/arm/mach-sunxi/dram_sun50i_h6.c b/arch/arm/mach-sunxi/dram_sun50i_h6.c
index 62bc2a0..e7862bd 100644
--- a/arch/arm/mach-sunxi/dram_sun50i_h6.c
+++ b/arch/arm/mach-sunxi/dram_sun50i_h6.c
@@ -5,7 +5,6 @@
  * (C) Copyright 2017      Icenowy Zheng <icenowy@aosc.io>
  *
  */
-#include <common.h>
 #include <init.h>
 #include <log.h>
 #include <asm/io.h>
diff --git a/arch/arm/mach-sunxi/dram_sun50i_h616.c b/arch/arm/mach-sunxi/dram_sun50i_h616.c
index e62d571..37c139e 100644
--- a/arch/arm/mach-sunxi/dram_sun50i_h616.c
+++ b/arch/arm/mach-sunxi/dram_sun50i_h616.c
@@ -12,7 +12,6 @@
  * (C) Copyright 2020 Jernej Skrabec <jernej.skrabec@siol.net>
  *
  */
-#include <common.h>
 #include <init.h>
 #include <log.h>
 #include <asm/io.h>
diff --git a/arch/arm/mach-sunxi/dram_sun6i.c b/arch/arm/mach-sunxi/dram_sun6i.c
index 0590110..c023845 100644
--- a/arch/arm/mach-sunxi/dram_sun6i.c
+++ b/arch/arm/mach-sunxi/dram_sun6i.c
@@ -9,7 +9,6 @@
  *
  * (C) Copyright 2014 Hans de Goede <hdegoede@redhat.com>
  */
-#include <common.h>
 #include <errno.h>
 #include <init.h>
 #include <asm/io.h>
diff --git a/arch/arm/mach-sunxi/dram_sun8i_a23.c b/arch/arm/mach-sunxi/dram_sun8i_a23.c
index 056cb03..1c3c6d8 100644
--- a/arch/arm/mach-sunxi/dram_sun8i_a23.c
+++ b/arch/arm/mach-sunxi/dram_sun8i_a23.c
@@ -19,7 +19,6 @@
  * This may be used as a (possible) reference for future work / cleanups.
  */
 
-#include <common.h>
 #include <errno.h>
 #include <init.h>
 #include <asm/io.h>
diff --git a/arch/arm/mach-sunxi/dram_sun8i_a33.c b/arch/arm/mach-sunxi/dram_sun8i_a33.c
index 367b740..0d08b6a 100644
--- a/arch/arm/mach-sunxi/dram_sun8i_a33.c
+++ b/arch/arm/mach-sunxi/dram_sun8i_a33.c
@@ -7,7 +7,6 @@
  * (C) Copyright 2015      Vishnu Patekar <vishnupatekar0510@gmail.com>
  * (C) Copyright 2015      Hans de Goede <hdegoede@redhat.com>
  */
-#include <common.h>
 #include <errno.h>
 #include <init.h>
 #include <asm/io.h>
diff --git a/arch/arm/mach-sunxi/dram_sun8i_a83t.c b/arch/arm/mach-sunxi/dram_sun8i_a83t.c
index a3f833d..ef83332 100644
--- a/arch/arm/mach-sunxi/dram_sun8i_a83t.c
+++ b/arch/arm/mach-sunxi/dram_sun8i_a83t.c
@@ -7,7 +7,6 @@
  * (C) Copyright 2015      Vishnu Patekar <vishnupatekar0510@gmail.com>
  * (C) Copyright 2015      Hans de Goede <hdegoede@redhat.com>
  */
-#include <common.h>
 #include <errno.h>
 #include <init.h>
 #include <asm/io.h>
diff --git a/arch/arm/mach-sunxi/dram_sun9i.c b/arch/arm/mach-sunxi/dram_sun9i.c
index 14be212..002b6df 100644
--- a/arch/arm/mach-sunxi/dram_sun9i.c
+++ b/arch/arm/mach-sunxi/dram_sun9i.c
@@ -10,7 +10,6 @@
  *                    Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
  */
 
-#include <common.h>
 #include <dm.h>
 #include <errno.h>
 #include <init.h>
diff --git a/arch/arm/mach-sunxi/dram_suniv.c b/arch/arm/mach-sunxi/dram_suniv.c
index 9e583e1..640f872 100644
--- a/arch/arm/mach-sunxi/dram_suniv.c
+++ b/arch/arm/mach-sunxi/dram_suniv.c
@@ -9,7 +9,7 @@
  * Copyright(c) 2007-2018 Jianjun Jiang <8192542@qq.com>
  */
 
-#include <common.h>
+#include <config.h>
 #include <asm/io.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/dram.h>
diff --git a/arch/arm/mach-sunxi/dram_sunxi_dw.c b/arch/arm/mach-sunxi/dram_sunxi_dw.c
index daef051..3bfcc63 100644
--- a/arch/arm/mach-sunxi/dram_sunxi_dw.c
+++ b/arch/arm/mach-sunxi/dram_sunxi_dw.c
@@ -8,7 +8,6 @@
  * (C) Copyright 2015      Hans de Goede <hdegoede@redhat.com>
  * (C) Copyright 2015      Jens Kuske <jenskuske@gmail.com>
  */
-#include <common.h>
 #include <init.h>
 #include <log.h>
 #include <asm/io.h>
diff --git a/arch/arm/mach-sunxi/gtbus_sun9i.c b/arch/arm/mach-sunxi/gtbus_sun9i.c
index 5624621..a058fea 100644
--- a/arch/arm/mach-sunxi/gtbus_sun9i.c
+++ b/arch/arm/mach-sunxi/gtbus_sun9i.c
@@ -6,7 +6,6 @@
  *                    Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
  */
 
-#include <common.h>
 #include <asm/io.h>
 #include <asm/arch/cpu.h>
 #include <asm/arch/gtbus_sun9i.h>
diff --git a/arch/arm/mach-sunxi/pmic_bus.c b/arch/arm/mach-sunxi/pmic_bus.c
index 8e7625f..87df312 100644
--- a/arch/arm/mach-sunxi/pmic_bus.c
+++ b/arch/arm/mach-sunxi/pmic_bus.c
@@ -9,7 +9,6 @@
  */
 
 #include <axp_pmic.h>
-#include <common.h>
 #include <dm.h>
 #include <asm/arch/p2wi.h>
 #include <asm/arch/rsb.h>
diff --git a/arch/arm/mach-sunxi/prcm.c b/arch/arm/mach-sunxi/prcm.c
index 71a2e44..ef7c46e 100644
--- a/arch/arm/mach-sunxi/prcm.c
+++ b/arch/arm/mach-sunxi/prcm.c
@@ -13,7 +13,6 @@
  * Tom Cubie <tangliang@allwinnertech.com>
  */
 
-#include <common.h>
 #include <errno.h>
 #include <asm/io.h>
 #include <asm/arch/cpu.h>
diff --git a/arch/arm/mach-sunxi/spl_spi_sunxi.c b/arch/arm/mach-sunxi/spl_spi_sunxi.c
index 267cb0b..72faa71 100644
--- a/arch/arm/mach-sunxi/spl_spi_sunxi.c
+++ b/arch/arm/mach-sunxi/spl_spi_sunxi.c
@@ -3,7 +3,6 @@
  * Copyright (C) 2016 Siarhei Siamashka <siarhei.siamashka@gmail.com>
  */
 
-#include <common.h>
 #include <image.h>
 #include <log.h>
 #include <spl.h>
diff --git a/arch/arm/mach-sunxi/timer.c b/arch/arm/mach-sunxi/timer.c
index 9a6f6c0..1bbfad5 100644
--- a/arch/arm/mach-sunxi/timer.c
+++ b/arch/arm/mach-sunxi/timer.c
@@ -5,7 +5,6 @@
  * Tom Cubie <tangliang@allwinnertech.com>
  */
 
-#include <common.h>
 #include <init.h>
 #include <time.h>
 #include <asm/global_data.h>
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
index c8907bc..05e194d 100644
--- a/arch/arm/mach-tegra/Kconfig
+++ b/arch/arm/mach-tegra/Kconfig
@@ -55,6 +55,7 @@
 	select DM_SPI
 	select DM_SPI_FLASH
 	select MISC
+	select MTD
 	select OF_CONTROL
 	select SPI
 	select SYSRESET
diff --git a/arch/arm/mach-zynq/clk.c b/arch/arm/mach-zynq/clk.c
index e6a6732..5e1ba8d 100644
--- a/arch/arm/mach-zynq/clk.c
+++ b/arch/arm/mach-zynq/clk.c
@@ -44,8 +44,6 @@
 			gd->bd->bi_arm_freq = rate;
 			gd->cpu_clk = clk_get_rate(&clk);
 		}
-
-		clk_free(&clk);
 	}
 	gd->bd->bi_dsp_freq = 0;
 
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig
index e38c9f6..4261e50 100644
--- a/arch/microblaze/Kconfig
+++ b/arch/microblaze/Kconfig
@@ -23,6 +23,7 @@
 	select SYSRESET
 	select DM_SPI
 	select DM_SPI_FLASH
+	select MTD
 	select SPI
 	imply CMD_DM
 
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 569f5f4..f0704d9 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -77,6 +77,7 @@
 	select PINMUX
 	select PINCONF
 	select RESET_MTMIPS
+	imply MTD
 	imply DM_SPI
 	imply DM_SPI_FLASH
 	select LAST_STAGE_INIT
@@ -109,6 +110,7 @@
 	select MIPS_L2_CACHE
 	select MIPS_MACH_EARLY_INIT
 	select MIPS_TUNE_OCTEON3
+	select MTD
 	select ROM_EXCEPTION_VECTORS
 	select SUPPORTS_BIG_ENDIAN
 	select SUPPORTS_CPU_MIPS64_OCTEON
diff --git a/arch/mips/mach-pic32/cpu.c b/arch/mips/mach-pic32/cpu.c
index 3181a94..668adbb 100644
--- a/arch/mips/mach-pic32/cpu.c
+++ b/arch/mips/mach-pic32/cpu.c
@@ -30,7 +30,6 @@
 	int ret;
 	struct udevice *dev;
 	struct clk clk;
-	ulong rate;
 
 	ret = uclass_get_device(UCLASS_CLK, 0, &dev);
 	if (ret) {
@@ -43,11 +42,7 @@
 	if (ret < 0)
 		return ret;
 
-	rate = clk_get_rate(&clk);
-
-	clk_free(&clk);
-
-	return rate;
+	return clk_get_rate(&clk);
 }
 
 static ulong clk_get_cpu_rate(void)
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 67126d9..ac52c5e 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -14,6 +14,9 @@
 config TARGET_MICROCHIP_ICICLE
 	bool "Support Microchip PolarFire-SoC Icicle Board"
 
+config TARGET_MILKV_DUO
+	bool "Support Milk-v Duo Board"
+
 config TARGET_OPENPITON_RISCV64
 	bool "Support RISC-V cores on OpenPiton SoC"
 
@@ -83,6 +86,7 @@
 source "board/sifive/unleashed/Kconfig"
 source "board/sifive/unmatched/Kconfig"
 source "board/sipeed/maix/Kconfig"
+source "board/sophgo/milkv_duo/Kconfig"
 source "board/starfive/visionfive2/Kconfig"
 source "board/thead/th1520_lpi4a/Kconfig"
 source "board/xilinx/mbv/Kconfig"
diff --git a/arch/riscv/config.mk b/arch/riscv/config.mk
index 9cf2aef..9f16dda 100644
--- a/arch/riscv/config.mk
+++ b/arch/riscv/config.mk
@@ -25,7 +25,7 @@
 PLATFORM_ELFFLAGS	+= -B riscv -O elf64-littleriscv
 endif
 
-PLATFORM_CPPFLAGS	+= -ffixed-gp -fpic
+PLATFORM_CPPFLAGS	+= -ffixed-x3 -fpic
 PLATFORM_RELFLAGS	+= -fno-common -ffunction-sections -fdata-sections
 LDFLAGS_u-boot		+= --gc-sections -static -pie
 
diff --git a/arch/riscv/dts/Makefile b/arch/riscv/dts/Makefile
index b05bb56..17cda48 100644
--- a/arch/riscv/dts/Makefile
+++ b/arch/riscv/dts/Makefile
@@ -2,6 +2,7 @@
 
 dtb-$(CONFIG_TARGET_ANDES_AE350) += ae350_32.dtb ae350_64.dtb
 dtb-$(CONFIG_TARGET_MICROCHIP_ICICLE) += mpfs-icicle-kit.dtb
+dtb-$(CONFIG_TARGET_MILKV_DUO) += cv1800b-milkv-duo.dtb
 dtb-$(CONFIG_TARGET_QEMU_VIRT) += qemu-virt32.dtb qemu-virt64.dtb
 dtb-$(CONFIG_TARGET_OPENPITON_RISCV64) += openpiton-riscv64.dtb
 dtb-$(CONFIG_TARGET_SIFIVE_UNLEASHED) += hifive-unleashed-a00.dtb
diff --git a/arch/riscv/dts/cv1800b-milkv-duo.dts b/arch/riscv/dts/cv1800b-milkv-duo.dts
new file mode 100644
index 0000000..3af9e34
--- /dev/null
+++ b/arch/riscv/dts/cv1800b-milkv-duo.dts
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2023 Jisheng Zhang <jszhang@kernel.org>
+ */
+
+/dts-v1/;
+
+#include "cv1800b.dtsi"
+
+/ {
+	model = "Milk-V Duo";
+	compatible = "milkv,duo", "sophgo,cv1800b";
+
+	aliases {
+		serial0 = &uart0;
+		serial1 = &uart1;
+		serial2 = &uart2;
+		serial3 = &uart3;
+		serial4 = &uart4;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory@80000000 {
+		device_type = "memory";
+		reg = <0x80000000 0x3f40000>;
+	};
+};
+
+&osc {
+	clock-frequency = <25000000>;
+};
+
+&uart0 {
+	status = "okay";
+};
diff --git a/arch/riscv/dts/cv1800b.dtsi b/arch/riscv/dts/cv1800b.dtsi
new file mode 100644
index 0000000..165e9e3
--- /dev/null
+++ b/arch/riscv/dts/cv1800b.dtsi
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2023 Jisheng Zhang <jszhang@kernel.org>
+ */
+
+#include "cv18xx.dtsi"
+
+/ {
+	compatible = "sophgo,cv1800b";
+};
+
+&plic {
+	compatible = "sophgo,cv1800b-plic", "thead,c900-plic";
+};
+
+&clint {
+	compatible = "sophgo,cv1800b-clint", "thead,c900-clint";
+};
diff --git a/arch/riscv/dts/cv18xx.dtsi b/arch/riscv/dts/cv18xx.dtsi
new file mode 100644
index 0000000..2d6f4a4
--- /dev/null
+++ b/arch/riscv/dts/cv18xx.dtsi
@@ -0,0 +1,192 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2023 Jisheng Zhang <jszhang@kernel.org>
+ * Copyright (C) 2023 Inochi Amaoto <inochiama@outlook.com>
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	cpus: cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		timebase-frequency = <25000000>;
+
+		cpu0: cpu@0 {
+			compatible = "thead,c906", "riscv";
+			device_type = "cpu";
+			reg = <0>;
+			d-cache-block-size = <64>;
+			d-cache-sets = <512>;
+			d-cache-size = <65536>;
+			i-cache-block-size = <64>;
+			i-cache-sets = <128>;
+			i-cache-size = <32768>;
+			mmu-type = "riscv,sv39";
+			riscv,isa = "rv64imafdc";
+			riscv,isa-base = "rv64i";
+			riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "zicntr", "zicsr",
+					       "zifencei", "zihpm";
+
+			cpu0_intc: interrupt-controller {
+				compatible = "riscv,cpu-intc";
+				interrupt-controller;
+				#interrupt-cells = <1>;
+			};
+		};
+	};
+
+	osc: oscillator {
+		compatible = "fixed-clock";
+		clock-output-names = "osc_25m";
+		#clock-cells = <0>;
+	};
+
+	soc {
+		compatible = "simple-bus";
+		interrupt-parent = <&plic>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		dma-noncoherent;
+		ranges;
+
+		gpio0: gpio@3020000 {
+			compatible = "snps,dw-apb-gpio";
+			reg = <0x3020000 0x1000>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			porta: gpio-controller@0 {
+				compatible = "snps,dw-apb-gpio-port";
+				gpio-controller;
+				#gpio-cells = <2>;
+				ngpios = <32>;
+				reg = <0>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				interrupts = <60 IRQ_TYPE_LEVEL_HIGH>;
+			};
+		};
+
+		gpio1: gpio@3021000 {
+			compatible = "snps,dw-apb-gpio";
+			reg = <0x3021000 0x1000>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			portb: gpio-controller@0 {
+				compatible = "snps,dw-apb-gpio-port";
+				gpio-controller;
+				#gpio-cells = <2>;
+				ngpios = <32>;
+				reg = <0>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				interrupts = <61 IRQ_TYPE_LEVEL_HIGH>;
+			};
+		};
+
+		gpio2: gpio@3022000 {
+			compatible = "snps,dw-apb-gpio";
+			reg = <0x3022000 0x1000>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			portc: gpio-controller@0 {
+				compatible = "snps,dw-apb-gpio-port";
+				gpio-controller;
+				#gpio-cells = <2>;
+				ngpios = <32>;
+				reg = <0>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				interrupts = <62 IRQ_TYPE_LEVEL_HIGH>;
+			};
+		};
+
+		gpio3: gpio@3023000 {
+			compatible = "snps,dw-apb-gpio";
+			reg = <0x3023000 0x1000>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			portd: gpio-controller@0 {
+				compatible = "snps,dw-apb-gpio-port";
+				gpio-controller;
+				#gpio-cells = <2>;
+				ngpios = <32>;
+				reg = <0>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				interrupts = <63 IRQ_TYPE_LEVEL_HIGH>;
+			};
+		};
+
+		uart0: serial@4140000 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x04140000 0x100>;
+			interrupts = <44 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&osc>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			status = "disabled";
+		};
+
+		uart1: serial@4150000 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x04150000 0x100>;
+			interrupts = <45 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&osc>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			status = "disabled";
+		};
+
+		uart2: serial@4160000 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x04160000 0x100>;
+			interrupts = <46 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&osc>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			status = "disabled";
+		};
+
+		uart3: serial@4170000 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x04170000 0x100>;
+			interrupts = <47 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&osc>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			status = "disabled";
+		};
+
+		uart4: serial@41c0000 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x041c0000 0x100>;
+			interrupts = <48 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&osc>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			status = "disabled";
+		};
+
+		plic: interrupt-controller@70000000 {
+			reg = <0x70000000 0x4000000>;
+			interrupts-extended = <&cpu0_intc 11>, <&cpu0_intc 9>;
+			interrupt-controller;
+			#address-cells = <0>;
+			#interrupt-cells = <2>;
+			riscv,ndev = <101>;
+		};
+
+		clint: timer@74000000 {
+			reg = <0x74000000 0x10000>;
+			interrupts-extended = <&cpu0_intc 3>, <&cpu0_intc 7>;
+		};
+	};
+};
diff --git a/arch/riscv/dts/jh7110-starfive-visionfive-2.dtsi b/arch/riscv/dts/jh7110-starfive-visionfive-2.dtsi
index e94f9fe..f2c6bec 100644
--- a/arch/riscv/dts/jh7110-starfive-visionfive-2.dtsi
+++ b/arch/riscv/dts/jh7110-starfive-visionfive-2.dtsi
@@ -127,6 +127,11 @@
 	pinctrl-0 = <&i2c5_pins>;
 	status = "okay";
 
+	pmic@36 {
+		compatible = "x-powers,axp15060";
+		reg = <0x36>;
+	};
+
 	eeprom@50 {
 		compatible = "atmel,24c04";
 		reg = <0x50>;
diff --git a/arch/riscv/dts/jh7110.dtsi b/arch/riscv/dts/jh7110.dtsi
index 6d2675d..2cdc683 100644
--- a/arch/riscv/dts/jh7110.dtsi
+++ b/arch/riscv/dts/jh7110.dtsi
@@ -473,6 +473,12 @@
 			status = "disabled";
 		};
 
+		power-controller@17030000 {
+			compatible = "starfive,jh7110-pmu";
+			reg = <0x0 0x17030000 0x0 0x10000>;
+			interrupts = <111>;
+		};
+
 		qspi: spi@13010000 {
 			compatible = "cdns,qspi-nor";
 			reg = <0x0 0x13010000 0x0 0x10000
diff --git a/arch/riscv/include/asm/arch-fu740/eeprom.h b/arch/riscv/include/asm/arch-fu740/eeprom.h
new file mode 100644
index 0000000..aaa02c6
--- /dev/null
+++ b/arch/riscv/include/asm/arch-fu740/eeprom.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2024 SiFive, Inc.
+ *
+ * Zong Li <zong.li@sifve.com>
+ */
+
+#ifndef _ASM_RISCV_EEPROM_H
+#define _ASM_RISCV_EEPROM_H
+
+#define PCB_REVISION_REV3      0x3
+
+u8 get_pcb_revision_from_eeprom(void);
+
+#endif /* _ASM_RISCV_EEPROM_H */
diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h
index bf4c9af..d1113f3 100644
--- a/arch/riscv/include/asm/sbi.h
+++ b/arch/riscv/include/asm/sbi.h
@@ -33,6 +33,7 @@
 	SBI_EXT_CPPC = 0x43505043,
 	SBI_EXT_NACL = 0x4E41434C,
 	SBI_EXT_STA = 0x535441,
+	SBI_EXT_DBTR = 0x44425452,
 };
 
 enum sbi_ext_base_fid {
diff --git a/arch/riscv/lib/crt0_riscv_efi.S b/arch/riscv/lib/crt0_riscv_efi.S
index 793eefd..46b0855 100644
--- a/arch/riscv/lib/crt0_riscv_efi.S
+++ b/arch/riscv/lib/crt0_riscv_efi.S
@@ -53,7 +53,7 @@
 	.long	IMAGE_NT_SIGNATURE		/* 'PE' */
 coff_header:
 	.short	PE_MACHINE			/* RISC-V 64/32-bit */
-	.short	2				/* nr_sections */
+	.short	3				/* nr_sections */
 	.long	0				/* TimeDateStamp */
 	.long	0				/* PointerToSymbolTable */
 	.long	0				/* NumberOfSymbols */
@@ -144,18 +144,37 @@
 	.byte	0
 	.byte	0
 	.byte	0			/* end of 0 padding of section name */
-	.long	_edata - _start		/* VirtualSize */
+	.long	_etext - _start		/* VirtualSize */
 	.long	_start - ImageBase	/* VirtualAddress */
-	.long	_edata - _start		/* SizeOfRawData */
+	.long	_etext - _start		/* SizeOfRawData */
 	.long	_start - ImageBase	/* PointerToRawData */
+	.long	0			/* PointerToRelocations (0 for executables) */
+	.long	0			/* PointerToLineNumbers (0 for executables) */
+	.short	0			/* NumberOfRelocations  (0 for executables) */
+	.short	0			/* NumberOfLineNumbers  (0 for executables) */
+	/* Characteristics (section flags) */
+	.long	(IMAGE_SCN_MEM_READ | \
+		 IMAGE_SCN_MEM_EXECUTE | \
+		 IMAGE_SCN_CNT_CODE)
 
-	.long	0		/* PointerToRelocations (0 for executables) */
-	.long	0		/* PointerToLineNumbers (0 for executables) */
-	.short	0		/* NumberOfRelocations  (0 for executables) */
-	.short	0		/* NumberOfLineNumbers  (0 for executables) */
-	.long	0xe0500020	/* Characteristics (section flags) */
+	.ascii	".data"
+	.byte	0
+	.byte	0
+	.byte	0			/* end of 0 padding of section name */
+	.long	_edata - _data		/* VirtualSize */
+	.long	_data - ImageBase	/* VirtualAddress */
+	.long	_edata - _data		/* SizeOfRawData */
+	.long	_data - ImageBase	/* PointerToRawData */
+	.long	0			/* PointerToRelocations */
+	.long	0			/* PointerToLineNumbers */
+	.short	0			/* NumberOfRelocations */
+	.short	0			/* NumberOfLineNumbers */
+	/* Characteristics (section flags) */
+	.long	(IMAGE_SCN_MEM_WRITE | \
+		 IMAGE_SCN_MEM_READ | \
+		 IMAGE_SCN_CNT_INITIALIZED_DATA)
 
-	.align	9
+	.align		12
 _start:
 	addi		sp, sp, -(SIZE_LONG * 3)
 	SAVE_LONG(a0, 0)
diff --git a/arch/riscv/lib/elf_riscv32_efi.lds b/arch/riscv/lib/elf_riscv32_efi.lds
index c3e0d20..7b9bd7b 100644
--- a/arch/riscv/lib/elf_riscv32_efi.lds
+++ b/arch/riscv/lib/elf_riscv32_efi.lds
@@ -1,14 +1,18 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
+/* SPDX-License-Identifier: BSD-2-Clause */
 /*
  * U-Boot riscv32 EFI linker script
  *
- * SPDX-License-Identifier:	BSD-2-Clause
- *
  * Modified from arch/arm/lib/elf_aarch64_efi.lds
  */
 
 OUTPUT_FORMAT("elf32-littleriscv", "elf32-littleriscv", "elf32-littleriscv")
 OUTPUT_ARCH(riscv)
+
+PHDRS
+{
+	data PT_LOAD FLAGS(3); /* SHF_WRITE | SHF_ALLOC */
+}
+
 ENTRY(_start)
 SECTIONS
 {
@@ -20,11 +24,17 @@
 		*(.gnu.linkonce.t.*)
 		*(.srodata)
 		*(.rodata*)
+		. = ALIGN(16);
+		*(.dynamic);
 		. = ALIGN(512);
 	}
+	.rela.dyn : { *(.rela.dyn) }
+	.rela.plt : { *(.rela.plt) }
+	.rela.got : { *(.rela.got) }
+	.rela.data : { *(.rela.data) *(.rela.data*) }
 	_etext = .;
 	_text_size = . - _text;
-	.dynamic  : { *(.dynamic) }
+	. = ALIGN(4096);
 	.data : {
 		_data = .;
 		*(.sdata)
@@ -49,12 +59,8 @@
 		. = ALIGN(512);
 		_bss_end = .;
 		_edata = .;
-	}
-	.rela.dyn : { *(.rela.dyn) }
-	.rela.plt : { *(.rela.plt) }
-	.rela.got : { *(.rela.got) }
-	.rela.data : { *(.rela.data) *(.rela.data*) }
-	_data_size = . - _etext;
+	} :data
+	_data_size = _edata - _data;
 
 	. = ALIGN(4096);
 	.dynsym   : { *(.dynsym) }
diff --git a/arch/riscv/lib/elf_riscv64_efi.lds b/arch/riscv/lib/elf_riscv64_efi.lds
index ecb9139..d0b4f3d 100644
--- a/arch/riscv/lib/elf_riscv64_efi.lds
+++ b/arch/riscv/lib/elf_riscv64_efi.lds
@@ -1,14 +1,18 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
+/* SPDX-License-Identifier: BSD-2-Clause */
 /*
  * U-Boot riscv64 EFI linker script
  *
- * SPDX-License-Identifier:	BSD-2-Clause
- *
  * Modified from arch/arm/lib/elf_aarch64_efi.lds
  */
 
 OUTPUT_FORMAT("elf64-littleriscv", "elf64-littleriscv", "elf64-littleriscv")
 OUTPUT_ARCH(riscv)
+
+PHDRS
+{
+	data PT_LOAD FLAGS(3); /* SHF_WRITE | SHF_ALLOC */
+}
+
 ENTRY(_start)
 SECTIONS
 {
@@ -20,11 +24,17 @@
 		*(.gnu.linkonce.t.*)
 		*(.srodata)
 		*(.rodata*)
+		. = ALIGN(16);
+		*(.dynamic);
 		. = ALIGN(512);
 	}
+	.rela.dyn : { *(.rela.dyn) }
+	.rela.plt : { *(.rela.plt) }
+	.rela.got : { *(.rela.got) }
+	.rela.data : { *(.rela.data) *(.rela.data*) }
 	_etext = .;
 	_text_size = . - _text;
-	.dynamic  : { *(.dynamic) }
+	. = ALIGN(4096);
 	.data : {
 		_data = .;
 		*(.sdata)
@@ -49,12 +59,8 @@
 		. = ALIGN(512);
 		_bss_end = .;
 		_edata = .;
-	}
-	.rela.dyn : { *(.rela.dyn) }
-	.rela.plt : { *(.rela.plt) }
-	.rela.got : { *(.rela.got) }
-	.rela.data : { *(.rela.data) *(.rela.data*) }
-	_data_size = . - _etext;
+	} :data
+	_data_size = _edata - _data;
 
 	. = ALIGN(4096);
 	.dynsym   : { *(.dynsym) }
diff --git a/arch/sandbox/include/asm/clk.h b/arch/sandbox/include/asm/clk.h
index d4e04ad..37fe49c 100644
--- a/arch/sandbox/include/asm/clk.h
+++ b/arch/sandbox/include/asm/clk.h
@@ -182,14 +182,6 @@
  */
 int sandbox_clk_test_disable_bulk(struct udevice *dev);
 /**
- * sandbox_clk_test_free - Ask the sandbox clock test device to free its
- * clocks.
- *
- * @dev:	The sandbox clock test (client) device.
- * @return:	0 if OK, or a negative error code.
- */
-int sandbox_clk_test_free(struct udevice *dev);
-/**
  * sandbox_clk_test_release_bulk - Ask the sandbox clock test device to release
  * all clocks in it's clock bulk struct.
  *
diff --git a/board/AndesTech/ae350/ae350.c b/board/AndesTech/ae350/ae350.c
index 4e53fee..62b93b4 100644
--- a/board/AndesTech/ae350/ae350.c
+++ b/board/AndesTech/ae350/ae350.c
@@ -21,8 +21,6 @@
 #include <fdtdec.h>
 #include <dm.h>
 #include <spl.h>
-#include <mapmem.h>
-#include <hang.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -51,29 +49,6 @@
 }
 #endif
 
-#if CONFIG_IS_ENABLED(LOAD_FIT) || CONFIG_IS_ENABLED(LOAD_FIT_FULL)
-#define ANDES_SPL_FDT_ADDR	(CONFIG_TEXT_BASE - 0x100000)
-void spl_perform_fixups(struct spl_image_info *spl_image)
-{
-	/*
-	 * Originally, u-boot-spl will place DTB directly after the kernel,
-	 * but the size of the kernel did not include the BSS section, which
-	 * means u-boot-spl will place the DTB in the kernel BSS section
-	 * causing the DTB to be cleared by kernel BSS initializtion.
-	 * Moving DTB in front of the kernel can avoid the error.
-	 */
-	if (ANDES_SPL_FDT_ADDR < 0) {
-		printf("%s: CONFIG_TEXT_BASE needs to be larger than 0x100000\n",
-		       __func__);
-		hang();
-	}
-
-	memcpy((void *)ANDES_SPL_FDT_ADDR, spl_image->fdt_addr,
-	       fdt_totalsize(spl_image->fdt_addr));
-	spl_image->fdt_addr = map_sysmem(ANDES_SPL_FDT_ADDR, 0);
-}
-#endif
-
 int board_init(void)
 {
 	gd->bd->bi_boot_params = PHYS_SDRAM_0 + 0x400;
diff --git a/board/data_modul/imx8mp_edm_sbc/spl.c b/board/data_modul/imx8mp_edm_sbc/spl.c
index a3600c8..cc2d253 100644
--- a/board/data_modul/imx8mp_edm_sbc/spl.c
+++ b/board/data_modul/imx8mp_edm_sbc/spl.c
@@ -80,6 +80,19 @@
 	return 0;
 }
 
+void spl_board_init(void)
+{
+	/*
+	 * Set GIC clock to 500 MHz for OD VDD_SOC. Kernel driver does not
+	 * allow to change it. Should set the clock after PMIC setting done.
+	 * Default is 400 MHz (system_pll1_800m with div = 2) set by ROM for
+	 * ND VDD_SOC.
+	 */
+	clock_enable(CCGR_GIC, 0);
+	clock_set_target_val(GIC_CLK_ROOT, CLK_ROOT_ON | CLK_ROOT_SOURCE_SEL(5));
+	clock_enable(CCGR_GIC, 1);
+}
+
 int spl_board_boot_device(enum boot_device boot_dev_spl)
 {
 	if (boot_dev_spl == SPI_NOR_BOOT)	/* SPI NOR */
diff --git a/board/microchip/mpfs_icicle/Kconfig b/board/microchip/mpfs_icicle/Kconfig
index 7cd5a59..4309f75 100644
--- a/board/microchip/mpfs_icicle/Kconfig
+++ b/board/microchip/mpfs_icicle/Kconfig
@@ -50,12 +50,12 @@
 	imply CMD_I2C
 	imply DM_I2C
 	imply SYS_I2C_MICROCHIP
+	imply MTD
 	imply SPI
 	imply DM_SPI
 	imply MICROCHIP_COREQSPI
 	imply MTD_SPI_NAND
 	imply CMD_MTD
-	imply MTD_PARTITIONS
 	imply CMD_MTDPARTS
 
 endif
diff --git a/board/microchip/pic32mzda/pic32mzda.c b/board/microchip/pic32mzda/pic32mzda.c
index e7337de..3c2203d 100644
--- a/board/microchip/pic32mzda/pic32mzda.c
+++ b/board/microchip/pic32mzda/pic32mzda.c
@@ -36,8 +36,6 @@
 	rate = clk_get_rate(&clk);
 	printf("CPU Speed: %lu MHz\n", rate / 1000000);
 
-	clk_free(&clk);
-
 	return 0;
 }
 #endif
diff --git a/board/renesas/alt/alt.c b/board/renesas/alt/alt.c
index 85fbaf0..be77cad 100644
--- a/board/renesas/alt/alt.c
+++ b/board/renesas/alt/alt.c
@@ -5,7 +5,6 @@
  * Copyright (C) 2014, 2015 Renesas Electronics Corporation
  */
 
-#include <common.h>
 #include <cpu_func.h>
 #include <env.h>
 #include <hang.h>
diff --git a/board/renesas/alt/alt_spl.c b/board/renesas/alt/alt_spl.c
index cdaa04e..fc9dac5 100644
--- a/board/renesas/alt/alt_spl.c
+++ b/board/renesas/alt/alt_spl.c
@@ -5,7 +5,6 @@
  * Copyright (C) 2018 Marek Vasut <marek.vasut@gmail.com>
  */
 
-#include <common.h>
 #include <cpu_func.h>
 #include <init.h>
 #include <malloc.h>
diff --git a/board/renesas/alt/qos.c b/board/renesas/alt/qos.c
index 2f65750..38dfa64 100644
--- a/board/renesas/alt/qos.c
+++ b/board/renesas/alt/qos.c
@@ -6,7 +6,6 @@
  *
  */
 
-#include <common.h>
 #include <asm/processor.h>
 #include <asm/mach-types.h>
 #include <asm/io.h>
diff --git a/board/renesas/blanche/blanche.c b/board/renesas/blanche/blanche.c
index 8e1ae29..c6ecea2 100644
--- a/board/renesas/blanche/blanche.c
+++ b/board/renesas/blanche/blanche.c
@@ -6,7 +6,6 @@
  * Copyright (C) 2016 Renesas Electronics Corporation
  */
 
-#include <common.h>
 #include <cpu_func.h>
 #include <init.h>
 #include <net.h>
diff --git a/board/renesas/blanche/qos.c b/board/renesas/blanche/qos.c
index e3ad83e..3134b36 100644
--- a/board/renesas/blanche/qos.c
+++ b/board/renesas/blanche/qos.c
@@ -5,7 +5,6 @@
  * Copyright (C) 2016 Renesas Electronics Corporation
  */
 
-#include <common.h>
 #include <asm/processor.h>
 #include <asm/mach-types.h>
 #include <asm/io.h>
diff --git a/board/renesas/draak/draak.c b/board/renesas/draak/draak.c
index 1ed72d3..06a3a83 100644
--- a/board/renesas/draak/draak.c
+++ b/board/renesas/draak/draak.c
@@ -6,7 +6,6 @@
  * Copyright (C) 2017 Marek Vasut <marek.vasut+renesas@gmail.com>
  */
 
-#include <common.h>
 #include <cpu_func.h>
 #include <hang.h>
 #include <init.h>
diff --git a/board/renesas/falcon/falcon.c b/board/renesas/falcon/falcon.c
index 0aa0f1a..cd86bb3 100644
--- a/board/renesas/falcon/falcon.c
+++ b/board/renesas/falcon/falcon.c
@@ -6,7 +6,6 @@
  * Copyright (C) 2020 Renesas Electronics Corp.
  */
 
-#include <common.h>
 #include <asm/arch/rmobile.h>
 #include <asm/arch/sys_proto.h>
 #include <asm/global_data.h>
@@ -15,6 +14,7 @@
 #include <asm/processor.h>
 #include <linux/errno.h>
 #include <asm/system.h>
+#include <asm/u-boot.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
diff --git a/board/renesas/gose/gose.c b/board/renesas/gose/gose.c
index 2d1435a..6edbdac 100644
--- a/board/renesas/gose/gose.c
+++ b/board/renesas/gose/gose.c
@@ -5,7 +5,6 @@
  * Copyright (C) 2014 Renesas Electronics Corporation
  */
 
-#include <common.h>
 #include <clock_legacy.h>
 #include <cpu_func.h>
 #include <env.h>
diff --git a/board/renesas/gose/gose_spl.c b/board/renesas/gose/gose_spl.c
index c0bf720..87126a0 100644
--- a/board/renesas/gose/gose_spl.c
+++ b/board/renesas/gose/gose_spl.c
@@ -5,7 +5,6 @@
  * Copyright (C) 2018 Marek Vasut <marek.vasut@gmail.com>
  */
 
-#include <common.h>
 #include <cpu_func.h>
 #include <init.h>
 #include <malloc.h>
diff --git a/board/renesas/gose/qos.c b/board/renesas/gose/qos.c
index 1c4ebfc..9944df7 100644
--- a/board/renesas/gose/qos.c
+++ b/board/renesas/gose/qos.c
@@ -6,7 +6,6 @@
  * Copyright (C) 2014 Renesas Electronics Corporation
  */
 
-#include <common.h>
 #include <asm/processor.h>
 #include <asm/mach-types.h>
 #include <asm/io.h>
diff --git a/board/renesas/grpeach/grpeach.c b/board/renesas/grpeach/grpeach.c
index f609e4f..c475c3f 100644
--- a/board/renesas/grpeach/grpeach.c
+++ b/board/renesas/grpeach/grpeach.c
@@ -4,12 +4,13 @@
  * Copyright (C) Chris Brandt
  */
 
-#include <common.h>
 #include <cpu_func.h>
+#include <errno.h>
 #include <init.h>
 #include <asm/global_data.h>
 #include <asm/io.h>
 #include <asm/arch/sys_proto.h>
+#include <asm/u-boot.h>
 
 #define RZA1_WDT_BASE	0xfcfe0000
 #define WTCSR		0x00
diff --git a/board/renesas/koelsch/koelsch.c b/board/renesas/koelsch/koelsch.c
index c3ebcd3..ee5597a 100644
--- a/board/renesas/koelsch/koelsch.c
+++ b/board/renesas/koelsch/koelsch.c
@@ -6,7 +6,6 @@
  *
  */
 
-#include <common.h>
 #include <clock_legacy.h>
 #include <cpu_func.h>
 #include <env.h>
diff --git a/board/renesas/koelsch/koelsch_spl.c b/board/renesas/koelsch/koelsch_spl.c
index b377f70..7581920 100644
--- a/board/renesas/koelsch/koelsch_spl.c
+++ b/board/renesas/koelsch/koelsch_spl.c
@@ -5,7 +5,6 @@
  * Copyright (C) 2018 Marek Vasut <marek.vasut@gmail.com>
  */
 
-#include <common.h>
 #include <cpu_func.h>
 #include <init.h>
 #include <malloc.h>
diff --git a/board/renesas/koelsch/qos.c b/board/renesas/koelsch/qos.c
index f884e5f..70cd117 100644
--- a/board/renesas/koelsch/qos.c
+++ b/board/renesas/koelsch/qos.c
@@ -6,7 +6,6 @@
  *
  */
 
-#include <common.h>
 #include <asm/processor.h>
 #include <asm/mach-types.h>
 #include <asm/io.h>
diff --git a/board/renesas/lager/lager.c b/board/renesas/lager/lager.c
index 1437875..0daad0b 100644
--- a/board/renesas/lager/lager.c
+++ b/board/renesas/lager/lager.c
@@ -7,7 +7,6 @@
  * Copyright (C) 2013 Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
  */
 
-#include <common.h>
 #include <clock_legacy.h>
 #include <cpu_func.h>
 #include <env.h>
diff --git a/board/renesas/lager/lager_spl.c b/board/renesas/lager/lager_spl.c
index d3d397e..df3e240 100644
--- a/board/renesas/lager/lager_spl.c
+++ b/board/renesas/lager/lager_spl.c
@@ -5,7 +5,6 @@
  * Copyright (C) 2018 Marek Vasut <marek.vasut@gmail.com>
  */
 
-#include <common.h>
 #include <cpu_func.h>
 #include <init.h>
 #include <malloc.h>
diff --git a/board/renesas/lager/qos.c b/board/renesas/lager/qos.c
index f01ca2f..ddc831c 100644
--- a/board/renesas/lager/qos.c
+++ b/board/renesas/lager/qos.c
@@ -5,7 +5,6 @@
  * Copyright (C) 2013,2014 Renesas Electronics Corporation
  */
 
-#include <common.h>
 #include <asm/processor.h>
 #include <asm/mach-types.h>
 #include <asm/io.h>
diff --git a/board/renesas/porter/porter.c b/board/renesas/porter/porter.c
index db1fb4b..2e6051a 100644
--- a/board/renesas/porter/porter.c
+++ b/board/renesas/porter/porter.c
@@ -6,7 +6,6 @@
  * Copyright (C) 2015 Cogent Embedded, Inc.
  */
 
-#include <common.h>
 #include <clock_legacy.h>
 #include <cpu_func.h>
 #include <env.h>
diff --git a/board/renesas/porter/porter_spl.c b/board/renesas/porter/porter_spl.c
index 8595770..039fc7b 100644
--- a/board/renesas/porter/porter_spl.c
+++ b/board/renesas/porter/porter_spl.c
@@ -5,7 +5,6 @@
  * Copyright (C) 2018 Marek Vasut <marek.vasut@gmail.com>
  */
 
-#include <common.h>
 #include <cpu_func.h>
 #include <init.h>
 #include <malloc.h>
diff --git a/board/renesas/porter/qos.c b/board/renesas/porter/qos.c
index bca54f7..e4d8f3d 100644
--- a/board/renesas/porter/qos.c
+++ b/board/renesas/porter/qos.c
@@ -7,7 +7,6 @@
  *
  */
 
-#include <common.h>
 #include <asm/processor.h>
 #include <asm/mach-types.h>
 #include <asm/io.h>
diff --git a/board/renesas/r2dplus/r2dplus.c b/board/renesas/r2dplus/r2dplus.c
index 4b9959a..78b8cb4 100644
--- a/board/renesas/r2dplus/r2dplus.c
+++ b/board/renesas/r2dplus/r2dplus.c
@@ -4,7 +4,6 @@
  * Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
  */
 
-#include <common.h>
 #include <ide.h>
 #include <init.h>
 #include <net.h>
diff --git a/board/renesas/rcar-common/common.c b/board/renesas/rcar-common/common.c
index ed3f093..66eb6a2 100644
--- a/board/renesas/rcar-common/common.c
+++ b/board/renesas/rcar-common/common.c
@@ -7,7 +7,6 @@
  * Copyright (C) 2015 Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
  */
 
-#include <common.h>
 #include <dm.h>
 #include <fdt_support.h>
 #include <hang.h>
diff --git a/board/renesas/rcar-common/gen3-spl.c b/board/renesas/rcar-common/gen3-spl.c
index b02a946..44a20ce 100644
--- a/board/renesas/rcar-common/gen3-spl.c
+++ b/board/renesas/rcar-common/gen3-spl.c
@@ -5,7 +5,6 @@
  * Copyright (C) 2019 Marek Vasut <marek.vasut@gmail.com>
  */
 
-#include <common.h>
 #include <cpu_func.h>
 #include <image.h>
 #include <init.h>
diff --git a/board/renesas/rcar-common/v3-common.c b/board/renesas/rcar-common/v3-common.c
index 7c6202e..26c589d 100644
--- a/board/renesas/rcar-common/v3-common.c
+++ b/board/renesas/rcar-common/v3-common.c
@@ -3,8 +3,8 @@
  * Copyright (C) 2017-2023 Marek Vasut <marek.vasut+renesas@mailbox.org>
  */
 
-#include <common.h>
 #include <clock_legacy.h>
+#include <asm/arch/rmobile.h>
 #include <asm/io.h>
 
 #define CPGWPR  0xE6150900
diff --git a/board/renesas/salvator-x/salvator-x.c b/board/renesas/salvator-x/salvator-x.c
index 939b48e..d8312dd 100644
--- a/board/renesas/salvator-x/salvator-x.c
+++ b/board/renesas/salvator-x/salvator-x.c
@@ -7,7 +7,6 @@
  * Copyright (C) 2015 Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
  */
 
-#include <common.h>
 #include <cpu_func.h>
 #include <image.h>
 #include <init.h>
diff --git a/board/renesas/silk/qos.c b/board/renesas/silk/qos.c
index 43a2989..bdd7646 100644
--- a/board/renesas/silk/qos.c
+++ b/board/renesas/silk/qos.c
@@ -7,7 +7,6 @@
  *
  */
 
-#include <common.h>
 #include <asm/processor.h>
 #include <asm/mach-types.h>
 #include <asm/io.h>
diff --git a/board/renesas/silk/silk.c b/board/renesas/silk/silk.c
index 6ecebfe..18ff759 100644
--- a/board/renesas/silk/silk.c
+++ b/board/renesas/silk/silk.c
@@ -6,7 +6,6 @@
  * Copyright (C) 2015 Cogent Embedded, Inc.
  */
 
-#include <common.h>
 #include <cpu_func.h>
 #include <env.h>
 #include <hang.h>
diff --git a/board/renesas/silk/silk_spl.c b/board/renesas/silk/silk_spl.c
index afb9f85..b899442 100644
--- a/board/renesas/silk/silk_spl.c
+++ b/board/renesas/silk/silk_spl.c
@@ -5,7 +5,6 @@
  * Copyright (C) 2018 Marek Vasut <marek.vasut@gmail.com>
  */
 
-#include <common.h>
 #include <cpu_func.h>
 #include <init.h>
 #include <malloc.h>
diff --git a/board/renesas/spider/spider.c b/board/renesas/spider/spider.c
index fd83a72..1eb75a6 100644
--- a/board/renesas/spider/spider.c
+++ b/board/renesas/spider/spider.c
@@ -6,7 +6,6 @@
  * Copyright (C) 2021 Renesas Electronics Corp.
  */
 
-#include <common.h>
 #include <asm/arch/rmobile.h>
 #include <asm/arch/sys_proto.h>
 #include <asm/global_data.h>
diff --git a/board/renesas/stout/cpld.c b/board/renesas/stout/cpld.c
index b7c75f5..f5bb549 100644
--- a/board/renesas/stout/cpld.c
+++ b/board/renesas/stout/cpld.c
@@ -7,7 +7,6 @@
  * Copyright (C) 2015 Cogent Embedded, Inc.
  */
 
-#include <common.h>
 #include <command.h>
 #include <cpu_func.h>
 #include <asm/io.h>
diff --git a/board/renesas/stout/qos.c b/board/renesas/stout/qos.c
index c2f0b85..9030ba7 100644
--- a/board/renesas/stout/qos.c
+++ b/board/renesas/stout/qos.c
@@ -7,7 +7,6 @@
  * Copyright (C) 2015 Cogent Embedded, Inc.
  */
 
-#include <common.h>
 #include <asm/processor.h>
 #include <asm/mach-types.h>
 #include <asm/io.h>
diff --git a/board/renesas/stout/stout.c b/board/renesas/stout/stout.c
index f069ecc..131deac 100644
--- a/board/renesas/stout/stout.c
+++ b/board/renesas/stout/stout.c
@@ -8,7 +8,6 @@
  * Copyright (C) 2015 Cogent Embedded, Inc.
  */
 
-#include <common.h>
 #include <clock_legacy.h>
 #include <env.h>
 #include <init.h>
diff --git a/board/renesas/stout/stout_spl.c b/board/renesas/stout/stout_spl.c
index c37c055..8ec0216 100644
--- a/board/renesas/stout/stout_spl.c
+++ b/board/renesas/stout/stout_spl.c
@@ -5,7 +5,6 @@
  * Copyright (C) 2018 Marek Vasut <marek.vasut@gmail.com>
  */
 
-#include <common.h>
 #include <cpu_func.h>
 #include <init.h>
 #include <malloc.h>
diff --git a/board/renesas/ulcb/cpld.c b/board/renesas/ulcb/cpld.c
index 0c060a5..e72e45e 100644
--- a/board/renesas/ulcb/cpld.c
+++ b/board/renesas/ulcb/cpld.c
@@ -6,7 +6,6 @@
  * Copyright (C) 2017 Cogent Embedded, Inc.
  */
 
-#include <common.h>
 #include <command.h>
 #include <asm/gpio.h>
 #include <asm/io.h>
diff --git a/board/renesas/ulcb/ulcb.c b/board/renesas/ulcb/ulcb.c
index 1477750..b2a16b0 100644
--- a/board/renesas/ulcb/ulcb.c
+++ b/board/renesas/ulcb/ulcb.c
@@ -6,7 +6,6 @@
  * Copyright (C) 2017 Renesas Electronics Corporation
  */
 
-#include <common.h>
 #include <image.h>
 #include <init.h>
 #include <malloc.h>
diff --git a/board/renesas/v3hsk/cpld.c b/board/renesas/v3hsk/cpld.c
index 6016f6d..1272aec 100644
--- a/board/renesas/v3hsk/cpld.c
+++ b/board/renesas/v3hsk/cpld.c
@@ -7,7 +7,6 @@
  *
  */
 
-#include <common.h>
 #include <dm.h>
 #include <errno.h>
 #include <i2c.h>
diff --git a/board/renesas/v3msk/cpld.c b/board/renesas/v3msk/cpld.c
index aed616a..260755a 100644
--- a/board/renesas/v3msk/cpld.c
+++ b/board/renesas/v3msk/cpld.c
@@ -7,7 +7,6 @@
  *
  */
 
-#include <common.h>
 #include <asm/gpio.h>
 #include <asm/io.h>
 #include <dm.h>
diff --git a/board/renesas/whitehawk/whitehawk.c b/board/renesas/whitehawk/whitehawk.c
index 32284b2..a72f5e0 100644
--- a/board/renesas/whitehawk/whitehawk.c
+++ b/board/renesas/whitehawk/whitehawk.c
@@ -6,7 +6,6 @@
  * Copyright (C) 2021 Renesas Electronics Corp.
  */
 
-#include <common.h>
 #include <asm/arch/rmobile.h>
 #include <asm/arch/sys_proto.h>
 #include <asm/global_data.h>
@@ -32,7 +31,7 @@
 
 static void init_gic_v3(void)
 {
-	 /* GIC v3 power on */
+	/* GIC v3 power on */
 	writel(BIT(1), GICR_LPI_PWRR);
 
 	/* Wait till the WAKER_CA_BIT changes to 0 */
diff --git a/board/sifive/unmatched/spl.c b/board/sifive/unmatched/spl.c
index 7c0beed..e69bed9 100644
--- a/board/sifive/unmatched/spl.c
+++ b/board/sifive/unmatched/spl.c
@@ -15,6 +15,29 @@
 #include <asm/gpio.h>
 #include <asm/arch/gpio.h>
 #include <asm/arch/spl.h>
+#include <linux/io.h>
+#include <asm/arch/eeprom.h>
+
+struct pwm_sifive_regs {
+	unsigned int cfg;       /* PWM configuration register */
+	unsigned int pad0;      /* Reserved */
+	unsigned int cnt;       /* PWM count register */
+	unsigned int pad1;      /* Reserved */
+	unsigned int pwms;      /* Scaled PWM count register */
+	unsigned int pad2;      /* Reserved */
+	unsigned int pad3;      /* Reserved */
+	unsigned int pad4;      /* Reserved */
+	unsigned int cmp0;      /* PWM 0 compare register */
+	unsigned int cmp1;      /* PWM 1 compare register */
+	unsigned int cmp2;      /* PWM 2 compare register */
+	unsigned int cmp3;      /* PWM 3 compare register */
+};
+
+#define PWM0_BASE               0x10020000
+#define PWM1_BASE               0x10021000
+#define PWM_CFG_INIT            0x1000
+#define PWM_CMP_ENABLE_VAL      0x0
+#define PWM_CMP_DISABLE_VAL     0xffff
 
 #define UBRDG_RESET	SIFIVE_GENERIC_GPIO_NR(0, 7)
 #define ULPI_RESET	SIFIVE_GENERIC_GPIO_NR(0, 9)
@@ -26,6 +49,33 @@
 #define MODE_SELECT_SD		0xb
 #define MODE_SELECT_MASK	GENMASK(3, 0)
 
+void spl_pwm_device_init(void)
+{
+	struct pwm_sifive_regs *pwm0, *pwm1;
+
+	pwm0 = (struct pwm_sifive_regs *)PWM0_BASE;
+	pwm1 = (struct pwm_sifive_regs *)PWM1_BASE;
+	writel(PWM_CMP_DISABLE_VAL, (void *)&pwm0->cmp0);
+
+	/* Set the 3-color PWM LEDs to yellow in SPL */
+	writel(PWM_CMP_ENABLE_VAL, (void *)&pwm0->cmp1);
+	writel(PWM_CMP_ENABLE_VAL, (void *)&pwm0->cmp2);
+	writel(PWM_CMP_DISABLE_VAL, (void *)&pwm0->cmp3);
+	writel(PWM_CFG_INIT, (void *)&pwm0->cfg);
+
+	/* Turn on all the fans, (J21), (J23) and (J24), on the unmatched board */
+	/* The SoC fan(J21) on the rev3 board cannot be controlled by PWM_COMP0,
+	 *            so here sets the initial value of PWM_COMP0 as DISABLE */
+	if (get_pcb_revision_from_eeprom() == PCB_REVISION_REV3)
+		writel(PWM_CMP_DISABLE_VAL, (void *)&pwm1->cmp1);
+	else
+		writel(PWM_CMP_ENABLE_VAL, (void *)&pwm1->cmp1);
+
+	writel(PWM_CMP_ENABLE_VAL, (void *)&pwm1->cmp2);
+	writel(PWM_CMP_ENABLE_VAL, (void *)&pwm1->cmp3);
+	writel(PWM_CFG_INIT, (void *)&pwm1->cfg);
+}
+
 static inline int spl_reset_device_by_gpio(const char *label, int pin, int low_width)
 {
 	int ret;
@@ -90,6 +140,8 @@
 		goto end;
 	}
 
+	spl_pwm_device_init();
+
 	ret = spl_gemgxl_init();
 	if (ret) {
 		debug("Gigabit ethernet PHY (VSC8541) init failed: %d\n", ret);
diff --git a/board/sipeed/maix/maix.c b/board/sipeed/maix/maix.c
index 79e492f..06653b5 100644
--- a/board/sipeed/maix/maix.c
+++ b/board/sipeed/maix/maix.c
@@ -32,7 +32,6 @@
 			continue;
 
 		ret = clk_enable(&clk);
-		clk_free(&clk);
 		if (ret)
 			return ret;
 	}
diff --git a/board/solidrun/clearfog/Kconfig b/board/solidrun/clearfog/Kconfig
index 60d3921..b1623038 100644
--- a/board/solidrun/clearfog/Kconfig
+++ b/board/solidrun/clearfog/Kconfig
@@ -39,6 +39,25 @@
 	  SGMII connection (requires a supporting SFP). By default, transfer speed
 	  of 1.25 Gbps is used, suitable for a more common 1 Gbps SFP module.
 
+choice CLEARFOG_GTR_SERDES0
+	prompt "Select Clearfog GTR SerDes 0 Function"
+	default CLEARFOG_GTR_SERDES0_PCIE
+	help
+	  Select function for SerDes 0 which is shared between CON3 and CON18
+	  for either pci-e or sata.
+
+config CLEARFOG_GTR_SERDES0_PCIE
+	bool "PCI-E on CON3"
+	help
+	  Configure SerDes 0 for PCI-E to enable CON3 mini-PCI-E connector.
+
+config CLEARFOG_GTR_SERDES0_SATA
+	bool "SATA on CON18"
+	help
+	  Configure SerDes 0 for SATA to enable CON18 SATA connector.
+
+endchoice
+
 config ENV_SIZE
 	hex "Environment Size"
 	default 0x10000
diff --git a/board/solidrun/clearfog/clearfog.c b/board/solidrun/clearfog/clearfog.c
index 6fa2fe5..6977db0 100644
--- a/board/solidrun/clearfog/clearfog.c
+++ b/board/solidrun/clearfog/clearfog.c
@@ -90,9 +90,22 @@
 
 	/* Apply runtime detection changes */
 	if (sr_product_is(&cf_tlv_data, "Clearfog GTR")) {
-		board_serdes_map[0].serdes_type = PEX0;
-		board_serdes_map[0].serdes_speed = SERDES_SPEED_5_GBPS;
-		board_serdes_map[0].serdes_mode = PEX_ROOT_COMPLEX_X1;
+		if (IS_ENABLED(CONFIG_CLEARFOG_GTR_SERDES0_SATA)) {
+			/* serdes 0 is sata (like clearfog pro) */
+		} else if (IS_ENABLED(CONFIG_CLEARFOG_GTR_SERDES0_PCIE)) {
+			/* serdes 0 is pci */
+			board_serdes_map[0].serdes_type = PEX0;
+			board_serdes_map[0].serdes_speed = SERDES_SPEED_5_GBPS;
+			board_serdes_map[0].serdes_mode = PEX_ROOT_COMPLEX_X1;
+		}
+		/* serdes 1 is 2.5Gbps fixed link to ethernet switch */
+		board_serdes_map[1].serdes_type = SGMII1;
+		board_serdes_map[1].serdes_speed = SERDES_SPEED_3_125_GBPS;
+		board_serdes_map[1].serdes_mode = SERDES_DEFAULT_MODE;
+		/* serdes 2 is pci (like clearfog pro) */
+		/* serdes 3 is usb-3 (like clearfog pro) */
+		/* serdes 4 is pci (like clearfog pro) */
+		/* serdes 5 is sfp connector (like clearfog pro) */
 	} else if (sr_product_is(&cf_tlv_data, "Clearfog Pro")) {
 		/* handle recognized product as noop, no adjustment required */
 	} else if (sr_product_is(&cf_tlv_data, "Clearfog Base")) {
diff --git a/board/sophgo/milkv_duo/Kconfig b/board/sophgo/milkv_duo/Kconfig
new file mode 100644
index 0000000..2a458f2
--- /dev/null
+++ b/board/sophgo/milkv_duo/Kconfig
@@ -0,0 +1,28 @@
+if TARGET_MILKV_DUO
+
+config SYS_BOARD
+	default "milkv_duo"
+
+config SYS_VENDOR
+	default "sophgo"
+
+config SYS_CPU
+	default "generic"
+
+config SYS_CONFIG_NAME
+	default "milkv_duo"
+
+config TEXT_BASE
+	default 0x80200000
+
+config ENV_SIZE
+	default 0x20000
+
+config ENV_SECT_SIZE
+	default 0x40000
+
+config BOARD_SPECIFIC_OPTIONS
+	def_bool y
+	select GENERIC_RISCV
+
+endif
diff --git a/board/sophgo/milkv_duo/MAINTAINERS b/board/sophgo/milkv_duo/MAINTAINERS
new file mode 100644
index 0000000..651a059
--- /dev/null
+++ b/board/sophgo/milkv_duo/MAINTAINERS
@@ -0,0 +1,6 @@
+Milk-V Duo
+M:	Kongyang Liu <seashell11234455@gmail.com>
+S:	Maintained
+F:	board/sophgo/milkv_duo/
+F:	configs/milkv_duo_defconfig
+F:	doc/board/sophgo/milkv_duo.rst
diff --git a/board/sophgo/milkv_duo/Makefile b/board/sophgo/milkv_duo/Makefile
new file mode 100644
index 0000000..a087013
--- /dev/null
+++ b/board/sophgo/milkv_duo/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (c) 2024, Kongyang Liu <seashell11234455@gmail.com>
+
+obj-y := board.o
diff --git a/board/sophgo/milkv_duo/board.c b/board/sophgo/milkv_duo/board.c
new file mode 100644
index 0000000..eaa47be
--- /dev/null
+++ b/board/sophgo/milkv_duo/board.c
@@ -0,0 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2024, Kongyang Liu <seashell11234455@gmail.com>
+ */
+
+int board_init(void)
+{
+	return 0;
+}
diff --git a/board/starfive/visionfive2/spl.c b/board/starfive/visionfive2/spl.c
index 336f0cd..1b49945 100644
--- a/board/starfive/visionfive2/spl.c
+++ b/board/starfive/visionfive2/spl.c
@@ -45,6 +45,10 @@
 	{"/soc/ethernet@16030000/mdio/ethernet-phy@0",
 		"motorcomm,tx-clk-1000-inverted", NULL},
 	{"/soc/ethernet@16030000/mdio/ethernet-phy@0",
+		"motorcomm,rx-clk-drv-microamp", "3970"},
+	{"/soc/ethernet@16030000/mdio/ethernet-phy@0",
+		"motorcomm,rx-data-drv-microamp", "2910"},
+	{"/soc/ethernet@16030000/mdio/ethernet-phy@0",
 		"rx-internal-delay-ps", "1900"},
 	{"/soc/ethernet@16030000/mdio/ethernet-phy@0",
 		"tx-internal-delay-ps", "1500"},
@@ -54,6 +58,10 @@
 	{ "/soc/ethernet@16040000/mdio/ethernet-phy@1",
 		"motorcomm,tx-clk-100-inverted", NULL},
 	{"/soc/ethernet@16040000/mdio/ethernet-phy@1",
+		"motorcomm,rx-clk-drv-microamp", "3970"},
+	{"/soc/ethernet@16040000/mdio/ethernet-phy@1",
+		"motorcomm,rx-data-drv-microamp", "2910"},
+	{"/soc/ethernet@16040000/mdio/ethernet-phy@1",
 		"rx-internal-delay-ps", "0"},
 	{"/soc/ethernet@16040000/mdio/ethernet-phy@1",
 		"tx-internal-delay-ps", "0"},
@@ -61,11 +69,13 @@
 
 void spl_fdt_fixup_version_a(void *fdt)
 {
+	static const char compat[] = "starfive,visionfive-2-v1.2a\0starfive,jh7110";
 	u32 phandle;
 	u8 i;
 	int offset;
 	int ret;
 
+	fdt_setprop(fdt, fdt_path_offset(fdt, "/"), "compatible", compat, sizeof(compat));
 	fdt_setprop_string(fdt, fdt_path_offset(fdt, "/"), "model",
 			   "StarFive VisionFive 2 v1.2A");
 
@@ -106,11 +116,13 @@
 
 void spl_fdt_fixup_version_b(void *fdt)
 {
+	static const char compat[] = "starfive,visionfive-2-v1.3b\0starfive,jh7110";
 	u32 phandle;
 	u8 i;
 	int offset;
 	int ret;
 
+	fdt_setprop(fdt, fdt_path_offset(fdt, "/"), "compatible", compat, sizeof(compat));
 	fdt_setprop_string(fdt, fdt_path_offset(fdt, "/"), "model",
 			   "StarFive VisionFive 2 v1.3B");
 
diff --git a/board/sunxi/MAINTAINERS b/board/sunxi/MAINTAINERS
index f556857..a2da6a4 100644
--- a/board/sunxi/MAINTAINERS
+++ b/board/sunxi/MAINTAINERS
@@ -348,6 +348,11 @@
 S:	Maintained
 F:	configs/libretech_all_h5_cc_h5_defconfig
 
+NANOPI DUO2 BOARD
+M:	Chuanhong Guo <gch981213@gmail.com>
+S:	Maintained
+F:	configs/nanopi_duo2_defconfig
+
 NANOPI-M1 BOARD
 M:	Mylène Josserand <mylene.josserand@free-electrons.com>
 S:	Maintained
@@ -550,6 +555,11 @@
 S:	Maintained
 F:	configs/tbs_a711_defconfig
 
+TRANSPEED 8K618-T BOARD
+M:	Nick Alilovic <nickalilovic@gmail.com>
+S:	Maintained
+F:	configs/transpeed-8k618-t_defconfig
+
 WEXLER-TAB7200 BOARD
 M:	Aleksei Mamlin <mamlinav@gmail.com>
 S:	Maintained
diff --git a/board/synopsys/hsdk/clk-lib.c b/board/synopsys/hsdk/clk-lib.c
index be76d6c..a9614e9 100644
--- a/board/synopsys/hsdk/clk-lib.c
+++ b/board/synopsys/hsdk/clk-lib.c
@@ -56,8 +56,6 @@
 
 	priv_rate = clk_get_rate(&clk);
 
-	clk_free(&clk);
-
 	mhz_rate = ceil(priv_rate, HZ_IN_MHZ);
 
 	if (ctl & CLK_MHZ)
diff --git a/board/ti/am62x/evm.c b/board/ti/am62x/evm.c
index ad93908..88e0215 100644
--- a/board/ti/am62x/evm.c
+++ b/board/ti/am62x/evm.c
@@ -60,27 +60,9 @@
 }
 
 #if defined(CONFIG_SPL_BUILD)
-static int video_setup(void)
-{
-	if (CONFIG_IS_ENABLED(VIDEO)) {
-		ulong addr;
-		int ret;
-
-		addr = gd->relocaddr;
-		ret = video_reserve(&addr);
-		if (ret)
-			return ret;
-		debug("Reserving %luk for video at: %08lx\n",
-		      ((unsigned long)gd->relocaddr - addr) >> 10, addr);
-		gd->relocaddr = addr;
-	}
-
-	return 0;
-}
 
 void spl_board_init(void)
 {
-	video_setup();
 	enable_caches();
 	if (IS_ENABLED(CONFIG_SPL_SPLASH_SCREEN) && IS_ENABLED(CONFIG_SPL_BMP))
 		splash_display();
diff --git a/board/ti/common/board_detect.c b/board/ti/common/board_detect.c
index 0ec6d1a..38e23cc 100644
--- a/board/ti/common/board_detect.c
+++ b/board/ti/common/board_detect.c
@@ -129,7 +129,7 @@
 
 	rc = dm_i2c_read(dev, 0x1, &offset_test, sizeof(offset_test));
 
-	if (*((u32 *)ep) != (header & 0xFF))
+	if (offset_test != ((header >> 8) & 0xFF))
 		one_byte_addressing = false;
 
 	/* Corrupted data??? */
@@ -181,7 +181,7 @@
 
 	rc = i2c_read(dev_addr, 0x1, byte, &offset_test, sizeof(offset_test));
 
-	if (*((u32 *)ep) != (header & 0xFF))
+	if (offset_test != ((header >> 8) & 0xFF))
 		one_byte_addressing = false;
 
 	/* Corrupted data??? */
diff --git a/board/toradex/verdin-am62/verdin-am62.c b/board/toradex/verdin-am62/verdin-am62.c
index 2718263..395eb36 100644
--- a/board/toradex/verdin-am62/verdin-am62.c
+++ b/board/toradex/verdin-am62/verdin-am62.c
@@ -14,10 +14,13 @@
 #include <fdt_support.h>
 #include <init.h>
 #include <k3-ddrss.h>
+#include <power/regulator.h>
 #include <spl.h>
 
 #include "../common/tdx-cfg-block.h"
 
+#define VDD_CORE_REG "buck1"
+
 DECLARE_GLOBAL_DATA_PTR;
 
 int board_init(void)
@@ -50,9 +53,37 @@
 }
 #endif
 
+static u32 get_vdd_core_nominal(void)
+{
+	int core_uvolt;
+
+	switch (k3_get_speed_grade()) {
+	case 'G':
+	case 'K':
+	case 'S':
+		core_uvolt = 750000;
+		break;
+	case 'T':
+	default:
+		core_uvolt = 850000;
+		break;
+	}
+	return core_uvolt;
+}
+
 #if IS_ENABLED(CONFIG_OF_LIBFDT) && IS_ENABLED(CONFIG_OF_BOARD_SETUP)
 int ft_board_setup(void *blob, struct bd_info *bd)
 {
+	int core_uvolt;
+
+	core_uvolt = get_vdd_core_nominal();
+	if (core_uvolt != 850000) {
+		do_fixup_by_path_u32(blob, "/bus@f0000/i2c@20000000/pmic@30/regulators/buck1",
+				     "regulator-max-microvolt", core_uvolt, 0);
+		do_fixup_by_path_u32(blob, "/bus@f0000/i2c@20000000/pmic@30/regulators/buck1",
+				     "regulator-min-microvolt", core_uvolt, 0);
+	}
+
 	return ft_common_board_setup(blob, bd);
 }
 #endif
@@ -87,6 +118,22 @@
 
 int board_late_init(void)
 {
+	int ret;
+	int core_uvolt;
+	struct udevice *dev = NULL;
+
+	core_uvolt = get_vdd_core_nominal();
+	if (core_uvolt != 850000) {
+		/* Set CPU core voltage to 0.75V for slower speed grades */
+		ret = regulator_get_by_devname(VDD_CORE_REG, &dev);
+		if (ret)
+			pr_err("VDD CORE Regulator get error: %d\n", ret);
+
+		ret = regulator_set_value_force(dev, core_uvolt);
+		if (ret)
+			pr_err("VDD CORE Regulator value setting error: %d\n", ret);
+	}
+
 	select_dt_from_module_version();
 
 	return 0;
@@ -102,12 +149,13 @@
 {
 	u32 val;
 
-	/* Set USB0 PHY core voltage to 0.85V */
+	/* Clear USB0_PHY_CTRL_CORE_VOLTAGE */
+	/* TI recommends to clear the bit independent of VDDA_CORE_USB */
 	val = readl(CTRLMMR_USB0_PHY_CTRL);
 	val &= ~(CORE_VOLTAGE);
 	writel(val, CTRLMMR_USB0_PHY_CTRL);
 
-	/* Set USB1 PHY core voltage to 0.85V */
+	/* Clear USB1_PHY_CTRL_CORE_VOLTAGE */
 	val = readl(CTRLMMR_USB1_PHY_CTRL);
 	val &= ~(CORE_VOLTAGE);
 	writel(val, CTRLMMR_USB1_PHY_CTRL);
diff --git a/cmd/Kconfig b/cmd/Kconfig
index 50625e7..a86b570 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -94,7 +94,7 @@
 
 config SYS_MAXARGS
 	int "Maximum number arguments accepted by commands"
-	default 16
+	default 64
 
 config SYS_XTRACE
 	bool "Command execution tracer"
@@ -232,6 +232,12 @@
 	help
 	  Display information about the SBI implementation.
 
+config CMD_SMBIOS
+	bool "smbios"
+	depends on SMBIOS
+	help
+	  Display the SMBIOS information.
+
 endmenu
 
 menu "Boot commands"
@@ -1085,7 +1091,7 @@
 config CMD_FLASH
 	bool "flinfo, erase, protect"
 	default y
-	depends on MTD || FLASH_CFI_DRIVER || MTD_NOR_FLASH
+	depends on FLASH_CFI_DRIVER || MTD_NOR_FLASH
 	help
 	  NOR flash support.
 	    flinfo - print FLASH memory information
@@ -2702,6 +2708,7 @@
 config CMD_MTDPARTS
 	bool "MTD partition support"
 	depends on MTD
+	select MTD_PARTITIONS
 	help
 	  MTD partitioning tool support.
 	  It is strongly encouraged to avoid using this command
diff --git a/cmd/Makefile b/cmd/Makefile
index e2a2b16..87133cc 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -168,6 +168,7 @@
 obj-$(CONFIG_CMD_SETEXPR_FMT) += printf.o
 obj-$(CONFIG_CMD_SPI) += spi.o
 obj-$(CONFIG_CMD_STRINGS) += strings.o
+obj-$(CONFIG_CMD_SMBIOS) += smbios.o
 obj-$(CONFIG_CMD_SMC) += smccc.o
 obj-$(CONFIG_CMD_SYSBOOT) += sysboot.o
 obj-$(CONFIG_CMD_STACKPROTECTOR_TEST) += stackprot_test.o
diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c
index 987b168..78184fc 100644
--- a/cmd/bootmenu.c
+++ b/cmd/bootmenu.c
@@ -119,7 +119,7 @@
 				iter = iter->next;
 			return iter->key;
 		case BKEY_QUIT:
-			/* Quit by choosing the last entry - U-Boot console */
+			/* Quit by choosing the last entry */
 			iter = menu->first;
 			while (iter->next)
 				iter = iter->next;
@@ -361,15 +361,15 @@
 	}
 #endif
 
-	/* Add U-Boot console entry at the end */
+	/* Add Exit entry at the end */
 	if (i <= MAX_COUNT - 1) {
 		entry = malloc(sizeof(struct bootmenu_entry));
 		if (!entry)
 			goto cleanup;
 
-		/* Add Quit entry if entering U-Boot console is disabled */
+		/* Add Quit entry if exiting bootmenu is disabled */
 		if (!IS_ENABLED(CONFIG_BOOTMENU_DISABLE_UBOOT_CONSOLE))
-			entry->title = strdup("U-Boot console");
+			entry->title = strdup("Exit");
 		else
 			entry->title = strdup("Quit");
 
@@ -532,7 +532,7 @@
 		title = strdup(iter->title);
 		command = strdup(iter->command);
 
-		/* last entry is U-Boot console or Quit */
+		/* last entry exits bootmenu */
 		if (iter->num == iter->menu->count - 1) {
 			ret = BOOTMENU_RET_QUIT;
 			goto cleanup;
diff --git a/cmd/efidebug.c b/cmd/efidebug.c
index a3a7556..a587860 100644
--- a/cmd/efidebug.c
+++ b/cmd/efidebug.c
@@ -173,15 +173,12 @@
 static int do_efi_capsule_esrt(struct cmd_tbl *cmdtp, int flag,
 			       int argc, char * const argv[])
 {
-	struct efi_system_resource_table *esrt = NULL;
+	struct efi_system_resource_table *esrt;
 
 	if (argc != 1)
 		return CMD_RET_USAGE;
 
-	for (int idx = 0; idx < systab.nr_tables; idx++)
-		if (!guidcmp(&efi_esrt_guid, &systab.tables[idx].guid))
-			esrt = (struct efi_system_resource_table *)systab.tables[idx].table;
-
+	esrt = efi_get_configuration_table(&efi_esrt_guid);
 	if (!esrt) {
 		log_info("ESRT: table not present\n");
 		return CMD_RET_SUCCESS;
diff --git a/cmd/riscv/sbi.c b/cmd/riscv/sbi.c
index 940d9bc..9daf0e2 100644
--- a/cmd/riscv/sbi.c
+++ b/cmd/riscv/sbi.c
@@ -53,6 +53,7 @@
 	{ SBI_EXT_CPPC,			      "Collaborative Processor Performance Control Extension" },
 	{ SBI_EXT_NACL,			      "Nested Acceleration Extension" },
 	{ SBI_EXT_STA,			      "Steal-time Accounting Extension" },
+	{ SBI_EXT_DBTR,			      "Debug Trigger Extension" },
 };
 
 static int do_sbi(struct cmd_tbl *cmdtp, int flag, int argc,
diff --git a/cmd/smbios.c b/cmd/smbios.c
new file mode 100644
index 0000000..feebf93
--- /dev/null
+++ b/cmd/smbios.c
@@ -0,0 +1,191 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * The 'smbios' command displays information from the SMBIOS table.
+ *
+ * Copyright (c) 2023, Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
+ */
+
+#include <command.h>
+#include <hexdump.h>
+#include <mapmem.h>
+#include <smbios.h>
+#include <tables_csum.h>
+#include <asm/global_data.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/**
+ * smbios_get_string() - get SMBIOS string from table
+ *
+ * @table:	SMBIOS table
+ * @index:	index of the string
+ * Return:	address of string, may point to empty string
+ */
+static const char *smbios_get_string(void *table, int index)
+{
+	const char *str = (char *)table +
+			  ((struct smbios_header *)table)->length;
+
+	if (!*str)
+		++str;
+	for (--index; *str && index; --index)
+		str += strlen(str) + 1;
+
+	return str;
+}
+
+static struct smbios_header *next_table(struct smbios_header *table)
+{
+	const char *str;
+
+	if (table->type == SMBIOS_END_OF_TABLE)
+		return NULL;
+
+	str = smbios_get_string(table, 0);
+	return (struct smbios_header *)(++str);
+}
+
+static void smbios_print_generic(struct smbios_header *table)
+{
+	char *str = (char *)table + table->length;
+
+	if (CONFIG_IS_ENABLED(HEXDUMP)) {
+		printf("Header and Data:\n");
+		print_hex_dump("\t", DUMP_PREFIX_OFFSET, 16, 1,
+			       table, table->length, false);
+	}
+	if (*str) {
+		printf("Strings:\n");
+		for (int index = 1; *str; ++index) {
+			printf("\tString %u: %s\n", index, str);
+			str += strlen(str) + 1;
+		}
+	}
+}
+
+void smbios_print_str(const char *label, void *table, u8 index)
+{
+	printf("\t%s: %s\n", label, smbios_get_string(table, index));
+}
+
+static void smbios_print_type1(struct smbios_type1 *table)
+{
+	printf("System Information\n");
+	smbios_print_str("Manufacturer", table, table->manufacturer);
+	smbios_print_str("Product Name", table, table->product_name);
+	smbios_print_str("Version", table, table->version);
+	smbios_print_str("Serial Number", table, table->serial_number);
+	if (table->length >= 0x19) {
+		printf("\tUUID %pUl\n", table->uuid);
+		smbios_print_str("Wake Up Type", table, table->serial_number);
+	}
+	if (table->length >= 0x1b) {
+		smbios_print_str("Serial Number", table, table->serial_number);
+		smbios_print_str("SKU Number", table, table->sku_number);
+	}
+}
+
+static void smbios_print_type2(struct smbios_type2 *table)
+{
+	u16 *handle;
+
+	printf("Base Board Information\n");
+	smbios_print_str("Manufacturer", table, table->manufacturer);
+	smbios_print_str("Product Name", table, table->product_name);
+	smbios_print_str("Version", table, table->version);
+	smbios_print_str("Serial Number", table, table->serial_number);
+	smbios_print_str("Asset Tag", table, table->asset_tag_number);
+	printf("\tFeature Flags: 0x%2x\n", table->feature_flags);
+	smbios_print_str("Chassis Location", table, table->chassis_location);
+	printf("\tChassis Handle: 0x%2x\n", table->chassis_handle);
+	smbios_print_str("Board Type", table, table->board_type);
+	printf("\tContained Object Handles: ");
+	handle = (void *)table->eos;
+	for (int i = 0; i < table->number_contained_objects; ++i)
+		printf("0x%04x ", handle[i]);
+	printf("\n");
+}
+
+static void smbios_print_type127(struct smbios_type127 *table)
+{
+	printf("End Of Table\n");
+}
+
+static int do_smbios(struct cmd_tbl *cmdtp, int flag, int argc,
+		     char *const argv[])
+{
+	ulong addr;
+	void *entry;
+	u32 size;
+	char version[12];
+	struct smbios_header *table;
+	static const char smbios_sig[] = "_SM_";
+	static const char smbios3_sig[] = "_SM3_";
+	size_t count = 0;
+	u32 max_struct_size;
+
+	addr = gd_smbios_start();
+	if (!addr) {
+		log_warning("SMBIOS not available\n");
+		return CMD_RET_FAILURE;
+	}
+	entry = map_sysmem(addr, 0);
+	if (!memcmp(entry, smbios3_sig, sizeof(smbios3_sig) - 1)) {
+		struct smbios3_entry *entry3 = entry;
+
+		table = (void *)(uintptr_t)entry3->struct_table_address;
+		snprintf(version, sizeof(version), "%d.%d.%d",
+			 entry3->major_ver, entry3->minor_ver, entry3->doc_rev);
+		table = (void *)(uintptr_t)entry3->struct_table_address;
+		size = entry3->length;
+		max_struct_size = entry3->max_struct_size;
+	} else if (!memcmp(entry, smbios_sig, sizeof(smbios_sig) - 1)) {
+		struct smbios_entry *entry2 = entry;
+
+		snprintf(version, sizeof(version), "%d.%d",
+			 entry2->major_ver, entry2->minor_ver);
+		table = (void *)(uintptr_t)entry2->struct_table_address;
+		size = entry2->length;
+		max_struct_size = entry2->max_struct_size;
+	} else {
+		log_err("Unknown SMBIOS anchor format\n");
+		return CMD_RET_FAILURE;
+	}
+	if (table_compute_checksum(entry, size)) {
+		log_err("Invalid anchor checksum\n");
+		return CMD_RET_FAILURE;
+	}
+	printf("SMBIOS %s present.\n", version);
+
+	for (struct smbios_header *pos = table; pos; pos = next_table(pos))
+		++count;
+	printf("%zd structures occupying %d bytes\n", count, max_struct_size);
+	printf("Table at 0x%llx\n", (unsigned long long)map_to_sysmem(table));
+
+	for (struct smbios_header *pos = table; pos; pos = next_table(pos)) {
+		printf("\nHandle 0x%04x, DMI type %d, %d bytes at 0x%llx\n",
+		       pos->handle, pos->type, pos->length,
+		       (unsigned long long)map_to_sysmem(pos));
+		switch (pos->type) {
+		case 1:
+			smbios_print_type1((struct smbios_type1 *)pos);
+			break;
+		case 2:
+			smbios_print_type2((struct smbios_type2 *)pos);
+			break;
+		case 127:
+			smbios_print_type127((struct smbios_type127 *)pos);
+			break;
+		default:
+			smbios_print_generic(pos);
+			break;
+		}
+	}
+
+	return CMD_RET_SUCCESS;
+}
+
+U_BOOT_LONGHELP(smbios, "- display SMBIOS information");
+
+U_BOOT_CMD(smbios, 1, 0, do_smbios, "display SMBIOS information",
+	   smbios_help_text);
diff --git a/common/board_f.c b/common/board_f.c
index d4d7d01..442b834 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -403,17 +403,47 @@
 	return 0;
 }
 
-static int reserve_video(void)
+static int reserve_video_from_videoblob(void)
 {
 	if (IS_ENABLED(CONFIG_SPL_VIDEO_HANDOFF) && spl_phase() > PHASE_SPL) {
 		struct video_handoff *ho;
+		int ret = 0;
 
 		ho = bloblist_find(BLOBLISTT_U_BOOT_VIDEO, sizeof(*ho));
 		if (!ho)
-			return log_msg_ret("blf", -ENOENT);
-		video_reserve_from_bloblist(ho);
-		gd->relocaddr = ho->fb;
-	} else if (CONFIG_IS_ENABLED(VIDEO)) {
+			return log_msg_ret("Missing video bloblist", -ENOENT);
+
+		ret = video_reserve_from_bloblist(ho);
+		if (ret)
+			return log_msg_ret("Invalid Video handoff info", ret);
+
+		/* Sanity check fb from blob is before current relocaddr */
+		if (likely(gd->relocaddr > (unsigned long)ho->fb))
+			gd->relocaddr = ho->fb;
+	}
+
+	return 0;
+}
+
+/*
+ * Check if any bloblist received specifying reserved areas from previous stage and adjust
+ * gd->relocaddr accordingly, so that we start reserving after pre-reserved areas
+ * from previous stage.
+ *
+ * NOTE:
+ * IT is recommended that all bloblists from previous stage are reserved from ram_top
+ * as next stage will simply start reserving further regions after them.
+ */
+static int setup_relocaddr_from_bloblist(void)
+{
+	reserve_video_from_videoblob();
+
+	return 0;
+}
+
+static int reserve_video(void)
+{
+	if (CONFIG_IS_ENABLED(VIDEO)) {
 		ulong addr;
 		int ret;
 
@@ -923,6 +953,7 @@
 	reserve_pram,
 #endif
 	reserve_round_4k,
+	setup_relocaddr_from_bloblist,
 	arch_reserve_mmu,
 	reserve_video,
 	reserve_trace,
diff --git a/common/console.c b/common/console.c
index cad6589..aa3053b 100644
--- a/common/console.c
+++ b/common/console.c
@@ -1049,9 +1049,16 @@
 	return 0;
 }
 
+static char *get_stdio(const u8 std)
+{
+	return stdio_devices[std] ? stdio_devices[std]->name : "No devices available!";
+}
+
 static void stdio_print_current_devices(void)
 {
-	char *stdinname, *stdoutname, *stderrname;
+	char *stdinname = NULL;
+	char *stdoutname = NULL;
+	char *stderrname = NULL;
 
 	if (CONFIG_IS_ENABLED(CONSOLE_MUX) &&
 	    CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV)) {
@@ -1059,22 +1066,12 @@
 		stdinname  = env_get("stdin");
 		stdoutname = env_get("stdout");
 		stderrname = env_get("stderr");
-
-		stdinname = stdinname ? : "No input devices available!";
-		stdoutname = stdoutname ? : "No output devices available!";
-		stderrname = stderrname ? : "No error devices available!";
-	} else {
-		stdinname = stdio_devices[stdin] ?
-			stdio_devices[stdin]->name :
-			"No input devices available!";
-		stdoutname = stdio_devices[stdout] ?
-			stdio_devices[stdout]->name :
-			"No output devices available!";
-		stderrname = stdio_devices[stderr] ?
-			stdio_devices[stderr]->name :
-			"No error devices available!";
 	}
 
+	stdinname = stdinname ? : get_stdio(stdin);
+	stdoutname = stdoutname ? : get_stdio(stdout);
+	stderrname = stderrname ? : get_stdio(stderr);
+
 	/* Print information */
 	puts("In:    ");
 	printf("%s\n", stdinname);
diff --git a/common/spl/Kconfig b/common/spl/Kconfig
index e7b84fc..8805dd3 100644
--- a/common/spl/Kconfig
+++ b/common/spl/Kconfig
@@ -97,8 +97,7 @@
 	default 0x31000 if ARCH_MX6 && MX6_OCRAM_256KB
 	default 0x11000 if ARCH_MX7 || (ARCH_MX6 && !MX6_OCRAM_256KB)
 	default 0x10000 if ARCH_KEYSTONE
-	default 0x8000 if ARCH_SUNXI && !MACH_SUN50I_H616
-	default 0x0 if ARCH_MTMIPS
+	default 0x0 if ARCH_MTMIPS || ARCH_SUNXI
 	default TPL_MAX_SIZE if TPL_MAX_SIZE > SPL_MAX_SIZE
 	default SPL_MAX_SIZE
 	help
@@ -585,8 +584,7 @@
 config SPL_FIT_IMAGE_TINY
 	bool "Remove functionality from SPL FIT loading to reduce size"
 	depends on SPL_FIT
-	default y if MACH_SUN50I || MACH_SUN50I_H5 || SUN50I_GEN_H6
-	default y if ARCH_IMX8M || ARCH_IMX9
+	default y if ARCH_IMX8M || ARCH_IMX9 || ARCH_SUNXI
 	help
 	  Enable this to reduce the size of the FIT image loading code
 	  in SPL, if space for the SPL binary is very tight.
@@ -1115,7 +1113,7 @@
 
 config SPL_PAYLOAD_ARGS_ADDR
 	hex "Address in memory to load 'args' file for Falcon Mode to"
-	depends on SPL_OS_BOOT
+	depends on SPL_OS_BOOT || SPL_LOAD_FIT_OPENSBI_OS_BOOT
 	default 0x88000000 if ARCH_OMAP2PLUS
 	help
 	  Address in memory where the 'args' file, typically a device tree
diff --git a/common/spl/spl.c b/common/spl/spl.c
index 3ce5bfe..b65c439 100644
--- a/common/spl/spl.c
+++ b/common/spl/spl.c
@@ -42,6 +42,7 @@
 #include <fdt_support.h>
 #include <bootcount.h>
 #include <wdt.h>
+#include <video.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 DECLARE_BINMAN_MAGIC_SYM;
@@ -152,6 +153,24 @@
 #endif
 }
 
+int spl_reserve_video_from_ram_top(void)
+{
+	if (CONFIG_IS_ENABLED(VIDEO)) {
+		ulong addr;
+		int ret;
+
+		addr = gd->ram_top;
+		ret = video_reserve(&addr);
+		if (ret)
+			return ret;
+		debug("Reserving %luk for video at: %08lx\n",
+		      ((unsigned long)gd->relocaddr - addr) >> 10, addr);
+		gd->relocaddr = addr;
+	}
+
+	return 0;
+}
+
 ulong spl_get_image_pos(void)
 {
 	if (!CONFIG_IS_ENABLED(BINMAN_UBOOT_SYMBOLS))
diff --git a/common/spl/spl_opensbi.c b/common/spl/spl_opensbi.c
index 9801d38..8127ebc 100644
--- a/common/spl/spl_opensbi.c
+++ b/common/spl/spl_opensbi.c
@@ -16,6 +16,7 @@
 #include <opensbi.h>
 #include <linux/libfdt.h>
 #include <linux/printk.h>
+#include <mapmem.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -58,6 +59,20 @@
 	}
 
 	/*
+	 * Originally, u-boot-spl will place DTB directly after the kernel,
+	 * but the size of the kernel did not include the BSS section, which
+	 * means u-boot-spl will place the DTB in the kernel BSS section
+	 * causing the DTB to be cleared by kernel BSS initializtion.
+	 * Moving DTB in front of the kernel can avoid the error.
+	 */
+#if CONFIG_IS_ENABLED(LOAD_FIT_OPENSBI_OS_BOOT) && \
+    CONFIG_IS_ENABLED(PAYLOAD_ARGS_ADDR)
+	memcpy((void *)CONFIG_SPL_PAYLOAD_ARGS_ADDR, spl_image->fdt_addr,
+	       fdt_totalsize(spl_image->fdt_addr));
+	spl_image->fdt_addr = map_sysmem(CONFIG_SPL_PAYLOAD_ARGS_ADDR, 0);
+#endif
+
+	/*
 	 * Find next os image in /fit-images
 	 * The next os image default is u-boot proper, once enable
 	 * OpenSBI OS boot mode, the OS image should be linux.
diff --git a/common/splash_source.c b/common/splash_source.c
index 7223a1a..2ce0768 100644
--- a/common/splash_source.c
+++ b/common/splash_source.c
@@ -216,7 +216,7 @@
 	}
 }
 
-#ifdef CONFIG_CMD_UBIFS
+#if defined(CONFIG_CMD_UBIFS) && !defined(CONFIG_SPL_BUILD)
 static int splash_mount_ubifs(struct splash_location *location)
 {
 	int res;
diff --git a/common/usb_hub.c b/common/usb_hub.c
index 70279f3..3fb7e14 100644
--- a/common/usb_hub.c
+++ b/common/usb_hub.c
@@ -174,8 +174,10 @@
 
 	debug("enabling power on all ports\n");
 	for (i = 0; i < dev->maxchild; i++) {
+		usb_set_port_feature(dev, i + 1, USB_PORT_FEAT_RESET);
+		debug("Reset : port %d returns %lX\n", i + 1, dev->status);
 		usb_set_port_feature(dev, i + 1, USB_PORT_FEAT_POWER);
-		debug("port %d returns %lX\n", i + 1, dev->status);
+		debug("PowerOn : port %d returns %lX\n", i + 1, dev->status);
 	}
 
 #ifdef CONFIG_SANDBOX
diff --git a/configs/3c120_defconfig b/configs/3c120_defconfig
index 1094897..077506e 100644
--- a/configs/3c120_defconfig
+++ b/configs/3c120_defconfig
@@ -37,6 +37,7 @@
 CONFIG_ALTERA_PIO=y
 CONFIG_MISC=y
 CONFIG_ALTERA_SYSID=y
+CONFIG_MTD=y
 CONFIG_DM_MTD=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_SHOW_PROGRESS=0
diff --git a/configs/A20-OLinuXino-Lime2-eMMC_defconfig b/configs/A20-OLinuXino-Lime2-eMMC_defconfig
index 44770ff..22d80ca 100644
--- a/configs/A20-OLinuXino-Lime2-eMMC_defconfig
+++ b/configs/A20-OLinuXino-Lime2-eMMC_defconfig
@@ -21,6 +21,7 @@
 CONFIG_SYS_I2C_MVTWSI=y
 CONFIG_SYS_I2C_SLAVE=0x7f
 CONFIG_SYS_I2C_SPEED=400000
+CONFIG_MTD=y
 CONFIG_PHY_MICREL=y
 CONFIG_PHY_MICREL_KSZ90X1=y
 CONFIG_PHY_REALTEK=y
diff --git a/configs/M5208EVBE_defconfig b/configs/M5208EVBE_defconfig
index fd44fa1..ed14662 100644
--- a/configs/M5208EVBE_defconfig
+++ b/configs/M5208EVBE_defconfig
@@ -39,6 +39,7 @@
 CONFIG_SYS_RX_ETH_BUFFER=8
 CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_FSL=y
+CONFIG_MTD=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_SYS_FLASH_CFI_WIDTH_16BIT=y
diff --git a/configs/M5235EVB_Flash32_defconfig b/configs/M5235EVB_Flash32_defconfig
index 810cde4..45e0460 100644
--- a/configs/M5235EVB_Flash32_defconfig
+++ b/configs/M5235EVB_Flash32_defconfig
@@ -47,6 +47,7 @@
 CONFIG_SYS_RX_ETH_BUFFER=8
 CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_FSL=y
+CONFIG_MTD=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_SYS_FLASH_CFI_WIDTH_32BIT=y
diff --git a/configs/M5235EVB_defconfig b/configs/M5235EVB_defconfig
index 11fe3ba..719a435 100644
--- a/configs/M5235EVB_defconfig
+++ b/configs/M5235EVB_defconfig
@@ -46,6 +46,7 @@
 CONFIG_SYS_RX_ETH_BUFFER=8
 CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_FSL=y
+CONFIG_MTD=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_SYS_FLASH_CFI_WIDTH_16BIT=y
diff --git a/configs/M5249EVB_defconfig b/configs/M5249EVB_defconfig
index 30c3e42..eac85b9 100644
--- a/configs/M5249EVB_defconfig
+++ b/configs/M5249EVB_defconfig
@@ -23,6 +23,7 @@
 CONFIG_CMD_CACHE=y
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 # CONFIG_NET is not set
+CONFIG_MTD=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_SYS_FLASH_CFI_WIDTH_16BIT=y
diff --git a/configs/M5253DEMO_defconfig b/configs/M5253DEMO_defconfig
index de631ae..14a3d9d 100644
--- a/configs/M5253DEMO_defconfig
+++ b/configs/M5253DEMO_defconfig
@@ -39,6 +39,7 @@
 CONFIG_IDE_RESET=y
 CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_FSL=y
+CONFIG_MTD=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_SYS_MAX_FLASH_SECT=2048
 CONFIG_USE_SYS_MAX_FLASH_BANKS=y
diff --git a/configs/M5272C3_defconfig b/configs/M5272C3_defconfig
index a760734..ccb756e 100644
--- a/configs/M5272C3_defconfig
+++ b/configs/M5272C3_defconfig
@@ -61,6 +61,7 @@
 CONFIG_SYS_BR7_PRELIM_BOOL=y
 CONFIG_SYS_BR7_PRELIM=0x701
 CONFIG_SYS_OR7_PRELIM=0xFFC0007C
+CONFIG_MTD=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_SYS_FLASH_CFI_WIDTH_16BIT=y
diff --git a/configs/M5275EVB_defconfig b/configs/M5275EVB_defconfig
index 8d677f9..4400075 100644
--- a/configs/M5275EVB_defconfig
+++ b/configs/M5275EVB_defconfig
@@ -35,6 +35,7 @@
 CONFIG_SYS_RX_ETH_BUFFER=8
 CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_FSL=y
+CONFIG_MTD=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_FLASH_SHOW_PROGRESS=0
diff --git a/configs/M5282EVB_defconfig b/configs/M5282EVB_defconfig
index ec2b9db..2786c67 100644
--- a/configs/M5282EVB_defconfig
+++ b/configs/M5282EVB_defconfig
@@ -37,6 +37,7 @@
 CONFIG_USE_SERVERIP=y
 CONFIG_SERVERIP="192.162.1.1"
 CONFIG_SYS_RX_ETH_BUFFER=8
+CONFIG_MTD=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_SYS_FLASH_CFI_WIDTH_16BIT=y
diff --git a/configs/M53017EVB_defconfig b/configs/M53017EVB_defconfig
index ecaed55..f0a7b1c 100644
--- a/configs/M53017EVB_defconfig
+++ b/configs/M53017EVB_defconfig
@@ -40,6 +40,7 @@
 CONFIG_SYS_RX_ETH_BUFFER=8
 CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_FSL=y
+CONFIG_MTD=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_SYS_FLASH_CFI_WIDTH_16BIT=y
diff --git a/configs/MPC837XERDB_defconfig b/configs/MPC837XERDB_defconfig
index 04c0ec2..9eac43a 100644
--- a/configs/MPC837XERDB_defconfig
+++ b/configs/MPC837XERDB_defconfig
@@ -170,6 +170,7 @@
 CONFIG_SYS_I2C_SPEED=400000
 CONFIG_FSL_ESDHC=y
 CONFIG_FSL_ESDHC_PIN_MUX=y
+CONFIG_MTD=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_FLASH_SHOW_PROGRESS=0
diff --git a/configs/MPC8548CDS_36BIT_defconfig b/configs/MPC8548CDS_36BIT_defconfig
index 728aae5..8670712 100644
--- a/configs/MPC8548CDS_36BIT_defconfig
+++ b/configs/MPC8548CDS_36BIT_defconfig
@@ -80,6 +80,7 @@
 CONFIG_SYS_I2C_FSL=y
 CONFIG_SYS_I2C_EEPROM_ADDR=0x57
 # CONFIG_MMC is not set
+CONFIG_MTD=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_FLASH_SHOW_PROGRESS=0
diff --git a/configs/MPC8548CDS_defconfig b/configs/MPC8548CDS_defconfig
index a680a31..e10e61a 100644
--- a/configs/MPC8548CDS_defconfig
+++ b/configs/MPC8548CDS_defconfig
@@ -79,6 +79,7 @@
 CONFIG_SYS_I2C_FSL=y
 CONFIG_SYS_I2C_EEPROM_ADDR=0x57
 # CONFIG_MMC is not set
+CONFIG_MTD=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_FLASH_SHOW_PROGRESS=0
diff --git a/configs/MPC8548CDS_legacy_defconfig b/configs/MPC8548CDS_legacy_defconfig
index 09a452a..6fcc727 100644
--- a/configs/MPC8548CDS_legacy_defconfig
+++ b/configs/MPC8548CDS_legacy_defconfig
@@ -79,6 +79,7 @@
 CONFIG_SYS_I2C_FSL=y
 CONFIG_SYS_I2C_EEPROM_ADDR=0x57
 # CONFIG_MMC is not set
+CONFIG_MTD=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_FLASH_SHOW_PROGRESS=0
diff --git a/configs/ae350_rv32_falcon_defconfig b/configs/ae350_rv32_falcon_defconfig
index abf7dd4..f814710 100644
--- a/configs/ae350_rv32_falcon_defconfig
+++ b/configs/ae350_rv32_falcon_defconfig
@@ -14,6 +14,7 @@
 CONFIG_RISCV_SMODE=y
 # CONFIG_AVAILABLE_HARTS is not set
 CONFIG_SPL_LOAD_FIT_OPENSBI_OS_BOOT=y
+CONFIG_SPL_PAYLOAD_ARGS_ADDR=0x01700000
 CONFIG_SYS_MONITOR_BASE=0x88000000
 CONFIG_FIT=y
 CONFIG_SPL_LOAD_FIT_ADDRESS=0x10000000
diff --git a/configs/ae350_rv32_falcon_xip_defconfig b/configs/ae350_rv32_falcon_xip_defconfig
index 5166ab7..50e164c 100644
--- a/configs/ae350_rv32_falcon_xip_defconfig
+++ b/configs/ae350_rv32_falcon_xip_defconfig
@@ -15,6 +15,7 @@
 CONFIG_RISCV_SMODE=y
 CONFIG_SPL_XIP=y
 CONFIG_SPL_LOAD_FIT_OPENSBI_OS_BOOT=y
+CONFIG_SPL_PAYLOAD_ARGS_ADDR=0x01700000
 CONFIG_SYS_MONITOR_BASE=0x88000000
 CONFIG_FIT=y
 CONFIG_SPL_LOAD_FIT_ADDRESS=0x80010000
diff --git a/configs/ae350_rv64_falcon_defconfig b/configs/ae350_rv64_falcon_defconfig
index 1289238..b0b7ae5 100644
--- a/configs/ae350_rv64_falcon_defconfig
+++ b/configs/ae350_rv64_falcon_defconfig
@@ -14,6 +14,7 @@
 CONFIG_RISCV_SMODE=y
 # CONFIG_AVAILABLE_HARTS is not set
 CONFIG_SPL_LOAD_FIT_OPENSBI_OS_BOOT=y
+CONFIG_SPL_PAYLOAD_ARGS_ADDR=0x01700000
 CONFIG_SYS_MONITOR_BASE=0x88000000
 CONFIG_FIT=y
 CONFIG_SPL_LOAD_FIT_ADDRESS=0x10000000
diff --git a/configs/ae350_rv64_falcon_xip_defconfig b/configs/ae350_rv64_falcon_xip_defconfig
index 18e2daf..cac315d 100644
--- a/configs/ae350_rv64_falcon_xip_defconfig
+++ b/configs/ae350_rv64_falcon_xip_defconfig
@@ -15,6 +15,7 @@
 CONFIG_RISCV_SMODE=y
 CONFIG_SPL_XIP=y
 CONFIG_SPL_LOAD_FIT_OPENSBI_OS_BOOT=y
+CONFIG_SPL_PAYLOAD_ARGS_ADDR=0x01700000
 CONFIG_SYS_MONITOR_BASE=0x88000000
 CONFIG_FIT=y
 CONFIG_SPL_LOAD_FIT_ADDRESS=0x80010000
diff --git a/configs/am43xx_evm_defconfig b/configs/am43xx_evm_defconfig
index d5ce299..58e5f65 100644
--- a/configs/am43xx_evm_defconfig
+++ b/configs/am43xx_evm_defconfig
@@ -67,7 +67,6 @@
 CONFIG_MISC=y
 CONFIG_SYS_I2C_EEPROM_ADDR=0x50
 CONFIG_MMC_OMAP_HS=y
-CONFIG_MTD=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_NAND_OMAP_ECCSCHEME_BCH16_CODE_HW=y
 CONFIG_SYS_NAND_BLOCK_SIZE=0x40000
diff --git a/configs/am43xx_evm_rtconly_defconfig b/configs/am43xx_evm_rtconly_defconfig
index a0a9e8a..8f33fc2 100644
--- a/configs/am43xx_evm_rtconly_defconfig
+++ b/configs/am43xx_evm_rtconly_defconfig
@@ -57,7 +57,6 @@
 CONFIG_DFU_SF=y
 CONFIG_SYS_I2C_EEPROM_ADDR=0x50
 CONFIG_MMC_OMAP_HS=y
-CONFIG_MTD=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_NAND_OMAP_ECCSCHEME_BCH16_CODE_HW=y
 CONFIG_SYS_NAND_BLOCK_SIZE=0x40000
diff --git a/configs/am43xx_evm_usbhost_boot_defconfig b/configs/am43xx_evm_usbhost_boot_defconfig
index cd47806..d875560 100644
--- a/configs/am43xx_evm_usbhost_boot_defconfig
+++ b/configs/am43xx_evm_usbhost_boot_defconfig
@@ -70,7 +70,6 @@
 CONFIG_DFU_SF=y
 CONFIG_MISC=y
 CONFIG_MMC_OMAP_HS=y
-CONFIG_MTD=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_NAND_OMAP_ECCSCHEME_BCH16_CODE_HW=y
 CONFIG_SYS_NAND_BLOCK_SIZE=0x40000
diff --git a/configs/am43xx_hs_evm_defconfig b/configs/am43xx_hs_evm_defconfig
index d721664..fd1e0c8 100644
--- a/configs/am43xx_hs_evm_defconfig
+++ b/configs/am43xx_hs_evm_defconfig
@@ -63,7 +63,6 @@
 CONFIG_MISC=y
 CONFIG_SYS_I2C_EEPROM_ADDR=0x50
 CONFIG_MMC_OMAP_HS=y
-CONFIG_MTD=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_NAND_OMAP_ECCSCHEME_BCH16_CODE_HW=y
 CONFIG_SYS_NAND_BLOCK_SIZE=0x40000
diff --git a/configs/am62ax_evm_r5_defconfig b/configs/am62ax_evm_r5_defconfig
index 4070415..8dd8f08 100644
--- a/configs/am62ax_evm_r5_defconfig
+++ b/configs/am62ax_evm_r5_defconfig
@@ -89,6 +89,7 @@
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_ADMA=y
 CONFIG_MMC_SDHCI_AM654=y
+CONFIG_MTD=y
 CONFIG_PINCTRL=y
 # CONFIG_PINCTRL_GENERIC is not set
 CONFIG_SPL_PINCTRL=y
diff --git a/configs/am62x_evm_a53_defconfig b/configs/am62x_evm_a53_defconfig
index aa96c1b..457931f 100644
--- a/configs/am62x_evm_a53_defconfig
+++ b/configs/am62x_evm_a53_defconfig
@@ -75,6 +75,7 @@
 CONFIG_MMC_SDHCI_ADMA=y
 CONFIG_SPL_MMC_SDHCI_ADMA=y
 CONFIG_MMC_SDHCI_AM654=y
+CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH_SFDP_SUPPORT=y
 CONFIG_SPI_FLASH_SOFT_RESET=y
diff --git a/configs/am62x_evm_r5_defconfig b/configs/am62x_evm_r5_defconfig
index 9ec3d56..3e4d3a7 100644
--- a/configs/am62x_evm_r5_defconfig
+++ b/configs/am62x_evm_r5_defconfig
@@ -96,6 +96,7 @@
 CONFIG_MMC_SDHCI_ADMA=y
 CONFIG_SPL_MMC_SDHCI_ADMA=y
 CONFIG_MMC_SDHCI_AM654=y
+CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH_SFDP_SUPPORT=y
 CONFIG_SPI_FLASH_SOFT_RESET=y
diff --git a/configs/am64x_evm_a53_defconfig b/configs/am64x_evm_a53_defconfig
index 05e35a8..6711e69 100644
--- a/configs/am64x_evm_a53_defconfig
+++ b/configs/am64x_evm_a53_defconfig
@@ -107,6 +107,7 @@
 CONFIG_MMC_SDHCI_ADMA=y
 CONFIG_SPL_MMC_SDHCI_ADMA=y
 CONFIG_MMC_SDHCI_AM654=y
+CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH_SPANSION=y
 CONFIG_SPI_FLASH_STMICRO=y
diff --git a/configs/am64x_evm_r5_defconfig b/configs/am64x_evm_r5_defconfig
index 0f9757b..56df6a4 100644
--- a/configs/am64x_evm_r5_defconfig
+++ b/configs/am64x_evm_r5_defconfig
@@ -115,6 +115,7 @@
 CONFIG_MMC_SDHCI_ADMA=y
 CONFIG_SPL_MMC_SDHCI_ADMA=y
 CONFIG_MMC_SDHCI_AM654=y
+CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH_SPANSION=y
 CONFIG_SPI_FLASH_STMICRO=y
diff --git a/configs/am65x_evm_r5_defconfig b/configs/am65x_evm_r5_defconfig
index 476c931..194bd1f 100644
--- a/configs/am65x_evm_r5_defconfig
+++ b/configs/am65x_evm_r5_defconfig
@@ -105,6 +105,7 @@
 CONFIG_MMC_SDHCI=y
 CONFIG_SPL_MMC_SDHCI_ADMA=y
 CONFIG_MMC_SDHCI_AM654=y
+CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH_SFDP_SUPPORT=y
 CONFIG_SPI_FLASH_STMICRO=y
diff --git a/configs/amcore_defconfig b/configs/amcore_defconfig
index 8c5c099..f1f5201 100644
--- a/configs/amcore_defconfig
+++ b/configs/amcore_defconfig
@@ -34,6 +34,7 @@
 CONFIG_USE_HOSTNAME=y
 CONFIG_HOSTNAME="AMCORE"
 # CONFIG_NET is not set
+CONFIG_MTD=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_FLASH_SHOW_PROGRESS=0
diff --git a/configs/arbel_evb_defconfig b/configs/arbel_evb_defconfig
index ac4fa71..45fafe7 100644
--- a/configs/arbel_evb_defconfig
+++ b/configs/arbel_evb_defconfig
@@ -63,6 +63,7 @@
 CONFIG_SUPPORT_EMMC_RPMB=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_NPCM=y
+CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH_MACRONIX=y
 CONFIG_SPI_FLASH_WINBOND=y
diff --git a/configs/arndale_defconfig b/configs/arndale_defconfig
index d322dd3..b664ad5 100644
--- a/configs/arndale_defconfig
+++ b/configs/arndale_defconfig
@@ -46,7 +46,6 @@
 CONFIG_MMC_DW=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_S5P=y
-CONFIG_MTD=y
 CONFIG_SMC911X=y
 CONFIG_SOUND=y
 CONFIG_I2S=y
diff --git a/configs/astro_mcf5373l_defconfig b/configs/astro_mcf5373l_defconfig
index 2550bf5..d1942c2 100644
--- a/configs/astro_mcf5373l_defconfig
+++ b/configs/astro_mcf5373l_defconfig
@@ -35,6 +35,7 @@
 CONFIG_SYS_FPGA_PROG_FEEDBACK=y
 CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_FSL=y
+CONFIG_MTD=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_FLASH_SHOW_PROGRESS=0
diff --git a/configs/axm_defconfig b/configs/axm_defconfig
index 86add8f..1a892a9 100644
--- a/configs/axm_defconfig
+++ b/configs/axm_defconfig
@@ -81,7 +81,6 @@
 CONFIG_CLK_AT91=y
 CONFIG_AT91_GPIO=y
 # CONFIG_MMC is not set
-CONFIG_MTD=y
 # CONFIG_SYS_NAND_USE_FLASH_BBT is not set
 CONFIG_NAND_ATMEL=y
 CONFIG_SYS_NAND_BLOCK_SIZE=0x20000
diff --git a/configs/bitmain_antminer_s9_defconfig b/configs/bitmain_antminer_s9_defconfig
index 858b07a..fffa9cb 100644
--- a/configs/bitmain_antminer_s9_defconfig
+++ b/configs/bitmain_antminer_s9_defconfig
@@ -84,7 +84,6 @@
 CONFIG_FPGA_ZYNQPL=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_ZYNQ=y
-CONFIG_MTD=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_NAND_ZYNQ=y
 CONFIG_NAND_ZYNQ_USE_BOOTLOADER1_TIMINGS=y
diff --git a/configs/chromebit_mickey_defconfig b/configs/chromebit_mickey_defconfig
index 1ec1a26..c413647 100644
--- a/configs/chromebit_mickey_defconfig
+++ b/configs/chromebit_mickey_defconfig
@@ -80,7 +80,6 @@
 # CONFIG_SPL_DM_MMC is not set
 CONFIG_MMC_DW=y
 CONFIG_MMC_DW_ROCKCHIP=y
-CONFIG_MTD=y
 CONFIG_SF_DEFAULT_BUS=2
 CONFIG_SPI_FLASH_GIGADEVICE=y
 CONFIG_SPI_FLASH_WINBOND=y
diff --git a/configs/chromebook_jerry_defconfig b/configs/chromebook_jerry_defconfig
index a3d2722..4b80d6a 100644
--- a/configs/chromebook_jerry_defconfig
+++ b/configs/chromebook_jerry_defconfig
@@ -80,7 +80,6 @@
 # CONFIG_SPL_DM_MMC is not set
 CONFIG_MMC_DW=y
 CONFIG_MMC_DW_ROCKCHIP=y
-CONFIG_MTD=y
 CONFIG_SF_DEFAULT_BUS=2
 CONFIG_SPI_FLASH_GIGADEVICE=y
 CONFIG_SPI_FLASH_WINBOND=y
diff --git a/configs/chromebook_minnie_defconfig b/configs/chromebook_minnie_defconfig
index 332ebdd..126b8ce 100644
--- a/configs/chromebook_minnie_defconfig
+++ b/configs/chromebook_minnie_defconfig
@@ -81,7 +81,6 @@
 # CONFIG_SPL_DM_MMC is not set
 CONFIG_MMC_DW=y
 CONFIG_MMC_DW_ROCKCHIP=y
-CONFIG_MTD=y
 CONFIG_SF_DEFAULT_BUS=2
 CONFIG_SPI_FLASH_GIGADEVICE=y
 CONFIG_SPI_FLASH_WINBOND=y
diff --git a/configs/chromebook_speedy_defconfig b/configs/chromebook_speedy_defconfig
index 87876e2..2346c83 100644
--- a/configs/chromebook_speedy_defconfig
+++ b/configs/chromebook_speedy_defconfig
@@ -81,7 +81,6 @@
 # CONFIG_SPL_DM_MMC is not set
 CONFIG_MMC_DW=y
 CONFIG_MMC_DW_ROCKCHIP=y
-CONFIG_MTD=y
 CONFIG_SF_DEFAULT_BUS=2
 CONFIG_SPI_FLASH_GIGADEVICE=y
 CONFIG_SPI_FLASH_WINBOND=y
diff --git a/configs/clearfog_defconfig b/configs/clearfog_defconfig
index 05e7751..368c81c 100644
--- a/configs/clearfog_defconfig
+++ b/configs/clearfog_defconfig
@@ -62,7 +62,6 @@
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_SDMA=y
 CONFIG_MMC_SDHCI_MV=y
-CONFIG_MTD=y
 CONFIG_SF_DEFAULT_BUS=1
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_SPI_FLASH_MTD=y
diff --git a/configs/clearfog_sata_defconfig b/configs/clearfog_sata_defconfig
index 4f11ea1..c38d5cc 100644
--- a/configs/clearfog_sata_defconfig
+++ b/configs/clearfog_sata_defconfig
@@ -63,7 +63,6 @@
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_SDMA=y
 CONFIG_MMC_SDHCI_MV=y
-CONFIG_MTD=y
 CONFIG_SF_DEFAULT_BUS=1
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_SPI_FLASH_MTD=y
diff --git a/configs/clearfog_spi_defconfig b/configs/clearfog_spi_defconfig
index 418c4cb..ccdcf09 100644
--- a/configs/clearfog_spi_defconfig
+++ b/configs/clearfog_spi_defconfig
@@ -63,7 +63,6 @@
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_SDMA=y
 CONFIG_MMC_SDHCI_MV=y
-CONFIG_MTD=y
 CONFIG_SF_DEFAULT_BUS=1
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_SPI_FLASH_MTD=y
diff --git a/configs/cobra5272_defconfig b/configs/cobra5272_defconfig
index e4e13db..d7ce719 100644
--- a/configs/cobra5272_defconfig
+++ b/configs/cobra5272_defconfig
@@ -53,6 +53,7 @@
 CONFIG_SYS_BR7_PRELIM_BOOL=y
 CONFIG_SYS_BR7_PRELIM=0x701
 CONFIG_SYS_OR7_PRELIM=0xFF00007C
+CONFIG_MTD=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_SYS_MAX_FLASH_SECT=11
 CONFIG_USE_SYS_MAX_FLASH_BANKS=y
diff --git a/configs/colibri_t20_defconfig b/configs/colibri_t20_defconfig
index b919009..3c506ff 100644
--- a/configs/colibri_t20_defconfig
+++ b/configs/colibri_t20_defconfig
@@ -54,7 +54,6 @@
 CONFIG_TFTP_BLOCKSIZE=1536
 CONFIG_TFTP_TSIZE=y
 CONFIG_SYS_I2C_TEGRA=y
-CONFIG_MTD=y
 CONFIG_DM_MTD=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_TEGRA_NAND=y
diff --git a/configs/comtrend_ct5361_ram_defconfig b/configs/comtrend_ct5361_ram_defconfig
index 4a5d1b7..49b3535 100644
--- a/configs/comtrend_ct5361_ram_defconfig
+++ b/configs/comtrend_ct5361_ram_defconfig
@@ -50,6 +50,7 @@
 CONFIG_BCM6345_GPIO=y
 CONFIG_LED=y
 CONFIG_LED_GPIO=y
+CONFIG_MTD=y
 CONFIG_DM_MTD=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_SHOW_PROGRESS=0
diff --git a/configs/comtrend_wap5813n_ram_defconfig b/configs/comtrend_wap5813n_ram_defconfig
index 20f477b..60f8f3f 100644
--- a/configs/comtrend_wap5813n_ram_defconfig
+++ b/configs/comtrend_wap5813n_ram_defconfig
@@ -50,6 +50,7 @@
 CONFIG_BCM6345_GPIO=y
 CONFIG_LED=y
 CONFIG_LED_GPIO=y
+CONFIG_MTD=y
 CONFIG_DM_MTD=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_SHOW_PROGRESS=0
diff --git a/configs/corstone1000_defconfig b/configs/corstone1000_defconfig
index e45415b..a86ac12 100644
--- a/configs/corstone1000_defconfig
+++ b/configs/corstone1000_defconfig
@@ -44,6 +44,7 @@
 CONFIG_ARM_FFA_TRANSPORT=y
 CONFIG_MISC=y
 # CONFIG_MMC is not set
+CONFIG_MTD=y
 CONFIG_NVMXIP_QSPI=y
 CONFIG_PHYLIB=y
 CONFIG_PHY_SMSC=y
diff --git a/configs/crs305-1g-4s-bit_defconfig b/configs/crs305-1g-4s-bit_defconfig
index fff81dc..b3eaec8 100644
--- a/configs/crs305-1g-4s-bit_defconfig
+++ b/configs/crs305-1g-4s-bit_defconfig
@@ -40,7 +40,6 @@
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_BOOTCOUNT_ENV=y
 # CONFIG_MMC is not set
-CONFIG_MTD=y
 CONFIG_DM_MTD=y
 CONFIG_SPI_FLASH_BAR=y
 CONFIG_SPI_FLASH_MACRONIX=y
diff --git a/configs/crs305-1g-4s_defconfig b/configs/crs305-1g-4s_defconfig
index da77a78a..cc3dea6 100644
--- a/configs/crs305-1g-4s_defconfig
+++ b/configs/crs305-1g-4s_defconfig
@@ -41,7 +41,6 @@
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_BOOTCOUNT_ENV=y
 # CONFIG_MMC is not set
-CONFIG_MTD=y
 CONFIG_DM_MTD=y
 CONFIG_SPI_FLASH_BAR=y
 CONFIG_SPI_FLASH_WINBOND=y
diff --git a/configs/crs326-24g-2s-bit_defconfig b/configs/crs326-24g-2s-bit_defconfig
index 9756740..5dad70d 100644
--- a/configs/crs326-24g-2s-bit_defconfig
+++ b/configs/crs326-24g-2s-bit_defconfig
@@ -40,7 +40,6 @@
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_BOOTCOUNT_ENV=y
 # CONFIG_MMC is not set
-CONFIG_MTD=y
 CONFIG_DM_MTD=y
 CONFIG_SPI_FLASH_BAR=y
 CONFIG_SPI_FLASH_MACRONIX=y
diff --git a/configs/crs326-24g-2s_defconfig b/configs/crs326-24g-2s_defconfig
index d62fd2e..462588a 100644
--- a/configs/crs326-24g-2s_defconfig
+++ b/configs/crs326-24g-2s_defconfig
@@ -40,7 +40,6 @@
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_BOOTCOUNT_ENV=y
 # CONFIG_MMC is not set
-CONFIG_MTD=y
 CONFIG_DM_MTD=y
 CONFIG_SPI_FLASH_BAR=y
 CONFIG_SPI_FLASH_WINBOND=y
diff --git a/configs/crs328-4c-20s-4s-bit_defconfig b/configs/crs328-4c-20s-4s-bit_defconfig
index 0729bae..9e1474a 100644
--- a/configs/crs328-4c-20s-4s-bit_defconfig
+++ b/configs/crs328-4c-20s-4s-bit_defconfig
@@ -40,7 +40,6 @@
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_BOOTCOUNT_ENV=y
 # CONFIG_MMC is not set
-CONFIG_MTD=y
 CONFIG_DM_MTD=y
 CONFIG_SPI_FLASH_BAR=y
 CONFIG_SPI_FLASH_MACRONIX=y
diff --git a/configs/crs328-4c-20s-4s_defconfig b/configs/crs328-4c-20s-4s_defconfig
index f317b97..afa4c52 100644
--- a/configs/crs328-4c-20s-4s_defconfig
+++ b/configs/crs328-4c-20s-4s_defconfig
@@ -40,7 +40,6 @@
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_BOOTCOUNT_ENV=y
 # CONFIG_MMC is not set
-CONFIG_MTD=y
 CONFIG_DM_MTD=y
 CONFIG_SPI_FLASH_BAR=y
 CONFIG_SPI_FLASH_WINBOND=y
diff --git a/configs/d2net_v2_defconfig b/configs/d2net_v2_defconfig
index 5fcac2c..bb1bcb0 100644
--- a/configs/d2net_v2_defconfig
+++ b/configs/d2net_v2_defconfig
@@ -61,6 +61,7 @@
 CONFIG_SYS_I2C_SLAVE=0x0
 CONFIG_SYS_I2C_EEPROM_ADDR=0x50
 # CONFIG_MMC is not set
+CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH_MACRONIX=y
 CONFIG_MVGBE=y
diff --git a/configs/db-88f6820-amc_defconfig b/configs/db-88f6820-amc_defconfig
index 71af33c..8919f17 100644
--- a/configs/db-88f6820-amc_defconfig
+++ b/configs/db-88f6820-amc_defconfig
@@ -64,7 +64,6 @@
 CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_MVTWSI=y
 # CONFIG_MMC is not set
-CONFIG_MTD=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_SYS_NAND_USE_FLASH_BBT=y
 CONFIG_NAND_PXA3XX=y
diff --git a/configs/db-88f6820-amc_nand_defconfig b/configs/db-88f6820-amc_nand_defconfig
index f565972..76d8d34 100644
--- a/configs/db-88f6820-amc_nand_defconfig
+++ b/configs/db-88f6820-amc_nand_defconfig
@@ -67,7 +67,6 @@
 CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_MVTWSI=y
 # CONFIG_MMC is not set
-CONFIG_MTD=y
 CONFIG_SYS_NAND_USE_FLASH_BBT=y
 CONFIG_NAND_PXA3XX=y
 CONFIG_SYS_NAND_BLOCK_SIZE=0x40000
diff --git a/configs/db-mv784mp-gp_defconfig b/configs/db-mv784mp-gp_defconfig
index 6ebf412..ea72fb9 100644
--- a/configs/db-mv784mp-gp_defconfig
+++ b/configs/db-mv784mp-gp_defconfig
@@ -65,7 +65,6 @@
 CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_MVTWSI=y
 # CONFIG_MMC is not set
-CONFIG_MTD=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_SYS_NAND_USE_FLASH_BBT=y
 CONFIG_NAND_PXA3XX=y
diff --git a/configs/db-xc3-24g4xg_defconfig b/configs/db-xc3-24g4xg_defconfig
index c5f60e4..61ce6e7 100644
--- a/configs/db-xc3-24g4xg_defconfig
+++ b/configs/db-xc3-24g4xg_defconfig
@@ -46,7 +46,6 @@
 CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_MVTWSI=y
 # CONFIG_MMC is not set
-CONFIG_MTD=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_SYS_NAND_USE_FLASH_BBT=y
 CONFIG_NAND_PXA3XX=y
diff --git a/configs/display5_defconfig b/configs/display5_defconfig
index ab1eefe..7707b32 100644
--- a/configs/display5_defconfig
+++ b/configs/display5_defconfig
@@ -106,7 +106,6 @@
 CONFIG_SYS_I2C_EEPROM_ADDR=0x50
 CONFIG_SUPPORT_EMMC_BOOT=y
 CONFIG_FSL_USDHC=y
-CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SF_DEFAULT_BUS=1
 CONFIG_SPI_FLASH_SFDP_SUPPORT=y
diff --git a/configs/display5_factory_defconfig b/configs/display5_factory_defconfig
index f3e419d..58f4751 100644
--- a/configs/display5_factory_defconfig
+++ b/configs/display5_factory_defconfig
@@ -105,7 +105,6 @@
 CONFIG_SYS_I2C_EEPROM_ADDR=0x50
 CONFIG_SUPPORT_EMMC_BOOT=y
 CONFIG_FSL_USDHC=y
-CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SF_DEFAULT_BUS=1
 CONFIG_SPI_FLASH_SFDP_SUPPORT=y
diff --git a/configs/ds116_defconfig b/configs/ds116_defconfig
index 8fb14bb..02ddc0e 100644
--- a/configs/ds116_defconfig
+++ b/configs/ds116_defconfig
@@ -70,7 +70,6 @@
 CONFIG_SYS_64BIT_LBA=y
 CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_MVTWSI=y
-CONFIG_MTD=y
 CONFIG_SPI_FLASH_MACRONIX=y
 CONFIG_SPI_FLASH_STMICRO=y
 CONFIG_PHY_MARVELL=y
diff --git a/configs/ds414_defconfig b/configs/ds414_defconfig
index 3929ea9..07c7456 100644
--- a/configs/ds414_defconfig
+++ b/configs/ds414_defconfig
@@ -67,7 +67,6 @@
 CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_MVTWSI=y
 # CONFIG_MMC is not set
-CONFIG_MTD=y
 CONFIG_SPI_FLASH_STMICRO=y
 CONFIG_PHY_ADDR_ENABLE=y
 CONFIG_PHY_MARVELL=y
diff --git a/configs/eDPU_defconfig b/configs/eDPU_defconfig
index 545fd43..c1f8505 100644
--- a/configs/eDPU_defconfig
+++ b/configs/eDPU_defconfig
@@ -61,7 +61,6 @@
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_SDMA=y
 CONFIG_MMC_SDHCI_XENON=y
-CONFIG_MTD=y
 CONFIG_DM_MTD=y
 CONFIG_SPI_FLASH_SFDP_SUPPORT=y
 CONFIG_SPI_FLASH_MACRONIX=y
diff --git a/configs/eb_cpu5282_defconfig b/configs/eb_cpu5282_defconfig
index 7578e0e..271dbdf 100644
--- a/configs/eb_cpu5282_defconfig
+++ b/configs/eb_cpu5282_defconfig
@@ -41,6 +41,7 @@
 CONFIG_LED_STATUS_BOOT_ENABLE=y
 CONFIG_LED_STATUS_BOOT=0
 CONFIG_LED_STATUS_CMD=y
+CONFIG_MTD=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_SYS_FLASH_CFI_WIDTH_16BIT=y
diff --git a/configs/eb_cpu5282_internal_defconfig b/configs/eb_cpu5282_internal_defconfig
index 6595f9c..89a7925 100644
--- a/configs/eb_cpu5282_internal_defconfig
+++ b/configs/eb_cpu5282_internal_defconfig
@@ -39,6 +39,7 @@
 CONFIG_LED_STATUS_BOOT_ENABLE=y
 CONFIG_LED_STATUS_BOOT=0
 CONFIG_LED_STATUS_CMD=y
+CONFIG_MTD=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_SYS_FLASH_CFI_WIDTH_16BIT=y
diff --git a/configs/evb-ast2500_defconfig b/configs/evb-ast2500_defconfig
index ab60d69..6685f37 100644
--- a/configs/evb-ast2500_defconfig
+++ b/configs/evb-ast2500_defconfig
@@ -42,6 +42,7 @@
 CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_ASPEED=y
 # CONFIG_MMC is not set
+CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH_SFDP_SUPPORT=y
 CONFIG_SPI_FLASH_GIGADEVICE=y
diff --git a/configs/evb-ast2600_defconfig b/configs/evb-ast2600_defconfig
index 23f15b7..314d5d3 100644
--- a/configs/evb-ast2600_defconfig
+++ b/configs/evb-ast2600_defconfig
@@ -91,6 +91,7 @@
 CONFIG_I2C_EEPROM=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_ASPEED=y
+CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH_SFDP_SUPPORT=y
 CONFIG_SPI_FLASH_GIGADEVICE=y
diff --git a/configs/evb-rk3036_defconfig b/configs/evb-rk3036_defconfig
index 21c657a..a5a4e36 100644
--- a/configs/evb-rk3036_defconfig
+++ b/configs/evb-rk3036_defconfig
@@ -48,7 +48,6 @@
 CONFIG_LED=y
 CONFIG_MMC_DW=y
 CONFIG_MMC_DW_ROCKCHIP=y
-CONFIG_MTD=y
 CONFIG_SPI_FLASH_GIGADEVICE=y
 CONFIG_PINCTRL=y
 # CONFIG_SPL_DM_SERIAL is not set
diff --git a/configs/evb-rk3128_defconfig b/configs/evb-rk3128_defconfig
index f159695..ffff062 100644
--- a/configs/evb-rk3128_defconfig
+++ b/configs/evb-rk3128_defconfig
@@ -39,7 +39,6 @@
 CONFIG_SYS_I2C_ROCKCHIP=y
 CONFIG_MMC_DW=y
 CONFIG_MMC_DW_ROCKCHIP=y
-CONFIG_MTD=y
 CONFIG_PHY=y
 CONFIG_PINCTRL=y
 CONFIG_REGULATOR_PWM=y
diff --git a/configs/evb-rk3229_defconfig b/configs/evb-rk3229_defconfig
index 9848970..d632fd7 100644
--- a/configs/evb-rk3229_defconfig
+++ b/configs/evb-rk3229_defconfig
@@ -57,7 +57,6 @@
 CONFIG_SYS_I2C_ROCKCHIP=y
 CONFIG_MMC_DW=y
 CONFIG_MMC_DW_ROCKCHIP=y
-CONFIG_MTD=y
 CONFIG_ETH_DESIGNWARE=y
 CONFIG_GMAC_ROCKCHIP=y
 CONFIG_PHY=y
diff --git a/configs/evb-rk3288_defconfig b/configs/evb-rk3288_defconfig
index fb74741..31dad12 100644
--- a/configs/evb-rk3288_defconfig
+++ b/configs/evb-rk3288_defconfig
@@ -69,7 +69,6 @@
 CONFIG_LED_GPIO=y
 CONFIG_MMC_DW=y
 CONFIG_MMC_DW_ROCKCHIP=y
-CONFIG_MTD=y
 CONFIG_ETH_DESIGNWARE=y
 CONFIG_GMAC_ROCKCHIP=y
 CONFIG_PINCTRL=y
diff --git a/configs/evb-rv1108_defconfig b/configs/evb-rv1108_defconfig
index 2b456c2..1c62149 100644
--- a/configs/evb-rv1108_defconfig
+++ b/configs/evb-rv1108_defconfig
@@ -31,7 +31,6 @@
 CONFIG_FASTBOOT_FLASH_MMC_DEV=1
 CONFIG_ROCKCHIP_GPIO=y
 CONFIG_SYS_I2C_ROCKCHIP=y
-CONFIG_MTD=y
 CONFIG_SPI_FLASH_GIGADEVICE=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_SPI_FLASH_MTD=y
diff --git a/configs/firefly-rk3288_defconfig b/configs/firefly-rk3288_defconfig
index aede3e1..4860298 100644
--- a/configs/firefly-rk3288_defconfig
+++ b/configs/firefly-rk3288_defconfig
@@ -65,7 +65,6 @@
 CONFIG_LED_GPIO=y
 CONFIG_MMC_DW=y
 CONFIG_MMC_DW_ROCKCHIP=y
-CONFIG_MTD=y
 CONFIG_ETH_DESIGNWARE=y
 CONFIG_GMAC_ROCKCHIP=y
 CONFIG_PINCTRL=y
diff --git a/configs/gardena-smart-gateway-mt7688_defconfig b/configs/gardena-smart-gateway-mt7688_defconfig
index 0b60cae..3b2d27b 100644
--- a/configs/gardena-smart-gateway-mt7688_defconfig
+++ b/configs/gardena-smart-gateway-mt7688_defconfig
@@ -83,7 +83,6 @@
 CONFIG_LED=y
 CONFIG_LED_BLINK=y
 CONFIG_LED_GPIO=y
-CONFIG_MTD=y
 CONFIG_DM_MTD=y
 CONFIG_MTD_SPI_NAND=y
 CONFIG_SPI_FLASH_GIGADEVICE=y
diff --git a/configs/gazerbeam_defconfig b/configs/gazerbeam_defconfig
index e02138b..9765c43 100644
--- a/configs/gazerbeam_defconfig
+++ b/configs/gazerbeam_defconfig
@@ -168,6 +168,7 @@
 CONFIG_GDSYS_SOC=y
 CONFIG_IHS_FPGA=y
 CONFIG_FSL_ESDHC=y
+CONFIG_MTD=y
 CONFIG_DM_MTD=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_SHOW_PROGRESS=0
diff --git a/configs/ge_b1x5v2_defconfig b/configs/ge_b1x5v2_defconfig
index 5644e7a..20384bc 100644
--- a/configs/ge_b1x5v2_defconfig
+++ b/configs/ge_b1x5v2_defconfig
@@ -87,6 +87,7 @@
 CONFIG_LED=y
 CONFIG_LED_GPIO=y
 CONFIG_FSL_USDHC=y
+CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH_SST=y
 CONFIG_SPI_FLASH_WINBOND=y
diff --git a/configs/gurnard_defconfig b/configs/gurnard_defconfig
index 5cf5eaa..a649bda 100644
--- a/configs/gurnard_defconfig
+++ b/configs/gurnard_defconfig
@@ -47,7 +47,6 @@
 CONFIG_TFTP_TSIZE=y
 CONFIG_AT91_GPIO=y
 CONFIG_GENERIC_ATMEL_MCI=y
-CONFIG_MTD=y
 CONFIG_MTD_RAW_NAND=y
 # CONFIG_SYS_NAND_USE_FLASH_BBT is not set
 CONFIG_NAND_ATMEL=y
diff --git a/configs/gxp_defconfig b/configs/gxp_defconfig
index 1b40aac..00a9211 100644
--- a/configs/gxp_defconfig
+++ b/configs/gxp_defconfig
@@ -41,6 +41,7 @@
 CONFIG_NETCONSOLE=y
 CONFIG_MISC=y
 # CONFIG_MMC is not set
+CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH_MACRONIX=y
 CONFIG_SPI_FLASH_SPANSION=y
diff --git a/configs/harmony_defconfig b/configs/harmony_defconfig
index 0689c7e..70bd454 100644
--- a/configs/harmony_defconfig
+++ b/configs/harmony_defconfig
@@ -44,7 +44,6 @@
 CONFIG_ENV_OVERWRITE=y
 CONFIG_ENV_IS_IN_NAND=y
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
-CONFIG_MTD=y
 CONFIG_DM_MTD=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_TEGRA_NAND=y
diff --git a/configs/helios4_defconfig b/configs/helios4_defconfig
index 1d8d374..0419400 100644
--- a/configs/helios4_defconfig
+++ b/configs/helios4_defconfig
@@ -63,7 +63,6 @@
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_SDMA=y
 CONFIG_MMC_SDHCI_MV=y
-CONFIG_MTD=y
 CONFIG_SF_DEFAULT_BUS=1
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_SPI_FLASH_MTD=y
diff --git a/configs/hihope_rzg2_defconfig b/configs/hihope_rzg2_defconfig
index ad61151..cad490e 100644
--- a/configs/hihope_rzg2_defconfig
+++ b/configs/hihope_rzg2_defconfig
@@ -64,6 +64,7 @@
 CONFIG_MMC_UHS_SUPPORT=y
 CONFIG_MMC_HS400_SUPPORT=y
 CONFIG_RENESAS_SDHI=y
+CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_BITBANGMII=y
diff --git a/configs/huawei_hg556a_ram_defconfig b/configs/huawei_hg556a_ram_defconfig
index 77dd33d..17d1c10 100644
--- a/configs/huawei_hg556a_ram_defconfig
+++ b/configs/huawei_hg556a_ram_defconfig
@@ -50,6 +50,7 @@
 CONFIG_BCM6345_GPIO=y
 CONFIG_LED=y
 CONFIG_LED_GPIO=y
+CONFIG_MTD=y
 CONFIG_DM_MTD=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_SHOW_PROGRESS=0
diff --git a/configs/imx8mm-cl-iot-gate-optee_defconfig b/configs/imx8mm-cl-iot-gate-optee_defconfig
index 8adc180..4568c9c 100644
--- a/configs/imx8mm-cl-iot-gate-optee_defconfig
+++ b/configs/imx8mm-cl-iot-gate-optee_defconfig
@@ -101,6 +101,7 @@
 CONFIG_SUPPORT_EMMC_RPMB=y
 CONFIG_SUPPORT_EMMC_BOOT=y
 CONFIG_FSL_USDHC=y
+CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_PHYLIB=y
 CONFIG_PHY_ATHEROS=y
diff --git a/configs/imx8mm-cl-iot-gate_defconfig b/configs/imx8mm-cl-iot-gate_defconfig
index 63d61de..54ad656 100644
--- a/configs/imx8mm-cl-iot-gate_defconfig
+++ b/configs/imx8mm-cl-iot-gate_defconfig
@@ -104,6 +104,7 @@
 CONFIG_SUPPORT_EMMC_RPMB=y
 CONFIG_SUPPORT_EMMC_BOOT=y
 CONFIG_FSL_USDHC=y
+CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_PHYLIB=y
 CONFIG_PHY_ATHEROS=y
diff --git a/configs/imx8mm_evk_fspi_defconfig b/configs/imx8mm_evk_fspi_defconfig
index 6feeae9..b689c7a 100644
--- a/configs/imx8mm_evk_fspi_defconfig
+++ b/configs/imx8mm_evk_fspi_defconfig
@@ -80,6 +80,7 @@
 CONFIG_MMC_HS400_ES_SUPPORT=y
 CONFIG_MMC_HS400_SUPPORT=y
 CONFIG_FSL_USDHC=y
+CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH_BAR=y
 CONFIG_SPI_FLASH_STMICRO=y
diff --git a/configs/imx8mn_beacon_2g_defconfig b/configs/imx8mn_beacon_2g_defconfig
index 8042c21..0c63192 100644
--- a/configs/imx8mn_beacon_2g_defconfig
+++ b/configs/imx8mn_beacon_2g_defconfig
@@ -109,6 +109,7 @@
 CONFIG_MMC_HS400_ES_SUPPORT=y
 CONFIG_MMC_HS400_SUPPORT=y
 CONFIG_FSL_USDHC=y
+CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH_BAR=y
 CONFIG_SPI_FLASH_STMICRO=y
diff --git a/configs/imx8mp_data_modul_edm_sbc_defconfig b/configs/imx8mp_data_modul_edm_sbc_defconfig
index ba4730a..fb4fb67 100644
--- a/configs/imx8mp_data_modul_edm_sbc_defconfig
+++ b/configs/imx8mp_data_modul_edm_sbc_defconfig
@@ -59,6 +59,7 @@
 CONFIG_SPL_HAS_BSS_LINKER_SECTION=y
 CONFIG_SPL_BSS_START_ADDR=0x96fc00
 CONFIG_SPL_BSS_MAX_SIZE=0x400
+CONFIG_SPL_BOARD_INIT=y
 CONFIG_SPL_BOOTROM_SUPPORT=y
 # CONFIG_SPL_RAW_IMAGE_SUPPORT is not set
 # CONFIG_SPL_SHARES_INIT_SP_ADDR is not set
diff --git a/configs/imx8mp_dhcom_pdk2_defconfig b/configs/imx8mp_dhcom_pdk2_defconfig
index 73e8421..af5ed56 100644
--- a/configs/imx8mp_dhcom_pdk2_defconfig
+++ b/configs/imx8mp_dhcom_pdk2_defconfig
@@ -57,6 +57,7 @@
 CONFIG_SPL_HAS_BSS_LINKER_SECTION=y
 CONFIG_SPL_BSS_START_ADDR=0x96fc00
 CONFIG_SPL_BSS_MAX_SIZE=0x400
+CONFIG_SPL_BOARD_INIT=y
 CONFIG_SPL_BOOTROM_SUPPORT=y
 # CONFIG_SPL_RAW_IMAGE_SUPPORT is not set
 # CONFIG_SPL_SHARES_INIT_SP_ADDR is not set
@@ -119,6 +120,7 @@
 CONFIG_CMD_CACHE=y
 CONFIG_CMD_TIME=y
 CONFIG_CMD_GETTIME=y
+CONFIG_CMD_KASLRSEED=y
 CONFIG_CMD_SYSBOOT=y
 CONFIG_CMD_UUID=y
 CONFIG_CMD_PMIC=y
@@ -227,6 +229,7 @@
 CONFIG_SPL_DM_REGULATOR_PCA9450=y
 CONFIG_DM_REGULATOR_FIXED=y
 CONFIG_DM_REGULATOR_GPIO=y
+CONFIG_DM_RNG=y
 CONFIG_DM_RTC=y
 CONFIG_RTC_M41T62=y
 CONFIG_CONS_INDEX=2
diff --git a/configs/imx8mp_dhcom_pdk3_defconfig b/configs/imx8mp_dhcom_pdk3_defconfig
index a3966fb..3a03469 100644
--- a/configs/imx8mp_dhcom_pdk3_defconfig
+++ b/configs/imx8mp_dhcom_pdk3_defconfig
@@ -58,6 +58,7 @@
 CONFIG_SPL_HAS_BSS_LINKER_SECTION=y
 CONFIG_SPL_BSS_START_ADDR=0x96fc00
 CONFIG_SPL_BSS_MAX_SIZE=0x400
+CONFIG_SPL_BOARD_INIT=y
 CONFIG_SPL_BOOTROM_SUPPORT=y
 # CONFIG_SPL_RAW_IMAGE_SUPPORT is not set
 # CONFIG_SPL_SHARES_INIT_SP_ADDR is not set
@@ -121,6 +122,7 @@
 CONFIG_CMD_CACHE=y
 CONFIG_CMD_TIME=y
 CONFIG_CMD_GETTIME=y
+CONFIG_CMD_KASLRSEED=y
 CONFIG_CMD_SYSBOOT=y
 CONFIG_CMD_UUID=y
 CONFIG_CMD_PMIC=y
@@ -232,6 +234,7 @@
 CONFIG_SPL_DM_REGULATOR_PCA9450=y
 CONFIG_DM_REGULATOR_FIXED=y
 CONFIG_DM_REGULATOR_GPIO=y
+CONFIG_DM_RNG=y
 CONFIG_DM_RTC=y
 CONFIG_RTC_M41T62=y
 CONFIG_CONS_INDEX=2
diff --git a/configs/imx8mp_rsb3720a1_4G_defconfig b/configs/imx8mp_rsb3720a1_4G_defconfig
index c53e8fd..019bbcc 100644
--- a/configs/imx8mp_rsb3720a1_4G_defconfig
+++ b/configs/imx8mp_rsb3720a1_4G_defconfig
@@ -123,6 +123,7 @@
 CONFIG_MMC_HS400_ES_SUPPORT=y
 CONFIG_MMC_HS400_SUPPORT=y
 CONFIG_FSL_USDHC=y
+CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH_BAR=y
 CONFIG_SPI_FLASH_STMICRO=y
diff --git a/configs/imx8mp_rsb3720a1_6G_defconfig b/configs/imx8mp_rsb3720a1_6G_defconfig
index 652c5db..efd69f2 100644
--- a/configs/imx8mp_rsb3720a1_6G_defconfig
+++ b/configs/imx8mp_rsb3720a1_6G_defconfig
@@ -123,6 +123,7 @@
 CONFIG_MMC_HS400_ES_SUPPORT=y
 CONFIG_MMC_HS400_SUPPORT=y
 CONFIG_FSL_USDHC=y
+CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH_BAR=y
 CONFIG_SPI_FLASH_STMICRO=y
diff --git a/configs/imx8ulp_evk_defconfig b/configs/imx8ulp_evk_defconfig
index 17ffa4a..836a797 100644
--- a/configs/imx8ulp_evk_defconfig
+++ b/configs/imx8ulp_evk_defconfig
@@ -71,6 +71,7 @@
 CONFIG_SUPPORT_EMMC_BOOT=y
 CONFIG_MMC_IO_VOLTAGE=y
 CONFIG_FSL_USDHC=y
+CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH_MACRONIX=y
 CONFIG_PHYLIB=y
diff --git a/configs/inetspace_v2_defconfig b/configs/inetspace_v2_defconfig
index 09b2f7b..2e8e3f3 100644
--- a/configs/inetspace_v2_defconfig
+++ b/configs/inetspace_v2_defconfig
@@ -61,6 +61,7 @@
 CONFIG_SYS_I2C_SLAVE=0x0
 CONFIG_SYS_I2C_EEPROM_ADDR=0x50
 # CONFIG_MMC is not set
+CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH_MACRONIX=y
 CONFIG_MVGBE=y
diff --git a/configs/integratorap_cm720t_defconfig b/configs/integratorap_cm720t_defconfig
index 779385b..bd0a7bf 100644
--- a/configs/integratorap_cm720t_defconfig
+++ b/configs/integratorap_cm720t_defconfig
@@ -28,6 +28,7 @@
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_SYS_RX_ETH_BUFFER=8
 # CONFIG_MMC is not set
+CONFIG_MTD=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_FLASH_SHOW_PROGRESS=0
diff --git a/configs/integratorap_cm920t_defconfig b/configs/integratorap_cm920t_defconfig
index 358a860..aae5512 100644
--- a/configs/integratorap_cm920t_defconfig
+++ b/configs/integratorap_cm920t_defconfig
@@ -28,6 +28,7 @@
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_SYS_RX_ETH_BUFFER=8
 # CONFIG_MMC is not set
+CONFIG_MTD=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_FLASH_SHOW_PROGRESS=0
diff --git a/configs/integratorap_cm926ejs_defconfig b/configs/integratorap_cm926ejs_defconfig
index 9e5bf8e..7aaec71 100644
--- a/configs/integratorap_cm926ejs_defconfig
+++ b/configs/integratorap_cm926ejs_defconfig
@@ -28,6 +28,7 @@
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_SYS_RX_ETH_BUFFER=8
 # CONFIG_MMC is not set
+CONFIG_MTD=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_FLASH_SHOW_PROGRESS=0
diff --git a/configs/integratorap_cm946es_defconfig b/configs/integratorap_cm946es_defconfig
index 2260e55..05fa604 100644
--- a/configs/integratorap_cm946es_defconfig
+++ b/configs/integratorap_cm946es_defconfig
@@ -28,6 +28,7 @@
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_SYS_RX_ETH_BUFFER=8
 # CONFIG_MMC is not set
+CONFIG_MTD=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_FLASH_SHOW_PROGRESS=0
diff --git a/configs/integratorcp_cm1136_defconfig b/configs/integratorcp_cm1136_defconfig
index ed4573f..f3e640b 100644
--- a/configs/integratorcp_cm1136_defconfig
+++ b/configs/integratorcp_cm1136_defconfig
@@ -36,6 +36,7 @@
 CONFIG_USE_SERVERIP=y
 CONFIG_SERVERIP="192.168.1.100"
 # CONFIG_MMC is not set
+CONFIG_MTD=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_FLASH_SHOW_PROGRESS=0
diff --git a/configs/integratorcp_cm920t_defconfig b/configs/integratorcp_cm920t_defconfig
index 2289ad9..1a03b57 100644
--- a/configs/integratorcp_cm920t_defconfig
+++ b/configs/integratorcp_cm920t_defconfig
@@ -36,6 +36,7 @@
 CONFIG_USE_SERVERIP=y
 CONFIG_SERVERIP="192.168.1.100"
 # CONFIG_MMC is not set
+CONFIG_MTD=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_FLASH_SHOW_PROGRESS=0
diff --git a/configs/integratorcp_cm926ejs_defconfig b/configs/integratorcp_cm926ejs_defconfig
index 9d99866..1eb1c1a 100644
--- a/configs/integratorcp_cm926ejs_defconfig
+++ b/configs/integratorcp_cm926ejs_defconfig
@@ -36,6 +36,7 @@
 CONFIG_USE_SERVERIP=y
 CONFIG_SERVERIP="192.168.1.100"
 # CONFIG_MMC is not set
+CONFIG_MTD=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_FLASH_SHOW_PROGRESS=0
diff --git a/configs/integratorcp_cm946es_defconfig b/configs/integratorcp_cm946es_defconfig
index 6a1629d..ee1191a 100644
--- a/configs/integratorcp_cm946es_defconfig
+++ b/configs/integratorcp_cm946es_defconfig
@@ -36,6 +36,7 @@
 CONFIG_USE_SERVERIP=y
 CONFIG_SERVERIP="192.168.1.100"
 # CONFIG_MMC is not set
+CONFIG_MTD=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_FLASH_SHOW_PROGRESS=0
diff --git a/configs/iot2050_defconfig b/configs/iot2050_defconfig
index c69e1d8..576105a 100644
--- a/configs/iot2050_defconfig
+++ b/configs/iot2050_defconfig
@@ -111,6 +111,7 @@
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_ADMA=y
 CONFIG_MMC_SDHCI_AM654=y
+CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH_SFDP_SUPPORT=y
 CONFIG_SPI_FLASH_STMICRO=y
diff --git a/configs/j721e_beagleboneai64_a72_defconfig b/configs/j721e_beagleboneai64_a72_defconfig
index f66206f..4b019fa 100644
--- a/configs/j721e_beagleboneai64_a72_defconfig
+++ b/configs/j721e_beagleboneai64_a72_defconfig
@@ -120,7 +120,6 @@
 CONFIG_MMC_SDHCI_ADMA=y
 CONFIG_SPL_MMC_SDHCI_ADMA=y
 CONFIG_MMC_SDHCI_AM654=y
-CONFIG_MTD_UBI=y
 CONFIG_MULTIPLEXER=y
 CONFIG_MUX_MMIO=y
 CONFIG_PHY_TI_DP83867=y
diff --git a/configs/jethub_j100_defconfig b/configs/jethub_j100_defconfig
index f52df1d..8632454 100644
--- a/configs/jethub_j100_defconfig
+++ b/configs/jethub_j100_defconfig
@@ -47,7 +47,6 @@
 CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_MESON=y
 CONFIG_MMC_MESON_GX=y
-CONFIG_MTD_UBI=y
 CONFIG_PHY_REALTEK=y
 CONFIG_ETH_DESIGNWARE_MESON8B=y
 CONFIG_MESON_GXL_USB_PHY=y
diff --git a/configs/jethub_j80_defconfig b/configs/jethub_j80_defconfig
index d32d74b..ca0808f 100644
--- a/configs/jethub_j80_defconfig
+++ b/configs/jethub_j80_defconfig
@@ -48,7 +48,6 @@
 CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_MESON=y
 CONFIG_MMC_MESON_GX=y
-CONFIG_MTD_UBI=y
 CONFIG_PHY_MESON_GXL=y
 CONFIG_DM_MDIO=y
 CONFIG_DM_MDIO_MUX=y
diff --git a/configs/kylin-rk3036_defconfig b/configs/kylin-rk3036_defconfig
index 8d3f1a7..cb313a1 100644
--- a/configs/kylin-rk3036_defconfig
+++ b/configs/kylin-rk3036_defconfig
@@ -52,7 +52,6 @@
 CONFIG_LED=y
 CONFIG_MMC_DW=y
 CONFIG_MMC_DW_ROCKCHIP=y
-CONFIG_MTD=y
 CONFIG_SPI_FLASH_GIGADEVICE=y
 CONFIG_PINCTRL=y
 CONFIG_DM_REGULATOR_FIXED=y
diff --git a/configs/lctech_pi_f1c200s_defconfig b/configs/lctech_pi_f1c200s_defconfig
index 310719c..e1e8d3a 100644
--- a/configs/lctech_pi_f1c200s_defconfig
+++ b/configs/lctech_pi_f1c200s_defconfig
@@ -7,5 +7,6 @@
 CONFIG_DRAM_ZQ=0
 CONFIG_SUNXI_MINIMUM_DRAM_MB=64
 # CONFIG_VIDEO_SUNXI is not set
+CONFIG_MTD=y
 CONFIG_CONS_INDEX=2
 CONFIG_SPI=y
diff --git a/configs/librem5_defconfig b/configs/librem5_defconfig
index 70b4d7c..91ead3f 100644
--- a/configs/librem5_defconfig
+++ b/configs/librem5_defconfig
@@ -115,6 +115,7 @@
 CONFIG_MMC_HS400_ES_SUPPORT=y
 CONFIG_MMC_HS400_SUPPORT=y
 CONFIG_FSL_USDHC=y
+CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH_STMICRO=y
 CONFIG_SPI_FLASH_WINBOND=y
diff --git a/configs/libretech_all_h3_it_h5_defconfig b/configs/libretech_all_h3_it_h5_defconfig
index cb7ffb4..f751c4f 100644
--- a/configs/libretech_all_h3_it_h5_defconfig
+++ b/configs/libretech_all_h3_it_h5_defconfig
@@ -7,6 +7,7 @@
 CONFIG_MMC_SUNXI_SLOT_EXTRA=2
 CONFIG_SPL_SPI_SUNXI=y
 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+CONFIG_MTD=y
 CONFIG_SPI_FLASH_XMC=y
 CONFIG_SPI=y
 CONFIG_USB_EHCI_HCD=y
diff --git a/configs/libretech_all_h5_cc_h5_defconfig b/configs/libretech_all_h5_cc_h5_defconfig
index c3aa4b1..c1761b4 100644
--- a/configs/libretech_all_h5_cc_h5_defconfig
+++ b/configs/libretech_all_h5_cc_h5_defconfig
@@ -7,6 +7,7 @@
 CONFIG_MMC_SUNXI_SLOT_EXTRA=2
 CONFIG_SPL_SPI_SUNXI=y
 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+CONFIG_MTD=y
 CONFIG_SPI_FLASH_XMC=y
 CONFIG_SUN8I_EMAC=y
 CONFIG_SPI=y
diff --git a/configs/licheepi_nano_defconfig b/configs/licheepi_nano_defconfig
index b25c9ba..d59affb 100644
--- a/configs/licheepi_nano_defconfig
+++ b/configs/licheepi_nano_defconfig
@@ -7,6 +7,7 @@
 CONFIG_DRAM_ZQ=0
 # CONFIG_VIDEO_SUNXI is not set
 CONFIG_SPL_SPI_SUNXI=y
+CONFIG_MTD=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_SPI_FLASH_XTX=y
 CONFIG_SPI=y
diff --git a/configs/linkit-smart-7688_defconfig b/configs/linkit-smart-7688_defconfig
index f592f21..fd11f08 100644
--- a/configs/linkit-smart-7688_defconfig
+++ b/configs/linkit-smart-7688_defconfig
@@ -65,7 +65,6 @@
 CONFIG_LED=y
 CONFIG_LED_BLINK=y
 CONFIG_LED_GPIO=y
-CONFIG_MTD=y
 CONFIG_SPI_FLASH_GIGADEVICE=y
 CONFIG_SPI_FLASH_MACRONIX=y
 CONFIG_SPI_FLASH_SPANSION=y
diff --git a/configs/lion-rk3368_defconfig b/configs/lion-rk3368_defconfig
index 9c29eb6..32d34bc 100644
--- a/configs/lion-rk3368_defconfig
+++ b/configs/lion-rk3368_defconfig
@@ -75,7 +75,6 @@
 CONFIG_SYS_I2C_ROCKCHIP=y
 CONFIG_MMC_DW=y
 CONFIG_MMC_DW_ROCKCHIP=y
-CONFIG_MTD=y
 CONFIG_SPI_FLASH_MACRONIX=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_PHY_MSCC=y
diff --git a/configs/malta64_defconfig b/configs/malta64_defconfig
index bbb5c55..ff371da 100644
--- a/configs/malta64_defconfig
+++ b/configs/malta64_defconfig
@@ -34,6 +34,7 @@
 CONFIG_SYS_ATA_DATA_OFFSET=0
 CONFIG_SYS_ATA_REG_OFFSET=0
 CONFIG_SYS_ATA_IDE0_OFFSET=0x01f0
+CONFIG_MTD=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_FLASH_SHOW_PROGRESS=0
diff --git a/configs/malta64el_defconfig b/configs/malta64el_defconfig
index d5db5a2..5b130bc 100644
--- a/configs/malta64el_defconfig
+++ b/configs/malta64el_defconfig
@@ -36,6 +36,7 @@
 CONFIG_SYS_ATA_DATA_OFFSET=0
 CONFIG_SYS_ATA_REG_OFFSET=0
 CONFIG_SYS_ATA_IDE0_OFFSET=0x01f0
+CONFIG_MTD=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_FLASH_SHOW_PROGRESS=0
diff --git a/configs/malta_defconfig b/configs/malta_defconfig
index 2c32fe7..ce917a6 100644
--- a/configs/malta_defconfig
+++ b/configs/malta_defconfig
@@ -33,6 +33,7 @@
 CONFIG_SYS_ATA_DATA_OFFSET=0
 CONFIG_SYS_ATA_REG_OFFSET=0
 CONFIG_SYS_ATA_IDE0_OFFSET=0x01f0
+CONFIG_MTD=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_FLASH_SHOW_PROGRESS=0
diff --git a/configs/maltael_defconfig b/configs/maltael_defconfig
index 88318cb..de29a7a 100644
--- a/configs/maltael_defconfig
+++ b/configs/maltael_defconfig
@@ -35,6 +35,7 @@
 CONFIG_SYS_ATA_DATA_OFFSET=0
 CONFIG_SYS_ATA_REG_OFFSET=0
 CONFIG_SYS_ATA_IDE0_OFFSET=0x01f0
+CONFIG_MTD=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_FLASH_SHOW_PROGRESS=0
diff --git a/configs/marsboard_defconfig b/configs/marsboard_defconfig
index 9f1f796..8325aaa 100644
--- a/configs/marsboard_defconfig
+++ b/configs/marsboard_defconfig
@@ -41,6 +41,7 @@
 CONFIG_SPL_SYS_I2C_LEGACY=y
 CONFIG_SYS_I2C_MXC=y
 CONFIG_FSL_USDHC=y
+CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH_SST=y
 CONFIG_PHYLIB=y
diff --git a/configs/mccmon6_nor_defconfig b/configs/mccmon6_nor_defconfig
index c0dd2da..8edc461 100644
--- a/configs/mccmon6_nor_defconfig
+++ b/configs/mccmon6_nor_defconfig
@@ -58,7 +58,6 @@
 CONFIG_I2C_SET_DEFAULT_BUS_NUM=y
 CONFIG_SYS_I2C_MXC=y
 CONFIG_FSL_USDHC=y
-CONFIG_MTD=y
 CONFIG_DM_MTD=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
diff --git a/configs/mccmon6_sd_defconfig b/configs/mccmon6_sd_defconfig
index e780591..6088d08 100644
--- a/configs/mccmon6_sd_defconfig
+++ b/configs/mccmon6_sd_defconfig
@@ -56,7 +56,6 @@
 CONFIG_I2C_SET_DEFAULT_BUS_NUM=y
 CONFIG_SYS_I2C_MXC=y
 CONFIG_FSL_USDHC=y
-CONFIG_MTD=y
 CONFIG_DM_MTD=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
diff --git a/configs/medcom-wide_defconfig b/configs/medcom-wide_defconfig
index d8dc5dd..9ed75ba 100644
--- a/configs/medcom-wide_defconfig
+++ b/configs/medcom-wide_defconfig
@@ -39,7 +39,6 @@
 CONFIG_ENV_OVERWRITE=y
 CONFIG_ENV_IS_IN_NAND=y
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
-CONFIG_MTD=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_TEGRA_NAND=y
 CONFIG_SYS_NAND_ONFI_DETECTION=y
diff --git a/configs/microblaze-generic_defconfig b/configs/microblaze-generic_defconfig
index 4346507..34e914e 100644
--- a/configs/microblaze-generic_defconfig
+++ b/configs/microblaze-generic_defconfig
@@ -61,7 +61,6 @@
 CONFIG_DM_I2C=y
 CONFIG_LED=y
 CONFIG_LED_GPIO=y
-CONFIG_MTD=y
 CONFIG_DM_MTD=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_SHOW_PROGRESS=0
diff --git a/configs/milkv_duo_defconfig b/configs/milkv_duo_defconfig
new file mode 100644
index 0000000..9eca6ab
--- /dev/null
+++ b/configs/milkv_duo_defconfig
@@ -0,0 +1,23 @@
+CONFIG_RISCV=y
+CONFIG_SYS_MALLOC_LEN=0x820000
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
+CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x82300000
+CONFIG_DEFAULT_DEVICE_TREE="cv1800b-milkv-duo"
+CONFIG_IDENT_STRING="milkv_duo"
+CONFIG_SYS_LOAD_ADDR=0x80080000
+CONFIG_TARGET_MILKV_DUO=y
+CONFIG_ARCH_RV64I=y
+CONFIG_RISCV_SMODE=y
+CONFIG_FIT=y
+CONFIG_SUPPORT_RAW_INITRD=y
+CONFIG_HUSH_PARSER=y
+CONFIG_SYS_PROMPT="milkv_duo# "
+CONFIG_SYS_MAXARGS=64
+CONFIG_SYS_CBSIZE=512
+CONFIG_SYS_PBSIZE=544
+CONFIG_SYS_BOOTM_LEN=0x4000000
+CONFIG_ENV_OVERWRITE=y
+CONFIG_SYS_NS16550=y
+CONFIG_SYS_NS16550_MEM32=y
diff --git a/configs/miqi-rk3288_defconfig b/configs/miqi-rk3288_defconfig
index d8c82a6..374d21e 100644
--- a/configs/miqi-rk3288_defconfig
+++ b/configs/miqi-rk3288_defconfig
@@ -63,7 +63,6 @@
 CONFIG_SYS_I2C_ROCKCHIP=y
 CONFIG_MMC_DW=y
 CONFIG_MMC_DW_ROCKCHIP=y
-CONFIG_MTD=y
 CONFIG_ETH_DESIGNWARE=y
 CONFIG_GMAC_ROCKCHIP=y
 CONFIG_PINCTRL=y
diff --git a/configs/mt7621_nand_rfb_defconfig b/configs/mt7621_nand_rfb_defconfig
index 4289f88..1acd9e5 100644
--- a/configs/mt7621_nand_rfb_defconfig
+++ b/configs/mt7621_nand_rfb_defconfig
@@ -64,7 +64,6 @@
 # CONFIG_MMC_QUIRKS is not set
 # CONFIG_MMC_HW_PARTITIONING is not set
 CONFIG_MMC_MTK=y
-CONFIG_MTD=y
 CONFIG_DM_MTD=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_NAND_MT7621=y
diff --git a/configs/mt7622_rfb_defconfig b/configs/mt7622_rfb_defconfig
index b015f89..0bda8cd 100644
--- a/configs/mt7622_rfb_defconfig
+++ b/configs/mt7622_rfb_defconfig
@@ -36,6 +36,7 @@
 CONFIG_CLK=y
 CONFIG_MMC_HS200_SUPPORT=y
 CONFIG_MMC_MTK=y
+CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH_EON=y
 CONFIG_SPI_FLASH_GIGADEVICE=y
diff --git a/configs/mvebu_ac5_rd_defconfig b/configs/mvebu_ac5_rd_defconfig
index 0a9adcc..677b211 100644
--- a/configs/mvebu_ac5_rd_defconfig
+++ b/configs/mvebu_ac5_rd_defconfig
@@ -58,7 +58,6 @@
 CONFIG_MISC=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_XENON=y
-CONFIG_MTD=y
 CONFIG_SPI_FLASH_GIGADEVICE=y
 CONFIG_SPI_FLASH_MACRONIX=y
 CONFIG_SPI_FLASH_SPANSION=y
diff --git a/configs/mvebu_crb_cn9130_defconfig b/configs/mvebu_crb_cn9130_defconfig
index 38f9579..4d5f575 100644
--- a/configs/mvebu_crb_cn9130_defconfig
+++ b/configs/mvebu_crb_cn9130_defconfig
@@ -56,7 +56,6 @@
 CONFIG_MMC_HS200_SUPPORT=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_XENON=y
-CONFIG_MTD=y
 CONFIG_DM_MTD=y
 CONFIG_SPI_FLASH_SFDP_SUPPORT=y
 CONFIG_SPI_FLASH_MACRONIX=y
diff --git a/configs/mvebu_db-88f3720_defconfig b/configs/mvebu_db-88f3720_defconfig
index 51518cf..372a660 100644
--- a/configs/mvebu_db-88f3720_defconfig
+++ b/configs/mvebu_db-88f3720_defconfig
@@ -56,7 +56,6 @@
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_SDMA=y
 CONFIG_MMC_SDHCI_XENON=y
-CONFIG_MTD=y
 CONFIG_SPI_FLASH_MACRONIX=y
 CONFIG_SPI_FLASH_SPANSION=y
 CONFIG_SPI_FLASH_STMICRO=y
diff --git a/configs/mvebu_db_cn9130_defconfig b/configs/mvebu_db_cn9130_defconfig
index f3f0019..9133e25 100644
--- a/configs/mvebu_db_cn9130_defconfig
+++ b/configs/mvebu_db_cn9130_defconfig
@@ -58,7 +58,6 @@
 CONFIG_MMC_HS200_SUPPORT=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_XENON=y
-CONFIG_MTD=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_SYS_NAND_USE_FLASH_BBT=y
 CONFIG_NAND_PXA3XX=y
diff --git a/configs/mvebu_espressobin-88f3720_defconfig b/configs/mvebu_espressobin-88f3720_defconfig
index 227607a..0cebebc 100644
--- a/configs/mvebu_espressobin-88f3720_defconfig
+++ b/configs/mvebu_espressobin-88f3720_defconfig
@@ -66,7 +66,6 @@
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_SDMA=y
 CONFIG_MMC_SDHCI_XENON=y
-CONFIG_MTD=y
 CONFIG_DM_MTD=y
 CONFIG_SPI_FLASH_GIGADEVICE=y
 CONFIG_SPI_FLASH_ISSI=y
diff --git a/configs/mx7ulp_com_defconfig b/configs/mx7ulp_com_defconfig
index 74dfc8a..f8dcc0a 100644
--- a/configs/mx7ulp_com_defconfig
+++ b/configs/mx7ulp_com_defconfig
@@ -40,6 +40,7 @@
 CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_IMX_LPI2C=y
 CONFIG_FSL_USDHC=y
+CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH_ATMEL=y
 CONFIG_PINCTRL=y
diff --git a/configs/n2350_defconfig b/configs/n2350_defconfig
index 696206c..26895e9 100644
--- a/configs/n2350_defconfig
+++ b/configs/n2350_defconfig
@@ -71,7 +71,6 @@
 CONFIG_SYS_64BIT_LBA=y
 CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_MVTWSI=y
-CONFIG_MTD=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_NAND_PXA3XX=y
 CONFIG_SYS_NAND_ONFI_DETECTION=y
diff --git a/configs/nanopi_duo2_defconfig b/configs/nanopi_duo2_defconfig
new file mode 100644
index 0000000..beb2f92
--- /dev/null
+++ b/configs/nanopi_duo2_defconfig
@@ -0,0 +1,12 @@
+CONFIG_ARM=y
+CONFIG_ARCH_SUNXI=y
+CONFIG_DEFAULT_DEVICE_TREE="sun8i-h3-nanopi-duo2"
+CONFIG_SPL=y
+CONFIG_MACH_SUN8I_H3=y
+CONFIG_DRAM_CLK=408
+# CONFIG_VIDEO_DE2 is not set
+# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+CONFIG_CONSOLE_MUX=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_MUSB_GADGET=y
diff --git a/configs/net2big_v2_defconfig b/configs/net2big_v2_defconfig
index aeb62fb..dda627a 100644
--- a/configs/net2big_v2_defconfig
+++ b/configs/net2big_v2_defconfig
@@ -62,6 +62,7 @@
 CONFIG_SYS_I2C_SLAVE=0x0
 CONFIG_SYS_I2C_EEPROM_ADDR=0x50
 # CONFIG_MMC is not set
+CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH_MACRONIX=y
 CONFIG_MVGBE=y
diff --git a/configs/netspace_lite_v2_defconfig b/configs/netspace_lite_v2_defconfig
index a0685aa..742e620 100644
--- a/configs/netspace_lite_v2_defconfig
+++ b/configs/netspace_lite_v2_defconfig
@@ -62,6 +62,7 @@
 CONFIG_SYS_I2C_SLAVE=0x0
 CONFIG_SYS_I2C_EEPROM_ADDR=0x50
 # CONFIG_MMC is not set
+CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH_MACRONIX=y
 CONFIG_MVGBE=y
diff --git a/configs/netspace_max_v2_defconfig b/configs/netspace_max_v2_defconfig
index eb14471..7779e68 100644
--- a/configs/netspace_max_v2_defconfig
+++ b/configs/netspace_max_v2_defconfig
@@ -62,6 +62,7 @@
 CONFIG_SYS_I2C_SLAVE=0x0
 CONFIG_SYS_I2C_EEPROM_ADDR=0x50
 # CONFIG_MMC is not set
+CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH_MACRONIX=y
 CONFIG_MVGBE=y
diff --git a/configs/netspace_mini_v2_defconfig b/configs/netspace_mini_v2_defconfig
index b594a88..9e3614b 100644
--- a/configs/netspace_mini_v2_defconfig
+++ b/configs/netspace_mini_v2_defconfig
@@ -60,6 +60,7 @@
 CONFIG_SYS_I2C_SLAVE=0x0
 CONFIG_SYS_I2C_EEPROM_ADDR=0x50
 # CONFIG_MMC is not set
+CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH_MACRONIX=y
 CONFIG_MVGBE=y
diff --git a/configs/netspace_v2_defconfig b/configs/netspace_v2_defconfig
index f7ee93e..1583a0a 100644
--- a/configs/netspace_v2_defconfig
+++ b/configs/netspace_v2_defconfig
@@ -62,6 +62,7 @@
 CONFIG_SYS_I2C_SLAVE=0x0
 CONFIG_SYS_I2C_EEPROM_ADDR=0x50
 # CONFIG_MMC is not set
+CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH_MACRONIX=y
 CONFIG_MVGBE=y
diff --git a/configs/oceanic_5205_5inmfd_defconfig b/configs/oceanic_5205_5inmfd_defconfig
index 6cdcf78..2e62f8e 100644
--- a/configs/oceanic_5205_5inmfd_defconfig
+++ b/configs/oceanic_5205_5inmfd_defconfig
@@ -8,6 +8,7 @@
 CONFIG_DRAM_ZQ=3881949
 CONFIG_SPL_SPI_SUNXI=y
 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+CONFIG_MTD=y
 CONFIG_SUN8I_EMAC=y
 CONFIG_SPI=y
 CONFIG_USB_EHCI_HCD=y
diff --git a/configs/octeon_ebb7304_defconfig b/configs/octeon_ebb7304_defconfig
index 90e3408..00fcd57 100644
--- a/configs/octeon_ebb7304_defconfig
+++ b/configs/octeon_ebb7304_defconfig
@@ -48,7 +48,6 @@
 CONFIG_MISC=y
 CONFIG_MMC=y
 CONFIG_MMC_OCTEONTX=y
-CONFIG_MTD=y
 CONFIG_DM_MTD=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_SHOW_PROGRESS=0
diff --git a/configs/octeon_nic23_defconfig b/configs/octeon_nic23_defconfig
index 80b2020..8bf2520 100644
--- a/configs/octeon_nic23_defconfig
+++ b/configs/octeon_nic23_defconfig
@@ -56,7 +56,6 @@
 CONFIG_MISC=y
 CONFIG_MMC=y
 CONFIG_MMC_OCTEONTX=y
-CONFIG_MTD=y
 CONFIG_DM_MTD=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH_ATMEL=y
diff --git a/configs/odroid-m1-rk3568_defconfig b/configs/odroid-m1-rk3568_defconfig
index 67812c9..3130e34 100644
--- a/configs/odroid-m1-rk3568_defconfig
+++ b/configs/odroid-m1-rk3568_defconfig
@@ -77,7 +77,6 @@
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_SDMA=y
 CONFIG_MMC_SDHCI_ROCKCHIP=y
-CONFIG_MTD=y
 CONFIG_SF_DEFAULT_BUS=4
 CONFIG_SPI_FLASH_SFDP_SUPPORT=y
 CONFIG_SPI_FLASH_MACRONIX=y
diff --git a/configs/odroid-xu3_defconfig b/configs/odroid-xu3_defconfig
index e3ac4d2..c80900e 100644
--- a/configs/odroid-xu3_defconfig
+++ b/configs/odroid-xu3_defconfig
@@ -54,7 +54,6 @@
 CONFIG_SYS_I2C_S3C24X0=y
 CONFIG_SUPPORT_EMMC_BOOT=y
 CONFIG_MMC_DW=y
-CONFIG_MTD=y
 CONFIG_SMC911X=y
 CONFIG_DM_PMIC=y
 CONFIG_PMIC_S2MPS11=y
diff --git a/configs/odroid_defconfig b/configs/odroid_defconfig
index 2c86768..fab41bd 100644
--- a/configs/odroid_defconfig
+++ b/configs/odroid_defconfig
@@ -58,7 +58,6 @@
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_SDMA=y
 CONFIG_MMC_SDHCI_S5P=y
-CONFIG_MTD=y
 CONFIG_DM_PMIC=y
 CONFIG_DM_PMIC_MAX77686=y
 CONFIG_DM_REGULATOR=y
diff --git a/configs/orangepi_pc2_defconfig b/configs/orangepi_pc2_defconfig
index fb6fbaf..24ab0a0 100644
--- a/configs/orangepi_pc2_defconfig
+++ b/configs/orangepi_pc2_defconfig
@@ -10,6 +10,7 @@
 CONFIG_SPL_I2C=y
 CONFIG_SPL_SYS_I2C_LEGACY=y
 CONFIG_SYS_I2C_MVTWSI=y
+CONFIG_MTD=y
 CONFIG_SPI_FLASH_MACRONIX=y
 CONFIG_SUN8I_EMAC=y
 CONFIG_SY8106A_POWER=y
diff --git a/configs/orangepi_r1_defconfig b/configs/orangepi_r1_defconfig
index 4496aa4..2d8a525 100644
--- a/configs/orangepi_r1_defconfig
+++ b/configs/orangepi_r1_defconfig
@@ -8,6 +8,7 @@
 CONFIG_SPL_SPI_SUNXI=y
 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
 CONFIG_CONSOLE_MUX=y
+CONFIG_MTD=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_SUN8I_EMAC=y
 CONFIG_SPI=y
diff --git a/configs/orangepi_win_defconfig b/configs/orangepi_win_defconfig
index 3ddaf05..4ce36cb 100644
--- a/configs/orangepi_win_defconfig
+++ b/configs/orangepi_win_defconfig
@@ -5,6 +5,7 @@
 CONFIG_MACH_SUN50I=y
 CONFIG_SPL_SPI_SUNXI=y
 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+CONFIG_MTD=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_PHY_REALTEK=y
 CONFIG_SUN8I_EMAC=y
diff --git a/configs/orangepi_zero2_defconfig b/configs/orangepi_zero2_defconfig
index 98aed84..c4e4f8b 100644
--- a/configs/orangepi_zero2_defconfig
+++ b/configs/orangepi_zero2_defconfig
@@ -17,6 +17,7 @@
 CONFIG_SYS_I2C_MVTWSI=y
 CONFIG_SYS_I2C_SLAVE=0x7f
 CONFIG_SYS_I2C_SPEED=400000
+CONFIG_MTD=y
 CONFIG_SPI_FLASH_MACRONIX=y
 CONFIG_PHY_REALTEK=y
 CONFIG_SUN8I_EMAC=y
diff --git a/configs/orangepi_zero3_defconfig b/configs/orangepi_zero3_defconfig
index 5a019fe..44b7ec7 100644
--- a/configs/orangepi_zero3_defconfig
+++ b/configs/orangepi_zero3_defconfig
@@ -22,6 +22,7 @@
 CONFIG_SYS_I2C_MVTWSI=y
 CONFIG_SYS_I2C_SLAVE=0x7f
 CONFIG_SYS_I2C_SPEED=400000
+CONFIG_MTD=y
 CONFIG_SPI_FLASH_ZBIT=y
 CONFIG_PHY_MOTORCOMM=y
 CONFIG_SUN8I_EMAC=y
diff --git a/configs/orangepi_zero_defconfig b/configs/orangepi_zero_defconfig
index f7f3bfb..abdf9a9 100644
--- a/configs/orangepi_zero_defconfig
+++ b/configs/orangepi_zero_defconfig
@@ -8,6 +8,7 @@
 CONFIG_SPL_SPI_SUNXI=y
 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
 CONFIG_CONSOLE_MUX=y
+CONFIG_MTD=y
 CONFIG_SPI_FLASH_MACRONIX=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_SUN8I_EMAC=y
diff --git a/configs/origen_defconfig b/configs/origen_defconfig
index f06d7c6..dc9285d 100644
--- a/configs/origen_defconfig
+++ b/configs/origen_defconfig
@@ -48,7 +48,6 @@
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_SDMA=y
 CONFIG_MMC_SDHCI_S5P=y
-CONFIG_MTD=y
 CONFIG_USB=y
 CONFIG_USB_GADGET=y
 CONFIG_USB_GADGET_MANUFACTURER="Samsung"
diff --git a/configs/pcm051_rev3_defconfig b/configs/pcm051_rev3_defconfig
index 831a146..7846981 100644
--- a/configs/pcm051_rev3_defconfig
+++ b/configs/pcm051_rev3_defconfig
@@ -50,6 +50,7 @@
 CONFIG_DM_I2C=y
 CONFIG_MISC=y
 CONFIG_MMC_OMAP_HS=y
+CONFIG_MTD=y
 CONFIG_DM_MTD=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH_WINBOND=y
diff --git a/configs/peach-pi_defconfig b/configs/peach-pi_defconfig
index fd76b5b..27d438e 100644
--- a/configs/peach-pi_defconfig
+++ b/configs/peach-pi_defconfig
@@ -58,7 +58,6 @@
 CONFIG_MMC_DW=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_S5P=y
-CONFIG_MTD=y
 CONFIG_SPI_FLASH_GIGADEVICE=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_SMC911X=y
diff --git a/configs/peach-pit_defconfig b/configs/peach-pit_defconfig
index 3ed17ba..1c7e011 100644
--- a/configs/peach-pit_defconfig
+++ b/configs/peach-pit_defconfig
@@ -57,7 +57,6 @@
 CONFIG_MMC_DW=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_S5P=y
-CONFIG_MTD=y
 CONFIG_SPI_FLASH_GIGADEVICE=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_SMC911X=y
diff --git a/configs/phycore-rk3288_defconfig b/configs/phycore-rk3288_defconfig
index ce77056..ce999e4 100644
--- a/configs/phycore-rk3288_defconfig
+++ b/configs/phycore-rk3288_defconfig
@@ -66,7 +66,6 @@
 CONFIG_I2C_EEPROM=y
 CONFIG_MMC_DW=y
 CONFIG_MMC_DW_ROCKCHIP=y
-CONFIG_MTD=y
 CONFIG_ETH_DESIGNWARE=y
 CONFIG_GMAC_ROCKCHIP=y
 CONFIG_PINCTRL=y
diff --git a/configs/phycore_am62x_a53_defconfig b/configs/phycore_am62x_a53_defconfig
index fb5c3f9..2d5d906 100644
--- a/configs/phycore_am62x_a53_defconfig
+++ b/configs/phycore_am62x_a53_defconfig
@@ -81,6 +81,7 @@
 CONFIG_MMC_SDHCI_ADMA=y
 CONFIG_SPL_MMC_SDHCI_ADMA=y
 CONFIG_MMC_SDHCI_AM654=y
+CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH_SFDP_SUPPORT=y
 # CONFIG_SPI_FLASH_SMART_HWCAPS is not set
diff --git a/configs/phycore_am62x_r5_defconfig b/configs/phycore_am62x_r5_defconfig
index f655d1b..bd28e14 100644
--- a/configs/phycore_am62x_r5_defconfig
+++ b/configs/phycore_am62x_r5_defconfig
@@ -97,6 +97,7 @@
 CONFIG_MMC_SDHCI_ADMA=y
 CONFIG_SPL_MMC_SDHCI_ADMA=y
 CONFIG_MMC_SDHCI_AM654=y
+CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH_SFDP_SUPPORT=y
 # CONFIG_SPI_FLASH_SMART_HWCAPS is not set
diff --git a/configs/pico-dwarf-imx6ul_defconfig b/configs/pico-dwarf-imx6ul_defconfig
index 7ae3726..8b90285 100644
--- a/configs/pico-dwarf-imx6ul_defconfig
+++ b/configs/pico-dwarf-imx6ul_defconfig
@@ -67,6 +67,7 @@
 CONFIG_DM_REGULATOR_PFUZE100=y
 CONFIG_DM_REGULATOR_FIXED=y
 CONFIG_DM_REGULATOR_GPIO=y
+CONFIG_DM_SERIAL=y
 CONFIG_MXC_UART=y
 CONFIG_USB=y
 CONFIG_SPL_USB_HOST=y
diff --git a/configs/pico-hobbit-imx6ul_defconfig b/configs/pico-hobbit-imx6ul_defconfig
index fc5a54b..e3aca6e 100644
--- a/configs/pico-hobbit-imx6ul_defconfig
+++ b/configs/pico-hobbit-imx6ul_defconfig
@@ -70,6 +70,7 @@
 CONFIG_DM_REGULATOR_PFUZE100=y
 CONFIG_DM_REGULATOR_FIXED=y
 CONFIG_DM_REGULATOR_GPIO=y
+CONFIG_DM_SERIAL=y
 CONFIG_MXC_UART=y
 CONFIG_USB=y
 CONFIG_SPL_USB_HOST=y
diff --git a/configs/pine64-lts_defconfig b/configs/pine64-lts_defconfig
index 9583d29..78f65c5 100644
--- a/configs/pine64-lts_defconfig
+++ b/configs/pine64-lts_defconfig
@@ -10,6 +10,7 @@
 CONFIG_SPL_SPI_SUNXI=y
 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
 CONFIG_SUPPORT_EMMC_BOOT=y
+CONFIG_MTD=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_SUN8I_EMAC=y
 CONFIG_SPI=y
diff --git a/configs/pine_h64_defconfig b/configs/pine_h64_defconfig
index 4712b8e..20a4a0a 100644
--- a/configs/pine_h64_defconfig
+++ b/configs/pine_h64_defconfig
@@ -10,6 +10,7 @@
 # CONFIG_PSCI_RESET is not set
 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
 CONFIG_SUPPORT_EMMC_BOOT=y
+CONFIG_MTD=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_SUN8I_EMAC=y
 CONFIG_PHY_SUN50I_USB3=y
diff --git a/configs/pinecube_defconfig b/configs/pinecube_defconfig
index 1551cf1..7cc0a86 100644
--- a/configs/pinecube_defconfig
+++ b/configs/pinecube_defconfig
@@ -14,6 +14,7 @@
 CONFIG_SYS_I2C_MVTWSI=y
 CONFIG_SYS_I2C_SLAVE=0x7f
 CONFIG_SYS_I2C_SPEED=400000
+CONFIG_MTD=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_AXP209_POWER=y
 CONFIG_AXP_DCDC2_VOLT=1250
diff --git a/configs/plutux_defconfig b/configs/plutux_defconfig
index ab33ac7..13543b3 100644
--- a/configs/plutux_defconfig
+++ b/configs/plutux_defconfig
@@ -38,7 +38,6 @@
 CONFIG_ENV_OVERWRITE=y
 CONFIG_ENV_IS_IN_NAND=y
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
-CONFIG_MTD=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_TEGRA_NAND=y
 CONFIG_SYS_NAND_ONFI_DETECTION=y
diff --git a/configs/poleg_evb_defconfig b/configs/poleg_evb_defconfig
index 6ec44df..99c6d69 100644
--- a/configs/poleg_evb_defconfig
+++ b/configs/poleg_evb_defconfig
@@ -60,6 +60,7 @@
 CONFIG_NPCM_HOST=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_NPCM=y
+CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH_MACRONIX=y
 CONFIG_SPI_FLASH_WINBOND=y
diff --git a/configs/popmetal-rk3288_defconfig b/configs/popmetal-rk3288_defconfig
index 481549a..09af09e 100644
--- a/configs/popmetal-rk3288_defconfig
+++ b/configs/popmetal-rk3288_defconfig
@@ -62,7 +62,6 @@
 CONFIG_SYS_I2C_ROCKCHIP=y
 CONFIG_MMC_DW=y
 CONFIG_MMC_DW_ROCKCHIP=y
-CONFIG_MTD=y
 CONFIG_ETH_DESIGNWARE=y
 CONFIG_GMAC_ROCKCHIP=y
 CONFIG_PINCTRL=y
diff --git a/configs/qemu_arm64_defconfig b/configs/qemu_arm64_defconfig
index 5100e19..631d886 100644
--- a/configs/qemu_arm64_defconfig
+++ b/configs/qemu_arm64_defconfig
@@ -27,6 +27,7 @@
 # CONFIG_DISPLAY_CPUINFO is not set
 # CONFIG_DISPLAY_BOARDINFO is not set
 CONFIG_PCI_INIT_R=y
+CONFIG_CMD_SMBIOS=y
 CONFIG_CMD_BOOTZ=y
 CONFIG_CMD_BOOTEFI_SELFTEST=y
 CONFIG_CMD_NVEDIT_EFI=y
diff --git a/configs/r2dplus_defconfig b/configs/r2dplus_defconfig
index dd7d2b7..1c87613 100644
--- a/configs/r2dplus_defconfig
+++ b/configs/r2dplus_defconfig
@@ -43,6 +43,7 @@
 CONFIG_SYS_ATA_ALT_OFFSET=0x800
 CONFIG_IDE_RESET=y
 CONFIG_CLK=y
+CONFIG_MTD=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_FLASH_SHOW_PROGRESS=0
diff --git a/configs/riotboard_defconfig b/configs/riotboard_defconfig
index aa8c410..1b303e7 100644
--- a/configs/riotboard_defconfig
+++ b/configs/riotboard_defconfig
@@ -58,6 +58,7 @@
 CONFIG_SYS_I2C_MXC=y
 CONFIG_SUPPORT_EMMC_BOOT=y
 CONFIG_FSL_USDHC=y
+CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH_SST=y
 CONFIG_PHYLIB=y
diff --git a/configs/rock2_defconfig b/configs/rock2_defconfig
index 1e5559a..3ebfb4e 100644
--- a/configs/rock2_defconfig
+++ b/configs/rock2_defconfig
@@ -63,7 +63,6 @@
 CONFIG_SYS_I2C_ROCKCHIP=y
 CONFIG_MMC_DW=y
 CONFIG_MMC_DW_ROCKCHIP=y
-CONFIG_MTD=y
 CONFIG_ETH_DESIGNWARE=y
 CONFIG_GMAC_ROCKCHIP=y
 CONFIG_PINCTRL=y
diff --git a/configs/rock_defconfig b/configs/rock_defconfig
index 94c4945..b3fa76f 100644
--- a/configs/rock_defconfig
+++ b/configs/rock_defconfig
@@ -53,7 +53,6 @@
 CONFIG_LED=y
 CONFIG_MMC_DW=y
 CONFIG_MMC_DW_ROCKCHIP=y
-CONFIG_MTD=y
 CONFIG_PINCTRL=y
 CONFIG_DM_PMIC=y
 # CONFIG_SPL_PMIC_CHILDREN is not set
diff --git a/configs/s5pc210_universal_defconfig b/configs/s5pc210_universal_defconfig
index 56a55f0..67959ad 100644
--- a/configs/s5pc210_universal_defconfig
+++ b/configs/s5pc210_universal_defconfig
@@ -49,7 +49,6 @@
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_SDMA=y
 CONFIG_MMC_SDHCI_S5P=y
-CONFIG_MTD=y
 CONFIG_SAMSUNG_ONENAND=y
 CONFIG_DM_PMIC=y
 CONFIG_DM_PMIC_MAX8998=y
diff --git a/configs/sama5d27_giantboard_defconfig b/configs/sama5d27_giantboard_defconfig
index 6a205e7..6637d15 100644
--- a/configs/sama5d27_giantboard_defconfig
+++ b/configs/sama5d27_giantboard_defconfig
@@ -78,6 +78,7 @@
 CONFIG_SYS_I2C_AT91=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_ATMEL=y
+CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_PINCTRL=y
 CONFIG_SPL_PINCTRL=y
diff --git a/configs/sama5d2_icp_mmc_defconfig b/configs/sama5d2_icp_mmc_defconfig
index f20b250..faf1f43 100644
--- a/configs/sama5d2_icp_mmc_defconfig
+++ b/configs/sama5d2_icp_mmc_defconfig
@@ -88,6 +88,7 @@
 CONFIG_I2C_EEPROM=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_ATMEL=y
+CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SF_DEFAULT_BUS=2
 CONFIG_SPI_FLASH_SFDP_SUPPORT=y
diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig
index 996bb7a..d101cca 100644
--- a/configs/sandbox64_defconfig
+++ b/configs/sandbox64_defconfig
@@ -167,7 +167,6 @@
 CONFIG_PWRSEQ=y
 CONFIG_I2C_EEPROM=y
 CONFIG_MMC_SANDBOX=y
-CONFIG_MTD=y
 CONFIG_DM_MTD=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_SYS_MAX_NAND_DEVICE=8
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index de06295..a8df5e6 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -42,6 +42,7 @@
 CONFIG_ANDROID_AB=y
 CONFIG_CMD_CPU=y
 CONFIG_CMD_LICENSE=y
+CONFIG_CMD_SMBIOS=y
 CONFIG_CMD_BOOTM_PRE_LOAD=y
 CONFIG_CMD_BOOTZ=y
 CONFIG_BOOTM_OPENRTOS=y
@@ -217,7 +218,6 @@
 CONFIG_MMC_PCI=y
 CONFIG_MMC_SANDBOX=y
 CONFIG_MMC_SDHCI=y
-CONFIG_MTD=y
 CONFIG_DM_MTD=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_SYS_MAX_NAND_DEVICE=8
diff --git a/configs/sandbox_noinst_defconfig b/configs/sandbox_noinst_defconfig
index 8f3684f..137b3c6 100644
--- a/configs/sandbox_noinst_defconfig
+++ b/configs/sandbox_noinst_defconfig
@@ -187,7 +187,6 @@
 CONFIG_SPL_PWRSEQ=y
 CONFIG_FS_LOADER=y
 CONFIG_MMC_SANDBOX=y
-CONFIG_MTD=y
 CONFIG_DM_MTD=y
 CONFIG_MTD_CONCAT=y
 CONFIG_MTD_RAW_NAND=y
diff --git a/configs/seaboard_defconfig b/configs/seaboard_defconfig
index 013e1ce..bb5a4f0 100644
--- a/configs/seaboard_defconfig
+++ b/configs/seaboard_defconfig
@@ -42,7 +42,6 @@
 CONFIG_SYS_MMC_ENV_PART=2
 CONFIG_SYS_I2C_TEGRA=y
 CONFIG_TEGRA_KEYBOARD=y
-CONFIG_MTD=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_TEGRA_NAND=y
 CONFIG_SYS_NAND_ONFI_DETECTION=y
diff --git a/configs/sfr_nb4-ser_ram_defconfig b/configs/sfr_nb4-ser_ram_defconfig
index b58873e..7125d49 100644
--- a/configs/sfr_nb4-ser_ram_defconfig
+++ b/configs/sfr_nb4-ser_ram_defconfig
@@ -52,6 +52,7 @@
 CONFIG_LED=y
 CONFIG_LED_BCM6358=y
 CONFIG_LED_GPIO=y
+CONFIG_MTD=y
 CONFIG_DM_MTD=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_SHOW_PROGRESS=0
diff --git a/configs/silinux_ek874_defconfig b/configs/silinux_ek874_defconfig
index 32370be..e74fbb8 100644
--- a/configs/silinux_ek874_defconfig
+++ b/configs/silinux_ek874_defconfig
@@ -64,6 +64,7 @@
 CONFIG_MMC_IO_VOLTAGE=y
 CONFIG_MMC_UHS_SUPPORT=y
 CONFIG_RENESAS_SDHI=y
+CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_BITBANGMII=y
diff --git a/configs/smdk5250_defconfig b/configs/smdk5250_defconfig
index 709aaf1..8b42c8b 100644
--- a/configs/smdk5250_defconfig
+++ b/configs/smdk5250_defconfig
@@ -53,7 +53,6 @@
 CONFIG_MMC_DW=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_S5P=y
-CONFIG_MTD=y
 CONFIG_SPI_FLASH_GIGADEVICE=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_SMC911X=y
diff --git a/configs/smdk5420_defconfig b/configs/smdk5420_defconfig
index c181082..55a5317 100644
--- a/configs/smdk5420_defconfig
+++ b/configs/smdk5420_defconfig
@@ -48,7 +48,6 @@
 CONFIG_MMC_DW=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_S5P=y
-CONFIG_MTD=y
 CONFIG_SPI_FLASH_GIGADEVICE=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_SMC911X=y
diff --git a/configs/smdkv310_defconfig b/configs/smdkv310_defconfig
index 4025f80..7a0f6f8 100644
--- a/configs/smdkv310_defconfig
+++ b/configs/smdkv310_defconfig
@@ -36,6 +36,5 @@
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_SDMA=y
 CONFIG_MMC_SDHCI_S5P=y
-CONFIG_MTD=y
 CONFIG_SMC911X=y
 CONFIG_USB=y
diff --git a/configs/snow_defconfig b/configs/snow_defconfig
index 6bcf47f..3a617c6 100644
--- a/configs/snow_defconfig
+++ b/configs/snow_defconfig
@@ -68,7 +68,6 @@
 CONFIG_MMC_DW=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_S5P=y
-CONFIG_MTD=y
 CONFIG_SPI_FLASH_GIGADEVICE=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_SMC911X=y
diff --git a/configs/socfpga_agilex_atf_defconfig b/configs/socfpga_agilex_atf_defconfig
index 6f8c1ee..704a9aa 100644
--- a/configs/socfpga_agilex_atf_defconfig
+++ b/configs/socfpga_agilex_atf_defconfig
@@ -73,7 +73,6 @@
 CONFIG_SYS_I2C_DW=y
 CONFIG_SYS_MMC_MAX_BLK_COUNT=256
 CONFIG_MMC_DW=y
-CONFIG_MTD=y
 CONFIG_SPI_FLASH_SPANSION=y
 CONFIG_SPI_FLASH_STMICRO=y
 CONFIG_PHY_MICREL=y
diff --git a/configs/socfpga_agilex_defconfig b/configs/socfpga_agilex_defconfig
index b90e5cd..67a4669 100644
--- a/configs/socfpga_agilex_defconfig
+++ b/configs/socfpga_agilex_defconfig
@@ -58,6 +58,7 @@
 CONFIG_CMD_EXT4=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
+# CONFIG_CMD_MTDPARTS is not set
 CONFIG_ENV_IS_IN_MMC=y
 CONFIG_USE_BOOTFILE=y
 CONFIG_BOOTFILE="Image"
diff --git a/configs/socfpga_agilex_vab_defconfig b/configs/socfpga_agilex_vab_defconfig
index c843364..a907fe5 100644
--- a/configs/socfpga_agilex_vab_defconfig
+++ b/configs/socfpga_agilex_vab_defconfig
@@ -74,7 +74,6 @@
 CONFIG_SYS_I2C_DW=y
 CONFIG_SYS_MMC_MAX_BLK_COUNT=256
 CONFIG_MMC_DW=y
-CONFIG_MTD=y
 CONFIG_SPI_FLASH_SPANSION=y
 CONFIG_SPI_FLASH_STMICRO=y
 CONFIG_PHY_MICREL=y
diff --git a/configs/socfpga_arria10_defconfig b/configs/socfpga_arria10_defconfig
index c35a360..5c7ef4f 100644
--- a/configs/socfpga_arria10_defconfig
+++ b/configs/socfpga_arria10_defconfig
@@ -56,7 +56,6 @@
 CONFIG_SPL_FS_LOADER=y
 CONFIG_SYS_MMC_MAX_BLK_COUNT=256
 CONFIG_MMC_DW=y
-CONFIG_MTD=y
 CONFIG_PHY_MICREL=y
 CONFIG_PHY_MICREL_KSZ90X1=y
 CONFIG_ETH_DESIGNWARE=y
diff --git a/configs/socfpga_arria5_defconfig b/configs/socfpga_arria5_defconfig
index 8980a65..eb7d3d2 100644
--- a/configs/socfpga_arria5_defconfig
+++ b/configs/socfpga_arria5_defconfig
@@ -57,7 +57,6 @@
 CONFIG_SYS_I2C_DW=y
 CONFIG_SYS_MMC_MAX_BLK_COUNT=256
 CONFIG_MMC_DW=y
-CONFIG_MTD=y
 CONFIG_SPI_FLASH_SPANSION=y
 CONFIG_SPI_FLASH_STMICRO=y
 # CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
diff --git a/configs/socfpga_chameleonv3_defconfig b/configs/socfpga_chameleonv3_defconfig
index fedf396..6ea61ca 100644
--- a/configs/socfpga_chameleonv3_defconfig
+++ b/configs/socfpga_chameleonv3_defconfig
@@ -22,6 +22,7 @@
 CONFIG_SPL_ENV_SUPPORT=y
 CONFIG_SPL_FS_EXT4=y
 CONFIG_SPL_FPGA=y
+# CONFIG_CMD_MTDPARTS is not set
 CONFIG_ENV_IS_IN_MMC=y
 CONFIG_SYS_I2C_DW=y
 CONFIG_MISC=y
diff --git a/configs/socfpga_cyclone5_defconfig b/configs/socfpga_cyclone5_defconfig
index 0d744f4..cdf3308 100644
--- a/configs/socfpga_cyclone5_defconfig
+++ b/configs/socfpga_cyclone5_defconfig
@@ -57,7 +57,6 @@
 CONFIG_SYS_I2C_DW=y
 CONFIG_SYS_MMC_MAX_BLK_COUNT=256
 CONFIG_MMC_DW=y
-CONFIG_MTD=y
 CONFIG_SPI_FLASH_MACRONIX=y
 CONFIG_SPI_FLASH_SPANSION=y
 CONFIG_SPI_FLASH_STMICRO=y
diff --git a/configs/socfpga_dbm_soc1_defconfig b/configs/socfpga_dbm_soc1_defconfig
index 2087b6e..342cfba 100644
--- a/configs/socfpga_dbm_soc1_defconfig
+++ b/configs/socfpga_dbm_soc1_defconfig
@@ -66,7 +66,6 @@
 CONFIG_SYS_I2C_DW=y
 CONFIG_SYS_MMC_MAX_BLK_COUNT=256
 CONFIG_MMC_DW=y
-CONFIG_MTD=y
 CONFIG_SPI_FLASH_MTD=y
 CONFIG_PHY_GIGE=y
 CONFIG_ETH_DESIGNWARE=y
diff --git a/configs/socfpga_de0_nano_soc_defconfig b/configs/socfpga_de0_nano_soc_defconfig
index 646552c..aada30d 100644
--- a/configs/socfpga_de0_nano_soc_defconfig
+++ b/configs/socfpga_de0_nano_soc_defconfig
@@ -57,7 +57,6 @@
 CONFIG_SYS_I2C_DW=y
 CONFIG_SYS_MMC_MAX_BLK_COUNT=256
 CONFIG_MMC_DW=y
-CONFIG_MTD=y
 CONFIG_SPI_FLASH_MTD=y
 CONFIG_PHY_MICREL=y
 CONFIG_PHY_MICREL_KSZ90X1=y
diff --git a/configs/socfpga_de10_nano_defconfig b/configs/socfpga_de10_nano_defconfig
index 3ae28e7..d71074e 100644
--- a/configs/socfpga_de10_nano_defconfig
+++ b/configs/socfpga_de10_nano_defconfig
@@ -54,7 +54,6 @@
 CONFIG_SYS_I2C_DW=y
 CONFIG_SYS_MMC_MAX_BLK_COUNT=256
 CONFIG_MMC_DW=y
-CONFIG_MTD=y
 CONFIG_SPI_FLASH_MTD=y
 CONFIG_PHY_MICREL=y
 CONFIG_PHY_MICREL_KSZ90X1=y
diff --git a/configs/socfpga_de10_standard_defconfig b/configs/socfpga_de10_standard_defconfig
index f3d86bc..9c5780e 100644
--- a/configs/socfpga_de10_standard_defconfig
+++ b/configs/socfpga_de10_standard_defconfig
@@ -54,7 +54,6 @@
 CONFIG_SYS_I2C_DW=y
 CONFIG_SYS_MMC_MAX_BLK_COUNT=256
 CONFIG_MMC_DW=y
-CONFIG_MTD=y
 CONFIG_SPI_FLASH_MTD=y
 CONFIG_PHY_MICREL=y
 CONFIG_PHY_MICREL_KSZ90X1=y
diff --git a/configs/socfpga_de1_soc_defconfig b/configs/socfpga_de1_soc_defconfig
index cc3038e..a7e5276 100644
--- a/configs/socfpga_de1_soc_defconfig
+++ b/configs/socfpga_de1_soc_defconfig
@@ -51,7 +51,6 @@
 CONFIG_SYS_I2C_DW=y
 CONFIG_SYS_MMC_MAX_BLK_COUNT=256
 CONFIG_MMC_DW=y
-CONFIG_MTD=y
 CONFIG_PHY_MICREL=y
 CONFIG_PHY_MICREL_KSZ90X1=y
 CONFIG_ETH_DESIGNWARE=y
diff --git a/configs/socfpga_is1_defconfig b/configs/socfpga_is1_defconfig
index 0551852..844f660 100644
--- a/configs/socfpga_is1_defconfig
+++ b/configs/socfpga_is1_defconfig
@@ -59,7 +59,6 @@
 CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_DW=y
 # CONFIG_MMC is not set
-CONFIG_MTD=y
 CONFIG_SPI_FLASH_STMICRO=y
 CONFIG_SPI_FLASH_MTD=y
 CONFIG_PHY_MICREL=y
diff --git a/configs/socfpga_mcvevk_defconfig b/configs/socfpga_mcvevk_defconfig
index 23ea23d..e5e1936 100644
--- a/configs/socfpga_mcvevk_defconfig
+++ b/configs/socfpga_mcvevk_defconfig
@@ -57,7 +57,6 @@
 CONFIG_SYS_I2C_DW=y
 CONFIG_SYS_MMC_MAX_BLK_COUNT=256
 CONFIG_MMC_DW=y
-CONFIG_MTD=y
 CONFIG_SPI_FLASH_MTD=y
 CONFIG_PHY_GIGE=y
 CONFIG_ETH_DESIGNWARE=y
diff --git a/configs/socfpga_n5x_atf_defconfig b/configs/socfpga_n5x_atf_defconfig
index 5856fc7..05b7604 100644
--- a/configs/socfpga_n5x_atf_defconfig
+++ b/configs/socfpga_n5x_atf_defconfig
@@ -72,7 +72,6 @@
 CONFIG_SYS_I2C_DW=y
 CONFIG_SYS_MMC_MAX_BLK_COUNT=256
 CONFIG_MMC_DW=y
-CONFIG_MTD=y
 CONFIG_SPI_FLASH_SPANSION=y
 CONFIG_SPI_FLASH_STMICRO=y
 CONFIG_PHY_MICREL=y
diff --git a/configs/socfpga_n5x_defconfig b/configs/socfpga_n5x_defconfig
index e6e9940..0cb8592 100644
--- a/configs/socfpga_n5x_defconfig
+++ b/configs/socfpga_n5x_defconfig
@@ -56,6 +56,7 @@
 CONFIG_CMD_EXT4=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
+# CONFIG_CMD_MTDPARTS is not set
 CONFIG_ENV_IS_IN_MMC=y
 CONFIG_USE_BOOTFILE=y
 CONFIG_BOOTFILE="Image"
diff --git a/configs/socfpga_n5x_vab_defconfig b/configs/socfpga_n5x_vab_defconfig
index 4511962..dd33210 100644
--- a/configs/socfpga_n5x_vab_defconfig
+++ b/configs/socfpga_n5x_vab_defconfig
@@ -73,7 +73,6 @@
 CONFIG_SYS_I2C_DW=y
 CONFIG_SYS_MMC_MAX_BLK_COUNT=256
 CONFIG_MMC_DW=y
-CONFIG_MTD=y
 CONFIG_SPI_FLASH_SPANSION=y
 CONFIG_SPI_FLASH_STMICRO=y
 CONFIG_PHY_MICREL=y
diff --git a/configs/socfpga_secu1_defconfig b/configs/socfpga_secu1_defconfig
index 67513d3..d9ac720 100644
--- a/configs/socfpga_secu1_defconfig
+++ b/configs/socfpga_secu1_defconfig
@@ -86,7 +86,6 @@
 CONFIG_SYS_I2C_EEPROM_ADDR=0x50
 CONFIG_SYS_MMC_MAX_BLK_COUNT=256
 CONFIG_MMC_DW=y
-CONFIG_MTD=y
 CONFIG_DM_MTD=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_SYS_NAND_USE_FLASH_BBT=y
diff --git a/configs/socfpga_sockit_defconfig b/configs/socfpga_sockit_defconfig
index 33b0c79..26547cb 100644
--- a/configs/socfpga_sockit_defconfig
+++ b/configs/socfpga_sockit_defconfig
@@ -57,7 +57,6 @@
 CONFIG_SYS_I2C_DW=y
 CONFIG_SYS_MMC_MAX_BLK_COUNT=256
 CONFIG_MMC_DW=y
-CONFIG_MTD=y
 CONFIG_SPI_FLASH_MACRONIX=y
 CONFIG_SPI_FLASH_SPANSION=y
 CONFIG_SPI_FLASH_STMICRO=y
diff --git a/configs/socfpga_socrates_defconfig b/configs/socfpga_socrates_defconfig
index 9f5dc70..24d56cb 100644
--- a/configs/socfpga_socrates_defconfig
+++ b/configs/socfpga_socrates_defconfig
@@ -57,7 +57,6 @@
 CONFIG_SYS_I2C_DW=y
 CONFIG_SYS_MMC_MAX_BLK_COUNT=256
 CONFIG_MMC_DW=y
-CONFIG_MTD=y
 CONFIG_SPI_FLASH_MACRONIX=y
 CONFIG_SPI_FLASH_SPANSION=y
 CONFIG_SPI_FLASH_STMICRO=y
diff --git a/configs/socfpga_sr1500_defconfig b/configs/socfpga_sr1500_defconfig
index dc88606..325dfc5 100644
--- a/configs/socfpga_sr1500_defconfig
+++ b/configs/socfpga_sr1500_defconfig
@@ -65,7 +65,6 @@
 CONFIG_SYS_I2C_DW=y
 CONFIG_SYS_MMC_MAX_BLK_COUNT=256
 CONFIG_MMC_DW=y
-CONFIG_MTD=y
 CONFIG_SPI_FLASH_STMICRO=y
 # CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
 CONFIG_SPI_FLASH_MTD=y
diff --git a/configs/socfpga_stratix10_atf_defconfig b/configs/socfpga_stratix10_atf_defconfig
index 404b0d8..6166a5d 100644
--- a/configs/socfpga_stratix10_atf_defconfig
+++ b/configs/socfpga_stratix10_atf_defconfig
@@ -74,7 +74,6 @@
 CONFIG_SYS_I2C_DW=y
 CONFIG_SYS_MMC_MAX_BLK_COUNT=256
 CONFIG_MMC_DW=y
-CONFIG_MTD=y
 CONFIG_SPI_FLASH_SPANSION=y
 CONFIG_SPI_FLASH_STMICRO=y
 CONFIG_PHY_MICREL=y
diff --git a/configs/socfpga_stratix10_defconfig b/configs/socfpga_stratix10_defconfig
index 811183b..2c38006 100644
--- a/configs/socfpga_stratix10_defconfig
+++ b/configs/socfpga_stratix10_defconfig
@@ -73,7 +73,6 @@
 CONFIG_SYS_I2C_DW=y
 CONFIG_SYS_MMC_MAX_BLK_COUNT=256
 CONFIG_MMC_DW=y
-CONFIG_MTD=y
 CONFIG_SPI_FLASH_SPANSION=y
 CONFIG_SPI_FLASH_STMICRO=y
 CONFIG_PHY_MICREL=y
diff --git a/configs/socfpga_vining_fpga_defconfig b/configs/socfpga_vining_fpga_defconfig
index 0edab55..e5f7283 100644
--- a/configs/socfpga_vining_fpga_defconfig
+++ b/configs/socfpga_vining_fpga_defconfig
@@ -94,7 +94,6 @@
 CONFIG_SYS_I2C_EEPROM_ADDR=0x50
 CONFIG_SYS_MMC_MAX_BLK_COUNT=256
 CONFIG_MMC_DW=y
-CONFIG_MTD=y
 CONFIG_SPI_FLASH_SFDP_SUPPORT=y
 CONFIG_SPI_FLASH_SPANSION=y
 CONFIG_SPI_FLASH_STMICRO=y
diff --git a/configs/sopine_baseboard_defconfig b/configs/sopine_baseboard_defconfig
index d9b0eb3..6d9d71f 100644
--- a/configs/sopine_baseboard_defconfig
+++ b/configs/sopine_baseboard_defconfig
@@ -10,6 +10,7 @@
 CONFIG_SPL_SPI_SUNXI=y
 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
 CONFIG_SUPPORT_EMMC_BOOT=y
+CONFIG_MTD=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_SUN8I_EMAC=y
 CONFIG_SPI=y
diff --git a/configs/spring_defconfig b/configs/spring_defconfig
index 5e791b7..2bd45cb 100644
--- a/configs/spring_defconfig
+++ b/configs/spring_defconfig
@@ -63,7 +63,6 @@
 CONFIG_MMC_DW=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_S5P=y
-CONFIG_MTD=y
 CONFIG_SPI_FLASH_GIGADEVICE=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_SMC911X=y
diff --git a/configs/starfive_visionfive2_defconfig b/configs/starfive_visionfive2_defconfig
index 1b7d57b..c68f3c2 100644
--- a/configs/starfive_visionfive2_defconfig
+++ b/configs/starfive_visionfive2_defconfig
@@ -77,7 +77,6 @@
 CONFIG_CMD_BOOTSTAGE=y
 CONFIG_OF_BOARD=y
 CONFIG_ENV_OVERWRITE=y
-CONFIG_ENV_IS_NOWHERE=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
 CONFIG_ENV_SECT_SIZE_AUTO=y
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
diff --git a/configs/stm32f429-discovery_defconfig b/configs/stm32f429-discovery_defconfig
index aae6ceb..5d59edb 100644
--- a/configs/stm32f429-discovery_defconfig
+++ b/configs/stm32f429-discovery_defconfig
@@ -29,6 +29,7 @@
 CONFIG_ENV_IS_IN_FLASH=y
 # CONFIG_NET is not set
 # CONFIG_MMC is not set
+CONFIG_MTD=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_STM32_FLASH=y
 CONFIG_SYS_MAX_FLASH_SECT=12
diff --git a/configs/stm32f429-evaluation_defconfig b/configs/stm32f429-evaluation_defconfig
index 75f6a4d..3e220d7 100644
--- a/configs/stm32f429-evaluation_defconfig
+++ b/configs/stm32f429-evaluation_defconfig
@@ -27,6 +27,7 @@
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 # CONFIG_NET is not set
 CONFIG_ARM_PL180_MMCI=y
+CONFIG_MTD=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_STM32_FLASH=y
 CONFIG_SYS_MAX_FLASH_SECT=12
diff --git a/configs/taurus_defconfig b/configs/taurus_defconfig
index 8f87428..8679b90 100644
--- a/configs/taurus_defconfig
+++ b/configs/taurus_defconfig
@@ -89,7 +89,6 @@
 CONFIG_SYS_DFU_DATA_BUF_SIZE=0x100000
 CONFIG_AT91_GPIO=y
 # CONFIG_MMC is not set
-CONFIG_MTD=y
 # CONFIG_SYS_NAND_USE_FLASH_BBT is not set
 CONFIG_NAND_ATMEL=y
 CONFIG_SYS_NAND_BLOCK_SIZE=0x20000
diff --git a/configs/tec_defconfig b/configs/tec_defconfig
index 61b9b59..4dba106 100644
--- a/configs/tec_defconfig
+++ b/configs/tec_defconfig
@@ -39,7 +39,6 @@
 CONFIG_ENV_OVERWRITE=y
 CONFIG_ENV_IS_IN_NAND=y
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
-CONFIG_MTD=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_TEGRA_NAND=y
 CONFIG_SYS_NAND_ONFI_DETECTION=y
diff --git a/configs/tinker-rk3288_defconfig b/configs/tinker-rk3288_defconfig
index 5059c17..edb6294 100644
--- a/configs/tinker-rk3288_defconfig
+++ b/configs/tinker-rk3288_defconfig
@@ -68,7 +68,6 @@
 CONFIG_I2C_EEPROM=y
 CONFIG_MMC_DW=y
 CONFIG_MMC_DW_ROCKCHIP=y
-CONFIG_MTD=y
 CONFIG_ETH_DESIGNWARE=y
 CONFIG_GMAC_ROCKCHIP=y
 CONFIG_PINCTRL=y
diff --git a/configs/transpeed-8k618-t_defconfig b/configs/transpeed-8k618-t_defconfig
new file mode 100644
index 0000000..020d397
--- /dev/null
+++ b/configs/transpeed-8k618-t_defconfig
@@ -0,0 +1,27 @@
+CONFIG_ARM=y
+CONFIG_ARCH_SUNXI=y
+CONFIG_DEFAULT_DEVICE_TREE="sun50i-h618-transpeed-8k618-t"
+CONFIG_SPL=y
+CONFIG_DRAM_SUN50I_H616_DX_ODT=0x03030303
+CONFIG_DRAM_SUN50I_H616_DX_DRI=0x0e0e0e0e
+CONFIG_DRAM_SUN50I_H616_CA_DRI=0x1f12
+CONFIG_DRAM_SUN50I_H616_TPR0=0xc0001002
+CONFIG_DRAM_SUN50I_H616_TPR10=0x2f1107
+CONFIG_DRAM_SUN50I_H616_TPR11=0xddddcccc
+CONFIG_DRAM_SUN50I_H616_TPR12=0xeddc7665
+CONFIG_MACH_SUN50I_H616=y
+CONFIG_SUNXI_DRAM_H616_DDR3_1333=y
+CONFIG_DRAM_CLK=648
+CONFIG_MMC_SUNXI_SLOT_EXTRA=2
+CONFIG_R_I2C_ENABLE=y
+# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+CONFIG_SPL_I2C=y
+CONFIG_SPL_SYS_I2C_LEGACY=y
+CONFIG_SYS_I2C_MVTWSI=y
+CONFIG_SYS_I2C_SLAVE=0x7f
+CONFIG_SYS_I2C_SPEED=400000
+CONFIG_SUPPORT_EMMC_BOOT=y
+CONFIG_AXP313_POWER=y
+CONFIG_AXP_DCDC3_VOLT=1360
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_OHCI_HCD=y
diff --git a/configs/trats2_defconfig b/configs/trats2_defconfig
index e663aea..6756136 100644
--- a/configs/trats2_defconfig
+++ b/configs/trats2_defconfig
@@ -52,7 +52,6 @@
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_SDMA=y
 CONFIG_MMC_SDHCI_S5P=y
-CONFIG_MTD=y
 CONFIG_DM_PMIC=y
 CONFIG_DM_PMIC_MAX77686=y
 CONFIG_DM_REGULATOR=y
diff --git a/configs/trats_defconfig b/configs/trats_defconfig
index 1ceea53..9892524 100644
--- a/configs/trats_defconfig
+++ b/configs/trats_defconfig
@@ -51,7 +51,6 @@
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_SDMA=y
 CONFIG_MMC_SDHCI_S5P=y
-CONFIG_MTD=y
 CONFIG_DM_PMIC=y
 CONFIG_PMIC_MAX8997=y
 CONFIG_USB=y
diff --git a/configs/turris_mox_defconfig b/configs/turris_mox_defconfig
index a6fbc79..a6f3fc9 100644
--- a/configs/turris_mox_defconfig
+++ b/configs/turris_mox_defconfig
@@ -74,7 +74,6 @@
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_SDMA=y
 CONFIG_MMC_SDHCI_XENON=y
-CONFIG_MTD=y
 CONFIG_DM_MTD=y
 CONFIG_SPI_FLASH_MACRONIX=y
 CONFIG_SPI_FLASH_SPANSION=y
diff --git a/configs/turris_omnia_defconfig b/configs/turris_omnia_defconfig
index 5f9a058..f045dd7 100644
--- a/configs/turris_omnia_defconfig
+++ b/configs/turris_omnia_defconfig
@@ -88,7 +88,6 @@
 CONFIG_DM_PCA953X=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_MV=y
-CONFIG_MTD=y
 CONFIG_DM_MTD=y
 CONFIG_SPI_FLASH_MACRONIX=y
 CONFIG_SPI_FLASH_SPANSION=y
diff --git a/configs/uDPU_defconfig b/configs/uDPU_defconfig
index 6395609..bb1c6ef 100644
--- a/configs/uDPU_defconfig
+++ b/configs/uDPU_defconfig
@@ -60,7 +60,6 @@
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_SDMA=y
 CONFIG_MMC_SDHCI_XENON=y
-CONFIG_MTD=y
 CONFIG_DM_MTD=y
 CONFIG_SPI_FLASH_SFDP_SUPPORT=y
 CONFIG_SPI_FLASH_MACRONIX=y
diff --git a/configs/vocore2_defconfig b/configs/vocore2_defconfig
index 966ae69..0e07d04 100644
--- a/configs/vocore2_defconfig
+++ b/configs/vocore2_defconfig
@@ -85,7 +85,6 @@
 CONFIG_MMC=y
 # CONFIG_MMC_HW_PARTITIONING is not set
 CONFIG_MMC_MTK=y
-CONFIG_MTD=y
 CONFIG_SPI_FLASH_SFDP_SUPPORT=y
 CONFIG_SPI_FLASH_GIGADEVICE=y
 CONFIG_SPI_FLASH_MACRONIX=y
diff --git a/configs/vyasa-rk3288_defconfig b/configs/vyasa-rk3288_defconfig
index 516cf04..02f2d74 100644
--- a/configs/vyasa-rk3288_defconfig
+++ b/configs/vyasa-rk3288_defconfig
@@ -70,7 +70,6 @@
 CONFIG_LED_GPIO=y
 CONFIG_MMC_DW=y
 CONFIG_MMC_DW_ROCKCHIP=y
-CONFIG_MTD=y
 CONFIG_ETH_DESIGNWARE=y
 CONFIG_GMAC_ROCKCHIP=y
 CONFIG_PINCTRL=y
diff --git a/configs/wandboard_defconfig b/configs/wandboard_defconfig
index 168e2f0..e9deab3 100644
--- a/configs/wandboard_defconfig
+++ b/configs/wandboard_defconfig
@@ -75,6 +75,8 @@
 CONFIG_SCSI=y
 CONFIG_DM_SERIAL=y
 CONFIG_MXC_UART=y
+CONFIG_SYSRESET=y
+CONFIG_SYSRESET_WATCHDOG=y
 CONFIG_DM_THERMAL=y
 CONFIG_USB=y
 CONFIG_VIDEO=y
@@ -88,3 +90,4 @@
 CONFIG_SPLASH_SCREEN=y
 CONFIG_SPLASH_SCREEN_ALIGN=y
 CONFIG_BMP_16BPP=y
+CONFIG_IMX_WATCHDOG=y
diff --git a/configs/x240_defconfig b/configs/x240_defconfig
index 152413d..fc0c9a7 100644
--- a/configs/x240_defconfig
+++ b/configs/x240_defconfig
@@ -50,7 +50,6 @@
 CONFIG_LED_GPIO=y
 CONFIG_MISC=y
 # CONFIG_MMC is not set
-CONFIG_MTD=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_NAND_PXA3XX=y
 CONFIG_SYS_NAND_ONFI_DETECTION=y
diff --git a/configs/x530_defconfig b/configs/x530_defconfig
index 11210ba..207748e 100644
--- a/configs/x530_defconfig
+++ b/configs/x530_defconfig
@@ -71,7 +71,6 @@
 CONFIG_I2C_MUX=y
 CONFIG_I2C_MUX_PCA954x=y
 # CONFIG_MMC is not set
-CONFIG_MTD=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_SYS_NAND_USE_FLASH_BBT=y
 CONFIG_NAND_PXA3XX=y
diff --git a/configs/xilinx_versal_mini_ospi_defconfig b/configs/xilinx_versal_mini_ospi_defconfig
index 96be5b9..72a123d 100644
--- a/configs/xilinx_versal_mini_ospi_defconfig
+++ b/configs/xilinx_versal_mini_ospi_defconfig
@@ -53,6 +53,7 @@
 # CONFIG_NET is not set
 # CONFIG_DM_DEVICE_REMOVE is not set
 # CONFIG_MMC is not set
+CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH_SOFT_RESET=y
 CONFIG_SPI_FLASH_SOFT_RESET_ON_BOOT=y
diff --git a/configs/xilinx_versal_mini_qspi_defconfig b/configs/xilinx_versal_mini_qspi_defconfig
index 7181b89..d9fbac9 100644
--- a/configs/xilinx_versal_mini_qspi_defconfig
+++ b/configs/xilinx_versal_mini_qspi_defconfig
@@ -58,6 +58,7 @@
 # CONFIG_I2C is not set
 # CONFIG_INPUT is not set
 # CONFIG_MMC is not set
+CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
 # CONFIG_SPI_FLASH_SMART_HWCAPS is not set
 # CONFIG_SPI_FLASH_LOCK is not set
diff --git a/configs/xilinx_versal_net_mini_ospi_defconfig b/configs/xilinx_versal_net_mini_ospi_defconfig
index 1ba6e08..5f42243 100644
--- a/configs/xilinx_versal_net_mini_ospi_defconfig
+++ b/configs/xilinx_versal_net_mini_ospi_defconfig
@@ -52,6 +52,7 @@
 # CONFIG_NET is not set
 # CONFIG_DM_DEVICE_REMOVE is not set
 # CONFIG_MMC is not set
+CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH_SOFT_RESET=y
 CONFIG_SPI_FLASH_SOFT_RESET_ON_BOOT=y
diff --git a/configs/xilinx_versal_net_mini_qspi_defconfig b/configs/xilinx_versal_net_mini_qspi_defconfig
index c9497bb..4fa83fa 100644
--- a/configs/xilinx_versal_net_mini_qspi_defconfig
+++ b/configs/xilinx_versal_net_mini_qspi_defconfig
@@ -57,6 +57,7 @@
 # CONFIG_I2C is not set
 # CONFIG_INPUT is not set
 # CONFIG_MMC is not set
+CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
 # CONFIG_SPI_FLASH_SMART_HWCAPS is not set
 # CONFIG_SPI_FLASH_LOCK is not set
diff --git a/configs/xilinx_zynq_virt_defconfig b/configs/xilinx_zynq_virt_defconfig
index 2a99cdb..708cfe9 100644
--- a/configs/xilinx_zynq_virt_defconfig
+++ b/configs/xilinx_zynq_virt_defconfig
@@ -110,7 +110,6 @@
 CONFIG_I2C_EEPROM=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_ZYNQ=y
-CONFIG_MTD=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_SHOW_PROGRESS=10
 CONFIG_CFI_FLASH=y
diff --git a/configs/xilinx_zynqmp_kria_defconfig b/configs/xilinx_zynqmp_kria_defconfig
index 86741f1..0dc6c5b 100644
--- a/configs/xilinx_zynqmp_kria_defconfig
+++ b/configs/xilinx_zynqmp_kria_defconfig
@@ -155,7 +155,6 @@
 CONFIG_MMC_HS200_SUPPORT=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_ZYNQ=y
-CONFIG_MTD=y
 CONFIG_DM_MTD=y
 CONFIG_SPI_FLASH_BAR=y
 CONFIG_SPI_FLASH_STMICRO=y
diff --git a/configs/xilinx_zynqmp_mini_nand_defconfig b/configs/xilinx_zynqmp_mini_nand_defconfig
index 8bf30ed..670add9 100644
--- a/configs/xilinx_zynqmp_mini_nand_defconfig
+++ b/configs/xilinx_zynqmp_mini_nand_defconfig
@@ -54,7 +54,6 @@
 # CONFIG_DM_DEVICE_REMOVE is not set
 # CONFIG_DM_MAILBOX is not set
 # CONFIG_MMC is not set
-CONFIG_MTD=y
 CONFIG_DM_MTD=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_NAND_ARASAN=y
diff --git a/configs/xilinx_zynqmp_mini_nand_single_defconfig b/configs/xilinx_zynqmp_mini_nand_single_defconfig
index a2984ae..7763050 100644
--- a/configs/xilinx_zynqmp_mini_nand_single_defconfig
+++ b/configs/xilinx_zynqmp_mini_nand_single_defconfig
@@ -54,7 +54,6 @@
 # CONFIG_DM_DEVICE_REMOVE is not set
 # CONFIG_DM_MAILBOX is not set
 # CONFIG_MMC is not set
-CONFIG_MTD=y
 CONFIG_DM_MTD=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_NAND_ARASAN=y
diff --git a/configs/xilinx_zynqmp_virt_defconfig b/configs/xilinx_zynqmp_virt_defconfig
index 8ac37cc..2742e38 100644
--- a/configs/xilinx_zynqmp_virt_defconfig
+++ b/configs/xilinx_zynqmp_virt_defconfig
@@ -159,7 +159,6 @@
 CONFIG_MMC_HS200_SUPPORT=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_ZYNQ=y
-CONFIG_MTD=y
 CONFIG_DM_MTD=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_NAND_ARASAN=y
diff --git a/configs/xtfpga_defconfig b/configs/xtfpga_defconfig
index 2e742c2..b96dc10 100644
--- a/configs/xtfpga_defconfig
+++ b/configs/xtfpga_defconfig
@@ -35,6 +35,7 @@
 # CONFIG_DM_DEVICE_REMOVE is not set
 # CONFIG_DM_STDIO is not set
 # CONFIG_DM_SEQ_ALIAS is not set
+CONFIG_MTD=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_SYS_FLASH_CFI_WIDTH_16BIT=y
diff --git a/configs/zynq_cse_nand_defconfig b/configs/zynq_cse_nand_defconfig
index f9a850a..b6b12e3 100644
--- a/configs/zynq_cse_nand_defconfig
+++ b/configs/zynq_cse_nand_defconfig
@@ -74,7 +74,6 @@
 # CONFIG_DM_DEVICE_REMOVE is not set
 CONFIG_SPL_DM_SEQ_ALIAS=y
 # CONFIG_MMC is not set
-CONFIG_MTD=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_NAND_ZYNQ=y
 CONFIG_SYS_NAND_ONFI_DETECTION=y
diff --git a/configs/zynq_cse_nor_defconfig b/configs/zynq_cse_nor_defconfig
index 0aa9a8e..d95f760 100644
--- a/configs/zynq_cse_nor_defconfig
+++ b/configs/zynq_cse_nor_defconfig
@@ -73,7 +73,6 @@
 # CONFIG_DM_DEVICE_REMOVE is not set
 CONFIG_SPL_DM_SEQ_ALIAS=y
 # CONFIG_MMC is not set
-CONFIG_MTD=y
 CONFIG_DM_MTD=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_FLASH_SHOW_PROGRESS=10
diff --git a/doc/board/index.rst b/doc/board/index.rst
index c96e5fd..d0f9f35 100644
--- a/doc/board/index.rst
+++ b/doc/board/index.rst
@@ -46,6 +46,7 @@
    sifive/index
    sipeed/index
    socionext/index
+   sophgo/index
    st/index
    starfive/index
    ste/index
diff --git a/doc/board/sophgo/index.rst b/doc/board/sophgo/index.rst
new file mode 100644
index 0000000..e097afd
--- /dev/null
+++ b/doc/board/sophgo/index.rst
@@ -0,0 +1,8 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+Sophgo
+======
+.. toctree::
+   :maxdepth: 1
+
+   milkv_duo
diff --git a/doc/board/sophgo/milkv_duo.rst b/doc/board/sophgo/milkv_duo.rst
new file mode 100644
index 0000000..cb2ed1a
--- /dev/null
+++ b/doc/board/sophgo/milkv_duo.rst
@@ -0,0 +1,64 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+Milk-V Duo
+==========
+
+CV1800B RISC-V SoC
+------------------
+The CV1800B is a high-performance, low-power 1+1 64-bit RISC-V SoC from Sophgo.
+
+Mainline support
+----------------
+The support for following drivers are already enabled:
+1. ns16550 UART Driver.
+
+Building
+~~~~~~~~
+1. Add the RISC-V toolchain to your PATH.
+2. Setup ARCH & cross compilation environment variable:
+
+.. code-block:: console
+
+   export CROSS_COMPILE=<riscv64 toolchain prefix>
+   cd <U-Boot-dir>
+   make milkv_duo_defconfig
+   make
+
+This will generate u-boot-dtb.bin
+
+Booting
+~~~~~~~
+Currently, we rely on vendor FSBL(First Stage Boot Loader) to initialize the
+clock and load the u-boot image, then bootup from it.
+
+Alternatively, to run u-boot-dtb.bin on top of FSBL, follow these steps:
+
+1. Use the vendor-provided tool to create a unified fip.bin file containing
+   FSBL, OpenSBI, and U-Boot.
+
+2. Place the generated fip.bin file into the FAT partition of the SD card.
+
+3. Insert the SD card into the board and power it on.
+
+The board will automatically execute the FSBL from the fip.bin file.
+Subsequently, it will transition to OpenSBI, and finally, OpenSBI will invoke
+U-Boot.
+
+
+Sample boot log from Milk-V Duo board
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.. code-block:: none
+
+   U-Boot 2024.01-rc5-00010-g51965baa36 (Dec 28 2023 - 13:15:53 +0800)milkv_duo
+
+   DRAM:  63.3 MiB
+   Core:  10 devices, 8 uclasses, devicetree: separate
+   Loading Environment from nowhere... OK
+   In:    serial@4140000
+   Out:   serial@4140000
+   Err:   serial@4140000
+   Net:   No ethernet found.
+   milkv_duo# cpu detail
+     0: cpu@0      rv64imafdc
+      ID = 0, freq = 0 Hz: L1 cache, MMU
+   milkv_duo#
diff --git a/doc/develop/driver-model/migration.rst b/doc/develop/driver-model/migration.rst
index 03fea94..b40a6af 100644
--- a/doc/develop/driver-model/migration.rst
+++ b/doc/develop/driver-model/migration.rst
@@ -13,7 +13,7 @@
 * Status: In progress
 * Deadline: 2020.01
 
-Starting with the 2010.01 release CONFIG_DM will be enabled for all boards.
+Starting with the 2020.01 release CONFIG_DM will be enabled for all boards.
 This does not concern CONFIG_DM_SPL and CONFIG_DM_TPL. The conversion date for
 these configuration items still needs to be defined.
 
diff --git a/doc/develop/falcon.rst b/doc/develop/falcon.rst
index 8a46c0e..244b4cc 100644
--- a/doc/develop/falcon.rst
+++ b/doc/develop/falcon.rst
@@ -256,3 +256,161 @@
 Falcon Mode was presented at the RMLL 2012. Slides are available at:
 
 http://schedule2012.rmll.info/IMG/pdf/LSM2012_UbootFalconMode_Babic.pdf
+
+Falcon Mode Boot on RISC-V
+--------------------------
+
+Introduction
+~~~~~~~~~~~~
+
+In the RISC-V environment, OpenSBI is required to enable a supervisor mode
+binary to execute certain privileged operations. The typical boot sequence on
+RISC-V is SPL -> OpenSBI -> U-Boot -> Linux kernel. SPL will load and start
+the OpenSBI initializations, then OpenSBI will bring up the next image, U-Boot
+proper. The OpenSBI binary must be prepared in advance of the U-Boot build
+process and it will be packed together with U-Boot into a file called
+u-boot.itb.
+
+The Falcon Mode on RISC-V platforms is a distinct boot sequence. Borrowing
+ideas from the U-Boot Falcon Mode on ARM, it skips the U-Boot proper phase
+in the normal boot process and allows OpenSBI to load and start the Linux
+kernel. Its boot sequence is SPL -> OpenSBI -> Linux kernel. The OpenSBI
+binary and Linux kernel binary must be prepared prior to the U-Boot build
+process and they will be packed together as a FIT image named linux.itb in
+this process.
+
+CONFIG_SPL_LOAD_FIT_OPENSBI_OS_BOOT enables the Falcon Mode boot on RISC-V.
+This configuration setting tells OpenSBI that Linux kernel is its next OS
+image and makes it load and start the kernel afterwards.
+
+Note that the Falcon Mode boot bypasses a lot of initializations by U-Boot.
+If the Linux kernel expects hardware initializations by U-Boot, make sure to
+port the relevant code to the SPL build process.
+
+Configuration
+~~~~~~~~~~~~~
+
+CONFIG_SPL_LOAD_FIT_ADDRESS
+    Specifies the address to load u-boot.itb in a normal boot. When the Falcon
+    Mode boot is enabled, it specifies the load address of linux.itb.
+
+CONFIG_SYS_TEXT_BASE
+    Specifies the address of the text section for a u-boot proper in a normal
+    boot. When the Falcon Mode boot is enabled, it specifies the text section
+    address for the Linux kernel image.
+
+CONFIG_SPL_PAYLOAD_ARGS_ADDR
+    The address in the RAM to which the FDT blob is to be moved by the SPL.
+    SPL places the FDT blob right after the kernel. As the kernel does not
+    include the BSS section in its size calculation, SPL ends up placing
+    the FDT blob within the BSS section of the kernel. This may cause the
+    FDT blob to be cleared during kernel BSS initialization. To avoid the
+    issue, be sure to move the FDT blob out of the kernel first.
+
+CONFIG_SPL_LOAD_FIT_OPENSBI_OS_BOOT
+    Activates the Falcon Mode boot on RISC-V.
+
+Example for Andes AE350 Board
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A FDT blob is required to boot the Linux kernel from the SPL. Andes AE350
+platforms generally come with a builtin dtb. To load a custom DTB, follow
+these steps:
+
+1. Load the custom DTB to SDRAM::
+
+        => fatload mmc 0:1 0x20000000 user_custom.dtb
+
+2. Set the SPI speed::
+
+        => sf probe 0:0 50000000 0
+
+3. Erase sectors from the SPI Flash::
+
+        => sf erase 0xf0000 0x10000
+
+4. Write the FDT blob to the erased sectors of the Flash::
+
+        => sf write 0x20000000 0xf0000 0x10000
+
+Console Log of AE350 Falcon Mode Boot
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+        U-Boot SPL 2023.01-00031-g777ecdea66 (Oct 31 2023 - 18:41:36 +0800)
+        Trying to boot from RAM
+
+        OpenSBI v1.2-51-g7304e42
+           ____                    _____ ____ _____
+          / __ \                  / ____|  _ \_   _|
+         | |  | |_ __   ___ _ __ | (___ | |_) || |
+         | |  | | '_ \ / _ \ '_ \ \___ \|  _ < | |
+         | |__| | |_) |  __/ | | |____) | |_) || |_
+          \____/| .__/ \___|_| |_|_____/|____/_____|
+                | |
+                |_|
+
+        Platform Name             : andestech,ax25
+        Platform Features         : medeleg
+        Platform HART Count       : 1
+        Platform IPI Device       : andes_plicsw
+        Platform Timer Device     : andes_plmt @ 60000000Hz
+        Platform Console Device   : uart8250
+        Platform HSM Device       : andes_smu
+        Platform PMU Device       : andes_pmu
+        Platform Reboot Device    : atcwdt200
+        Platform Shutdown Device  : ---
+        Firmware Base             : 0x0
+        Firmware Size             : 196 KB
+        Runtime SBI Version       : 1.0
+
+        Domain0 Name              : root
+        Domain0 Boot HART         : 0
+        Domain0 HARTs             : 0*
+        Domain0 Region00          : 0x0000000000000000-0x000000000003ffff ()
+        Domain0 Region01          : 0x00000000e6000000-0x00000000e60fffff (I,R)
+        Domain0 Region02          : 0x00000000e6400000-0x00000000e67fffff (I)
+        Domain0 Region03          : 0x0000000000000000-0xffffffffffffffff (R,W,X)
+        Domain0 Next Address      : 0x0000000001800000
+        Domain0 Next Arg1         : 0x0000000001700000
+        Domain0 Next Mode         : S-mode
+        Domain0 SysReset          : yes
+
+        Boot HART ID              : 0
+        Boot HART Domain          : root
+        Boot HART Priv Version    : v1.11
+        Boot HART Base ISA        : rv64imafdcx
+        Boot HART ISA Extensions  : none
+        Boot HART PMP Count       : 8
+        Boot HART PMP Granularity : 4
+        Boot HART PMP Address Bits: 31
+        Boot HART MHPM Count      : 4
+        Boot HART MHPM Bits       : 64
+        Boot HART MIDELEG         : 0x0000000000000222
+        Boot HART MEDELEG         : 0x000000000000b109
+        [    0.000000] Linux version 6.1.47-09019-g0584b09ad862-dirty
+        [    0.000000] OF: fdt: Ignoring memory range 0x0 - 0x1800000
+        [    0.000000] Machine model: andestech,ax25
+        [    0.000000] earlycon: sbi0 at I/O port 0x0 (options '')
+        [    0.000000] printk: bootconsole [sbi0] enabled
+        [    0.000000] Disabled 4-level and 5-level paging
+        [    0.000000] efi: UEFI not found.
+        [    0.000000] Zone ranges:
+        [    0.000000]   DMA32    [mem 0x0000000001800000-0x000000003fffffff]
+        [    0.000000]   Normal   empty
+        [    0.000000] Movable zone start for each node
+        [    0.000000] Early memory node ranges
+        [    0.000000]   node   0: [mem 0x0000000001800000-0x000000003fffffff]
+        [    0.000000] Initmem setup node 0 [mem 0x0000000001800000-0x000000003fffffff]
+        [    0.000000] SBI specification v1.0 detected
+        [    0.000000] SBI implementation ID=0x1 Version=0x10002
+        [    0.000000] SBI TIME extension detected
+        [    0.000000] SBI IPI extension detected
+        [    0.000000] SBI RFENCE extension detected
+        [    0.000000] SBI SRST extension detected
+        [    0.000000] SBI HSM extension detected
+        [    0.000000] riscv: base ISA extensions acim
+        [    0.000000] riscv: ELF capabilities acim
+        [    0.000000] percpu: Embedded 18 pages/cpu s35000 r8192 d30536 u73728
+        [    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 252500
diff --git a/doc/develop/release_cycle.rst b/doc/develop/release_cycle.rst
index 2773313..4f18623 100644
--- a/doc/develop/release_cycle.rst
+++ b/doc/develop/release_cycle.rst
@@ -50,8 +50,7 @@
 
 * U-Boot v2024.01 was released on Mon 08 January 2024.
 
-* The Merge Window for the next release (v2024.04) is **open** until the -rc1
-  release on Mon 29 January 2024.
+* The Merge Window for the next release (v2024.04) is **closed**.
 
 * The next branch is now **closed**.
 
@@ -63,9 +62,9 @@
 .. The following commented out dates are for when release candidates are
    planned to be tagged.
 
-.. For the next scheduled release, release candidates were made on::
+For the next scheduled release, release candidates were made on::
 
-.. * U-Boot v2024.01-rc1 was released on Mon 29 January 2024.
+* U-Boot v2024.01-rc1 was released on Mon 29 January 2024.
 
 .. * U-Boot v2024.01-rc2 was released on Mon 12 February 2024.
 
diff --git a/doc/develop/spl.rst b/doc/develop/spl.rst
index 76e87f0..0a3e572 100644
--- a/doc/develop/spl.rst
+++ b/doc/develop/spl.rst
@@ -65,6 +65,15 @@
 CONFIG_SPL_SPI_LOAD (drivers/mtd/spi/spi_spl_load.o)
 CONFIG_SPL_RAM_DEVICE (common/spl/spl.c)
 CONFIG_SPL_WATCHDOG (drivers/watchdog/libwatchdog.o)
+CONFIG_SPL_SYSCON (drivers/core/syscon-uclass.o)
+CONFIG_SPL_GZIP (lib/gzip.o)
+CONFIG_SPL_VIDEO (drivers/video/video-uclass.o drivers/video/vidconsole-uclass.o)
+CONFIG_SPL_SPLASH_SCREEN (common/splash.o)
+CONFIG_SPL_SPLASH_SOURCE (common/splash_source.o)
+CONFIG_SPL_GPIO (drivers/gpio)
+CONFIG_SPL_DM_GPIO (drivers/gpio/gpio-uclass.o)
+CONFIG_SPL_BMP (drivers/video/bmp.o)
+CONFIG_SPL_BLOBLIST (common/bloblist.o)
 
 Adding SPL-specific code
 ------------------------
@@ -164,3 +173,31 @@
 the config files and picks functions based on #ifdef.  Parsing the '.i'
 files instead introduces another set of headaches.  These warnings are
 not usually important to understanding the flow, however.
+
+
+Reserving memory in SPL
+-----------------------
+
+If memory needs to be reserved in RAM during SPL stage with the requirement that
+the SPL reserved memory remains preserved across further boot stages too
+then it needs to be reserved mandatorily starting from end of RAM. This is to
+ensure that further stages can simply skip this region before carrying out
+further reservations or updating the relocation address.
+
+Also out of these regions which are to be preserved across further stages of
+boot, video framebuffer memory region must be reserved first starting from
+end of RAM for which helper function spl_reserve_video_from_ram_top is provided
+which makes sure that video memory is placed at top of reservation area with
+further reservations below it.
+
+The corresponding information of reservation for those regions can be passed to
+further boot stages using a bloblist. For e.g. the information for
+framebuffer area reserved by SPL can be passed onto U-boot using
+BLOBLISTT_U_BOOT_VIDEO.
+
+The further boot stages need to parse each of the bloblist passed from SPL stage
+starting from video bloblist and skip this whole SPL reserved memory area from
+end of RAM as per the bloblists received, before carrying out further
+reservations or updating the relocation address. For e.g, U-boot proper uses
+function "setup_relocaddr_from_bloblist" to parse the bloblists passed from
+previous stage and skip the memory reserved from previous stage accordingly.
diff --git a/doc/develop/uefi/uefi.rst b/doc/develop/uefi/uefi.rst
index 6bc9d92..0389b26 100644
--- a/doc/develop/uefi/uefi.rst
+++ b/doc/develop/uefi/uefi.rst
@@ -193,7 +193,7 @@
 .. code-block:: bash
 
     cd <U-Boot source directory>
-    pytest.py test/py/tests/test_efi_secboot/test_signed.py --bd sandbox
+    pytest test/py/tests/test_efi_secboot/test_signed.py --bd sandbox
 
 UEFI binaries may be signed by Microsoft using the following certificates:
 
@@ -830,7 +830,7 @@
 controller refers to the device for which the driver is installed.
 
 The relevant drivers are identified using the EFI_DRIVER_BINDING_PROTOCOL. This
-protocol has has three functions:
+protocol has three functions:
 
 * supported - determines if the driver is compatible with the device
 * start - installs the driver by opening the relevant protocol with
diff --git a/doc/usage/cmd/smbios.rst b/doc/usage/cmd/smbios.rst
new file mode 100644
index 0000000..1ffd706
--- /dev/null
+++ b/doc/usage/cmd/smbios.rst
@@ -0,0 +1,93 @@
+.. SPDX-License-Identifier: GPL-2.0-or-later:
+
+smbios command
+==============
+
+Synopsis
+--------
+
+::
+
+        smbios
+
+Description
+-----------
+
+The smbios command displays information from the SMBIOS tables.
+
+Examples
+--------
+
+The example below shows an example output of the smbios command.
+
+::
+
+    => smbios
+    SMBIOS 2.8.0 present.
+    8 structures occupying 81 bytes
+    Table at 0x6d35018
+
+    Handle 0x0100, DMI type 1, 27 bytes at 0x6d35018
+    System Information
+        Manufacturer: QEMU
+        Product Name: Standard PC (i440FX + PIIX, 1996)
+        Version: pc-i440fx-2.5
+        Serial Number:
+        UUID 00000000-0000-0000-0000-000000000000
+        Wake Up Type:
+        Serial Number:
+        SKU Number:
+
+    Handle 0x0300, DMI type 3, 22 bytes at 0x6d35069
+    Header and Data:
+        00000000: 03 16 00 03 01 01 02 00 00 03 03 03 02 00 00 00
+        00000010: 00 00 00 00 00 00
+    Strings:
+        String 1: QEMU
+        String 2: pc-i440fx-2.5
+
+    Handle 0x0400, DMI type 4, 42 bytes at 0x6d35093
+    Header and Data:
+        00000000: 04 2a 00 04 01 03 01 02 63 06 00 00 fd ab 81 07
+        00000010: 03 00 00 00 d0 07 d0 07 41 01 ff ff ff ff ff ff
+        00000020: 00 00 00 01 01 01 02 00 01 00
+    Strings:
+        String 1: CPU 0
+        String 2: QEMU
+        String 3: pc-i440fx-2.5
+
+    Handle 0x1000, DMI type 16, 23 bytes at 0x6d350d7
+    Header and Data:
+        00000000: 10 17 00 10 01 03 06 00 00 02 00 fe ff 01 00 00
+        00000010: 00 00 00 00 00 00 00
+
+    Handle 0x1100, DMI type 17, 40 bytes at 0x6d350f0
+    Header and Data:
+        00000000: 11 28 00 11 00 10 fe ff ff ff ff ff 80 00 09 00
+        00000010: 01 00 07 02 00 00 00 02 00 00 00 00 00 00 00 00
+        00000020: 00 00 00 00 00 00 00 00
+    Strings:
+        String 1: DIMM 0
+        String 2: QEMU
+
+    Handle 0x1300, DMI type 19, 31 bytes at 0x6d35125
+    Header and Data:
+        00000000: 13 1f 00 13 00 00 00 00 ff ff 01 00 00 10 01 00
+        00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
+    Handle 0x2000, DMI type 32, 11 bytes at 0x6d35146
+    Header and Data:
+        00000000: 20 0b 00 20 00 00 00 00 00 00 00
+
+    Handle 0x7f00, DMI type 127, 4 bytes at 0x6d35153
+    End Of Table
+
+Configuration
+-------------
+
+The command is only available if CONFIG_CMD_SMBIOS=y.
+
+Return value
+------------
+
+The return value $? is 0 (true) on success, 1 (false) otherwise.
diff --git a/doc/usage/index.rst b/doc/usage/index.rst
index c171c02..0d174ee 100644
--- a/doc/usage/index.rst
+++ b/doc/usage/index.rst
@@ -103,6 +103,7 @@
    cmd/size
    cmd/sleep
    cmd/sm
+   cmd/smbios
    cmd/sound
    cmd/source
    cmd/temperature
diff --git a/drivers/clk/altera/clk-mem-n5x.h b/drivers/clk/altera/clk-mem-n5x.h
index 7b68701..c6bc44b 100644
--- a/drivers/clk/altera/clk-mem-n5x.h
+++ b/drivers/clk/altera/clk-mem-n5x.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
 /*
- * Copyright (C) 2020-2022 Intel Corporation <www.intel.com>
+ * Copyright (C) 2020-2023 Intel Corporation <www.intel.com>
  */
 
 #ifndef	_CLK_MEM_N5X_
@@ -77,7 +77,7 @@
 #define MEMCLKMGR_PLLOUTDIV_C0CNT_MASK			GENMASK(4, 0)
 #define MEMCLKMGR_PLLOUTDIV_C0CNT_OFFSET		0
 
-#define MEMCLKMGR_EXTCNTRST_C0CNTRST			BIT(7)
+#define MEMCLKMGR_EXTCNTRST_C0CNTRST			BIT(0)
 #define MEMCLKMGR_EXTCNTRST_ALLCNTRST			\
 	(MEMCLKMGR_EXTCNTRST_C0CNTRST)
 
diff --git a/drivers/clk/aspeed/clk_ast2600.c b/drivers/clk/aspeed/clk_ast2600.c
index eecfacd..a159093 100644
--- a/drivers/clk/aspeed/clk_ast2600.c
+++ b/drivers/clk/aspeed/clk_ast2600.c
@@ -1143,8 +1143,6 @@
 		ret = clk_get_rate(&clk);
 		rate = ret;
 
-		clk_free(&clk);
-
 		if (ret == -EINVAL) {
 			printf("clk ID %lu not supported yet\n",
 			       aspeed_clk_names[i].id);
diff --git a/drivers/clk/at91/compat.c b/drivers/clk/at91/compat.c
index 2fdc2fb..ee67093 100644
--- a/drivers/clk/at91/compat.c
+++ b/drivers/clk/at91/compat.c
@@ -516,7 +516,6 @@
 {
 	struct udevice *dev;
 	struct clk clk_dev;
-	ulong clk_rate;
 	int ret;
 
 	dev = dev_get_parent(clk->dev);
@@ -525,11 +524,7 @@
 	if (ret)
 		return ret;
 
-	clk_rate = clk_get_rate(&clk_dev);
-
-	clk_free(&clk_dev);
-
-	return clk_rate;
+	return clk_get_rate(&clk_dev);
 }
 
 static struct clk_ops periph_clk_ops = {
@@ -762,7 +757,6 @@
 	struct pmc_plat *plat = dev_get_plat(clk->dev);
 	struct at91_pmc *pmc = plat->reg_base;
 	struct clk parent;
-	ulong clk_rate;
 	u32 tmp, gckdiv;
 	u8 clock_source, parent_index;
 	int ret;
@@ -778,11 +772,7 @@
 	if (ret)
 		return 0;
 
-	clk_rate = clk_get_rate(&parent) / (gckdiv + 1);
-
-	clk_free(&parent);
-
-	return clk_rate;
+	return clk_get_rate(&parent) / (gckdiv + 1);
 }
 
 static ulong generic_clk_set_rate(struct clk *clk, ulong rate)
diff --git a/drivers/clk/clk-gpio.c b/drivers/clk/clk-gpio.c
index 26d795b..4ed1430 100644
--- a/drivers/clk/clk-gpio.c
+++ b/drivers/clk/clk-gpio.c
@@ -3,19 +3,23 @@
  * Copyright (C) 2023 Marek Vasut <marek.vasut+renesas@mailbox.org>
  */
 
-#include <asm/gpio.h>
-#include <common.h>
+#include <clk.h>
 #include <clk-uclass.h>
 #include <dm.h>
+#include <linux/clk-provider.h>
+
+#include <asm/gpio.h>
 
 struct clk_gpio_priv {
-	struct gpio_desc	enable;
+	struct gpio_desc	enable;	/* GPIO, controlling the gate */
+	struct clk		*clk;	/* Gated clock */
 };
 
 static int clk_gpio_enable(struct clk *clk)
 {
 	struct clk_gpio_priv *priv = dev_get_priv(clk->dev);
 
+	clk_enable(priv->clk);
 	dm_gpio_set_value(&priv->enable, 1);
 
 	return 0;
@@ -26,21 +30,45 @@
 	struct clk_gpio_priv *priv = dev_get_priv(clk->dev);
 
 	dm_gpio_set_value(&priv->enable, 0);
+	clk_disable(priv->clk);
 
 	return 0;
 }
 
+static ulong clk_gpio_get_rate(struct clk *clk)
+{
+	struct clk_gpio_priv *priv = dev_get_priv(clk->dev);
+
+	return clk_get_rate(priv->clk);
+}
+
 const struct clk_ops clk_gpio_ops = {
 	.enable		= clk_gpio_enable,
 	.disable	= clk_gpio_disable,
+	.get_rate	= clk_gpio_get_rate,
 };
 
 static int clk_gpio_probe(struct udevice *dev)
 {
 	struct clk_gpio_priv *priv = dev_get_priv(dev);
+	int ret;
 
-	return gpio_request_by_name(dev, "enable-gpios", 0,
-				    &priv->enable, GPIOD_IS_OUT);
+	priv->clk = devm_clk_get(dev, NULL);
+	if (IS_ERR(priv->clk)) {
+		log_debug("%s: Could not get gated clock: %ld\n",
+			  __func__, PTR_ERR(priv->clk));
+		return PTR_ERR(priv->clk);
+	}
+
+	ret = gpio_request_by_name(dev, "enable-gpios", 0,
+				   &priv->enable, GPIOD_IS_OUT);
+	if (ret) {
+		log_debug("%s: Could not decode enable-gpios (%d)\n",
+			  __func__, ret);
+		return ret;
+	}
+
+	return 0;
 }
 
 /*
diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c
index 3e9d68f..ed6e60b 100644
--- a/drivers/clk/clk-uclass.c
+++ b/drivers/clk/clk-uclass.c
@@ -437,8 +437,6 @@
 		ret = clk_disable(&clk[i]);
 		if (ret && ret != -ENOSYS)
 			return ret;
-
-		clk_free(&clk[i]);
 	}
 
 	return 0;
@@ -461,24 +459,9 @@
 	return ops->request(clk);
 }
 
-void clk_free(struct clk *clk)
-{
-	const struct clk_ops *ops;
-
-	debug("%s(clk=%p)\n", __func__, clk);
-	if (!clk_valid(clk))
-		return;
-	ops = clk_dev_ops(clk->dev);
-
-	if (ops->rfree)
-		ops->rfree(clk);
-	return;
-}
-
 ulong clk_get_rate(struct clk *clk)
 {
 	const struct clk_ops *ops;
-	ulong ret;
 
 	debug("%s(clk=%p)\n", __func__, clk);
 	if (!clk_valid(clk))
@@ -488,11 +471,7 @@
 	if (!ops->get_rate)
 		return -ENOSYS;
 
-	ret = ops->get_rate(clk);
-	if (ret)
-		return log_ret(ret);
-
-	return 0;
+	return ops->get_rate(clk);
 }
 
 struct clk *clk_get_parent(struct clk *clk)
@@ -791,22 +770,12 @@
 	return false;
 }
 
-static void devm_clk_release(struct udevice *dev, void *res)
-{
-	clk_free(res);
-}
-
-static int devm_clk_match(struct udevice *dev, void *res, void *data)
-{
-	return res == data;
-}
-
 struct clk *devm_clk_get(struct udevice *dev, const char *id)
 {
 	int rc;
 	struct clk *clk;
 
-	clk = devres_alloc(devm_clk_release, sizeof(struct clk), __GFP_ZERO);
+	clk = devm_kzalloc(dev, sizeof(*clk), GFP_KERNEL);
 	if (unlikely(!clk))
 		return ERR_PTR(-ENOMEM);
 
@@ -814,21 +783,9 @@
 	if (rc)
 		return ERR_PTR(rc);
 
-	devres_add(dev, clk);
 	return clk;
 }
 
-void devm_clk_put(struct udevice *dev, struct clk *clk)
-{
-	int rc;
-
-	if (!clk)
-		return;
-
-	rc = devres_release(dev, devm_clk_release, devm_clk_match, clk);
-	WARN_ON(rc);
-}
-
 int clk_uclass_post_probe(struct udevice *dev)
 {
 	/*
diff --git a/drivers/clk/clk-xlnx-clock-wizard.c b/drivers/clk/clk-xlnx-clock-wizard.c
index 70ee3af..a10a843 100644
--- a/drivers/clk/clk-xlnx-clock-wizard.c
+++ b/drivers/clk/clk-xlnx-clock-wizard.c
@@ -137,7 +137,6 @@
 	ret = clk_enable(&clk_in1);
 	if (ret) {
 		dev_err(dev, "failed to enable clock\n");
-		clk_free(&clk_in1);
 		return ret;
 	}
 
diff --git a/drivers/clk/clk_sandbox.c b/drivers/clk/clk_sandbox.c
index 636914d..73d943f 100644
--- a/drivers/clk/clk_sandbox.c
+++ b/drivers/clk/clk_sandbox.c
@@ -101,17 +101,6 @@
 	return 0;
 }
 
-static void sandbox_clk_free(struct clk *clk)
-{
-	struct sandbox_clk_priv *priv = dev_get_priv(clk->dev);
-
-	if (clk->id >= SANDBOX_CLK_ID_COUNT)
-		return;
-
-	priv->requested[clk->id] = false;
-	return;
-}
-
 static struct clk_ops sandbox_clk_ops = {
 	.round_rate	= sandbox_clk_round_rate,
 	.get_rate	= sandbox_clk_get_rate,
@@ -119,7 +108,6 @@
 	.enable		= sandbox_clk_enable,
 	.disable	= sandbox_clk_disable,
 	.request	= sandbox_clk_request,
-	.rfree		= sandbox_clk_free,
 };
 
 static int sandbox_clk_probe(struct udevice *dev)
diff --git a/drivers/clk/clk_sandbox_test.c b/drivers/clk/clk_sandbox_test.c
index c695b69..c224dc1 100644
--- a/drivers/clk/clk_sandbox_test.c
+++ b/drivers/clk/clk_sandbox_test.c
@@ -135,18 +135,6 @@
 	return clk_disable_bulk(&sbct->bulk);
 }
 
-int sandbox_clk_test_free(struct udevice *dev)
-{
-	struct sandbox_clk_test *sbct = dev_get_priv(dev);
-	int i;
-
-	devm_clk_put(dev, sbct->clkps[SANDBOX_CLK_TEST_ID_DEVM1]);
-	for (i = 0; i < SANDBOX_CLK_TEST_NON_DEVM_COUNT; i++)
-		clk_free(&sbct->clks[i]);
-
-	return 0;
-}
-
 int sandbox_clk_test_release_bulk(struct udevice *dev)
 {
 	struct sandbox_clk_test *sbct = dev_get_priv(dev);
diff --git a/drivers/clk/clk_versaclock.c b/drivers/clk/clk_versaclock.c
index 699df3c..bbe7225 100644
--- a/drivers/clk/clk_versaclock.c
+++ b/drivers/clk/clk_versaclock.c
@@ -1000,26 +1000,18 @@
 	return 0;
 
 free_out:
-	for (n = 1; n < vc5->chip_info->clk_out_cnt; n++) {
-		clk_free(&vc5->clk_out[n].hw);
+	for (n = 1; n < vc5->chip_info->clk_out_cnt; n++)
 		free(out_name[n]);
-	}
 free_selb:
-	clk_free(&vc5->clk_out[0].hw);
 	free(outsel_name);
 free_fod:
-	for (n = 0; n < vc5->chip_info->clk_fod_cnt; n++) {
-		clk_free(&vc5->clk_fod[n].hw);
+	for (n = 0; n < vc5->chip_info->clk_fod_cnt; n++)
 		free(fod_name[n]);
-	}
 free_pll:
-	clk_free(&vc5->clk_pll.hw);
 	free(pll_name);
 free_pfd:
-	clk_free(&vc5->clk_pfd);
 	free(pfd_name);
 free_mux:
-	clk_free(&vc5->clk_mux);
 	free(mux_name);
 
 	return ret;
diff --git a/drivers/clk/clk_zynq.c b/drivers/clk/clk_zynq.c
index 34f964d..e3cefe2 100644
--- a/drivers/clk/clk_zynq.c
+++ b/drivers/clk/clk_zynq.c
@@ -491,8 +491,6 @@
 
 			rate = clk_get_rate(&clk);
 
-			clk_free(&clk);
-
 			if ((rate == (unsigned long)-ENOSYS) ||
 			    (rate == (unsigned long)-ENXIO))
 				printf("%10s%20s\n", name, "unknown");
diff --git a/drivers/clk/clk_zynqmp.c b/drivers/clk/clk_zynqmp.c
index 0ffac19..e23f7da 100644
--- a/drivers/clk/clk_zynqmp.c
+++ b/drivers/clk/clk_zynqmp.c
@@ -757,8 +757,6 @@
 
 			rate = clk_get_rate(&clk);
 
-			clk_free(&clk);
-
 			if ((rate == (unsigned long)-ENOSYS) ||
 			    (rate == (unsigned long)-ENXIO) ||
 			    (rate == (unsigned long)-EIO))
diff --git a/drivers/clk/imx/clk-imx8.c b/drivers/clk/imx/clk-imx8.c
index 9600672..d39b87b 100644
--- a/drivers/clk/imx/clk-imx8.c
+++ b/drivers/clk/imx/clk-imx8.c
@@ -62,8 +62,6 @@
 		ret = clk_get_rate(&clk);
 		rate = ret;
 
-		clk_free(&clk);
-
 		if (ret == -EINVAL) {
 			printf("clk ID %lu not supported yet\n",
 			       imx8_clk_names[i].id);
diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
index cdc9d6f..ee33c61 100644
--- a/drivers/clk/meson/Kconfig
+++ b/drivers/clk/meson/Kconfig
@@ -29,3 +29,13 @@
 	help
 	  Enable clock support for the Amlogic A1 SoC family, such as
 	  the A113L
+
+config CLK_MESON_MSR
+	bool "Enable clock measure driver for Amlogic SoCs"
+	depends on CLK && ARCH_MESON
+	depends on CMD_CLK
+	default ARCH_MESON
+	help
+	  Enable measuring a set of internal Amlogic SoC clock frequencies
+	  using the Hardware Clock Measure registers and print them using
+	  the clk dump command.
diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
index d975f07..c7a446e 100644
--- a/drivers/clk/meson/Makefile
+++ b/drivers/clk/meson/Makefile
@@ -9,3 +9,4 @@
 obj-$(CONFIG_CLK_MESON_G12A) += g12a.o
 obj-$(CONFIG_CLK_MESON_G12A) += g12a-ao.o
 obj-$(CONFIG_CLK_MESON_A1) += a1.o
+obj-$(CONFIG_CLK_MESON_MSR) += clk-measure.o
diff --git a/drivers/clk/meson/clk-measure.c b/drivers/clk/meson/clk-measure.c
new file mode 100644
index 0000000..f653fc6
--- /dev/null
+++ b/drivers/clk/meson/clk-measure.c
@@ -0,0 +1,634 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Based on Linux driver from:
+ * (C) Copyright 2018 - BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ * (C) Copyright 2023 - Neil Armstrong <neil.armstrong@linaro.org>
+ */
+
+#include <log.h>
+#include <clk-uclass.h>
+#include <div64.h>
+#include <dm.h>
+#include <time.h>
+#include <regmap.h>
+#include <syscon.h>
+#include <linux/bitops.h>
+#include <linux/bitfield.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+
+#define MSR_CLK_DUTY		0x0
+#define MSR_CLK_REG0		0x4
+#define MSR_CLK_REG1		0x8
+#define MSR_CLK_REG2		0xc
+
+#define MSR_DURATION		GENMASK(15, 0)
+#define MSR_ENABLE		BIT(16)
+#define MSR_CONT		BIT(17) /* continuous measurement */
+#define MSR_INTR		BIT(18) /* interrupts */
+#define MSR_RUN			BIT(19)
+#define MSR_CLK_SRC		GENMASK(26, 20)
+#define MSR_BUSY		BIT(31)
+
+#define MSR_VAL_MASK		GENMASK(15, 0)
+
+#define DIV_MIN			32
+#define DIV_STEP		32
+#define DIV_MAX			640
+
+#define CLK_MSR_MAX		128
+
+struct meson_msr_id {
+	unsigned int id;
+	const char *name;
+};
+
+struct meson_msr {
+	struct regmap *regmap;
+	struct meson_msr_id *msr_table;
+};
+
+#define CLK_MSR_ID(__id, __name) \
+	[__id] = {.id = __id, .name = __name,}
+
+static struct meson_msr_id clk_msr_m8[CLK_MSR_MAX] = {
+	CLK_MSR_ID(0, "ring_osc_out_ee0"),
+	CLK_MSR_ID(1, "ring_osc_out_ee1"),
+	CLK_MSR_ID(2, "ring_osc_out_ee2"),
+	CLK_MSR_ID(3, "a9_ring_osck"),
+	CLK_MSR_ID(6, "vid_pll"),
+	CLK_MSR_ID(7, "clk81"),
+	CLK_MSR_ID(8, "encp"),
+	CLK_MSR_ID(9, "encl"),
+	CLK_MSR_ID(11, "eth_rmii"),
+	CLK_MSR_ID(13, "amclk"),
+	CLK_MSR_ID(14, "fec_clk_0"),
+	CLK_MSR_ID(15, "fec_clk_1"),
+	CLK_MSR_ID(16, "fec_clk_2"),
+	CLK_MSR_ID(18, "a9_clk_div16"),
+	CLK_MSR_ID(19, "hdmi_sys"),
+	CLK_MSR_ID(20, "rtc_osc_clk_out"),
+	CLK_MSR_ID(21, "i2s_clk_in_src0"),
+	CLK_MSR_ID(22, "clk_rmii_from_pad"),
+	CLK_MSR_ID(23, "hdmi_ch0_tmds"),
+	CLK_MSR_ID(24, "lvds_fifo"),
+	CLK_MSR_ID(26, "sc_clk_int"),
+	CLK_MSR_ID(28, "sar_adc"),
+	CLK_MSR_ID(30, "mpll_clk_test_out"),
+	CLK_MSR_ID(31, "audac_clkpi"),
+	CLK_MSR_ID(32, "vdac"),
+	CLK_MSR_ID(33, "sdhc_rx"),
+	CLK_MSR_ID(34, "sdhc_sd"),
+	CLK_MSR_ID(35, "mali"),
+	CLK_MSR_ID(36, "hdmi_tx_pixel"),
+	CLK_MSR_ID(38, "vdin_meas"),
+	CLK_MSR_ID(39, "pcm_sclk"),
+	CLK_MSR_ID(40, "pcm_mclk"),
+	CLK_MSR_ID(41, "eth_rx_tx"),
+	CLK_MSR_ID(42, "pwm_d"),
+	CLK_MSR_ID(43, "pwm_c"),
+	CLK_MSR_ID(44, "pwm_b"),
+	CLK_MSR_ID(45, "pwm_a"),
+	CLK_MSR_ID(46, "pcm2_sclk"),
+	CLK_MSR_ID(47, "ddr_dpll_pt"),
+	CLK_MSR_ID(48, "pwm_f"),
+	CLK_MSR_ID(49, "pwm_e"),
+	CLK_MSR_ID(59, "hcodec"),
+	CLK_MSR_ID(60, "usb_32k_alt"),
+	CLK_MSR_ID(61, "gpio"),
+	CLK_MSR_ID(62, "vid2_pll"),
+	CLK_MSR_ID(63, "mipi_csi_cfg"),
+};
+
+static struct meson_msr_id clk_msr_gx[CLK_MSR_MAX] = {
+	CLK_MSR_ID(0, "ring_osc_out_ee_0"),
+	CLK_MSR_ID(1, "ring_osc_out_ee_1"),
+	CLK_MSR_ID(2, "ring_osc_out_ee_2"),
+	CLK_MSR_ID(3, "a53_ring_osc"),
+	CLK_MSR_ID(4, "gp0_pll"),
+	CLK_MSR_ID(6, "enci"),
+	CLK_MSR_ID(7, "clk81"),
+	CLK_MSR_ID(8, "encp"),
+	CLK_MSR_ID(9, "encl"),
+	CLK_MSR_ID(10, "vdac"),
+	CLK_MSR_ID(11, "rgmii_tx"),
+	CLK_MSR_ID(12, "pdm"),
+	CLK_MSR_ID(13, "amclk"),
+	CLK_MSR_ID(14, "fec_0"),
+	CLK_MSR_ID(15, "fec_1"),
+	CLK_MSR_ID(16, "fec_2"),
+	CLK_MSR_ID(17, "sys_pll_div16"),
+	CLK_MSR_ID(18, "sys_cpu_div16"),
+	CLK_MSR_ID(19, "hdmitx_sys"),
+	CLK_MSR_ID(20, "rtc_osc_out"),
+	CLK_MSR_ID(21, "i2s_in_src0"),
+	CLK_MSR_ID(22, "eth_phy_ref"),
+	CLK_MSR_ID(23, "hdmi_todig"),
+	CLK_MSR_ID(26, "sc_int"),
+	CLK_MSR_ID(28, "sar_adc"),
+	CLK_MSR_ID(31, "mpll_test_out"),
+	CLK_MSR_ID(32, "vdec"),
+	CLK_MSR_ID(35, "mali"),
+	CLK_MSR_ID(36, "hdmi_tx_pixel"),
+	CLK_MSR_ID(37, "i958"),
+	CLK_MSR_ID(38, "vdin_meas"),
+	CLK_MSR_ID(39, "pcm_sclk"),
+	CLK_MSR_ID(40, "pcm_mclk"),
+	CLK_MSR_ID(41, "eth_rx_or_rmii"),
+	CLK_MSR_ID(42, "mp0_out"),
+	CLK_MSR_ID(43, "fclk_div5"),
+	CLK_MSR_ID(44, "pwm_b"),
+	CLK_MSR_ID(45, "pwm_a"),
+	CLK_MSR_ID(46, "vpu"),
+	CLK_MSR_ID(47, "ddr_dpll_pt"),
+	CLK_MSR_ID(48, "mp1_out"),
+	CLK_MSR_ID(49, "mp2_out"),
+	CLK_MSR_ID(50, "mp3_out"),
+	CLK_MSR_ID(51, "nand_core"),
+	CLK_MSR_ID(52, "sd_emmc_b"),
+	CLK_MSR_ID(53, "sd_emmc_a"),
+	CLK_MSR_ID(55, "vid_pll_div_out"),
+	CLK_MSR_ID(56, "cci"),
+	CLK_MSR_ID(57, "wave420l_c"),
+	CLK_MSR_ID(58, "wave420l_b"),
+	CLK_MSR_ID(59, "hcodec"),
+	CLK_MSR_ID(60, "alt_32k"),
+	CLK_MSR_ID(61, "gpio_msr"),
+	CLK_MSR_ID(62, "hevc"),
+	CLK_MSR_ID(66, "vid_lock"),
+	CLK_MSR_ID(70, "pwm_f"),
+	CLK_MSR_ID(71, "pwm_e"),
+	CLK_MSR_ID(72, "pwm_d"),
+	CLK_MSR_ID(73, "pwm_c"),
+	CLK_MSR_ID(75, "aoclkx2_int"),
+	CLK_MSR_ID(76, "aoclk_int"),
+	CLK_MSR_ID(77, "rng_ring_osc_0"),
+	CLK_MSR_ID(78, "rng_ring_osc_1"),
+	CLK_MSR_ID(79, "rng_ring_osc_2"),
+	CLK_MSR_ID(80, "rng_ring_osc_3"),
+	CLK_MSR_ID(81, "vapb"),
+	CLK_MSR_ID(82, "ge2d"),
+};
+
+static struct meson_msr_id clk_msr_axg[CLK_MSR_MAX] = {
+	CLK_MSR_ID(0, "ring_osc_out_ee_0"),
+	CLK_MSR_ID(1, "ring_osc_out_ee_1"),
+	CLK_MSR_ID(2, "ring_osc_out_ee_2"),
+	CLK_MSR_ID(3, "a53_ring_osc"),
+	CLK_MSR_ID(4, "gp0_pll"),
+	CLK_MSR_ID(5, "gp1_pll"),
+	CLK_MSR_ID(7, "clk81"),
+	CLK_MSR_ID(9, "encl"),
+	CLK_MSR_ID(17, "sys_pll_div16"),
+	CLK_MSR_ID(18, "sys_cpu_div16"),
+	CLK_MSR_ID(20, "rtc_osc_out"),
+	CLK_MSR_ID(23, "mmc_clk"),
+	CLK_MSR_ID(28, "sar_adc"),
+	CLK_MSR_ID(31, "mpll_test_out"),
+	CLK_MSR_ID(40, "mod_eth_tx_clk"),
+	CLK_MSR_ID(41, "mod_eth_rx_clk_rmii"),
+	CLK_MSR_ID(42, "mp0_out"),
+	CLK_MSR_ID(43, "fclk_div5"),
+	CLK_MSR_ID(44, "pwm_b"),
+	CLK_MSR_ID(45, "pwm_a"),
+	CLK_MSR_ID(46, "vpu"),
+	CLK_MSR_ID(47, "ddr_dpll_pt"),
+	CLK_MSR_ID(48, "mp1_out"),
+	CLK_MSR_ID(49, "mp2_out"),
+	CLK_MSR_ID(50, "mp3_out"),
+	CLK_MSR_ID(51, "sd_emmm_c"),
+	CLK_MSR_ID(52, "sd_emmc_b"),
+	CLK_MSR_ID(61, "gpio_msr"),
+	CLK_MSR_ID(66, "audio_slv_lrclk_c"),
+	CLK_MSR_ID(67, "audio_slv_lrclk_b"),
+	CLK_MSR_ID(68, "audio_slv_lrclk_a"),
+	CLK_MSR_ID(69, "audio_slv_sclk_c"),
+	CLK_MSR_ID(70, "audio_slv_sclk_b"),
+	CLK_MSR_ID(71, "audio_slv_sclk_a"),
+	CLK_MSR_ID(72, "pwm_d"),
+	CLK_MSR_ID(73, "pwm_c"),
+	CLK_MSR_ID(74, "wifi_beacon"),
+	CLK_MSR_ID(75, "tdmin_lb_lrcl"),
+	CLK_MSR_ID(76, "tdmin_lb_sclk"),
+	CLK_MSR_ID(77, "rng_ring_osc_0"),
+	CLK_MSR_ID(78, "rng_ring_osc_1"),
+	CLK_MSR_ID(79, "rng_ring_osc_2"),
+	CLK_MSR_ID(80, "rng_ring_osc_3"),
+	CLK_MSR_ID(81, "vapb"),
+	CLK_MSR_ID(82, "ge2d"),
+	CLK_MSR_ID(84, "audio_resample"),
+	CLK_MSR_ID(85, "audio_pdm_sys"),
+	CLK_MSR_ID(86, "audio_spdifout"),
+	CLK_MSR_ID(87, "audio_spdifin"),
+	CLK_MSR_ID(88, "audio_lrclk_f"),
+	CLK_MSR_ID(89, "audio_lrclk_e"),
+	CLK_MSR_ID(90, "audio_lrclk_d"),
+	CLK_MSR_ID(91, "audio_lrclk_c"),
+	CLK_MSR_ID(92, "audio_lrclk_b"),
+	CLK_MSR_ID(93, "audio_lrclk_a"),
+	CLK_MSR_ID(94, "audio_sclk_f"),
+	CLK_MSR_ID(95, "audio_sclk_e"),
+	CLK_MSR_ID(96, "audio_sclk_d"),
+	CLK_MSR_ID(97, "audio_sclk_c"),
+	CLK_MSR_ID(98, "audio_sclk_b"),
+	CLK_MSR_ID(99, "audio_sclk_a"),
+	CLK_MSR_ID(100, "audio_mclk_f"),
+	CLK_MSR_ID(101, "audio_mclk_e"),
+	CLK_MSR_ID(102, "audio_mclk_d"),
+	CLK_MSR_ID(103, "audio_mclk_c"),
+	CLK_MSR_ID(104, "audio_mclk_b"),
+	CLK_MSR_ID(105, "audio_mclk_a"),
+	CLK_MSR_ID(106, "pcie_refclk_n"),
+	CLK_MSR_ID(107, "pcie_refclk_p"),
+	CLK_MSR_ID(108, "audio_locker_out"),
+	CLK_MSR_ID(109, "audio_locker_in"),
+};
+
+static struct meson_msr_id clk_msr_g12a[CLK_MSR_MAX] = {
+	CLK_MSR_ID(0, "ring_osc_out_ee_0"),
+	CLK_MSR_ID(1, "ring_osc_out_ee_1"),
+	CLK_MSR_ID(2, "ring_osc_out_ee_2"),
+	CLK_MSR_ID(3, "sys_cpu_ring_osc"),
+	CLK_MSR_ID(4, "gp0_pll"),
+	CLK_MSR_ID(6, "enci"),
+	CLK_MSR_ID(7, "clk81"),
+	CLK_MSR_ID(8, "encp"),
+	CLK_MSR_ID(9, "encl"),
+	CLK_MSR_ID(10, "vdac"),
+	CLK_MSR_ID(11, "eth_tx"),
+	CLK_MSR_ID(12, "hifi_pll"),
+	CLK_MSR_ID(13, "mod_tcon"),
+	CLK_MSR_ID(14, "fec_0"),
+	CLK_MSR_ID(15, "fec_1"),
+	CLK_MSR_ID(16, "fec_2"),
+	CLK_MSR_ID(17, "sys_pll_div16"),
+	CLK_MSR_ID(18, "sys_cpu_div16"),
+	CLK_MSR_ID(19, "lcd_an_ph2"),
+	CLK_MSR_ID(20, "rtc_osc_out"),
+	CLK_MSR_ID(21, "lcd_an_ph3"),
+	CLK_MSR_ID(22, "eth_phy_ref"),
+	CLK_MSR_ID(23, "mpll_50m"),
+	CLK_MSR_ID(24, "eth_125m"),
+	CLK_MSR_ID(25, "eth_rmii"),
+	CLK_MSR_ID(26, "sc_int"),
+	CLK_MSR_ID(27, "in_mac"),
+	CLK_MSR_ID(28, "sar_adc"),
+	CLK_MSR_ID(29, "pcie_inp"),
+	CLK_MSR_ID(30, "pcie_inn"),
+	CLK_MSR_ID(31, "mpll_test_out"),
+	CLK_MSR_ID(32, "vdec"),
+	CLK_MSR_ID(33, "sys_cpu_ring_osc_1"),
+	CLK_MSR_ID(34, "eth_mpll_50m"),
+	CLK_MSR_ID(35, "mali"),
+	CLK_MSR_ID(36, "hdmi_tx_pixel"),
+	CLK_MSR_ID(37, "cdac"),
+	CLK_MSR_ID(38, "vdin_meas"),
+	CLK_MSR_ID(39, "bt656"),
+	CLK_MSR_ID(41, "eth_rx_or_rmii"),
+	CLK_MSR_ID(42, "mp0_out"),
+	CLK_MSR_ID(43, "fclk_div5"),
+	CLK_MSR_ID(44, "pwm_b"),
+	CLK_MSR_ID(45, "pwm_a"),
+	CLK_MSR_ID(46, "vpu"),
+	CLK_MSR_ID(47, "ddr_dpll_pt"),
+	CLK_MSR_ID(48, "mp1_out"),
+	CLK_MSR_ID(49, "mp2_out"),
+	CLK_MSR_ID(50, "mp3_out"),
+	CLK_MSR_ID(51, "sd_emmc_c"),
+	CLK_MSR_ID(52, "sd_emmc_b"),
+	CLK_MSR_ID(53, "sd_emmc_a"),
+	CLK_MSR_ID(54, "vpu_clkc"),
+	CLK_MSR_ID(55, "vid_pll_div_out"),
+	CLK_MSR_ID(56, "wave420l_a"),
+	CLK_MSR_ID(57, "wave420l_c"),
+	CLK_MSR_ID(58, "wave420l_b"),
+	CLK_MSR_ID(59, "hcodec"),
+	CLK_MSR_ID(61, "gpio_msr"),
+	CLK_MSR_ID(62, "hevcb"),
+	CLK_MSR_ID(63, "dsi_meas"),
+	CLK_MSR_ID(64, "spicc_1"),
+	CLK_MSR_ID(65, "spicc_0"),
+	CLK_MSR_ID(66, "vid_lock"),
+	CLK_MSR_ID(67, "dsi_phy"),
+	CLK_MSR_ID(68, "hdcp22_esm"),
+	CLK_MSR_ID(69, "hdcp22_skp"),
+	CLK_MSR_ID(70, "pwm_f"),
+	CLK_MSR_ID(71, "pwm_e"),
+	CLK_MSR_ID(72, "pwm_d"),
+	CLK_MSR_ID(73, "pwm_c"),
+	CLK_MSR_ID(75, "hevcf"),
+	CLK_MSR_ID(77, "rng_ring_osc_0"),
+	CLK_MSR_ID(78, "rng_ring_osc_1"),
+	CLK_MSR_ID(79, "rng_ring_osc_2"),
+	CLK_MSR_ID(80, "rng_ring_osc_3"),
+	CLK_MSR_ID(81, "vapb"),
+	CLK_MSR_ID(82, "ge2d"),
+	CLK_MSR_ID(83, "co_rx"),
+	CLK_MSR_ID(84, "co_tx"),
+	CLK_MSR_ID(89, "hdmi_todig"),
+	CLK_MSR_ID(90, "hdmitx_sys"),
+	CLK_MSR_ID(91, "sys_cpub_div16"),
+	CLK_MSR_ID(92, "sys_pll_cpub_div16"),
+	CLK_MSR_ID(94, "eth_phy_rx"),
+	CLK_MSR_ID(95, "eth_phy_pll"),
+	CLK_MSR_ID(96, "vpu_b"),
+	CLK_MSR_ID(97, "cpu_b_tmp"),
+	CLK_MSR_ID(98, "ts"),
+	CLK_MSR_ID(99, "ring_osc_out_ee_3"),
+	CLK_MSR_ID(100, "ring_osc_out_ee_4"),
+	CLK_MSR_ID(101, "ring_osc_out_ee_5"),
+	CLK_MSR_ID(102, "ring_osc_out_ee_6"),
+	CLK_MSR_ID(103, "ring_osc_out_ee_7"),
+	CLK_MSR_ID(104, "ring_osc_out_ee_8"),
+	CLK_MSR_ID(105, "ring_osc_out_ee_9"),
+	CLK_MSR_ID(106, "ephy_test"),
+	CLK_MSR_ID(107, "au_dac_g128x"),
+	CLK_MSR_ID(108, "audio_locker_out"),
+	CLK_MSR_ID(109, "audio_locker_in"),
+	CLK_MSR_ID(110, "audio_tdmout_c_sclk"),
+	CLK_MSR_ID(111, "audio_tdmout_b_sclk"),
+	CLK_MSR_ID(112, "audio_tdmout_a_sclk"),
+	CLK_MSR_ID(113, "audio_tdmin_lb_sclk"),
+	CLK_MSR_ID(114, "audio_tdmin_c_sclk"),
+	CLK_MSR_ID(115, "audio_tdmin_b_sclk"),
+	CLK_MSR_ID(116, "audio_tdmin_a_sclk"),
+	CLK_MSR_ID(117, "audio_resample"),
+	CLK_MSR_ID(118, "audio_pdm_sys"),
+	CLK_MSR_ID(119, "audio_spdifout_b"),
+	CLK_MSR_ID(120, "audio_spdifout"),
+	CLK_MSR_ID(121, "audio_spdifin"),
+	CLK_MSR_ID(122, "audio_pdm_dclk"),
+};
+
+static struct meson_msr_id clk_msr_sm1[CLK_MSR_MAX] = {
+	CLK_MSR_ID(0, "ring_osc_out_ee_0"),
+	CLK_MSR_ID(1, "ring_osc_out_ee_1"),
+	CLK_MSR_ID(2, "ring_osc_out_ee_2"),
+	CLK_MSR_ID(3, "ring_osc_out_ee_3"),
+	CLK_MSR_ID(4, "gp0_pll"),
+	CLK_MSR_ID(5, "gp1_pll"),
+	CLK_MSR_ID(6, "enci"),
+	CLK_MSR_ID(7, "clk81"),
+	CLK_MSR_ID(8, "encp"),
+	CLK_MSR_ID(9, "encl"),
+	CLK_MSR_ID(10, "vdac"),
+	CLK_MSR_ID(11, "eth_tx"),
+	CLK_MSR_ID(12, "hifi_pll"),
+	CLK_MSR_ID(13, "mod_tcon"),
+	CLK_MSR_ID(14, "fec_0"),
+	CLK_MSR_ID(15, "fec_1"),
+	CLK_MSR_ID(16, "fec_2"),
+	CLK_MSR_ID(17, "sys_pll_div16"),
+	CLK_MSR_ID(18, "sys_cpu_div16"),
+	CLK_MSR_ID(19, "lcd_an_ph2"),
+	CLK_MSR_ID(20, "rtc_osc_out"),
+	CLK_MSR_ID(21, "lcd_an_ph3"),
+	CLK_MSR_ID(22, "eth_phy_ref"),
+	CLK_MSR_ID(23, "mpll_50m"),
+	CLK_MSR_ID(24, "eth_125m"),
+	CLK_MSR_ID(25, "eth_rmii"),
+	CLK_MSR_ID(26, "sc_int"),
+	CLK_MSR_ID(27, "in_mac"),
+	CLK_MSR_ID(28, "sar_adc"),
+	CLK_MSR_ID(29, "pcie_inp"),
+	CLK_MSR_ID(30, "pcie_inn"),
+	CLK_MSR_ID(31, "mpll_test_out"),
+	CLK_MSR_ID(32, "vdec"),
+	CLK_MSR_ID(34, "eth_mpll_50m"),
+	CLK_MSR_ID(35, "mali"),
+	CLK_MSR_ID(36, "hdmi_tx_pixel"),
+	CLK_MSR_ID(37, "cdac"),
+	CLK_MSR_ID(38, "vdin_meas"),
+	CLK_MSR_ID(39, "bt656"),
+	CLK_MSR_ID(40, "arm_ring_osc_out_4"),
+	CLK_MSR_ID(41, "eth_rx_or_rmii"),
+	CLK_MSR_ID(42, "mp0_out"),
+	CLK_MSR_ID(43, "fclk_div5"),
+	CLK_MSR_ID(44, "pwm_b"),
+	CLK_MSR_ID(45, "pwm_a"),
+	CLK_MSR_ID(46, "vpu"),
+	CLK_MSR_ID(47, "ddr_dpll_pt"),
+	CLK_MSR_ID(48, "mp1_out"),
+	CLK_MSR_ID(49, "mp2_out"),
+	CLK_MSR_ID(50, "mp3_out"),
+	CLK_MSR_ID(51, "sd_emmc_c"),
+	CLK_MSR_ID(52, "sd_emmc_b"),
+	CLK_MSR_ID(53, "sd_emmc_a"),
+	CLK_MSR_ID(54, "vpu_clkc"),
+	CLK_MSR_ID(55, "vid_pll_div_out"),
+	CLK_MSR_ID(56, "wave420l_a"),
+	CLK_MSR_ID(57, "wave420l_c"),
+	CLK_MSR_ID(58, "wave420l_b"),
+	CLK_MSR_ID(59, "hcodec"),
+	CLK_MSR_ID(60, "arm_ring_osc_out_5"),
+	CLK_MSR_ID(61, "gpio_msr"),
+	CLK_MSR_ID(62, "hevcb"),
+	CLK_MSR_ID(63, "dsi_meas"),
+	CLK_MSR_ID(64, "spicc_1"),
+	CLK_MSR_ID(65, "spicc_0"),
+	CLK_MSR_ID(66, "vid_lock"),
+	CLK_MSR_ID(67, "dsi_phy"),
+	CLK_MSR_ID(68, "hdcp22_esm"),
+	CLK_MSR_ID(69, "hdcp22_skp"),
+	CLK_MSR_ID(70, "pwm_f"),
+	CLK_MSR_ID(71, "pwm_e"),
+	CLK_MSR_ID(72, "pwm_d"),
+	CLK_MSR_ID(73, "pwm_c"),
+	CLK_MSR_ID(74, "arm_ring_osc_out_6"),
+	CLK_MSR_ID(75, "hevcf"),
+	CLK_MSR_ID(76, "arm_ring_osc_out_7"),
+	CLK_MSR_ID(77, "rng_ring_osc_0"),
+	CLK_MSR_ID(78, "rng_ring_osc_1"),
+	CLK_MSR_ID(79, "rng_ring_osc_2"),
+	CLK_MSR_ID(80, "rng_ring_osc_3"),
+	CLK_MSR_ID(81, "vapb"),
+	CLK_MSR_ID(82, "ge2d"),
+	CLK_MSR_ID(83, "co_rx"),
+	CLK_MSR_ID(84, "co_tx"),
+	CLK_MSR_ID(85, "arm_ring_osc_out_8"),
+	CLK_MSR_ID(86, "arm_ring_osc_out_9"),
+	CLK_MSR_ID(87, "mipi_dsi_phy"),
+	CLK_MSR_ID(88, "cis2_adapt"),
+	CLK_MSR_ID(89, "hdmi_todig"),
+	CLK_MSR_ID(90, "hdmitx_sys"),
+	CLK_MSR_ID(91, "nna_core"),
+	CLK_MSR_ID(92, "nna_axi"),
+	CLK_MSR_ID(93, "vad"),
+	CLK_MSR_ID(94, "eth_phy_rx"),
+	CLK_MSR_ID(95, "eth_phy_pll"),
+	CLK_MSR_ID(96, "vpu_b"),
+	CLK_MSR_ID(97, "cpu_b_tmp"),
+	CLK_MSR_ID(98, "ts"),
+	CLK_MSR_ID(99, "arm_ring_osc_out_10"),
+	CLK_MSR_ID(100, "arm_ring_osc_out_11"),
+	CLK_MSR_ID(101, "arm_ring_osc_out_12"),
+	CLK_MSR_ID(102, "arm_ring_osc_out_13"),
+	CLK_MSR_ID(103, "arm_ring_osc_out_14"),
+	CLK_MSR_ID(104, "arm_ring_osc_out_15"),
+	CLK_MSR_ID(105, "arm_ring_osc_out_16"),
+	CLK_MSR_ID(106, "ephy_test"),
+	CLK_MSR_ID(107, "au_dac_g128x"),
+	CLK_MSR_ID(108, "audio_locker_out"),
+	CLK_MSR_ID(109, "audio_locker_in"),
+	CLK_MSR_ID(110, "audio_tdmout_c_sclk"),
+	CLK_MSR_ID(111, "audio_tdmout_b_sclk"),
+	CLK_MSR_ID(112, "audio_tdmout_a_sclk"),
+	CLK_MSR_ID(113, "audio_tdmin_lb_sclk"),
+	CLK_MSR_ID(114, "audio_tdmin_c_sclk"),
+	CLK_MSR_ID(115, "audio_tdmin_b_sclk"),
+	CLK_MSR_ID(116, "audio_tdmin_a_sclk"),
+	CLK_MSR_ID(117, "audio_resample"),
+	CLK_MSR_ID(118, "audio_pdm_sys"),
+	CLK_MSR_ID(119, "audio_spdifout_b"),
+	CLK_MSR_ID(120, "audio_spdifout"),
+	CLK_MSR_ID(121, "audio_spdifin"),
+	CLK_MSR_ID(122, "audio_pdm_dclk"),
+	CLK_MSR_ID(123, "audio_resampled"),
+	CLK_MSR_ID(124, "earcrx_pll"),
+	CLK_MSR_ID(125, "earcrx_pll_test"),
+	CLK_MSR_ID(126, "csi_phy0"),
+	CLK_MSR_ID(127, "csi2_data"),
+};
+
+static int meson_clk_msr_measure_id(struct meson_msr *priv, unsigned int id,
+				    unsigned int duration)
+{
+	unsigned int val;
+	int ret;
+
+	regmap_write(priv->regmap, MSR_CLK_REG0, 0);
+
+	/* Set measurement duration */
+	regmap_update_bits(priv->regmap, MSR_CLK_REG0, MSR_DURATION,
+			   FIELD_PREP(MSR_DURATION, duration - 1));
+
+	/* Set ID */
+	regmap_update_bits(priv->regmap, MSR_CLK_REG0, MSR_CLK_SRC,
+			   FIELD_PREP(MSR_CLK_SRC, id));
+
+	/* Enable & Start */
+	regmap_update_bits(priv->regmap, MSR_CLK_REG0,
+			   MSR_RUN | MSR_ENABLE,
+			   MSR_RUN | MSR_ENABLE);
+
+	ret = regmap_read_poll_timeout(priv->regmap, MSR_CLK_REG0,
+				       val, !(val & MSR_BUSY), 10, 10000);
+	if (ret)
+		return ret;
+
+	/* Disable */
+	regmap_update_bits(priv->regmap, MSR_CLK_REG0, MSR_ENABLE, 0);
+
+	/* Get the value in multiple of gate time counts */
+	regmap_read(priv->regmap, MSR_CLK_REG2, &val);
+
+	if (val >= MSR_VAL_MASK)
+		return -EINVAL;
+
+	return DIV_ROUND_CLOSEST_ULL((val & MSR_VAL_MASK) * 1000000ULL,
+				     duration);
+}
+
+static int meson_clk_msr_best_id(struct meson_msr *priv, unsigned int id,
+				 unsigned int *precision)
+{
+	unsigned int duration = DIV_MAX;
+	int ret;
+
+	/* Start from max duration and down to min duration */
+	do {
+		ret = meson_clk_msr_measure_id(priv, id, duration);
+		if (ret >= 0)
+			*precision = (2 * 1000000) / duration;
+		else
+			duration -= DIV_STEP;
+	} while (duration >= DIV_MIN && ret == -EINVAL);
+
+	return ret;
+}
+
+static void meson_clk_msr_dump(struct udevice *dev)
+{
+	struct meson_msr *priv = dev_get_priv(dev);
+	unsigned int precision = 0;
+	int val, i;
+
+	printf("  clock                     rate    precision\n");
+	printf("---------------------------------------------\n");
+
+	for (i = 0 ; i < CLK_MSR_MAX ; ++i) {
+		if (!priv->msr_table[i].name)
+			continue;
+
+		val = meson_clk_msr_best_id(priv, i, &precision);
+		if (val < 0)
+			return;
+
+		printf(" %-20s %10d    +/-%dHz\n",
+		       priv->msr_table[i].name, val, precision);
+	}
+}
+
+static int meson_clk_msr_xlate(struct clk *clk, struct ofnode_phandle_args *args)
+{
+	/* This driver doesn't expose any clocks */
+	return -EINVAL;
+}
+
+static int meson_clk_msr_probe(struct udevice *dev)
+{
+	struct meson_msr *priv = dev_get_priv(dev);
+	int ret;
+
+	priv->msr_table = (struct meson_msr_id *)dev_get_driver_data(dev);
+
+	ret = regmap_init_mem(dev_ofnode(dev), &priv->regmap);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static struct clk_ops meson_clk_msr_ops = {
+	.of_xlate = meson_clk_msr_xlate,
+	.dump = meson_clk_msr_dump,
+};
+
+static const struct udevice_id meson_clk_msr_ids[] = {
+	{
+		.compatible = "amlogic,meson-gx-clk-measure",
+		.data = (ulong)clk_msr_gx,
+	},
+	{
+		.compatible = "amlogic,meson8-clk-measure",
+		.data = (ulong)clk_msr_m8,
+	},
+	{
+		.compatible = "amlogic,meson8b-clk-measure",
+		.data = (ulong)clk_msr_m8,
+	},
+	{
+		.compatible = "amlogic,meson-axg-clk-measure",
+		.data = (ulong)clk_msr_axg,
+	},
+	{
+		.compatible = "amlogic,meson-g12a-clk-measure",
+		.data = (ulong)clk_msr_g12a,
+	},
+	{
+		.compatible = "amlogic,meson-sm1-clk-measure",
+		.data = (ulong)clk_msr_sm1,
+	},
+	{ /* sentinel */ }
+};
+
+U_BOOT_DRIVER(meson_clk_msr) = {
+	.name		= "meson_clk_msr",
+	.id		= UCLASS_CLK,
+	.of_match	= meson_clk_msr_ids,
+	.priv_auto	= sizeof(struct meson_msr),
+	.ops		= &meson_clk_msr_ops,
+	.probe		= meson_clk_msr_probe,
+};
diff --git a/drivers/clk/mvebu/armada-37xx-periph.c b/drivers/clk/mvebu/armada-37xx-periph.c
index 1a70970..f5c9bd7 100644
--- a/drivers/clk/mvebu/armada-37xx-periph.c
+++ b/drivers/clk/mvebu/armada-37xx-periph.c
@@ -454,7 +454,6 @@
 	if (parent->dev != check_parent.dev)
 		ret = -EINVAL;
 
-	clk_free(&check_parent);
 	if (ret < 0)
 		return ret;
 
@@ -596,7 +595,6 @@
 		}
 
 		priv->parents[i] = clk_get_rate(&clk);
-		clk_free(&clk);
 	}
 
 	return 0;
diff --git a/drivers/clk/renesas/clk-rcar-gen2.c b/drivers/clk/renesas/clk-rcar-gen2.c
index 850d641..66ffef9 100644
--- a/drivers/clk/renesas/clk-rcar-gen2.c
+++ b/drivers/clk/renesas/clk-rcar-gen2.c
@@ -10,7 +10,6 @@
  * Copyright (C) 2016 Glider bvba
  */
 
-#include <common.h>
 #include <clk-uclass.h>
 #include <dm.h>
 #include <errno.h>
diff --git a/drivers/clk/renesas/clk-rcar-gen3.c b/drivers/clk/renesas/clk-rcar-gen3.c
index 0d274bb..196903e 100644
--- a/drivers/clk/renesas/clk-rcar-gen3.c
+++ b/drivers/clk/renesas/clk-rcar-gen3.c
@@ -10,7 +10,6 @@
  * Copyright (C) 2016 Glider bvba
  */
 
-#include <common.h>
 #include <clk-uclass.h>
 #include <dm.h>
 #include <dm/device-internal.h>
diff --git a/drivers/clk/renesas/r8a774a1-cpg-mssr.c b/drivers/clk/renesas/r8a774a1-cpg-mssr.c
index 6f94906..d23041a 100644
--- a/drivers/clk/renesas/r8a774a1-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a774a1-cpg-mssr.c
@@ -9,7 +9,6 @@
  * Copyright (C) 2016 Glider bvba
  */
 
-#include <common.h>
 #include <clk-uclass.h>
 #include <dm.h>
 
diff --git a/drivers/clk/renesas/r8a774b1-cpg-mssr.c b/drivers/clk/renesas/r8a774b1-cpg-mssr.c
index 1a79498..81d7dfe 100644
--- a/drivers/clk/renesas/r8a774b1-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a774b1-cpg-mssr.c
@@ -9,7 +9,6 @@
  * Copyright (C) 2016 Glider bvba
  */
 
-#include <common.h>
 #include <clk-uclass.h>
 #include <dm.h>
 
diff --git a/drivers/clk/renesas/r8a774c0-cpg-mssr.c b/drivers/clk/renesas/r8a774c0-cpg-mssr.c
index ec8ce6a..f92fd25 100644
--- a/drivers/clk/renesas/r8a774c0-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a774c0-cpg-mssr.c
@@ -10,7 +10,6 @@
  * Copyright (C) 2015 Renesas Electronics Corp.
  */
 
-#include <common.h>
 #include <clk-uclass.h>
 #include <dm.h>
 #include <linux/bitops.h>
diff --git a/drivers/clk/renesas/r8a774e1-cpg-mssr.c b/drivers/clk/renesas/r8a774e1-cpg-mssr.c
index 6a8fe92..7c7cb7b 100644
--- a/drivers/clk/renesas/r8a774e1-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a774e1-cpg-mssr.c
@@ -9,7 +9,6 @@
  * Copyright (C) 2015 Glider bvba
  */
 
-#include <common.h>
 #include <clk-uclass.h>
 #include <dm.h>
 #include <linux/bitops.h>
diff --git a/drivers/clk/renesas/r8a7790-cpg-mssr.c b/drivers/clk/renesas/r8a7790-cpg-mssr.c
index 686f2af..190b68e 100644
--- a/drivers/clk/renesas/r8a7790-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a7790-cpg-mssr.c
@@ -9,7 +9,6 @@
  * Copyright (C) 2013 Ideas On Board SPRL
  */
 
-#include <common.h>
 #include <clk-uclass.h>
 #include <dm.h>
 #include <linux/bitops.h>
diff --git a/drivers/clk/renesas/r8a7791-cpg-mssr.c b/drivers/clk/renesas/r8a7791-cpg-mssr.c
index dcb0fd8..30711bf 100644
--- a/drivers/clk/renesas/r8a7791-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a7791-cpg-mssr.c
@@ -9,7 +9,6 @@
  * Copyright (C) 2013 Ideas On Board SPRL
  */
 
-#include <common.h>
 #include <clk-uclass.h>
 #include <dm.h>
 #include <linux/bitops.h>
diff --git a/drivers/clk/renesas/r8a7792-cpg-mssr.c b/drivers/clk/renesas/r8a7792-cpg-mssr.c
index 496e51a..623981e 100644
--- a/drivers/clk/renesas/r8a7792-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a7792-cpg-mssr.c
@@ -9,7 +9,6 @@
  * Copyright (C) 2013 Ideas On Board SPRL
  */
 
-#include <common.h>
 #include <clk-uclass.h>
 #include <dm.h>
 #include <linux/bitops.h>
diff --git a/drivers/clk/renesas/r8a7794-cpg-mssr.c b/drivers/clk/renesas/r8a7794-cpg-mssr.c
index f1828a6..c412491 100644
--- a/drivers/clk/renesas/r8a7794-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a7794-cpg-mssr.c
@@ -9,7 +9,6 @@
  * Copyright (C) 2013 Ideas On Board SPRL
  */
 
-#include <common.h>
 #include <clk-uclass.h>
 #include <dm.h>
 #include <linux/bitops.h>
diff --git a/drivers/clk/renesas/r8a7795-cpg-mssr.c b/drivers/clk/renesas/r8a7795-cpg-mssr.c
index 0e9b9cc..e511f74 100644
--- a/drivers/clk/renesas/r8a7795-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a7795-cpg-mssr.c
@@ -10,7 +10,6 @@
  * Copyright (C) 2015 Renesas Electronics Corp.
  */
 
-#include <common.h>
 #include <clk-uclass.h>
 #include <dm.h>
 #include <linux/bitops.h>
diff --git a/drivers/clk/renesas/r8a7796-cpg-mssr.c b/drivers/clk/renesas/r8a7796-cpg-mssr.c
index d741d54..02b078a 100644
--- a/drivers/clk/renesas/r8a7796-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a7796-cpg-mssr.c
@@ -12,7 +12,6 @@
  * Copyright (C) 2015 Renesas Electronics Corp.
  */
 
-#include <common.h>
 #include <clk-uclass.h>
 #include <dm.h>
 #include <linux/bitops.h>
diff --git a/drivers/clk/renesas/r8a77965-cpg-mssr.c b/drivers/clk/renesas/r8a77965-cpg-mssr.c
index cf45038..037861e 100644
--- a/drivers/clk/renesas/r8a77965-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a77965-cpg-mssr.c
@@ -11,7 +11,6 @@
  * Copyright (C) 2015 Renesas Electronics Corp.
  */
 
-#include <common.h>
 #include <clk-uclass.h>
 #include <dm.h>
 #include <linux/bitops.h>
diff --git a/drivers/clk/renesas/r8a77970-cpg-mssr.c b/drivers/clk/renesas/r8a77970-cpg-mssr.c
index 32923b4..d8bb5aa 100644
--- a/drivers/clk/renesas/r8a77970-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a77970-cpg-mssr.c
@@ -9,7 +9,6 @@
  * Copyright (C) 2015 Glider bvba
  */
 
-#include <common.h>
 #include <clk-uclass.h>
 #include <dm.h>
 #include <linux/bitops.h>
diff --git a/drivers/clk/renesas/r8a77980-cpg-mssr.c b/drivers/clk/renesas/r8a77980-cpg-mssr.c
index f35032b..9d8335a 100644
--- a/drivers/clk/renesas/r8a77980-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a77980-cpg-mssr.c
@@ -10,7 +10,6 @@
  * Copyright (C) 2015 Glider bvba
  */
 
-#include <common.h>
 #include <clk-uclass.h>
 #include <dm.h>
 #include <linux/bitops.h>
diff --git a/drivers/clk/renesas/r8a77990-cpg-mssr.c b/drivers/clk/renesas/r8a77990-cpg-mssr.c
index 87b0666..4c9acd7 100644
--- a/drivers/clk/renesas/r8a77990-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a77990-cpg-mssr.c
@@ -10,7 +10,6 @@
  * Copyright (C) 2015 Renesas Electronics Corp.
  */
 
-#include <common.h>
 #include <clk-uclass.h>
 #include <dm.h>
 #include <linux/bitops.h>
diff --git a/drivers/clk/renesas/r8a77995-cpg-mssr.c b/drivers/clk/renesas/r8a77995-cpg-mssr.c
index dd2c948..f49faa4 100644
--- a/drivers/clk/renesas/r8a77995-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a77995-cpg-mssr.c
@@ -10,7 +10,6 @@
  * Copyright (C) 2015 Renesas Electronics Corp.
  */
 
-#include <common.h>
 #include <clk-uclass.h>
 #include <dm.h>
 #include <linux/bitops.h>
diff --git a/drivers/clk/renesas/r8a779a0-cpg-mssr.c b/drivers/clk/renesas/r8a779a0-cpg-mssr.c
index 652bfe4..ba086be 100644
--- a/drivers/clk/renesas/r8a779a0-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a779a0-cpg-mssr.c
@@ -10,7 +10,6 @@
  * Copyright (C) 2015 Renesas Electronics Corp.
  */
 
-#include <common.h>
 #include <clk-uclass.h>
 #include <dm.h>
 
diff --git a/drivers/clk/renesas/r8a779f0-cpg-mssr.c b/drivers/clk/renesas/r8a779f0-cpg-mssr.c
index 643e8b8..108655f 100644
--- a/drivers/clk/renesas/r8a779f0-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a779f0-cpg-mssr.c
@@ -7,7 +7,6 @@
  * Based on r8a779a0-cpg-mssr.c
  */
 
-#include <common.h>
 #include <clk-uclass.h>
 #include <dm.h>
 
diff --git a/drivers/clk/renesas/r8a779g0-cpg-mssr.c b/drivers/clk/renesas/r8a779g0-cpg-mssr.c
index 219024a..781806e 100644
--- a/drivers/clk/renesas/r8a779g0-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a779g0-cpg-mssr.c
@@ -7,7 +7,6 @@
  * Based on r8a779f0-cpg-mssr.c
  */
 
-#include <common.h>
 #include <clk-uclass.h>
 #include <dm.h>
 
diff --git a/drivers/clk/renesas/r9a06g032-clocks.c b/drivers/clk/renesas/r9a06g032-clocks.c
index d2f6123..d207bf6 100644
--- a/drivers/clk/renesas/r9a06g032-clocks.c
+++ b/drivers/clk/renesas/r9a06g032-clocks.c
@@ -7,7 +7,6 @@
  * Michel Pollet <michel.pollet@bp.renesas.com>, <buserror@gmail.com>
  */
 
-#include <common.h>
 #include <clk-uclass.h>
 #include <dm.h>
 #include <dm/device_compat.h>
diff --git a/drivers/clk/renesas/rcar-cpg-lib.c b/drivers/clk/renesas/rcar-cpg-lib.c
index a2fca66..8862fbc 100644
--- a/drivers/clk/renesas/rcar-cpg-lib.c
+++ b/drivers/clk/renesas/rcar-cpg-lib.c
@@ -10,7 +10,6 @@
  * Copyright (C) 2016 Glider bvba
  */
 
-#include <common.h>
 #include <clk-uclass.h>
 #include <dm.h>
 #include <errno.h>
diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c
index 10bd54d..35bad7f 100644
--- a/drivers/clk/renesas/renesas-cpg-mssr.c
+++ b/drivers/clk/renesas/renesas-cpg-mssr.c
@@ -9,7 +9,6 @@
  *
  * Copyright (C) 2016 Glider bvba
  */
-#include <common.h>
 #include <clk-uclass.h>
 #include <dm.h>
 #include <errno.h>
diff --git a/drivers/cpu/riscv_cpu.c b/drivers/cpu/riscv_cpu.c
index 034b9b4..a9b2537 100644
--- a/drivers/cpu/riscv_cpu.c
+++ b/drivers/cpu/riscv_cpu.c
@@ -45,7 +45,6 @@
 		ret = clk_get_rate(&clk);
 		if (!IS_ERR_VALUE(ret))
 			info->cpu_freq = ret;
-		clk_free(&clk);
 	}
 
 	if (!info->cpu_freq)
@@ -145,7 +144,6 @@
 		return 0;
 
 	ret = clk_enable(&clk);
-	clk_free(&clk);
 	if (ret == -ENOSYS || ret == -ENOTSUPP)
 		return 0;
 	else
diff --git a/drivers/dma/bcm6348-iudma.c b/drivers/dma/bcm6348-iudma.c
index d4cfe0c..33c7b98 100644
--- a/drivers/dma/bcm6348-iudma.c
+++ b/drivers/dma/bcm6348-iudma.c
@@ -596,8 +596,6 @@
 			pr_err("error enabling clock %d\n", i);
 			return ret;
 		}
-
-		clk_free(&clk);
 	}
 
 	/* try to perform resets */
diff --git a/drivers/gpio/at91_gpio.c b/drivers/gpio/at91_gpio.c
index 1409db5..f80f4af 100644
--- a/drivers/gpio/at91_gpio.c
+++ b/drivers/gpio/at91_gpio.c
@@ -603,8 +603,6 @@
 	if (ret)
 		return ret;
 
-	clk_free(&clk);
-
 #if CONFIG_IS_ENABLED(OF_CONTROL)
 	plat->base_addr = dev_read_addr(dev);
 #endif
diff --git a/drivers/gpio/atmel_pio4.c b/drivers/gpio/atmel_pio4.c
index 47ed297..be1dd75 100644
--- a/drivers/gpio/atmel_pio4.c
+++ b/drivers/gpio/atmel_pio4.c
@@ -310,8 +310,6 @@
 	if (ret)
 		return ret;
 
-	clk_free(&clk);
-
 	addr_base = dev_read_addr(dev);
 	if (addr_base == FDT_ADDR_T_NONE)
 		return -EINVAL;
diff --git a/drivers/gpio/gpio-rcar.c b/drivers/gpio/gpio-rcar.c
index d6cfbd2..7077850 100644
--- a/drivers/gpio/gpio-rcar.c
+++ b/drivers/gpio/gpio-rcar.c
@@ -165,7 +165,6 @@
 	}
 
 	ret = clk_enable(&clk);
-	clk_free(&clk);
 	if (ret) {
 		dev_err(dev, "Failed to enable GPIO bank clock\n");
 		return ret;
diff --git a/drivers/hwspinlock/stm32_hwspinlock.c b/drivers/hwspinlock/stm32_hwspinlock.c
index 46ed646..346b138 100644
--- a/drivers/hwspinlock/stm32_hwspinlock.c
+++ b/drivers/hwspinlock/stm32_hwspinlock.c
@@ -69,11 +69,7 @@
 	if (ret)
 		return ret;
 
-	ret = clk_enable(&clk);
-	if (ret)
-		clk_free(&clk);
-
-	return ret;
+	return clk_enable(&clk);
 }
 
 static const struct hwspinlock_ops stm32mp1_hwspinlock_ops = {
diff --git a/drivers/i2c/at91_i2c.c b/drivers/i2c/at91_i2c.c
index e743d2a..b7a2588 100644
--- a/drivers/i2c/at91_i2c.c
+++ b/drivers/i2c/at91_i2c.c
@@ -201,8 +201,6 @@
 
 	bus->bus_clk_rate = clk_rate;
 
-	clk_free(&clk);
-
 	return 0;
 }
 
diff --git a/drivers/i2c/designware_i2c.c b/drivers/i2c/designware_i2c.c
index 215ce01..29cf633 100644
--- a/drivers/i2c/designware_i2c.c
+++ b/drivers/i2c/designware_i2c.c
@@ -770,7 +770,6 @@
 
 	ret = clk_enable(&priv->clk);
 	if (ret && ret != -ENOSYS && ret != -ENOTSUPP) {
-		clk_free(&priv->clk);
 		dev_err(bus, "failed to enable clock\n");
 		return ret;
 	}
@@ -803,7 +802,6 @@
 
 #if CONFIG_IS_ENABLED(CLK)
 	clk_disable(&priv->clk);
-	clk_free(&priv->clk);
 #endif
 
 	return reset_release_bulk(&priv->resets);
diff --git a/drivers/i2c/i2c-microchip.c b/drivers/i2c/i2c-microchip.c
index d82b80f..d453e24 100644
--- a/drivers/i2c/i2c-microchip.c
+++ b/drivers/i2c/i2c-microchip.c
@@ -183,8 +183,6 @@
 	if (!clk_rate)
 		return -EINVAL;
 
-	clk_free(&bus->i2c_clk);
-
 	divisor = clk_rate / bus->clk_rate;
 
 	ctrl = readl(bus->base + MPFS_I2C_CTRL);
diff --git a/drivers/i2c/npcm_i2c.c b/drivers/i2c/npcm_i2c.c
index b867b6c..c64752e 100644
--- a/drivers/i2c/npcm_i2c.c
+++ b/drivers/i2c/npcm_i2c.c
@@ -570,7 +570,6 @@
 		printf("%s: fail to get rate\n", __func__);
 		return -EINVAL;
 	}
-	clk_free(&clk);
 
 	bus->num = dev->seq_;
 	bus->reg = dev_read_addr_ptr(dev);
diff --git a/drivers/i2c/ocores_i2c.c b/drivers/i2c/ocores_i2c.c
index 3b19ba7..fff8511 100644
--- a/drivers/i2c/ocores_i2c.c
+++ b/drivers/i2c/ocores_i2c.c
@@ -396,8 +396,6 @@
 
 	bus->ip_clk_khz = clk_rate / 1000;
 
-	clk_free(&bus->clk);
-
 	return 0;
 }
 
diff --git a/drivers/i2c/stm32f7_i2c.c b/drivers/i2c/stm32f7_i2c.c
index eaa1d69..f42e08a 100644
--- a/drivers/i2c/stm32f7_i2c.c
+++ b/drivers/i2c/stm32f7_i2c.c
@@ -890,7 +890,7 @@
 
 	ret = clk_enable(&i2c_priv->clk);
 	if (ret)
-		goto clk_free;
+		return ret;
 
 	ret = reset_get_by_index(dev, 0, &reset_ctl);
 	if (ret)
@@ -904,8 +904,6 @@
 
 clk_disable:
 	clk_disable(&i2c_priv->clk);
-clk_free:
-	clk_free(&i2c_priv->clk);
 
 	return ret;
 }
diff --git a/drivers/mailbox/stm32-ipcc.c b/drivers/mailbox/stm32-ipcc.c
index 69c86e0..046e1a8 100644
--- a/drivers/mailbox/stm32-ipcc.c
+++ b/drivers/mailbox/stm32-ipcc.c
@@ -134,18 +134,13 @@
 
 	ret = clk_enable(&clk);
 	if (ret)
-		goto clk_free;
+		return ret;
 
 	/* get channel number */
 	ipcc->n_chans = readl(ipcc->reg_base + IPCC_HWCFGR);
 	ipcc->n_chans &= IPCFGR_CHAN_MASK;
 
 	return 0;
-
-clk_free:
-	clk_free(&clk);
-
-	return ret;
 }
 
 static const struct udevice_id stm32_ipcc_ids[] = {
diff --git a/drivers/misc/ls2_sfp.c b/drivers/misc/ls2_sfp.c
index 2a81bc7..5351c7e 100644
--- a/drivers/misc/ls2_sfp.c
+++ b/drivers/misc/ls2_sfp.c
@@ -249,7 +249,6 @@
 		}
 
 		rate = clk_get_rate(&clk);
-		clk_free(&clk);
 		if (!rate || IS_ERR_VALUE(rate)) {
 			ret = rate ? rate : -ENOENT;
 			dev_dbg(dev, "could not get clock rate (err %d)\n",
diff --git a/drivers/misc/qfw_smbios.c b/drivers/misc/qfw_smbios.c
index 9019345..a898cb4 100644
--- a/drivers/misc/qfw_smbios.c
+++ b/drivers/misc/qfw_smbios.c
@@ -90,7 +90,7 @@
 		entry->length = sizeof(struct smbios3_entry);
 		entry->major_ver = entry2->major_ver;
 		entry->minor_ver = entry2->minor_ver;
-		entry->max_struct_size = entry2->max_struct_size;
+		entry->max_struct_size = entry2->struct_table_length;
 	} else {
 		ret = -ENOENT;
 		goto out;
diff --git a/drivers/mmc/arm_pl180_mmci.c b/drivers/mmc/arm_pl180_mmci.c
index 9c5d48e..5cf5502 100644
--- a/drivers/mmc/arm_pl180_mmci.c
+++ b/drivers/mmc/arm_pl180_mmci.c
@@ -447,7 +447,6 @@
 
 	ret = clk_enable(&clk);
 	if (ret) {
-		clk_free(&clk);
 		dev_err(dev, "failed to enable clock\n");
 		return ret;
 	}
diff --git a/drivers/mmc/aspeed_sdhci.c b/drivers/mmc/aspeed_sdhci.c
index 9d79bf5..c9626c6 100644
--- a/drivers/mmc/aspeed_sdhci.c
+++ b/drivers/mmc/aspeed_sdhci.c
@@ -35,7 +35,7 @@
 	ret = clk_enable(&clk);
 	if (ret) {
 		debug("%s: clock enable failed %d\n", __func__, ret);
-		goto free;
+		return ret;
 	}
 
 	host->name = dev->name;
@@ -66,8 +66,6 @@
 
 err:
 	clk_disable(&clk);
-free:
-	clk_free(&clk);
 	return ret;
 }
 
diff --git a/drivers/mmc/atmel_sdhci.c b/drivers/mmc/atmel_sdhci.c
index 5347ba9..d92bad9 100644
--- a/drivers/mmc/atmel_sdhci.c
+++ b/drivers/mmc/atmel_sdhci.c
@@ -147,8 +147,6 @@
 	host->ops = &atmel_sdhci_ops;
 	upriv->mmc = host->mmc;
 
-	clk_free(&clk);
-
 	ret = sdhci_probe(dev);
 	if (ret)
 		return ret;
diff --git a/drivers/mmc/gen_atmel_mci.c b/drivers/mmc/gen_atmel_mci.c
index d91819a..3ee9955 100644
--- a/drivers/mmc/gen_atmel_mci.c
+++ b/drivers/mmc/gen_atmel_mci.c
@@ -559,27 +559,20 @@
 	int ret = 0;
 
 	ret = clk_get_by_index(dev, 0, &clk);
-	if (ret) {
-		ret = -EINVAL;
-		goto failed;
-	}
+	if (ret)
+		return -EINVAL;
 
 	ret = clk_enable(&clk);
 	if (ret)
-		goto failed;
+		return ret;
 
 	clk_rate = clk_get_rate(&clk);
-	if (!clk_rate) {
-		ret = -EINVAL;
-		goto failed;
-	}
+	if (!clk_rate)
+		return -EINVAL;
 
 	priv->bus_clk_rate = clk_rate;
 
-failed:
-	clk_free(&clk);
-
-	return ret;
+	return 0;
 }
 
 static int atmel_mci_probe(struct udevice *dev)
diff --git a/drivers/mmc/msm_sdhci.c b/drivers/mmc/msm_sdhci.c
index 604f9c3..fe1e754 100644
--- a/drivers/mmc/msm_sdhci.c
+++ b/drivers/mmc/msm_sdhci.c
@@ -81,7 +81,6 @@
 		return ret;
 
 	ret = clk_set_rate(&clk, clk_rate);
-	clk_free(&clk);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/mmc/pic32_sdhci.c b/drivers/mmc/pic32_sdhci.c
index fe55510..7a8e33d 100644
--- a/drivers/mmc/pic32_sdhci.c
+++ b/drivers/mmc/pic32_sdhci.c
@@ -32,7 +32,6 @@
 		return ret;
 
 	clk_rate = clk_get_rate(&clk);
-	clk_free(&clk);
 
 	if (IS_ERR_VALUE(clk_rate))
 		return clk_rate;
diff --git a/drivers/mmc/renesas-sdhi.c b/drivers/mmc/renesas-sdhi.c
index 97aaf1e..a74559c 100644
--- a/drivers/mmc/renesas-sdhi.c
+++ b/drivers/mmc/renesas-sdhi.c
@@ -979,19 +979,19 @@
 	ret = clk_get_by_name(dev, "cd", &imclk2);
 	if (ret < 0) {
 		dev_err(dev, "failed to get imclk2 (chip detect clk)\n");
-		goto err_get_imclk2;
+		return ret;
 	}
 
 	ret = clk_get_by_name(dev, "aclk", &aclk);
 	if (ret < 0) {
 		dev_err(dev, "failed to get aclk\n");
-		goto err_get_aclk;
+		return ret;
 	}
 
 	ret = clk_enable(&imclk2);
 	if (ret < 0) {
 		dev_err(dev, "failed to enable imclk2 (chip detect clk)\n");
-		goto err_imclk2;
+		return ret;
 	}
 
 	ret = clk_enable(&aclk);
@@ -1026,11 +1026,6 @@
 	clk_disable(&aclk);
 err_aclk:
 	clk_disable(&imclk2);
-err_imclk2:
-	clk_free(&aclk);
-err_get_aclk:
-	clk_free(&imclk2);
-err_get_imclk2:
 	return ret;
 }
 
@@ -1071,7 +1066,7 @@
 		ret = clk_set_rate(&priv->clkh, 800000000);
 		if (ret < 0) {
 			dev_err(dev, "failed to set rate for SDnH clock (%d)\n", ret);
-			goto err_clk;
+			return ret;
 		}
 	}
 
@@ -1079,13 +1074,13 @@
 	ret = clk_set_rate(&priv->clk, 200000000);
 	if (ret < 0) {
 		dev_err(dev, "failed to set rate for SDn clock (%d)\n", ret);
-		goto err_clkh;
+		return ret;
 	}
 
 	ret = clk_enable(&priv->clk);
 	if (ret) {
 		dev_err(dev, "failed to enable SDn clock (%d)\n", ret);
-		goto err_clkh;
+		return ret;
 	}
 
 	if (device_is_compatible(dev, "renesas,sdhi-r9a07g044"))
@@ -1107,10 +1102,6 @@
 
 err_tmio_probe:
 	clk_disable(&priv->clk);
-err_clkh:
-	clk_free(&priv->clkh);
-err_clk:
-	clk_free(&priv->clk);
 	return ret;
 }
 
diff --git a/drivers/mmc/snps_dw_mmc.c b/drivers/mmc/snps_dw_mmc.c
index 50a8805..0134399 100644
--- a/drivers/mmc/snps_dw_mmc.c
+++ b/drivers/mmc/snps_dw_mmc.c
@@ -46,7 +46,7 @@
 
 	ret = clk_enable(&clk_ciu);
 	if (ret && ret != -ENOSYS && ret != -ENOTSUPP)
-		goto clk_err_ciu;
+		goto clk_err;
 
 	host->bus_hz = clk_get_rate(&clk_ciu);
 	if (host->bus_hz < CLOCK_MIN) {
@@ -60,16 +60,12 @@
 
 	ret = clk_enable(&clk_biu);
 	if (ret && ret != -ENOSYS && ret != -ENOTSUPP)
-		goto clk_err_biu;
+		goto clk_err_ciu_dis;
 
 	return 0;
 
-clk_err_biu:
-	clk_free(&clk_biu);
 clk_err_ciu_dis:
 	clk_disable(&clk_ciu);
-clk_err_ciu:
-	clk_free(&clk_ciu);
 clk_err:
 	dev_err(dev, "failed to setup clocks, ret %d\n", ret);
 
diff --git a/drivers/mmc/socfpga_dw_mmc.c b/drivers/mmc/socfpga_dw_mmc.c
index be3d8bf..387cb8b 100644
--- a/drivers/mmc/socfpga_dw_mmc.c
+++ b/drivers/mmc/socfpga_dw_mmc.c
@@ -99,7 +99,6 @@
 
 	host->bus_hz = clk_get_rate(&clk);
 
-	clk_free(&clk);
 #else
 	/* Fixed clock divide by 4 which due to the SDMMC wrapper */
 	host->bus_hz = cm_get_mmc_controller_clk_hz();
diff --git a/drivers/mmc/stm32_sdmmc2.c b/drivers/mmc/stm32_sdmmc2.c
index 5ff5e1a..a2b111a 100644
--- a/drivers/mmc/stm32_sdmmc2.c
+++ b/drivers/mmc/stm32_sdmmc2.c
@@ -766,10 +766,8 @@
 	int ret;
 
 	ret = clk_enable(&plat->clk);
-	if (ret) {
-		clk_free(&plat->clk);
+	if (ret)
 		return ret;
-	}
 
 	upriv->mmc = &plat->mmc;
 
diff --git a/drivers/mmc/uniphier-sd.c b/drivers/mmc/uniphier-sd.c
index 75003a0..8cde430 100644
--- a/drivers/mmc/uniphier-sd.c
+++ b/drivers/mmc/uniphier-sd.c
@@ -64,7 +64,6 @@
 	ret = clk_set_rate(&priv->clk, ULONG_MAX);
 	if (ret < 0) {
 		dev_err(dev, "failed to set rate for host clock\n");
-		clk_free(&priv->clk);
 		return ret;
 	}
 
diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
index c56840c..4fdc964 100644
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -9,6 +9,8 @@
 	  Enable the MTD stack, necessary to interact with NAND, NOR,
 	  SPI-NOR, SPI-NAND, OneNAND, etc.
 
+if MTD
+
 config DM_MTD
 	bool "Enable Driver Model for MTD drivers"
 	depends on DM
@@ -24,7 +26,6 @@
 
 config MTD_CONCAT
 	bool "Enable MTD device concatenation"
-	depends on MTD
 	help
 	  Enable support for concatenating multiple physical MTD devices
 	  into a single logical device. The larger logical device can then
@@ -32,7 +33,6 @@
 
 config SYS_MTDPARTS_RUNTIME
 	bool "Allow MTDPARTS to be configured at runtime"
-	depends on MTD
 	help
 	  This option allows to call the function board_mtdparts_default to
 	  dynamically build the variables mtdids and mtdparts at runtime.
@@ -272,4 +272,6 @@
 
 source "drivers/mtd/nvmxip/Kconfig"
 
+endif
+
 endmenu
diff --git a/drivers/mtd/nand/raw/atmel/nand-controller.c b/drivers/mtd/nand/raw/atmel/nand-controller.c
index a2151f9..0e04414 100644
--- a/drivers/mtd/nand/raw/atmel/nand-controller.c
+++ b/drivers/mtd/nand/raw/atmel/nand-controller.c
@@ -1999,10 +1999,8 @@
 
 	hsmc_nc = container_of(nc, struct atmel_hsmc_nand_controller, base);
 
-	if (hsmc_nc->clk) {
+	if (hsmc_nc->clk)
 		clk_disable_unprepare(hsmc_nc->clk);
-		devm_clk_put(nc->dev, hsmc_nc->clk);
-	}
 
 	return 0;
 }
diff --git a/drivers/mtd/renesas_rpc_hf.c b/drivers/mtd/renesas_rpc_hf.c
index aca7a6c..979b64d 100644
--- a/drivers/mtd/renesas_rpc_hf.c
+++ b/drivers/mtd/renesas_rpc_hf.c
@@ -370,7 +370,6 @@
 	}
 
 	ret = clk_enable(&clk);
-	clk_free(&clk);
 	if (ret) {
 		dev_err(dev, "Failed to enable RPC clock\n");
 		return ret;
diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index 3f5f3c8..f86003c 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -331,18 +331,42 @@
 				 u8 *val)
 {
 	struct spi_mem_op op =
-		SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDAR, 1),
-			   SPI_MEM_OP_ADDR(nor->addr_mode_nbytes, addr, 1),
-			   SPI_MEM_OP_DUMMY(dummy / 8, 1),
-			   SPI_MEM_OP_DATA_IN(1, NULL, 1));
+		SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RD_ANY_REG, 0),
+			   SPI_MEM_OP_ADDR(nor->addr_mode_nbytes, addr, 0),
+			   SPI_MEM_OP_DUMMY(dummy, 0),
+			   SPI_MEM_OP_DATA_IN(1, NULL, 0));
+	u8 buf[2];
+	int ret;
+
+	spi_nor_setup_op(nor, &op, nor->reg_proto);
 
-	return spi_nor_read_write_reg(nor, &op, val);
+	/*
+	 * In Octal DTR mode, the number of address bytes is always 4 regardless
+	 * of addressing mode setting.
+	 */
+	if (nor->reg_proto == SNOR_PROTO_8_8_8_DTR)
+		op.addr.nbytes = 4;
+
+	/*
+	 * We don't want to read only one byte in DTR mode. So, read 2 and then
+	 * discard the second byte.
+	 */
+	if (spi_nor_protocol_is_dtr(nor->reg_proto))
+		op.data.nbytes = 2;
+
+	ret = spi_nor_read_write_reg(nor, &op, buf);
+	if (ret)
+		return ret;
+
+	*val = buf[0];
+
+	return 0;
 }
 
 static int spansion_write_any_reg(struct spi_nor *nor, u32 addr, u8 val)
 {
 	struct spi_mem_op op =
-		SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WRAR, 1),
+		SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WR_ANY_REG, 1),
 			   SPI_MEM_OP_ADDR(nor->addr_mode_nbytes, addr, 1),
 			   SPI_MEM_OP_NO_DUMMY,
 			   SPI_MEM_OP_DATA_OUT(1, NULL, 1));
@@ -714,7 +738,7 @@
  */
 static int spansion_sr_ready(struct spi_nor *nor, u32 addr_base, u8 dummy)
 {
-	u32 reg_addr = addr_base + SPINOR_REG_ADDR_STR1V;
+	u32 reg_addr = addr_base + SPINOR_REG_CYPRESS_STR1V;
 	u8 sr;
 	int ret;
 
@@ -728,7 +752,7 @@
 		else
 			dev_dbg(nor->dev, "Programming Error occurred\n");
 
-		nor->write_reg(nor, SPINOR_OP_CLSR, NULL, 0);
+		nor->write_reg(nor, SPINOR_OP_CYPRESS_CLPEF, NULL, 0);
 		return -EIO;
 	}
 
@@ -1856,7 +1880,7 @@
 static int spansion_quad_enable_volatile(struct spi_nor *nor, u32 addr_base,
 					 u8 dummy)
 {
-	u32 addr = addr_base + SPINOR_REG_ADDR_CFR1V;
+	u32 addr = addr_base + SPINOR_REG_CYPRESS_CFR1V;
 
 	u8 cr;
 	int ret;
@@ -3293,11 +3317,11 @@
 	 * Read CR3V to check if uniform sector is selected. If not, assign an
 	 * erase hook that supports non-uniform erase.
 	 */
-	ret = spansion_read_any_reg(nor, SPINOR_REG_ADDR_CFR3V,
+	ret = spansion_read_any_reg(nor, SPINOR_REG_CYPRESS_CFR3V,
 				    S25FS_S_RDAR_DUMMY, &cfr3v);
 	if (ret)
 		return ret;
-	if (!(cfr3v & CFR3V_UNHYSA))
+	if (!(cfr3v & SPINOR_REG_CYPRESS_CFR3_UNISECT))
 		nor->erase = s25fs_s_erase_non_uniform;
 
 	return spi_nor_default_setup(nor, info, params);
@@ -3346,13 +3370,13 @@
 	.post_sfdp = s25fs_s_post_sfdp_fixup,
 };
 
-static int s25_mdp_ready(struct spi_nor *nor)
+static int s25_s28_mdp_ready(struct spi_nor *nor)
 {
 	u32 addr;
 	int ret;
 
 	for (addr = 0; addr < nor->mtd.size; addr += SZ_128M) {
-		ret = spansion_sr_ready(nor, addr, 0);
+		ret = spansion_sr_ready(nor, addr, nor->rdsr_dummy);
 		if (!ret)
 			return ret;
 	}
@@ -3374,15 +3398,15 @@
 	return 0;
 }
 
-static int s25_erase_non_uniform(struct spi_nor *nor, loff_t addr)
+static int s25_s28_erase_non_uniform(struct spi_nor *nor, loff_t addr)
 {
 	/* Support 32 x 4KB sectors at bottom */
 	return spansion_erase_non_uniform(nor, addr, SPINOR_OP_BE_4K_4B, 0,
 					  SZ_128K);
 }
 
-static int s25_setup(struct spi_nor *nor, const struct flash_info *info,
-		     const struct spi_nor_flash_parameter *params)
+static int s25_s28_setup(struct spi_nor *nor, const struct flash_info *info,
+			 const struct spi_nor_flash_parameter *params)
 {
 	int ret;
 	u8 cr;
@@ -3396,7 +3420,8 @@
 	 * uniform 128KB only due to complexity of non-uniform layout.
 	 */
 	if (nor->info->id[4] == S25FS256T_ID4) {
-		ret = spansion_read_any_reg(nor, SPINOR_REG_ADDR_ARCFN, 8, &cr);
+		ret = spansion_read_any_reg(nor, SPINOR_REG_CYPRESS_ARCFN, 8,
+					    &cr);
 		if (ret)
 			return ret;
 
@@ -3410,31 +3435,31 @@
 	 * Read CFR3V to check if uniform sector is selected. If not, assign an
 	 * erase hook that supports non-uniform erase.
 	 */
-	ret = spansion_read_any_reg(nor, SPINOR_REG_ADDR_CFR3V, 0, &cr);
+	ret = spansion_read_any_reg(nor, SPINOR_REG_CYPRESS_CFR3V, 0, &cr);
 	if (ret)
 		return ret;
-	if (!(cr & CFR3V_UNHYSA))
-		nor->erase = s25_erase_non_uniform;
+	if (!(cr & SPINOR_REG_CYPRESS_CFR3_UNISECT))
+		nor->erase = s25_s28_erase_non_uniform;
 
 	/*
 	 * For the multi-die package parts, the ready() hook is needed to check
 	 * all dies' status via read any register.
 	 */
 	if (nor->mtd.size > SZ_128M)
-		nor->ready = s25_mdp_ready;
+		nor->ready = s25_s28_mdp_ready;
 
 	return spi_nor_default_setup(nor, info, params);
 }
 
 static void s25_default_init(struct spi_nor *nor)
 {
-	nor->setup = s25_setup;
+	nor->setup = s25_s28_setup;
 }
 
-static int s25_post_bfpt_fixup(struct spi_nor *nor,
-			       const struct sfdp_parameter_header *header,
-			       const struct sfdp_bfpt *bfpt,
-			       struct spi_nor_flash_parameter *params)
+static int s25_s28_post_bfpt_fixup(struct spi_nor *nor,
+				   const struct sfdp_parameter_header *header,
+				   const struct sfdp_bfpt *bfpt,
+				   struct spi_nor_flash_parameter *params)
 {
 	int ret;
 	u32 addr;
@@ -3474,12 +3499,13 @@
 	 * dies are configured to 512B buffer.
 	 */
 	for (addr = 0; addr < params->size; addr += SZ_128M) {
-		ret = spansion_read_any_reg(nor, addr + SPINOR_REG_ADDR_CFR3V,
-					    0, &cfr3v);
+		ret = spansion_read_any_reg(nor,
+					    addr + SPINOR_REG_CYPRESS_CFR3V, 0,
+					    &cfr3v);
 		if (ret)
 			return ret;
 
-		if (!(cfr3v & CFR3V_PGMBUF)) {
+		if (!(cfr3v & SPINOR_REG_CYPRESS_CFR3_PGSZ)) {
 			params->page_size = 256;
 			return 0;
 		}
@@ -3507,7 +3533,7 @@
 
 static struct spi_nor_fixups s25_fixups = {
 	.default_init = s25_default_init,
-	.post_bfpt = s25_post_bfpt_fixup,
+	.post_bfpt = s25_s28_post_bfpt_fixup,
 	.post_sfdp = s25_post_sfdp_fixup,
 };
 
@@ -3539,97 +3565,57 @@
  */
 static int spi_nor_cypress_octal_dtr_enable(struct spi_nor *nor)
 {
-	struct spi_mem_op op;
+	u32 addr;
 	u8 buf;
-	u8 addr_width = 3;
 	int ret;
 
-	/* Use 24 dummy cycles for memory array reads. */
 	ret = write_enable(nor);
 	if (ret)
 		return ret;
 
-	buf = SPINOR_REG_CYPRESS_CFR2_MEMLAT_11_24;
-	op = (struct spi_mem_op)SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WR_ANY_REG, 1),
-			SPI_MEM_OP_ADDR(addr_width, SPINOR_REG_CYPRESS_CFR2V, 1),
-			SPI_MEM_OP_NO_DUMMY,
-			SPI_MEM_OP_DATA_OUT(1, &buf, 1));
-	ret = spi_mem_exec_op(nor->spi, &op);
-	if (ret) {
-		dev_warn(nor->dev,
-			 "failed to set default memory latency value: %d\n",
-			 ret);
-		return ret;
-	}
-	ret = spi_nor_wait_till_ready(nor);
-	if (ret)
-		return ret;
+	/* Use 24 dummy cycles for memory array reads. */
+	for (addr = 0; addr < nor->mtd.size; addr += SZ_128M) {
+		ret = spansion_read_any_reg(nor,
+					    addr + SPINOR_REG_CYPRESS_CFR2V, 0,
+					    &buf);
+		if (ret)
+			return ret;
 
+		buf &= ~SPINOR_REG_CYPRESS_CFR2_MEMLAT_MASK;
+		buf |= SPINOR_REG_CYPRESS_CFR2_MEMLAT_11_24;
+		ret = spansion_write_any_reg(nor,
+					     addr + SPINOR_REG_CYPRESS_CFR2V,
+					     buf);
+		if (ret) {
+			dev_warn(nor->dev, "failed to set default memory latency value: %d\n", ret);
+			return ret;
+		}
+	}
 	nor->read_dummy = 24;
 
-	/* Set the octal and DTR enable bits. */
 	ret = write_enable(nor);
 	if (ret)
 		return ret;
 
+	/* Set the octal and DTR enable bits. */
 	buf = SPINOR_REG_CYPRESS_CFR5_OCT_DTR_EN;
-	op = (struct spi_mem_op)SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WR_ANY_REG, 1),
-			SPI_MEM_OP_ADDR(addr_width, SPINOR_REG_CYPRESS_CFR5V, 1),
-			SPI_MEM_OP_NO_DUMMY,
-			SPI_MEM_OP_DATA_OUT(1, &buf, 1));
-	ret = spi_mem_exec_op(nor->spi, &op);
-	if (ret) {
-		dev_warn(nor->dev, "Failed to enable octal DTR mode\n");
-		return ret;
+	for (addr = 0; addr < nor->mtd.size; addr += SZ_128M) {
+		ret = spansion_write_any_reg(nor,
+					     addr + SPINOR_REG_CYPRESS_CFR5V,
+					     buf);
+		if (ret) {
+			dev_warn(nor->dev, "Failed to enable octal DTR mode\n");
+			return ret;
+		}
 	}
 
 	return 0;
 }
 
-static int s28hx_t_erase_non_uniform(struct spi_nor *nor, loff_t addr)
-{
-	/* Factory default configuration: 32 x 4 KiB sectors at bottom. */
-	return spansion_erase_non_uniform(nor, addr, SPINOR_OP_S28_SE_4K,
-					  0, SZ_128K);
-}
-
-static int s28hx_t_setup(struct spi_nor *nor, const struct flash_info *info,
-			 const struct spi_nor_flash_parameter *params)
-{
-	struct spi_mem_op op;
-	u8 buf;
-	u8 addr_width = 3;
-	int ret;
-
-	ret = spi_nor_wait_till_ready(nor);
-	if (ret)
-		return ret;
-
-	/*
-	 * Check CFR3V to check if non-uniform sector mode is selected. If it
-	 * is, set the erase hook to the non-uniform erase procedure.
-	 */
-	op = (struct spi_mem_op)
-		SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RD_ANY_REG, 1),
-			   SPI_MEM_OP_ADDR(addr_width,
-					   SPINOR_REG_CYPRESS_CFR3V, 1),
-			   SPI_MEM_OP_NO_DUMMY,
-			   SPI_MEM_OP_DATA_IN(1, &buf, 1));
-
-	ret = spi_mem_exec_op(nor->spi, &op);
-	if (ret)
-		return ret;
-
-	if (!(buf & SPINOR_REG_CYPRESS_CFR3_UNISECT))
-		nor->erase = s28hx_t_erase_non_uniform;
-
-	return spi_nor_default_setup(nor, info, params);
-}
-
 static void s28hx_t_default_init(struct spi_nor *nor)
 {
 	nor->octal_dtr_enable = spi_nor_cypress_octal_dtr_enable;
-	nor->setup = s28hx_t_setup;
+	nor->setup = s25_s28_setup;
 }
 
 static void s28hx_t_post_sfdp_fixup(struct spi_nor *nor,
@@ -3663,50 +3649,10 @@
 	params->rdsr_addr_nbytes = 4;
 }
 
-static int s28hx_t_post_bfpt_fixup(struct spi_nor *nor,
-				   const struct sfdp_parameter_header *bfpt_header,
-				   const struct sfdp_bfpt *bfpt,
-				   struct spi_nor_flash_parameter *params)
-{
-	struct spi_mem_op op;
-	u8 buf;
-	u8 addr_width = 3;
-	int ret;
-
-	/*
-	 * The BFPT table advertises a 512B page size but the page size is
-	 * actually configurable (with the default being 256B). Read from
-	 * CFR3V[4] and set the correct size.
-	 */
-	op = (struct spi_mem_op)
-		SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RD_ANY_REG, 1),
-			   SPI_MEM_OP_ADDR(addr_width, SPINOR_REG_CYPRESS_CFR3V, 1),
-			   SPI_MEM_OP_NO_DUMMY,
-			   SPI_MEM_OP_DATA_IN(1, &buf, 1));
-	ret = spi_mem_exec_op(nor->spi, &op);
-	if (ret)
-		return ret;
-
-	if (buf & SPINOR_REG_CYPRESS_CFR3_PGSZ)
-		params->page_size = 512;
-	else
-		params->page_size = 256;
-
-	/*
-	 * The BFPT advertises that it supports 4k erases, and the datasheet
-	 * says the same. But 4k erases did not work when testing. So, use 256k
-	 * erases for now.
-	 */
-	nor->erase_opcode = SPINOR_OP_SE_4B;
-	nor->mtd.erasesize = 0x40000;
-
-	return 0;
-}
-
 static struct spi_nor_fixups s28hx_t_fixups = {
 	.default_init = s28hx_t_default_init,
 	.post_sfdp = s28hx_t_post_sfdp_fixup,
-	.post_bfpt = s28hx_t_post_bfpt_fixup,
+	.post_bfpt = s25_s28_post_bfpt_fixup,
 };
 #endif /* CONFIG_SPI_FLASH_S28HX_T */
 
diff --git a/drivers/mtd/spi/spi-nor-ids.c b/drivers/mtd/spi/spi-nor-ids.c
index 8db522f..38a2874 100644
--- a/drivers/mtd/spi/spi-nor-ids.c
+++ b/drivers/mtd/spi/spi-nor-ids.c
@@ -239,6 +239,8 @@
 			SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
 	{ INFO("is25wx256",  0x9d5b19, 0, 128 * 1024, 256,
 			SECT_4K | USE_FSR | SPI_NOR_OCTAL_READ | SPI_NOR_4B_OPCODES) },
+	{ INFO("is25lx512",  0x9d5a1a, 0, 64 * 1024, 1024,
+			SECT_4K | USE_FSR | SPI_NOR_4B_OPCODES | SPI_NOR_HAS_TB) },
 #endif
 #ifdef CONFIG_SPI_FLASH_MACRONIX	/* MACRONIX */
 	/* Macronix */
@@ -381,6 +383,7 @@
 	{ INFO("s28hl01gt",  0x345a1b,      0, 256 * 1024, 512, SPI_NOR_OCTAL_DTR_READ) },
 	{ INFO("s28hs512t",  0x345b1a,      0, 256 * 1024, 256, SPI_NOR_OCTAL_DTR_READ) },
 	{ INFO("s28hs01gt",  0x345b1b,      0, 256 * 1024, 512, SPI_NOR_OCTAL_DTR_READ) },
+	{ INFO("s28hs02gt",  0x345b1c,      0, 256 * 1024, 1024, SPI_NOR_OCTAL_DTR_READ) },
 #endif
 #endif
 #ifdef CONFIG_SPI_FLASH_SST		/* SST */
@@ -554,6 +557,10 @@
 	{ INFO("XM25QH64C", 0x204017, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
 	{ INFO("XM25QH128A", 0x207018, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
 	{ INFO("XM25QU128C", 0x204118, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+	{ INFO("XM25QH256C", 0x204019, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
+	{ INFO("XM25QU256C", 0x204119, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
+	{ INFO("XM25QH512C", 0x204020, 0, 64 * 1024, 1024, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
+	{ INFO("XM25QU512C", 0x204120, 0, 64 * 1024, 1024, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
 #endif
 #ifdef CONFIG_SPI_FLASH_XTX
 	/* XTX Technology Limited */
diff --git a/drivers/net/bcm6348-eth.c b/drivers/net/bcm6348-eth.c
index 72dcd07..15a94f6 100644
--- a/drivers/net/bcm6348-eth.c
+++ b/drivers/net/bcm6348-eth.c
@@ -457,8 +457,6 @@
 			pr_err("%s: error enabling clock %d\n", __func__, i);
 			return ret;
 		}
-
-		clk_free(&clk);
 	}
 
 	/* try to perform resets */
diff --git a/drivers/net/bcm6368-eth.c b/drivers/net/bcm6368-eth.c
index fdd938c..9679a45 100644
--- a/drivers/net/bcm6368-eth.c
+++ b/drivers/net/bcm6368-eth.c
@@ -546,8 +546,6 @@
 			pr_err("%s: error enabling clock %d\n", __func__, i);
 			return ret;
 		}
-
-		clk_free(&clk);
 	}
 
 	/* try to perform resets */
diff --git a/drivers/net/designware.c b/drivers/net/designware.c
index a174344..c869635 100644
--- a/drivers/net/designware.c
+++ b/drivers/net/designware.c
@@ -702,7 +702,6 @@
 			err = clk_enable(&priv->clocks[i]);
 			if (err && err != -ENOSYS && err != -ENOTSUPP) {
 				pr_err("failed to enable clock %d\n", i);
-				clk_free(&priv->clocks[i]);
 				goto clk_err;
 			}
 			priv->clock_count++;
diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c
index e40e399..9b3bce1 100644
--- a/drivers/net/dwc_eth_qos.c
+++ b/drivers/net/dwc_eth_qos.c
@@ -1382,38 +1382,30 @@
 	ret = clk_get_by_name(dev, "master_bus", &eqos->clk_master_bus);
 	if (ret) {
 		pr_err("clk_get_by_name(master_bus) failed: %d", ret);
-		goto err_free_clk_slave_bus;
+		goto err_free_gpio_phy_reset;
 	}
 
 	ret = clk_get_by_name(dev, "rx", &eqos->clk_rx);
 	if (ret) {
 		pr_err("clk_get_by_name(rx) failed: %d", ret);
-		goto err_free_clk_master_bus;
+		goto err_free_gpio_phy_reset;
 	}
 
 	ret = clk_get_by_name(dev, "ptp_ref", &eqos->clk_ptp_ref);
 	if (ret) {
 		pr_err("clk_get_by_name(ptp_ref) failed: %d", ret);
-		goto err_free_clk_rx;
+		goto err_free_gpio_phy_reset;
 	}
 
 	ret = clk_get_by_name(dev, "tx", &eqos->clk_tx);
 	if (ret) {
 		pr_err("clk_get_by_name(tx) failed: %d", ret);
-		goto err_free_clk_ptp_ref;
+		goto err_free_gpio_phy_reset;
 	}
 
 	debug("%s: OK\n", __func__);
 	return 0;
 
-err_free_clk_ptp_ref:
-	clk_free(&eqos->clk_ptp_ref);
-err_free_clk_rx:
-	clk_free(&eqos->clk_rx);
-err_free_clk_master_bus:
-	clk_free(&eqos->clk_master_bus);
-err_free_clk_slave_bus:
-	clk_free(&eqos->clk_slave_bus);
 err_free_gpio_phy_reset:
 	dm_gpio_free(dev, &eqos->phy_reset_gpio);
 err_free_reset_eqos:
@@ -1451,13 +1443,13 @@
 	ret = clk_get_by_name(dev, "mac-clk-rx", &eqos->clk_rx);
 	if (ret) {
 		pr_err("clk_get_by_name(rx) failed: %d", ret);
-		goto err_free_clk_master_bus;
+		goto err_probe;
 	}
 
 	ret = clk_get_by_name(dev, "mac-clk-tx", &eqos->clk_tx);
 	if (ret) {
 		pr_err("clk_get_by_name(tx) failed: %d", ret);
-		goto err_free_clk_rx;
+		goto err_probe;
 	}
 
 	/*  Get ETH_CLK clocks (optional) */
@@ -1468,10 +1460,6 @@
 	debug("%s: OK\n", __func__);
 	return 0;
 
-err_free_clk_rx:
-	clk_free(&eqos->clk_rx);
-err_free_clk_master_bus:
-	clk_free(&eqos->clk_master_bus);
 err_probe:
 
 	debug("%s: returns %d\n", __func__, ret);
@@ -1489,13 +1477,6 @@
 
 	debug("%s(dev=%p):\n", __func__, dev);
 
-#ifdef CONFIG_CLK
-	clk_free(&eqos->clk_tx);
-	clk_free(&eqos->clk_ptp_ref);
-	clk_free(&eqos->clk_rx);
-	clk_free(&eqos->clk_slave_bus);
-	clk_free(&eqos->clk_master_bus);
-#endif
 	dm_gpio_free(dev, &eqos->phy_reset_gpio);
 	reset_free(&eqos->reset_ctl);
 
@@ -1505,19 +1486,7 @@
 
 static int eqos_remove_resources_stm32(struct udevice *dev)
 {
-	struct eqos_priv * __maybe_unused eqos = dev_get_priv(dev);
-
 	debug("%s(dev=%p):\n", __func__, dev);
-
-#ifdef CONFIG_CLK
-	clk_free(&eqos->clk_tx);
-	clk_free(&eqos->clk_rx);
-	clk_free(&eqos->clk_master_bus);
-	if (clk_valid(&eqos->clk_ck))
-		clk_free(&eqos->clk_ck);
-#endif
-
-	debug("%s: OK\n", __func__);
 	return 0;
 }
 
diff --git a/drivers/net/dwc_eth_qos_imx.c b/drivers/net/dwc_eth_qos_imx.c
index e3f55dd..9c4e390 100644
--- a/drivers/net/dwc_eth_qos_imx.c
+++ b/drivers/net/dwc_eth_qos_imx.c
@@ -70,30 +70,24 @@
 	ret = clk_get_by_name(dev, "ptp_ref", &eqos->clk_ptp_ref);
 	if (ret) {
 		dev_dbg(dev, "clk_get_by_name(ptp_ref) failed: %d", ret);
-		goto err_free_clk_master_bus;
+		goto err_probe;
 	}
 
 	ret = clk_get_by_name(dev, "tx", &eqos->clk_tx);
 	if (ret) {
 		dev_dbg(dev, "clk_get_by_name(tx) failed: %d", ret);
-		goto err_free_clk_ptp_ref;
+		goto err_probe;
 	}
 
 	ret = clk_get_by_name(dev, "pclk", &eqos->clk_ck);
 	if (ret) {
 		dev_dbg(dev, "clk_get_by_name(pclk) failed: %d", ret);
-		goto err_free_clk_tx;
+		goto err_probe;
 	}
 
 	debug("%s: OK\n", __func__);
 	return 0;
 
-err_free_clk_tx:
-	clk_free(&eqos->clk_tx);
-err_free_clk_ptp_ref:
-	clk_free(&eqos->clk_ptp_ref);
-err_free_clk_master_bus:
-	clk_free(&eqos->clk_master_bus);
 err_probe:
 
 	debug("%s: returns %d\n", __func__, ret);
@@ -102,16 +96,7 @@
 
 static int eqos_remove_resources_imx(struct udevice *dev)
 {
-	struct eqos_priv *eqos = dev_get_priv(dev);
-
 	debug("%s(dev=%p):\n", __func__, dev);
-
-	clk_free(&eqos->clk_ck);
-	clk_free(&eqos->clk_tx);
-	clk_free(&eqos->clk_ptp_ref);
-	clk_free(&eqos->clk_master_bus);
-
-	debug("%s: OK\n", __func__);
 	return 0;
 }
 
diff --git a/drivers/net/dwc_eth_qos_qcom.c b/drivers/net/dwc_eth_qos_qcom.c
index df83f1c..8178138 100644
--- a/drivers/net/dwc_eth_qos_qcom.c
+++ b/drivers/net/dwc_eth_qos_qcom.c
@@ -575,7 +575,6 @@
 
 	debug("%s(dev=%p):\n", __func__, dev);
 
-	clk_free(&eqos->clk_tx);
 	dm_gpio_free(dev, &eqos->phy_reset_gpio);
 	reset_free(&eqos->reset_ctl);
 
diff --git a/drivers/net/dwc_eth_qos_rockchip.c b/drivers/net/dwc_eth_qos_rockchip.c
index 834307a..fa9e513 100644
--- a/drivers/net/dwc_eth_qos_rockchip.c
+++ b/drivers/net/dwc_eth_qos_rockchip.c
@@ -372,7 +372,7 @@
 		ret = clk_get_by_name(dev, "clk_mac_speed", &eqos->clk_tx);
 		if (ret) {
 			dev_dbg(dev, "clk_get_by_name(clk_mac_speed) failed: %d", ret);
-			goto err_free_clk_master_bus;
+			goto err_release_resets;
 		}
 	}
 
@@ -393,8 +393,6 @@
 
 	return 0;
 
-err_free_clk_master_bus:
-	clk_free(&eqos->clk_master_bus);
 err_release_resets:
 	reset_release_bulk(&data->resets);
 err_free:
@@ -412,8 +410,6 @@
 	if (dm_gpio_is_valid(&eqos->phy_reset_gpio))
 		dm_gpio_free(dev, &eqos->phy_reset_gpio);
 
-	clk_free(&eqos->clk_tx);
-	clk_free(&eqos->clk_master_bus);
 	reset_release_bulk(&data->resets);
 	free(data);
 
diff --git a/drivers/net/phy/motorcomm.c b/drivers/net/phy/motorcomm.c
index 8635a96..a2c763c 100644
--- a/drivers/net/phy/motorcomm.c
+++ b/drivers/net/phy/motorcomm.c
@@ -23,6 +23,12 @@
 
 #define YTPHY_SYNCE_CFG_REG			0xA012
 
+#define YT8531_PAD_DRIVE_STRENGTH_CFG_REG		0xA010
+#define YT8531_RGMII_RXC_DS_MASK		GENMASK(15, 13)
+#define YT8531_RGMII_RXD_DS_HI_MASK		BIT(12)		/* Bit 2 of rxd_ds */
+#define YT8531_RGMII_RXD_DS_LOW_MASK		GENMASK(5, 4)	/* Bit 1/0 of rxd_ds */
+#define YT8531_RGMII_RX_DS_DEFAULT		0x3
+
 #define YTPHY_DTS_OUTPUT_CLK_DIS		0
 #define YTPHY_DTS_OUTPUT_CLK_25M		25000000
 #define YTPHY_DTS_OUTPUT_CLK_125M		125000000
@@ -114,6 +120,10 @@
 #define YT8531_CCR_RXC_DLY_EN			BIT(8)
 #define YT8531_CCR_RXC_DLY_1_900_NS		1900
 
+#define YT8531_CCR_CFG_LDO_MASK		GENMASK(5, 4)
+#define YT8531_CCR_CFG_LDO_3V3			0x0
+#define YT8531_CCR_CFG_LDO_1V8			0x2
+
 /* bits in struct ytphy_plat_priv->flag */
 #define TX_CLK_ADJ_ENABLED			BIT(0)
 #define AUTO_SLEEP_DISABLED			BIT(1)
@@ -224,6 +234,17 @@
 	return phy_modify(phydev, MDIO_DEVAD_NONE, YTPHY_PAGE_DATA, mask, set);
 }
 
+static int ytphy_read_ext(struct phy_device *phydev, u16 regnum)
+{
+	int ret;
+
+	ret = phy_write(phydev, MDIO_DEVAD_NONE, YTPHY_PAGE_SELECT, regnum);
+	if (ret < 0)
+		return ret;
+
+	return phy_read(phydev, MDIO_DEVAD_NONE, YTPHY_PAGE_DATA);
+}
+
 static int ytphy_rgmii_clk_delay_config(struct phy_device *phydev)
 {
 	struct ytphy_plat_priv	*priv = phydev->priv;
@@ -425,6 +446,111 @@
 	return 0;
 }
 
+/**
+ * struct ytphy_ldo_vol_map - map a current value to a register value
+ * @vol: ldo voltage
+ * @ds:  value in the register
+ * @cur: value in device configuration
+ */
+struct ytphy_ldo_vol_map {
+	u32 vol;
+	u32 ds;
+	u32 cur;
+};
+
+static const struct ytphy_ldo_vol_map yt8531_ldo_vol[] = {
+	{.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 0, .cur = 1200},
+	{.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 1, .cur = 2100},
+	{.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 2, .cur = 2700},
+	{.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 3, .cur = 2910},
+	{.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 4, .cur = 3110},
+	{.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 5, .cur = 3600},
+	{.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 6, .cur = 3970},
+	{.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 7, .cur = 4350},
+	{.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 0, .cur = 3070},
+	{.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 1, .cur = 4080},
+	{.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 2, .cur = 4370},
+	{.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 3, .cur = 4680},
+	{.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 4, .cur = 5020},
+	{.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 5, .cur = 5450},
+	{.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 6, .cur = 5740},
+	{.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 7, .cur = 6140},
+};
+
+static u32 yt8531_get_ldo_vol(struct phy_device *phydev)
+{
+	u32 val;
+
+	val = ytphy_read_ext(phydev, YT8531_CHIP_CONFIG_REG);
+	val = FIELD_GET(YT8531_CCR_CFG_LDO_MASK, val);
+
+	return val <= YT8531_CCR_CFG_LDO_1V8 ? val : YT8531_CCR_CFG_LDO_1V8;
+}
+
+static int yt8531_get_ds_map(struct phy_device *phydev, u32 cur)
+{
+	u32 vol;
+	int i;
+
+	vol = yt8531_get_ldo_vol(phydev);
+	for (i = 0; i < ARRAY_SIZE(yt8531_ldo_vol); i++) {
+		if (yt8531_ldo_vol[i].vol == vol && yt8531_ldo_vol[i].cur == cur)
+			return yt8531_ldo_vol[i].ds;
+	}
+
+	return -EINVAL;
+}
+
+static int yt8531_set_ds(struct phy_device *phydev)
+{
+	u32 ds_field_low, ds_field_hi, val;
+	int ret, ds;
+
+	/* set rgmii rx clk driver strength */
+	if (!ofnode_read_u32(phydev->node, "motorcomm,rx-clk-drv-microamp", &val)) {
+		ds = yt8531_get_ds_map(phydev, val);
+		if (ds < 0) {
+			pr_warn("No matching current value was found.");
+			return -EINVAL;
+		}
+	} else {
+		ds = YT8531_RGMII_RX_DS_DEFAULT;
+	}
+
+	ret = ytphy_modify_ext(phydev,
+			       YT8531_PAD_DRIVE_STRENGTH_CFG_REG,
+			       YT8531_RGMII_RXC_DS_MASK,
+			       FIELD_PREP(YT8531_RGMII_RXC_DS_MASK, ds));
+	if (ret < 0)
+		return ret;
+
+	/* set rgmii rx data driver strength */
+	if (!ofnode_read_u32(phydev->node, "motorcomm,rx-data-drv-microamp", &val)) {
+		ds = yt8531_get_ds_map(phydev, val);
+		if (ds < 0) {
+			pr_warn("No matching current value was found.");
+			return -EINVAL;
+		}
+	} else {
+		ds = YT8531_RGMII_RX_DS_DEFAULT;
+	}
+
+	ds_field_hi = FIELD_GET(BIT(2), ds);
+	ds_field_hi = FIELD_PREP(YT8531_RGMII_RXD_DS_HI_MASK, ds_field_hi);
+
+	ds_field_low = FIELD_GET(GENMASK(1, 0), ds);
+	ds_field_low = FIELD_PREP(YT8531_RGMII_RXD_DS_LOW_MASK, ds_field_low);
+
+	ret = ytphy_modify_ext(phydev,
+			       YT8531_PAD_DRIVE_STRENGTH_CFG_REG,
+			       YT8531_RGMII_RXD_DS_LOW_MASK | YT8531_RGMII_RXD_DS_HI_MASK,
+			       ds_field_low | ds_field_hi);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
 static int yt8531_config(struct phy_device *phydev)
 {
 	struct ytphy_plat_priv	*priv = phydev->priv;
@@ -487,6 +613,10 @@
 			return ret;
 	}
 
+	ret = yt8531_set_ds(phydev);
+	if (ret < 0)
+		return ret;
+
 	return 0;
 }
 
diff --git a/drivers/net/sni_ave.c b/drivers/net/sni_ave.c
index 8eeecbc..a265ce9 100644
--- a/drivers/net/sni_ave.c
+++ b/drivers/net/sni_ave.c
@@ -777,7 +777,7 @@
 		if (ret) {
 			dev_err(dev, "Failed to get clocks property: %d\n",
 				ret);
-			goto out_clk_free;
+			return ret;
 		}
 		priv->nclks++;
 	}
@@ -823,9 +823,6 @@
 out_reset_free:
 	while (--nr >= 0)
 		reset_free(&priv->rst[nr]);
-out_clk_free:
-	while (--nc >= 0)
-		clk_free(&priv->clk[nc]);
 
 	return ret;
 }
diff --git a/drivers/net/sun8i_emac.c b/drivers/net/sun8i_emac.c
index a12f7e3..8bff4fe 100644
--- a/drivers/net/sun8i_emac.c
+++ b/drivers/net/sun8i_emac.c
@@ -833,11 +833,8 @@
 	priv->use_internal_phy = false;
 
 	offset = fdtdec_lookup_phandle(gd->fdt_blob, node, "phy-handle");
-	if (offset < 0) {
-		debug("%s: Cannot find PHY address\n", __func__);
-		return -EINVAL;
-	}
-	priv->phyaddr = fdtdec_get_int(gd->fdt_blob, offset, "reg", -1);
+	if (offset >= 0)
+		priv->phyaddr = fdtdec_get_int(gd->fdt_blob, offset, "reg", -1);
 
 	pdata->phy_interface = dev_read_phy_mode(dev);
 	debug("phy interface %d\n", pdata->phy_interface);
diff --git a/drivers/net/ti/am65-cpsw-nuss.c b/drivers/net/ti/am65-cpsw-nuss.c
index 18a33c4..6da018c 100644
--- a/drivers/net/ti/am65-cpsw-nuss.c
+++ b/drivers/net/ti/am65-cpsw-nuss.c
@@ -948,7 +948,6 @@
 		 cpsw_common->bus_freq);
 
 out:
-	clk_free(&cpsw_common->fclk);
 	power_domain_free(&cpsw_common->pwrdmn);
 	return ret;
 }
diff --git a/drivers/phy/bcm6318-usbh-phy.c b/drivers/phy/bcm6318-usbh-phy.c
index 1c10853..a2fa446 100644
--- a/drivers/phy/bcm6318-usbh-phy.c
+++ b/drivers/phy/bcm6318-usbh-phy.c
@@ -98,8 +98,6 @@
 	if (ret < 0)
 		return ret;
 
-	clk_free(&clk);
-
 	/* enable power domain */
 	ret = power_domain_get(dev, &pwr_dom);
 	if (ret < 0)
diff --git a/drivers/phy/bcm6348-usbh-phy.c b/drivers/phy/bcm6348-usbh-phy.c
index ce6be3d..857fb57 100644
--- a/drivers/phy/bcm6348-usbh-phy.c
+++ b/drivers/phy/bcm6348-usbh-phy.c
@@ -62,8 +62,6 @@
 	if (ret < 0)
 		return ret;
 
-	clk_free(&clk);
-
 	/* perform reset */
 	ret = reset_get_by_index(dev, 0, &rst_ctl);
 	if (ret < 0)
diff --git a/drivers/phy/bcm6368-usbh-phy.c b/drivers/phy/bcm6368-usbh-phy.c
index d057f1f..1a2870d 100644
--- a/drivers/phy/bcm6368-usbh-phy.c
+++ b/drivers/phy/bcm6368-usbh-phy.c
@@ -137,8 +137,6 @@
 	if (ret < 0)
 		return ret;
 
-	clk_free(&clk);
-
 #if defined(CONFIG_POWER_DOMAIN)
 	/* enable power domain */
 	ret = power_domain_get(dev, &pwr_dom);
@@ -173,8 +171,6 @@
 		ret = clk_enable(&clk);
 		if (ret < 0)
 			return ret;
-
-		clk_free(&clk);
 	}
 
 	mdelay(100);
diff --git a/drivers/phy/meson-axg-mipi-dphy.c b/drivers/phy/meson-axg-mipi-dphy.c
index a69b6c9..faa1d9d 100644
--- a/drivers/phy/meson-axg-mipi-dphy.c
+++ b/drivers/phy/meson-axg-mipi-dphy.c
@@ -369,7 +369,6 @@
 	ret = clk_enable(&priv->clk);
 	if (ret && ret != -ENOSYS && ret != -ENOTSUPP) {
 		pr_err("failed to enable PHY clock\n");
-		clk_free(&priv->clk);
 		return ret;
 	}
 #endif
diff --git a/drivers/phy/meson-g12a-usb3-pcie.c b/drivers/phy/meson-g12a-usb3-pcie.c
index 40a5da9..1eaff41 100644
--- a/drivers/phy/meson-g12a-usb3-pcie.c
+++ b/drivers/phy/meson-g12a-usb3-pcie.c
@@ -398,7 +398,6 @@
 	ret = clk_enable(&priv->clk);
 	if (ret && ret != -ENOENT && ret != -ENOTSUPP) {
 		pr_err("failed to enable PHY clock\n");
-		clk_free(&priv->clk);
 		return ret;
 	}
 #endif
diff --git a/drivers/phy/meson-gxl-usb2.c b/drivers/phy/meson-gxl-usb2.c
index 8f5e4a4..d633eff 100644
--- a/drivers/phy/meson-gxl-usb2.c
+++ b/drivers/phy/meson-gxl-usb2.c
@@ -203,7 +203,6 @@
 	ret = clk_enable(&priv->clk);
 	if (ret && ret != -ENOSYS && ret != -ENOTSUPP) {
 		pr_err("failed to enable PHY clock\n");
-		clk_free(&priv->clk);
 		return ret;
 	}
 #endif
diff --git a/drivers/phy/phy-rcar-gen2.c b/drivers/phy/phy-rcar-gen2.c
index 1794095..e528c4e 100644
--- a/drivers/phy/phy-rcar-gen2.c
+++ b/drivers/phy/phy-rcar-gen2.c
@@ -172,7 +172,6 @@
 	struct rcar_gen2_phy *priv = dev_get_priv(dev);
 
 	clk_disable(&priv->clk);
-	clk_free(&priv->clk);
 
 	return 0;
 }
diff --git a/drivers/phy/phy-rcar-gen3.c b/drivers/phy/phy-rcar-gen3.c
index 7159e7e..03c747b 100644
--- a/drivers/phy/phy-rcar-gen3.c
+++ b/drivers/phy/phy-rcar-gen3.c
@@ -142,7 +142,6 @@
 	struct rcar_gen3_phy *priv = dev_get_priv(dev);
 
 	clk_disable(&priv->clk);
-	clk_free(&priv->clk);
 
 	return 0;
 }
diff --git a/drivers/pinctrl/pinctrl-k210.c b/drivers/pinctrl/pinctrl-k210.c
index 13f0a34..ee35dfe 100644
--- a/drivers/pinctrl/pinctrl-k210.c
+++ b/drivers/pinctrl/pinctrl-k210.c
@@ -691,23 +691,19 @@
 
 	ret = clk_enable(&priv->clk);
 	if (ret && ret != -ENOSYS && ret != -ENOTSUPP)
-		goto err;
+		return ret;
 
 	ret = dev_read_phandle_with_args(dev, "canaan,k210-sysctl-power",
 					NULL, 1, 0, &args);
         if (ret)
-		goto err;
+		return ret;
 
-	if (args.args_count != 1) {
-		ret = -EINVAL;
-		goto err;
-        }
+	if (args.args_count != 1)
+		return -EINVAL;
 
 	priv->sysctl = syscon_node_to_regmap(args.node);
-	if (IS_ERR(priv->sysctl)) {
-		ret = PTR_ERR(priv->sysctl);
-		goto err;
-	}
+	if (IS_ERR(priv->sysctl))
+		return PTR_ERR(priv->sysctl);
 
 	priv->power_offset = args.args[0];
 
@@ -728,10 +724,6 @@
 	}
 
 	return 0;
-
-err:
-	clk_free(&priv->clk);
-	return ret;
 }
 
 static const struct udevice_id k210_pc_ids[] = {
diff --git a/drivers/pinctrl/renesas/pfc-r8a7790.c b/drivers/pinctrl/renesas/pfc-r8a7790.c
index 7203648..e1811c4 100644
--- a/drivers/pinctrl/renesas/pfc-r8a7790.c
+++ b/drivers/pinctrl/renesas/pfc-r8a7790.c
@@ -8,7 +8,6 @@
  * Copyright (C) 2012  Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
  */
 
-#include <common.h>
 #include <dm.h>
 #include <errno.h>
 #include <dm/pinctrl.h>
diff --git a/drivers/pinctrl/renesas/pfc-r8a7791.c b/drivers/pinctrl/renesas/pfc-r8a7791.c
index b25453e..fa94a51 100644
--- a/drivers/pinctrl/renesas/pfc-r8a7791.c
+++ b/drivers/pinctrl/renesas/pfc-r8a7791.c
@@ -6,7 +6,6 @@
  * Copyright (C) 2014-2017 Cogent Embedded, Inc.
  */
 
-#include <common.h>
 #include <dm.h>
 #include <errno.h>
 #include <dm/pinctrl.h>
diff --git a/drivers/pinctrl/renesas/pfc-r8a7792.c b/drivers/pinctrl/renesas/pfc-r8a7792.c
index 08f1f97..7c1e6d4 100644
--- a/drivers/pinctrl/renesas/pfc-r8a7792.c
+++ b/drivers/pinctrl/renesas/pfc-r8a7792.c
@@ -6,7 +6,6 @@
  * Copyright (C) 2016 Cogent Embedded, Inc., <source@cogentembedded.com>
  */
 
-#include <common.h>
 #include <dm.h>
 #include <errno.h>
 #include <dm/pinctrl.h>
diff --git a/drivers/pinctrl/renesas/pfc-r8a7794.c b/drivers/pinctrl/renesas/pfc-r8a7794.c
index e5d125c..29eab26 100644
--- a/drivers/pinctrl/renesas/pfc-r8a7794.c
+++ b/drivers/pinctrl/renesas/pfc-r8a7794.c
@@ -7,7 +7,6 @@
  * Copyright (C) 2015-2017 Cogent Embedded, Inc. <source@cogentembedded.com>
  */
 
-#include <common.h>
 #include <dm.h>
 #include <errno.h>
 #include <dm/pinctrl.h>
diff --git a/drivers/pinctrl/renesas/pfc-r8a77951.c b/drivers/pinctrl/renesas/pfc-r8a77951.c
index 5d1c81c..81568ae 100644
--- a/drivers/pinctrl/renesas/pfc-r8a77951.c
+++ b/drivers/pinctrl/renesas/pfc-r8a77951.c
@@ -5,7 +5,6 @@
  * Copyright (C) 2015-2019 Renesas Electronics Corporation
  */
 
-#include <common.h>
 #include <dm.h>
 #include <errno.h>
 #include <dm/pinctrl.h>
diff --git a/drivers/pinctrl/renesas/pfc-r8a7796.c b/drivers/pinctrl/renesas/pfc-r8a7796.c
index 163d180..3de43fe 100644
--- a/drivers/pinctrl/renesas/pfc-r8a7796.c
+++ b/drivers/pinctrl/renesas/pfc-r8a7796.c
@@ -11,7 +11,6 @@
  * Copyright (C) 2015  Renesas Electronics Corporation
  */
 
-#include <common.h>
 #include <dm.h>
 #include <errno.h>
 #include <dm/pinctrl.h>
diff --git a/drivers/pinctrl/renesas/pfc-r8a77965.c b/drivers/pinctrl/renesas/pfc-r8a77965.c
index 377143d..3a6813c 100644
--- a/drivers/pinctrl/renesas/pfc-r8a77965.c
+++ b/drivers/pinctrl/renesas/pfc-r8a77965.c
@@ -12,7 +12,6 @@
  * Copyright (C) 2015  Renesas Electronics Corporation
  */
 
-#include <common.h>
 #include <dm.h>
 #include <errno.h>
 #include <dm/pinctrl.h>
diff --git a/drivers/pinctrl/renesas/pfc-r8a77970.c b/drivers/pinctrl/renesas/pfc-r8a77970.c
index 1cc6fa4..3c9c060 100644
--- a/drivers/pinctrl/renesas/pfc-r8a77970.c
+++ b/drivers/pinctrl/renesas/pfc-r8a77970.c
@@ -12,7 +12,6 @@
  * Copyright (C) 2015  Renesas Electronics Corporation
  */
 
-#include <common.h>
 #include <dm.h>
 #include <errno.h>
 #include <dm/pinctrl.h>
diff --git a/drivers/pinctrl/renesas/pfc-r8a77980.c b/drivers/pinctrl/renesas/pfc-r8a77980.c
index 523faa0..14a4b4d 100644
--- a/drivers/pinctrl/renesas/pfc-r8a77980.c
+++ b/drivers/pinctrl/renesas/pfc-r8a77980.c
@@ -12,7 +12,6 @@
  * Copyright (C) 2015 Renesas Electronics Corporation
  */
 
-#include <common.h>
 #include <dm.h>
 #include <errno.h>
 #include <dm/pinctrl.h>
diff --git a/drivers/pinctrl/renesas/pfc-r8a77990.c b/drivers/pinctrl/renesas/pfc-r8a77990.c
index 215a19e..e3a9c5e 100644
--- a/drivers/pinctrl/renesas/pfc-r8a77990.c
+++ b/drivers/pinctrl/renesas/pfc-r8a77990.c
@@ -11,7 +11,6 @@
  * Copyright (C) 2016-2017 Renesas Electronics Corp.
  */
 
-#include <common.h>
 #include <dm.h>
 #include <errno.h>
 #include <dm/pinctrl.h>
diff --git a/drivers/pinctrl/renesas/pfc-r8a77995.c b/drivers/pinctrl/renesas/pfc-r8a77995.c
index c0d6993..eccf5c1 100644
--- a/drivers/pinctrl/renesas/pfc-r8a77995.c
+++ b/drivers/pinctrl/renesas/pfc-r8a77995.c
@@ -11,7 +11,6 @@
  * Copyright (C) 2015  Renesas Electronics Corporation
  */
 
-#include <common.h>
 #include <dm.h>
 #include <errno.h>
 #include <dm/pinctrl.h>
diff --git a/drivers/pinctrl/renesas/pfc-r8a779a0.c b/drivers/pinctrl/renesas/pfc-r8a779a0.c
index 3c4b03b..6f89838 100644
--- a/drivers/pinctrl/renesas/pfc-r8a779a0.c
+++ b/drivers/pinctrl/renesas/pfc-r8a779a0.c
@@ -7,7 +7,6 @@
  * This file is based on the drivers/pinctrl/renesas/pfc-r8a7795.c
  */
 
-#include <common.h>
 #include <dm.h>
 #include <errno.h>
 #include <dm/pinctrl.h>
diff --git a/drivers/pinctrl/renesas/pfc-r8a779f0.c b/drivers/pinctrl/renesas/pfc-r8a779f0.c
index 5123e26..de5ec6c 100644
--- a/drivers/pinctrl/renesas/pfc-r8a779f0.c
+++ b/drivers/pinctrl/renesas/pfc-r8a779f0.c
@@ -7,7 +7,6 @@
  * This file is based on the drivers/pinctrl/renesas/pfc-r8a779a0.c
  */
 
-#include <common.h>
 #include <dm.h>
 #include <errno.h>
 #include <dm/pinctrl.h>
diff --git a/drivers/pinctrl/renesas/pfc-r8a779g0.c b/drivers/pinctrl/renesas/pfc-r8a779g0.c
index 20498a1..6749c15 100644
--- a/drivers/pinctrl/renesas/pfc-r8a779g0.c
+++ b/drivers/pinctrl/renesas/pfc-r8a779g0.c
@@ -7,7 +7,6 @@
  * This file is based on the drivers/pinctrl/renesas/pfc-r8a779a0.c
  */
 
-#include <common.h>
 #include <dm.h>
 #include <errno.h>
 #include <dm/pinctrl.h>
diff --git a/drivers/pinctrl/renesas/pfc.c b/drivers/pinctrl/renesas/pfc.c
index 3ac25cb..4ceb5db 100644
--- a/drivers/pinctrl/renesas/pfc.c
+++ b/drivers/pinctrl/renesas/pfc.c
@@ -11,7 +11,6 @@
 
 #define DRV_NAME "sh-pfc"
 
-#include <common.h>
 #include <dm.h>
 #include <errno.h>
 #include <dm/device_compat.h>
diff --git a/drivers/pinctrl/renesas/pinctrl-rza1.c b/drivers/pinctrl/renesas/pinctrl-rza1.c
index a445cdb..2d993be 100644
--- a/drivers/pinctrl/renesas/pinctrl-rza1.c
+++ b/drivers/pinctrl/renesas/pinctrl-rza1.c
@@ -5,7 +5,6 @@
  * Copyright (C) 2019 Marek Vasut <marek.vasut@gmail.com>
  */
 
-#include <common.h>
 #include <dm.h>
 #include <asm/global_data.h>
 #include <dm/lists.h>
diff --git a/drivers/power/domain/imx8mp-hsiomix.c b/drivers/power/domain/imx8mp-hsiomix.c
index 6a721a9..e2d772c 100644
--- a/drivers/power/domain/imx8mp-hsiomix.c
+++ b/drivers/power/domain/imx8mp-hsiomix.c
@@ -111,7 +111,7 @@
 
 	ret = power_domain_get_by_name(dev, &priv->pd_bus, "bus");
 	if (ret < 0)
-		goto err_pd_bus;
+		return ret;
 
 	ret = power_domain_get_by_name(dev, &priv->pd_usb, "usb");
 	if (ret < 0)
@@ -133,8 +133,6 @@
 	power_domain_free(&priv->pd_usb);
 err_pd_usb:
 	power_domain_free(&priv->pd_bus);
-err_pd_bus:
-	clk_free(&priv->clk_usb);
 	return ret;
 }
 
diff --git a/drivers/reset/reset-hisilicon.c b/drivers/reset/reset-hisilicon.c
index 8152cec..85e02b2 100644
--- a/drivers/reset/reset-hisilicon.c
+++ b/drivers/reset/reset-hisilicon.c
@@ -49,7 +49,18 @@
 static int hisi_reset_of_xlate(struct reset_ctl *rst,
 			       struct ofnode_phandle_args *args)
 {
-	if (args->args_count != 3) {
+	unsigned long polarity;
+
+	switch (args->args_count) {
+	case 2:
+		polarity = ASSERT_SET;
+		break;
+
+	case 3:
+		polarity = args->args[2];
+		break;
+
+	default:
 		debug("Invalid args_count: %d\n", args->args_count);
 		return -EINVAL;
 	}
@@ -57,7 +68,7 @@
 	/* Use .data field as register offset and .id field as bit shift */
 	rst->data = args->args[0];
 	rst->id = args->args[1];
-	rst->polarity = args->args[2];
+	rst->polarity = polarity;
 
 	return 0;
 }
diff --git a/drivers/rtc/stm32_rtc.c b/drivers/rtc/stm32_rtc.c
index 1753283..ec7584c 100644
--- a/drivers/rtc/stm32_rtc.c
+++ b/drivers/rtc/stm32_rtc.c
@@ -223,10 +223,8 @@
 		return ret;
 
 	ret = clk_enable(&clk);
-	if (ret) {
-		clk_free(&clk);
+	if (ret)
 		return ret;
-	}
 
 	rate = clk_get_rate(&clk);
 
@@ -275,10 +273,8 @@
 unlock:
 	stm32_rtc_lock(dev);
 
-	if (ret) {
+	if (ret)
 		clk_disable(&clk);
-		clk_free(&clk);
-	}
 
 	return ret;
 }
@@ -298,17 +294,13 @@
 		return ret;
 
 	ret = clk_enable(&clk);
-	if (ret) {
-		clk_free(&clk);
+	if (ret)
 		return ret;
-	}
 
 	ret = stm32_rtc_init(dev);
 
-	if (ret) {
+	if (ret)
 		clk_disable(&clk);
-		clk_free(&clk);
-	}
 
 	return ret;
 }
diff --git a/drivers/serial/atmel_usart.c b/drivers/serial/atmel_usart.c
index 9853f49..9827c00 100644
--- a/drivers/serial/atmel_usart.c
+++ b/drivers/serial/atmel_usart.c
@@ -253,8 +253,6 @@
 
 	priv->usart_clk_rate = clk_rate;
 
-	clk_free(&clk);
-
 	return 0;
 }
 #endif
diff --git a/drivers/serial/serial_bcm6345.c b/drivers/serial/serial_bcm6345.c
index 2359656..13bc517 100644
--- a/drivers/serial/serial_bcm6345.c
+++ b/drivers/serial/serial_bcm6345.c
@@ -239,7 +239,6 @@
 	if (ret < 0)
 		return ret;
 	priv->uartclk = clk_get_rate(&clk);
-	clk_free(&clk);
 
 	/* initialize serial */
 	return bcm6345_serial_init(priv->base, priv->uartclk, CONFIG_BAUDRATE);
diff --git a/drivers/serial/serial_msm.c b/drivers/serial/serial_msm.c
index a22623c..f4d9631 100644
--- a/drivers/serial/serial_msm.c
+++ b/drivers/serial/serial_msm.c
@@ -185,7 +185,6 @@
 		return ret;
 
 	ret = clk_set_rate(&clk, clk_rate);
-	clk_free(&clk);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/serial/serial_pic32.c b/drivers/serial/serial_pic32.c
index 3c5d37c..0a03a9a 100644
--- a/drivers/serial/serial_pic32.c
+++ b/drivers/serial/serial_pic32.c
@@ -155,7 +155,6 @@
 	if (ret < 0)
 		return ret;
 	priv->uartclk = clk_get_rate(&clk);
-	clk_free(&clk);
 
 	/* initialize serial */
 	return pic32_serial_init(priv->base, priv->uartclk, CONFIG_BAUDRATE);
diff --git a/drivers/spi/atcspi200_spi.c b/drivers/spi/atcspi200_spi.c
index de9c148..70cb242 100644
--- a/drivers/spi/atcspi200_spi.c
+++ b/drivers/spi/atcspi200_spi.c
@@ -362,7 +362,6 @@
 		return -EINVAL;
 
 	ns->clock = clk_rate;
-	clk_free(&clk);
 
 	return 0;
 }
diff --git a/drivers/spi/atmel-quadspi.c b/drivers/spi/atmel-quadspi.c
index cb64119..bd73e4f 100644
--- a/drivers/spi/atmel-quadspi.c
+++ b/drivers/spi/atmel-quadspi.c
@@ -877,7 +877,6 @@
 	ret = clk_enable(&gclk);
 	if (ret)
 		dev_err(bus, "Failed to enable QSPI generic clock\n");
-	clk_free(&gclk);
 
 	return ret;
 }
@@ -1000,7 +999,7 @@
 	ret = clk_enable(&pclk);
 	if (ret) {
 		dev_err(dev, "Failed to enable QSPI peripheral clock\n");
-		goto free_pclk;
+		return ret;
 	}
 
 	if (aq->caps->has_qspick) {
@@ -1008,32 +1007,27 @@
 		ret = clk_get_by_name(dev, "qspick", &qspick);
 		if (ret) {
 			dev_err(dev, "Missing QSPI peripheral clock\n");
-			goto free_pclk;
+			return ret;
 		}
 
 		ret = clk_enable(&qspick);
 		if (ret)
 			dev_err(dev, "Failed to enable QSPI system clock\n");
-		clk_free(&qspick);
 	} else if (aq->caps->has_gclk) {
 		ret = clk_get_by_name(dev, "gclk", &gclk);
 		if (ret) {
 			dev_err(dev, "Missing QSPI generic clock\n");
-			goto free_pclk;
+			return ret;
 		}
 
 		ret = clk_enable(&gclk);
 		if (ret)
 			dev_err(dev, "Failed to enable QSPI system clock\n");
-		clk_free(&gclk);
 	}
 
 	aq->bus_clk_rate = clk_get_rate(&pclk);
 	if (!aq->bus_clk_rate)
-		ret = -EINVAL;
-
-free_pclk:
-	clk_free(&pclk);
+		return -EINVAL;
 
 	return ret;
 }
diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c
index aec6f4e..d4f0c4c 100644
--- a/drivers/spi/atmel_spi.c
+++ b/drivers/spi/atmel_spi.c
@@ -338,8 +338,6 @@
 
 	priv->bus_clk_rate = clk_rate;
 
-	clk_free(&clk);
-
 	return 0;
 }
 
diff --git a/drivers/spi/bcm63xx_hsspi.c b/drivers/spi/bcm63xx_hsspi.c
index 19d9a5a..23ac5bb 100644
--- a/drivers/spi/bcm63xx_hsspi.c
+++ b/drivers/spi/bcm63xx_hsspi.c
@@ -581,8 +581,6 @@
 	if (ret < 0 && ret != -ENOSYS)
 		return ret;
 
-	clk_free(&clk);
-
 	/* get clock rate */
 	ret = clk_get_by_name(dev, "pll", &clk);
 	if (ret < 0 && ret != -ENOSYS)
@@ -590,8 +588,6 @@
 
 	priv->clk_rate = clk_get_rate(&clk);
 
-	clk_free(&clk);
-
 	/* perform reset */
 	ret = reset_get_by_index(dev, 0, &rst_ctl);
 	if (ret >= 0) {
diff --git a/drivers/spi/bcm63xx_spi.c b/drivers/spi/bcm63xx_spi.c
index 0600d56..889ac1f 100644
--- a/drivers/spi/bcm63xx_spi.c
+++ b/drivers/spi/bcm63xx_spi.c
@@ -391,8 +391,6 @@
 	if (ret < 0)
 		return ret;
 
-	clk_free(&clk);
-
 	/* perform reset */
 	ret = reset_get_by_index(dev, 0, &rst_ctl);
 	if (ret < 0)
diff --git a/drivers/spi/bcmbca_hsspi.c b/drivers/spi/bcmbca_hsspi.c
index fbe315a..af45882 100644
--- a/drivers/spi/bcmbca_hsspi.c
+++ b/drivers/spi/bcmbca_hsspi.c
@@ -375,8 +375,6 @@
 	if (ret < 0 && ret != -ENOSYS)
 		return ret;
 
-	clk_free(&clk);
-
 	/* get clock rate */
 	ret = clk_get_by_name(dev, "pll", &clk);
 	if (ret < 0 && ret != -ENOSYS)
@@ -384,8 +382,6 @@
 
 	priv->clk_rate = clk_get_rate(&clk);
 
-	clk_free(&clk);
-
 	/* initialize hardware */
 	writel(0, priv->regs + SPI_IR_MASK_REG);
 
diff --git a/drivers/spi/cadence_ospi_versal.c b/drivers/spi/cadence_ospi_versal.c
index e02a3b3..c2be307 100644
--- a/drivers/spi/cadence_ospi_versal.c
+++ b/drivers/spi/cadence_ospi_versal.c
@@ -18,9 +18,6 @@
 #include "cadence_qspi.h"
 #include <dt-bindings/power/xlnx-versal-power.h>
 
-#define CMD_4BYTE_READ  0x13
-#define CMD_4BYTE_FAST_READ  0x0C
-
 int cadence_qspi_apb_dma_read(struct cadence_spi_priv *priv,
 			      const struct spi_mem_op *op)
 {
diff --git a/drivers/spi/cadence_qspi.c b/drivers/spi/cadence_qspi.c
index dfc74c8..f4593c4 100644
--- a/drivers/spi/cadence_qspi.c
+++ b/drivers/spi/cadence_qspi.c
@@ -236,7 +236,6 @@
 #endif
 		} else {
 			priv->ref_clk_hz = clk_get_rate(&clk);
-			clk_free(&clk);
 			if (IS_ERR_VALUE(priv->ref_clk_hz))
 				return priv->ref_clk_hz;
 		}
diff --git a/drivers/spi/cadence_qspi.h b/drivers/spi/cadence_qspi.h
index 12825f8..693474a 100644
--- a/drivers/spi/cadence_qspi.h
+++ b/drivers/spi/cadence_qspi.h
@@ -33,6 +33,10 @@
 #define CQSPI_DUMMY_BYTES_MAX                   4
 #define CQSPI_DUMMY_CLKS_MAX                    31
 
+#define CMD_4BYTE_FAST_READ			0x0C
+#define CMD_4BYTE_OCTAL_READ			0x7c
+#define CMD_4BYTE_READ				0x13
+
 /****************************************************************************
  * Controller's configuration and status register (offset from QSPI_BASE)
  ****************************************************************************/
diff --git a/drivers/spi/cadence_qspi_apb.c b/drivers/spi/cadence_qspi_apb.c
index d033184..fb90532 100644
--- a/drivers/spi/cadence_qspi_apb.c
+++ b/drivers/spi/cadence_qspi_apb.c
@@ -469,6 +469,9 @@
 	else
 		opcode = op->cmd.opcode;
 
+	if (opcode == CMD_4BYTE_OCTAL_READ && !priv->dtr)
+		opcode = CMD_4BYTE_FAST_READ;
+
 	reg = opcode << CQSPI_REG_CMDCTRL_OPCODE_LSB;
 
 	/* Set up dummy cycles. */
diff --git a/drivers/spi/designware_spi.c b/drivers/spi/designware_spi.c
index 1c7d0ca..22a79da 100644
--- a/drivers/spi/designware_spi.c
+++ b/drivers/spi/designware_spi.c
@@ -111,6 +111,9 @@
 #define SR_TX_ERR			BIT(5)
 #define SR_DCOL				BIT(6)
 
+/* Bit field in RISR */
+#define RISR_INT_RXOI			BIT(3)
+
 #define RX_TIMEOUT			1000		/* timeout in ms */
 
 struct dw_spi_plat {
@@ -316,7 +319,6 @@
 
 err_rate:
 	clk_disable(&priv->clk);
-	clk_free(&priv->clk);
 
 	return -EINVAL;
 }
@@ -588,7 +590,7 @@
 	struct dw_spi_priv *priv = dev_get_priv(bus);
 	u8 op_len = op->cmd.nbytes + op->addr.nbytes + op->dummy.nbytes;
 	u8 op_buf[op_len];
-	u32 cr0;
+	u32 cr0, sts;
 
 	if (read)
 		priv->tmode = CTRLR0_TMOD_EPROMREAD;
@@ -632,12 +634,21 @@
 	 * them to fail because we are not reading/writing the fifo fast enough.
 	 */
 	if (read) {
-		priv->rx = op->data.buf.in;
+		void *prev_rx = priv->rx = op->data.buf.in;
 		priv->rx_end = priv->rx + op->data.nbytes;
 
 		dw_write(priv, DW_SPI_SER, 1 << spi_chip_select(slave->dev));
-		while (priv->rx != priv->rx_end)
+		while (priv->rx != priv->rx_end) {
 			dw_reader(priv);
+			if (prev_rx == priv->rx) {
+				sts = dw_read(priv, DW_SPI_RISR);
+				if (sts & RISR_INT_RXOI) {
+					dev_err(bus, "FIFO overflow on Rx\n");
+					return -EIO;
+				}
+			}
+			prev_rx = priv->rx;
+		}
 	} else {
 		u32 val;
 
@@ -731,10 +742,6 @@
 	ret = clk_disable(&priv->clk);
 	if (ret)
 		return ret;
-
-	clk_free(&priv->clk);
-	if (ret)
-		return ret;
 #endif
 	return 0;
 }
diff --git a/drivers/spi/meson_spifc_a1.c b/drivers/spi/meson_spifc_a1.c
index cca4deb..943bf69 100644
--- a/drivers/spi/meson_spifc_a1.c
+++ b/drivers/spi/meson_spifc_a1.c
@@ -343,15 +343,6 @@
 	return 0;
 }
 
-static int amlogic_spifc_a1_remove(struct udevice *dev)
-{
-	struct amlogic_spifc_a1 *spifc = dev_get_priv(dev);
-
-	clk_free(&spifc->clk);
-
-	return 0;
-}
-
 static const struct udevice_id meson_spifc_ids[] = {
 	{ .compatible = "amlogic,a1-spifc", },
 	{ }
@@ -379,6 +370,5 @@
 	.of_match	= meson_spifc_ids,
 	.ops		= &amlogic_spifc_a1_ops,
 	.probe		= amlogic_spifc_a1_probe,
-	.remove		= amlogic_spifc_a1_remove,
 	.priv_auto	= sizeof(struct amlogic_spifc_a1),
 };
diff --git a/drivers/spi/mvebu_a3700_spi.c b/drivers/spi/mvebu_a3700_spi.c
index 52882e8..bba2383 100644
--- a/drivers/spi/mvebu_a3700_spi.c
+++ b/drivers/spi/mvebu_a3700_spi.c
@@ -296,15 +296,6 @@
 	return 0;
 }
 
-static int mvebu_spi_remove(struct udevice *bus)
-{
-	struct mvebu_spi_plat *plat = dev_get_plat(bus);
-
-	clk_free(&plat->clk);
-
-	return 0;
-}
-
 static const struct dm_spi_ops mvebu_spi_ops = {
 	.xfer		= mvebu_spi_xfer,
 	.set_speed	= mvebu_spi_set_speed,
@@ -328,5 +319,4 @@
 	.of_to_plat = mvebu_spi_of_to_plat,
 	.plat_auto	= sizeof(struct mvebu_spi_plat),
 	.probe = mvebu_spi_probe,
-	.remove = mvebu_spi_remove,
 };
diff --git a/drivers/spi/spi-aspeed-smc.c b/drivers/spi/spi-aspeed-smc.c
index 3962031..7d5f101 100644
--- a/drivers/spi/spi-aspeed-smc.c
+++ b/drivers/spi/spi-aspeed-smc.c
@@ -1148,7 +1148,6 @@
 	}
 
 	plat->hclk_rate = clk_get_rate(&hclk);
-	clk_free(&hclk);
 
 	dev_dbg(bus, "ctrl_base = 0x%x, ahb_base = 0x%p, size = 0x%llx\n",
 		(u32)priv->regs, plat->ahb_base, (fdt64_t)plat->ahb_sz);
diff --git a/drivers/spi/stm32_spi.c b/drivers/spi/stm32_spi.c
index 82f6ed7..ddb410a 100644
--- a/drivers/spi/stm32_spi.c
+++ b/drivers/spi/stm32_spi.c
@@ -526,22 +526,16 @@
 
 	ret = reset_get_by_index(dev, 0, &plat->rst_ctl);
 	if (ret < 0)
-		goto clk_err;
+		return ret;
 
 	ret = gpio_request_list_by_name(dev, "cs-gpios", plat->cs_gpios,
 					ARRAY_SIZE(plat->cs_gpios), 0);
 	if (ret < 0) {
 		dev_err(dev, "Can't get %s cs gpios: %d", dev->name, ret);
-		ret = -ENOENT;
-		goto clk_err;
+		return -ENOENT;
 	}
 
 	return 0;
-
-clk_err:
-	clk_free(&plat->clk);
-
-	return ret;
 }
 
 static int stm32_spi_probe(struct udevice *dev)
@@ -610,7 +604,6 @@
 
 clk_err:
 	clk_disable(&plat->clk);
-	clk_free(&plat->clk);
 
 	return ret;
 };
@@ -630,13 +623,7 @@
 
 	reset_free(&plat->rst_ctl);
 
-	ret = clk_disable(&plat->clk);
-	if (ret < 0)
-		return ret;
-
-	clk_free(&plat->clk);
-
-	return ret;
+	return clk_disable(&plat->clk);
 };
 
 static const struct dm_spi_ops stm32_spi_ops = {
diff --git a/drivers/timer/dw-apb-timer.c b/drivers/timer/dw-apb-timer.c
index 6cd2525..0607f75 100644
--- a/drivers/timer/dw-apb-timer.c
+++ b/drivers/timer/dw-apb-timer.c
@@ -74,8 +74,6 @@
 			return ret;
 
 		uc_priv->clock_rate = clk_get_rate(&clk);
-
-		clk_free(&clk);
 	}
 
 	/* init timer */
diff --git a/drivers/timer/ostm_timer.c b/drivers/timer/ostm_timer.c
index 3ec729d..3bf0d46 100644
--- a/drivers/timer/ostm_timer.c
+++ b/drivers/timer/ostm_timer.c
@@ -49,8 +49,6 @@
 		return ret;
 
 	uc_priv->clock_rate = clk_get_rate(&clk);
-
-	clk_free(&clk);
 #else
 	uc_priv->clock_rate = get_board_sys_clk() / 2;
 #endif
diff --git a/drivers/usb/dwc3/dwc3-meson-g12a.c b/drivers/usb/dwc3/dwc3-meson-g12a.c
index 1960352..1a3e935 100644
--- a/drivers/usb/dwc3/dwc3-meson-g12a.c
+++ b/drivers/usb/dwc3/dwc3-meson-g12a.c
@@ -361,10 +361,8 @@
 
 #if CONFIG_IS_ENABLED(CLK)
 	ret = clk_enable(&priv->clk);
-	if (ret) {
-		clk_free(&priv->clk);
+	if (ret)
 		return ret;
-	}
 #endif
 
 	return 0;
diff --git a/drivers/usb/dwc3/dwc3-meson-gxl.c b/drivers/usb/dwc3/dwc3-meson-gxl.c
index cbe8aaa..2ce9157 100644
--- a/drivers/usb/dwc3/dwc3-meson-gxl.c
+++ b/drivers/usb/dwc3/dwc3-meson-gxl.c
@@ -284,10 +284,8 @@
 
 #if CONFIG_IS_ENABLED(CLK)
 	ret = clk_enable(&priv->clk);
-	if (ret) {
-		clk_free(&priv->clk);
+	if (ret)
 		return ret;
-	}
 #endif
 
 	return 0;
diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c
index fba3595..c6d50fd 100644
--- a/drivers/usb/host/ehci-atmel.c
+++ b/drivers/usb/host/ehci-atmel.c
@@ -70,13 +70,7 @@
 	if (ret)
 		return -EINVAL;
 
-	ret = clk_enable(&clk);
-	if (ret)
-		return ret;
-
-	clk_free(&clk);
-
-	return 0;
+	return clk_enable(&clk);
 }
 
 static int ehci_atmel_probe(struct udevice *dev)
diff --git a/drivers/usb/host/ohci-da8xx.c b/drivers/usb/host/ohci-da8xx.c
index 33c4a91..d3d73d2 100644
--- a/drivers/usb/host/ohci-da8xx.c
+++ b/drivers/usb/host/ohci-da8xx.c
@@ -115,7 +115,6 @@
 			err = clk_enable(&priv->clocks[i]);
 			if (err) {
 				dev_err(dev, "failed to enable clock %d\n", i);
-				clk_free(&priv->clocks[i]);
 				goto clk_err;
 			}
 			priv->clock_count++;
diff --git a/drivers/usb/host/xhci-rcar.c b/drivers/usb/host/xhci-rcar.c
index 5fc7afb..fedcf78 100644
--- a/drivers/usb/host/xhci-rcar.c
+++ b/drivers/usb/host/xhci-rcar.c
@@ -90,7 +90,7 @@
 	ret = clk_enable(&plat->clk);
 	if (ret) {
 		dev_err(dev, "Failed to enable USB3 clock\n");
-		goto err_clk;
+		return ret;
 	}
 
 	ctx->hcd = (struct xhci_hccr *)plat->hcd_base;
@@ -114,8 +114,6 @@
 
 err_fw:
 	clk_disable(&plat->clk);
-err_clk:
-	clk_free(&plat->clk);
 	return ret;
 }
 
@@ -127,7 +125,6 @@
 	ret = xhci_deregister(dev);
 
 	clk_disable(&plat->clk);
-	clk_free(&plat->clk);
 
 	return ret;
 }
diff --git a/drivers/video/atmel_hlcdfb.c b/drivers/video/atmel_hlcdfb.c
index 2bf19a6..652ba14 100644
--- a/drivers/video/atmel_hlcdfb.c
+++ b/drivers/video/atmel_hlcdfb.c
@@ -62,8 +62,6 @@
 
 	priv->clk_rate = clk_rate;
 
-	clk_free(&clk);
-
 	return 0;
 }
 
diff --git a/drivers/video/console_core.c b/drivers/video/console_core.c
index d17764d..9393636 100644
--- a/drivers/video/console_core.c
+++ b/drivers/video/console_core.c
@@ -225,7 +225,7 @@
 {
 	info->name = fonts[seq].name;
 
-	return 0;
+	return info->name ? 0 : -ENOENT;
 }
 
 int console_simple_select_font(struct udevice *dev, const char *name, uint size)
diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c
index 14fb81e..547e5a8 100644
--- a/drivers/video/console_truetype.c
+++ b/drivers/video/console_truetype.c
@@ -397,7 +397,10 @@
 
 					if (vid_priv->colour_bg)
 						val = 255 - val;
-					out = val | val << 8 | val << 16;
+					if (vid_priv->format == VIDEO_X2R10G10B10)
+						out = val << 2 | val << 12 | val << 22;
+					else
+						out = val | val << 8 | val << 16;
 					if (vid_priv->colour_fg)
 						*dst++ |= out;
 					else
@@ -911,7 +914,10 @@
 				for (i = 0; i < width; i++) {
 					int out;
 
-					out = val | val << 8 | val << 16;
+					if (vid_priv->format == VIDEO_X2R10G10B10)
+						out = val << 2 | val << 12 | val << 22;
+					else
+						out = val | val << 8 | val << 16;
 					if (vid_priv->colour_fg)
 						*dst++ |= out;
 					else
diff --git a/drivers/video/mali_dp.c b/drivers/video/mali_dp.c
index cbcdb99..dbb2f53 100644
--- a/drivers/video/mali_dp.c
+++ b/drivers/video/mali_dp.c
@@ -360,25 +360,18 @@
 
 	err = malidp_setup_mode(priv, &timings);
 	if (err)
-		goto fail_timings;
+		return err;
 
 	malidp_setup_layer(priv, &timings, MALIDP_LAYER_LV1,
 			   (phys_addr_t)uc_plat->base);
 
 	err = malidp_leave_config(priv);
 	if (err)
-		goto fail_timings;
+		return err;
 
 	malidp_set_configvalid(priv);
 
 	return 0;
-
-fail_timings:
-	clk_free(&priv->aclk);
-fail_aclk:
-	clk_free(&priv->pxlclk);
-
-	return err;
 }
 
 static int malidp_bind(struct udevice *dev)
diff --git a/drivers/video/rockchip/rk3288_hdmi.c b/drivers/video/rockchip/rk3288_hdmi.c
index 327ae78..8bedee5 100644
--- a/drivers/video/rockchip/rk3288_hdmi.c
+++ b/drivers/video/rockchip/rk3288_hdmi.c
@@ -67,10 +67,8 @@
 	 * monitor wants
 	 */
 	ret = clk_get_by_index(uc_plat->src_dev, 0, &clk);
-	if (ret >= 0) {
+	if (ret >= 0)
 		ret = clk_set_rate(&clk, 384000000);
-		clk_free(&clk);
-	}
 	if (ret < 0) {
 		debug("%s: Failed to set clock in source device '%s': ret=%d\n",
 		      __func__, uc_plat->src_dev->name, ret);
diff --git a/drivers/video/rockchip/rk_edp.c b/drivers/video/rockchip/rk_edp.c
index 3697d58..dbd70ad 100644
--- a/drivers/video/rockchip/rk_edp.c
+++ b/drivers/video/rockchip/rk_edp.c
@@ -1095,20 +1095,16 @@
 
 	if (edp_data->chip_type == RK3288_DP) {
 		ret = clk_get_by_index(dev, 1, &clk);
-		if (ret >= 0) {
+		if (ret >= 0)
 			ret = clk_set_rate(&clk, 0);
-			clk_free(&clk);
-		}
 		if (ret) {
 			debug("%s: Failed to set EDP clock: ret=%d\n", __func__, ret);
 			return ret;
 		}
 	}
 	ret = clk_get_by_index(uc_plat->src_dev, 0, &clk);
-	if (ret >= 0) {
+	if (ret >= 0)
 		ret = clk_set_rate(&clk, 192000000);
-		clk_free(&clk);
-	}
 	if (ret < 0) {
 		debug("%s: Failed to set clock in source device '%s': ret=%d\n",
 		      __func__, uc_plat->src_dev->name, ret);
diff --git a/drivers/video/tidss/tidss_drv.c b/drivers/video/tidss/tidss_drv.c
index e285f25..1380c6b 100644
--- a/drivers/video/tidss/tidss_drv.c
+++ b/drivers/video/tidss/tidss_drv.c
@@ -107,7 +107,7 @@
 
 	.num_planes = 2,
 	/* note: vid is plane_id 0 and vidl1 is plane_id 1 */
-	.vid_name = { "vidl1", "vid1" },
+	.vid_name = { "vidl1", "vid" },
 	.vid_lite = { true, false },
 	.vid_order = { 1, 0 },
 };
@@ -814,13 +814,13 @@
 		priv->bus_format = &dss_bus_formats[8];
 
 	/* Common address */
-	priv->base_common = dev_remap_addr_index(dev, 0);
+	priv->base_common = dev_remap_addr_name(dev, priv->feat->common);
 	if (!priv->base_common)
 		return -EINVAL;
 
 	/* plane address setup and enable */
 	for (i = 0; i < priv->feat->num_planes; i++) {
-		priv->base_vid[i] = dev_remap_addr_index(dev, i + 2);
+		priv->base_vid[i] = dev_remap_addr_name(dev, priv->feat->vid_name[i]);
 		if (!priv->base_vid[i])
 			return -EINVAL;
 	}
@@ -841,8 +841,8 @@
 
 	/* video port address clocks and enable */
 	for (i = 0; i < priv->feat->num_vps; i++) {
-		priv->base_ovr[i] = dev_remap_addr_index(dev, i + 4);
-		priv->base_vp[i] = dev_remap_addr_index(dev, i + 6);
+		priv->base_ovr[i] = dev_remap_addr_name(dev, priv->feat->ovr_name[i]);
+		priv->base_vp[i] = dev_remap_addr_name(dev, priv->feat->vp_name[i]);
 	}
 
 	ret = clk_get_by_name(dev, "vp1", &priv->vp_clk[0]);
diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c
index f743ed7..3571e62 100644
--- a/drivers/video/video-uclass.c
+++ b/drivers/video/video-uclass.c
@@ -123,6 +123,9 @@
 	struct udevice *dev;
 	ulong size;
 
+	if (IS_ENABLED(CONFIG_SPL_VIDEO_HANDOFF) && spl_phase() == PHASE_BOARD_F)
+		return 0;
+
 	gd->video_top = *addrp;
 	for (uclass_find_first_device(UCLASS_VIDEO, &dev);
 	     dev;
@@ -141,16 +144,6 @@
 	debug("Video frame buffers from %lx to %lx\n", gd->video_bottom,
 	      gd->video_top);
 
-	if (spl_phase() == PHASE_SPL && CONFIG_IS_ENABLED(VIDEO_HANDOFF)) {
-		struct video_handoff *ho;
-
-		ho = bloblist_add(BLOBLISTT_U_BOOT_VIDEO, sizeof(*ho), 0);
-		if (!ho)
-			return log_msg_ret("blf", -ENOENT);
-		ho->fb = *addrp;
-		ho->size = size;
-	}
-
 	return 0;
 }
 
@@ -208,11 +201,14 @@
 
 int video_reserve_from_bloblist(struct video_handoff *ho)
 {
+	if (!ho->fb || ho->size == 0)
+		return -ENOENT;
+
 	gd->video_bottom = ho->fb;
 	gd->fb_base = ho->fb;
 	gd->video_top = ho->fb + ho->size;
-	debug("Reserving %luk for video using blob at: %08x\n",
-	      ((unsigned long)ho->size) >> 10, (u32)ho->fb);
+	debug("%s: Reserving %lx bytes at %08x as per bloblist received\n",
+	      __func__, (unsigned long)ho->size, (u32)ho->fb);
 
 	return 0;
 }
@@ -546,6 +542,26 @@
 
 	priv->fb_size = priv->line_length * priv->ysize;
 
+	/*
+	 * Set up video handoff fields for passing video blob to next stage
+	 * NOTE:
+	 * This assumes that reserved video memory only uses a single framebuffer
+	 */
+	if (spl_phase() == PHASE_SPL && CONFIG_IS_ENABLED(BLOBLIST)) {
+		struct video_handoff *ho;
+
+		ho = bloblist_add(BLOBLISTT_U_BOOT_VIDEO, sizeof(*ho), 0);
+		if (!ho)
+			return log_msg_ret("blf", -ENOENT);
+		ho->fb = gd->video_bottom;
+		/* Fill aligned size here as calculated in video_reserve() */
+		ho->size = gd->video_top - gd->video_bottom;
+		ho->xsize = priv->xsize;
+		ho->ysize = priv->ysize;
+		ho->line_length = priv->line_length;
+		ho->bpix = priv->bpix;
+	}
+
 	if (IS_ENABLED(CONFIG_VIDEO_COPY) && plat->copy_base)
 		priv->copy_fb = map_sysmem(plat->copy_base, plat->size);
 
diff --git a/drivers/watchdog/designware_wdt.c b/drivers/watchdog/designware_wdt.c
index 447a22d..b22e0ee 100644
--- a/drivers/watchdog/designware_wdt.c
+++ b/drivers/watchdog/designware_wdt.c
@@ -124,13 +124,11 @@
 
 	ret = clk_enable(&clk);
 	if (ret)
-		goto err;
+		return ret;
 
 	priv->clk_khz = clk_get_rate(&clk) / 1000;
-	if (!priv->clk_khz) {
-		ret = -EINVAL;
-		goto err;
-	}
+	if (!priv->clk_khz)
+		return -EINVAL;
 #else
 	priv->clk_khz = CFG_DW_WDT_CLOCK_KHZ;
 #endif
@@ -139,21 +137,15 @@
 	    ofnode_read_prop(dev_ofnode(dev), "resets", &ret)) {
 		ret = reset_get_bulk(dev, &priv->resets);
 		if (ret)
-			goto err;
+			return ret;
 
 		ret = reset_deassert_bulk(&priv->resets);
 		if (ret)
-			goto err;
+			return ret;
 	}
 
 	/* reset to disable the watchdog */
 	return designware_wdt_stop(dev);
-
-err:
-#if CONFIG_IS_ENABLED(CLK)
-	clk_free(&clk);
-#endif
-	return ret;
 }
 
 static const struct wdt_ops designware_wdt_ops = {
diff --git a/drivers/watchdog/meson_gxbb_wdt.c b/drivers/watchdog/meson_gxbb_wdt.c
index 6ab0058..01a35b3 100644
--- a/drivers/watchdog/meson_gxbb_wdt.c
+++ b/drivers/watchdog/meson_gxbb_wdt.c
@@ -98,10 +98,8 @@
 		return ret;
 
 	ret = clk_enable(&clk);
-	if (ret) {
-		clk_free(&clk);
+	if (ret)
 		return ret;
-	}
 
 	/* Setup with 1ms timebase */
 	writel(((clk_get_rate(&clk) / 1000) & GXBB_WDT_CTRL_DIV_MASK) |
diff --git a/env/Kconfig b/env/Kconfig
index f5f0969..7885c8b 100644
--- a/env/Kconfig
+++ b/env/Kconfig
@@ -342,7 +342,7 @@
 
 config ENV_IS_IN_SPI_FLASH
 	bool "Environment is in SPI flash"
-	depends on !CHAIN_OF_TRUST && SPI
+	depends on !CHAIN_OF_TRUST && (SPI_FLASH || DM_SPI_FLASH)
 	default y if ARMADA_XP
 	default y if INTEL_BAYTRAIL
 	default y if INTEL_BRASWELL
diff --git a/env/sf.c b/env/sf.c
index a425ecc..8f5c03b 100644
--- a/env/sf.c
+++ b/env/sf.c
@@ -210,8 +210,10 @@
 		saved_size = sect_size - CONFIG_ENV_SIZE;
 		saved_offset = CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE;
 		saved_buffer = malloc(saved_size);
-		if (!saved_buffer)
+		if (!saved_buffer) {
+			ret = -ENOMEM;
 			goto done;
+		}
 
 		ret = spi_flash_read(env_flash, saved_offset,
 			saved_size, saved_buffer);
diff --git a/include/clk-uclass.h b/include/clk-uclass.h
index cd62848..8c07e72 100644
--- a/include/clk-uclass.h
+++ b/include/clk-uclass.h
@@ -18,7 +18,6 @@
  * struct clk_ops - The functions that a clock driver must implement.
  * @of_xlate: Translate a client's device-tree (OF) clock specifier.
  * @request: Request a translated clock.
- * @rfree: Free a previously requested clock.
  * @round_rate: Adjust a rate to the exact rate a clock can provide.
  * @get_rate: Get current clock rate.
  * @set_rate: Set current clock rate.
@@ -33,7 +32,6 @@
 	int (*of_xlate)(struct clk *clock,
 			struct ofnode_phandle_args *args);
 	int (*request)(struct clk *clock);
-	void (*rfree)(struct clk *clock);
 	ulong (*round_rate)(struct clk *clk, ulong rate);
 	ulong (*get_rate)(struct clk *clk);
 	ulong (*set_rate)(struct clk *clk, ulong rate);
@@ -58,11 +56,20 @@
  * default implementation, which assumes #clock-cells = <1>, and that
  * the DT cell contains a simple integer clock ID.
  *
+ * This function should be a simple translation of @args into @clock->id and
+ * (optionally) @clock->data. All other processing, allocation, or error
+ * checking should take place in request().
+ *
  * At present, the clock API solely supports device-tree. If this
  * changes, other xxx_xlate() functions may be added to support those
  * other mechanisms.
  *
- * Return: 0 if OK, or a negative error code.
+ * Return:
+ * * 0 on success
+ * * -%EINVAL if @args does not have the correct format. For example, it could
+ *   have too many/few arguments.
+ * * -%ENOENT if @args has the correct format but cannot be translated. This can
+ *   happen if translation involves a table lookup and @args is not present.
  */
 int of_xlate(struct clk *clock, struct ofnode_phandle_args *args);
 
@@ -77,24 +84,36 @@
  * xxx_xlate() call, or as the only step in implementing a client's
  * clk_request() call.
  *
- * Return: 0 if OK, or a negative error code.
- */
-int request(struct clk *clock);
-
-/**
- * rfree() - Free a previously requested clock.
- * @clock:	The clock to free.
+ * This is the right place to do bounds checking (rejecting invalid or
+ * unimplemented clocks), allocate resources, or perform other setup not done
+ * during driver probe(). Most clock drivers should allocate resources in their
+ * probe() function, but it is possible to lazily initialize something here.
  *
- * Free any resources allocated in request().
+ * Return:
+ * * 0 on success
+ * * -%ENOENT, if there is no clock corresponding to @clock->id and
+ *   @clock->data.
  */
-void rfree(struct clk *clock);
+int request(struct clk *clock);
 
 /**
  * round_rate() - Adjust a rate to the exact rate a clock can provide.
- * @clk:	The clock to manipulate.
- * @rate:	Desidered clock rate in Hz.
+ * @clk:	The clock to query.
+ * @rate:	Desired clock rate in Hz.
+ *
+ * This function returns a new rate which can be provided to set_rate(). This
+ * new rate should be the closest rate to @rate which can be set without
+ * rounding. The following pseudo-code should hold::
  *
- * Return: rounded rate in Hz, or -ve error code.
+ *   for all rate in range(ULONG_MAX):
+ *     rounded = round_rate(clk, rate)
+ *     new_rate = set_rate(clk, rate)
+ *     assert(IS_ERR_VALUE(new_rate) || new_rate == rounded)
+ *
+ * Return:
+ * * The rounded rate in Hz on success
+ * * A negative error value from another API (such as clk_get_rate()). This
+ *   function must not return an error for any other reason.
  */
 ulong round_rate(struct clk *clk, ulong rate);
 
@@ -102,7 +121,22 @@
  * get_rate() - Get current clock rate.
  * @clk:	The clock to query.
  *
+ * This returns the current rate of a clock. If the clock is disabled, it
+ * returns the rate at which the clock would run if it was enabled. The
+ * following pseudo-code should hold::
+ *
- * Return: clock rate in Hz, or -ve error code
+ *   disable(clk)
+ *   rate = get_rate(clk)
+ *   enable(clk)
+ *   assert(get_rate(clk) == rate)
+ *
+ * Return:
+ * * The rate of @clk
+ * * -%ENOSYS if this function is not implemented for @clk
+ * * -%ENOENT if @clk->id is invalid. Prefer using an assert instead, and doing
+ *   this check in request().
+ * * Another negative error value (such as %EIO or %ECOMM) if the rate could
+ *   not be determined due to a bus error.
  */
 ulong get_rate(struct clk *clk);
 
@@ -111,7 +145,27 @@
  * @clk:	The clock to manipulate.
  * @rate:	New clock rate in Hz.
  *
- * Return: new rate, or -ve error code.
+ * Set the rate of @clk to @rate. The actual rate may be rounded. However,
+ * excessive rounding should be avoided. It is left to the driver author's
+ * discretion when this function should attempt to round and when it should
+ * return an error. For example, a dividing clock might use the following
+ * pseudo-logic when implemening this function::
+ *
+ *   divisor = parent_rate / rate
+ *   if divisor < min || divisor > max:
+ *     return -EINVAL
+ *
+ * If there is any concern about rounding, prefer to let consumers make the
+ * decision by calling round_rate().
+ *
+ * Return:
+ * * The new rate on success
+ * * -%ENOSYS if this function is not implemented for @clk
+ * * -%ENOENT if @clk->id is invalid. Prefer using an assert instead, and doing
+ *   this check in request().
+ * * -%EINVAL if @rate is not valid for @clk.
+ * * Another negative error value (such as %EIO or %ECOMM) if the rate could
+ *   not be set due to a bus error.
  */
 ulong set_rate(struct clk *clk, ulong rate);
 
@@ -120,7 +174,19 @@
  * @clk:        The clock to manipulate.
  * @parent:     New clock parent.
  *
+ * Set the current parent of @clk to @parent. The rate of the clock may be
+ * modified by this call. If @clk was enabled before this function, it should
+ * remain enabled after this function, although it may be temporarily disabled
+ * if necessary.
+ *
- * Return: zero on success, or -ve error code.
+ * Return:
+ * * 0 on success
+ * * -%ENOSYS if this function is not implemented for @clk
+ * * -%ENOENT if @clk->id or @parent->id is invalid. Prefer using an assert
+ *   instead, and doing this check in request().
+ * * -%EINVAL if @parent is not a valid parent for @clk.
+ * * Another negative error value (such as %EIO or %ECOMM) if the parent could
+ *   not be set due to a bus error.
  */
 int set_parent(struct clk *clk, struct clk *parent);
 
@@ -128,7 +194,16 @@
  * enable() - Enable a clock.
  * @clk:	The clock to manipulate.
  *
- * Return: zero on success, or -ve error code.
+ * Enable (un-gate) the clock. This function should not modify the rate of the
+ * clock (see get_rate() for details).
+ *
+ * Return:
+ * * 0 on success
+ * * -%ENOSYS if this function is not implemented for @clk
+ * * -%ENOENT if @clk->id is invalid. Prefer using an assert instead, and doing
+ *   this check in request().
+ * * Another negative error value (such as %EIO or %ECOMM) if the clock could
+ *   not be enabled due to a bus error.
  */
 int enable(struct clk *clk);
 
@@ -136,7 +211,15 @@
  * disable() - Disable a clock.
  * @clk:	The clock to manipulate.
  *
- * Return: zero on success, or -ve error code.
+ * Disable (gate) the clock. This function should not modify the rate of the
+ * clock (see get_rate() for details).
+ *
+ * * 0 on success
+ * * -%ENOSYS if this function is not implemented for @clk
+ * * -%ENOENT if @clk->id is invalid. Prefer using an assert instead, and doing
+ *   this check in request().
+ * * Another negative error value (such as %EIO or %ECOMM) if the clock could
+ *   not be disabled due to a bus error.
  */
 int disable(struct clk *clk);
 
diff --git a/include/clk.h b/include/clk.h
index 3d63944..af23e4f 100644
--- a/include/clk.h
+++ b/include/clk.h
@@ -247,19 +247,6 @@
  */
 int clk_release_all(struct clk *clk, unsigned int count);
 
-/**
- * devm_clk_put	- "free" a managed clock source
- * @dev: device used to acquire the clock
- * @clk: clock source acquired with devm_clk_get()
- *
- * Note: drivers must ensure that all clk_enable calls made on this
- * clock source are balanced by clk_disable calls prior to calling
- * this function.
- *
- * clk_put should not be called from within interrupt context.
- */
-void devm_clk_put(struct udevice *dev, struct clk *clk);
-
 #else
 
 static inline int clk_get_by_phandle(struct udevice *dev, const
@@ -313,10 +300,6 @@
 {
 	return -ENOSYS;
 }
-
-static inline void devm_clk_put(struct udevice *dev, struct clk *clk)
-{
-}
 #endif
 
 /**
@@ -442,15 +425,6 @@
 int clk_request(struct udevice *dev, struct clk *clk);
 
 /**
- * clk_free() - Free a previously requested clock.
- * @clk:	A clock struct that was previously successfully requested by
- *		clk_request/get_by_*().
- *
- * Free resources allocated by clk_request() (or any clk_get_* function).
- */
-void clk_free(struct clk *clk);
-
-/**
  * clk_get_rate() - Get current clock rate.
  * @clk:	A clock struct that was previously successfully requested by
  *		clk_request/get_by_*().
@@ -594,11 +568,6 @@
 	return -ENOSYS;
 }
 
-static inline void clk_free(struct clk *clk)
-{
-	return;
-}
-
 static inline ulong clk_get_rate(struct clk *clk)
 {
 	return -ENOSYS;
diff --git a/include/configs/milkv_duo.h b/include/configs/milkv_duo.h
new file mode 100644
index 0000000..0b4109d
--- /dev/null
+++ b/include/configs/milkv_duo.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2024, Kongyang Liu <seashell11234455@gmail.com>
+ *
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#define CFG_SYS_SDRAM_BASE         0x80000000
+
+#endif /* __CONFIG_H */
diff --git a/include/configs/qemu-riscv.h b/include/configs/qemu-riscv.h
index 584559c..2f594bf 100644
--- a/include/configs/qemu-riscv.h
+++ b/include/configs/qemu-riscv.h
@@ -23,6 +23,7 @@
 
 #define BOOT_TARGET_DEVICES(func) \
 	func(VIRTIO, virtio, 0) \
+	func(VIRTIO, virtio, 1) \
 	func(SCSI, scsi, 0) \
 	func(DHCP, dhcp, na)
 
diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
index b8ca77d..b29a25d 100644
--- a/include/configs/sunxi-common.h
+++ b/include/configs/sunxi-common.h
@@ -14,8 +14,9 @@
 
 #include <linux/stringify.h>
 
-/* Serial & console */
-/* ns16550 reg in the low bits of cpu reg */
+/****************************************************************************
+ *                  base addresses for the SPL UART driver                  *
+ ****************************************************************************/
 #ifdef CONFIG_MACH_SUNIV
 /* suniv doesn't have apb2 and uart is connected to apb1 */
 #define CFG_SYS_NS16550_CLK		100000000
@@ -31,8 +32,9 @@
 # define CFG_SYS_NS16550_COM5		SUNXI_R_UART_BASE
 #endif
 
-/* CPU */
-
+/****************************************************************************
+ *                             DRAM base address                            *
+ ****************************************************************************/
 /*
  * The DRAM Base differs between some models. We cannot use macros for the
  * CONFIG_FOO defines which contain the DRAM base address since they end
@@ -52,16 +54,6 @@
 /* V3s do not have enough memory to place code at 0x4a000000 */
 #endif
 
-/*
- * The A80's A1 sram starts at 0x00010000 rather then at 0x00000000 and is
- * slightly bigger. Note that it is possible to map the first 32 KiB of the
- * A1 at 0x00000000 like with older SoCs by writing 0x16aa0001 to the
- * undocumented 0x008000e0 SYS_CTRL register. Where the 16aa is a key and
- * the 1 actually activates the mapping of the first 32 KiB to 0x00000000.
- * A64 and H5 also has SRAM A1 at 0x00010000, but no magic remap register
- * is known yet.
- * H6 has SRAM A1 at 0x00020000.
- */
 #define CFG_SYS_INIT_RAM_ADDR	CONFIG_SUNXI_SRAM_ADDRESS
 /* FIXME: this may be larger on some SoCs */
 #define CFG_SYS_INIT_RAM_SIZE	0x8000 /* 32 KiB */
@@ -69,36 +61,13 @@
 #define PHYS_SDRAM_0			CFG_SYS_SDRAM_BASE
 #define PHYS_SDRAM_0_SIZE		0x80000000 /* 2 GiB */
 
-/*
- * Miscellaneous configurable options
- */
-
-/* FLASH and environment organization */
-
+/****************************************************************************
+ *           environment variables holding default load addresses           *
+ ****************************************************************************/
 /*
  * We cannot use expressions here, because expressions won't be evaluated in
  * autoconf.mk.
  */
-#if CONFIG_SUNXI_SRAM_ADDRESS == 0x10000
-#ifdef CONFIG_ARM64
-/* end of SRAM A2 for now, as SRAM A1 is pretty tight for an ARM64 build */
-#define LOW_LEVEL_SRAM_STACK		0x00054000
-#else
-#define LOW_LEVEL_SRAM_STACK		0x00018000
-#endif /* !CONFIG_ARM64 */
-#elif CONFIG_SUNXI_SRAM_ADDRESS == 0x20000
-#ifdef CONFIG_MACH_SUN50I_H616
-#define LOW_LEVEL_SRAM_STACK		0x52a00		/* below FEL buffers */
-#else
-/* end of SRAM A2 on H6 for now */
-#define LOW_LEVEL_SRAM_STACK		0x00118000
-#endif
-#else
-#define LOW_LEVEL_SRAM_STACK		0x00008000	/* End of sram */
-#endif
-
-/* Ethernet support */
-
 #ifdef CONFIG_ARM64
 /*
  * Boards seem to come with at least 512MB of DRAM.
@@ -174,15 +143,11 @@
 	"ramdisk_addr_r=" RAMDISK_ADDR_R "\0"
 
 #ifdef CONFIG_ARM64
-
 #define MEM_LAYOUT_ENV_EXTRA_SETTINGS \
 	"kernel_comp_addr_r=" KERNEL_COMP_ADDR_R "\0" \
 	"kernel_comp_size=" KERNEL_COMP_SIZE "\0"
-
 #else
-
 #define MEM_LAYOUT_ENV_EXTRA_SETTINGS ""
-
 #endif
 
 #define DFU_ALT_INFO_RAM \
@@ -191,6 +156,9 @@
 	"fdt ram " FDT_ADDR_R " 0x100000;" \
 	"ramdisk ram " RAMDISK_ADDR_R " 0x4000000\0"
 
+/****************************************************************************
+ *                  definitions for the distro boot system                  *
+ ****************************************************************************/
 #ifdef CONFIG_MMC
 #if CONFIG_MMC_SUNXI_SLOT_EXTRA != -1
 #define BOOTENV_DEV_MMC_AUTO(devtypeu, devtypel, instance)		\
diff --git a/include/dfu.h b/include/dfu.h
index 2f42781..fa1918c 100644
--- a/include/dfu.h
+++ b/include/dfu.h
@@ -10,6 +10,7 @@
 #ifndef __DFU_ENTITY_H_
 #define __DFU_ENTITY_H_
 
+#include <linux/errno.h>
 #include <linux/list.h>
 #include <mmc.h>
 #include <spi_flash.h>
diff --git a/include/dm/pinctrl.h b/include/dm/pinctrl.h
index 70d8cc5..e41baea 100644
--- a/include/dm/pinctrl.h
+++ b/include/dm/pinctrl.h
@@ -6,6 +6,8 @@
 #ifndef __PINCTRL_H
 #define __PINCTRL_H
 
+#include <linux/errno.h>
+
 #define PINNAME_SIZE	10
 #define PINMUX_SIZE	90
 
diff --git a/include/efi_loader.h b/include/efi_loader.h
index d5fca2f..7daca0a 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -340,6 +340,7 @@
 extern const efi_guid_t efi_esrt_guid;
 /* GUID of the SMBIOS table */
 extern const efi_guid_t smbios_guid;
+extern const efi_guid_t smbios3_guid;
 /*GUID of console */
 extern const efi_guid_t efi_guid_text_input_protocol;
 extern const efi_guid_t efi_guid_text_output_protocol;
@@ -545,6 +546,8 @@
 /* Set up load options from environment variable */
 efi_status_t efi_env_set_load_options(efi_handle_t handle, const char *env_var,
 				      u16 **load_options);
+/* Get EFI configuration table */
+void *efi_get_configuration_table(const efi_guid_t *guid);
 /* Install device tree */
 efi_status_t efi_install_fdt(void *fdt);
 /* Execute loaded UEFI image */
diff --git a/include/hwspinlock.h b/include/hwspinlock.h
index d8556c0..dd51354 100644
--- a/include/hwspinlock.h
+++ b/include/hwspinlock.h
@@ -6,6 +6,8 @@
 #ifndef _HWSPINLOCK_H_
 #define _HWSPINLOCK_H_
 
+#include <linux/errno.h>
+
 /**
  * Implement a hwspinlock uclass.
  * Hardware spinlocks are used to perform hardware protection of
diff --git a/include/i2c_eeprom.h b/include/i2c_eeprom.h
index 32dcb03..cba991e 100644
--- a/include/i2c_eeprom.h
+++ b/include/i2c_eeprom.h
@@ -6,6 +6,8 @@
 #ifndef __I2C_EEPROM
 #define __I2C_EEPROM
 
+#include <linux/errno.h>
+
 struct udevice;
 
 struct i2c_eeprom_ops {
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index 2861b73..d1dbf3e 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -136,14 +136,6 @@
 #define SPINOR_OP_BRRD		0x16	/* Bank register read */
 #define SPINOR_OP_CLSR		0x30	/* Clear status register 1 */
 #define SPINOR_OP_EX4B_CYPRESS	0xB8	/* Exit 4-byte mode */
-#define SPINOR_OP_RDAR		0x65	/* Read any register */
-#define SPINOR_OP_WRAR		0x71	/* Write any register */
-#define SPINOR_REG_ADDR_STR1V	0x00800000
-#define SPINOR_REG_ADDR_CFR1V	0x00800002
-#define SPINOR_REG_ADDR_CFR3V	0x00800004
-#define SPINOR_REG_ADDR_ARCFN	0x00000006
-#define CFR3V_UNHYSA		BIT(3)	/* Uniform sectors or not */
-#define CFR3V_PGMBUF		BIT(4)	/* Program buffer size */
 
 /* Used for Micron flashes only. */
 #define SPINOR_OP_RD_EVCR	0x65	/* Read EVCR register */
@@ -188,8 +180,12 @@
 /* For Cypress flash. */
 #define SPINOR_OP_RD_ANY_REG			0x65	/* Read any register */
 #define SPINOR_OP_WR_ANY_REG			0x71	/* Write any register */
-#define SPINOR_OP_S28_SE_4K			0x21
+#define SPINOR_OP_CYPRESS_CLPEF			0x82	/* Clear P/E err flag */
+#define SPINOR_REG_CYPRESS_ARCFN		0x00000006
+#define SPINOR_REG_CYPRESS_STR1V		0x00800000
+#define SPINOR_REG_CYPRESS_CFR1V		0x00800002
 #define SPINOR_REG_CYPRESS_CFR2V		0x00800003
+#define SPINOR_REG_CYPRESS_CFR2_MEMLAT_MASK	GENMASK(3, 0)
 #define SPINOR_REG_CYPRESS_CFR2_MEMLAT_11_24	0xb
 #define SPINOR_REG_CYPRESS_CFR3V		0x00800004
 #define SPINOR_REG_CYPRESS_CFR3_PGSZ		BIT(4) /* Page size. */
diff --git a/include/nvmem.h b/include/nvmem.h
index 822e698..e6a8a98 100644
--- a/include/nvmem.h
+++ b/include/nvmem.h
@@ -6,6 +6,8 @@
 #ifndef NVMEM_H
 #define NVMEM_H
 
+#include <linux/errno.h>
+
 /**
  * DOC: Design
  *
diff --git a/include/part.h b/include/part.h
index db34bc6..32ee404 100644
--- a/include/part.h
+++ b/include/part.h
@@ -685,8 +685,8 @@
 /**
  * part_get_bootable() - Find the first bootable partition
  *
- * @desc: Block-device descriptor
- * @return first bootable partition, or 0 if there is none
+ * @desc:	Block-device descriptor
+ * Return:	first bootable partition, or 0 if there is none
  */
 int part_get_bootable(struct blk_desc *desc);
 
diff --git a/include/power-domain.h b/include/power-domain.h
index 2ff6c77..1852507 100644
--- a/include/power-domain.h
+++ b/include/power-domain.h
@@ -6,6 +6,8 @@
 #ifndef _POWER_DOMAIN_H
 #define _POWER_DOMAIN_H
 
+#include <linux/errno.h>
+
 /**
  * A power domain is a portion of an SoC or chip that is powered by a
  * switchable source of power. In many cases, software has control over the
diff --git a/include/power/regulator.h b/include/power/regulator.h
index 200652c..bb07a81 100644
--- a/include/power/regulator.h
+++ b/include/power/regulator.h
@@ -7,6 +7,8 @@
 #ifndef _INCLUDE_REGULATOR_H_
 #define _INCLUDE_REGULATOR_H_
 
+#include <linux/errno.h>
+
 struct udevice;
 
 /**
diff --git a/include/remoteproc.h b/include/remoteproc.h
index a11dc8a..91a8879 100644
--- a/include/remoteproc.h
+++ b/include/remoteproc.h
@@ -14,6 +14,7 @@
  * platforms have moved to dm/fdt.
  */
 #include <dm/platdata.h>	/* For platform data support - non dt world */
+#include <linux/errno.h>
 
 /**
  * struct fw_rsc_hdr - firmware resource entry header
diff --git a/include/smbios.h b/include/smbios.h
index b507b9d..e2b7f69 100644
--- a/include/smbios.h
+++ b/include/smbios.h
@@ -139,6 +139,7 @@
 	u8 chassis_location;
 	u16 chassis_handle;
 	u8 board_type;
+	u8 number_contained_objects;
 	char eos[SMBIOS_STRUCT_EOS_BYTES];
 };
 
@@ -326,10 +327,10 @@
  * This function clear the device dependent parameters such as
  * serial number for the measurement.
  *
- * @entry: pointer to a struct smbios_entry
+ * @entry: pointer to a struct smbios3_entry
  * @header: pointer to a struct smbios_header
  */
-void smbios_prepare_measurement(const struct smbios_entry *entry,
+void smbios_prepare_measurement(const struct smbios3_entry *entry,
 				struct smbios_header *header);
 
 #endif /* _SMBIOS_H_ */
diff --git a/include/soc.h b/include/soc.h
index 850db28..b8cfc50 100644
--- a/include/soc.h
+++ b/include/soc.h
@@ -7,6 +7,8 @@
 #ifndef __SOC_H
 #define __SOC_H
 
+#include <linux/errno.h>
+
 #define SOC_MAX_STR_SIZE	128
 
 struct udevice;
diff --git a/include/spi-mem.h b/include/spi-mem.h
index b07cf2e..3c8e95b 100644
--- a/include/spi-mem.h
+++ b/include/spi-mem.h
@@ -11,6 +11,8 @@
 #ifndef __UBOOT_SPI_MEM_H
 #define __UBOOT_SPI_MEM_H
 
+#include <linux/errno.h>
+
 struct udevice;
 
 #define SPI_MEM_OP_CMD(__opcode, __buswidth)			\
diff --git a/include/spl.h b/include/spl.h
index 0952188..043875f 100644
--- a/include/spl.h
+++ b/include/spl.h
@@ -889,6 +889,16 @@
 
 int spl_ymodem_load_image(struct spl_image_info *spl_image,
 			  struct spl_boot_device *bootdev);
+/**
+ * spl_reserve_video_from_ram_top() - Reserve framebuffer memory from end of RAM
+ *
+ * This enforces framebuffer reservation at SPL stage from end of RAM so that
+ * next stage can directly skip this pre-reserved area before carrying out
+ * further reservations. The allocation address is stored in struct video_uc_plat.
+ *
+ * Return: 0 on success, otherwise error code
+ */
+int spl_reserve_video_from_ram_top(void);
 
 /**
  * spl_invoke_atf - boot using an ARM trusted firmware image
diff --git a/include/sysinfo.h b/include/sysinfo.h
index f2c1aa2..524c7d6 100644
--- a/include/sysinfo.h
+++ b/include/sysinfo.h
@@ -7,6 +7,8 @@
 #ifndef __SYSINFO_H__
 #define __SYSINFO_H__
 
+#include <linux/errno.h>
+
 struct udevice;
 
 /*
diff --git a/include/tlv_eeprom.h b/include/tlv_eeprom.h
index fd45e5f..2b1e19b 100644
--- a/include/tlv_eeprom.h
+++ b/include/tlv_eeprom.h
@@ -7,6 +7,8 @@
 #ifndef __TLV_EEPROM_H_
 #define __TLV_EEPROM_H_
 
+#include <linux/errno.h>
+
 /*
  *  The Definition of the TlvInfo EEPROM format can be found at onie.org or
  *  github.com/onie
diff --git a/lib/charset.c b/lib/charset.c
index 89057ef..2b43175 100644
--- a/lib/charset.c
+++ b/lib/charset.c
@@ -570,6 +570,10 @@
 		}
 		if (pos == end)
 			return 0;
+		/*
+		 * Appending the byte lead to an invalid UTF-8 byte sequence.
+		 * Consider it as the start of a new code sequence.
+		 */
 		*buffer = 0;
 	}
 }
diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c
index 68d7db5..4ac5192 100644
--- a/lib/efi_loader/efi_bootmgr.c
+++ b/lib/efi_loader/efi_bootmgr.c
@@ -294,14 +294,17 @@
 }
 
 /**
- * check_disk_has_default_file() - load the default file
+ * fill_default_file_path() - get fallback boot device path for block device
+ *
+ * Provide the device path to the fallback UEFI boot file, e.g.
+ * EFI/BOOT/BOOTAA64.EFI if that file exists on the block device @blk.
  *
  * @blk:	pointer to the UCLASS_BLK udevice
- * @dp:		pointer to default file device path
+ * @dp:		pointer to store the fallback boot device path
  * Return:	status code
  */
-static efi_status_t check_disk_has_default_file(struct udevice *blk,
-						struct efi_device_path **dp)
+static efi_status_t fill_default_file_path(struct udevice *blk,
+					   struct efi_device_path **dp)
 {
 	efi_status_t ret;
 	struct udevice *partition;
@@ -348,7 +351,7 @@
 	if (!ramdisk_blk)
 		return EFI_LOAD_ERROR;
 
-	ret = check_disk_has_default_file(ramdisk_blk, dp);
+	ret = fill_default_file_path(ramdisk_blk, dp);
 	if (ret != EFI_SUCCESS) {
 		log_info("Cannot boot from downloaded image\n");
 		goto err;
@@ -547,6 +550,50 @@
 }
 
 /**
+ * try_load_from_media() - load file from media
+ *
+ * @file_path:		file path
+ * @handle_img:		on return handle for the newly installed image
+ *
+ * If @file_path contains a file name, load the file.
+ * If @file_path does not have a file name, search the architecture-specific
+ * fallback boot file and load it.
+ * TODO: If the FilePathList[0] device does not support
+ * EFI_SIMPLE_FILE_SYSTEM_PROTOCOL but supports EFI_BLOCK_IO_PROTOCOL,
+ * call EFI_BOOT_SERVICES.ConnectController()
+ * TODO: FilePathList[0] device supports the EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
+ * not based on EFI_BLOCK_IO_PROTOCOL
+ *
+ * Return:	status code
+ */
+static efi_status_t try_load_from_media(struct efi_device_path *file_path,
+					efi_handle_t *handle_img)
+{
+	efi_handle_t handle_blkdev;
+	efi_status_t ret = EFI_SUCCESS;
+	struct efi_device_path *rem, *dp = NULL;
+	struct efi_device_path *final_dp = file_path;
+
+	handle_blkdev = efi_dp_find_obj(file_path, &efi_block_io_guid, &rem);
+	if (handle_blkdev) {
+		if (rem->type == DEVICE_PATH_TYPE_END) {
+			/* no file name present, try default file */
+			ret = fill_default_file_path(handle_blkdev->dev, &dp);
+			if (ret != EFI_SUCCESS)
+				return ret;
+
+			final_dp = dp;
+		}
+	}
+
+	ret = EFI_CALL(efi_load_image(true, efi_root, final_dp, NULL, 0, handle_img));
+
+	efi_free_pool(dp);
+
+	return ret;
+}
+
+/**
  * try_load_entry() - try to load image for boot option
  *
  * Attempt to load load-option number 'n', returning device_path and file_path
@@ -580,7 +627,6 @@
 	}
 
 	if (lo.attributes & LOAD_OPTION_ACTIVE) {
-		struct efi_device_path *file_path;
 		u32 attributes;
 
 		log_debug("trying to load \"%ls\" from %pD\n", lo.label,
@@ -597,10 +643,7 @@
 			else
 				ret = EFI_LOAD_ERROR;
 		} else {
-			file_path = expand_media_path(lo.file_path);
-			ret = EFI_CALL(efi_load_image(true, efi_root, file_path,
-						      NULL, 0, handle));
-			efi_free_pool(file_path);
+			ret = try_load_from_media(lo.file_path, handle);
 		}
 		if (ret != EFI_SUCCESS) {
 			log_warning("Loading %ls '%ls' failed\n",
@@ -731,22 +774,26 @@
 }
 
 /**
- * efi_bootmgr_enumerate_boot_option() - enumerate the possible bootable media
+ * efi_bootmgr_enumerate_boot_options() - enumerate the possible bootable media
  *
  * @opt:		pointer to the media boot option structure
- * @volume_handles:	pointer to the efi handles
- * @count:		number of efi handle
+ * @index:		index of the opt array to store the boot option
+ * @handles:		pointer to block device handles
+ * @count:		On entry number of handles to block devices.
+ *			On exit number of boot options.
+ * @removable:		flag to parse removable only
  * Return:		status code
  */
-static efi_status_t efi_bootmgr_enumerate_boot_option(struct eficonfig_media_boot_option *opt,
-						      efi_handle_t *volume_handles,
-						      efi_status_t count)
+static efi_status_t
+efi_bootmgr_enumerate_boot_options(struct eficonfig_media_boot_option *opt,
+				   efi_uintn_t index, efi_handle_t *handles,
+				   efi_uintn_t *count, bool removable)
 {
-	u32 i;
+	u32 i, num = index;
 	struct efi_handler *handler;
 	efi_status_t ret = EFI_SUCCESS;
 
-	for (i = 0; i < count; i++) {
+	for (i = 0; i < *count; i++) {
 		u16 *p;
 		u16 dev_name[BOOTMENU_DEVICE_NAME_MAX];
 		char *optional_data;
@@ -754,8 +801,18 @@
 		char buf[BOOTMENU_DEVICE_NAME_MAX];
 		struct efi_device_path *device_path;
 		struct efi_device_path *short_dp;
+		struct efi_block_io *blkio;
 
-		ret = efi_search_protocol(volume_handles[i], &efi_guid_device_path, &handler);
+		ret = efi_search_protocol(handles[i], &efi_block_io_guid, &handler);
+		blkio = handler->protocol_interface;
+
+		if (blkio->media->logical_partition)
+			continue;
+
+		if (removable != (blkio->media->removable_media != 0))
+			continue;
+
+		ret = efi_search_protocol(handles[i], &efi_guid_device_path, &handler);
 		if (ret != EFI_SUCCESS)
 			continue;
 		ret = efi_protocol_open(handler, (void **)&device_path,
@@ -763,7 +820,7 @@
 		if (ret != EFI_SUCCESS)
 			continue;
 
-		ret = efi_disk_get_device_name(volume_handles[i], buf, BOOTMENU_DEVICE_NAME_MAX);
+		ret = efi_disk_get_device_name(handles[i], buf, BOOTMENU_DEVICE_NAME_MAX);
 		if (ret != EFI_SUCCESS)
 			continue;
 
@@ -787,17 +844,23 @@
 		 * to store guid, instead of realloc the load_option.
 		 */
 		lo.optional_data = "1234567";
-		opt[i].size = efi_serialize_load_option(&lo, (u8 **)&opt[i].lo);
-		if (!opt[i].size) {
+		opt[num].size = efi_serialize_load_option(&lo, (u8 **)&opt[num].lo);
+		if (!opt[num].size) {
 			ret = EFI_OUT_OF_RESOURCES;
 			goto out;
 		}
 		/* set the guid */
-		optional_data = (char *)opt[i].lo + (opt[i].size - u16_strsize(u"1234567"));
+		optional_data = (char *)opt[num].lo + (opt[num].size - u16_strsize(u"1234567"));
 		memcpy(optional_data, &efi_guid_bootmenu_auto_generated, sizeof(efi_guid_t));
+		num++;
+
+		if (num >= *count)
+			break;
 	}
 
 out:
+	*count = num;
+
 	return ret;
 }
 
@@ -1026,8 +1089,7 @@
 /**
  * efi_bootmgr_update_media_device_boot_option() - generate the media device boot option
  *
- * This function enumerates all devices supporting EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
- * and generate the bootmenu entries.
+ * This function enumerates all BlockIo devices and add the boot option for it.
  * This function also provide the BOOT#### variable maintenance for
  * the media device entries.
  * - Automatically create the BOOT#### variable for the newly detected device,
@@ -1042,14 +1104,14 @@
 {
 	u32 i;
 	efi_status_t ret;
-	efi_uintn_t count;
-	efi_handle_t *volume_handles = NULL;
+	efi_uintn_t count, num, total;
+	efi_handle_t *handles = NULL;
 	struct eficonfig_media_boot_option *opt = NULL;
 
 	ret = efi_locate_handle_buffer_int(BY_PROTOCOL,
-					   &efi_simple_file_system_protocol_guid,
+					   &efi_block_io_guid,
 					   NULL, &count,
-					   (efi_handle_t **)&volume_handles);
+					   (efi_handle_t **)&handles);
 	if (ret != EFI_SUCCESS)
 		goto out;
 
@@ -1059,23 +1121,32 @@
 		goto out;
 	}
 
-	/* enumerate all devices supporting EFI_SIMPLE_FILE_SYSTEM_PROTOCOL */
-	ret = efi_bootmgr_enumerate_boot_option(opt, volume_handles, count);
+	/* parse removable block io followed by fixed block io */
+	num = count;
+	ret = efi_bootmgr_enumerate_boot_options(opt, 0, handles, &num, true);
 	if (ret != EFI_SUCCESS)
 		goto out;
 
+	total = num;
+	num = count;
+	ret = efi_bootmgr_enumerate_boot_options(opt, total, handles, &num, false);
+	if (ret != EFI_SUCCESS)
+		goto out;
+
+	total = num;
+
 	/*
 	 * System hardware configuration may vary depending on the user setup.
 	 * The boot option is automatically added by the bootmenu.
 	 * If the device is not attached to the system, the boot option needs
 	 * to be deleted.
 	 */
-	ret = efi_bootmgr_delete_invalid_boot_option(opt, count);
+	ret = efi_bootmgr_delete_invalid_boot_option(opt, total);
 	if (ret != EFI_SUCCESS)
 		goto out;
 
 	/* add non-existent boot option */
-	for (i = 0; i < count; i++) {
+	for (i = 0; i < total; i++) {
 		u32 boot_index;
 		u16 var_name[9];
 
@@ -1104,11 +1175,11 @@
 
 out:
 	if (opt) {
-		for (i = 0; i < count; i++)
+		for (i = 0; i < total; i++)
 			free(opt[i].lo);
 	}
 	free(opt);
-	efi_free_pool(volume_handles);
+	efi_free_pool(handles);
 
 	if (ret == EFI_NOT_FOUND)
 		return EFI_SUCCESS;
diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c
index 013842f..b1739d9 100644
--- a/lib/efi_loader/efi_disk.c
+++ b/lib/efi_loader/efi_disk.c
@@ -371,6 +371,20 @@
 	return 1;
 }
 
+static void efi_disk_free_diskobj(struct efi_disk_obj *diskobj)
+{
+	struct efi_device_path *dp = diskobj->dp;
+	struct efi_simple_file_system_protocol *volume = diskobj->volume;
+
+	/*
+	 * ignore error of efi_delete_handle() since this function
+	 * is expected to be called in error path.
+	 */
+	efi_delete_handle(&diskobj->header);
+	efi_free_pool(dp);
+	free(volume);
+}
+
 /**
  * efi_disk_add_dev() - create a handle for a partition or disk
  *
@@ -528,9 +542,7 @@
 	}
 	return EFI_SUCCESS;
 error:
-	efi_delete_handle(&diskobj->header);
-	free(diskobj->volume);
-	free(diskobj);
+	efi_disk_free_diskobj(diskobj);
 	return ret;
 }
 
@@ -569,8 +581,7 @@
 		return ret;
 	}
 	if (efi_link_dev(&disk->header, dev)) {
-		efi_free_pool(disk->dp);
-		efi_delete_handle(&disk->header);
+		efi_disk_free_diskobj(disk);
 
 		return -EINVAL;
 	}
@@ -624,8 +635,9 @@
 		return -1;
 	}
 	if (efi_link_dev(&disk->header, dev)) {
-		efi_free_pool(disk->dp);
-		efi_delete_handle(&disk->header);
+		efi_disk_free_diskobj(disk);
+
+		/* TODO: closing the parent EFI_BLOCK_IO_PROTOCOL is missing. */
 
 		return -1;
 	}
@@ -707,7 +719,9 @@
 	struct udevice *dev = event->data.dm.dev;
 	efi_handle_t handle;
 	struct blk_desc *desc;
+	struct efi_device_path *dp = NULL;
 	struct efi_disk_obj *diskobj = NULL;
+	struct efi_simple_file_system_protocol *volume = NULL;
 	efi_status_t ret;
 
 	if (dev_tag_get_ptr(dev, DM_TAG_EFI, (void **)&handle))
@@ -717,25 +731,35 @@
 	switch (id) {
 	case UCLASS_BLK:
 		desc = dev_get_uclass_plat(dev);
-		if (desc && desc->uclass_id != UCLASS_EFI_LOADER)
-			diskobj = container_of(handle, struct efi_disk_obj,
-					       header);
+		if (desc && desc->uclass_id == UCLASS_EFI_LOADER)
+			/*
+			 * EFI application/driver manages the EFI handle,
+			 * no need to delete EFI handle.
+			 */
+			return 0;
+
+		diskobj = (struct efi_disk_obj *)handle;
 		break;
 	case UCLASS_PARTITION:
-		diskobj = container_of(handle, struct efi_disk_obj, header);
+		diskobj = (struct efi_disk_obj *)handle;
+
+		/* TODO: closing the parent EFI_BLOCK_IO_PROTOCOL is missing. */
+
 		break;
 	default:
 		return 0;
 	}
 
+	dp = diskobj->dp;
+	volume = diskobj->volume;
+
 	ret = efi_delete_handle(handle);
 	/* Do not delete DM device if there are still EFI drivers attached. */
 	if (ret != EFI_SUCCESS)
 		return -1;
 
-	if (diskobj)
-		efi_free_pool(diskobj->dp);
-
+	efi_free_pool(dp);
+	free(volume);
 	dev_tag_del(dev, DM_TAG_EFI);
 
 	return 0;
diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c
index 9fd1329..ba5aba0 100644
--- a/lib/efi_loader/efi_firmware.c
+++ b/lib/efi_loader/efi_firmware.c
@@ -400,18 +400,18 @@
 	}
 
 	size = num_banks * sizeof(*var_state);
-	var_state = calloc(1, size);
+	var_state = malloc(size);
 	if (!var_state)
 		return EFI_OUT_OF_RESOURCES;
 
 	/*
 	 * GetVariable may fail, EFI_NOT_FOUND is returned if FmpState
 	 * variable has not been set yet.
-	 * Ignore the error here since the correct FmpState variable
-	 * is set later.
 	 */
-	efi_get_variable_int(varname, image_type_id, NULL, &size, var_state,
-			     NULL);
+	ret = efi_get_variable_int(varname, image_type_id, NULL, &size,
+				   var_state, NULL);
+	if (ret != EFI_SUCCESS)
+		memset(var_state, 0, num_banks * sizeof(*var_state));
 
 	/*
 	 * Only the fw_version is set here.
diff --git a/lib/efi_loader/efi_helper.c b/lib/efi_loader/efi_helper.c
index 11066eb..5dd9cc8 100644
--- a/lib/efi_loader/efi_helper.c
+++ b/lib/efi_loader/efi_helper.c
@@ -380,12 +380,12 @@
 }
 
 /**
- * get_config_table() - get configuration table
+ * efi_get_configuration_table() - get configuration table
  *
  * @guid:	GUID of the configuration table
  * Return:	pointer to configuration table or NULL
  */
-static void *get_config_table(const efi_guid_t *guid)
+void *efi_get_configuration_table(const efi_guid_t *guid)
 {
 	size_t i;
 
@@ -430,7 +430,7 @@
 		uintptr_t fdt_addr;
 
 		/* Look for device tree that is already installed */
-		if (get_config_table(&efi_guid_fdt))
+		if (efi_get_configuration_table(&efi_guid_fdt))
 			return EFI_SUCCESS;
 		/* Check if there is a hardware device tree */
 		fdt_opt = env_get("fdt_addr");
diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c
index 8db35d0..b5d4aa7 100644
--- a/lib/efi_loader/efi_tcg2.c
+++ b/lib/efi_loader/efi_tcg2.c
@@ -1075,12 +1075,17 @@
  */
 static efi_status_t
 tcg2_measure_smbios(struct udevice *dev,
-		    const struct smbios_entry *entry)
+		    const struct smbios3_entry *entry)
 {
 	efi_status_t ret;
 	struct smbios_header *smbios_copy;
 	struct smbios_handoff_table_pointers2 *event = NULL;
 	u32 event_size;
+	const char smbios3_anchor[] = "_SM3_";
+
+	/* We only support SMBIOS 3.0 Entry Point structure */
+	if (memcmp(entry->anchor, smbios3_anchor, sizeof(smbios3_anchor) - 1))
+		return EFI_UNSUPPORTED;
 
 	/*
 	 * TCG PC Client PFP Spec says
@@ -1093,7 +1098,7 @@
 	 */
 	event_size = sizeof(struct smbios_handoff_table_pointers2) +
 		     FIELD_SIZEOF(struct efi_configuration_table, guid) +
-		     entry->struct_table_length;
+		     entry->max_struct_size;
 	event = calloc(1, event_size);
 	if (!event) {
 		ret = EFI_OUT_OF_RESOURCES;
@@ -1104,11 +1109,11 @@
 	memcpy(event->table_description, SMBIOS_HANDOFF_TABLE_DESC,
 	       sizeof(SMBIOS_HANDOFF_TABLE_DESC));
 	put_unaligned_le64(1, &event->number_of_tables);
-	guidcpy(&event->table_entry[0].guid, &smbios_guid);
+	guidcpy(&event->table_entry[0].guid, &smbios3_guid);
 	smbios_copy = (struct smbios_header *)((uintptr_t)&event->table_entry[0].table);
 	memcpy(&event->table_entry[0].table,
 	       (void *)((uintptr_t)entry->struct_table_address),
-	       entry->struct_table_length);
+	       entry->max_struct_size);
 
 	smbios_prepare_measurement(entry, smbios_copy);
 
@@ -1124,23 +1129,6 @@
 }
 
 /**
- * find_smbios_table() - find smbios table
- *
- * Return:	pointer to the smbios table
- */
-static void *find_smbios_table(void)
-{
-	u32 i;
-
-	for (i = 0; i < systab.nr_tables; i++) {
-		if (!guidcmp(&smbios_guid, &systab.tables[i].guid))
-			return systab.tables[i].table;
-	}
-
-	return NULL;
-}
-
-/**
  * tcg2_measure_gpt_table() - measure gpt table
  *
  * @dev:		TPM device
@@ -1360,7 +1348,7 @@
 	u32 pcr_index;
 	struct udevice *dev;
 	u32 event = 0;
-	struct smbios_entry *entry;
+	struct smbios3_entry *entry;
 
 	if (!is_tcg2_protocol_installed())
 		return EFI_SUCCESS;
@@ -1382,7 +1370,7 @@
 	if (ret != EFI_SUCCESS)
 		goto out;
 
-	entry = (struct smbios_entry *)find_smbios_table();
+	entry = efi_get_configuration_table(&smbios3_guid);
 	if (entry) {
 		ret = tcg2_measure_smbios(dev, entry);
 		if (ret != EFI_SUCCESS)
diff --git a/lib/efi_selftest/efi_selftest_miniapp_exit.c b/lib/efi_selftest/efi_selftest_miniapp_exit.c
index 8b2e60c..0909a5c 100644
--- a/lib/efi_selftest/efi_selftest_miniapp_exit.c
+++ b/lib/efi_selftest/efi_selftest_miniapp_exit.c
@@ -39,7 +39,7 @@
 				  NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
 	if (ret != EFI_SUCCESS) {
 		cout->output_string(cout,
-				    u"Could not open loaded image protocol");
+				    u"Could not open loaded image protocol\n");
 		return ret;
 	}
 	if ((void *)check_loaded_image_protocol <
diff --git a/lib/efi_selftest/efi_selftest_tcg2.c b/lib/efi_selftest/efi_selftest_tcg2.c
index 67a886e..fb8b997 100644
--- a/lib/efi_selftest/efi_selftest_tcg2.c
+++ b/lib/efi_selftest/efi_selftest_tcg2.c
@@ -126,41 +126,40 @@
 
 static void *orig_smbios_table;
 static u64 dmi_addr = U32_MAX;
-#define SMBIOS_ENTRY_HEADER_SIZE 0x20
+#define SMBIOS3_ENTRY_HEADER_SIZE 0x18
 /* smbios table for the measurement test */
-static u8 smbios_table_test[] = {
-0x5f, 0x53, 0x4d, 0x5f, 0x2c, 0x1f, 0x03, 0x00, 0x54, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x5f, 0x44, 0x4d, 0x49, 0x5f, 0xe4, 0x5c, 0x01,
-0x20, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00,
-0x01, 0x02, 0x00, 0x00, 0x03, 0x00, 0x80, 0x08, 0x01, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x0c, 0x15, 0x0a, 0xff, 0xff, 0x55, 0x2d, 0x42, 0x6f,
-0x6f, 0x74, 0x00, 0x32, 0x30, 0x32, 0x31, 0x2e, 0x31, 0x30, 0x2d, 0x72,
-0x63, 0x34, 0x2d, 0x30, 0x30, 0x30, 0x30, 0x35, 0x2d, 0x67, 0x37, 0x32,
-0x37, 0x63, 0x33, 0x66, 0x33, 0x32, 0x35, 0x39, 0x2d, 0x64, 0x69, 0x72,
-0x74, 0x79, 0x00, 0x31, 0x30, 0x2f, 0x30, 0x31, 0x2f, 0x32, 0x30, 0x32,
-0x31, 0x00, 0x00, 0x01, 0x1b, 0x01, 0x00, 0x01, 0x02, 0x00, 0x03, 0x31,
-0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77,
-0x6e, 0x00, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x20, 0x50, 0x72,
-0x6f, 0x64, 0x75, 0x63, 0x74, 0x00, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
-0x37, 0x38, 0x00, 0x00, 0x02, 0x0e, 0x02, 0x00, 0x01, 0x02, 0x00, 0x04,
-0x03, 0x01, 0x01, 0x01, 0x00, 0x0a, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77,
-0x6e, 0x00, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x20, 0x50, 0x72,
-0x6f, 0x64, 0x75, 0x63, 0x74, 0x00, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
-0x33, 0x33, 0x00, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x00,
-0x00, 0x03, 0x15, 0x03, 0x00, 0x01, 0x03, 0x00, 0x02, 0x03, 0x03, 0x03,
-0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x6e,
-0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x00, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
-0x37, 0x38, 0x00, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x00,
-0x00, 0x04, 0x30, 0x04, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x01, 0x06, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02, 0x03, 0x04,
-0x04, 0x04, 0x08, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00, 0x08, 0x00, 0x01,
-0x00, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x00, 0x31, 0x32, 0x33,
-0x34, 0x35, 0x36, 0x37, 0x38, 0x00, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
-0x33, 0x33, 0x00, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x00,
-0x00, 0x20, 0x0b, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x7f, 0x04, 0x06, 0x00, 0x00, 0x00
+static u8 smbios3_table_test[] = {
+0x5f, 0x53, 0x4d, 0x33, 0x5f, 0x00, 0x18, 0x03, 0x07, 0x00, 0x01, 0x00,
+0x5c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x18, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x03, 0x00, 0x80, 0x08,
+0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x15, 0x0a, 0xff, 0xff,
+0x55, 0x2d, 0x42, 0x6f, 0x6f, 0x74, 0x00, 0x32, 0x30, 0x32, 0x31, 0x2e,
+0x31, 0x30, 0x2d, 0x72, 0x63, 0x34, 0x2d, 0x30, 0x30, 0x30, 0x30, 0x35,
+0x2d, 0x67, 0x37, 0x32, 0x37, 0x63, 0x33, 0x66, 0x33, 0x32, 0x35, 0x39,
+0x2d, 0x64, 0x69, 0x72, 0x74, 0x79, 0x00, 0x31, 0x30, 0x2f, 0x30, 0x31,
+0x2f, 0x32, 0x30, 0x32, 0x31, 0x00, 0x00, 0x01, 0x1b, 0x01, 0x00, 0x01,
+0x02, 0x00, 0x03, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x55, 0x6e,
+0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x00, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77,
+0x6e, 0x20, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x00, 0x31, 0x32,
+0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x00, 0x00, 0x02, 0x0e, 0x02, 0x00,
+0x01, 0x02, 0x00, 0x04, 0x03, 0x01, 0x01, 0x01, 0x00, 0x0a, 0x55, 0x6e,
+0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x00, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77,
+0x6e, 0x20, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x00, 0x33, 0x33,
+0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x31, 0x32, 0x33, 0x34, 0x35,
+0x36, 0x37, 0x38, 0x00, 0x00, 0x03, 0x15, 0x03, 0x00, 0x01, 0x03, 0x00,
+0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x00, 0x31, 0x32,
+0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x00, 0x33, 0x33, 0x33, 0x33, 0x33,
+0x33, 0x33, 0x33, 0x00, 0x00, 0x04, 0x30, 0x04, 0x00, 0x00, 0x03, 0x02,
+0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0x02, 0x03, 0x04, 0x04, 0x04, 0x08, 0x00, 0x00, 0x02, 0x00, 0x08,
+0x00, 0x08, 0x00, 0x01, 0x00, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e,
+0x00, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x00, 0x33, 0x33,
+0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x35, 0x35, 0x35, 0x35, 0x35,
+0x35, 0x35, 0x35, 0x00, 0x00, 0x20, 0x0b, 0x05, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x04, 0x06, 0x00, 0x00, 0x00
 };
 
 #define IDX_ARRAY_SZ 3 /* support 24 PCRs */
@@ -179,10 +178,10 @@
 	 0x7b, 0xb9, 0xfe, 0xa1, 0xcd, 0x64, 0x49, 0xdd,
 	 0xed, 0xe2, 0x65, 0x82, 0xc5, 0x3e, 0xf4, 0xc4},
 
-	{0xf5, 0x79, 0xf3, 0x20, 0x62, 0x6e, 0x8b, 0x58,
-	 0x62, 0xa3, 0x4e, 0x2f, 0xb7, 0x10, 0xac, 0x34,
-	 0x4e, 0x68, 0x94, 0x37, 0x87, 0x29, 0xc4, 0xbe,
-	 0xa3, 0xc4, 0xd9, 0x14, 0x2b, 0x66, 0x79, 0x9b},
+	{0x75, 0xb5, 0x91, 0x54, 0x12, 0xa8, 0xa4, 0x25,
+	 0x73, 0x79, 0xa7, 0x47, 0xd9, 0x32, 0x54, 0x78,
+	 0x9a, 0x80, 0x3f, 0xa8, 0x34, 0xfe, 0xd2, 0xae,
+	 0x76, 0xd3, 0x16, 0x4a, 0xb2, 0x03, 0xac, 0xe6},
 
 	{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea,
 	 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d,
@@ -543,7 +542,7 @@
 	u32 i;
 
 	for (i = 0; i < systable->nr_tables; i++) {
-		if (!guidcmp(&smbios_guid, &systable->tables[i].guid))
+		if (!guidcmp(&smbios3_guid, &systable->tables[i].guid))
 			return systable->tables[i].table;
 	}
 
@@ -558,14 +557,12 @@
  */
 static efi_status_t setup_smbios_table(const struct efi_system_table *systable)
 {
-	struct smbios_entry *se;
+	struct smbios3_entry *se;
 	efi_status_t ret;
 	/* Map within the low 32 bits, to allow for 32bit SMBIOS tables */
 	void *dmi;
-	char *istart;
-	int isize;
 
-	if (sizeof(smbios_table_test) > EFI_PAGE_SIZE)
+	if (sizeof(smbios3_table_test) > EFI_PAGE_SIZE)
 		return EFI_OUT_OF_RESOURCES;
 
 	orig_smbios_table = find_smbios_table(systable);
@@ -586,19 +583,15 @@
 
 	dmi = (void *)(uintptr_t)dmi_addr;
 	se = dmi;
-	boottime->copy_mem(se, smbios_table_test, sizeof(smbios_table_test));
+	boottime->copy_mem(se, smbios3_table_test, sizeof(smbios3_table_test));
 
 	/* update smbios table start address */
-	se->struct_table_address = (uintptr_t)((u8 *)dmi + SMBIOS_ENTRY_HEADER_SIZE);
+	se->struct_table_address = (uintptr_t)((u8 *)dmi + SMBIOS3_ENTRY_HEADER_SIZE);
 
-	/* calculate checksums */
-	istart = (char *)se + SMBIOS_INTERMEDIATE_OFFSET;
-	isize = sizeof(struct smbios_entry) - SMBIOS_INTERMEDIATE_OFFSET;
-	se->intermediate_checksum = table_compute_checksum(istart, isize);
-	se->checksum = table_compute_checksum(se, sizeof(struct smbios_entry));
+	se->checksum = table_compute_checksum(se, sizeof(struct smbios3_entry));
 
 	/* Install SMBIOS information as configuration table */
-	ret = boottime->install_configuration_table(&smbios_guid, dmi);
+	ret = boottime->install_configuration_table(&smbios3_guid, dmi);
 	if (ret != EFI_SUCCESS) {
 		efi_st_error("Cannot install SMBIOS table\n");
 		boottime->free_pages(dmi_addr, 1);
@@ -992,7 +985,7 @@
 	 * If orig_smbios_table is NULL, calling install_configuration_table()
 	 * removes dummy SMBIOS table form systab.
 	 */
-	r = boottime->install_configuration_table(&smbios_guid, orig_smbios_table);
+	r = boottime->install_configuration_table(&smbios3_guid, orig_smbios_table);
 	if (r != EFI_SUCCESS) {
 		efi_st_error("Failed to restore SMBOIS table\n");
 		return EFI_ST_FAILURE;
diff --git a/lib/smbios-parser.c b/lib/smbios-parser.c
index ac9a367..f48d743 100644
--- a/lib/smbios-parser.c
+++ b/lib/smbios-parser.c
@@ -223,21 +223,24 @@
 	}
 }
 
-void smbios_prepare_measurement(const struct smbios_entry *entry,
+void smbios_prepare_measurement(const struct smbios3_entry *entry,
 				struct smbios_header *smbios_copy)
 {
 	u32 i, j;
+	void *table_end;
 	struct smbios_header *header;
 
+	table_end = (void *)((u8 *)smbios_copy + entry->max_struct_size);
+
 	for (i = 0; i < ARRAY_SIZE(smbios_filter_tables); i++) {
 		header = smbios_copy;
-		for (j = 0; j < entry->struct_count; j++) {
+		for (j = 0; (void *)header < table_end; j++) {
 			if (header->type == smbios_filter_tables[i].type)
 				break;
 
 			header = get_next_header(header);
 		}
-		if (j >= entry->struct_count)
+		if ((void *)header >= table_end)
 			continue;
 
 		clear_smbios_table(header,
diff --git a/lib/uuid.c b/lib/uuid.c
index 0be22bc..2d7d995 100644
--- a/lib/uuid.c
+++ b/lib/uuid.c
@@ -177,6 +177,10 @@
 		SMBIOS_TABLE_GUID,
 	},
 	{
+		"SMBIOS3 table",
+		SMBIOS3_TABLE_GUID,
+	},
+	{
 		"Runtime properties",
 		EFI_RT_PROPERTIES_TABLE_GUID,
 	},
diff --git a/test/dm/clk.c b/test/dm/clk.c
index 01417fb..57fabbd 100644
--- a/test/dm/clk.c
+++ b/test/dm/clk.c
@@ -182,19 +182,10 @@
 						   SANDBOX_CLK_ID_I2C));
 	ut_asserteq(1, sandbox_clk_query_requested(dev_clk,
 						   SANDBOX_CLK_ID_UART2));
-	ut_assertok(sandbox_clk_test_free(dev_test));
-	ut_asserteq(0, sandbox_clk_query_requested(dev_clk,
-						   SANDBOX_CLK_ID_SPI));
-	ut_asserteq(0, sandbox_clk_query_requested(dev_clk,
-						   SANDBOX_CLK_ID_I2C));
-	ut_asserteq(0, sandbox_clk_query_requested(dev_clk,
-						   SANDBOX_CLK_ID_UART2));
 
 	ut_asserteq(1, sandbox_clk_query_requested(dev_clk,
 						   SANDBOX_CLK_ID_UART1));
 	ut_assertok(device_remove(dev_test, DM_REMOVE_NORMAL));
-	ut_asserteq(0, sandbox_clk_query_requested(dev_clk,
-						   SANDBOX_CLK_ID_UART1));
 	return 0;
 }
 DM_TEST(dm_test_clk, UT_TESTF_SCAN_FDT);
diff --git a/test/py/requirements.txt b/test/py/requirements.txt
index c3cc916..0f67c3c 100644
--- a/test/py/requirements.txt
+++ b/test/py/requirements.txt
@@ -11,10 +11,10 @@
 packaging==23.2
 pbr==5.4.3
 pluggy==0.13.0
-py==1.10.0
+py==1.11.0
 pycryptodomex==3.19.1
 pyelftools==0.27
-pygit2==1.9.2
+pygit2==1.13.3
 pyparsing==3.0.7
 pytest==6.2.5
 pytest-xdist==2.5.0
diff --git a/test/py/tests/test_gpio.py b/test/py/tests/test_gpio.py
index 0af186f..3e16e63 100644
--- a/test/py/tests/test_gpio.py
+++ b/test/py/tests/test_gpio.py
@@ -85,6 +85,13 @@
         'gpio_ip_pin_clear':'66',
         'gpio_clear_value': 'value is 0',
         'gpio_set_value': 'value is 1',
+        # GPIO pin list to test gpio functionality for each pins, pin should be
+        # pin names (str)
+        'gpio_pin_list': ['gpio@1000031', 'gpio@1000032', 'gpio@20000033'],
+        # GPIO input output list for shorted gpio pins to test gpio
+        # functionality for each of pairs, where the first element is
+        # configured as input and second as output
+        'gpio_ip_op_list': [['gpio0', 'gpio1'], ['gpio2', 'gpio3']],
 }
 """
 
@@ -223,3 +230,86 @@
     response = u_boot_console.run_command(cmd)
     good_response = gpio_set_value
     assert good_response in response
+
+@pytest.mark.buildconfigspec('cmd_gpio')
+def test_gpio_pins_generic(u_boot_console):
+    """Test various gpio related functionality, such as the input, set, clear,
+       and toggle for the set of gpio pin list.
+
+       Specific set of gpio pins (by mentioning gpio pin name) configured as
+       input (mentioned as 'gpio_pin_list') to be tested for multiple gpio
+       commands.
+    """
+
+    f = u_boot_console.config.env.get('env__gpio_dev_config', False)
+    if not f:
+        pytest.skip('gpio not configured')
+
+    gpio_pins = f.get('gpio_pin_list', None)
+    if not gpio_pins:
+        pytest.skip('gpio pin list are not configured')
+
+    for gpin in gpio_pins:
+        # gpio input
+        u_boot_console.run_command(f'gpio input {gpin}')
+        expected_response = f'{gpin}: input:'
+        response = u_boot_console.run_command(f'gpio status -a {gpin}')
+        assert expected_response in response
+
+        # gpio set
+        u_boot_console.run_command(f'gpio set {gpin}')
+        expected_response = f'{gpin}: output: 1'
+        response = u_boot_console.run_command(f'gpio status -a {gpin}')
+        assert expected_response in response
+
+        # gpio clear
+        u_boot_console.run_command(f'gpio clear {gpin}')
+        expected_response = f'{gpin}: output: 0'
+        response = u_boot_console.run_command(f'gpio status -a {gpin}')
+        assert expected_response in response
+
+        # gpio toggle
+        u_boot_console.run_command(f'gpio toggle {gpin}')
+        expected_response = f'{gpin}: output: 1'
+        response = u_boot_console.run_command(f'gpio status -a {gpin}')
+        assert expected_response in response
+
+@pytest.mark.buildconfigspec('cmd_gpio')
+def test_gpio_pins_input_output_generic(u_boot_console):
+    """Test gpio related functionality such as input and output for the list of
+       shorted gpio pins provided as a pair of input and output pins. This test
+       will fail, if the gpio pins are not shorted properly.
+
+       Specific set of shorted gpio pins (by mentioning gpio pin name)
+       configured as input and output (mentioned as 'gpio_ip_op_list') as a
+       pair to be tested for gpio input output case.
+    """
+
+    f = u_boot_console.config.env.get('env__gpio_dev_config', False)
+    if not f:
+        pytest.skip('gpio not configured')
+
+    gpio_pins = f.get('gpio_ip_op_list', None)
+    if not gpio_pins:
+        pytest.skip('gpio pin list for input and output are not configured')
+
+    for gpins in gpio_pins:
+        u_boot_console.run_command(f'gpio input {gpins[0]}')
+        expected_response = f'{gpins[0]}: input:'
+        response = u_boot_console.run_command(f'gpio status -a {gpins[0]}')
+        assert expected_response in response
+
+        u_boot_console.run_command(f'gpio set {gpins[1]}')
+        expected_response = f'{gpins[1]}: output:'
+        response = u_boot_console.run_command(f'gpio status -a {gpins[1]}')
+        assert expected_response in response
+
+        u_boot_console.run_command(f'gpio clear {gpins[1]}')
+        expected_response = f'{gpins[0]}: input: 0'
+        response = u_boot_console.run_command(f'gpio status -a {gpins[0]}')
+        assert expected_response in response
+
+        u_boot_console.run_command(f'gpio set {gpins[1]}')
+        expected_response = f'{gpins[0]}: input: 1'
+        response = u_boot_console.run_command(f'gpio status -a {gpins[0]}')
+        assert expected_response in response
diff --git a/test/py/tests/test_mmc.py b/test/py/tests/test_mmc.py
new file mode 100644
index 0000000..a96c4e8
--- /dev/null
+++ b/test/py/tests/test_mmc.py
@@ -0,0 +1,671 @@
+# SPDX-License-Identifier: GPL-2.0
+# (C) Copyright 2023, Advanced Micro Devices, Inc.
+
+import pytest
+import random
+import re
+import u_boot_utils
+
+"""
+Note: This test doesn't rely on boardenv_* configuration values but it can
+change the test behavior. To test MMC file system cases (fat32, ext2, ext4),
+MMC device should be formatted and valid partitions should be created for
+different file system, otherwise it may leads to failure. This test will be
+skipped if the MMC device is not detected.
+
+For example:
+
+# Setup env__mmc_device_test_skip to not skipping the test. By default, its
+# value is set to True. Set it to False to run all tests for MMC device.
+env__mmc_device_test_skip = False
+"""
+
+mmc_set_up = False
+controllers = 0
+devices = {}
+
+def setup_mmc(u_boot_console):
+    if u_boot_console.config.env.get('env__mmc_device_test_skip', True):
+        pytest.skip('MMC device test is not enabled')
+
+@pytest.mark.buildconfigspec('cmd_mmc')
+def test_mmc_list(u_boot_console):
+    setup_mmc(u_boot_console)
+    output = u_boot_console.run_command('mmc list')
+    if 'No MMC device available' in output:
+        pytest.skip('No SD/MMC/eMMC controller available')
+
+    if 'Card did not respond to voltage select' in output:
+        pytest.skip('No SD/MMC card present')
+
+    array = output.split()
+    global devices
+    global controllers
+    controllers = int(len(array) / 2)
+    for x in range(0, controllers):
+        y = x * 2
+        devices[x] = {}
+        devices[x]['name'] = array[y]
+
+    global mmc_set_up
+    mmc_set_up = True
+
+@pytest.mark.buildconfigspec('cmd_mmc')
+def test_mmc_dev(u_boot_console):
+    if not mmc_set_up:
+        pytest.skip('No SD/MMC/eMMC controller available')
+
+    fail = 0
+    for x in range(0, controllers):
+        devices[x]['detected'] = 'yes'
+        output = u_boot_console.run_command('mmc dev %d' % x)
+
+        # Some sort of switch here
+        if 'Card did not respond to voltage select' in output:
+            fail = 1
+            devices[x]['detected'] = 'no'
+
+        if 'no mmc device at slot' in output:
+            devices[x]['detected'] = 'no'
+
+        if 'MMC: no card present' in output:
+            devices[x]['detected'] = 'no'
+
+    if fail:
+        pytest.fail('Card not present')
+
+@pytest.mark.buildconfigspec('cmd_mmc')
+def test_mmcinfo(u_boot_console):
+    if not mmc_set_up:
+        pytest.skip('No SD/MMC/eMMC controller available')
+
+    for x in range(0, controllers):
+        if devices[x]['detected'] == 'yes':
+            u_boot_console.run_command('mmc dev %d' % x)
+            output = u_boot_console.run_command('mmcinfo')
+            if 'busy timeout' in output:
+                pytest.skip('No SD/MMC/eMMC device present')
+
+            obj = re.search(r'Capacity: (\d+|\d+[\.]?\d)', output)
+            try:
+                capacity = float(obj.groups()[0])
+                print(capacity)
+                devices[x]['capacity'] = capacity
+                print('Capacity of dev %d is: %g GiB' % (x, capacity))
+            except ValueError:
+                pytest.fail('MMC capacity not recognized')
+
+@pytest.mark.buildconfigspec('cmd_mmc')
+def test_mmc_info(u_boot_console):
+    if not mmc_set_up:
+        pytest.skip('No SD/MMC/eMMC controller available')
+
+    for x in range(0, controllers):
+        if devices[x]['detected'] == 'yes':
+            u_boot_console.run_command('mmc dev %d' % x)
+
+            output = u_boot_console.run_command('mmc info')
+
+            obj = re.search(r'Capacity: (\d+|\d+[\.]?\d)', output)
+            try:
+                capacity = float(obj.groups()[0])
+                print(capacity)
+                if devices[x]['capacity'] != capacity:
+                    pytest.fail("MMC capacity doesn't match mmcinfo")
+
+            except ValueError:
+                pytest.fail('MMC capacity not recognized')
+
+@pytest.mark.buildconfigspec('cmd_mmc')
+def test_mmc_rescan(u_boot_console):
+    if not mmc_set_up:
+        pytest.skip('No SD/MMC/eMMC controller available')
+
+    if not devices:
+        pytest.skip('No devices detected')
+
+    for x in range(0, controllers):
+        if devices[x]['detected'] == 'yes':
+            u_boot_console.run_command('mmc dev %d' % x)
+            output = u_boot_console.run_command('mmc rescan')
+            if output:
+                pytest.fail('mmc rescan has something to check')
+            output = u_boot_console.run_command('echo $?')
+            assert output.endswith('0')
+
+@pytest.mark.buildconfigspec('cmd_mmc')
+def test_mmc_part(u_boot_console):
+    if not mmc_set_up:
+        pytest.skip('No SD/MMC/eMMC controller available')
+
+    if not devices:
+        pytest.skip('No devices detected')
+
+    for x in range(0, controllers):
+        if devices[x]['detected'] == 'yes':
+            u_boot_console.run_command('mmc dev %d' % x)
+            output = u_boot_console.run_command('mmc part')
+
+            lines = output.split('\n')
+            part_fat = []
+            part_ext = []
+            for line in lines:
+                obj = re.search(
+                        r'(\d)\s+\d+\s+\d+\s+\w+\d+\w+-\d+\s+(\d+\w+)', line)
+                if obj:
+                    part_id = int(obj.groups()[0])
+                    part_type = obj.groups()[1]
+                    print('part_id:%d, part_type:%s' % (part_id, part_type))
+
+                    if part_type in ['0c', '0b', '0e']:
+                        print('Fat detected')
+                        part_fat.append(part_id)
+                    elif part_type == '83':
+                        print('ext detected')
+                        part_ext.append(part_id)
+                    else:
+                        pytest.fail('Unsupported Filesystem on device %d' % x)
+            devices[x]['ext4'] = part_ext
+            devices[x]['ext2'] = part_ext
+            devices[x]['fat'] = part_fat
+
+            if not part_ext and not part_fat:
+                pytest.fail('No partition detected on device %d' % x)
+
+@pytest.mark.buildconfigspec('cmd_mmc')
+@pytest.mark.buildconfigspec('cmd_fat')
+def test_mmc_fatls_fatinfo(u_boot_console):
+    if not mmc_set_up:
+        pytest.skip('No SD/MMC/eMMC controller available')
+
+    if not devices:
+        pytest.skip('No devices detected')
+
+    part_detect = 0
+    fs = 'fat'
+    for x in range(0, controllers):
+        if devices[x]['detected'] == 'yes':
+            u_boot_console.run_command('mmc dev %d' % x)
+            try:
+                partitions = devices[x][fs]
+            except:
+                print('No %s table on this device' % fs.upper())
+                continue
+
+            for part in partitions:
+                output = u_boot_console.run_command(
+                        'fatls mmc %d:%s' % (x, part))
+                if 'Unrecognized filesystem type' in output:
+                    partitions.remove(part)
+                    pytest.fail('Unrecognized filesystem')
+
+                if not re.search(r'\d file\(s\), \d dir\(s\)', output):
+                    pytest.fail('%s read failed on device %d' % (fs.upper, x))
+                output = u_boot_console.run_command(
+                        'fatinfo mmc %d:%s' % (x, part))
+                string = 'Filesystem: %s' % fs.upper
+                if re.search(string, output):
+                    pytest.fail('%s FS failed on device %d' % (fs.upper(), x))
+                part_detect = 1
+
+    if not part_detect:
+        pytest.skip('No %s partition detected' % fs.upper())
+
+
+@pytest.mark.buildconfigspec('cmd_mmc')
+@pytest.mark.buildconfigspec('cmd_fat')
+@pytest.mark.buildconfigspec('cmd_memory')
+def test_mmc_fatload_fatwrite(u_boot_console):
+    if not mmc_set_up:
+        pytest.skip('No SD/MMC/eMMC controller available')
+
+    if not devices:
+        pytest.skip('No devices detected')
+
+    part_detect = 0
+    fs = 'fat'
+    for x in range(0, controllers):
+        if devices[x]['detected'] == 'yes':
+            u_boot_console.run_command('mmc dev %d' % x)
+            try:
+                partitions = devices[x][fs]
+            except:
+                print('No %s table on this device' % fs.upper())
+                continue
+
+            for part in partitions:
+                part_detect = 1
+                addr = u_boot_utils.find_ram_base(u_boot_console)
+                devices[x]['addr_%d' % part] = addr
+                size = random.randint(4, 1 * 1024 * 1024)
+                devices[x]['size_%d' % part] = size
+                # count CRC32
+                output = u_boot_console.run_command('crc32 %x %x' % (addr, size))
+                m = re.search('==> (.+?)', output)
+                if not m:
+                    pytest.fail('CRC32 failed')
+                expected_crc32 = m.group(1)
+                devices[x]['expected_crc32_%d' % part] = expected_crc32
+                # do write
+                file = '%s_%d' % ('uboot_test', size)
+                devices[x]['file_%d' % part] = file
+                output = u_boot_console.run_command(
+                    '%swrite mmc %d:%s %x %s %x' % (fs, x, part, addr, file, size)
+                )
+                assert 'Unable to write' not in output
+                assert 'Error' not in output
+                assert 'overflow' not in output
+                expected_text = '%d bytes written' % size
+                assert expected_text in output
+
+                alignment = int(
+                    u_boot_console.config.buildconfig.get(
+                        'config_sys_cacheline_size', 128
+                    )
+                )
+                offset = random.randrange(alignment, 1024, alignment)
+                output = u_boot_console.run_command(
+                    '%sload mmc %d:%s %x %s' % (fs, x, part, addr + offset, file)
+                )
+                assert 'Invalid FAT entry' not in output
+                assert 'Unable to read file' not in output
+                assert 'Misaligned buffer address' not in output
+                expected_text = '%d bytes read' % size
+                assert expected_text in output
+
+                output = u_boot_console.run_command(
+                    'crc32 %x $filesize' % (addr + offset)
+                )
+                assert expected_crc32 in output
+
+    if not part_detect:
+        pytest.skip('No %s partition detected' % fs.upper())
+
+@pytest.mark.buildconfigspec('cmd_mmc')
+@pytest.mark.buildconfigspec('cmd_ext4')
+def test_mmc_ext4ls(u_boot_console):
+    if not mmc_set_up:
+        pytest.skip('No SD/MMC/eMMC controller available')
+
+    if not devices:
+        pytest.skip('No devices detected')
+
+    part_detect = 0
+    fs = 'ext4'
+    for x in range(0, controllers):
+        if devices[x]['detected'] == 'yes':
+            try:
+                partitions = devices[x][fs]
+            except:
+                print('No %s table on this device' % fs.upper())
+                continue
+
+            u_boot_console.run_command('mmc dev %d' % x)
+            for part in partitions:
+                output = u_boot_console.run_command('%sls mmc %d:%s' % (fs, x, part))
+                if 'Unrecognized filesystem type' in output:
+                    partitions.remove(part)
+                    pytest.fail('Unrecognized filesystem')
+                part_detect = 1
+
+    if not part_detect:
+        pytest.skip('No %s partition detected' % fs.upper())
+
+@pytest.mark.buildconfigspec('cmd_mmc')
+@pytest.mark.buildconfigspec('cmd_ext4')
+@pytest.mark.buildconfigspec('ext4_write')
+@pytest.mark.buildconfigspec('cmd_memory')
+def test_mmc_ext4load_ext4write(u_boot_console):
+    if not mmc_set_up:
+        pytest.skip('No SD/MMC/eMMC controller available')
+
+    if not devices:
+        pytest.skip('No devices detected')
+
+    part_detect = 0
+    fs = 'ext4'
+    for x in range(0, controllers):
+        if devices[x]['detected'] == 'yes':
+            u_boot_console.run_command('mmc dev %d' % x)
+            try:
+                partitions = devices[x][fs]
+            except:
+                print('No %s table on this device' % fs.upper())
+                continue
+
+            for part in partitions:
+                part_detect = 1
+                addr = u_boot_utils.find_ram_base(u_boot_console)
+                devices[x]['addr_%d' % part] = addr
+                size = random.randint(4, 1 * 1024 * 1024)
+                devices[x]['size_%d' % part] = size
+                # count CRC32
+                output = u_boot_console.run_command('crc32 %x %x' % (addr, size))
+                m = re.search('==> (.+?)', output)
+                if not m:
+                    pytest.fail('CRC32 failed')
+                expected_crc32 = m.group(1)
+                devices[x]['expected_crc32_%d' % part] = expected_crc32
+                # do write
+
+                file = '%s_%d' % ('uboot_test', size)
+                devices[x]['file_%d' % part] = file
+                output = u_boot_console.run_command(
+                    '%swrite mmc %d:%s %x /%s %x' % (fs, x, part, addr, file, size)
+                )
+                assert 'Unable to write' not in output
+                assert 'Error' not in output
+                assert 'overflow' not in output
+                expected_text = '%d bytes written' % size
+                assert expected_text in output
+
+                offset = random.randrange(128, 1024, 128)
+                output = u_boot_console.run_command(
+                    '%sload mmc %d:%s %x /%s' % (fs, x, part, addr + offset, file)
+                )
+                expected_text = '%d bytes read' % size
+                assert expected_text in output
+
+                output = u_boot_console.run_command(
+                    'crc32 %x $filesize' % (addr + offset)
+                )
+                assert expected_crc32 in output
+
+    if not part_detect:
+        pytest.skip('No %s partition detected' % fs.upper())
+
+@pytest.mark.buildconfigspec('cmd_mmc')
+@pytest.mark.buildconfigspec('cmd_ext2')
+def test_mmc_ext2ls(u_boot_console):
+    if not mmc_set_up:
+        pytest.skip('No SD/MMC/eMMC controller available')
+
+    if not devices:
+        pytest.skip('No devices detected')
+
+    part_detect = 0
+    fs = 'ext2'
+    for x in range(0, controllers):
+        if devices[x]['detected'] == 'yes':
+            u_boot_console.run_command('mmc dev %d' % x)
+            try:
+                partitions = devices[x][fs]
+            except:
+                print('No %s table on this device' % fs.upper())
+                continue
+
+            for part in partitions:
+                part_detect = 1
+                output = u_boot_console.run_command('%sls mmc %d:%s' % (fs, x, part))
+                if 'Unrecognized filesystem type' in output:
+                    partitions.remove(part)
+                    pytest.fail('Unrecognized filesystem')
+                part_detect = 1
+
+    if not part_detect:
+        pytest.skip('No %s partition detected' % fs.upper())
+
+@pytest.mark.buildconfigspec('cmd_mmc')
+@pytest.mark.buildconfigspec('cmd_ext2')
+@pytest.mark.buildconfigspec('cmd_ext4')
+@pytest.mark.buildconfigspec('ext4_write')
+@pytest.mark.buildconfigspec('cmd_memory')
+def test_mmc_ext2load(u_boot_console):
+    if not mmc_set_up:
+        pytest.skip('No SD/MMC/eMMC controller available')
+
+    if not devices:
+        pytest.skip('No devices detected')
+
+    part_detect = 0
+    fs = 'ext2'
+    for x in range(0, controllers):
+        if devices[x]['detected'] == 'yes':
+            u_boot_console.run_command('mmc dev %d' % x)
+            try:
+                partitions = devices[x][fs]
+            except:
+                print('No %s table on this device' % fs.upper())
+                continue
+
+            for part in partitions:
+                part_detect = 1
+                addr = devices[x]['addr_%d' % part]
+                size = devices[x]['size_%d' % part]
+                expected_crc32 = devices[x]['expected_crc32_%d' % part]
+                file = devices[x]['file_%d' % part]
+
+                offset = random.randrange(128, 1024, 128)
+                output = u_boot_console.run_command(
+                    '%sload mmc %d:%s %x /%s' % (fs, x, part, addr + offset, file)
+                )
+                expected_text = '%d bytes read' % size
+                assert expected_text in output
+
+                output = u_boot_console.run_command(
+                    'crc32 %x $filesize' % (addr + offset)
+                )
+                assert expected_crc32 in output
+
+    if not part_detect:
+        pytest.skip('No %s partition detected' % fs.upper())
+
+@pytest.mark.buildconfigspec('cmd_mmc')
+@pytest.mark.buildconfigspec('cmd_fs_generic')
+def test_mmc_ls(u_boot_console):
+    if not mmc_set_up:
+        pytest.skip('No SD/MMC/eMMC controller available')
+
+    if not devices:
+        pytest.skip('No devices detected')
+
+    part_detect = 0
+    for x in range(0, controllers):
+        if devices[x]['detected'] == 'yes':
+            u_boot_console.run_command('mmc dev %d' % x)
+            for fs in ['fat', 'ext4']:
+                try:
+                    partitions = devices[x][fs]
+                except:
+                    print('No %s table on this device' % fs.upper())
+                    continue
+
+                for part in partitions:
+                    part_detect = 1
+                    output = u_boot_console.run_command('ls mmc %d:%s' % (x, part))
+                    if re.search(r'No \w+ table on this device', output):
+                        pytest.fail(
+                            '%s: Partition table not found %d' % (fs.upper(), x)
+                        )
+
+    if not part_detect:
+        pytest.skip('No partition detected')
+
+@pytest.mark.buildconfigspec('cmd_mmc')
+@pytest.mark.buildconfigspec('cmd_fs_generic')
+def test_mmc_load(u_boot_console):
+    if not mmc_set_up:
+        pytest.skip('No SD/MMC/eMMC controller available')
+
+    if not devices:
+        pytest.skip('No devices detected')
+
+    part_detect = 0
+    for x in range(0, controllers):
+        if devices[x]['detected'] == 'yes':
+            u_boot_console.run_command('mmc dev %d' % x)
+            for fs in ['fat', 'ext4']:
+                try:
+                    partitions = devices[x][fs]
+                except:
+                    print('No %s table on this device' % fs.upper())
+                    continue
+
+                for part in partitions:
+                    part_detect = 1
+                    addr = devices[x]['addr_%d' % part]
+                    size = devices[x]['size_%d' % part]
+                    expected_crc32 = devices[x]['expected_crc32_%d' % part]
+                    file = devices[x]['file_%d' % part]
+
+                    offset = random.randrange(128, 1024, 128)
+                    output = u_boot_console.run_command(
+                        'load mmc %d:%s %x /%s' % (x, part, addr + offset, file)
+                    )
+                    expected_text = '%d bytes read' % size
+                    assert expected_text in output
+
+                    output = u_boot_console.run_command(
+                        'crc32 %x $filesize' % (addr + offset)
+                    )
+                    assert expected_crc32 in output
+
+    if not part_detect:
+        pytest.skip('No partition detected')
+
+@pytest.mark.buildconfigspec('cmd_mmc')
+@pytest.mark.buildconfigspec('cmd_fs_generic')
+def test_mmc_save(u_boot_console):
+    if not mmc_set_up:
+        pytest.skip('No SD/MMC/eMMC controller available')
+
+    if not devices:
+        pytest.skip('No devices detected')
+
+    part_detect = 0
+    for x in range(0, controllers):
+        if devices[x]['detected'] == 'yes':
+            u_boot_console.run_command('mmc dev %d' % x)
+            for fs in ['fat', 'ext4']:
+                try:
+                    partitions = devices[x][fs]
+                except:
+                    print('No %s table on this device' % fs.upper())
+                    continue
+
+                for part in partitions:
+                    part_detect = 1
+                    addr = devices[x]['addr_%d' % part]
+                    size = 0
+                    file = devices[x]['file_%d' % part]
+
+                    offset = random.randrange(128, 1024, 128)
+                    output = u_boot_console.run_command(
+                        'save mmc %d:%s %x /%s %d'
+                        % (x, part, addr + offset, file, size)
+                    )
+                    expected_text = '%d bytes written' % size
+                    assert expected_text in output
+
+    if not part_detect:
+        pytest.skip('No partition detected')
+
+@pytest.mark.buildconfigspec('cmd_mmc')
+@pytest.mark.buildconfigspec('cmd_fat')
+@pytest.mark.buildconfigspec('cmd_memory')
+def test_mmc_fat_read_write_files(u_boot_console):
+    test_mmc_list(u_boot_console)
+    test_mmc_dev(u_boot_console)
+    test_mmcinfo(u_boot_console)
+    test_mmc_part(u_boot_console)
+    if not mmc_set_up:
+        pytest.skip('No SD/MMC/eMMC controller available')
+
+    if not devices:
+        pytest.skip('No devices detected')
+
+    part_detect = 0
+    fs = 'fat'
+
+    # Number of files to be written/read in MMC card
+    num_files = 100
+
+    for x in range(0, controllers):
+        if devices[x]['detected'] == 'yes':
+            u_boot_console.run_command('mmc dev %d' % x)
+            try:
+                partitions = devices[x][fs]
+            except:
+                print('No %s table on this device' % fs.upper())
+                continue
+
+            for part in partitions:
+                part_detect = 1
+                addr = u_boot_utils.find_ram_base(u_boot_console)
+                count_f = 0
+                addr_l = []
+                size_l = []
+                file_l = []
+                crc32_l = []
+                offset_l = []
+                addr_l.append(addr)
+
+                while count_f < num_files:
+                    size_l.append(random.randint(4, 1 * 1024 * 1024))
+
+                    # CRC32 count
+                    output = u_boot_console.run_command(
+                        'crc32 %x %x' % (addr_l[count_f], size_l[count_f])
+                    )
+                    m = re.search('==> (.+?)', output)
+                    if not m:
+                        pytest.fail('CRC32 failed')
+                    crc32_l.append(m.group(1))
+
+                    # Write operation
+                    file_l.append('%s_%d_%d' % ('uboot_test', count_f, size_l[count_f]))
+                    output = u_boot_console.run_command(
+                        '%swrite mmc %d:%s %x %s %x'
+                        % (
+                            fs,
+                            x,
+                            part,
+                            addr_l[count_f],
+                            file_l[count_f],
+                            size_l[count_f],
+                        )
+                    )
+                    assert 'Unable to write' not in output
+                    assert 'Error' not in output
+                    assert 'overflow' not in output
+                    expected_text = '%d bytes written' % size_l[count_f]
+                    assert expected_text in output
+
+                    addr_l.append(addr_l[count_f] + size_l[count_f] + 1048576)
+                    count_f += 1
+
+                count_f = 0
+                while count_f < num_files:
+                    alignment = int(
+                        u_boot_console.config.buildconfig.get(
+                            'config_sys_cacheline_size', 128
+                        )
+                    )
+                    offset_l.append(random.randrange(alignment, 1024, alignment))
+
+                    # Read operation
+                    output = u_boot_console.run_command(
+                        '%sload mmc %d:%s %x %s'
+                        % (
+                            fs,
+                            x,
+                            part,
+                            addr_l[count_f] + offset_l[count_f],
+                            file_l[count_f],
+                        )
+                    )
+                    assert 'Invalid FAT entry' not in output
+                    assert 'Unable to read file' not in output
+                    assert 'Misaligned buffer address' not in output
+                    expected_text = '%d bytes read' % size_l[count_f]
+                    assert expected_text in output
+
+                    output = u_boot_console.run_command(
+                        'crc32 %x $filesize' % (addr_l[count_f] + offset_l[count_f])
+                    )
+                    assert crc32_l[count_f] in output
+
+                    count_f += 1
+
+    if not part_detect:
+        pytest.skip('No %s partition detected' % fs.upper())
diff --git a/test/py/tests/test_scsi.py b/test/py/tests/test_scsi.py
new file mode 100644
index 0000000..be2e283
--- /dev/null
+++ b/test/py/tests/test_scsi.py
@@ -0,0 +1,92 @@
+# SPDX-License-Identifier: GPL-2.0
+# (C) Copyright 2023, Advanced Micro Devices, Inc.
+
+import pytest
+
+"""
+Note: This test relies on boardenv_* containing configuration values to define
+the SCSI device number, type and capacity. This test will be automatically
+skipped without this.
+
+For example:
+
+# Setup env__scsi_device_test to set the SCSI device number/slot, the type of
+device, and the device capacity in MB.
+env__scsi_device_test = {
+    'dev_num': 0,
+    'device_type': 'Hard Disk',
+    'device_capacity': '476940.0 MB',
+}
+"""
+
+def scsi_setup(u_boot_console):
+    f = u_boot_console.config.env.get('env__scsi_device_test', None)
+    if not f:
+        pytest.skip('No SCSI device to test')
+
+    dev_num = f.get('dev_num', None)
+    if not isinstance(dev_num, int):
+        pytest.skip('No device number specified in env file to read')
+
+    dev_type = f.get('device_type')
+    if not dev_type:
+        pytest.skip('No device type specified in env file to read')
+
+    dev_size = f.get('device_capacity')
+    if not dev_size:
+        pytest.skip('No device capacity specified in env file to read')
+
+    return dev_num, dev_type, dev_size
+
+@pytest.mark.buildconfigspec('cmd_scsi')
+def test_scsi_reset(u_boot_console):
+    dev_num, dev_type, dev_size = scsi_setup(u_boot_console)
+    output = u_boot_console.run_command('scsi reset')
+    assert f'Device {dev_num}:' in output
+    assert f'Type: {dev_type}' in output
+    assert f'Capacity: {dev_size}' in output
+    output = u_boot_console.run_command('echo $?')
+    assert output.endswith('0')
+
+@pytest.mark.buildconfigspec('cmd_scsi')
+def test_scsi_info(u_boot_console):
+    dev_num, dev_type, dev_size = scsi_setup(u_boot_console)
+    output = u_boot_console.run_command('scsi info')
+    assert f'Device {dev_num}:' in output
+    assert f'Type: {dev_type}' in output
+    assert f'Capacity: {dev_size}' in output
+    output = u_boot_console.run_command('echo $?')
+    assert output.endswith('0')
+
+@pytest.mark.buildconfigspec('cmd_scsi')
+def test_scsi_scan(u_boot_console):
+    dev_num, dev_type, dev_size = scsi_setup(u_boot_console)
+    output = u_boot_console.run_command('scsi scan')
+    assert f'Device {dev_num}:' in output
+    assert f'Type: {dev_type}' in output
+    assert f'Capacity: {dev_size}' in output
+    output = u_boot_console.run_command('echo $?')
+    assert output.endswith('0')
+
+@pytest.mark.buildconfigspec('cmd_scsi')
+def test_scsi_dev(u_boot_console):
+    dev_num, dev_type, dev_size = scsi_setup(u_boot_console)
+    output = u_boot_console.run_command('scsi device')
+    assert 'no scsi devices available' not in output
+    assert f'device {dev_num}:' in output
+    assert f'Type: {dev_type}' in output
+    assert f'Capacity: {dev_size}' in output
+    output = u_boot_console.run_command('echo $?')
+    assert output.endswith('0')
+    output = u_boot_console.run_command('scsi device %d' % dev_num)
+    assert 'is now current device' in output
+    output = u_boot_console.run_command('echo $?')
+    assert output.endswith('0')
+
+@pytest.mark.buildconfigspec('cmd_scsi')
+def test_scsi_part(u_boot_console):
+    test_scsi_dev(u_boot_console)
+    output = u_boot_console.run_command('scsi part')
+    assert 'Partition Map for SCSI device' in output
+    output = u_boot_console.run_command('echo $?')
+    assert output.endswith('0')
diff --git a/test/py/tests/test_smbios.py b/test/py/tests/test_smbios.py
new file mode 100644
index 0000000..82b0b68
--- /dev/null
+++ b/test/py/tests/test_smbios.py
@@ -0,0 +1,41 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+"""Test smbios command"""
+
+import pytest
+
+@pytest.mark.buildconfigspec('cmd_smbios')
+@pytest.mark.notbuildconfigspec('qfw_smbios')
+@pytest.mark.notbuildconfigspec('sandbox')
+def test_cmd_smbios(u_boot_console):
+    """Run the smbios command"""
+    output = u_boot_console.run_command('smbios')
+    assert 'DMI type 127,' in output
+
+@pytest.mark.buildconfigspec('cmd_smbios')
+@pytest.mark.buildconfigspec('qfw_smbios')
+@pytest.mark.notbuildconfigspec('sandbox')
+# TODO:
+# QEMU v8.2.0 lacks SMBIOS support for RISC-V
+# Once support is available in our Docker image we can remove the constraint.
+@pytest.mark.notbuildconfigspec('riscv')
+def test_cmd_smbios_qemu(u_boot_console):
+    """Run the smbios command on QEMU"""
+    output = u_boot_console.run_command('smbios')
+    assert 'DMI type 1,' in output
+    assert 'Manufacturer: QEMU' in output
+    assert 'DMI type 127,' in output
+
+@pytest.mark.buildconfigspec('cmd_smbios')
+@pytest.mark.buildconfigspec('sandbox')
+def test_cmd_smbios_sandbox(u_boot_console):
+    """Run the smbios command on the sandbox"""
+    output = u_boot_console.run_command('smbios')
+    assert 'DMI type 0,' in output
+    assert 'String 1: U-Boot' in output
+    assert 'DMI type 1,' in output
+    assert 'Manufacturer: sandbox' in output
+    assert 'DMI type 2,' in output
+    assert 'DMI type 3,' in output
+    assert 'DMI type 4,' in output
+    assert 'DMI type 127,' in output
diff --git a/test/py/tests/test_usb.py b/test/py/tests/test_usb.py
new file mode 100644
index 0000000..fb3d20f
--- /dev/null
+++ b/test/py/tests/test_usb.py
@@ -0,0 +1,626 @@
+# SPDX-License-Identifier: GPL-2.0
+# (C) Copyright 2023, Advanced Micro Devices, Inc.
+
+import pytest
+import random
+import re
+import u_boot_utils
+
+"""
+Note: This test doesn't rely on boardenv_* configuration values but it can
+change the test behavior. To test USB file system cases (fat32, ext2, ext4),
+USB device should be formatted and valid partitions should be created for
+different file system, otherwise it may leads to failure. This test will be
+skipped if the USB device is not detected.
+
+For example:
+
+# Setup env__usb_device_test_skip to not skipping the test. By default, its
+# value is set to True. Set it to False to run all tests for USB device.
+env__usb_device_test_skip = False
+"""
+
+def setup_usb(u_boot_console):
+    if u_boot_console.config.env.get('env__usb_device_test_skip', True):
+        pytest.skip('USB device test is not enabled')
+
+@pytest.mark.buildconfigspec('cmd_usb')
+def test_usb_start(u_boot_console):
+    setup_usb(u_boot_console)
+    output = u_boot_console.run_command('usb start')
+
+    # if output is empty, usb start may already run as part of preboot command
+    # re-start the usb, in that case
+    if not output:
+        u_boot_console.run_command('usb stop')
+        output = u_boot_console.run_command('usb start')
+
+    if 'No USB device found' in output:
+        pytest.skip('No USB controller available')
+
+    if 'Card did not respond to voltage select' in output:
+        pytest.skip('No USB device present')
+
+    controllers = 0
+    storage_device = 0
+    obj = re.search(r'\d USB Device\(s\) found', output)
+    controllers = int(obj.group()[0])
+
+    if not controllers:
+        pytest.skip('No USB device present')
+
+    obj = re.search(r'\d Storage Device\(s\) found', output)
+    storage_device = int(obj.group()[0])
+
+    if not storage_device:
+        pytest.skip('No USB storage device present')
+
+    assert 'USB init failed' not in output
+    assert 'starting USB...' in output
+
+    if 'Starting the controller' in output:
+        assert 'USB XHCI' in output
+
+    output = u_boot_console.run_command('echo $?')
+    assert output.endswith('0')
+    return controllers, storage_device
+
+@pytest.mark.buildconfigspec('cmd_usb')
+def test_usb_stop(u_boot_console):
+    setup_usb(u_boot_console)
+    output = u_boot_console.run_command('usb stop')
+    assert 'stopping USB..' in output
+
+    output = u_boot_console.run_command('echo $?')
+    assert output.endswith('0')
+
+    output = u_boot_console.run_command('usb dev')
+    assert "USB is stopped. Please issue 'usb start' first." in output
+
+@pytest.mark.buildconfigspec('cmd_usb')
+def test_usb_reset(u_boot_console):
+    setup_usb(u_boot_console)
+    output = u_boot_console.run_command('usb reset')
+
+    if 'No USB device found' in output:
+        pytest.skip('No USB controller available')
+
+    if 'Card did not respond to voltage select' in output:
+        pytest.skip('No USB device present')
+
+    obj = re.search(r'\d USB Device\(s\) found', output)
+    usb_dev_num = int(obj.group()[0])
+
+    if not usb_dev_num:
+        pytest.skip('No USB device present')
+
+    obj = re.search(r'\d Storage Device\(s\) found', output)
+    usb_stor_num = int(obj.group()[0])
+
+    if not usb_stor_num:
+        pytest.skip('No USB storage device present')
+
+    assert 'BUG' not in output
+    assert 'USB init failed' not in output
+    assert 'resetting USB...' in output
+
+    if 'Starting the controller' in output:
+        assert 'USB XHCI' in output
+
+    output = u_boot_console.run_command('echo $?')
+    assert output.endswith('0')
+
+@pytest.mark.buildconfigspec('cmd_usb')
+def test_usb_info(u_boot_console):
+    controllers, storage_device = test_usb_start(u_boot_console)
+    output = u_boot_console.run_command('usb info')
+
+    num_controller = len(re.findall(': Hub,', output))
+    num_mass_storage = len(re.findall(': Mass Storage,', output))
+
+    assert num_controller == controllers - 1
+    assert num_mass_storage == storage_device
+
+    output = u_boot_console.run_command('echo $?')
+    assert output.endswith('0')
+
+    for i in range(0, storage_device + controllers - 1):
+        output = u_boot_console.run_command('usb info %d' % i)
+        num_controller = len(re.findall(': Hub,', output))
+        num_mass_storage = len(re.findall(': Mass Storage,', output))
+        assert num_controller + num_mass_storage == 1
+        assert 'No device available' not in output
+        output = u_boot_console.run_command('echo $?')
+        assert output.endswith('0')
+
+@pytest.mark.buildconfigspec('cmd_usb')
+def test_usb_tree(u_boot_console):
+    controllers, storage_device = test_usb_start(u_boot_console)
+    output = u_boot_console.run_command('usb tree')
+
+    num_controller = len(re.findall('Hub', output))
+    num_mass_storage = len(re.findall('Mass Storage', output))
+
+    assert num_controller == controllers - 1
+    assert num_mass_storage == storage_device
+
+    output = u_boot_console.run_command('echo $?')
+    assert output.endswith('0')
+
+@pytest.mark.buildconfigspec('cmd_usb')
+@pytest.mark.buildconfigspec('usb_storage')
+def test_usb_storage(u_boot_console):
+    controllers, storage_device = test_usb_start(u_boot_console)
+    output = u_boot_console.run_command('usb storage')
+
+    obj = re.findall(r'Capacity: (\d+|\d+[\.]?\d)', output)
+    devices = {}
+
+    for key in range(int(storage_device)):
+        devices[key] = {}
+
+    for x in range(int(storage_device)):
+        try:
+            capacity = float(obj[x].split()[0])
+            devices[x]['capacity'] = capacity
+            print('USB storage device %d capacity is: %g MB' % (x, capacity))
+        except ValueError:
+            pytest.fail('USB storage device capacity not recognized')
+
+    output = u_boot_console.run_command('echo $?')
+    assert output.endswith('0')
+
+@pytest.mark.buildconfigspec('cmd_usb')
+def test_usb_dev(u_boot_console):
+    controllers, storage_device = test_usb_start(u_boot_console)
+    output = u_boot_console.run_command('usb dev')
+
+    assert 'no usb devices available' not in output
+
+    output = u_boot_console.run_command('echo $?')
+    assert output.endswith('0')
+
+    devices = {}
+
+    for key in range(int(storage_device)):
+        devices[key] = {}
+
+    fail = 0
+    for x in range(0, storage_device):
+        devices[x]['detected'] = 'yes'
+        output = u_boot_console.run_command('usb dev %d' % x)
+
+        if 'Card did not respond to voltage select' in output:
+            fail = 1
+            devices[x]['detected'] = 'no'
+
+        if 'No USB device found' in output:
+            devices[x]['detected'] = 'no'
+
+        if 'unknown device' in output:
+            devices[x]['detected'] = 'no'
+
+        assert 'is now current device' in output
+        output = u_boot_console.run_command('echo $?')
+        assert output.endswith('0')
+
+    if fail:
+        pytest.fail('USB device not present')
+
+    return devices, controllers, storage_device
+
+@pytest.mark.buildconfigspec('cmd_usb')
+def test_usb_part(u_boot_console):
+    devices, controllers, storage_device = test_usb_dev(u_boot_console)
+    if not devices:
+        pytest.skip('No devices detected')
+
+    u_boot_console.run_command('usb part')
+
+    output = u_boot_console.run_command('echo $?')
+    assert output.endswith('0')
+
+    for i in range(0, storage_device):
+        if devices[i]['detected'] == 'yes':
+            u_boot_console.run_command('usb dev %d' % i)
+            output = u_boot_console.run_command('usb part')
+
+            lines = output.split('\n')
+            part_fat = []
+            part_ext = []
+            for line in lines:
+                obj = re.search(r'(\d)\s+\d+\s+\d+\s+\w+\d+\w+-\d+\s+(\d+\w+)', line)
+                if obj:
+                    part_id = int(obj.groups()[0])
+                    part_type = obj.groups()[1]
+                    print('part_id:%d, part_type:%s' % (part_id, part_type))
+
+                    if part_type == '0c' or part_type == '0b' or part_type == '0e':
+                        print('Fat detected')
+                        part_fat.append(part_id)
+                    elif part_type == '83':
+                        print('ext detected')
+                        part_ext.append(part_id)
+                    else:
+                        pytest.fail('Unsupported Filesystem on device %d' % i)
+            devices[i]['ext4'] = part_ext
+            devices[i]['ext2'] = part_ext
+            devices[i]['fat'] = part_fat
+
+            if not part_ext and not part_fat:
+                pytest.fail('No partition detected on device %d' % i)
+
+    return devices, controllers, storage_device
+
+@pytest.mark.buildconfigspec('cmd_usb')
+@pytest.mark.buildconfigspec('cmd_fat')
+def test_usb_fatls_fatinfo(u_boot_console):
+    devices, controllers, storage_device = test_usb_part(u_boot_console)
+    if not devices:
+        pytest.skip('No devices detected')
+
+    part_detect = 0
+    fs = 'fat'
+    for x in range(0, int(storage_device)):
+        if devices[x]['detected'] == 'yes':
+            u_boot_console.run_command('usb dev %d' % x)
+            try:
+                partitions = devices[x][fs]
+            except:
+                print('No %s table on this device' % fs.upper())
+                continue
+
+            for part in partitions:
+                output = u_boot_console.run_command('fatls usb %d:%s' % (x, part))
+                if 'Unrecognized filesystem type' in output:
+                    partitions.remove(part)
+                    pytest.fail('Unrecognized filesystem')
+
+                if not re.search(r'\d file\(s\), \d dir\(s\)', output):
+                    pytest.fail('%s read failed on device %d' % (fs.upper, x))
+
+                output = u_boot_console.run_command('fatinfo usb %d:%s' % (x, part))
+                string = 'Filesystem: %s' % fs.upper
+                if re.search(string, output):
+                    pytest.fail('%s FS failed on device %d' % (fs.upper(), x))
+                part_detect = 1
+
+    if not part_detect:
+        pytest.skip('No %s partition detected' % fs.upper())
+
+@pytest.mark.buildconfigspec('cmd_usb')
+@pytest.mark.buildconfigspec('cmd_fat')
+@pytest.mark.buildconfigspec('cmd_memory')
+def test_usb_fatload_fatwrite(u_boot_console):
+    devices, controllers, storage_device = test_usb_part(u_boot_console)
+    if not devices:
+        pytest.skip('No devices detected')
+
+    part_detect = 0
+    fs = 'fat'
+    for x in range(0, int(storage_device)):
+        if devices[x]['detected'] == 'yes':
+            u_boot_console.run_command('usb dev %d' % x)
+            try:
+                partitions = devices[x][fs]
+            except:
+                print('No %s table on this device' % fs.upper())
+                continue
+
+            for part in partitions:
+                part_detect = 1
+                addr = u_boot_utils.find_ram_base(u_boot_console)
+                size = random.randint(4, 1 * 1024 * 1024)
+                output = u_boot_console.run_command('crc32 %x %x' % (addr, size))
+                m = re.search('==> (.+?)', output)
+                if not m:
+                    pytest.fail('CRC32 failed')
+                expected_crc32 = m.group(1)
+
+                file = '%s_%d' % ('uboot_test', size)
+                output = u_boot_console.run_command(
+                    '%swrite usb %d:%s %x %s %x' % (fs, x, part, addr, file, size)
+                )
+                assert 'Unable to write' not in output
+                assert 'Error' not in output
+                assert 'overflow' not in output
+                expected_text = '%d bytes written' % size
+                assert expected_text in output
+
+                alignment = int(
+                    u_boot_console.config.buildconfig.get(
+                        'config_sys_cacheline_size', 128
+                    )
+                )
+                offset = random.randrange(alignment, 1024, alignment)
+                output = u_boot_console.run_command(
+                    '%sload usb %d:%s %x %s' % (fs, x, part, addr + offset, file)
+                )
+                assert 'Invalid FAT entry' not in output
+                assert 'Unable to read file' not in output
+                assert 'Misaligned buffer address' not in output
+                expected_text = '%d bytes read' % size
+                assert expected_text in output
+
+                output = u_boot_console.run_command(
+                    'crc32 %x $filesize' % (addr + offset)
+                )
+                assert expected_crc32 in output
+
+    if not part_detect:
+        pytest.skip('No %s partition detected' % fs.upper())
+
+    return file, size
+
+@pytest.mark.buildconfigspec('cmd_usb')
+@pytest.mark.buildconfigspec('cmd_ext4')
+def test_usb_ext4ls(u_boot_console):
+    devices, controllers, storage_device = test_usb_part(u_boot_console)
+    if not devices:
+        pytest.skip('No devices detected')
+
+    part_detect = 0
+    fs = 'ext4'
+    for x in range(0, int(storage_device)):
+        if devices[x]['detected'] == 'yes':
+            try:
+                partitions = devices[x][fs]
+            except:
+                print('No %s table on this device' % fs.upper())
+                continue
+
+            u_boot_console.run_command('usb dev %d' % x)
+            for part in partitions:
+                output = u_boot_console.run_command('%sls usb %d:%s' % (fs, x, part))
+                if 'Unrecognized filesystem type' in output:
+                    partitions.remove(part)
+                    pytest.fail('Unrecognized filesystem')
+                part_detect = 1
+
+    if not part_detect:
+        pytest.skip('No %s partition detected' % fs.upper())
+
+@pytest.mark.buildconfigspec('cmd_usb')
+@pytest.mark.buildconfigspec('cmd_ext4')
+@pytest.mark.buildconfigspec('ext4_write')
+@pytest.mark.buildconfigspec('cmd_memory')
+def test_usb_ext4load_ext4write(u_boot_console):
+    devices, controllers, storage_device = test_usb_part(u_boot_console)
+    if not devices:
+        pytest.skip('No devices detected')
+
+    part_detect = 0
+    fs = 'ext4'
+    for x in range(0, int(storage_device)):
+        if devices[x]['detected'] == 'yes':
+            u_boot_console.run_command('usb dev %d' % x)
+            try:
+                partitions = devices[x][fs]
+            except:
+                print('No %s table on this device' % fs.upper())
+                continue
+
+            for part in partitions:
+                part_detect = 1
+                addr = u_boot_utils.find_ram_base(u_boot_console)
+                size = random.randint(4, 1 * 1024 * 1024)
+                output = u_boot_console.run_command('crc32 %x %x' % (addr, size))
+                m = re.search('==> (.+?)', output)
+                if not m:
+                    pytest.fail('CRC32 failed')
+                expected_crc32 = m.group(1)
+                file = '%s_%d' % ('uboot_test', size)
+
+                output = u_boot_console.run_command(
+                    '%swrite usb %d:%s %x /%s %x' % (fs, x, part, addr, file, size)
+                )
+                assert 'Unable to write' not in output
+                assert 'Error' not in output
+                assert 'overflow' not in output
+                expected_text = '%d bytes written' % size
+                assert expected_text in output
+
+                offset = random.randrange(128, 1024, 128)
+                output = u_boot_console.run_command(
+                    '%sload usb %d:%s %x /%s' % (fs, x, part, addr + offset, file)
+                )
+                expected_text = '%d bytes read' % size
+                assert expected_text in output
+
+                output = u_boot_console.run_command(
+                    'crc32 %x $filesize' % (addr + offset)
+                )
+                assert expected_crc32 in output
+
+    if not part_detect:
+        pytest.skip('No %s partition detected' % fs.upper())
+
+    return file, size
+
+@pytest.mark.buildconfigspec('cmd_usb')
+@pytest.mark.buildconfigspec('cmd_ext2')
+def test_usb_ext2ls(u_boot_console):
+    devices, controllers, storage_device = test_usb_part(u_boot_console)
+    if not devices:
+        pytest.skip('No devices detected')
+
+    part_detect = 0
+    fs = 'ext2'
+    for x in range(0, int(storage_device)):
+        if devices[x]['detected'] == 'yes':
+            u_boot_console.run_command('usb dev %d' % x)
+            try:
+                partitions = devices[x][fs]
+            except:
+                print('No %s table on this device' % fs.upper())
+                continue
+
+            for part in partitions:
+                part_detect = 1
+                output = u_boot_console.run_command('%sls usb %d:%s' % (fs, x, part))
+                if 'Unrecognized filesystem type' in output:
+                    partitions.remove(part)
+                    pytest.fail('Unrecognized filesystem')
+                part_detect = 1
+
+    if not part_detect:
+        pytest.skip('No %s partition detected' % fs.upper())
+
+@pytest.mark.buildconfigspec('cmd_usb')
+@pytest.mark.buildconfigspec('cmd_ext2')
+@pytest.mark.buildconfigspec('cmd_ext4')
+@pytest.mark.buildconfigspec('ext4_write')
+@pytest.mark.buildconfigspec('cmd_memory')
+def test_usb_ext2load(u_boot_console):
+    devices, controllers, storage_device = test_usb_part(u_boot_console)
+    file, size = test_usb_ext4load_ext4write(u_boot_console)
+
+    if not devices:
+        pytest.skip('No devices detected')
+
+    part_detect = 0
+    fs = 'ext2'
+    for x in range(0, int(storage_device)):
+        if devices[x]['detected'] == 'yes':
+            u_boot_console.run_command('usb dev %d' % x)
+            try:
+                partitions = devices[x][fs]
+            except:
+                print('No %s table on this device' % fs.upper())
+                continue
+
+            for part in partitions:
+                part_detect = 1
+                addr = u_boot_utils.find_ram_base(u_boot_console)
+                output = u_boot_console.run_command('crc32 %x %x' % (addr, size))
+                m = re.search('==> (.+?)', output)
+                if not m:
+                    pytest.fail('CRC32 failed')
+                expected_crc32 = m.group(1)
+
+                offset = random.randrange(128, 1024, 128)
+                output = u_boot_console.run_command(
+                    '%sload usb %d:%s %x /%s' % (fs, x, part, addr + offset, file)
+                )
+                expected_text = '%d bytes read' % size
+                assert expected_text in output
+
+                output = u_boot_console.run_command(
+                    'crc32 %x $filesize' % (addr + offset)
+                )
+                assert expected_crc32 in output
+
+    if not part_detect:
+        pytest.skip('No %s partition detected' % fs.upper())
+
+@pytest.mark.buildconfigspec('cmd_usb')
+@pytest.mark.buildconfigspec('cmd_fs_generic')
+def test_usb_ls(u_boot_console):
+    devices, controllers, storage_device = test_usb_part(u_boot_console)
+    if not devices:
+        pytest.skip('No devices detected')
+
+    part_detect = 0
+    for x in range(0, int(storage_device)):
+        if devices[x]['detected'] == 'yes':
+            u_boot_console.run_command('usb dev %d' % x)
+            for fs in ['fat', 'ext4']:
+                try:
+                    partitions = devices[x][fs]
+                except:
+                    print('No %s table on this device' % fs.upper())
+                    continue
+
+                for part in partitions:
+                    part_detect = 1
+                    output = u_boot_console.run_command('ls usb %d:%s' % (x, part))
+                    if re.search(r'No \w+ table on this device', output):
+                        pytest.fail(
+                            '%s: Partition table not found %d' % (fs.upper(), x)
+                        )
+
+    if not part_detect:
+        pytest.skip('No partition detected')
+
+@pytest.mark.buildconfigspec('cmd_usb')
+@pytest.mark.buildconfigspec('cmd_fs_generic')
+def test_usb_load(u_boot_console):
+    devices, controllers, storage_device = test_usb_part(u_boot_console)
+    if not devices:
+        pytest.skip('No devices detected')
+
+    part_detect = 0
+    for x in range(0, int(storage_device)):
+        if devices[x]['detected'] == 'yes':
+            u_boot_console.run_command('usb dev %d' % x)
+            for fs in ['fat', 'ext4']:
+                try:
+                    partitions = devices[x][fs]
+                except:
+                    print('No %s table on this device' % fs.upper())
+                    continue
+
+                for part in partitions:
+                    part_detect = 1
+                    addr = u_boot_utils.find_ram_base(u_boot_console)
+
+                    if fs == 'fat':
+                        file, size = test_usb_fatload_fatwrite(u_boot_console)
+                    elif fs == 'ext4':
+                        file, size = test_usb_ext4load_ext4write(u_boot_console)
+
+                    output = u_boot_console.run_command('crc32 %x %x' % (addr, size))
+                    m = re.search('==> (.+?)', output)
+                    if not m:
+                        pytest.fail('CRC32 failed')
+                    expected_crc32 = m.group(1)
+
+                    offset = random.randrange(128, 1024, 128)
+                    output = u_boot_console.run_command(
+                        'load usb %d:%s %x /%s' % (x, part, addr + offset, file)
+                    )
+                    expected_text = '%d bytes read' % size
+                    assert expected_text in output
+
+                    output = u_boot_console.run_command(
+                        'crc32 %x $filesize' % (addr + offset)
+                    )
+                    assert expected_crc32 in output
+
+    if not part_detect:
+        pytest.skip('No partition detected')
+
+@pytest.mark.buildconfigspec('cmd_usb')
+@pytest.mark.buildconfigspec('cmd_fs_generic')
+def test_usb_save(u_boot_console):
+    devices, controllers, storage_device = test_usb_part(u_boot_console)
+    if not devices:
+        pytest.skip('No devices detected')
+
+    part_detect = 0
+    for x in range(0, int(storage_device)):
+        if devices[x]['detected'] == 'yes':
+            u_boot_console.run_command('usb dev %d' % x)
+            for fs in ['fat', 'ext4']:
+                try:
+                    partitions = devices[x][fs]
+                except:
+                    print('No %s table on this device' % fs.upper())
+                    continue
+
+                for part in partitions:
+                    part_detect = 1
+                    addr = u_boot_utils.find_ram_base(u_boot_console)
+                    size = random.randint(4, 1 * 1024 * 1024)
+                    file = '%s_%d' % ('uboot_test', size)
+
+                    offset = random.randrange(128, 1024, 128)
+                    output = u_boot_console.run_command(
+                        'save usb %d:%s %x /%s %x'
+                        % (x, part, addr + offset, file, size)
+                    )
+                    expected_text = '%d bytes written' % size
+                    assert expected_text in output
+
+    if not part_detect:
+        pytest.skip('No partition detected')
diff --git a/test/py/tests/test_zynq_secure.py b/test/py/tests/test_zynq_secure.py
new file mode 100644
index 0000000..0ee5aeb
--- /dev/null
+++ b/test/py/tests/test_zynq_secure.py
@@ -0,0 +1,190 @@
+# SPDX-License-Identifier: GPL-2.0
+# (C) Copyright 2023, Advanced Micro Devices, Inc.
+
+import pytest
+import re
+import u_boot_utils
+import test_net
+
+"""
+This test verifies different type of secure boot images to authentication and
+decryption using AES and RSA features for AMD's Zynq SoC.
+
+Note: This test relies on boardenv_* containing configuration values to define
+the network available and files to be used for testing. Without this, this test
+will be automatically skipped. It also relies on dhcp or setup_static net test
+to support tftp to load files from a TFTP server.
+
+For example:
+
+# Details regarding the files that may be read from a TFTP server and addresses
+# and size for aes and rsa cases respectively. This variable may be omitted or
+# set to None if zynqmp secure testing is not possible or desired.
+env__zynq_aes_readable_file = {
+    'fn': 'zynq_aes_image.bin',
+    'fnbit': 'zynq_aes_bit.bin',
+    'fnpbit': 'zynq_aes_par_bit.bin',
+    'srcaddr': 0x1000000,
+    'dstaddr': 0x2000000,
+    'dstlen': 0x1000000,
+}
+
+env__zynq_rsa_readable_file = {
+    'fn': 'zynq_rsa_image.bin',
+    'fninvalid': 'zynq_rsa_image_invalid.bin',
+    'srcaddr': 0x1000000,
+}
+"""
+
+def zynq_secure_pre_commands(u_boot_console):
+    output = u_boot_console.run_command('print modeboot')
+    if not 'modeboot=' in output:
+        pytest.skip('bootmode cannnot be determined')
+    m = re.search('modeboot=(.+?)boot', output)
+    if not m:
+        pytest.skip('bootmode cannnot be determined')
+    bootmode = m.group(1)
+    if bootmode == 'jtag':
+        pytest.skip('skipping due to jtag bootmode')
+
+@pytest.mark.buildconfigspec('cmd_zynq_aes')
+def test_zynq_aes_image(u_boot_console):
+    f = u_boot_console.config.env.get('env__zynq_aes_readable_file', None)
+    if not f:
+        pytest.skip('No TFTP readable file for zynq secure aes case to read')
+
+    dstaddr = f.get('dstaddr', None)
+    if not dstaddr:
+        pytest.skip('No dstaddr specified in env file to read')
+
+    dstsize = f.get('dstlen', None)
+    if not dstsize:
+        pytest.skip('No dstlen specified in env file to read')
+
+    zynq_secure_pre_commands(u_boot_console)
+    test_net.test_net_dhcp(u_boot_console)
+    if not test_net.net_set_up:
+        test_net.test_net_setup_static(u_boot_console)
+
+    srcaddr = f.get('srcaddr', None)
+    if not srcaddr:
+        addr = u_boot_utils.find_ram_base(u_boot_console)
+
+    expected_tftp = 'Bytes transferred = '
+    fn = f['fn']
+    output = u_boot_console.run_command('tftpboot %x %s' % (srcaddr, fn))
+    assert expected_tftp in output
+
+    expected_op = 'zynq aes [operation type] <srcaddr>'
+    output = u_boot_console.run_command(
+        'zynq aes %x $filesize %x %x' % (srcaddr, dstaddr, dstsize)
+    )
+    assert expected_op not in output
+    output = u_boot_console.run_command('echo $?')
+    assert output.endswith('0')
+
+@pytest.mark.buildconfigspec('cmd_zynq_aes')
+def test_zynq_aes_bitstream(u_boot_console):
+    f = u_boot_console.config.env.get('env__zynq_aes_readable_file', None)
+    if not f:
+        pytest.skip('No TFTP readable file for zynq secure aes case to read')
+
+    zynq_secure_pre_commands(u_boot_console)
+    test_net.test_net_dhcp(u_boot_console)
+    if not test_net.net_set_up:
+        test_net.test_net_setup_static(u_boot_console)
+
+    srcaddr = f.get('srcaddr', None)
+    if not srcaddr:
+        addr = u_boot_utils.find_ram_base(u_boot_console)
+
+    expected_tftp = 'Bytes transferred = '
+    fn = f['fnbit']
+    output = u_boot_console.run_command('tftpboot %x %s' % (srcaddr, fn))
+    assert expected_tftp in output
+
+    expected_op = 'zynq aes [operation type] <srcaddr>'
+    output = u_boot_console.run_command(
+        'zynq aes load %x $filesize' % (srcaddr)
+    )
+    assert expected_op not in output
+    output = u_boot_console.run_command('echo $?')
+    assert output.endswith('0')
+
+@pytest.mark.buildconfigspec('cmd_zynq_aes')
+def test_zynq_aes_partial_bitstream(u_boot_console):
+    f = u_boot_console.config.env.get('env__zynq_aes_readable_file', None)
+    if not f:
+        pytest.skip('No TFTP readable file for zynq secure aes case to read')
+
+    zynq_secure_pre_commands(u_boot_console)
+    test_net.test_net_dhcp(u_boot_console)
+    if not test_net.net_set_up:
+        test_net.test_net_setup_static(u_boot_console)
+
+    srcaddr = f.get('srcaddr', None)
+    if not srcaddr:
+        addr = u_boot_utils.find_ram_base(u_boot_console)
+
+    expected_tftp = 'Bytes transferred = '
+    fn = f['fnpbit']
+    output = u_boot_console.run_command('tftpboot %x %s' % (srcaddr, fn))
+    assert expected_tftp in output
+
+    expected_op = 'zynq aes [operation type] <srcaddr>'
+    output = u_boot_console.run_command('zynq aes loadp %x $filesize' % (srcaddr))
+    assert expected_op not in output
+    output = u_boot_console.run_command('echo $?')
+    assert output.endswith('0')
+
+@pytest.mark.buildconfigspec('cmd_zynq_rsa')
+def test_zynq_rsa_image(u_boot_console):
+    f = u_boot_console.config.env.get('env__zynq_rsa_readable_file', None)
+    if not f:
+        pytest.skip('No TFTP readable file for zynq secure rsa case to read')
+
+    zynq_secure_pre_commands(u_boot_console)
+    test_net.test_net_dhcp(u_boot_console)
+    if not test_net.net_set_up:
+        test_net.test_net_setup_static(u_boot_console)
+
+    srcaddr = f.get('srcaddr', None)
+    if not srcaddr:
+        addr = u_boot_utils.find_ram_base(u_boot_console)
+
+    expected_tftp = 'Bytes transferred = '
+    fn = f['fn']
+    output = u_boot_console.run_command('tftpboot %x %s' % (srcaddr, fn))
+    assert expected_tftp in output
+
+    expected_op = 'zynq rsa <baseaddr>'
+    output = u_boot_console.run_command('zynq rsa %x ' % (srcaddr))
+    assert expected_op not in output
+    output = u_boot_console.run_command('echo $?')
+    assert output.endswith('0')
+
+@pytest.mark.buildconfigspec('cmd_zynq_rsa')
+def test_zynq_rsa_image_invalid(u_boot_console):
+    f = u_boot_console.config.env.get('env__zynq_rsa_readable_file', None)
+    if not f:
+        pytest.skip('No TFTP readable file for zynq secure rsa case to read')
+
+    zynq_secure_pre_commands(u_boot_console)
+    test_net.test_net_dhcp(u_boot_console)
+    if not test_net.net_set_up:
+        test_net.test_net_setup_static(u_boot_console)
+
+    srcaddr = f.get('srcaddr', None)
+    if not srcaddr:
+        addr = u_boot_utils.find_ram_base(u_boot_console)
+
+    expected_tftp = 'Bytes transferred = '
+    fninvalid = f['fninvalid']
+    output = u_boot_console.run_command('tftpboot %x %s' % (srcaddr, fninvalid))
+    assert expected_tftp in output
+
+    expected_op = 'zynq rsa <baseaddr>'
+    output = u_boot_console.run_command('zynq rsa %x ' % (srcaddr))
+    assert expected_op in output
+    output = u_boot_console.run_command('echo $?')
+    assert not output.endswith('0')
diff --git a/test/py/tests/test_zynqmp_rpu.py b/test/py/tests/test_zynqmp_rpu.py
new file mode 100644
index 0000000..479a612
--- /dev/null
+++ b/test/py/tests/test_zynqmp_rpu.py
@@ -0,0 +1,208 @@
+# SPDX-License-Identifier: GPL-2.0
+# (C) Copyright 2023, Advanced Micro Devices, Inc.
+
+import pytest
+import random
+import string
+import test_net
+
+"""
+Note: This test relies on boardenv_* containing configuration values to define
+RPU applications information for AMD's ZynqMP SoC which contains, application
+names, processors, address where it is built, expected output and the tftp load
+addresses. This test will be automatically skipped without this.
+
+It also relies on dhcp or setup_static net test to support tftp to load
+application on DDR. All the environment parameters are stored sequentially.
+The length of all parameters values should be same. For example, if 2 app_names
+are defined in a list as a value of parameter 'app_name' then the other
+parameters value also should have a list with 2 items.
+It will run RPU cases for all the applications defined in boardenv_*
+configuration file.
+
+Example:
+env__zynqmp_rpu_apps = {
+    'app_name': ['hello_world_r5_0_ddr.elf', 'hello_world_r5_1_ddr.elf'],
+    'proc': ['rpu0', 'rpu1'],
+    'cpu_num': [4, 5],
+    'addr': [0xA00000, 0xB00000],
+    'output': ['Successfully ran Hello World application on DDR from RPU0',
+               'Successfully ran Hello World application on DDR from RPU1'],
+    'tftp_addr': [0x100000, 0x200000],
+}
+"""
+
+# Get rpu apps params from env
+def get_rpu_apps_env(u_boot_console):
+    rpu_apps = u_boot_console.config.env.get('env__zynqmp_rpu_apps', False)
+    if not rpu_apps:
+        pytest.skip('ZynqMP RPU application info not defined!')
+
+    apps = rpu_apps.get('app_name', None)
+    if not apps:
+        pytest.skip('No RPU application found!')
+
+    procs = rpu_apps.get('proc', None)
+    if not procs:
+        pytest.skip('No RPU application processor provided!')
+
+    cpu_nums = rpu_apps.get('cpu_num', None)
+    if not cpu_nums:
+        pytest.skip('No CPU number for respective processor provided!')
+
+    addrs = rpu_apps.get('addr', None)
+    if not addrs:
+        pytest.skip('No RPU application build address found!')
+
+    outputs = rpu_apps.get('output', None)
+    if not outputs:
+        pytest.skip('Expected output not found!')
+
+    tftp_addrs = rpu_apps.get('tftp_addr', None)
+    if not tftp_addrs:
+        pytest.skip('TFTP address to load application not found!')
+
+    return apps, procs, cpu_nums, addrs, outputs, tftp_addrs
+
+# Check return code
+def ret_code(u_boot_console):
+    return u_boot_console.run_command('echo $?')
+
+# Initialize tcm
+def tcminit(u_boot_console, rpu_mode):
+    output = u_boot_console.run_command('zynqmp tcminit %s' % rpu_mode)
+    assert 'Initializing TCM overwrites TCM content' in output
+    return ret_code(u_boot_console)
+
+# Load application in DDR
+def load_app_ddr(u_boot_console, tftp_addr, app):
+    output = u_boot_console.run_command('tftpboot %x %s' % (tftp_addr, app))
+    assert 'TIMEOUT' not in output
+    assert 'Bytes transferred = ' in output
+
+    # Load elf
+    u_boot_console.run_command('bootelf -p %x' % tftp_addr)
+    assert ret_code(u_boot_console).endswith('0')
+
+# Disable cpus
+def disable_cpus(u_boot_console, cpu_nums):
+    for num in cpu_nums:
+        u_boot_console.run_command(f'cpu {num} disable')
+
+# Load apps on RPU cores
+def rpu_apps_load(u_boot_console, rpu_mode):
+    apps, procs, cpu_nums, addrs, outputs, tftp_addrs = get_rpu_apps_env(
+        u_boot_console)
+    test_net.test_net_dhcp(u_boot_console)
+    if not test_net.net_set_up:
+        test_net.test_net_setup_static(u_boot_console)
+
+    try:
+        assert tcminit(u_boot_console, rpu_mode).endswith('0')
+
+        for i in range(len(apps)):
+            if rpu_mode == 'lockstep' and procs[i] != 'rpu0':
+                continue
+
+            load_app_ddr(u_boot_console, tftp_addrs[i], apps[i])
+            rel_addr = int(addrs[i] + 0x3C)
+
+            # Release cpu at app load address
+            cpu_num = cpu_nums[i]
+            cmd = 'cpu %d release %x %s' % (cpu_num, rel_addr, rpu_mode)
+            output = u_boot_console.run_command(cmd)
+            exp_op = f'Using TCM jump trampoline for address {hex(rel_addr)}'
+            assert exp_op in output
+            assert f'R5 {rpu_mode} mode' in output
+            u_boot_console.wait_for(outputs[i])
+            assert ret_code(u_boot_console).endswith('0')
+    finally:
+        disable_cpus(u_boot_console, cpu_nums)
+
+@pytest.mark.buildconfigspec('cmd_zynqmp')
+def test_zynqmp_rpu_app_load_split(u_boot_console):
+    rpu_apps_load(u_boot_console, 'split')
+
+@pytest.mark.buildconfigspec('cmd_zynqmp')
+def test_zynqmp_rpu_app_load_lockstep(u_boot_console):
+    rpu_apps_load(u_boot_console, 'lockstep')
+
+@pytest.mark.buildconfigspec('cmd_zynqmp')
+def test_zynqmp_rpu_app_load_negative(u_boot_console):
+    apps, procs, cpu_nums, addrs, outputs, tftp_addrs = get_rpu_apps_env(
+        u_boot_console)
+
+    # Invalid commands
+    u_boot_console.run_command('zynqmp tcminit mode')
+    assert ret_code(u_boot_console).endswith('1')
+
+    rand_str = ''.join(random.choices(string.ascii_lowercase, k=4))
+    u_boot_console.run_command('zynqmp tcminit %s' % rand_str)
+    assert ret_code(u_boot_console).endswith('1')
+
+    rand_num = random.randint(2, 100)
+    u_boot_console.run_command('zynqmp tcminit %d' % rand_num)
+    assert ret_code(u_boot_console).endswith('1')
+
+    test_net.test_net_dhcp(u_boot_console)
+    if not test_net.net_set_up:
+        test_net.test_net_setup_static(u_boot_console)
+
+    try:
+        rpu_mode = 'split'
+        assert tcminit(u_boot_console, rpu_mode).endswith('0')
+
+        for i in range(len(apps)):
+            load_app_ddr(u_boot_console, tftp_addrs[i], apps[i])
+
+            # Run in split mode at different load address
+            rel_addr = int(addrs[i]) + random.randint(200, 1000)
+            cpu_num = cpu_nums[i]
+            cmd = 'cpu %d release %x %s' % (cpu_num, rel_addr, rpu_mode)
+            output = u_boot_console.run_command(cmd)
+            exp_op = f'Using TCM jump trampoline for address {hex(rel_addr)}'
+            assert exp_op in output
+            assert f'R5 {rpu_mode} mode' in output
+            assert not outputs[i] in output
+
+            # Invalid rpu mode
+            rand_str = ''.join(random.choices(string.ascii_lowercase, k=4))
+            cmd = 'cpu %d release %x %s' % (cpu_num, rel_addr, rand_str)
+            output = u_boot_console.run_command(cmd)
+            assert exp_op in output
+            assert f'Unsupported mode' in output
+            assert not ret_code(u_boot_console).endswith('0')
+
+        # Switch to lockstep mode, without disabling CPUs
+        rpu_mode = 'lockstep'
+        u_boot_console.run_command('zynqmp tcminit %s' % rpu_mode)
+        assert not ret_code(u_boot_console).endswith('0')
+
+        # Disable cpus
+        disable_cpus(u_boot_console, cpu_nums)
+
+        # Switch to lockstep mode, after disabling CPUs
+        output = u_boot_console.run_command('zynqmp tcminit %s' % rpu_mode)
+        assert 'Initializing TCM overwrites TCM content' in output
+        assert ret_code(u_boot_console).endswith('0')
+
+        # Run lockstep mode for RPU1
+        for i in range(len(apps)):
+            if procs[i] == 'rpu0':
+                continue
+
+            load_app_ddr(u_boot_console, tftp_addrs[i], apps[i])
+            rel_addr = int(addrs[i] + 0x3C)
+            cpu_num = cpu_nums[i]
+            cmd = 'cpu %d release %x %s' % (cpu_num, rel_addr, rpu_mode)
+            output = u_boot_console.run_command(cmd)
+            exp_op = f'Using TCM jump trampoline for address {hex(rel_addr)}'
+            assert exp_op in output
+            assert f'R5 {rpu_mode} mode' in output
+            assert u_boot_console.p.expect([outputs[i]])
+    finally:
+        disable_cpus(u_boot_console, cpu_nums)
+        # This forces the console object to be shutdown, so any subsequent test
+        # will reset the board back into U-Boot.
+        u_boot_console.drain_console()
+        u_boot_console.cleanup_spawn()
diff --git a/test/py/tests/test_zynqmp_secure.py b/test/py/tests/test_zynqmp_secure.py
new file mode 100644
index 0000000..570bd24
--- /dev/null
+++ b/test/py/tests/test_zynqmp_secure.py
@@ -0,0 +1,104 @@
+# SPDX-License-Identifier: GPL-2.0
+# (C) Copyright 2023, Advanced Micro Devices, Inc.
+
+import pytest
+import re
+import u_boot_utils
+import test_net
+
+"""
+This test verifies different type of secure boot images loaded at the DDR for
+AMD's ZynqMP SoC.
+
+Note: This test relies on boardenv_* containing configuration values to define
+the files to be used for testing. Without this, this test will be automatically
+skipped. It also relies on dhcp or setup_static net test to support tftp to
+load files from a TFTP server.
+
+For example:
+
+# Details regarding the files that may be read from a TFTP server. This
+# variable may be omitted or set to None if zynqmp secure testing is not
+# possible or desired.
+env__zynqmp_secure_readable_file = {
+    'fn': 'auth_bhdr_ppk1.bin',
+    'enckupfn': 'auth_bhdr_enc_kup_load.bin',
+    'addr': 0x1000000,
+    'keyaddr': 0x100000,
+    'keyfn': 'aes.txt',
+}
+"""
+
+@pytest.mark.buildconfigspec('cmd_zynqmp')
+def test_zynqmp_secure_boot_image(u_boot_console):
+    """This test verifies secure boot image at the DDR address for
+    authentication only case.
+    """
+
+    f = u_boot_console.config.env.get('env__zynqmp_secure_readable_file', None)
+    if not f:
+        pytest.skip('No TFTP readable file for zynqmp secure cases to read')
+
+    test_net.test_net_dhcp(u_boot_console)
+    if not test_net.net_set_up:
+        test_net.test_net_setup_static(u_boot_console)
+
+    addr = f.get('addr', None)
+    if not addr:
+        addr = u_boot_utils.find_ram_base(u_boot_console)
+
+    expected_tftp = 'Bytes transferred = '
+    fn = f['fn']
+    output = u_boot_console.run_command('tftpboot %x %s' % (addr, fn))
+    assert expected_tftp in output
+
+    output = u_boot_console.run_command('zynqmp secure %x $filesize' % (addr))
+    assert 'Verified image at' in output
+    ver_addr = re.search(r'Verified image at 0x(.+)', output).group(1)
+    output = u_boot_console.run_command('echo $?')
+    assert output.endswith('0')
+    output = u_boot_console.run_command('print zynqmp_verified_img_addr')
+    assert f'zynqmp_verified_img_addr={ver_addr}' in output
+    assert 'Error' not in output
+
+
+@pytest.mark.buildconfigspec('cmd_zynqmp')
+def test_zynqmp_secure_boot_img_kup(u_boot_console):
+    """This test verifies secure boot image at the DDR address for encryption
+    with kup key case.
+    """
+
+    f = u_boot_console.config.env.get('env__zynqmp_secure_readable_file', None)
+    if not f:
+        pytest.skip('No TFTP readable file for zynqmp secure cases to read')
+
+    test_net.test_net_dhcp(u_boot_console)
+    if not test_net.net_set_up:
+        test_net.test_net_setup_static(u_boot_console)
+
+    keyaddr = f.get('keyaddr', None)
+    if not keyaddr:
+        addr = u_boot_utils.find_ram_base(u_boot_console)
+    expected_tftp = 'Bytes transferred = '
+    keyfn = f['keyfn']
+    output = u_boot_console.run_command('tftpboot %x %s' % (keyaddr, keyfn))
+    assert expected_tftp in output
+
+    addr = f.get('addr', None)
+    if not addr:
+        addr = u_boot_utils.find_ram_base(u_boot_console)
+    expected_tftp = 'Bytes transferred = '
+    fn = f['enckupfn']
+    output = u_boot_console.run_command('tftpboot %x %s' % (addr, fn))
+    assert expected_tftp in output
+
+    output = u_boot_console.run_command(
+        'zynqmp secure %x $filesize %x' % (addr, keyaddr)
+    )
+    assert 'Verified image at' in output
+    ver_addr = re.search(r'Verified image at 0x(.+)', output).group(1)
+    output = u_boot_console.run_command('echo $?')
+    assert output.endswith('0')
+    output = u_boot_console.run_command('print zynqmp_verified_img_addr')
+    assert f'zynqmp_verified_img_addr={ver_addr}' in output
+    assert 'Error' not in output
diff --git a/test/unicode_ut.c b/test/unicode_ut.c
index 1d0d90c..47c3f52 100644
--- a/test/unicode_ut.c
+++ b/test/unicode_ut.c
@@ -752,9 +752,10 @@
 
 	const u32 u1[] = {0x55, 0x2D, 0x42, 0x6F, 0x6F, 0x74, 0x0000};
 	const u32 u2[] = {0x6B, 0x61, 0x66, 0x62, 0xE1, 0x74, 0x75, 0x72, 0x00};
-	const u32 u3[] = {0x0392, 0x20, 0x69, 0x73, 0x20, 0x6E, 0x6F, 0x74,
-			  0x20, 0x42, 0x00};
+	const u32 u3[] = {0x6f5c, 0x6c34, 0x8266};
 	const u32 u4[] = {0x6A, 0x32, 0x6C, 0x00};
+	const u32 u5[] = {0x0392, 0x20, 0x69, 0x73, 0x20, 0x6E, 0x6F, 0x74,
+			  0x20, 0x42, 0x00};
 
 	memset(buf, 0, sizeof(buf));
 	utf8_to_utf32_stream_helper(d1, buf);
@@ -765,10 +766,14 @@
 	ut_asserteq_mem(u2, buf, sizeof(u2));
 
 	memset(buf, 0, sizeof(buf));
-	utf8_to_utf32_stream_helper(d5, buf);
+	utf8_to_utf32_stream_helper(d3, buf);
 	ut_asserteq_mem(u3, buf, sizeof(u3));
 
 	memset(buf, 0, sizeof(buf));
+	utf8_to_utf32_stream_helper(d5, buf);
+	ut_asserteq_mem(u5, buf, sizeof(u5));
+
+	memset(buf, 0, sizeof(buf));
 	utf8_to_utf32_stream_helper(j2, buf);
 	ut_asserteq_mem(u4, buf, sizeof(u4));
 
diff --git a/tools/buildman/bsettings.py b/tools/buildman/bsettings.py
index f7f8276..e225ac2 100644
--- a/tools/buildman/bsettings.py
+++ b/tools/buildman/bsettings.py
@@ -16,7 +16,7 @@
     global settings
     global config_fname
 
-    settings = configparser.SafeConfigParser()
+    settings = configparser.ConfigParser()
     if fname is not None:
         config_fname = fname
         if config_fname == '':
diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile
index 0e2dd0a..6122776 100644
--- a/tools/docker/Dockerfile
+++ b/tools/docker/Dockerfile
@@ -240,12 +240,14 @@
 # COPY / ADD directives don't work as we need them to.
 RUN wget -O /tmp/pytest-requirements.txt https://source.denx.de/u-boot/u-boot/-/raw/master/test/py/requirements.txt
 RUN wget -O /tmp/sphinx-requirements.txt https://source.denx.de/u-boot/u-boot/-/raw/master/doc/sphinx/requirements.txt
+RUN wget -O /tmp/buildman-requirements.txt https://source.denx.de/u-boot/u-boot/-/raw/master/tools/buildman/requirements.txt
 RUN virtualenv -p /usr/bin/python3 /tmp/venv && \
 	. /tmp/venv/bin/activate && \
 	pip install -r /tmp/pytest-requirements.txt \
-		-r /tmp/sphinx-requirements.txt && \
+		-r /tmp/sphinx-requirements.txt \
+		-r /tmp/buildman-requirements.txt && \
 	deactivate && \
-	rm -rf /tmp/venv /tmp/pytest-requirements.txt /tmp/sphinx-requirements.txt
+	rm -rf /tmp/venv /tmp/*-requirements.txt
 
 # Create the buildman config file
 RUN /bin/echo -e "[toolchain]\nroot = /usr" > ~/.buildman