Merge tag 'xilinx-for-v2023.01-rc1-v3' of https://source.denx.de/u-boot/custodians/u-boot-microblaze

Xilinx changes for v2023.01-rc1 (round 3)

fpga:
- Create new uclass
- Get rid of FPGA_DEBUG and use logging infrastructure

zynq:
- Enable early EEPROM decoding
- Some DT updates

zynqmp:
- Use OCM_BANK_0 to check config loading permission
- Change config object loading in SPL
- Some DT updates

net:
- emaclite: Enable driver for RISC-V

xilinx:
- Fix static checker warnings
- Fix GCC12 warning

sdhci:
- Read PD id from DT
diff --git a/.azure-pipelines.yml b/.azure-pipelines.yml
index d78a170..f200b40 100644
--- a/.azure-pipelines.yml
+++ b/.azure-pipelines.yml
@@ -2,7 +2,7 @@
   windows_vm: windows-2019
   ubuntu_vm: ubuntu-22.04
   macos_vm: macOS-12
-  ci_runner_image: trini/u-boot-gitlab-ci-runner:jammy-20220801-09Aug2022
+  ci_runner_image: trini/u-boot-gitlab-ci-runner:jammy-20221003-07Oct2022
   # Add '-u 0' options for Azure pipelines, otherwise we get "permission
   # denied" error when it tries to "useradd -m -u 1001 vsts_azpcontainer",
   # since our $(ci_runner_image) user is not root.
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 29af8c6..7052a60 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -2,7 +2,7 @@
 
 # Grab our configured image.  The source for this is found
 # in the u-boot tree at tools/docker/Dockerfile
-image: trini/u-boot-gitlab-ci-runner:jammy-20220801-09Aug2022
+image: trini/u-boot-gitlab-ci-runner:jammy-20221003-07Oct2022
 
 # We run some tests in different order, to catch some failures quicker.
 stages:
diff --git a/MAINTAINERS b/MAINTAINERS
index c4ed454..3377866 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -871,6 +871,7 @@
 F:	include/efi*
 F:	include/pe.h
 F:	include/asm-generic/pe.h
+F:	include/mm_communication.h
 F:	lib/charset.c
 F:	lib/efi*/
 F:	test/lib/efi_*
@@ -884,12 +885,6 @@
 F:	tools/file2include.c
 F:	tools/mkeficapsule.c
 
-EFI VARIABLES VIA OP-TEE
-M:	Ilias Apalodimas <ilias.apalodimas@linaro.org>
-S:	Maintained
-F:	lib/efi_loader/efi_variable_tee.c
-F:	include/mm_communication.h
-
 ENVIRONMENT
 M:	Joe Hershberger <joe.hershberger@ni.com>
 R:	Wolfgang Denk <wd@denx.de>
diff --git a/Makefile b/Makefile
index 45f1075..3866cc6 100644
--- a/Makefile
+++ b/Makefile
@@ -1023,7 +1023,7 @@
 LDFLAGS_u-boot += $(call ld-option, --no-dynamic-linker)
 
 # ld.lld support
-LDFLAGS_u-boot += -z notext
+LDFLAGS_u-boot += -z notext $(call ld-option,--apply-dynamic-relocs)
 
 LDFLAGS_u-boot += --build-id=none
 
diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c
index e4736e5..2a226fd 100644
--- a/arch/arm/cpu/armv8/cache_v8.c
+++ b/arch/arm/cpu/armv8/cache_v8.c
@@ -503,6 +503,10 @@
 		mmu_setup();
 	}
 
+	/* Set up page tables only once (it is done also by mmu_setup()) */
+	if (!gd->arch.tlb_fillptr)
+		setup_all_pgtables();
+
 	set_sctlr(get_sctlr() | CR_C);
 }
 
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 71e9bd4..9b00b64 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -58,7 +58,6 @@
 	kirkwood-ib62x0.dtb \
 	kirkwood-iconnect.dtb \
 	kirkwood-is2.dtb \
-	kirkwood-km_kirkwood.dtb \
 	kirkwood-lsxhl.dtb \
 	kirkwood-lschlv2.dtb \
 	kirkwood-net2big.dtb \
@@ -1253,6 +1252,7 @@
 	mt8518-ap1-emmc.dtb
 
 dtb-$(CONFIG_ARCH_NPCM7xx) += nuvoton-npcm750-evb.dtb
+dtb-$(CONFIG_ARCH_NPCM8XX) += nuvoton-npcm845-evb.dtb
 dtb-$(CONFIG_XEN) += xenguest-arm64.dtb
 
 dtb-$(CONFIG_ARCH_OCTEONTX) += octeontx.dtb
diff --git a/arch/arm/dts/kirkwood-km_common.dtsi b/arch/arm/dts/kirkwood-km_common.dtsi
deleted file mode 100644
index 9d0fc51..0000000
--- a/arch/arm/dts/kirkwood-km_common.dtsi
+++ /dev/null
@@ -1,48 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/ {
-	chosen {
-		bootargs = "console=ttyS0,115200n8 earlyprintk";
-		stdout-path = &uart0;
-	};
-
-	ocp@f1000000 {
-		pinctrl: pin-controller@10000 {
-			pinctrl-0 = < &pmx_i2c_gpio_sda &pmx_i2c_gpio_scl >;
-			pinctrl-names = "default";
-
-			pmx_i2c_gpio_sda: pmx-gpio-sda {
-				marvell,pins = "mpp8";
-				marvell,function = "gpio";
-			};
-			pmx_i2c_gpio_scl: pmx-gpio-scl {
-				marvell,pins = "mpp9";
-				marvell,function = "gpio";
-			};
-		};
-
-		serial@12000 {
-			status = "okay";
-			clock-frequency = <200000000>;
-		};
-	};
-
-	i2c {
-		compatible = "i2c-gpio";
-		gpios = < &gpio0 8 GPIO_ACTIVE_HIGH		/* sda */
-			  &gpio0 9 GPIO_ACTIVE_HIGH>;		/* scl */
-		i2c-gpio,delay-us = <2>;	/* ~100 kHz */
-	};
-};
-
-&nand {
-	status = "okay";
-	chip-delay = <25>;
-};
-
-&pciec {
-        status = "okay";
-};
-
-&pcie0 {
-	status = "okay";
-};
diff --git a/arch/arm/dts/kirkwood-km_kirkwood.dts b/arch/arm/dts/kirkwood-km_kirkwood.dts
deleted file mode 100644
index b2c0209..0000000
--- a/arch/arm/dts/kirkwood-km_kirkwood.dts
+++ /dev/null
@@ -1,53 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/dts-v1/;
-
-#include "kirkwood.dtsi"
-#include "kirkwood-98dx4122.dtsi"
-#include "kirkwood-km_common.dtsi"
-
-/ {
-	model = "Keymile Kirkwood Reference Design";
-	compatible = "keymile,km_kirkwood", "marvell,kirkwood-98DX4122", "marvell,kirkwood";
-
-	memory {
-		device_type = "memory";
-		reg = <0x00000000 0x08000000>;
-	};
-
-	aliases {
-		spi0 = &spi0;
-	};
-};
-
-&mdio {
-	status = "okay";
-
-	ethphy0: ethernet-phy@0 {
-		reg = <0>;
-	};
-};
-
-&eth0 {
-	status = "okay";
-	ethernet0-port@0 {
-		phy-handle = <&ethphy0>;
-	};
-};
-
-&spi0 {
-	status = "okay";
-
-	flash@0 {
-		#address-cells = <1>;
-		#size-cells = <1>;
-		compatible = "st,m25p80", "jedec,spi-nor", "spi-flash";
-		reg = <0>;
-		spi-max-frequency = <33000000>;
-		mode = <3>;
-
-		partition@uboot {
-			reg = <0x000000 0x0c0000>;
-			label = "uboot";
-		};
-	};
-};
diff --git a/arch/arm/dts/nuvoton-common-npcm8xx.dtsi b/arch/arm/dts/nuvoton-common-npcm8xx.dtsi
new file mode 100644
index 0000000..aa7aac8
--- /dev/null
+++ b/arch/arm/dts/nuvoton-common-npcm8xx.dtsi
@@ -0,0 +1,170 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2021 Nuvoton Technology tomer.maimon@nuvoton.com
+
+#include <dt-bindings/clock/nuvoton,npcm845-clk.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+	#address-cells = <2>;
+	#size-cells = <2>;
+	interrupt-parent = <&gic>;
+
+	soc {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		compatible = "simple-bus";
+		interrupt-parent = <&gic>;
+		ranges;
+
+		gcr: system-controller@f0800000 {
+			compatible = "nuvoton,npcm845-gcr", "syscon";
+			reg = <0x0 0xf0800000 0x0 0x1000>;
+		};
+
+		gic: interrupt-controller@dfff9000 {
+			compatible = "arm,gic-400";
+			reg = <0x0 0xdfff9000 0x0 0x1000>,
+			      <0x0 0xdfffa000 0x0 0x2000>,
+			      <0x0 0xdfffc000 0x0 0x2000>,
+			      <0x0 0xdfffe000 0x0 0x2000>;
+			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+			#interrupt-cells = <3>;
+			interrupt-controller;
+			#address-cells = <0>;
+			ppi-partitions {
+				ppi_cluster0: interrupt-partition-0 {
+					affinity = <&cpu0 &cpu1 &cpu2 &cpu3>;
+				};
+			};
+		};
+	};
+
+	ahb {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		compatible = "simple-bus";
+		interrupt-parent = <&gic>;
+		ranges;
+
+		rstc: reset-controller@f0801000 {
+			compatible = "nuvoton,npcm845-reset";
+			reg = <0x0 0xf0801000 0x0 0x78>;
+			#reset-cells = <2>;
+			nuvoton,sysgcr = <&gcr>;
+		};
+
+		clk: clock-controller@f0801000 {
+			compatible = "nuvoton,npcm845-clk";
+			#clock-cells = <1>;
+			reg = <0x0 0xf0801000 0x0 0x1000>;
+		};
+
+		apb {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "simple-bus";
+			interrupt-parent = <&gic>;
+			ranges = <0x0 0x0 0xf0000000 0x00300000>,
+				<0xfff00000 0x0 0xfff00000 0x00016000>;
+
+			timer0: timer@8000 {
+				compatible = "nuvoton,npcm845-timer";
+				interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+				reg = <0x8000 0x1C>;
+				clocks = <&clk NPCM8XX_CLK_REFCLK>;
+				clock-names = "refclk";
+			};
+
+			serial0: serial@0 {
+				compatible = "nuvoton,npcm845-uart", "nuvoton,npcm750-uart";
+				reg = <0x0 0x1000>;
+				clocks = <&clk NPCM8XX_CLK_UART>;
+				interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>;
+				reg-shift = <2>;
+				status = "disabled";
+			};
+
+			serial1: serial@1000 {
+				compatible = "nuvoton,npcm845-uart", "nuvoton,npcm750-uart";
+				reg = <0x1000 0x1000>;
+				clocks = <&clk NPCM8XX_CLK_UART>;
+				interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
+				reg-shift = <2>;
+				status = "disabled";
+			};
+
+			serial2: serial@2000 {
+				compatible = "nuvoton,npcm845-uart", "nuvoton,npcm750-uart";
+				reg = <0x2000 0x1000>;
+				clocks = <&clk NPCM8XX_CLK_UART>;
+				interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>;
+				reg-shift = <2>;
+				status = "disabled";
+			};
+
+			serial3: serial@3000 {
+				compatible = "nuvoton,npcm845-uart", "nuvoton,npcm750-uart";
+				reg = <0x3000 0x1000>;
+				clocks = <&clk NPCM8XX_CLK_UART>;
+				interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>;
+				reg-shift = <2>;
+				status = "disabled";
+			};
+
+			serial4: serial@4000 {
+				compatible = "nuvoton,npcm845-uart", "nuvoton,npcm750-uart";
+				reg = <0x4000 0x1000>;
+				clocks = <&clk NPCM8XX_CLK_UART>;
+				interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>;
+				reg-shift = <2>;
+				status = "disabled";
+			};
+
+			serial5: serial@5000 {
+				compatible = "nuvoton,npcm845-uart", "nuvoton,npcm750-uart";
+				reg = <0x5000 0x1000>;
+				clocks = <&clk NPCM8XX_CLK_UART>;
+				interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>;
+				reg-shift = <2>;
+				status = "disabled";
+			};
+
+			serial6: serial@6000 {
+				compatible = "nuvoton,npcm845-uart", "nuvoton,npcm750-uart";
+				reg = <0x6000 0x1000>;
+				clocks = <&clk NPCM8XX_CLK_UART>;
+				interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>;
+				reg-shift = <2>;
+				status = "disabled";
+			};
+
+			watchdog0: watchdog@801c {
+				compatible = "nuvoton,npcm845-wdt", "nuvoton,npcm750-wdt";
+				interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
+				reg = <0x801c 0x4>;
+				status = "disabled";
+				clocks = <&clk NPCM8XX_CLK_REFCLK>;
+				syscon = <&gcr>;
+			};
+
+			watchdog1: watchdog@901c {
+				compatible = "nuvoton,npcm845-wdt", "nuvoton,npcm750-wdt";
+				interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
+				reg = <0x901c 0x4>;
+				status = "disabled";
+				clocks = <&clk NPCM8XX_CLK_REFCLK>;
+				syscon = <&gcr>;
+			};
+
+			watchdog2: watchdog@a01c {
+				compatible = "nuvoton,npcm845-wdt", "nuvoton,npcm750-wdt";
+				interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
+				reg = <0xa01c 0x4>;
+				status = "disabled";
+				clocks = <&clk NPCM8XX_CLK_REFCLK>;
+				syscon = <&gcr>;
+			};
+		};
+	};
+};
diff --git a/arch/arm/dts/nuvoton-npcm845-evb.dts b/arch/arm/dts/nuvoton-npcm845-evb.dts
new file mode 100644
index 0000000..a5ab2bc
--- /dev/null
+++ b/arch/arm/dts/nuvoton-npcm845-evb.dts
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2021 Nuvoton Technology tomer.maimon@nuvoton.com
+
+/dts-v1/;
+#include "nuvoton-npcm845.dtsi"
+
+/ {
+	model = "Nuvoton npcm845 Development Board (Device Tree)";
+	compatible = "nuvoton,npcm845-evb", "nuvoton,npcm845";
+
+	aliases {
+		serial0 = &serial0;
+	};
+
+	chosen {
+		stdout-path = &serial0;
+	};
+
+	memory {
+		reg = <0x0 0x0 0x0 0x40000000>;
+	};
+};
+
+&serial0 {
+	status = "okay";
+};
+
+&watchdog1 {
+	status = "okay";
+};
diff --git a/arch/arm/dts/nuvoton-npcm845.dtsi b/arch/arm/dts/nuvoton-npcm845.dtsi
new file mode 100644
index 0000000..6ce03f3
--- /dev/null
+++ b/arch/arm/dts/nuvoton-npcm845.dtsi
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2021 Nuvoton Technology tomer.maimon@nuvoton.com
+
+#include "nuvoton-common-npcm8xx.dtsi"
+#include "nuvoton-npcm8xx-u-boot.dtsi"
+
+/ {
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		cpu0: cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a35";
+			clocks = <&clk NPCM8XX_CLK_CPU>;
+			reg = <0x0 0x0>;
+			next-level-cache = <&l2>;
+			enable-method = "psci";
+		};
+
+		cpu1: cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a35";
+			clocks = <&clk NPCM8XX_CLK_CPU>;
+			reg = <0x0 0x1>;
+			next-level-cache = <&l2>;
+			enable-method = "psci";
+		};
+
+		cpu2: cpu@2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a35";
+			clocks = <&clk NPCM8XX_CLK_CPU>;
+			reg = <0x0 0x2>;
+			next-level-cache = <&l2>;
+			enable-method = "psci";
+		};
+
+		cpu3: cpu@3 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a35";
+			clocks = <&clk NPCM8XX_CLK_CPU>;
+			reg = <0x0 0x3>;
+			next-level-cache = <&l2>;
+			enable-method = "psci";
+		};
+
+		l2: l2-cache {
+			compatible = "cache";
+		};
+	};
+
+	arm-pmu {
+		compatible = "arm,cortex-a35-pmu";
+		interrupts = <GIC_SPI 242 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 243 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 244 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 245 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;
+	};
+
+	psci {
+		compatible      = "arm,psci-1.0";
+		method          = "smc";
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+	};
+};
diff --git a/arch/arm/dts/nuvoton-npcm8xx-u-boot.dtsi b/arch/arm/dts/nuvoton-npcm8xx-u-boot.dtsi
new file mode 100644
index 0000000..f5f1ce6
--- /dev/null
+++ b/arch/arm/dts/nuvoton-npcm8xx-u-boot.dtsi
@@ -0,0 +1,136 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <dt-bindings/reset/nuvoton,npcm8xx-reset.h>
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	interrupt-parent = <&gic>;
+
+	/* external reference clock */
+	clk_refclk: clk-refclk {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <25000000>;
+		clock-output-names = "refclk";
+	};
+
+	ahb {
+		rstc: reset-controller@f0801000 {
+			compatible = "nuvoton,npcm845-reset", "syscon",
+				"simple-mfd";
+			reg = <0x0 0xf0801000 0x0 0xC4>;
+			rstc1: reset-controller1 {
+				compatible = "syscon-reset";
+				#reset-cells = <1>;
+				regmap = <&rstc>;
+				offset = <NPCM8XX_RESET_IPSRST1>;
+				mask = <0xFFFFFFFF>;
+			};
+			rstc2: reset-controller2 {
+				compatible = "syscon-reset";
+				#reset-cells = <1>;
+				regmap = <&rstc>;
+				offset = <NPCM8XX_RESET_IPSRST2>;
+				mask = <0xFFFFFFFF>;
+			};
+			rstc3: reset-controller3 {
+				compatible = "syscon-reset";
+				#reset-cells = <1>;
+				regmap = <&rstc>;
+				offset = <NPCM8XX_RESET_IPSRST3>;
+				mask = <0xFFFFFFFF>;
+			};
+			rstc4: reset-controller4 {
+				compatible = "syscon-reset";
+				#reset-cells = <1>;
+				regmap = <&rstc>;
+				offset = <NPCM8XX_RESET_IPSRST4>;
+				mask = <0xFFFFFFFF>;
+			};
+		};
+
+		clk: clock-controller@f0801000 {
+			compatible = "nuvoton,npcm845-clk", "syscon";
+			#clock-cells = <1>;
+			clock-controller;
+			reg = <0x0 0xf0801000 0x0 0x1000>;
+			clock-names = "refclk";
+			clocks = <&clk_refclk>;
+		};
+
+		apb {
+			serial0: serial@0 {
+				compatible = "nuvoton,npcm845-uart";
+				reg = <0x0 0x1000>;
+				clocks = <&clk NPCM8XX_CLK_UART>, <&clk NPCM8XX_CLK_PLL2DIV2>;
+				clock-frequency = <24000000>;
+				status = "disabled";
+			};
+
+			gpio0: gpio0@10000 {
+				compatible = "nuvoton,npcm-gpio";
+				reg = <0x10000 0xB0>;
+				#gpio-cells = <2>;
+				gpio-controller;
+				gpio-bank-name = "gpio0";
+			};
+
+			gpio1: gpio1@11000 {
+				compatible = "nuvoton,npcm-gpio";
+				reg = <0x11000 0xB0>;
+				#gpio-cells = <2>;
+				gpio-controller;
+				gpio-bank-name = "gpio1";
+			};
+
+			gpio2: gpio2@12000 {
+				compatible = "nuvoton,npcm-gpio";
+				reg = <0x12000 0xB0>;
+				#gpio-cells = <2>;
+				gpio-controller;
+				gpio-bank-name = "gpio2";
+			};
+
+			gpio3: gpio3@13000 {
+				compatible = "nuvoton,npcm-gpio";
+				reg = <0x13000 0xB0>;
+				#gpio-cells = <2>;
+				gpio-controller;
+				gpio-bank-name = "gpio3";
+			};
+
+			gpio4: gpio4@14000 {
+				compatible = "nuvoton,npcm-gpio";
+				reg = <0x14000 0xB0>;
+				#gpio-cells = <2>;
+				gpio-controller;
+				gpio-bank-name = "gpio4";
+			};
+
+			gpio5: gpio5@15000 {
+				compatible = "nuvoton,npcm-gpio";
+				reg = <0x15000 0xB0>;
+				#gpio-cells = <2>;
+				gpio-controller;
+				gpio-bank-name = "gpio5";
+			};
+
+			gpio6: gpio6@16000 {
+				compatible = "nuvoton,npcm-gpio";
+				reg = <0x16000 0xB0>;
+				#gpio-cells = <2>;
+				gpio-controller;
+				gpio-bank-name = "gpio6";
+			};
+
+			gpio7: gpio7@17000 {
+				compatible = "nuvoton,npcm-gpio";
+				reg = <0x17000 0xB0>;
+				#gpio-cells = <2>;
+				gpio-controller;
+				gpio-bank-name = "gpio7";
+			};
+		};
+	};
+};
diff --git a/arch/arm/include/asm/arch-npcm8xx/gcr.h b/arch/arm/include/asm/arch-npcm8xx/gcr.h
new file mode 100644
index 0000000..ee6677a
--- /dev/null
+++ b/arch/arm/include/asm/arch-npcm8xx/gcr.h
@@ -0,0 +1,140 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * System Global Control Register definitions
+ * Copyright (c) 2022 Nuvoton Technology Corp.
+ */
+
+#ifndef _NPCM_GCR_H_
+#define _NPCM_GCR_H_
+
+#define NPCM_GCR_BA		0xF0800000
+
+/* On-Chip ARBEL NPCM8XX VERSIONS */
+#define ARBEL_Z1			0x00A35850
+#define ARBEL_A1			0x04a35850
+#define ARBEL_NPCM845			0x00000000
+#define ARBEL_NPCM830			0x00300395
+#define ARBEL_NPCM810			0x00000220
+
+#define MFSEL4_ESPISEL		BIT(8)
+#define MFSEL1_LPCSEL		BIT(26)
+#define INTCR2_WDC		BIT(21)
+
+struct npcm_gcr {
+	unsigned int  pdid;
+	unsigned int  pwron;
+	unsigned int  swstrps;
+	unsigned int  rsvd1[2];
+	unsigned int  miscpe;
+	unsigned int  spldcnt;
+	unsigned int  rsvd2[1];
+	unsigned int  flockr2;
+	unsigned int  flockr3;
+	unsigned int  rsvd3[3];
+	unsigned int  a35_mode;
+	unsigned int  spswc;
+	unsigned int  intcr;
+	unsigned int  intsr;
+	unsigned int  obscr1;
+	unsigned int  obsdr1;
+	unsigned int  rsvd4[1];
+	unsigned int  hifcr;
+	unsigned int  rsvd5[3];
+	unsigned int  intcr2;
+	unsigned int  rsvd6[1];
+	unsigned int  srcnt;
+	unsigned int  ressr;
+	unsigned int  rlockr1;
+	unsigned int  flockr1;
+	unsigned int  dscnt;
+	unsigned int  mdlr;
+	unsigned int  scrpad_c;
+	unsigned int  scrpad_b;
+	unsigned int  rsvd7[4];
+	unsigned int  daclvlr;
+	unsigned int  intcr3;
+	unsigned int  pcirctl;
+	unsigned int  rsvd8[2];
+	unsigned int  vsintr;
+	unsigned int  rsvd9[1];
+	unsigned int  sd2sur1;
+	unsigned int  sd2sur2;
+	unsigned int  sd2irv3;
+	unsigned int  intcr4;
+	unsigned int  obscr2;
+	unsigned int  obsdr2;
+	unsigned int  rsvd10[5];
+	unsigned int  i2csegsel;
+	unsigned int  i2csegctl;
+	unsigned int  vsrcr;
+	unsigned int  mlockr;
+	unsigned int  rsvd11[8];
+	unsigned int  etsr;
+	unsigned int  dft1r;
+	unsigned int  dft2r;
+	unsigned int  dft3r;
+	unsigned int  edffsr;
+	unsigned int  rsvd12[1];
+	unsigned int  intcrpce3;
+	unsigned int  intcrpce2;
+	unsigned int  intcrpce0;
+	unsigned int  intcrpce1;
+	unsigned int  dactest;
+	unsigned int  scrpad;
+	unsigned int  usb1phyctl;
+	unsigned int  usb2phyctl;
+	unsigned int  usb3phyctl;
+	unsigned int  intsr2;
+	unsigned int  intcrpce2b;
+	unsigned int  intcrpce0b;
+	unsigned int  intcrpce1b;
+	unsigned int  intcrpce3b;
+	unsigned int  rsvd13[4];
+	unsigned int  intcrpce2c;
+	unsigned int  intcrpce0c;
+	unsigned int  intcrpce1c;
+	unsigned int  intcrpce3c;
+	unsigned int  rsvd14[40];
+	unsigned int  sd2irv4;
+	unsigned int  sd2irv5;
+	unsigned int  sd2irv6;
+	unsigned int  sd2irv7;
+	unsigned int  sd2irv8;
+	unsigned int  sd2irv9;
+	unsigned int  sd2irv10;
+	unsigned int  sd2irv11;
+	unsigned int  rsvd15[8];
+	unsigned int  mfsel1;
+	unsigned int  mfsel2;
+	unsigned int  mfsel3;
+	unsigned int  mfsel4;
+	unsigned int  mfsel5;
+	unsigned int  mfsel6;
+	unsigned int  mfsel7;
+	unsigned int  rsvd16[1];
+	unsigned int  mfsel_lk1;
+	unsigned int  mfsel_lk2;
+	unsigned int  mfsel_lk3;
+	unsigned int  mfsel_lk4;
+	unsigned int  mfsel_lk5;
+	unsigned int  mfsel_lk6;
+	unsigned int  mfsel_lk7;
+	unsigned int  rsvd17[1];
+	unsigned int  mfsel_set1;
+	unsigned int  mfsel_set2;
+	unsigned int  mfsel_set3;
+	unsigned int  mfsel_set4;
+	unsigned int  mfsel_set5;
+	unsigned int  mfsel_set6;
+	unsigned int  mfsel_set7;
+	unsigned int  rsvd18[1];
+	unsigned int  mfsel_clr1;
+	unsigned int  mfsel_clr2;
+	unsigned int  mfsel_clr3;
+	unsigned int  mfsel_clr4;
+	unsigned int  mfsel_clr5;
+	unsigned int  mfsel_clr6;
+	unsigned int  mfsel_clr7;
+	};
+
+#endif
diff --git a/arch/arm/include/asm/arch-npcm8xx/rst.h b/arch/arm/include/asm/arch-npcm8xx/rst.h
new file mode 100644
index 0000000..379e841
--- /dev/null
+++ b/arch/arm/include/asm/arch-npcm8xx/rst.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+
+#ifndef _NPCM_RST_H_
+#define _NPCM_RST_H_
+
+/* Watchdog Timer Controller Register */
+#define WTCR0_REG	0xF000801C
+#define WTCR_WTR	BIT(0)
+#define WTCR_WTRE	BIT(1)
+#define WTCR_WTE	BIT(7)
+
+/* Reset status bits */
+#define PORST		BIT(31)
+#define CORST		BIT(30)
+#define WD0RST		BIT(29)
+#define SW1RST		BIT(28)
+#define SW2RST		BIT(27)
+#define SW3RST		BIT(26)
+#define SW4RST		BIT(25)
+#define WD1RST		BIT(24)
+#define WD2RST		BIT(23)
+#define RST_STS_MASK	GENMASK(31, 23)
+
+int npcm_get_reset_status(void);
+
+#endif
diff --git a/arch/arm/include/asm/mach-imx/regs-gpmi.h b/arch/arm/include/asm/mach-imx/regs-gpmi.h
index 33daa53..7a15778 100644
--- a/arch/arm/include/asm/mach-imx/regs-gpmi.h
+++ b/arch/arm/include/asm/mach-imx/regs-gpmi.h
@@ -93,6 +93,11 @@
 #define	GPMI_CTRL1_DECOUPLE_CS				(1 << 24)
 #define	GPMI_CTRL1_WRN_DLY_SEL_MASK			(0x3 << 22)
 #define	GPMI_CTRL1_WRN_DLY_SEL_OFFSET			22
+#define	GPMI_CTRL1_WRN_DLY_SEL_4_TO_8NS			0x0
+#define	GPMI_CTRL1_WRN_DLY_SEL_6_TO_10NS		0x1
+#define	GPMI_CTRL1_WRN_DLY_SEL_7_TO_12NS		0x2
+#define	GPMI_CTRL1_WRN_DLY_SEL_NO_DELAY			0x3
+
 #define	GPMI_CTRL1_TIMEOUT_IRQ_EN			(1 << 20)
 #define	GPMI_CTRL1_GANGED_RDYBUSY			(1 << 19)
 #define	GPMI_CTRL1_BCH_MODE				(1 << 18)
@@ -111,6 +116,10 @@
 #define	GPMI_CTRL1_ATA_IRQRDY_POLARITY			(1 << 2)
 #define	GPMI_CTRL1_CAMERA_MODE				(1 << 1)
 #define	GPMI_CTRL1_GPMI_MODE				(1 << 0)
+#define	GPMI_CTRL1_CLEAR_MASK				(GPMI_CTRL1_WRN_DLY_SEL_MASK | \
+							 GPMI_CTRL1_DLL_ENABLE | \
+							 GPMI_CTRL1_RDN_DELAY_MASK | \
+							 GPMI_CTRL1_HALF_PERIOD)
 
 #define	GPMI_TIMING0_ADDRESS_SETUP_MASK			(0xff << 16)
 #define	GPMI_TIMING0_ADDRESS_SETUP_OFFSET		16
diff --git a/arch/arm/lib/bdinfo.c b/arch/arm/lib/bdinfo.c
index b22ee07..826e09e 100644
--- a/arch/arm/lib/bdinfo.c
+++ b/arch/arm/lib/bdinfo.c
@@ -9,9 +9,21 @@
 #include <common.h>
 #include <init.h>
 #include <asm/global_data.h>
+#include <asm/mach-types.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
+int arch_setup_bdinfo(void)
+{
+#ifdef CONFIG_MACH_TYPE
+	struct bd_info *bd = gd->bd;
+
+	bd->bi_arch_number = CONFIG_MACH_TYPE; /* board id for Linux */
+#endif
+
+	return 0;
+}
+
 void arch_print_bdinfo(void)
 {
 	struct bd_info *bd = gd->bd;
diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
index 2ebe341..fe6b785 100644
--- a/arch/arm/mach-mvebu/Kconfig
+++ b/arch/arm/mach-mvebu/Kconfig
@@ -348,6 +348,21 @@
 	  from a memory block.
 	  This is can be used for testing prog scripts.
 
+config MVEBU_EFUSE_VHV_GPIO
+	string "VHV_Enable GPIO name for eFuse programming"
+	depends on MVEBU_EFUSE && !ARMADA_3700
+	help
+	  The eFuse programing (burning) phase requires supplying 1.8V to the
+	  device on the VHV power pin, while for normal operation the VHV power
+	  rail must be left unconnected. See Marvell AN-389: ARMADA VHV Power
+	  document (Doc. No. MV-S302545-00 Rev. C, August 2, 2016) for details.
+	  .
+	  This specify VHV_Enable GPIO name used in U-Boot for enabling VHV power.
+
+config MVEBU_EFUSE_VHV_GPIO_ACTIVE_LOW
+	bool "VHV_Enable GPIO is Active Low"
+	depends on MVEBU_EFUSE_VHV_GPIO != ""
+
 config SECURED_MODE_IMAGE
 	bool "Build image for trusted boot"
 	default false
diff --git a/arch/arm/mach-mvebu/Makefile b/arch/arm/mach-mvebu/Makefile
index 103e64c..406a9ee 100644
--- a/arch/arm/mach-mvebu/Makefile
+++ b/arch/arm/mach-mvebu/Makefile
@@ -16,10 +16,6 @@
 obj-y	+= gpio.o
 obj-y	+= mbus.o
 
-ifndef CONFIG_TIMER
-obj-y	+= timer.o
-endif
-
 else # CONFIG_ARCH_KIRKWOOD
 
 obj-y	= cpu.o
@@ -97,7 +93,6 @@
 endif # CONFIG_SPL_BUILD
 obj-y	+= gpio.o
 obj-y	+= mbus.o
-obj-y	+= timer.o
 obj-$(CONFIG_SPL_BUILD) += spl.o
 obj-$(CONFIG_SPL_BUILD) += lowlevel_spl.o
 
diff --git a/arch/arm/mach-mvebu/efuse.c b/arch/arm/mach-mvebu/efuse.c
index 80318c3..be5dc0e 100644
--- a/arch/arm/mach-mvebu/efuse.c
+++ b/arch/arm/mach-mvebu/efuse.c
@@ -10,6 +10,7 @@
 #include <asm/arch/cpu.h>
 #include <asm/arch/efuse.h>
 #include <asm/arch/soc.h>
+#include <asm/gpio.h>
 #include <linux/bitops.h>
 #include <linux/delay.h>
 #include <linux/mbus.h>
@@ -56,17 +57,48 @@
 	return efuses + nr;
 }
 
-static void enable_efuse_program(void)
+#ifndef DRY_RUN
+static int vhv_gpio;
+#endif
+
+static int enable_efuse_program(void)
 {
 #ifndef DRY_RUN
+	if (CONFIG_MVEBU_EFUSE_VHV_GPIO[0]) {
+		if (gpio_lookup_name(CONFIG_MVEBU_EFUSE_VHV_GPIO, NULL, NULL, &vhv_gpio)) {
+			printf("Error: VHV gpio lookup failed\n");
+			return -EOPNOTSUPP;
+		}
+		if (gpio_request(vhv_gpio, CONFIG_MVEBU_EFUSE_VHV_GPIO)) {
+			printf("Error: VHV gpio request failed\n");
+			return -EOPNOTSUPP;
+		}
+		if (gpio_direction_output(vhv_gpio,
+		    IS_ENABLED(CONFIG_MVEBU_EFUSE_VHV_GPIO_ACTIVE_LOW) ? 0 : 1)) {
+			printf("Error: VHV gpio enable failed\n");
+			return -EINVAL;
+		}
+		mdelay(5); /* Wait for the VHV power to stabilize */
+	}
+
 	setbits_le32(MVEBU_EFUSE_CONTROL, MVEBU_EFUSE_CTRL_PROGRAM_ENABLE);
 #endif
+
+	return 0;
 }
 
 static void disable_efuse_program(void)
 {
 #ifndef DRY_RUN
 	clrbits_le32(MVEBU_EFUSE_CONTROL, MVEBU_EFUSE_CTRL_PROGRAM_ENABLE);
+
+	if (CONFIG_MVEBU_EFUSE_VHV_GPIO[0]) {
+		if (gpio_direction_output(vhv_gpio,
+		    IS_ENABLED(CONFIG_MVEBU_EFUSE_VHV_GPIO_ACTIVE_LOW) ? 1 : 0))
+			printf("Error: VHV gpio disable failed\n");
+		gpio_free(vhv_gpio);
+		vhv_gpio = 0;
+	}
 #endif
 }
 
@@ -123,7 +155,9 @@
 	if (!new_val->dwords.d[0] && !new_val->dwords.d[1] && (mask0 | mask1))
 		return 0;
 
-	enable_efuse_program();
+	res = enable_efuse_program();
+	if (res)
+		return res;
 
 	res = do_prog_efuse(efuse, new_val, mask0, mask1);
 
@@ -132,6 +166,48 @@
 	return res;
 }
 
+int mvebu_prog_ld_efuse(int ld1, u32 word, u32 val)
+{
+	int i, res;
+	u32 line[EFUSE_LD_WORDS];
+
+	res = mvebu_efuse_init_hw();
+	if (res)
+		return res;
+
+	mvebu_read_ld_efuse(ld1, line);
+
+	/* check if lock bit is already programmed */
+	if (line[EFUSE_LD_WORDS - 1])
+		return -EPERM;
+
+	/* check if word is valid */
+	if (word >= EFUSE_LD_WORDS)
+		return -EINVAL;
+
+	/* check if there is some bit for programming */
+	if (val == (line[word] & val))
+		return 0;
+
+	res = enable_efuse_program();
+	if (res)
+		return res;
+
+	mvebu_read_ld_efuse(ld1, line);
+	line[word] |= val;
+
+	for (i = 0; i < EFUSE_LD_WORDS; i++) {
+		writel(line[i], ld_efuses + i);
+		mdelay(1);
+	}
+
+	mdelay(5);
+
+	disable_efuse_program();
+
+	return 0;
+}
+
 int mvebu_efuse_init_hw(void)
 {
 	int ret;
@@ -254,6 +330,9 @@
 {
 	int res = 0;
 
+	if (bank == EFUSE_LD0_LINE || bank == EFUSE_LD1_LINE)
+		return mvebu_prog_ld_efuse(bank == EFUSE_LD1_LINE, word, val);
+
 	/*
 	 * NOTE: Fuse line should be written as whole.
 	 * So how can we do that with this API?
diff --git a/arch/arm/mach-mvebu/include/mach/efuse.h b/arch/arm/mach-mvebu/include/mach/efuse.h
index 122e735..b125c30 100644
--- a/arch/arm/mach-mvebu/include/mach/efuse.h
+++ b/arch/arm/mach-mvebu/include/mach/efuse.h
@@ -70,4 +70,8 @@
 
 int mvebu_lock_efuse(int nr);
 
+void mvebu_read_ld_efuse(int ld1, u32 *line);
+
+int mvebu_prog_ld_efuse(int ld1, u32 word, u32 val);
+
 #endif
diff --git a/arch/arm/mach-mvebu/spl.c b/arch/arm/mach-mvebu/spl.c
index ca2d5a5..4245992 100644
--- a/arch/arm/mach-mvebu/spl.c
+++ b/arch/arm/mach-mvebu/spl.c
@@ -340,8 +340,6 @@
 
 	preloader_console_init();
 
-	timer_init();
-
 	/* Armada 375 does not support SerDes and DDR3 init yet */
 #if !defined(CONFIG_ARMADA_375)
 	/* First init the serdes PHY's */
diff --git a/arch/arm/mach-mvebu/timer.c b/arch/arm/mach-mvebu/timer.c
deleted file mode 100644
index 557a378..0000000
--- a/arch/arm/mach-mvebu/timer.c
+++ /dev/null
@@ -1,41 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright (C) Marvell International Ltd. and its affiliates
- * Written-by: Prafulla Wadaskar <prafulla@marvell.com>
- *
- * Copyright (C) 2015 Stefan Roese <sr@denx.de>
- */
-
-#include <common.h>
-#include <init.h>
-#include <asm/io.h>
-#include <asm/arch/soc.h>
-#include <linux/bitops.h>
-
-#define TIMER_LOAD_VAL			0xffffffff
-
-static int init_done __section(".data") = 0;
-
-/*
- * Timer initialization
- */
-int timer_init(void)
-{
-	/* Only init the timer once */
-	if (init_done)
-		return 0;
-	init_done = 1;
-
-	/* load value into timer */
-	writel(TIMER_LOAD_VAL, MVEBU_TIMER_BASE + 0x10);
-	writel(TIMER_LOAD_VAL, MVEBU_TIMER_BASE + 0x14);
-
-#if defined(CONFIG_ARCH_MVEBU)
-	/* On Armada XP / 38x ..., the 25MHz clock source needs to be enabled */
-	setbits_le32(MVEBU_TIMER_BASE + 0x00, BIT(11));
-#endif
-	/* enable timer in auto reload mode */
-	setbits_le32(MVEBU_TIMER_BASE + 0x00, 0x3);
-
-	return 0;
-}
diff --git a/arch/arm/mach-npcm/Kconfig b/arch/arm/mach-npcm/Kconfig
index cf5043d..7f2f9ac 100644
--- a/arch/arm/mach-npcm/Kconfig
+++ b/arch/arm/mach-npcm/Kconfig
@@ -19,8 +19,16 @@
 	  General support for NPCM7xx BMC (Poleg).
 	  Nuvoton NPCM7xx BMC is based on the Cortex A9.
 
+config ARCH_NPCM8XX
+	bool "Support Nuvoton NPCM8xx SoC"
+	select ARM64
+	help
+	  General support for NPCM8xx BMC (Arbel).
+	  Nuvoton NPCM8xx BMC is based on the Cortex A35.
+
 endchoice
 
 source "arch/arm/mach-npcm/npcm7xx/Kconfig"
+source "arch/arm/mach-npcm/npcm8xx/Kconfig"
 
 endif
diff --git a/arch/arm/mach-npcm/Makefile b/arch/arm/mach-npcm/Makefile
index 8a1572b..b448329 100644
--- a/arch/arm/mach-npcm/Makefile
+++ b/arch/arm/mach-npcm/Makefile
@@ -1 +1,2 @@
 obj-$(CONFIG_ARCH_NPCM7xx) += npcm7xx/
+obj-$(CONFIG_ARCH_NPCM8XX) += npcm8xx/
diff --git a/arch/arm/mach-npcm/npcm8xx/Kconfig b/arch/arm/mach-npcm/npcm8xx/Kconfig
new file mode 100644
index 0000000..5f4a050
--- /dev/null
+++ b/arch/arm/mach-npcm/npcm8xx/Kconfig
@@ -0,0 +1,18 @@
+if ARCH_NPCM8XX
+
+config SYS_CPU
+	default "armv8"
+
+config SYS_SOC
+	default "npcm8xx"
+
+config TARGET_ARBEL_EVB
+	bool "Arbel Evaluation Board"
+	help
+	  ARBEL_EVB is Nuvoton evaluation board for NPCM845 SoC,
+	  supports general functions of Basebase Management Controller
+	  (BMC).
+
+source "board/nuvoton/arbel_evb/Kconfig"
+
+endif
diff --git a/arch/arm/mach-npcm/npcm8xx/Makefile b/arch/arm/mach-npcm/npcm8xx/Makefile
new file mode 100644
index 0000000..6c080e1
--- /dev/null
+++ b/arch/arm/mach-npcm/npcm8xx/Makefile
@@ -0,0 +1 @@
+obj-y += cpu.o reset.o
diff --git a/arch/arm/mach-npcm/npcm8xx/cpu.c b/arch/arm/mach-npcm/npcm8xx/cpu.c
new file mode 100644
index 0000000..2d839cf
--- /dev/null
+++ b/arch/arm/mach-npcm/npcm8xx/cpu.c
@@ -0,0 +1,135 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2022 Nuvoton Technology Corp.
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/arch/gcr.h>
+#include <asm/armv8/mmu.h>
+
+#define SYSCNT_CTRL_BASE_ADDR   0xF07FC000
+#define SC_CNTCR_ENABLE		BIT(0)
+#define SC_CNTCR_HDBG		BIT(1)
+#define SC_CNTCR_FREQ0		BIT(8)
+#define SC_CNTCR_FREQ1		BIT(9)
+
+/* System Counter register map */
+struct sctr_regs {
+	u32 cntcr;
+	u32 cntsr;
+	u32 cntcv1;
+	u32 cntcv2;
+	u32 resv1[4];
+	u32 cntfid0;
+	u32 cntfid1;
+	u32 cntfid2;
+	u32 resv2[1001];
+	u32 counterid[1];
+};
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int print_cpuinfo(void)
+{
+	struct npcm_gcr *gcr = (struct npcm_gcr *)NPCM_GCR_BA;
+	unsigned int val;
+	unsigned long mpidr_val;
+
+	asm volatile("mrs %0, mpidr_el1" : "=r" (mpidr_val));
+
+	val = readl(&gcr->mdlr);
+
+	printf("CPU-%lu: ", mpidr_val & 0x3);
+
+	switch (val) {
+	case ARBEL_NPCM845:
+		printf("NPCM845 ");
+		break;
+	case ARBEL_NPCM830:
+		printf("NPCM830 ");
+		break;
+	case ARBEL_NPCM810:
+		printf("NPCM810 ");
+		break;
+	default:
+		printf("NPCM8XX ");
+		break;
+	}
+
+	val = readl(&gcr->pdid);
+	switch (val) {
+	case ARBEL_Z1:
+		printf("Z1 @ ");
+		break;
+	case ARBEL_A1:
+		printf("A1 @ ");
+		break;
+	default:
+		printf("Unknown\n");
+		break;
+	}
+
+	return 0;
+}
+
+int arch_cpu_init(void)
+{
+	if (!IS_ENABLED(CONFIG_SYS_DCACHE_OFF)) {
+		/* Enable cache to speed up system running */
+		if (get_sctlr() & CR_M)
+			return 0;
+
+		icache_enable();
+		__asm_invalidate_dcache_all();
+		__asm_invalidate_tlb_all();
+		set_sctlr(get_sctlr() | CR_C);
+	}
+
+	return 0;
+}
+
+static struct mm_region npcm_mem_map[1 + CONFIG_NR_DRAM_BANKS + 1] = {
+	{
+		/* DRAM */
+		.phys = 0x0UL,
+		.virt = 0x0UL,
+		.size = 0x80000000UL,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+			 PTE_BLOCK_INNER_SHARE
+	},
+	{
+		.phys = 0x80000000UL,
+		.virt = 0x80000000UL,
+		.size = 0x80000000UL,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+			 PTE_BLOCK_NON_SHARE |
+			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
+	},
+	{
+		/* List terminator */
+		0,
+	}
+};
+
+struct mm_region *mem_map = npcm_mem_map;
+
+int timer_init(void)
+{
+	struct sctr_regs *sctr = (struct sctr_regs *)SYSCNT_CTRL_BASE_ADDR;
+	u32 cntfrq_el0;
+
+	/* Enable system counter */
+	__asm__ __volatile__("mrs %0, CNTFRQ_EL0\n\t" : "=r" (cntfrq_el0) : : "memory");
+	writel(cntfrq_el0, &sctr->cntfid0);
+	clrsetbits_le32(&sctr->cntcr, SC_CNTCR_FREQ0 | SC_CNTCR_FREQ1,
+			SC_CNTCR_ENABLE | SC_CNTCR_HDBG);
+
+	gd->arch.tbl = 0;
+	gd->arch.tbu = 0;
+
+	return 0;
+}
diff --git a/arch/arm/mach-npcm/npcm8xx/reset.c b/arch/arm/mach-npcm/npcm8xx/reset.c
new file mode 100644
index 0000000..6954e6c
--- /dev/null
+++ b/arch/arm/mach-npcm/npcm8xx/reset.c
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2022 Nuvoton Technology Corp.
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/gcr.h>
+#include <asm/arch/rst.h>
+
+void reset_cpu(void)
+{
+	/* Generate a watchdog0 reset */
+	writel(WTCR_WTR | WTCR_WTRE | WTCR_WTE, WTCR0_REG);
+
+	while (1)
+		;
+}
+
+void reset_misc(void)
+{
+	struct npcm_gcr *gcr = (struct npcm_gcr *)NPCM_GCR_BA;
+
+	clrbits_le32(&gcr->intcr2, INTCR2_WDC);
+}
+
+int npcm_get_reset_status(void)
+{
+	struct npcm_gcr *gcr = (struct npcm_gcr *)NPCM_GCR_BA;
+	u32 val;
+
+	val = readl(&gcr->ressr);
+	if (!val)
+		val = readl(&gcr->intcr2);
+
+	return val & RST_STS_MASK;
+}
diff --git a/arch/powerpc/include/asm/global_data.h b/arch/powerpc/include/asm/global_data.h
index 6709e69..6ed21c7 100644
--- a/arch/powerpc/include/asm/global_data.h
+++ b/arch/powerpc/include/asm/global_data.h
@@ -92,12 +92,6 @@
 
 #include <asm-generic/global_data.h>
 
-#if 1
 #define DECLARE_GLOBAL_DATA_PTR     register volatile gd_t *gd asm ("r2")
-#else /* We could use plain global data, but the resulting code is bigger */
-#define XTRN_DECLARE_GLOBAL_DATA_PTR	extern
-#define DECLARE_GLOBAL_DATA_PTR     XTRN_DECLARE_GLOBAL_DATA_PTR \
-				    gd_t *gd
-#endif
 
 #endif /* __ASM_GBL_DATA_H */
diff --git a/arch/powerpc/lib/stack.c b/arch/powerpc/lib/stack.c
index f2a4652..2e731aa 100644
--- a/arch/powerpc/lib/stack.c
+++ b/arch/powerpc/lib/stack.c
@@ -13,6 +13,7 @@
 #include <common.h>
 #include <init.h>
 #include <asm/global_data.h>
+#include <asm/mp.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -30,3 +31,19 @@
 
 	return 0;
 }
+
+int arch_setup_dest_addr(void)
+{
+#if defined(CONFIG_MP) && (defined(CONFIG_MPC86xx) || defined(CONFIG_E500))
+	/*
+	 * We need to make sure the location we intend to put secondary core
+	 * boot code is reserved and not used by any part of u-boot
+	 */
+	if (gd->relocaddr > determine_mp_bootpg(NULL)) {
+		gd->relocaddr = determine_mp_bootpg(NULL);
+		debug("Reserving MP boot page to %08lx\n", gd->relocaddr);
+	}
+#endif
+
+	return 0;
+}
diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
index 0b80eb8..53d1194 100644
--- a/arch/riscv/Makefile
+++ b/arch/riscv/Makefile
@@ -24,7 +24,16 @@
 	CMODEL = medany
 endif
 
-ARCH_FLAGS = -march=$(ARCH_BASE)$(ARCH_A)$(ARCH_C) -mabi=$(ABI) \
+RISCV_MARCH = $(ARCH_BASE)$(ARCH_A)$(ARCH_C)
+
+# Newer binutils versions default to ISA spec version 20191213 which moves some
+# instructions from the I extension to the Zicsr and Zifencei extensions.
+toolchain-need-zicsr-zifencei := $(call cc-option-yn, -mabi=$(ABI) -march=$(RISCV_MARCH)_zicsr_zifencei)
+ifeq ($(toolchain-need-zicsr-zifencei),y)
+	RISCV_MARCH := $(RISCV_MARCH)_zicsr_zifencei
+endif
+
+ARCH_FLAGS = -march=$(RISCV_MARCH) -mabi=$(ABI) \
 	     -mcmodel=$(CMODEL)
 
 PLATFORM_CPPFLAGS	+= $(ARCH_FLAGS)
diff --git a/board/keymile/Kconfig b/board/keymile/Kconfig
index f22faee..9f78443 100644
--- a/board/keymile/Kconfig
+++ b/board/keymile/Kconfig
@@ -167,7 +167,6 @@
 
 source "board/keymile/km83xx/Kconfig"
 source "board/keymile/kmcent2/Kconfig"
-source "board/keymile/km_arm/Kconfig"
 source "board/keymile/pg-wcom-ls102xa/Kconfig"
 
 endmenu
diff --git a/board/keymile/km_arm/Kconfig b/board/keymile/km_arm/Kconfig
deleted file mode 100644
index 9d222d7..0000000
--- a/board/keymile/km_arm/Kconfig
+++ /dev/null
@@ -1,86 +0,0 @@
-menu "KM ARM Options"
-	depends on ARM
-
-config KM_FPGA_CONFIG
-	bool "FPGA Configuration"
-	help
-	  Include capability to change FPGA configuration.
-
-config KM_FPGA_FORCE_CONFIG
-	bool "FPGA reconfiguration"
-	help
-	  If yes we force to reconfigure the FPGA always
-
-config KM_FPGA_NO_RESET
-	bool "FPGA skip reset"
-	help
-	  If yes we skip triggering a reset of the FPGA
-
-config KM_ENV_IS_IN_SPI_NOR
-	bool "Environment in SPI NOR"
-	help
-	  Put the U-Boot environment in the SPI NOR flash.
-
-config KM_PIGGY4_88E6061
-	bool "Piggy via Switch 88E6061"
-	help
-	  The Piggy4 board is connected via a Marvell 88E6061 switch.
-
-config KM_PIGGY4_88E6352
-	bool "Piggy via Switch 88E6352"
-	help
-	  The Piggy4 board is connected via a Marvell 88E6352 switch.
-
-endmenu
-
-if TARGET_KM_KIRKWOOD
-
-config SYS_BOARD
-	default "km_arm"
-
-config SYS_VENDOR
-	default "keymile"
-
-config SYS_CONFIG_NAME
-	default "km_kirkwood"
-
-config BOARD_SPECIFIC_OPTIONS # dummy
-	def_bool y
-	select BOARD_LATE_INIT
-	select DM
-	select DM_ETH
-	select DM_SERIAL
-	select DM_SPI
-	select DM_SPI_FLASH
-	select USB
-	select USB_EHCI_HCD
-	select USB_EHCI_MARVELL
-	imply CMD_CRAMFS
-	imply CMD_DIAG
-	imply FS_CRAMFS
-	imply CMD_USB
-
-choice
-	prompt "Board model"
-
-config KM_COGE5UN
-	bool "Hitachi Power Grids COGE5UN"
-
-config KM_KIRKWOOD_128M16
-	bool "Hitachi Power Grids Kirkwood 128M16"
-
-config KM_KIRKWOOD
-	bool "Hitachi Power Grids Kirkwood"
-
-config KM_KIRKWOOD_PCI
-	bool "Hitachi Power Grids Kirkwood PCI"
-
-config KM_NUSA
-	bool "Hitachi Power Grids Kirkwood (NUSA)"
-
-config KM_SUSE2
-	bool "Hitachi Power Grids Kirkwood (SUSE2)"
-
-endchoice
-
-endif
diff --git a/board/keymile/km_arm/MAINTAINERS b/board/keymile/km_arm/MAINTAINERS
deleted file mode 100644
index bc6858b..0000000
--- a/board/keymile/km_arm/MAINTAINERS
+++ /dev/null
@@ -1,11 +0,0 @@
-KM_ARM BOARD
-M:	Holger Brunck <holger.brunck@hitachienergy.com>
-S:	Maintained
-F:	board/keymile/km_arm/
-F:	include/configs/km_kirkwood.h
-F:	configs/km_kirkwood_defconfig
-F:	configs/km_kirkwood_128m16_defconfig
-F:	configs/km_kirkwood_pci_defconfig
-F:	configs/kmcoge5un_defconfig
-F:	configs/kmnusa_defconfig
-F:	configs/kmsuse2_defconfig
diff --git a/board/keymile/km_arm/Makefile b/board/keymile/km_arm/Makefile
deleted file mode 100644
index 79ccc76..0000000
--- a/board/keymile/km_arm/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0+
-#
-# (C) Copyright 2009
-# Marvell Semiconductor <www.marvell.com>
-# Prafulla Wadaskar <prafulla@marvell.com>
-
-obj-y	:= km_arm.o ../common/common.o ../common/ivm.o
-
-ifdef CONFIG_KM_FPGA_CONFIG
-obj-y	+= fpga_config.o
-endif
diff --git a/board/keymile/km_arm/fpga_config.c b/board/keymile/km_arm/fpga_config.c
deleted file mode 100644
index 839b162..0000000
--- a/board/keymile/km_arm/fpga_config.c
+++ /dev/null
@@ -1,255 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * (C) Copyright 2012
- * Valentin Lontgchamp, Keymile AG, valentin.longchamp@keymile.com
- */
-
-#include <common.h>
-#include <i2c.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-
-/* GPIO Pin from kirkwood connected to PROGRAM_B pin of the xilinx FPGA */
-#define KM_XLX_PROGRAM_B_PIN    39
-
-#define BOCO_ADDR	0x10
-
-#define ID_REG		0x00
-#define BOCO2_ID	0x5b
-
-static int check_boco2(void)
-{
-	int ret;
-	u8 id;
-
-	ret = i2c_read(BOCO_ADDR, ID_REG, 1, &id, 1);
-	if (ret) {
-		printf("%s: error reading the BOCO id !!\n", __func__);
-		return ret;
-	}
-
-	return (id == BOCO2_ID);
-}
-
-static int boco_clear_bits(u8 reg, u8 flags)
-{
-	int ret;
-	u8 regval;
-
-	/* give access to the EEPROM from FPGA */
-	ret = i2c_read(BOCO_ADDR, reg, 1, &regval, 1);
-	if (ret) {
-		printf("%s: error reading the BOCO @%#x !!\n",
-		       __func__, reg);
-		return ret;
-	}
-	regval &= ~flags;
-	ret = i2c_write(BOCO_ADDR, reg, 1, &regval, 1);
-	if (ret) {
-		printf("%s: error writing the BOCO @%#x !!\n",
-		       __func__, reg);
-		return ret;
-	}
-
-	return 0;
-}
-
-static int boco_set_bits(u8 reg, u8 flags)
-{
-	int ret;
-	u8 regval;
-
-	/* give access to the EEPROM from FPGA */
-	ret = i2c_read(BOCO_ADDR, reg, 1, &regval, 1);
-	if (ret) {
-		printf("%s: error reading the BOCO @%#x !!\n",
-		       __func__, reg);
-		return ret;
-	}
-	regval |= flags;
-	ret = i2c_write(BOCO_ADDR, reg, 1, &regval, 1);
-	if (ret) {
-		printf("%s: error writing the BOCO @%#x !!\n",
-		       __func__, reg);
-		return ret;
-	}
-
-	return 0;
-}
-
-#define SPI_REG		0x06
-#define CFG_EEPROM	0x02
-#define FPGA_PROG	0x04
-#define FPGA_INIT_B	0x10
-#define FPGA_DONE	0x20
-
-#ifndef CONFIG_KM_FPGA_FORCE_CONFIG
-static int fpga_done(void)
-{
-	int ret = 0;
-	u8 regval;
-
-	/* this is only supported with the boco2 design */
-	if (!check_boco2())
-		return 0;
-
-	ret = i2c_read(BOCO_ADDR, SPI_REG, 1, &regval, 1);
-	if (ret) {
-		printf("%s: error reading the BOCO @%#x !!\n",
-			__func__, SPI_REG);
-		return 0;
-	}
-
-	return regval & FPGA_DONE ? 1 : 0;
-}
-#endif /* CONFIG_KM_FPGA_FORCE_CONFIG */
-
-static int skip;
-
-int trigger_fpga_config(void)
-{
-	int ret = 0;
-
-	skip = 0;
-#ifndef CONFIG_KM_FPGA_FORCE_CONFIG
-	/* if the FPGA is already configured, we do not want to
-	 * reconfigure it
-	 */
-	skip = 0;
-	if (fpga_done()) {
-		printf("PCIe FPGA config: skipped\n");
-		skip = 1;
-		return 0;
-	}
-#endif /* CONFIG_KM_FPGA_FORCE_CONFIG */
-
-	if (check_boco2()) {
-		/* we have a BOCO2, this has to be triggered here */
-
-		/* make sure the FPGA_can access the EEPROM */
-		ret = boco_clear_bits(SPI_REG, CFG_EEPROM);
-		if (ret)
-			return ret;
-
-		/* trigger the config start */
-		ret = boco_clear_bits(SPI_REG, FPGA_PROG | FPGA_INIT_B);
-		if (ret)
-			return ret;
-
-		/* small delay for the pulse */
-		udelay(10);
-
-		/* up signal for pulse end */
-		ret = boco_set_bits(SPI_REG, FPGA_PROG);
-		if (ret)
-			return ret;
-
-		/* finally, raise INIT_B to remove the config delay */
-		ret = boco_set_bits(SPI_REG, FPGA_INIT_B);
-		if (ret)
-			return ret;
-
-	} else {
-		/* we do it the old way, with the gpio pin */
-		kw_gpio_set_valid(KM_XLX_PROGRAM_B_PIN, 1);
-		kw_gpio_direction_output(KM_XLX_PROGRAM_B_PIN, 0);
-		/* small delay for the pulse */
-		udelay(10);
-		kw_gpio_direction_input(KM_XLX_PROGRAM_B_PIN);
-	}
-
-	return 0;
-}
-
-int wait_for_fpga_config(void)
-{
-	int ret = 0;
-	u8 spictrl;
-	u32 timeout = 20000;
-
-	if (skip)
-		return 0;
-
-	if (!check_boco2()) {
-		/* we do not have BOCO2, this is not really used */
-		return 0;
-	}
-
-	printf("PCIe FPGA config:");
-	do {
-		ret = i2c_read(BOCO_ADDR, SPI_REG, 1, &spictrl, 1);
-		if (ret) {
-			printf("%s: error reading the BOCO spictrl !!\n",
-			       __func__);
-			return ret;
-		}
-		if (timeout-- == 0) {
-			printf(" FPGA_DONE timeout\n");
-			return -EFAULT;
-		}
-		udelay(10);
-	} while (!(spictrl & FPGA_DONE));
-
-	printf(" done\n");
-
-	return 0;
-}
-
-#if defined(CONFIG_KM_FPGA_NO_RESET)
-int fpga_reset(void)
-{
-	/* no dedicated reset pin for FPGA */
-	return 0;
-}
-#else
-
-#define PRST1		0x4
-#define PCIE_RST	0x10
-#define TRAFFIC_RST	0x04
-
-int fpga_reset(void)
-{
-	int ret = 0;
-	u8 resets;
-
-	if (!check_boco2()) {
-		/* we do not have BOCO2, this is not really used */
-		return 0;
-	}
-
-	/* if we have skipped, we only want to reset the PCIe part */
-	resets = skip ? PCIE_RST : PCIE_RST | TRAFFIC_RST;
-
-	ret = boco_clear_bits(PRST1, resets);
-	if (ret)
-		return ret;
-
-	/* small delay for the pulse */
-	udelay(10);
-
-	ret = boco_set_bits(PRST1, resets);
-	if (ret)
-		return ret;
-
-	return 0;
-}
-#endif
-
-/* the FPGA was configured, we configure the BOCO2 so that the EEPROM
- * is available from the Bobcat SPI bus
- */
-int toggle_eeprom_spi_bus(void)
-{
-	int ret = 0;
-
-	if (!check_boco2()) {
-		/* we do not have BOCO2, this is not really used */
-		return 0;
-	}
-
-	ret = boco_set_bits(SPI_REG, CFG_EEPROM);
-	if (ret)
-		return ret;
-
-	return 0;
-}
diff --git a/board/keymile/km_arm/km_arm.c b/board/keymile/km_arm/km_arm.c
deleted file mode 100644
index e9af090..0000000
--- a/board/keymile/km_arm/km_arm.c
+++ /dev/null
@@ -1,520 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * (C) Copyright 2009
- * Marvell Semiconductor <www.marvell.com>
- * Prafulla Wadaskar <prafulla@marvell.com>
- *
- * (C) Copyright 2009
- * Stefan Roese, DENX Software Engineering, sr@denx.de.
- *
- * (C) Copyright 2010
- * Heiko Schocher, DENX Software Engineering, hs@denx.de.
- */
-
-#include <common.h>
-#include <env.h>
-#include <i2c.h>
-#include <init.h>
-#include <nand.h>
-#include <net.h>
-#include <netdev.h>
-#include <miiphy.h>
-#include <spi.h>
-#include <asm/global_data.h>
-#include <asm/io.h>
-#include <asm/arch/cpu.h>
-#include <asm/arch/soc.h>
-#include <asm/arch/mpp.h>
-
-#include "../common/common.h"
-
-DECLARE_GLOBAL_DATA_PTR;
-
-/*
- * BOCO FPGA definitions
- */
-#define BOCO		0x10
-#define REG_CTRL_H		0x02
-#define MASK_WRL_UNITRUN	0x01
-#define MASK_RBX_PGY_PRESENT	0x40
-#define REG_IRQ_CIRQ2		0x2d
-#define MASK_RBI_DEFECT_16	0x01
-
-/*
- * PHY registers definitions
- */
-#define PHY_MARVELL_OUI					0x5043
-#define PHY_MARVELL_88E1118_MODEL			0x0022
-#define PHY_MARVELL_88E1118R_MODEL			0x0024
-
-#define PHY_MARVELL_PAGE_REG				0x0016
-#define PHY_MARVELL_DEFAULT_PAGE			0x0000
-
-#define PHY_MARVELL_88E1118R_LED_CTRL_PAGE		0x0003
-#define PHY_MARVELL_88E1118R_LED_CTRL_REG		0x0010
-
-#define PHY_MARVELL_88E1118R_LED_CTRL_RESERVED		0x1000
-#define PHY_MARVELL_88E1118R_LED_CTRL_LED0_1000MB	(0x7 << 0)
-#define PHY_MARVELL_88E1118R_LED_CTRL_LED1_ACT		(0x3 << 4)
-#define PHY_MARVELL_88E1118R_LED_CTRL_LED2_LINK		(0x0 << 8)
-
-/* I/O pin to erase flash RGPP09 = MPP43 */
-#define KM_FLASH_ERASE_ENABLE	43
-
-/* Multi-Purpose Pins Functionality configuration */
-static const u32 kwmpp_config[] = {
-	MPP0_NF_IO2,
-	MPP1_NF_IO3,
-	MPP2_NF_IO4,
-	MPP3_NF_IO5,
-	MPP4_NF_IO6,
-	MPP5_NF_IO7,
-	MPP6_SYSRST_OUTn,
-	MPP7_PEX_RST_OUTn,
-#if defined(CONFIG_SYS_I2C_SOFT)
-	MPP8_GPIO,		/* SDA */
-	MPP9_GPIO,		/* SCL */
-#endif
-	MPP10_UART0_TXD,
-	MPP11_UART0_RXD,
-	MPP12_GPO,		/* Reserved */
-	MPP13_UART1_TXD,
-	MPP14_UART1_RXD,
-	MPP15_GPIO,		/* Not used */
-	MPP16_GPIO,		/* Not used */
-	MPP17_GPIO,		/* Reserved */
-	MPP18_NF_IO0,
-	MPP19_NF_IO1,
-	MPP20_GPIO,
-	MPP21_GPIO,
-	MPP22_GPIO,
-	MPP23_GPIO,
-	MPP24_GPIO,
-	MPP25_GPIO,
-	MPP26_GPIO,
-	MPP27_GPIO,
-	MPP28_GPIO,
-	MPP29_GPIO,
-	MPP30_GPIO,
-	MPP31_GPIO,
-	MPP32_GPIO,
-	MPP33_GPIO,
-	MPP34_GPIO,		/* CDL1 (input) */
-	MPP35_GPIO,		/* CDL2 (input) */
-	MPP36_GPIO,		/* MAIN_IRQ (input) */
-	MPP37_GPIO,		/* BOARD_LED */
-	MPP38_GPIO,		/* Piggy3 LED[1] */
-	MPP39_GPIO,		/* Piggy3 LED[2] */
-	MPP40_GPIO,		/* Piggy3 LED[3] */
-	MPP41_GPIO,		/* Piggy3 LED[4] */
-	MPP42_GPIO,		/* Piggy3 LED[5] */
-	MPP43_GPIO,		/* Piggy3 LED[6] */
-	MPP44_GPIO,		/* Piggy3 LED[7], BIST_EN_L */
-	MPP45_GPIO,		/* Piggy3 LED[8] */
-	MPP46_GPIO,		/* Reserved */
-	MPP47_GPIO,		/* Reserved */
-	MPP48_GPIO,		/* Reserved */
-	MPP49_GPIO,		/* SW_INTOUTn */
-	0
-};
-
-static uchar ivm_content[CONFIG_SYS_IVM_EEPROM_MAX_LEN];
-
-#if (defined(CONFIG_KM_PIGGY4_88E6061)|defined(CONFIG_KM_PIGGY4_88E6352))
-/*
- * All boards with PIGGY4 connected via a simple switch have ethernet always
- * present.
- */
-int ethernet_present(void)
-{
-	return 1;
-}
-#else
-int ethernet_present(void)
-{
-	uchar	buf;
-	int	ret = 0;
-
-	if (i2c_read(BOCO, REG_CTRL_H, 1, &buf, 1) != 0) {
-		printf("%s: Error reading Boco\n", __func__);
-		return -1;
-	}
-	if ((buf & MASK_RBX_PGY_PRESENT) == MASK_RBX_PGY_PRESENT)
-		ret = 1;
-
-	return ret;
-}
-#endif
-
-static int initialize_unit_leds(void)
-{
-	/*
-	 * Init the unit LEDs per default they all are
-	 * ok apart from bootstat
-	 */
-	uchar buf;
-
-	if (i2c_read(BOCO, REG_CTRL_H, 1, &buf, 1) != 0) {
-		printf("%s: Error reading Boco\n", __func__);
-		return -1;
-	}
-	buf |= MASK_WRL_UNITRUN;
-	if (i2c_write(BOCO, REG_CTRL_H, 1, &buf, 1) != 0) {
-		printf("%s: Error writing Boco\n", __func__);
-		return -1;
-	}
-	return 0;
-}
-
-static void set_bootcount_addr(void)
-{
-	uchar buf[32];
-	unsigned int bootcountaddr;
-
-	bootcountaddr = gd->ram_size - BOOTCOUNT_ADDR;
-	sprintf((char *)buf, "0x%x", bootcountaddr);
-	env_set("bootcountaddr", (char *)buf);
-}
-
-int misc_init_r(void)
-{
-	ivm_read_eeprom(ivm_content, CONFIG_SYS_IVM_EEPROM_MAX_LEN,
-			CONFIG_PIGGY_MAC_ADDRESS_OFFSET);
-
-	initialize_unit_leds();
-	set_km_env();
-	set_bootcount_addr();
-	return 0;
-}
-
-int board_early_init_f(void)
-{
-#if defined(CONFIG_SYS_I2C_SOFT)
-	u32 tmp;
-
-	/* set the 2 bitbang i2c pins as output gpios */
-	tmp = readl(MVEBU_GPIO0_BASE + 4);
-	writel(tmp & (~KM_KIRKWOOD_SOFT_I2C_GPIOS), MVEBU_GPIO0_BASE + 4);
-#endif
-	/* adjust SDRAM size for bank 0 */
-	mvebu_sdram_size_adjust(0);
-	kirkwood_mpp_conf(kwmpp_config, NULL);
-	return 0;
-}
-
-int board_init(void)
-{
-	/* address of boot parameters */
-	gd->bd->bi_boot_params = mvebu_sdram_bar(0) + 0x100;
-
-	/*
-	 * The KM_FLASH_GPIO_PIN switches between using a
-	 * NAND or a SPI FLASH. Set this pin on start
-	 * to NAND mode.
-	 */
-	kw_gpio_set_valid(KM_FLASH_GPIO_PIN, 1);
-	kw_gpio_direction_output(KM_FLASH_GPIO_PIN, 1);
-
-#if defined(CONFIG_SYS_I2C_SOFT)
-	/*
-	 * Reinit the GPIO for I2C Bitbang driver so that the now
-	 * available gpio framework is consistent. The calls to
-	 * direction output in are not necessary, they are already done in
-	 * board_early_init_f
-	 */
-	kw_gpio_set_valid(KM_KIRKWOOD_SDA_PIN, 1);
-	kw_gpio_set_valid(KM_KIRKWOOD_SCL_PIN, 1);
-#endif
-
-#if defined(CONFIG_SYS_EEPROM_WREN)
-	kw_gpio_set_valid(KM_KIRKWOOD_ENV_WP, 38);
-	kw_gpio_direction_output(KM_KIRKWOOD_ENV_WP, 1);
-#endif
-
-#if defined(CONFIG_KM_FPGA_CONFIG)
-	trigger_fpga_config();
-#endif
-
-	return 0;
-}
-
-int board_late_init(void)
-{
-#if defined(CONFIG_KM_COGE5UN)
-	u8 dip_switch = kw_gpio_get_value(KM_FLASH_ERASE_ENABLE);
-
-	/* if pin 1 do full erase */
-	if (dip_switch != 0) {
-		/* start bootloader */
-		puts("DIP:   Enabled\n");
-		env_set("actual_bank", "0");
-	}
-#endif
-
-#if defined(CONFIG_KM_FPGA_CONFIG)
-	wait_for_fpga_config();
-	fpga_reset();
-	toggle_eeprom_spi_bus();
-#endif
-	return 0;
-}
-
-static const u32 spi_mpp_config[] = {
-	MPP1_SPI_MOSI,
-	MPP2_SPI_SCK,
-	MPP3_SPI_MISO,
-	0
-};
-
-static u32 spi_mpp_backup[4];
-
-int mvebu_board_spi_claim_bus(struct udevice *dev)
-{
-	spi_mpp_backup[3] = 0;
-
-	/* set new spi mpp config and save current one */
-	kirkwood_mpp_conf(spi_mpp_config, spi_mpp_backup);
-
-	kw_gpio_set_value(KM_FLASH_GPIO_PIN, 0);
-
-	return 0;
-}
-
-int mvebu_board_spi_release_bus(struct udevice *dev)
-{
-	/* restore saved mpp config */
-	kirkwood_mpp_conf(spi_mpp_backup, NULL);
-
-	kw_gpio_set_value(KM_FLASH_GPIO_PIN, 1);
-
-	return 0;
-}
-
-#if (defined(CONFIG_KM_PIGGY4_88E6061))
-
-#define	PHY_LED_SEL_REG		0x18
-#define PHY_LED0_LINK		(0x5)
-#define PHY_LED1_ACT		(0x8 << 4)
-#define PHY_LED2_INT		(0xe << 8)
-#define	PHY_SPEC_CTRL_REG	0x1c
-#define PHY_RGMII_CLK_STABLE	(0x1 << 10)
-#define PHY_CLSA		(0x1 << 1)
-
-/* Configure and enable MV88E3018 PHY */
-void reset_phy(void)
-{
-	char *name = "egiga0";
-	unsigned short reg;
-
-	if (miiphy_set_current_dev(name))
-		return;
-
-	/* RGMII clk transition on data stable */
-	if (miiphy_read(name, CONFIG_PHY_BASE_ADR, PHY_SPEC_CTRL_REG, &reg))
-		printf("Error reading PHY spec ctrl reg\n");
-	if (miiphy_write(name, CONFIG_PHY_BASE_ADR, PHY_SPEC_CTRL_REG,
-			 reg | PHY_RGMII_CLK_STABLE | PHY_CLSA))
-		printf("Error writing PHY spec ctrl reg\n");
-
-	/* leds setup */
-	if (miiphy_write(name, CONFIG_PHY_BASE_ADR, PHY_LED_SEL_REG,
-			 PHY_LED0_LINK | PHY_LED1_ACT | PHY_LED2_INT))
-		printf("Error writing PHY LED reg\n");
-
-	/* reset the phy */
-	miiphy_reset(name, CONFIG_PHY_BASE_ADR);
-}
-#elif defined(CONFIG_KM_PIGGY4_88E6352)
-
-#include <mv88e6352.h>
-
-#if defined(CONFIG_KM_NUSA)
-struct mv88e_sw_reg extsw_conf[] = {
-	/*
-	 * port 0, PIGGY4, autoneg
-	 * first the fix for the 1000Mbits Autoneg, this is from
-	 * a Marvell errata, the regs are undocumented
-	 */
-	{ PHY(0), PHY_PAGE, AN1000FIX_PAGE },
-	{ PHY(0), PHY_STATUS, AN1000FIX },
-	{ PHY(0), PHY_PAGE, 0 },
-	/* now the real port and phy configuration */
-	{ PORT(0), PORT_PHY, NO_SPEED_FOR },
-	{ PORT(0), PORT_CTRL, FORWARDING | EGRS_FLD_ALL },
-	{ PHY(0), PHY_1000_CTRL, NO_ADV },
-	{ PHY(0), PHY_SPEC_CTRL, AUTO_MDIX_EN },
-	{ PHY(0), PHY_CTRL, PHY_100_MBPS | AUTONEG_EN | AUTONEG_RST |
-		FULL_DUPLEX },
-	/* port 1, unused */
-	{ PORT(1), PORT_CTRL, PORT_DIS },
-	{ PHY(1), PHY_CTRL, PHY_PWR_DOWN },
-	{ PHY(1), PHY_SPEC_CTRL, SPEC_PWR_DOWN },
-	/* port 2, unused */
-	{ PORT(2), PORT_CTRL, PORT_DIS },
-	{ PHY(2), PHY_CTRL, PHY_PWR_DOWN },
-	{ PHY(2), PHY_SPEC_CTRL, SPEC_PWR_DOWN },
-	/* port 3, unused */
-	{ PORT(3), PORT_CTRL, PORT_DIS },
-	{ PHY(3), PHY_CTRL, PHY_PWR_DOWN },
-	{ PHY(3), PHY_SPEC_CTRL, SPEC_PWR_DOWN },
-	/* port 4, ICNEV, SerDes, SGMII */
-	{ PORT(4), PORT_STATUS, NO_PHY_DETECT },
-	{ PORT(4), PORT_PHY, SPEED_1000_FOR },
-	{ PORT(4), PORT_CTRL, FORWARDING | EGRS_FLD_ALL },
-	{ PHY(4), PHY_CTRL, PHY_PWR_DOWN },
-	{ PHY(4), PHY_SPEC_CTRL, SPEC_PWR_DOWN },
-	/* port 5, CPU_RGMII */
-	{ PORT(5), PORT_PHY, RX_RGMII_TIM | TX_RGMII_TIM | FLOW_CTRL_EN |
-		FLOW_CTRL_FOR | LINK_VAL | LINK_FOR | FULL_DPX |
-		FULL_DPX_FOR | SPEED_1000_FOR },
-	{ PORT(5), PORT_CTRL, FORWARDING | EGRS_FLD_ALL },
-	/* port 6, unused, this port has no phy */
-	{ PORT(6), PORT_CTRL, PORT_DIS },
-};
-#else
-struct mv88e_sw_reg extsw_conf[] = {};
-#endif
-
-void reset_phy(void)
-{
-#if defined(CONFIG_KM_MVEXTSW_ADDR)
-	char *name = "egiga0";
-
-	if (miiphy_set_current_dev(name))
-		return;
-
-	mv88e_sw_program(name, CONFIG_KM_MVEXTSW_ADDR, extsw_conf,
-		ARRAY_SIZE(extsw_conf));
-	mv88e_sw_reset(name, CONFIG_KM_MVEXTSW_ADDR);
-#endif
-}
-
-#else
-/* Configure and enable MV88E1118 PHY on the piggy*/
-void reset_phy(void)
-{
-	unsigned int oui;
-	unsigned char model, rev;
-
-	char *name = "egiga0";
-
-	if (miiphy_set_current_dev(name))
-		return;
-
-	/* reset the phy */
-	miiphy_reset(name, CONFIG_PHY_BASE_ADR);
-
-	/* get PHY model */
-	if (miiphy_info(name, CONFIG_PHY_BASE_ADR, &oui, &model, &rev))
-		return;
-
-	/* check for Marvell 88E1118R Gigabit PHY (PIGGY3) */
-	if (oui == PHY_MARVELL_OUI &&
-	    model == PHY_MARVELL_88E1118R_MODEL) {
-		/* set page register to 3 */
-		if (miiphy_write(name, CONFIG_PHY_BASE_ADR,
-				 PHY_MARVELL_PAGE_REG,
-				 PHY_MARVELL_88E1118R_LED_CTRL_PAGE))
-			printf("Error writing PHY page reg\n");
-
-		/*
-		 * leds setup as printed on PCB:
-		 * LED2 (Link): 0x0 (On Link, Off No Link)
-		 * LED1 (Activity): 0x3 (On Activity, Off No Activity)
-		 * LED0 (Speed): 0x7 (On 1000 MBits, Off Else)
-		 */
-		if (miiphy_write(name, CONFIG_PHY_BASE_ADR,
-				 PHY_MARVELL_88E1118R_LED_CTRL_REG,
-				 PHY_MARVELL_88E1118R_LED_CTRL_RESERVED |
-				 PHY_MARVELL_88E1118R_LED_CTRL_LED0_1000MB |
-				 PHY_MARVELL_88E1118R_LED_CTRL_LED1_ACT |
-				 PHY_MARVELL_88E1118R_LED_CTRL_LED2_LINK))
-			printf("Error writing PHY LED reg\n");
-
-		/* set page register back to 0 */
-		if (miiphy_write(name, CONFIG_PHY_BASE_ADR,
-				 PHY_MARVELL_PAGE_REG,
-				 PHY_MARVELL_DEFAULT_PAGE))
-			printf("Error writing PHY page reg\n");
-	}
-}
-#endif
-
-#if defined(CONFIG_HUSH_INIT_VAR)
-int hush_init_var(void)
-{
-	ivm_analyze_eeprom(ivm_content, CONFIG_SYS_IVM_EEPROM_MAX_LEN);
-	return 0;
-}
-#endif
-
-#if defined(CONFIG_SYS_I2C_SOFT)
-void set_sda(int state)
-{
-	I2C_ACTIVE;
-	I2C_SDA(state);
-}
-
-void set_scl(int state)
-{
-	I2C_SCL(state);
-}
-
-int get_sda(void)
-{
-	I2C_TRISTATE;
-	return I2C_READ;
-}
-
-int get_scl(void)
-{
-	return kw_gpio_get_value(KM_KIRKWOOD_SCL_PIN) ? 1 : 0;
-}
-#endif
-
-#if defined(CONFIG_POST)
-
-#define KM_POST_EN_L	44
-#define POST_WORD_OFF	8
-
-int post_hotkeys_pressed(void)
-{
-	if (IS_ENABLED(CONFIG_KM_COGE5UN))
-		return kw_gpio_get_value(KM_POST_EN_L);
-	else
-		return !kw_gpio_get_value(KM_POST_EN_L);
-}
-
-ulong post_word_load(void)
-{
-	void *addr = (void *)(gd->ram_size - BOOTCOUNT_ADDR + POST_WORD_OFF);
-
-	return in_le32(addr);
-
-}
-void post_word_store(ulong value)
-{
-	void *addr = (void *)(gd->ram_size - BOOTCOUNT_ADDR + POST_WORD_OFF);
-
-	out_le32(addr, value);
-}
-
-int arch_memory_test_prepare(u32 *vstart, u32 *size, phys_addr_t *phys_offset)
-{
-	*vstart = CONFIG_SYS_SDRAM_BASE;
-
-	/* we go up to relocation plus a 1 MB margin */
-	*size = CONFIG_SYS_TEXT_BASE - (1 << 20);
-
-	return 0;
-}
-#endif
-
-#if defined(CONFIG_SYS_EEPROM_WREN)
-int eeprom_write_enable(unsigned int dev_addr, int state)
-{
-	kw_gpio_set_value(KM_KIRKWOOD_ENV_WP, !state);
-
-	return !kw_gpio_get_value(KM_KIRKWOOD_ENV_WP);
-}
-#endif
diff --git a/board/keymile/km_arm/kwbimage-memphis.cfg b/board/keymile/km_arm/kwbimage-memphis.cfg
deleted file mode 100644
index d850e10..0000000
--- a/board/keymile/km_arm/kwbimage-memphis.cfg
+++ /dev/null
@@ -1,179 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0+
-#
-# (C) Copyright 2010
-# Heiko Schocher, DENX Software Engineering, hs@denx.de.
-#
-# (C) Copyright 2011
-# Valentin Longchamp, Keymile AG, valentin.longchamp@keymile.com
-# Refer doc/README.kwbimage for more details about how-to configure
-# and create kirkwood boot image
-#
-
-# Boot Media configurations
-BOOT_FROM	spi	# Boot from SPI flash
-
-DATA 0xFFD10000 0x01112222	# MPP Control 0 Register
-# bit 3-0:   MPPSel0	2, NF_IO[2]
-# bit 7-4:   MPPSel1	2, NF_IO[3]
-# bit 12-8:  MPPSel2	2, NF_IO[4]
-# bit 15-12: MPPSel3	2, NF_IO[5]
-# bit 19-16: MPPSel4	1, NF_IO[6]
-# bit 23-20: MPPSel5	1, NF_IO[7]
-# bit 27-24: MPPSel6	1, SYSRST_O
-# bit 31-28: MPPSel7	0, GPO[7]
-
-DATA 0xFFD10004 0x03303300
-
-DATA 0xFFD10008 0x00001100	# MPP Control 2 Register
-# bit 3-0:   MPPSel16	0, GPIO[16]
-# bit 7-4:   MPPSel17	0, GPIO[17]
-# bit 12-8:  MPPSel18	1, NF_IO[0]
-# bit 15-12: MPPSel19	1, NF_IO[1]
-# bit 19-16: MPPSel20	0, GPIO[20]
-# bit 23-20: MPPSel21	0, GPIO[21]
-# bit 27-24: MPPSel22	0, GPIO[22]
-# bit 31-28: MPPSel23	0, GPIO[23]
-
-DATA 0xFFD100E0 0x1B1B1B1B	# IO Configuration 0 Register
-DATA 0xFFD20134 0x66666666	# L2 RAM Timing 0 Register
-DATA 0xFFD20138 0x66666666	# L2 RAM Timing 1 Register
-
-# NOTE: Don't write on 0x20148 , 0x2014c and 0x20154, leave them untouched!
-# If not it could cause KW Exceptions during boot in Fast Corners/High Voltage
-
-#Dram initalization
-DATA 0xFFD01400 0x430004E0	# SDRAM Configuration Register
-# bit13-0:  0x4E0 (DDR2 clks refresh rate)
-# bit23-14: zero
-# bit24: 1= enable exit self refresh mode on DDR access
-# bit25: 1 required
-# bit29-26: zero
-# bit31-30: 01
-
-DATA 0xFFD01404 0x38543000	# DDR Controller Control Low
-# bit 3-0:  0 reserved
-# bit 4:    0=addr/cmd in smame cycle
-# bit 5:    0=clk is driven during self refresh, we don't care for APX
-# bit 6:    0=use recommended falling edge of clk for addr/cmd
-# bit14:    0=input buffer always powered up
-# bit18:    1=cpu lock transaction enabled
-# bit23-20: 5=recommended value for CL=4 and STARTBURST_DEL disabled bit31=0
-# bit27-24: 8= CL+4, STARTBURST sample stages, for freqs 400MHz, unbuffered DIMM
-# bit30-28: 3 required
-# bit31:    0=no additional STARTBURST delay
-
-DATA 0xFFD01408 0x2302433E	# DDR Timing (Low) (active cycles value +1)
-# bit3-0:   TRAS lsbs
-# bit7-4:   TRCD
-# bit11- 8: TRP
-# bit15-12: TWR
-# bit19-16: TWTR
-# bit20:    TRAS msb
-# bit23-21: 0x0
-# bit27-24: TRRD
-# bit31-28: TRTP
-
-DATA 0xFFD0140C 0x00000A3E	#  DDR Timing (High)
-# bit6-0:   TRFC
-# bit8-7:   TR2R
-# bit10-9:  TR2W
-# bit12-11: TW2W
-# bit31-13: zero required
-
-DATA 0xFFD01410 0x00000001	#  DDR Address Control
-# bit1-0:   01, Cs0width=x16
-# bit3-2:   00, Cs0size=2Gb
-# bit5-4:   00, Cs2width=nonexistent
-# bit7-6:   00, Cs1size =nonexistent
-# bit9-8:   00, Cs2width=nonexistent
-# bit11-10: 00, Cs2size =nonexistent
-# bit13-12: 00, Cs3width=nonexistent
-# bit15-14: 00, Cs3size =nonexistent
-# bit16:    0,  Cs0AddrSel
-# bit17:    0,  Cs1AddrSel
-# bit18:    0,  Cs2AddrSel
-# bit19:    0,  Cs3AddrSel
-# bit31-20: 0 required
-
-DATA 0xFFD01414 0x00000000	#  DDR Open Pages Control
-# bit0:    0,  OpenPage enabled
-# bit31-1: 0 required
-
-DATA 0xFFD01418 0x00000000	#  DDR Operation
-# bit3-0:   0x0, DDR cmd
-# bit31-4:  0 required
-
-DATA 0xFFD0141C 0x00000652	#  DDR Mode
-DATA 0xFFD01420 0x00000006	#  DDR Extended Mode
-# bit0:    0,  DDR DLL enabled
-# bit1:    1,  DDR drive strenght reduced
-# bit2:    1,  DDR ODT control lsd disabled
-# bit5-3:  000, required
-# bit6:    0,  DDR ODT control msb disabled
-# bit9-7:  000, required
-# bit10:   0,  differential DQS enabled
-# bit11:   0, required
-# bit12:   0, DDR output buffer enabled
-# bit31-13: 0 required
-
-DATA 0xFFD01424 0x0000F17F	#  DDR Controller Control High
-# bit2-0:  111, required
-# bit3  :  1  , MBUS Burst Chop disabled
-# bit6-4:  111, required
-# bit7  :  0
-# bit8  :  1  , add a sample stage
-# bit9  :  0  , no half clock cycle addition to dataout
-# bit10 :  0  , 1/4 clock cycle skew enabled for addr/ctl signals
-# bit11 :  0  , 1/4 clock cycle skew disabled for write mesh
-# bit15-12: 1111 required
-# bit31-16: 0    required
-
-DATA 0xFFD01428 0x00084520	# DDR2 SDRAM Timing Low
-# bit3-0  : 0000, required
-# bit7-4  : 0010, M_ODT assertion 2 cycles after read
-# bit11-8 : 0101, M_ODT de-assertion 5 cycles after read
-# bit15-12: 0100, internal ODT assertion 4 cycles after read
-# bit19-16: 1000, internal ODT de-assertion 8 cycles after read
-# bit31-20: 0   , required
-
-DATA 0xFFD0147c 0x00008451	# DDR2 SDRAM Timing High
-# bit3-0  : 0001, M_ODT assertion same cycle as write
-# bit7-4  : 0101, M_ODT de-assertion x cycles after write
-# bit11-8 : 0100, internal ODT assertion x cycles after write
-# bit15-12: 1000, internal ODT de-assertion x cycles after write
-
-DATA 0xFFD01500 0x00000000	# CS[0]n Base address to 0x0
-DATA 0xFFD01504 0x0FFFFFF1	# CS[0]n Size
-# bit0:    1,  Window enabled
-# bit1:    0,  Write Protect disabled
-# bit3-2:  00, CS0 hit selected
-# bit23-4: ones, required
-# bit31-24: 0x0F, Size (i.e. 256MB)
-
-DATA 0xFFD0150C 0x00000000	# CS[1]n Size, window disabled
-DATA 0xFFD01514 0x00000000	# CS[2]n Size, window disabled
-DATA 0xFFD0151C 0x00000000	# CS[3]n Size, window disabled
-
-DATA 0xFFD01494 0x00010000	#  DDR ODT Control (Low)
-# bit3-0:  0, ODT0Rd, MODT[0] not asserted during read from DRAM CS0
-# bit19-16:1, ODT0Wr, MODT[0] asserted during write to DRAM CS0
-
-DATA 0xFFD01498 0x00000000	#  DDR ODT Control (High)
-# bit1-0:  00, ODT0 controlled by ODT Control (low) register above
-# bit3-2:  00, ODT1 controlled by register
-# bit31-4: zero, required
-
-DATA 0xFFD0149C 0x0000F801	# CPU ODT Control
-# bit3-0:  1, ODT0Rd, Internal ODT asserted during read from DRAM bank0
-# bit7-4:  0, ODT0Wr, Internal ODT not asserted during write to DRAM bank0
-# bit9-8:  0, ODTEn, controlled by ODT0Rd and ODT0Wr
-# bit11-10:2, DQ_ODTSel. ODT select turned on, 75 ohm
-# bit13-12:3, STARTBURST ODT buffer selected, 50 ohm
-# bit14   :1, STARTBURST ODT enabled
-# bit15   :1, Use ODT Block
-
-DATA 0xFFD01480 0x00000001	# DDR Initialization Control
-# bit0=1, enable DDR init upon this register write
-
-# End of Header extension
-DATA 0x0 0x0
diff --git a/board/keymile/km_arm/kwbimage.cfg b/board/keymile/km_arm/kwbimage.cfg
deleted file mode 100644
index 6b62ce0..0000000
--- a/board/keymile/km_arm/kwbimage.cfg
+++ /dev/null
@@ -1,161 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0+
-#
-# (C) Copyright 2010
-# Heiko Schocher, DENX Software Engineering, hs@denx.de.
-# Refer doc/README.kwbimage for more details about how-to configure
-# and create kirkwood boot image
-#
-
-# Boot Media configurations
-BOOT_FROM	spi	# Boot from SPI flash
-
-DATA 0xFFD10000 0x01112222	# MPP Control 0 Register
-# bit 3-0:   MPPSel0	2, NF_IO[2]
-# bit 7-4:   MPPSel1	2, NF_IO[3]
-# bit 12-8:  MPPSel2	2, NF_IO[4]
-# bit 15-12: MPPSel3	2, NF_IO[5]
-# bit 19-16: MPPSel4	1, NF_IO[6]
-# bit 23-20: MPPSel5	1, NF_IO[7]
-# bit 27-24: MPPSel6	1, SYSRST_O
-# bit 31-28: MPPSel7	0, GPO[7]
-
-DATA 0xFFD10004 0x03303300
-
-DATA 0xFFD10008 0x00001100	# MPP Control 2 Register
-# bit 3-0:   MPPSel16	0, GPIO[16]
-# bit 7-4:   MPPSel17	0, GPIO[17]
-# bit 12-8:  MPPSel18	1, NF_IO[0]
-# bit 15-12: MPPSel19	1, NF_IO[1]
-# bit 19-16: MPPSel20	0, GPIO[20]
-# bit 23-20: MPPSel21	0, GPIO[21]
-# bit 27-24: MPPSel22	0, GPIO[22]
-# bit 31-28: MPPSel23	0, GPIO[23]
-
-DATA 0xFFD100E0 0x1B1B1B1B	# IO Configuration 0 Register
-DATA 0xFFD20134 0x66666666	# L2 RAM Timing 0 Register
-DATA 0xFFD20138 0x66666666	# L2 RAM Timing 1 Register
-
-# NOTE: Don't write on 0x20148 , 0x2014c and 0x20154, leave them untouched!
-# If not it could cause KW Exceptions during boot in Fast Corners/High Voltage
-
-#Dram initalization
-DATA 0xFFD01400 0x43000400	# SDRAM Configuration Register
-# bit13-0:  0x400 (DDR2 clks refresh rate)
-# bit23-14: zero
-# bit24: 1= enable exit self refresh mode on DDR access
-# bit25: 1 required
-# bit29-26: zero
-# bit31-30: 01
-
-DATA 0xFFD01404 0x39543000	# DDR Controller Control Low
-# bit 3-0:  0 reserved
-# bit 4:    0=addr/cmd in smame cycle
-# bit 5:    0=clk is driven during self refresh, we don't care for APX
-# bit 6:    0=use recommended falling edge of clk for addr/cmd
-# bit14:    0=input buffer always powered up
-# bit18:    1=cpu lock transaction enabled
-# bit23-20: 3=recommended value for CL=3 and STARTBURST_DEL disabled bit31=0
-# bit27-24: 6= CL+3, STARTBURST sample stages, for freqs 400MHz, unbuffered DIMM
-# bit30-28: 3 required
-# bit31:    0=no additional STARTBURST delay
-
-DATA 0xFFD01408 0x34136552	# DDR Timing (Low) (active cycles value +1)
-# bit3-0:   TRAS lsbs
-# bit7-4:   TRCD
-# bit11- 8: TRP
-# bit15-12: TWR
-# bit19-16: TWTR
-# bit20:    TRAS msb
-# bit23-21: 0x0
-# bit27-24: TRRD
-# bit31-28: TRTP
-
-DATA 0xFFD0140C 0x00000033	#  DDR Timing (High)
-# bit6-0:   TRFC
-# bit8-7:   TR2R
-# bit10-9:  TR2W
-# bit12-11: TW2W
-# bit31-13: zero required
-
-DATA 0xFFD01410 0x0000000D	#  DDR Address Control
-# bit1-0:   01, Cs0width=x16
-# bit3-2:   11, Cs0size=1Gb
-# bit5-4:   00, Cs2width=nonexistent
-# bit7-6:   00, Cs1size =nonexistent
-# bit9-8:   00, Cs2width=nonexistent
-# bit11-10: 00, Cs2size =nonexistent
-# bit13-12: 00, Cs3width=nonexistent
-# bit15-14: 00, Cs3size =nonexistent
-# bit16:    0,  Cs0AddrSel
-# bit17:    0,  Cs1AddrSel
-# bit18:    0,  Cs2AddrSel
-# bit19:    0,  Cs3AddrSel
-# bit31-20: 0 required
-
-DATA 0xFFD01414 0x00000000	#  DDR Open Pages Control
-# bit0:    0,  OpenPage enabled
-# bit31-1: 0 required
-
-DATA 0xFFD01418 0x00000000	#  DDR Operation
-# bit3-0:   0x0, DDR cmd
-# bit31-4:  0 required
-
-DATA 0xFFD0141C 0x00000652	#  DDR Mode
-DATA 0xFFD01420 0x00000044	#  DDR Extended Mode
-# bit0:    0,  DDR DLL enabled
-# bit1:    0,  DDR drive strenght normal
-# bit2:    1,  DDR ODT control lsd disabled
-# bit5-3:  000, required
-# bit6:    1,  DDR ODT control msb, enabled
-# bit9-7:  000, required
-# bit10:   0,  differential DQS enabled
-# bit11:   0, required
-# bit12:   0, DDR output buffer enabled
-# bit31-13: 0 required
-
-DATA 0xFFD01424 0x0000F07F	#  DDR Controller Control High
-# bit2-0:  111, required
-# bit3  :  1  , MBUS Burst Chop disabled
-# bit6-4:  111, required
-# bit7  :  0
-# bit8  :  0  , no sample stage
-# bit9  :  0  , no half clock cycle addition to dataout
-# bit10 :  0  , 1/4 clock cycle skew enabled for addr/ctl signals
-# bit11 :  0  , 1/4 clock cycle skew disabled for write mesh
-# bit15-12: 1111 required
-# bit31-16: 0    required
-DATA 0xFFD01428 0x00074510
-DATA 0xFFD0147c 0x00007451
-
-DATA 0xFFD01500 0x00000000	# CS[0]n Base address to 0x0
-DATA 0xFFD01504 0x07FFFFF1	# CS[0]n Size
-# bit0:    1,  Window enabled
-# bit1:    0,  Write Protect disabled
-# bit3-2:  00, CS0 hit selected
-# bit23-4: ones, required
-# bit31-24: 0x07, Size (i.e. 128MB)
-
-DATA 0xFFD0150C 0x00000000	# CS[1]n Size, window disabled
-DATA 0xFFD01514 0x00000000	# CS[2]n Size, window disabled
-DATA 0xFFD0151C 0x00000000	# CS[3]n Size, window disabled
-
-DATA 0xFFD01494 0x00010001	#  DDR ODT Control (Low)
-# bit3-0:  0, ODT0Rd, MODT[0] asserted during read from DRAM CS0
-# bit19-16:0, ODT0Wr, MODT[0] asserted during write to DRAM CS0
-
-DATA 0xFFD01498 0x00000000	#  DDR ODT Control (High)
-# bit1-0:  00, ODT0 controlled by ODT Control (low) register above
-# bit3-2:  00, ODT1 controlled by register
-# bit31-4: zero, required
-
-DATA 0xFFD0149C 0x0000FC11	# CPU ODT Control
-# bit3-0:  F, ODT0Rd, Internal ODT asserted during read from DRAM bank0
-# bit7-4:  0, ODT0Wr, Internal ODT asserted during write to DRAM bank0
-# bit9-8:  1, ODTEn, never active
-# bit11-10:2, DQ_ODTSel. ODT select turned on, 75 ohm
-
-DATA 0xFFD01480 0x00000001	# DDR Initialization Control
-# bit0=1, enable DDR init upon this register write
-
-# End of Header extension
-DATA 0x0 0x0
diff --git a/board/keymile/km_arm/kwbimage_128M16_1.cfg b/board/keymile/km_arm/kwbimage_128M16_1.cfg
deleted file mode 100644
index e30c0fe..0000000
--- a/board/keymile/km_arm/kwbimage_128M16_1.cfg
+++ /dev/null
@@ -1,257 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0+
-#
-# (C) Copyright 2010
-# Heiko Schocher, DENX Software Engineering, hs@denx.de.
-#
-# (C) Copyright 2012
-# Valentin Longchamp, Keymile AG, valentin.longchamp@keymile.com
-# Stefan Bigler, Keymile AG, stefan.bigler@keymile.com
-#
-# (C) Copyright 2012
-#
-# Refer doc/README.kwbimage for more details about how-to configure
-# and create kirkwood boot image
-#
-
-# Boot Media configurations
-BOOT_FROM	spi	# Boot from SPI flash
-
-DATA 0xFFD10000 0x01112222	# MPP Control 0 Register
-# bit 3-0:   2, MPPSel0  SPI_CSn  (1=NF_IO[2])
-# bit 7-4:   2, MPPSel1  SPI_SI   (1=NF_IO[3])
-# bit 12-8:  2, MPPSel2  SPI_SCK  (1=NF_IO[4])
-# bit 15-12: 2, MPPSel3  SPI_SO   (1=NF_IO[5])
-# bit 19-16: 1, MPPSel4  NF_IO[6]
-# bit 23-20: 1, MPPSel5  NF_IO[7]
-# bit 27-24: 1, MPPSel6  SYSRST_O
-# bit 31-28: 0, MPPSel7  GPO[7]
-
-DATA 0xFFD10004 0x03303300	# MPP Control 1 Register
-# bit 3-0:   0, MPPSel8	 GPIO[8]
-# bit 7-4:   0, MPPSel9  GPIO[9]
-# bit 12-8:  3, MPPSel10 UA0_TXD
-# bit 15-12: 3, MPPSel11 UA0_RXD
-# bit 19-16: 0, MPPSel12 not connected
-# bit 23-20: 3, MPPSel13 UA1_TXD
-# bit 27-24: 3, MPPSel14 UA1_RXD
-# bit 31-28: 0, MPPSel15 GPIO[15]
-
-DATA 0xFFD10008 0x00001100	# MPP Control 2 Register
-# bit 3-0:   0, MPPSel16 GPIO[16]
-# bit 7-4:   0, MPPSel17 not connected
-# bit 12-8:  1, MPPSel18 NF_IO[0]
-# bit 15-12: 1, MPPSel19 NF_IO[1]
-# bit 19-16: 0, MPPSel20 GPIO[20]
-# bit 23-20: 0, MPPSel21 GPIO[21]
-# bit 27-24: 0, MPPSel22 GPIO[22]
-# bit 31-28: 0, MPPSel23 GPIO[23]
-
-# MPP Control 3-6 Register untouched (MPP24-49)
-
-DATA 0xFFD100E0 0x1B1B1B1B	# IO Configuration 0 Register
-# bit 2-0:   3, Reserved
-# bit 5-3:   3, Reserved
-# bit 6:     0, Reserved
-# bit 7:     0, RGMII-pads voltage = 3.3V
-# bit 10-8:  3, Reserved
-# bit 13-11: 3, Reserved
-# bit 14:    0, Reserved
-# bit 15:    0, MPP RGMII-pads voltage = 3.3V
-# bit 31-16  0x1B1B, Reserved
-
-DATA 0xFFD20134 0x66666666	# L2 RAM Timing 0 Register
-# bit 0-1:   2, Tag RAM RTC RAM0
-# bit 3-2:   1, Tag RAM WTC RAM0
-# bit 7-4:   6, Reserve
-# bit 9-8:   2, Valid RAM RTC RAM
-# bit 11-10: 1, Valid RAM WTC RAM
-# bit 13-12: 2, Dirty RAM RTC RAM
-# bit 15-14: 1, Dirty RAM WTC RAM
-# bit 17-16: 2, Data RAM RTC RAM0
-# bit 19-18: 1, Data RAM WTC RAM0
-# bit 21-20: 2, Data RAM RTC RAM1
-# bit 23-22: 1, Data RAM WTC RAM1
-# bit 25-24: 2, Data RAM RTC RAM2
-# bit 27-26: 1, Data RAM WTC RAM2
-# bit 29-28: 2, Data RAM RTC RAM3
-# bit 31-30: 1, Data RAM WTC RAM4
-
-DATA 0xFFD20138 0x66666666	# L2 RAM Timing 1 Register
-# bit 15-0:  ???, Reserve
-# bit 17-16: 2, ECC RAM RTC RAM0
-# bit 19-18: 1, ECC RAM WTC RAM0
-# bit 31-20: ???,Reserve
-
-# NOTE: Don't write on 0x20148 , 0x2014c and 0x20154, leave them untouched!
-# If not it could cause KW Exceptions during boot in Fast Corners/High Voltage
-
-# SDRAM initalization
-DATA 0xFFD01400 0x430004E0	# SDRAM Configuration Register
-# bit 13-0:  0x4E0, DDR2 clks refresh rate
-# bit 14:    0, reserved
-# bit 15:    0, reserved
-# bit 16:    0, CPU to Dram Write buffer policy
-# bit 17:    0, Enable Registered DIMM or Equivalent Sampling Logic
-# bit 19-18: 0, reserved
-# bit 23-20: 0, reserved
-# bit 24:    1, enable exit self refresh mode on DDR access
-# bit 25:    1, required
-# bit 29-26: 0, reserved
-# bit 31-30: 1, reserved
-
-DATA 0xFFD01404 0x36543000	# DDR Controller Control Low
-# bit 3-0:   0, reserved
-# bit 4:     0, 2T mode =addr/cmd in same cycle
-# bit 5:     0, clk is driven during self refresh, we don't care for APX
-# bit 6:     0, use recommended falling edge of clk for addr/cmd
-# bit 7-11:  0, reserved
-# bit 12-13: 1, reserved, required 1
-# bit 14:    0, input buffer always powered up
-# bit 17-15: 0, reserved
-# bit 18:    1, cpu lock transaction enabled
-# bit 19:    0, reserved
-# bit 23-20: 5, recommended value for CL=4 and STARTBURST_DEL disabled bit31=0
-# bit 27-24: 6, CL+1, STARTBURST sample stages, for freqs 200-399MHz, unbuffered DIMM
-# bit 30-28: 3, required
-# bit 31:    0,no additional STARTBURST delay
-
-DATA 0xFFD01408 0x2302444e	# DDR Timing (Low) (active cycles value +1)
-# bit 3-0:   0xE, TRAS, 15 clk (45 ns)
-# bit 7-4:   0x4, TRCD, 5 clk (15 ns)
-# bit 11-8:  0x4, TRP, 5 clk (15 ns)
-# bit 15-12: 0x4, TWR, 5 clk (15 ns)
-# bit 19-16: 0x2, TWTR, 3 clk (7.5 ns)
-# bit 20:      0, extended TRAS msb
-# bit 23-21:   0, reserved
-# bit 27-24: 0x3, TRRD, 4 clk (10 ns)
-# bit 31-28: 0x2, TRTP, 3 clk (7.5 ns)
-
-DATA 0xFFD0140C 0x0000003e	#  DDR Timing (High)
-# bit 6-0:   0x3E, TRFC, 63 clk (195 ns)
-# bit 8-7:      0, TR2R
-# bit 10-9:     0, TR2W
-# bit 12-11:    0, TW2W
-# bit 31-13:    0, reserved
-
-DATA 0xFFD01410 0x00000001	#  DDR Address Control
-# bit 1-0:    1, Cs0width=x16
-# bit 3-2:    0, Cs0size=2Gb
-# bit 5-4:    0, Cs1width=nonexistent
-# bit 7-6:    0, Cs1size =nonexistent
-# bit 9-8:    0, Cs2width=nonexistent
-# bit 11-10:  0, Cs2size =nonexistent
-# bit 13-12:  0, Cs3width=nonexistent
-# bit 15-14:  0, Cs3size =nonexistent
-# bit 16:     0, Cs0AddrSel
-# bit 17:     0, Cs1AddrSel
-# bit 18:     0, Cs2AddrSel
-# bit 19:     0, Cs3AddrSel
-# bit 31-20:  0, required
-
-DATA 0xFFD01414 0x00000000	#  DDR Open Pages Control
-# bit 0:      0,  OpenPage enabled
-# bit 31-1:   0, required
-
-DATA 0xFFD01418 0x00000000	#  DDR Operation
-# bit 3-0:    0, DDR cmd
-# bit 31-4:   0, required
-
-DATA 0xFFD0141C 0x00000652	#  DDR Mode
-# bit 2-0:    2, Burst Length = 4
-# bit 3:      0, Burst Type
-# bit 6-4:    5, CAS Latency = 5
-# bit 7:      0, Test mode
-# bit 8:      0, DLL Reset
-# bit 11-9:   3, Write recovery for auto-precharge must be 3
-# bit 12:     0, Active power down exit time, fast exit
-# bit 14-13:  0, reserved
-# bit 31-15:  0, reserved
-
-DATA 0xFFD01420 0x00000006	#  DDR Extended Mode
-# bit 0:      0, DDR DLL enabled
-# bit 1:      1,  DDR drive strength reduced
-# bit 2:      1,  DDR ODT control lsb, 75 ohm termination [RTT0]
-# bit 5-3:    0, required
-# bit 6:      0, DDR ODT control msb, 75 ohm termination [RTT1]
-# bit 9-7:    0, required
-# bit 10:     0, differential DQS enabled
-# bit 11:     0, required
-# bit 12:     0, DDR output buffer enabled
-# bit 31-13:  0 required
-
-DATA 0xFFD01424 0x0000F17F	#  DDR Controller Control High
-# bit 2-0:    7, required
-# bit 3:      1, MBUS Burst Chop disabled
-# bit 6-4:    7, required
-# bit 7:      0, reserved
-# bit 8:      1, add sample stage required for f > 266 MHz
-# bit 9:      0, no half clock cycle addition to dataout
-# bit 10:     0, 1/4 clock cycle skew enabled for addr/ctl signals
-# bit 11:     0, 1/4 clock cycle skew disabled for write mesh
-# bit 15-12:0xf, required
-# bit 31-16:  0, required
-
-DATA 0xFFD01428 0x00084520	# DDR2 SDRAM Timing Low
-# bit 3-0:    0, required
-# bit 7-4:    2, M_ODT assertion 2 cycles after read start command
-# bit 11-8:   5, M_ODT de-assertion 5 cycles after read start command
-#                (ODT turn off delay 2,5 clk cycles)
-# bit 15-12:  4, internal ODT time based on bit 7-4
-#                with the considered SDRAM internal delay
-# bit 19-16:  8, internal ODT de-assertion based on bit 11-8
-#                with the considered SDRAM internal delay
-# bit 31-20:  0, required
-
-DATA 0xFFD0147c 0x00008452	# DDR2 SDRAM Timing High
-# bit 3-0:    2, M_ODT assertion same as bit 11-8
-# bit 7-4:    5, M_ODT de-assertion same as bit 15-12
-# bit 11-8:   4, internal ODT assertion 2 cycles after write start command
-#                with the considered SDRAM internal delay
-# bit 15-12:  8, internal ODT de-assertion 5 cycles after write start command
-#                with the considered SDRAM internal delay
-
-DATA 0xFFD01500 0x00000000	# CS[0]n Base address to 0x0
-# bit 23-0:   0, reserved
-# bit 31-24:  0, CPU CS Window0 Base Address, addr bits [31:24]
-
-DATA 0xFFD01504 0x0FFFFFF1	# CS[0]n Size
-# bit 0:      1, Window enabled
-# bit 1:      0, Write Protect disabled
-# bit 3-2:    0, CS0 hit selected
-# bit 23-4:ones, required
-# bit 31-24: 0x0F, Size (i.e. 256MB)
-
-DATA 0xFFD0150C 0x00000000	# CS[1]n Size, window disabled
-DATA 0xFFD01514 0x00000000	# CS[2]n Size, window disabled
-DATA 0xFFD0151C 0x00000000	# CS[3]n Size, window disabled
-
-DATA 0xFFD01494 0x00010000	#  DDR ODT Control (Low)
-# bit 3-0:     0, ODT0Rd, MODT[0] not asserted during read from DRAM CS0
-# bit 7-4:     0, ODT0Rd, MODT[1] not asserted
-# bit 11-8:    0, required
-# big 15-11:   0, required
-# bit 19-16:   1, ODT0Wr, MODT[0] asserted during write to DRAM CS0
-# bit 23-20:   0, ODT0Wr, MODT[1] not asserted
-# bit 27-24:   0, required
-# bit 31-28:   0, required
-
-DATA 0xFFD01498 0x00000000	#  DDR ODT Control (High)
-# bit 1-0:     0, ODT0 controlled by ODT Control (low) register above
-# bit 3-2:     0, ODT1 controlled by register
-# bit 31-4:    0, required
-
-DATA 0xFFD0149C 0x0000E801	# CPU ODT Control
-# bit 3-0:     1, ODTRd, Internal ODT asserted during read from DRAM bank0
-# bit 7-4:     0, ODTWr, Internal ODT not asserted during write to DRAM
-# bit 9-8:     0, ODTEn, controlled by ODTRd and ODTWr
-# bit 11-10:   2, DQ_ODTSel. ODT select turned on, 75 ohm
-# bit 13-12:   2, STARTBURST ODT buffer selected, 75 ohm
-# bit 14:      1, STARTBURST ODT enabled
-# bit 15:      1, Use ODT Block
-
-DATA 0xFFD01480 0x00000001	# DDR Initialization Control
-# bit 0:       1, enable DDR init upon this register write
-# bit 31-1:    0, reserved
-
-# End of Header extension
-DATA 0x0 0x0
diff --git a/board/keymile/km_arm/kwbimage_256M8_1.cfg b/board/keymile/km_arm/kwbimage_256M8_1.cfg
deleted file mode 100644
index 91ea5f0..0000000
--- a/board/keymile/km_arm/kwbimage_256M8_1.cfg
+++ /dev/null
@@ -1,257 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0+
-#
-# (C) Copyright 2012
-# Stefan Bigler, Keymile AG, stefan.bigler@keymile.com
-# Norbert Mayer, Keymile AG, norbert.mayer@keymile.com
-# Deepak Patel, XENTECH Limited, deepak.patel@xentech.co.uk
-# Refer doc/README.kwbimage for more details about how-to configure
-# and create kirkwood boot image
-#
-# This configuration applies to COGE5 design (ARM-part)
-# Two 8-Bit devices are connected on the 16-Bit bus on the same
-# chip-select. The supported devices are
-#   MT47H256M8EB-3IT:C
-#   MT47H256M8EB-25EIT:C
-
-# Boot Media configurations
-BOOT_FROM	spi	# Boot from SPI flash
-
-DATA 0xFFD10000 0x01112222	# MPP Control 0 Register
-# bit 3-0:   2, MPPSel0  SPI_CSn  (1=NF_IO[2])
-# bit 7-4:   2, MPPSel1  SPI_MOSI (1=NF_IO[3])
-# bit 12-8:  2, MPPSel2  SPI_SCK  (1=NF_IO[4])
-# bit 15-12: 2, MPPSel3  SPI_MISO (1=NF_IO[5])
-# bit 19-16: 1, MPPSel4  NF_IO[6]
-# bit 23-20: 1, MPPSel5  NF_IO[7]
-# bit 27-24: 1, MPPSel6  SYSRST_O
-# bit 31-28: 0, MPPSel7  GPO[7]
-
-DATA 0xFFD10004 0x03303300	# MPP Control 1 Register
-# bit 3-0:   0, MPPSel8	 GPIO[8] CPU_SDA bitbanged
-# bit 7-4:   0, MPPSel9  GPIO[9] CPU_SCL bitbanged
-# bit 12-8:  3, MPPSel10 UA0_TXD
-# bit 15-12: 3, MPPSel11 UA0_RXD
-# bit 19-16: 0, MPPSel12 not connected
-# bit 23-20: 3, MPPSel13 GPIO[14]
-# bit 27-24: 3, MPPSel14 GPIO[15]
-# bit 31-28: 0, MPPSel15 GPIO[16] BOOT_FL_SEL (SPI-MUX Signal)
-
-DATA 0xFFD10008 0x00001100	# MPP Control 2 Register
-# bit 3-0:   0, MPPSel16 GPIO[16]
-# bit 7-4:   0, MPPSel17 not connected
-# bit 11-8:  1, MPPSel18 NF_IO[0]
-# bit 15-12: 1, MPPSel19 NF_IO[1]
-# bit 19-16: 0, MPPSel20 GPIO[20]
-# bit 23-20: 0, MPPSel21 GPIO[21]
-# bit 27-24: 0, MPPSel22 GPIO[22]
-# bit 31-28: 0, MPPSel23 GPIO[23]
-
-# MPP Control 3-6 Register untouched (MPP24-49)
-
-DATA 0xFFD100E0 0x1B1B1B1B	# IO Configuration 0 Register
-# bit 2-0:   3, Reserved
-# bit 5-3:   3, Reserved
-# bit 6:     0, Reserved
-# bit 7:     0, RGMII-pads voltage = 3.3V
-# bit 10-8:  3, Reserved
-# bit 13-11: 3, Reserved
-# bit 14:    0, Reserved
-# bit 15:    0, MPP RGMII-pads voltage = 3.3V
-# bit 31-16  0x1B1B, Reserved
-
-DATA 0xFFD20134 0x66666666	# L2 RAM Timing 0 Register
-# bit 0-1:   2, Tag RAM RTC RAM0
-# bit 3-2:   1, Tag RAM WTC RAM0
-# bit 7-4:   6, Reserved
-# bit 9-8:   2, Valid RAM RTC RAM
-# bit 11-10: 1, Valid RAM WTC RAM
-# bit 13-12: 2, Dirty RAM RTC RAM
-# bit 15-14: 1, Dirty RAM WTC RAM
-# bit 17-16: 2, Data RAM RTC RAM0
-# bit 19-18: 1, Data RAM WTC RAM0
-# bit 21-20: 2, Data RAM RTC RAM1
-# bit 23-22: 1, Data RAM WTC RAM1
-# bit 25-24: 2, Data RAM RTC RAM2
-# bit 27-26: 1, Data RAM WTC RAM2
-# bit 29-28: 2, Data RAM RTC RAM3
-# bit 31-30: 1, Data RAM WTC RAM4
-
-DATA 0xFFD20138 0x66666666	# L2 RAM Timing 1 Register
-# bit 15-0:  ?, Reserved
-# bit 17-16: 2, ECC RAM RTC RAM0
-# bit 19-18: 1, ECC RAM WTC RAM0
-# bit 31-20: ?,Reserved
-
-# NOTE: Don't write on 0x20148 , 0x2014c and 0x20154, leave them untouched!
-# If not it could cause KW Exceptions during boot in Fast Corners/High Voltage
-
-# SDRAM initalization
-DATA 0xFFD01400 0x430004E0	# SDRAM Configuration Register
-# bit 13-0:  0x4E0, DDR2 clks refresh rate
-# bit 14:    0, reserved
-# bit 15:    0, reserved
-# bit 16:    0, CPU to Dram Write buffer policy
-# bit 17:    0, Enable Registered DIMM or Equivalent Sampling Logic
-# bit 19-18: 0, reserved
-# bit 23-20: 0, reserved
-# bit 24:    1, enable exit self refresh mode on DDR access
-# bit 25:    1, required
-# bit 29-26: 0, reserved
-# bit 31-30: 1, reserved
-
-DATA 0xFFD01404 0x36543000	# DDR Controller Control Low
-# bit 3-0:   0, reserved
-# bit 4:     0, 2T mode =addr/cmd in same cycle
-# bit 5:     0, clk is driven during self refresh, we don't care for APX
-# bit 6:     0, use recommended falling edge of clk for addr/cmd
-# bit 7-11:  0, reserved
-# bit 12-13: 1, reserved, required 1
-# bit 14:    0, input buffer always powered up
-# bit 17-15: 0, reserved
-# bit 18:    1, cpu lock transaction enabled
-# bit 19:    0, reserved
-# bit 23-20: 5, recommended value for CL=4 and STARTBURST_DEL disabled bit31=0
-# bit 27-24: 6, CL+1, STARTBURST sample stages, freq 200-399MHz, unbuffer DIMM
-# bit 30-28: 3, required
-# bit 31:    0, no additional STARTBURST delay
-
-DATA 0xFFD01408 0x2202444E	# DDR Timing (Low) (active cycles value +1)
-# bit 3-0:   0xe, TRAS = 45ns -> 15 clk cycles
-# bit 7-4:   0x4, TRCD = 15ns -> 5 clk cycles
-# bit 11-8:  0x4, TRP = 15ns -> 5 clk cycles
-# bit 15-12: 0x4, TWR = 15ns -> 5 clk cycles
-# bit 19-16: 0x2, TWTR = 7,5ns -> 3 clk cycles
-# bit 20:      0, extended TRAS msb
-# bit 23-21:   0, reserved
-# bit 27-24: 0x2, TRRD = 7,5ns -> 3 clk cycles
-# bit 31-28: 0x2, TRTP = 7,5ns -> 3 clk cycles
-
-DATA 0xFFD0140C 0x0000003E	#  DDR Timing (High)
-# bit 6-0:   0x3E, TRFC = 195ns -> 63 clk cycles
-# bit 8-7:      0, TR2R
-# bit 10-9:     0, TR2W
-# bit 12-11:    0, TW2W
-# bit 31-13:    0, reserved
-
-DATA 0xFFD01410 0x00000000	#  DDR Address Control
-# bit 1-0:    0, Cs0width=x8 (2 devices)
-# bit 3-2:    0, Cs0size=2Gb
-# bit 5-4:    0, Cs1width=nonexistent
-# bit 7-6:    0, Cs1size =nonexistent
-# bit 9-8:    0, Cs2width=nonexistent
-# bit 11-10:  0, Cs2size =nonexistent
-# bit 13-12:  0, Cs3width=nonexistent
-# bit 15-14:  0, Cs3size =nonexistent
-# bit 16:     0, Cs0AddrSel
-# bit 17:     0, Cs1AddrSel
-# bit 18:     0, Cs2AddrSel
-# bit 19:     0, Cs3AddrSel
-# bit 31-20:  0, required
-
-DATA 0xFFD01414 0x00000000	#  DDR Open Pages Control
-# bit 0:      0,  OpenPage enabled
-# bit 31-1:   0, required
-
-DATA 0xFFD01418 0x00000000	#  DDR Operation
-# bit 3-0:    0, DDR cmd
-# bit 31-4:   0, required
-
-DATA 0xFFD0141C 0x00000652	#  DDR Mode
-# bit 2-0:    2, Burst Length = 4
-# bit 3:      0, Burst Type
-# bit 6-4:    5, CAS Latency = 5
-# bit 7:      0, Test mode
-# bit 8:      0, DLL Reset
-# bit 11-9:   3, Write recovery for auto-precharge must be 3
-# bit 12:     0, Active power down exit time, fast exit
-# bit 14-13:  0, reserved
-# bit 31-15:  0, reserved
-
-DATA 0xFFD01420 0x00000006	#  DDR Extended Mode
-# bit 0:      0, DDR DLL enabled
-# bit 1:      1, DDR drive strenght reduced
-# bit 2:      1, DDR ODT control lsb, 75ohm termination [RTT0]
-# bit 5-3:    0, required
-# bit 6:      0, DDR ODT control msb, 75ohm termination [RTT1]
-# bit 9-7:    0, required
-# bit 10:     0, differential DQS enabled
-# bit 11:     0, required
-# bit 12:     0, DDR output buffer enabled
-# bit 31-13:  0 required
-
-DATA 0xFFD01424 0x0000F17F	#  DDR Controller Control High
-# bit 2-0:    7, required
-# bit 3:      1, MBUS Burst Chop disabled
-# bit 6-4:    7, required
-# bit 7:      0, reserved
-# bit 8:      1, add sample stage required for > 266Mhz
-# bit 9:      0, no half clock cycle addition to dataout
-# bit 10:     0, 1/4 clock cycle skew enabled for addr/ctl signals
-# bit 11:     0, 1/4 clock cycle skew disabled for write mesh
-# bit 15-12:0xf, required
-# bit 31-16:  0, required
-
-DATA 0xFFD01428 0x00084520	# DDR2 SDRAM Timing Low
-# bit 3-0:    0, required
-# bit 7-4:    2, M_ODT assertion 2 cycles after read start command
-# bit 11-8:   5, M_ODT de-assertion 5 cycles after read start command
-#                (ODT turn off delay 2,5 clk cycles)
-# bit 15-12:  4, internal ODT time based on bit 7-4
-#                with the considered SDRAM internal delay
-# bit 19-16:  8, internal ODT de-assertion based on bit 11-8
-#                with the considered SDRAM internal delay
-# bit 31-20:  0, required
-
-DATA 0xFFD0147c 0x00008452	# DDR2 SDRAM Timing High
-# bit 3-0:    2, M_ODT assertion same as bit 11-8
-# bit 7-4:    5, M_ODT de-assertion same as bit 15-12
-# bit 11-8:   4, internal ODT assertion 2 cycles after write start command
-#                with the considered SDRAM internal delay
-# bit 15-12:  8, internal ODT de-assertion 5 cycles after write start command
-#                with the considered SDRAM internal delay
-
-DATA 0xFFD01500 0x00000000	# CS[0]n Base address to 0x0
-# bit 23-0:   0, reserved
-# bit 31-24:  0, CPU CS Window0 Base Address, addr bits [31:24]
-
-DATA 0xFFD01504 0x1FFFFFF1	# CS[0]n Size
-# bit 0:      1, Window enabled
-# bit 1:      0, Write Protect disabled
-# bit 3-2:    0, CS0 hit selected
-# bit 23-4:ones, required
-# bit 31-24:0x1F, Size (i.e. 512MB)
-
-DATA 0xFFD0150C 0x00000000	# CS[1]n Size, window disabled
-DATA 0xFFD01514 0x00000000	# CS[2]n Size, window disabled
-DATA 0xFFD0151C 0x00000000	# CS[3]n Size, window disabled
-
-DATA 0xFFD01494 0x00010000	#  DDR ODT Control (Low)
-# bit 3-0:     0, ODT0Rd, MODT[0] not asserted during read from DRAM CS0
-# bit 7-4:     0, ODT0Rd, MODT[1] not asserted
-# bit 11-8:    0, required
-# big 15-11:   0, required
-# bit 19-16:   1, ODT0Wr, MODT[0] asserted during write to DRAM CS0
-# bit 23-20:   0, ODT0Wr, MODT[1] not asserted
-# bit 27-24:   0, required
-# bit 31-28:   0, required
-
-DATA 0xFFD01498 0x00000004	#  DDR ODT Control (High)
-# bit 1-0:     0, ODT0 controlled by ODT Control (low) register above
-# bit 3-2:     1, ODT1 never active
-# bit 31-4:    0, required
-
-DATA 0xFFD0149C 0x0000E801	# CPU ODT Control
-# bit 3-0:     1, ODT0Rd, Internal ODT asserted during read from DRAM bank0
-# bit 7-4:     0, ODT0Wr, Internal ODT not asserted during write to DRAM bank0
-# bit 9-8:     0, ODTEn, controlled by ODT0Rd and ODT0Wr
-# bit 11-10:   2, DQ_ODTSel. ODT select turned on, 75 ohm
-# bit 13-12:   2, STARTBURST ODT buffer selected, 75 ohm
-# bit 14:      1, STARTBURST ODT enabled
-# bit 15:      1, Use ODT Block
-
-DATA 0xFFD01480 0x00000001	# DDR Initialization Control
-# bit 0:       1, enable DDR init upon this register write
-# bit 31-1:    0, reserved
-
-# End of Header extension
-DATA 0x0 0x0
diff --git a/board/keymile/scripts/develop-common.txt b/board/keymile/scripts/develop-common.txt
index 4384c0d..1bdff2f 100644
--- a/board/keymile/scripts/develop-common.txt
+++ b/board/keymile/scripts/develop-common.txt
@@ -8,5 +8,5 @@
 toolchain=/opt/eldk
 rootfssize=0
 set_uimage=printenv uimage || setenv uimage uImage
-set_tftppath=if test ${hostname} = kmcoge5un; then setenv tftppath CI5UN; else if test ${hostname} = kmcoge5ne; then setenv tftppath CI5NE; else setenv tftppath ${IVM_Symbol}; fi; fi
+set_tftppath=if test ${hostname} = kmcoge5ne; then setenv tftppath CI5NE; else setenv tftppath ${IVM_Symbol}; fi
 try_import_nfs_path=if tftpboot ${load_addr_r} ${tftppath}/nfs-path.txt; then env import -t ${load_addr_r} ${filesize}; else echo no auto nfs path imported; echo you can set nfsargs in /tftpboot/${tftppath}/nfs-path.txt and rerun develop; fi
diff --git a/board/nuvoton/arbel_evb/Kconfig b/board/nuvoton/arbel_evb/Kconfig
new file mode 100644
index 0000000..efe8597
--- /dev/null
+++ b/board/nuvoton/arbel_evb/Kconfig
@@ -0,0 +1,18 @@
+if TARGET_ARBEL_EVB
+
+config SYS_BOARD
+	default "arbel_evb"
+
+config SYS_VENDOR
+	default "nuvoton"
+
+config SYS_CONFIG_NAME
+	default "arbel"
+
+config SYS_MEM_TOP_HIDE
+	hex "Reserved TOP memory"
+	default 0xB000000
+	help
+	  Reserve memory for ECC/GFX/VCD/ECE.
+
+endif
diff --git a/board/nuvoton/arbel_evb/MAINTAINERS b/board/nuvoton/arbel_evb/MAINTAINERS
new file mode 100644
index 0000000..a5eb61a
--- /dev/null
+++ b/board/nuvoton/arbel_evb/MAINTAINERS
@@ -0,0 +1,7 @@
+Arbel EVB
+M:	Stanley Chu <yschu@nuvoton.com>
+M:	Jim Liu <JJLIU0@nuvoton.com>
+S:	Maintained
+F:	board/nuvoton/arbel_evb/
+F:	include/configs/arbel.h
+F:	configs/arbel_evb_defconfig
diff --git a/board/nuvoton/arbel_evb/Makefile b/board/nuvoton/arbel_evb/Makefile
new file mode 100644
index 0000000..1b1e485
--- /dev/null
+++ b/board/nuvoton/arbel_evb/Makefile
@@ -0,0 +1 @@
+obj-y	+= arbel_evb.o
diff --git a/board/nuvoton/arbel_evb/arbel_evb.c b/board/nuvoton/arbel_evb/arbel_evb.c
new file mode 100644
index 0000000..cd12ce3
--- /dev/null
+++ b/board/nuvoton/arbel_evb/arbel_evb.c
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2022 Nuvoton Technology Corp.
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <asm/io.h>
+#include <asm/arch/gcr.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int board_init(void)
+{
+	return 0;
+}
+
+int dram_init(void)
+{
+	struct npcm_gcr *gcr = (struct npcm_gcr *)NPCM_GCR_BA;
+
+	/*
+	 * Get dram size from bootblock.
+	 * The value is stored in scrpad_02 register.
+	 */
+	gd->ram_size = readl(&gcr->scrpad_b);
+
+	return 0;
+}
diff --git a/board/socionext/developerbox/developerbox.c b/board/socionext/developerbox/developerbox.c
index f5a5fe0..6415c90 100644
--- a/board/socionext/developerbox/developerbox.c
+++ b/board/socionext/developerbox/developerbox.c
@@ -89,8 +89,6 @@
 	struct draminfo_entry	entry[3];
 };
 
-struct draminfo *synquacer_draminfo = (void *)SQ_DRAMINFO_BASE;
-
 DECLARE_GLOBAL_DATA_PTR;
 
 #define LOAD_OFFSET 0x100
@@ -137,21 +135,44 @@
 
 int dram_init(void)
 {
+	struct draminfo *synquacer_draminfo = (void *)SQ_DRAMINFO_BASE;
+	struct draminfo_entry *ent = synquacer_draminfo->entry;
+
+	gd->ram_size = ent[0].size;
+	gd->ram_base = ent[0].base;
+
+	return 0;
+}
+
+int dram_init_banksize(void)
+{
+	struct draminfo *synquacer_draminfo = (void *)SQ_DRAMINFO_BASE;
+	struct draminfo_entry *ent = synquacer_draminfo->entry;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(gd->bd->bi_dram); i++) {
+		if (i < synquacer_draminfo->nr_regions) {
+			debug("%s: dram[%d] = %llx@%llx\n", __func__, i, ent[i].size, ent[i].base);
+			gd->bd->bi_dram[i].start = ent[i].base;
+			gd->bd->bi_dram[i].size = ent[i].size;
+		}
+	}
+
+	return 0;
+}
+
+void build_mem_map(void)
+{
+	struct draminfo *synquacer_draminfo = (void *)SQ_DRAMINFO_BASE;
 	struct draminfo_entry *ent = synquacer_draminfo->entry;
 	struct mm_region *mr;
 	int i, ri;
 
 	if (synquacer_draminfo->nr_regions < 1) {
 		log_err("Failed to get correct DRAM information\n");
-		return -1;
+		return;
 	}
 
-	/*
-	 * U-Boot RAM size must be under the first DRAM region so that it doesn't
-	 * access secure memory which is at the end of the first DRAM region.
-	 */
-	gd->ram_size = ent[0].size;
-
 	/* Update memory region maps */
 	for (i = 0; i < synquacer_draminfo->nr_regions; i++) {
 		if (i >= MAX_DDR_REGIONS)
@@ -160,31 +181,21 @@
 		ri = DDR_REGION_INDEX(i);
 		mem_map[ri].phys = ent[i].base;
 		mem_map[ri].size = ent[i].size;
+		mem_map[ri].virt = mem_map[ri].phys;
 		if (i == 0)
 			continue;
 
 		mr = &mem_map[DDR_REGION_INDEX(0)];
-		mem_map[ri].virt = mr->virt + mr->size;
 		mem_map[ri].attrs = mr->attrs;
 	}
-
-	return 0;
 }
 
-int dram_init_banksize(void)
+void enable_caches(void)
 {
-	struct draminfo_entry *ent = synquacer_draminfo->entry;
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(gd->bd->bi_dram); i++) {
-		if (i < synquacer_draminfo->nr_regions) {
-			debug("%s: dram[%d] = %llx@%llx\n", __func__, i, ent[i].size, ent[i].base);
-			gd->bd->bi_dram[i].start = ent[i].base;
-			gd->bd->bi_dram[i].size = ent[i].size;
-		}
-	}
+	build_mem_map();
 
-	return 0;
+	icache_enable();
+	dcache_enable();
 }
 
 int print_cpuinfo(void)
diff --git a/cmd/Kconfig b/cmd/Kconfig
index bfa12ce..6f00bd9 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -1914,7 +1914,6 @@
 
 config CMD_CLS
 	bool "Enable clear screen command 'cls'"
-	depends on DM_VIDEO || LCD || VIDEO
 	default y if LCD
 	help
 	  Enable the 'cls' command which clears the screen contents
diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index 3041873..b93c0d3 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -492,7 +492,7 @@
 	efi_handle_t mem_handle = NULL, handle;
 	struct efi_device_path *file_path = NULL;
 	struct efi_device_path *msg_path;
-	efi_status_t ret;
+	efi_status_t ret, ret2;
 	u16 *load_options;
 
 	if (!bootefi_device_path || !bootefi_image_path) {
@@ -509,14 +509,11 @@
 		 * Make sure that device for device_path exist
 		 * in load_image(). Otherwise, shell and grub will fail.
 		 */
-		ret = efi_create_handle(&mem_handle);
+		ret = efi_install_multiple_protocol_interfaces(&mem_handle,
+							       &efi_guid_device_path,
+							       file_path, NULL);
 		if (ret != EFI_SUCCESS)
 			goto out;
-
-		ret = efi_add_protocol(mem_handle, &efi_guid_device_path,
-				       file_path);
-		if (ret != EFI_SUCCESS)
-			goto out;
 		msg_path = file_path;
 	} else {
 		file_path = efi_dp_append(bootefi_device_path,
@@ -542,9 +539,11 @@
 	ret = do_bootefi_exec(handle, load_options);
 
 out:
-	efi_delete_handle(mem_handle);
+	ret2 = efi_uninstall_multiple_protocol_interfaces(mem_handle,
+							  &efi_guid_device_path,
+							  file_path, NULL);
 	efi_free_pool(file_path);
-	return ret;
+	return (ret != EFI_SUCCESS) ? ret : ret2;
 }
 
 #ifdef CONFIG_CMD_BOOTEFI_SELFTEST
diff --git a/cmd/efidebug.c b/cmd/efidebug.c
index 84e6ff5..4b49f30 100644
--- a/cmd/efidebug.c
+++ b/cmd/efidebug.c
@@ -8,6 +8,7 @@
 #include <charset.h>
 #include <common.h>
 #include <command.h>
+#include <dm/device.h>
 #include <efi_dt_fixup.h>
 #include <efi_load_initrd.h>
 #include <efi_loader.h>
@@ -344,80 +345,12 @@
 }
 #endif /* CONFIG_EFI_HAVE_CAPSULE_SUPPORT */
 
-/**
- * efi_get_device_path_text() - get device path text
- *
- * Return the text representation of the device path of a handle.
- *
- * @handle:	handle of UEFI device
- * Return:
- * Pointer to the device path text or NULL.
- * The caller is responsible for calling FreePool().
- */
-static u16 *efi_get_device_path_text(efi_handle_t handle)
-{
-	struct efi_handler *handler;
-	efi_status_t ret;
-
-	ret = efi_search_protocol(handle, &efi_guid_device_path, &handler);
-	if (ret == EFI_SUCCESS && handler->protocol_interface) {
-		struct efi_device_path *dp = handler->protocol_interface;
-
-		return efi_dp_str(dp);
-	} else {
-		return NULL;
-	}
-}
-
 #define EFI_HANDLE_WIDTH ((int)sizeof(efi_handle_t) * 2)
 
 static const char spc[] = "                ";
 static const char sep[] = "================";
 
 /**
- * do_efi_show_devices() - show UEFI devices
- *
- * @cmdtp:	Command table
- * @flag:	Command flag
- * @argc:	Number of arguments
- * @argv:	Argument array
- * Return:	CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure
- *
- * Implement efidebug "devices" sub-command.
- * Show all UEFI devices and their information.
- */
-static int do_efi_show_devices(struct cmd_tbl *cmdtp, int flag,
-			       int argc, char *const argv[])
-{
-	efi_handle_t *handles;
-	efi_uintn_t num, i;
-	u16 *dev_path_text;
-	efi_status_t ret;
-
-	ret = EFI_CALL(efi_locate_handle_buffer(ALL_HANDLES, NULL, NULL,
-						&num, &handles));
-	if (ret != EFI_SUCCESS)
-		return CMD_RET_FAILURE;
-
-	if (!num)
-		return CMD_RET_SUCCESS;
-
-	printf("Device%.*s Device Path\n", EFI_HANDLE_WIDTH - 6, spc);
-	printf("%.*s ====================\n", EFI_HANDLE_WIDTH, sep);
-	for (i = 0; i < num; i++) {
-		dev_path_text = efi_get_device_path_text(handles[i]);
-		if (dev_path_text) {
-			printf("%p %ls\n", handles[i], dev_path_text);
-			efi_free_pool(dev_path_text);
-		}
-	}
-
-	efi_free_pool(handles);
-
-	return CMD_RET_SUCCESS;
-}
-
-/**
  * efi_get_driver_handle_info() - get information of UEFI driver
  *
  * @handle:		Handle of UEFI device
@@ -535,26 +468,25 @@
 	if (!num)
 		return CMD_RET_SUCCESS;
 
-	printf("Handle%.*s Protocols\n", EFI_HANDLE_WIDTH - 6, spc);
-	printf("%.*s ====================\n", EFI_HANDLE_WIDTH, sep);
 	for (i = 0; i < num; i++) {
-		printf("%p", handles[i]);
+		struct efi_handler *handler;
+
+		printf("\n%p", handles[i]);
+		if (handles[i]->dev)
+			printf(" (%s)", handles[i]->dev->name);
+		printf("\n");
+		/* Print device path */
+		ret = efi_search_protocol(handles[i], &efi_guid_device_path,
+					  &handler);
+		if (ret == EFI_SUCCESS)
+			printf("  %pD\n", handler->protocol_interface);
 		ret = EFI_CALL(BS->protocols_per_handle(handles[i], &guid,
 							&count));
-		if (ret || !count) {
-			putc('\n');
-			continue;
-		}
-
+		/* Print other protocols */
 		for (j = 0; j < count; j++) {
-			if (j)
-				printf(", ");
-			else
-				putc(' ');
-
-			printf("%pUs", guid[j]);
+			if (guidcmp(guid[j], &efi_guid_device_path))
+				printf("  %pUs\n", guid[j]);
 		}
-		putc('\n');
 	}
 
 	efi_free_pool(handles);
@@ -812,7 +744,6 @@
 	char *endp;
 	u16 var_name16[9];
 	efi_guid_t guid;
-	size_t label_len, label_len16;
 	u16 *label;
 	struct efi_device_path *file_path = NULL;
 	struct efi_device_path *fp_free = NULL;
@@ -859,13 +790,10 @@
 						"Boot", id);
 
 			/* label */
-			label_len = strlen(argv[2]);
-			label_len16 = utf8_utf16_strnlen(argv[2], label_len);
-			label = malloc((label_len16 + 1) * sizeof(u16));
+			label = efi_convert_string(argv[2]);
 			if (!label)
 				return CMD_RET_FAILURE;
 			lo.label = label; /* label will be changed below */
-			utf8_utf16_strncpy(&label, argv[2], label_len);
 
 			/* file path */
 			ret = efi_dp_from_name(argv[3], argv[4], argv[5],
@@ -1539,8 +1467,6 @@
 	U_BOOT_CMD_MKENT(capsule, CONFIG_SYS_MAXARGS, 1, do_efi_capsule,
 			 "", ""),
 #endif
-	U_BOOT_CMD_MKENT(devices, CONFIG_SYS_MAXARGS, 1, do_efi_show_devices,
-			 "", ""),
 	U_BOOT_CMD_MKENT(drivers, CONFIG_SYS_MAXARGS, 1, do_efi_show_drivers,
 			 "", ""),
 	U_BOOT_CMD_MKENT(dh, CONFIG_SYS_MAXARGS, 1, do_efi_show_handles,
@@ -1630,8 +1556,6 @@
 #endif
 	"\n"
 #endif
-	"efidebug devices\n"
-	"  - show UEFI devices\n"
 	"efidebug drivers\n"
 	"  - show UEFI drivers\n"
 	"efidebug dh\n"
diff --git a/cmd/fastboot.c b/cmd/fastboot.c
index dd223b1..b498e4b 100644
--- a/cmd/fastboot.c
+++ b/cmd/fastboot.c
@@ -83,9 +83,9 @@
 	ret = CMD_RET_SUCCESS;
 
 exit:
+	usb_gadget_release(controller_index);
 	g_dnl_unregister();
 	g_dnl_clear_detach();
-	usb_gadget_release(controller_index);
 
 	return ret;
 #else
diff --git a/cmd/nvedit_efi.c b/cmd/nvedit_efi.c
index 770877c..24944ab 100644
--- a/cmd/nvedit_efi.c
+++ b/cmd/nvedit_efi.c
@@ -382,8 +382,7 @@
 	efi_guid_t guid;
 	u32 attributes;
 	bool default_guid, verbose, value_on_memory;
-	u16 *var_name16 = NULL, *p;
-	size_t len;
+	u16 *var_name16;
 	efi_status_t ret;
 
 	if (argc == 1)
@@ -487,18 +486,15 @@
 			       16, 1, value, size, true);
 	}
 
-	len = utf8_utf16_strnlen(var_name, strlen(var_name));
-	var_name16 = malloc((len + 1) * 2);
+	var_name16 = efi_convert_string(var_name);
 	if (!var_name16) {
 		printf("## Out of memory\n");
 		ret = CMD_RET_FAILURE;
 		goto out;
 	}
-	p = var_name16;
-	utf8_utf16_strncpy(&p, var_name, len + 1);
-
 	ret = efi_set_variable_int(var_name16, &guid, attributes, size, value,
 				   true);
+	free(var_name16);
 	unmap_sysmem(value);
 	if (ret == EFI_SUCCESS) {
 		ret = CMD_RET_SUCCESS;
@@ -533,7 +529,6 @@
 		unmap_sysmem(value);
 	else
 		free(value);
-	free(var_name16);
 
 	return ret;
 }
diff --git a/common/board_f.c b/common/board_f.c
index 3df4efe..5f17111 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -36,9 +36,7 @@
 #include <post.h>
 #include <relocate.h>
 #include <serial.h>
-#ifdef CONFIG_SPL
 #include <spl.h>
-#endif
 #include <status_led.h>
 #include <sysreset.h>
 #include <timer.h>
@@ -46,12 +44,6 @@
 #include <video.h>
 #include <watchdog.h>
 #include <asm/cache.h>
-#ifdef CONFIG_MACH_TYPE
-#include <asm/mach-types.h>
-#endif
-#if defined(CONFIG_MP) && defined(CONFIG_PPC)
-#include <asm/mp.h>
-#endif
 #include <asm/global_data.h>
 #include <asm/io.h>
 #include <asm/sections.h>
@@ -59,18 +51,7 @@
 #include <linux/errno.h>
 #include <linux/log2.h>
 
-/*
- * Pointer to initial global data area
- *
- * Here we initialize it if needed.
- */
-#ifdef XTRN_DECLARE_GLOBAL_DATA_PTR
-#undef	XTRN_DECLARE_GLOBAL_DATA_PTR
-#define XTRN_DECLARE_GLOBAL_DATA_PTR	/* empty = allocate here */
-DECLARE_GLOBAL_DATA_PTR = (gd_t *)(CONFIG_SYS_INIT_GD_ADDR);
-#else
 DECLARE_GLOBAL_DATA_PTR;
-#endif
 
 /*
  * TODO(sjg@chromium.org): IMO this code should be
@@ -357,6 +338,11 @@
 	return gd->ram_top;
 }
 
+__weak int arch_setup_dest_addr(void)
+{
+	return 0;
+}
+
 static int setup_dest_addr(void)
 {
 	debug("Monitor len: %08lX\n", gd->mon_len);
@@ -384,17 +370,8 @@
 	gd->ram_top = board_get_usable_ram_top(gd->mon_len);
 	gd->relocaddr = gd->ram_top;
 	debug("Ram top: %08llX\n", (unsigned long long)gd->ram_top);
-#if defined(CONFIG_MP) && (defined(CONFIG_MPC86xx) || defined(CONFIG_E500))
-	/*
-	 * We need to make sure the location we intend to put secondary core
-	 * boot code is reserved and not used by any part of u-boot
-	 */
-	if (gd->relocaddr > determine_mp_bootpg(NULL)) {
-		gd->relocaddr = determine_mp_bootpg(NULL);
-		debug("Reserving MP boot page to %08lx\n", gd->relocaddr);
-	}
-#endif
-	return 0;
+
+	return arch_setup_dest_addr();
 }
 
 #ifdef CONFIG_PRAM
@@ -635,10 +612,6 @@
 		bd->bi_sramsize = CONFIG_SYS_SRAM_SIZE;  /* size  of SRAM */
 	}
 
-#ifdef CONFIG_MACH_TYPE
-	bd->bi_arch_number = CONFIG_MACH_TYPE; /* board id for Linux */
-#endif
-
 	return arch_setup_bdinfo();
 }
 
diff --git a/common/spl/spl_atf.c b/common/spl/spl_atf.c
index e1b68dd..bae5c01 100644
--- a/common/spl/spl_atf.c
+++ b/common/spl/spl_atf.c
@@ -184,7 +184,7 @@
 
 static inline void raw_write_daif(unsigned int daif)
 {
-	__asm__ __volatile__("msr DAIF, %0\n\t" : : "r" (daif) : "memory");
+	__asm__ __volatile__("msr DAIF, %x0\n\t" : : "r" (daif) : "memory");
 }
 
 typedef void (*atf_entry_t)(struct bl31_params *params, void *plat_params);
diff --git a/common/usb_hub.c b/common/usb_hub.c
index d736389..95f1449 100644
--- a/common/usb_hub.c
+++ b/common/usb_hub.c
@@ -168,7 +168,7 @@
 	int i;
 	struct usb_device *dev;
 	unsigned pgood_delay = hub->desc.bPwrOn2PwrGood * 2;
-	const char *env;
+	const char __maybe_unused *env;
 
 	dev = hub->pusb_dev;
 
@@ -193,10 +193,12 @@
 	 * but allow this time to be increased via env variable as some
 	 * devices break the spec and require longer warm-up times
 	 */
+#if CONFIG_IS_ENABLED(ENV_SUPPORT)
 	env = env_get("usb_pgood_delay");
 	if (env)
 		pgood_delay = max(pgood_delay,
 			          (unsigned)simple_strtol(env, NULL, 0));
+#endif
 	debug("pgood_delay=%dms\n", pgood_delay);
 
 	/*
diff --git a/configs/arbel_evb_defconfig b/configs/arbel_evb_defconfig
new file mode 100644
index 0000000..7285d41
--- /dev/null
+++ b/configs/arbel_evb_defconfig
@@ -0,0 +1,66 @@
+CONFIG_ARM=y
+CONFIG_ARCH_NPCM=y
+CONFIG_SYS_MALLOC_LEN=0x240000
+CONFIG_SYS_MALLOC_F_LEN=0x1000
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_ENV_SIZE=0x40000
+CONFIG_ENV_OFFSET=0x1C0000
+CONFIG_ENV_SECT_SIZE=0x1000
+CONFIG_DM_GPIO=y
+CONFIG_DEFAULT_DEVICE_TREE="nuvoton-npcm845-evb"
+CONFIG_SYS_PROMPT="U-Boot>"
+# CONFIG_PSCI_RESET is not set
+CONFIG_ARCH_NPCM8XX=y
+CONFIG_TARGET_ARBEL_EVB=y
+CONFIG_SYS_LOAD_ADDR=0x10000000
+CONFIG_ENV_ADDR=0x801C0000
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_USE_BOOTCOMMAND=y
+CONFIG_BOOTCOMMAND="run common_bootargs; run romboot"
+CONFIG_HUSH_PARSER=y
+CONFIG_SYS_MAXARGS=32
+CONFIG_SYS_BOOTM_LEN=0x1400000
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_SPI=y
+CONFIG_CMD_USB=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_CACHE=y
+CONFIG_CMD_UUID=y
+CONFIG_CMD_FAT=y
+CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_CLK=y
+CONFIG_NPCM_GPIO=y
+# CONFIG_INPUT is not set
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_PHY_BROADCOM=y
+CONFIG_PHY_GIGE=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_RGMII=y
+CONFIG_MII=y
+CONFIG_PINCTRL=y
+CONFIG_PINCONF=y
+CONFIG_PINCTRL_NPCM8XX=y
+CONFIG_DM_RESET=y
+CONFIG_RESET_SYSCON=y
+CONFIG_DM_SERIAL=y
+CONFIG_NPCM_SERIAL=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_NPCM_FIU_SPI=y
+CONFIG_TIMER=y
+CONFIG_NPCM_TIMER=y
+CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_GENERIC=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_GENERIC=y
+CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS=1
+CONFIG_USB_STORAGE=y
+# CONFIG_EFI_LOADER is not set
diff --git a/configs/km_kirkwood_128m16_defconfig b/configs/km_kirkwood_128m16_defconfig
deleted file mode 100644
index 054038f..0000000
--- a/configs/km_kirkwood_128m16_defconfig
+++ /dev/null
@@ -1,81 +0,0 @@
-CONFIG_ARM=y
-CONFIG_SKIP_LOWLEVEL_INIT=y
-CONFIG_SYS_DCACHE_OFF=y
-CONFIG_ARCH_CPU_INIT=y
-CONFIG_ARCH_KIRKWOOD=y
-CONFIG_SYS_KWD_CONFIG="board/keymile/km_arm/kwbimage_128M16_1.cfg"
-CONFIG_SYS_TEXT_BASE=0x07d00000
-CONFIG_SYS_MALLOC_F_LEN=0x400
-CONFIG_TARGET_KM_KIRKWOOD=y
-# CONFIG_KIRKWOOD_PCIE_INIT is not set
-CONFIG_ENV_SIZE=0x2000
-CONFIG_ENV_OFFSET=0x0
-CONFIG_DEFAULT_DEVICE_TREE="kirkwood-km_kirkwood"
-CONFIG_BOOTCOUNT_BOOTLIMIT=3
-CONFIG_ENV_OFFSET_REDUND=0x2000
-CONFIG_IDENT_STRING="\nHitachi Power Grids Kirkwood 128M16"
-CONFIG_SYS_LOAD_ADDR=0x800000
-CONFIG_KM_KIRKWOOD_128M16=y
-CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
-CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xc8012000
-CONFIG_AUTOBOOT_KEYED=y
-CONFIG_AUTOBOOT_PROMPT="Hit <SPACE> key to stop autoboot in %2ds\n"
-CONFIG_AUTOBOOT_STOP_STR=" "
-# CONFIG_DISPLAY_BOARDINFO is not set
-CONFIG_MISC_INIT_R=y
-CONFIG_RESET_PHY_R=y
-CONFIG_HUSH_PARSER=y
-CONFIG_SYS_MAXARGS=32
-CONFIG_SYS_CBSIZE=512
-CONFIG_SYS_PBSIZE=532
-# CONFIG_BOOTM_NETBSD is not set
-# CONFIG_BOOTM_PLAN9 is not set
-# CONFIG_BOOTM_RTEMS is not set
-# CONFIG_BOOTM_VXWORKS is not set
-CONFIG_SYS_BOOTM_LEN=0x2000000
-CONFIG_CMD_ASKENV=y
-CONFIG_CMD_GREPENV=y
-CONFIG_CMD_EEPROM=y
-CONFIG_SYS_I2C_EEPROM_ADDR_LEN=2
-CONFIG_SYS_EEPROM_PAGE_WRITE_BITS=6
-CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS=10
-# CONFIG_CMD_FLASH is not set
-CONFIG_CMD_I2C=y
-CONFIG_CMD_NAND=y
-CONFIG_BOOTP_BOOTFILESIZE=y
-CONFIG_CMD_MII=y
-CONFIG_CMD_PING=y
-CONFIG_CMD_MTDPARTS=y
-CONFIG_MTDIDS_DEFAULT="nand0=orion_nand"
-CONFIG_MTDPARTS_DEFAULT="mtdparts=orion_nand:-(ubi0);"
-CONFIG_CMD_UBI=y
-# CONFIG_CMD_UBIFS is not set
-CONFIG_OF_CONTROL=y
-CONFIG_ENV_OVERWRITE=y
-CONFIG_ENV_IS_IN_EEPROM=y
-CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
-CONFIG_SYS_RELOC_GD_ENV_ADDR=y
-CONFIG_VERSION_VARIABLE=y
-CONFIG_NETCONSOLE=y
-CONFIG_SYS_FAULT_ECHO_LINK_DOWN=y
-CONFIG_BOOTCOUNT_LIMIT=y
-CONFIG_BOOTCOUNT_RAM=y
-CONFIG_KIRKWOOD_GPIO=y
-CONFIG_SYS_I2C_LEGACY=y
-CONFIG_SYS_I2C_SOFT=y
-CONFIG_SYS_I2C_SOFT_SLAVE=0x0
-CONFIG_SYS_I2C_MVTWSI=y
-CONFIG_SYS_I2C_SLAVE=0x0
-CONFIG_SYS_I2C_EEPROM_ADDR=0x50
-# CONFIG_MMC is not set
-CONFIG_MTD=y
-CONFIG_MTD_RAW_NAND=y
-CONFIG_SF_DEFAULT_SPEED=8100000
-CONFIG_SPI_FLASH_MACRONIX=y
-CONFIG_SPI_FLASH_STMICRO=y
-CONFIG_MVGBE=y
-CONFIG_MII=y
-CONFIG_SYS_NS16550=y
-CONFIG_SPI=y
-CONFIG_KIRKWOOD_SPI=y
-CONFIG_BCH=y
diff --git a/configs/km_kirkwood_defconfig b/configs/km_kirkwood_defconfig
deleted file mode 100644
index ac2deeb..0000000
--- a/configs/km_kirkwood_defconfig
+++ /dev/null
@@ -1,81 +0,0 @@
-CONFIG_ARM=y
-CONFIG_SKIP_LOWLEVEL_INIT=y
-CONFIG_SYS_DCACHE_OFF=y
-CONFIG_ARCH_CPU_INIT=y
-CONFIG_ARCH_KIRKWOOD=y
-CONFIG_SYS_KWD_CONFIG="board/keymile/km_arm/kwbimage.cfg"
-CONFIG_SYS_TEXT_BASE=0x07d00000
-CONFIG_SYS_MALLOC_F_LEN=0x400
-CONFIG_TARGET_KM_KIRKWOOD=y
-# CONFIG_KIRKWOOD_PCIE_INIT is not set
-CONFIG_ENV_SIZE=0x2000
-CONFIG_ENV_OFFSET=0x0
-CONFIG_DEFAULT_DEVICE_TREE="kirkwood-km_kirkwood"
-CONFIG_BOOTCOUNT_BOOTLIMIT=3
-CONFIG_ENV_OFFSET_REDUND=0x2000
-CONFIG_IDENT_STRING="\nHitachi Power Grids Kirkwood"
-CONFIG_SYS_LOAD_ADDR=0x800000
-CONFIG_KM_KIRKWOOD=y
-CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
-CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xc8012000
-CONFIG_AUTOBOOT_KEYED=y
-CONFIG_AUTOBOOT_PROMPT="Hit <SPACE> key to stop autoboot in %2ds\n"
-CONFIG_AUTOBOOT_STOP_STR=" "
-# CONFIG_DISPLAY_BOARDINFO is not set
-CONFIG_MISC_INIT_R=y
-CONFIG_RESET_PHY_R=y
-CONFIG_HUSH_PARSER=y
-CONFIG_SYS_MAXARGS=32
-CONFIG_SYS_CBSIZE=512
-CONFIG_SYS_PBSIZE=532
-# CONFIG_BOOTM_NETBSD is not set
-# CONFIG_BOOTM_PLAN9 is not set
-# CONFIG_BOOTM_RTEMS is not set
-# CONFIG_BOOTM_VXWORKS is not set
-CONFIG_SYS_BOOTM_LEN=0x2000000
-CONFIG_CMD_ASKENV=y
-CONFIG_CMD_GREPENV=y
-CONFIG_CMD_EEPROM=y
-CONFIG_SYS_I2C_EEPROM_ADDR_LEN=2
-CONFIG_SYS_EEPROM_PAGE_WRITE_BITS=6
-CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS=10
-# CONFIG_CMD_FLASH is not set
-CONFIG_CMD_I2C=y
-CONFIG_CMD_NAND=y
-CONFIG_BOOTP_BOOTFILESIZE=y
-CONFIG_CMD_MII=y
-CONFIG_CMD_PING=y
-CONFIG_CMD_MTDPARTS=y
-CONFIG_MTDIDS_DEFAULT="nand0=orion_nand"
-CONFIG_MTDPARTS_DEFAULT="mtdparts=orion_nand:-(ubi0);"
-CONFIG_CMD_UBI=y
-# CONFIG_CMD_UBIFS is not set
-CONFIG_OF_CONTROL=y
-CONFIG_ENV_OVERWRITE=y
-CONFIG_ENV_IS_IN_EEPROM=y
-CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
-CONFIG_SYS_RELOC_GD_ENV_ADDR=y
-CONFIG_VERSION_VARIABLE=y
-CONFIG_NETCONSOLE=y
-CONFIG_SYS_FAULT_ECHO_LINK_DOWN=y
-CONFIG_BOOTCOUNT_LIMIT=y
-CONFIG_BOOTCOUNT_RAM=y
-CONFIG_KIRKWOOD_GPIO=y
-CONFIG_SYS_I2C_LEGACY=y
-CONFIG_SYS_I2C_SOFT=y
-CONFIG_SYS_I2C_SOFT_SLAVE=0x0
-CONFIG_SYS_I2C_MVTWSI=y
-CONFIG_SYS_I2C_SLAVE=0x0
-CONFIG_SYS_I2C_EEPROM_ADDR=0x50
-# CONFIG_MMC is not set
-CONFIG_MTD=y
-CONFIG_MTD_RAW_NAND=y
-CONFIG_SF_DEFAULT_SPEED=8100000
-CONFIG_SPI_FLASH_MACRONIX=y
-CONFIG_SPI_FLASH_STMICRO=y
-CONFIG_MVGBE=y
-CONFIG_MII=y
-CONFIG_SYS_NS16550=y
-CONFIG_SPI=y
-CONFIG_KIRKWOOD_SPI=y
-CONFIG_BCH=y
diff --git a/configs/km_kirkwood_pci_defconfig b/configs/km_kirkwood_pci_defconfig
deleted file mode 100644
index 8074679..0000000
--- a/configs/km_kirkwood_pci_defconfig
+++ /dev/null
@@ -1,81 +0,0 @@
-CONFIG_ARM=y
-CONFIG_SKIP_LOWLEVEL_INIT=y
-CONFIG_SYS_DCACHE_OFF=y
-CONFIG_ARCH_CPU_INIT=y
-CONFIG_ARCH_KIRKWOOD=y
-CONFIG_SYS_KWD_CONFIG="board/keymile/km_arm/kwbimage.cfg"
-CONFIG_SYS_TEXT_BASE=0x07d00000
-CONFIG_SYS_MALLOC_F_LEN=0x400
-CONFIG_TARGET_KM_KIRKWOOD=y
-CONFIG_ENV_SIZE=0x2000
-CONFIG_ENV_OFFSET=0x0
-CONFIG_DEFAULT_DEVICE_TREE="kirkwood-km_kirkwood"
-CONFIG_BOOTCOUNT_BOOTLIMIT=3
-CONFIG_ENV_OFFSET_REDUND=0x2000
-CONFIG_IDENT_STRING="\nHitachi Power Grids Kirkwood PCI"
-CONFIG_SYS_LOAD_ADDR=0x800000
-CONFIG_KM_FPGA_CONFIG=y
-CONFIG_KM_KIRKWOOD_PCI=y
-CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
-CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xc8012000
-CONFIG_AUTOBOOT_KEYED=y
-CONFIG_AUTOBOOT_PROMPT="Hit <SPACE> key to stop autoboot in %2ds\n"
-CONFIG_AUTOBOOT_STOP_STR=" "
-# CONFIG_DISPLAY_BOARDINFO is not set
-CONFIG_MISC_INIT_R=y
-CONFIG_RESET_PHY_R=y
-CONFIG_HUSH_PARSER=y
-CONFIG_SYS_MAXARGS=32
-CONFIG_SYS_CBSIZE=512
-CONFIG_SYS_PBSIZE=532
-# CONFIG_BOOTM_NETBSD is not set
-# CONFIG_BOOTM_PLAN9 is not set
-# CONFIG_BOOTM_RTEMS is not set
-# CONFIG_BOOTM_VXWORKS is not set
-CONFIG_SYS_BOOTM_LEN=0x2000000
-CONFIG_CMD_ASKENV=y
-CONFIG_CMD_GREPENV=y
-CONFIG_CMD_EEPROM=y
-CONFIG_SYS_I2C_EEPROM_ADDR_LEN=2
-CONFIG_SYS_EEPROM_PAGE_WRITE_BITS=6
-CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS=10
-# CONFIG_CMD_FLASH is not set
-CONFIG_CMD_I2C=y
-CONFIG_CMD_NAND=y
-CONFIG_BOOTP_BOOTFILESIZE=y
-CONFIG_CMD_MII=y
-CONFIG_CMD_PING=y
-CONFIG_CMD_MTDPARTS=y
-CONFIG_MTDIDS_DEFAULT="nand0=orion_nand"
-CONFIG_MTDPARTS_DEFAULT="mtdparts=orion_nand:-(ubi0);"
-CONFIG_CMD_UBI=y
-# CONFIG_CMD_UBIFS is not set
-CONFIG_OF_CONTROL=y
-CONFIG_ENV_OVERWRITE=y
-CONFIG_ENV_IS_IN_EEPROM=y
-CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
-CONFIG_SYS_RELOC_GD_ENV_ADDR=y
-CONFIG_VERSION_VARIABLE=y
-CONFIG_NETCONSOLE=y
-CONFIG_SYS_FAULT_ECHO_LINK_DOWN=y
-CONFIG_BOOTCOUNT_LIMIT=y
-CONFIG_BOOTCOUNT_RAM=y
-CONFIG_KIRKWOOD_GPIO=y
-CONFIG_SYS_I2C_LEGACY=y
-CONFIG_SYS_I2C_SOFT=y
-CONFIG_SYS_I2C_SOFT_SLAVE=0x0
-CONFIG_SYS_I2C_MVTWSI=y
-CONFIG_SYS_I2C_SLAVE=0x0
-CONFIG_SYS_I2C_EEPROM_ADDR=0x50
-# CONFIG_MMC is not set
-CONFIG_MTD=y
-CONFIG_MTD_RAW_NAND=y
-CONFIG_SF_DEFAULT_SPEED=8100000
-CONFIG_SPI_FLASH_MACRONIX=y
-CONFIG_SPI_FLASH_STMICRO=y
-CONFIG_MVGBE=y
-CONFIG_MII=y
-CONFIG_SYS_NS16550=y
-CONFIG_SPI=y
-CONFIG_KIRKWOOD_SPI=y
-CONFIG_BCH=y
diff --git a/configs/kmcoge5un_defconfig b/configs/kmcoge5un_defconfig
deleted file mode 100644
index 5766f49..0000000
--- a/configs/kmcoge5un_defconfig
+++ /dev/null
@@ -1,84 +0,0 @@
-CONFIG_ARM=y
-CONFIG_SKIP_LOWLEVEL_INIT=y
-CONFIG_SYS_DCACHE_OFF=y
-CONFIG_ARCH_CPU_INIT=y
-CONFIG_ARCH_KIRKWOOD=y
-CONFIG_SYS_KWD_CONFIG="board/keymile/km_arm/kwbimage_256M8_1.cfg"
-CONFIG_SYS_TEXT_BASE=0x07d00000
-CONFIG_SYS_MALLOC_F_LEN=0x400
-CONFIG_TARGET_KM_KIRKWOOD=y
-# CONFIG_KIRKWOOD_PCIE_INIT is not set
-CONFIG_ENV_SIZE=0x2000
-CONFIG_ENV_OFFSET=0xC0000
-CONFIG_ENV_SECT_SIZE=0x10000
-CONFIG_DEFAULT_DEVICE_TREE="kirkwood-km_kirkwood"
-CONFIG_BOOTCOUNT_BOOTLIMIT=3
-CONFIG_ENV_OFFSET_REDUND=0xD0000
-CONFIG_IDENT_STRING="\nHitachi Power Grids COGE5UN"
-CONFIG_SYS_LOAD_ADDR=0x800000
-CONFIG_PIGGY_MAC_ADDRESS_OFFSET=3
-CONFIG_KM_ENV_IS_IN_SPI_NOR=y
-CONFIG_KM_PIGGY4_88E6352=y
-CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
-CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xc8012000
-CONFIG_AUTOBOOT_KEYED=y
-CONFIG_AUTOBOOT_PROMPT="Hit <SPACE> key to stop autoboot in %2ds\n"
-CONFIG_AUTOBOOT_STOP_STR=" "
-# CONFIG_DISPLAY_BOARDINFO is not set
-CONFIG_MISC_INIT_R=y
-CONFIG_RESET_PHY_R=y
-CONFIG_HUSH_PARSER=y
-CONFIG_SYS_MAXARGS=32
-CONFIG_SYS_CBSIZE=512
-CONFIG_SYS_PBSIZE=532
-# CONFIG_BOOTM_NETBSD is not set
-# CONFIG_BOOTM_PLAN9 is not set
-# CONFIG_BOOTM_RTEMS is not set
-# CONFIG_BOOTM_VXWORKS is not set
-CONFIG_SYS_BOOTM_LEN=0x2000000
-CONFIG_CMD_ASKENV=y
-CONFIG_CMD_GREPENV=y
-CONFIG_CMD_EEPROM=y
-CONFIG_SYS_I2C_EEPROM_ADDR_LEN=2
-CONFIG_SYS_EEPROM_PAGE_WRITE_BITS=6
-CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS=10
-# CONFIG_CMD_FLASH is not set
-CONFIG_CMD_I2C=y
-CONFIG_CMD_NAND=y
-CONFIG_BOOTP_BOOTFILESIZE=y
-CONFIG_CMD_MII=y
-CONFIG_CMD_PING=y
-CONFIG_CMD_MTDPARTS=y
-CONFIG_MTDIDS_DEFAULT="nand0=orion_nand"
-CONFIG_MTDPARTS_DEFAULT="mtdparts=orion_nand:-(ubi0);"
-CONFIG_CMD_UBI=y
-# CONFIG_CMD_UBIFS is not set
-CONFIG_OF_CONTROL=y
-CONFIG_ENV_OVERWRITE=y
-CONFIG_ENV_IS_IN_SPI_FLASH=y
-CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
-CONFIG_SYS_RELOC_GD_ENV_ADDR=y
-CONFIG_VERSION_VARIABLE=y
-CONFIG_NETCONSOLE=y
-CONFIG_SYS_FAULT_ECHO_LINK_DOWN=y
-CONFIG_BOOTCOUNT_LIMIT=y
-CONFIG_BOOTCOUNT_RAM=y
-CONFIG_KIRKWOOD_GPIO=y
-CONFIG_SYS_I2C_LEGACY=y
-CONFIG_SYS_I2C_SOFT=y
-CONFIG_SYS_I2C_SOFT_SLAVE=0x0
-CONFIG_SYS_I2C_MVTWSI=y
-CONFIG_SYS_I2C_SLAVE=0x0
-CONFIG_SYS_I2C_EEPROM_ADDR=0x50
-# CONFIG_MMC is not set
-CONFIG_MTD=y
-CONFIG_MTD_RAW_NAND=y
-CONFIG_SF_DEFAULT_SPEED=8100000
-CONFIG_SPI_FLASH_MACRONIX=y
-CONFIG_SPI_FLASH_STMICRO=y
-CONFIG_MVGBE=y
-CONFIG_MII=y
-CONFIG_SYS_NS16550=y
-CONFIG_SPI=y
-CONFIG_KIRKWOOD_SPI=y
-CONFIG_BCH=y
diff --git a/configs/kmnusa_defconfig b/configs/kmnusa_defconfig
deleted file mode 100644
index a309aca..0000000
--- a/configs/kmnusa_defconfig
+++ /dev/null
@@ -1,85 +0,0 @@
-CONFIG_ARM=y
-CONFIG_SKIP_LOWLEVEL_INIT=y
-CONFIG_SYS_DCACHE_OFF=y
-CONFIG_ARCH_CPU_INIT=y
-CONFIG_ARCH_KIRKWOOD=y
-CONFIG_SYS_KWD_CONFIG="board/keymile/km_arm/kwbimage_128M16_1.cfg"
-CONFIG_SYS_TEXT_BASE=0x07d00000
-CONFIG_SYS_MALLOC_F_LEN=0x400
-CONFIG_TARGET_KM_KIRKWOOD=y
-CONFIG_ENV_SIZE=0x2000
-CONFIG_ENV_OFFSET=0xC0000
-CONFIG_ENV_SECT_SIZE=0x10000
-CONFIG_DEFAULT_DEVICE_TREE="kirkwood-km_kirkwood"
-CONFIG_BOOTCOUNT_BOOTLIMIT=3
-CONFIG_ENV_OFFSET_REDUND=0xD0000
-CONFIG_IDENT_STRING="\nHitachi Power Grids Kirkwood"
-CONFIG_SYS_LOAD_ADDR=0x800000
-CONFIG_KM_FPGA_CONFIG=y
-CONFIG_KM_ENV_IS_IN_SPI_NOR=y
-CONFIG_KM_PIGGY4_88E6352=y
-CONFIG_KM_NUSA=y
-CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
-CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xc8012000
-CONFIG_AUTOBOOT_KEYED=y
-CONFIG_AUTOBOOT_PROMPT="Hit <SPACE> key to stop autoboot in %2ds\n"
-CONFIG_AUTOBOOT_STOP_STR=" "
-# CONFIG_DISPLAY_BOARDINFO is not set
-CONFIG_MISC_INIT_R=y
-CONFIG_RESET_PHY_R=y
-CONFIG_HUSH_PARSER=y
-CONFIG_SYS_MAXARGS=32
-CONFIG_SYS_CBSIZE=512
-CONFIG_SYS_PBSIZE=532
-# CONFIG_BOOTM_NETBSD is not set
-# CONFIG_BOOTM_PLAN9 is not set
-# CONFIG_BOOTM_RTEMS is not set
-# CONFIG_BOOTM_VXWORKS is not set
-CONFIG_SYS_BOOTM_LEN=0x2000000
-CONFIG_CMD_ASKENV=y
-CONFIG_CMD_GREPENV=y
-CONFIG_CMD_EEPROM=y
-CONFIG_SYS_I2C_EEPROM_ADDR_LEN=2
-CONFIG_SYS_EEPROM_PAGE_WRITE_BITS=6
-CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS=10
-# CONFIG_CMD_FLASH is not set
-CONFIG_CMD_I2C=y
-CONFIG_CMD_NAND=y
-CONFIG_BOOTP_BOOTFILESIZE=y
-CONFIG_CMD_MII=y
-CONFIG_CMD_PING=y
-CONFIG_CMD_MTDPARTS=y
-CONFIG_MTDIDS_DEFAULT="nand0=orion_nand"
-CONFIG_MTDPARTS_DEFAULT="mtdparts=orion_nand:-(ubi0);"
-CONFIG_CMD_UBI=y
-# CONFIG_CMD_UBIFS is not set
-CONFIG_OF_CONTROL=y
-CONFIG_ENV_OVERWRITE=y
-CONFIG_ENV_IS_IN_SPI_FLASH=y
-CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
-CONFIG_SYS_RELOC_GD_ENV_ADDR=y
-CONFIG_VERSION_VARIABLE=y
-CONFIG_NETCONSOLE=y
-CONFIG_SYS_FAULT_ECHO_LINK_DOWN=y
-CONFIG_BOOTCOUNT_LIMIT=y
-CONFIG_BOOTCOUNT_RAM=y
-CONFIG_KIRKWOOD_GPIO=y
-CONFIG_SYS_I2C_LEGACY=y
-CONFIG_SYS_I2C_SOFT=y
-CONFIG_SYS_I2C_SOFT_SLAVE=0x0
-CONFIG_SYS_I2C_MVTWSI=y
-CONFIG_SYS_I2C_SLAVE=0x0
-CONFIG_SYS_I2C_EEPROM_ADDR=0x50
-# CONFIG_MMC is not set
-CONFIG_MTD=y
-CONFIG_MTD_RAW_NAND=y
-CONFIG_SF_DEFAULT_SPEED=8100000
-CONFIG_SPI_FLASH_MACRONIX=y
-CONFIG_SPI_FLASH_STMICRO=y
-CONFIG_MV88E6352_SWITCH=y
-CONFIG_MVGBE=y
-CONFIG_MII=y
-CONFIG_SYS_NS16550=y
-CONFIG_SPI=y
-CONFIG_KIRKWOOD_SPI=y
-CONFIG_BCH=y
diff --git a/configs/kmsuse2_defconfig b/configs/kmsuse2_defconfig
deleted file mode 100644
index de44deb..0000000
--- a/configs/kmsuse2_defconfig
+++ /dev/null
@@ -1,85 +0,0 @@
-CONFIG_ARM=y
-CONFIG_SKIP_LOWLEVEL_INIT=y
-CONFIG_SYS_DCACHE_OFF=y
-CONFIG_ARCH_CPU_INIT=y
-CONFIG_ARCH_KIRKWOOD=y
-CONFIG_SYS_KWD_CONFIG="board/keymile/km_arm/kwbimage_128M16_1.cfg"
-CONFIG_SYS_TEXT_BASE=0x07d00000
-CONFIG_SYS_MALLOC_F_LEN=0x400
-CONFIG_TARGET_KM_KIRKWOOD=y
-CONFIG_ENV_SIZE=0x2000
-CONFIG_ENV_OFFSET=0xC0000
-CONFIG_ENV_SECT_SIZE=0x10000
-CONFIG_DEFAULT_DEVICE_TREE="kirkwood-km_kirkwood"
-CONFIG_BOOTCOUNT_BOOTLIMIT=3
-CONFIG_ENV_OFFSET_REDUND=0xD0000
-CONFIG_IDENT_STRING="\nHitachi Power Grids Kirkwood"
-CONFIG_SYS_LOAD_ADDR=0x800000
-CONFIG_KM_FPGA_CONFIG=y
-CONFIG_KM_FPGA_FORCE_CONFIG=y
-CONFIG_KM_FPGA_NO_RESET=y
-CONFIG_KM_ENV_IS_IN_SPI_NOR=y
-CONFIG_KM_SUSE2=y
-CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
-CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xc8012000
-CONFIG_AUTOBOOT_KEYED=y
-CONFIG_AUTOBOOT_PROMPT="Hit <SPACE> key to stop autoboot in %2ds\n"
-CONFIG_AUTOBOOT_STOP_STR=" "
-# CONFIG_DISPLAY_BOARDINFO is not set
-CONFIG_MISC_INIT_R=y
-CONFIG_RESET_PHY_R=y
-CONFIG_HUSH_PARSER=y
-CONFIG_SYS_MAXARGS=32
-CONFIG_SYS_CBSIZE=512
-CONFIG_SYS_PBSIZE=532
-# CONFIG_BOOTM_NETBSD is not set
-# CONFIG_BOOTM_PLAN9 is not set
-# CONFIG_BOOTM_RTEMS is not set
-# CONFIG_BOOTM_VXWORKS is not set
-CONFIG_SYS_BOOTM_LEN=0x2000000
-CONFIG_CMD_ASKENV=y
-CONFIG_CMD_GREPENV=y
-CONFIG_CMD_EEPROM=y
-CONFIG_SYS_I2C_EEPROM_ADDR_LEN=2
-CONFIG_SYS_EEPROM_PAGE_WRITE_BITS=6
-CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS=10
-# CONFIG_CMD_FLASH is not set
-CONFIG_CMD_I2C=y
-CONFIG_CMD_NAND=y
-CONFIG_BOOTP_BOOTFILESIZE=y
-CONFIG_CMD_MII=y
-CONFIG_CMD_PING=y
-CONFIG_CMD_MTDPARTS=y
-CONFIG_MTDIDS_DEFAULT="nand0=orion_nand"
-CONFIG_MTDPARTS_DEFAULT="mtdparts=orion_nand:-(ubi0);"
-CONFIG_CMD_UBI=y
-# CONFIG_CMD_UBIFS is not set
-CONFIG_OF_CONTROL=y
-CONFIG_ENV_OVERWRITE=y
-CONFIG_ENV_IS_IN_SPI_FLASH=y
-CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
-CONFIG_SYS_RELOC_GD_ENV_ADDR=y
-CONFIG_VERSION_VARIABLE=y
-CONFIG_NETCONSOLE=y
-CONFIG_SYS_FAULT_ECHO_LINK_DOWN=y
-CONFIG_BOOTCOUNT_LIMIT=y
-CONFIG_BOOTCOUNT_RAM=y
-CONFIG_KIRKWOOD_GPIO=y
-CONFIG_SYS_I2C_LEGACY=y
-CONFIG_SYS_I2C_SOFT=y
-CONFIG_SYS_I2C_SOFT_SLAVE=0x0
-CONFIG_SYS_I2C_MVTWSI=y
-CONFIG_SYS_I2C_SLAVE=0x0
-CONFIG_SYS_I2C_EEPROM_ADDR=0x50
-# CONFIG_MMC is not set
-CONFIG_MTD=y
-CONFIG_MTD_RAW_NAND=y
-CONFIG_SF_DEFAULT_SPEED=8100000
-CONFIG_SPI_FLASH_MACRONIX=y
-CONFIG_SPI_FLASH_STMICRO=y
-CONFIG_MVGBE=y
-CONFIG_MII=y
-CONFIG_SYS_NS16550=y
-CONFIG_SPI=y
-CONFIG_KIRKWOOD_SPI=y
-CONFIG_BCH=y
diff --git a/configs/turris_omnia_defconfig b/configs/turris_omnia_defconfig
index 6698f23..639c68c 100644
--- a/configs/turris_omnia_defconfig
+++ b/configs/turris_omnia_defconfig
@@ -10,6 +10,8 @@
 CONFIG_TARGET_TURRIS_OMNIA=y
 CONFIG_DDR_RESET_ON_TRAINING_FAILURE=y
 CONFIG_MVEBU_EFUSE=y
+CONFIG_MVEBU_EFUSE_VHV_GPIO="mcu_56"
+CONFIG_MVEBU_EFUSE_VHV_GPIO_ACTIVE_LOW=y
 CONFIG_ENV_SIZE=0x10000
 CONFIG_ENV_OFFSET=0xF0000
 CONFIG_ENV_SECT_SIZE=0x10000
diff --git a/doc/api/efi.rst b/doc/api/efi.rst
index 2b96783..43d6f93 100644
--- a/doc/api/efi.rst
+++ b/doc/api/efi.rst
@@ -172,6 +172,12 @@
 .. kernel-doc:: lib/efi_loader/efi_firmware.c
    :internal:
 
+Driver binding protocol
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. kernel-doc:: include/efi_driver.h
+   :internal:
+
 Unit testing
 ------------
 
diff --git a/doc/build/gcc.rst b/doc/build/gcc.rst
index a71f860..a0650a5 100644
--- a/doc/build/gcc.rst
+++ b/doc/build/gcc.rst
@@ -27,10 +27,11 @@
       device-tree-compiler dfu-util efitools flex gdisk graphviz imagemagick \
       liblz4-tool libgnutls28-dev libguestfs-tools libncurses-dev \
       libpython3-dev libsdl2-dev libssl-dev lz4 lzma lzma-alone openssl \
-      pkg-config python3 python3-asteval python3-coverage \
+      pkg-config python3 python3-asteval python3-coverage python3-filelock \
       python3-pkg-resources python3-pycryptodome python3-pyelftools \
-      python3-pytest python3-sphinxcontrib.apidoc python3-sphinx-rtd-theme \
-      python3-subunit python3-testtools python3-virtualenv swig uuid-dev
+      python3-pytest python3-pytest-xdist python3-sphinxcontrib.apidoc \
+      python3-sphinx-rtd-theme python3-subunit python3-testtools \
+      python3-virtualenv swig uuid-dev
 
 SUSE based
 ~~~~~~~~~~
diff --git a/doc/develop/global_data.rst b/doc/develop/global_data.rst
index 2ac893d..d143f27 100644
--- a/doc/develop/global_data.rst
+++ b/doc/develop/global_data.rst
@@ -36,6 +36,11 @@
 
 The sandbox, x86_64, and Xtensa are notable exceptions.
 
+Current implementation uses a register for the GD pointer because this results
+in smaller code. However, using plain global data for the GD pointer would be
+possible too (and simpler, as it does not require the reservation of a specific
+register for it), but the resulting code is bigger.
+
 Clang for ARM does not support assigning a global register. When using Clang
 gd is defined as an inline function using assembly code. This adds a few bytes
 to the code size.
diff --git a/doc/develop/package/index.rst b/doc/develop/package/index.rst
index 9374be2..4f44831 100644
--- a/doc/develop/package/index.rst
+++ b/doc/develop/package/index.rst
@@ -4,7 +4,7 @@
 ==============
 
 U-Boot uses Flat Image Tree (FIT) as a standard file format for packaging
-images that it it reads and boots. Documentation about FIT is available at
+images that it reads and boots. Documentation about FIT is available at
 doc/uImage.FIT
 
 U-Boot also provides binman for cases not covered by FIT. Examples include
diff --git a/doc/develop/py_testing.rst b/doc/develop/py_testing.rst
index 92fbd22..6ff7810 100644
--- a/doc/develop/py_testing.rst
+++ b/doc/develop/py_testing.rst
@@ -47,6 +47,7 @@
 * coreutils
 * dosfstools
 * efitools
+* guestfs-tools
 * mount
 * mtools
 * sbsigntool
@@ -63,6 +64,24 @@
   physical board, attach to the board's console stream, and reset the board.
   Further details are described later.
 
+The usage of command 'sudo' should be avoided in tests. To create disk images
+use command virt-make-fs which is provided by package guestfs-tools. This
+command creates a virtual machine with QEMU in which the disk image is
+generated.
+
+Command virt-make-fs needs read access to the current kernel. On Ubuntu only
+root has this privilege. You can add a script /etc/initramfs-tools/hooks/vmlinuz
+with the following content to overcome the problem:
+
+.. code-block:: bash
+
+    #!/bin/sh
+    echo "chmod a+r vmlinuz-*"
+    chmod a+r /boot/vmlinuz-*
+
+The script should be chmod 755. It will be invoked whenever the initial RAM file
+system is updated.
+
 Using `virtualenv` to provide requirements
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/doc/usage/cmd/cls.rst b/doc/usage/cmd/cls.rst
new file mode 100644
index 0000000..b5c43e0
--- /dev/null
+++ b/doc/usage/cmd/cls.rst
@@ -0,0 +1,26 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+cls command
+===========
+
+Synopsis
+--------
+
+::
+
+    cls
+
+Description
+-----------
+
+The cls command clears the screen.
+
+Configuration
+-------------
+
+The cls command is only available if CONFIG_CMD_CLS=y.
+
+Return value
+------------
+
+The return value $? is 0 (true) on success and 1 (false) on failure.
diff --git a/doc/usage/index.rst b/doc/usage/index.rst
index 0fda121..d064110 100644
--- a/doc/usage/index.rst
+++ b/doc/usage/index.rst
@@ -32,6 +32,7 @@
    cmd/button
    cmd/bootz
    cmd/cbsysinfo
+   cmd/cls
    cmd/conitrace
    cmd/cyclic
    cmd/dm
diff --git a/drivers/clk/imx/clk-gate2.c b/drivers/clk/imx/clk-gate2.c
index 40b2d4c..da27230 100644
--- a/drivers/clk/imx/clk-gate2.c
+++ b/drivers/clk/imx/clk-gate2.c
@@ -20,6 +20,7 @@
 #include <clk-uclass.h>
 #include <dm/device.h>
 #include <dm/devres.h>
+#include <linux/bug.h>
 #include <linux/clk-provider.h>
 #include <clk.h>
 #include "clk.h"
@@ -33,6 +34,7 @@
 	u8		bit_idx;
 	u8		cgr_val;
 	u8		flags;
+	unsigned int	*share_count;
 };
 
 #define to_clk_gate2(_clk) container_of(_clk, struct clk_gate2, clk)
@@ -42,6 +44,9 @@
 	struct clk_gate2 *gate = to_clk_gate2(clk);
 	u32 reg;
 
+	if (gate->share_count && (*gate->share_count)++ > 0)
+		return 0;
+
 	reg = readl(gate->reg);
 	reg &= ~(3 << gate->bit_idx);
 	reg |= gate->cgr_val << gate->bit_idx;
@@ -55,6 +60,13 @@
 	struct clk_gate2 *gate = to_clk_gate2(clk);
 	u32 reg;
 
+	if (gate->share_count) {
+		if (WARN_ON(*gate->share_count == 0))
+			return 0;
+		else if (--(*gate->share_count) > 0)
+			return 0;
+	}
+
 	reg = readl(gate->reg);
 	reg &= ~(3 << gate->bit_idx);
 	writel(reg, gate->reg);
@@ -82,7 +94,7 @@
 struct clk *clk_register_gate2(struct device *dev, const char *name,
 		const char *parent_name, unsigned long flags,
 		void __iomem *reg, u8 bit_idx, u8 cgr_val,
-		u8 clk_gate2_flags)
+		u8 clk_gate2_flags, unsigned int *share_count)
 {
 	struct clk_gate2 *gate;
 	struct clk *clk;
@@ -96,6 +108,7 @@
 	gate->bit_idx = bit_idx;
 	gate->cgr_val = cgr_val;
 	gate->flags = clk_gate2_flags;
+	gate->share_count = share_count;
 
 	clk = &gate->clk;
 
diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c
index 15d7599..35e0d93 100644
--- a/drivers/clk/imx/clk-imx8mn.c
+++ b/drivers/clk/imx/clk-imx8mn.c
@@ -15,6 +15,8 @@
 
 #include "clk.h"
 
+static u32 share_count_nand;
+
 static const char *pll_ref_sels[] = { "clock-osc-24m", "dummy", "dummy", "dummy", };
 static const char *dram_pll_bypass_sels[] = {"dram_pll", "dram_pll_ref_sel", };
 static const char *arm_pll_bypass_sels[] = {"arm_pll", "arm_pll_ref_sel", };
@@ -90,6 +92,10 @@
 static const char *imx8mn_qspi_sels[] = {"clock-osc-24m", "sys_pll1_400m", "sys_pll2_333m", "sys_pll2_500m",
 					   "audio_pll2_out", "sys_pll1_266m", "sys_pll3_out", "sys_pll1_100m", };
 
+static const char * const imx8mn_nand_sels[] = {"osc_24m", "sys_pll2_500m", "audio_pll1_out",
+						"sys_pll1_400m", "audio_pll2_out", "sys_pll3_out",
+						"sys_pll2_250m", "video_pll1_out", };
+
 static const char * const imx8mn_usb_core_sels[] = {"clock-osc-24m", "sys_pll1_100m", "sys_pll1_40m",
 						"sys_pll2_100m", "sys_pll2_200m", "clk_ext2",
 						"clk_ext3", "audio_pll2_out", };
@@ -268,6 +274,8 @@
 	clk_dm(IMX8MN_CLK_USDHC3,
 	       imx8m_clk_composite("usdhc3", imx8mn_usdhc3_sels,
 				   base + 0xbc80));
+	clk_dm(IMX8MN_CLK_NAND,
+	       imx8m_clk_composite("nand", imx8mn_nand_sels, base + 0xab00));
 	clk_dm(IMX8MN_CLK_QSPI,
 	       imx8m_clk_composite("qspi", imx8mn_qspi_sels, base + 0xab80));
 	clk_dm(IMX8MN_CLK_USB_CORE_REF,
@@ -299,6 +307,12 @@
 	       imx_clk_gate4("usdhc3_root_clk", "usdhc3", base + 0x45e0, 0));
 	clk_dm(IMX8MN_CLK_QSPI_ROOT,
 	       imx_clk_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0));
+	clk_dm(IMX8MN_CLK_NAND_ROOT,
+	       imx_clk_gate2_shared2("nand_root_clk", "nand", base + 0x4300, 0, &share_count_nand));
+	clk_dm(IMX8MN_CLK_NAND_USDHC_BUS_RAWNAND_CLK,
+	       imx_clk_gate2_shared2("nand_usdhc_rawnand_clk",
+				     "nand_usdhc_bus", base + 0x4300, 0,
+				     &share_count_nand));
 	clk_dm(IMX8MN_CLK_USB1_CTRL_ROOT,
 		imx_clk_gate4("usb1_ctrl_root_clk", "usb_bus", base + 0x44d0, 0));
 
diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
index 46dee35..11f5dca 100644
--- a/drivers/clk/imx/clk.h
+++ b/drivers/clk/imx/clk.h
@@ -53,7 +53,7 @@
 struct clk *clk_register_gate2(struct device *dev, const char *name,
 		const char *parent_name, unsigned long flags,
 		void __iomem *reg, u8 bit_idx, u8 cgr_val,
-		u8 clk_gate_flags);
+		u8 clk_gate_flags, unsigned int *share_count);
 
 struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
 			  const char *parent_name, void __iomem *base,
@@ -63,15 +63,34 @@
 					void __iomem *reg, u8 shift)
 {
 	return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
-			shift, 0x3, 0);
+			shift, 0x3, 0, NULL);
 }
 
+static inline struct clk *imx_clk_gate2_shared(const char *name,
+					       const char *parent,
+					       void __iomem *reg, u8 shift,
+					       unsigned int *share_count)
+{
+	return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
+				  shift, 0x3, 0, share_count);
+}
+
+static inline struct clk *imx_clk_gate2_shared2(const char *name,
+						const char *parent,
+						void __iomem *reg, u8 shift,
+						unsigned int *share_count)
+{
+	return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT |
+				  CLK_OPS_PARENT_ENABLE, reg, shift, 0x3, 0,
+				  share_count);
+}
+
 static inline struct clk *imx_clk_gate4(const char *name, const char *parent,
 		void __iomem *reg, u8 shift)
 {
 	return clk_register_gate2(NULL, name, parent,
 			CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
-			reg, shift, 0x3, 0);
+			reg, shift, 0x3, 0, NULL);
 }
 
 static inline struct clk *imx_clk_gate4_flags(const char *name,
@@ -80,7 +99,7 @@
 {
 	return clk_register_gate2(NULL, name, parent,
 			flags | CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
-			reg, shift, 0x3, 0);
+			reg, shift, 0x3, 0, NULL);
 }
 
 static inline struct clk *imx_clk_fixed_factor(const char *name,
diff --git a/drivers/clk/nuvoton/Makefile b/drivers/clk/nuvoton/Makefile
index c63d9c1..b55dc80 100644
--- a/drivers/clk/nuvoton/Makefile
+++ b/drivers/clk/nuvoton/Makefile
@@ -1,2 +1,3 @@
 obj-$(CONFIG_ARCH_NPCM) += clk_npcm.o
 obj-$(CONFIG_ARCH_NPCM7xx) += clk_npcm7xx.o
+obj-$(CONFIG_ARCH_NPCM8XX) += clk_npcm8xx.o
diff --git a/drivers/clk/nuvoton/clk_npcm8xx.c b/drivers/clk/nuvoton/clk_npcm8xx.c
new file mode 100644
index 0000000..27e3cfc
--- /dev/null
+++ b/drivers/clk/nuvoton/clk_npcm8xx.c
@@ -0,0 +1,98 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2022 Nuvoton Technology Corp.
+ */
+
+#include <dm.h>
+#include <dt-bindings/clock/nuvoton,npcm845-clk.h>
+#include "clk_npcm.h"
+
+/* Parent clock map */
+static const struct parent_data pll_parents[] = {
+	{NPCM8XX_CLK_PLL0, 0},
+	{NPCM8XX_CLK_PLL1, 1},
+	{NPCM8XX_CLK_REFCLK, 2},
+	{NPCM8XX_CLK_PLL2DIV2, 3}
+};
+
+static const struct parent_data cpuck_parents[] = {
+	{NPCM8XX_CLK_PLL0, 0},
+	{NPCM8XX_CLK_PLL1, 1},
+	{NPCM8XX_CLK_REFCLK, 2},
+	{NPCM8XX_CLK_PLL2, 7}
+};
+
+static const struct parent_data apb_parent[] = {{NPCM8XX_CLK_AHB, 0}};
+
+static struct npcm_clk_pll npcm8xx_clk_plls[] = {
+	{NPCM8XX_CLK_PLL0, NPCM8XX_CLK_REFCLK, PLLCON0, 0},
+	{NPCM8XX_CLK_PLL1, NPCM8XX_CLK_REFCLK, PLLCON1, 0},
+	{NPCM8XX_CLK_PLL2, NPCM8XX_CLK_REFCLK, PLLCON2, 0},
+	{NPCM8XX_CLK_PLL2DIV2, NPCM8XX_CLK_REFCLK, PLLCON2, POST_DIV2}
+};
+
+static struct npcm_clk_select npcm8xx_clk_selectors[] = {
+	{NPCM8XX_CLK_AHB, cpuck_parents, CLKSEL, NPCM8XX_CPUCKSEL, 4, 0},
+	{NPCM8XX_CLK_APB2, apb_parent, 0, 0, 1, FIXED_PARENT},
+	{NPCM8XX_CLK_APB5, apb_parent, 0, 0, 1, FIXED_PARENT},
+	{NPCM8XX_CLK_SPI0, apb_parent, 0, 0, 1, FIXED_PARENT},
+	{NPCM8XX_CLK_SPI1, apb_parent, 0, 0, 1, FIXED_PARENT},
+	{NPCM8XX_CLK_SPI3, apb_parent, 0, 0, 1, FIXED_PARENT},
+	{NPCM8XX_CLK_SPIX, apb_parent, 0, 0, 1, FIXED_PARENT},
+	{NPCM8XX_CLK_UART, pll_parents, CLKSEL, UARTCKSEL, 4, 0},
+	{NPCM8XX_CLK_UART2, pll_parents, CLKSEL, UARTCKSEL, 4, 0},
+	{NPCM8XX_CLK_SDHC, pll_parents, CLKSEL, SDCKSEL, 4, 0}
+};
+
+static struct npcm_clk_div npcm8xx_clk_dividers[] = {
+	{NPCM8XX_CLK_AHB, CLKDIV1, CLK4DIV, DIV_TYPE1 | PRE_DIV2},
+	{NPCM8XX_CLK_APB2, CLKDIV2, APB2CKDIV, DIV_TYPE2},
+	{NPCM8XX_CLK_APB5, CLKDIV2, APB5CKDIV, DIV_TYPE2},
+	{NPCM8XX_CLK_SPI0, CLKDIV3, SPI0CKDIV, DIV_TYPE1},
+	{NPCM8XX_CLK_SPI1, CLKDIV3, SPI1CKDIV, DIV_TYPE1},
+	{NPCM8XX_CLK_SPI3, CLKDIV1, SPI3CKDIV, DIV_TYPE1},
+	{NPCM8XX_CLK_SPIX, CLKDIV3, SPIXCKDIV, DIV_TYPE1},
+	{NPCM8XX_CLK_UART, CLKDIV1, UARTDIV1, DIV_TYPE1},
+	{NPCM8XX_CLK_UART2, CLKDIV3, UARTDIV2, DIV_TYPE1},
+	{NPCM8XX_CLK_SDHC, CLKDIV1, MMCCKDIV, DIV_TYPE1}
+};
+
+static struct npcm_clk_data npcm8xx_clk_data = {
+	.clk_plls = npcm8xx_clk_plls,
+	.num_plls = ARRAY_SIZE(npcm8xx_clk_plls),
+	.clk_selectors = npcm8xx_clk_selectors,
+	.num_selectors = ARRAY_SIZE(npcm8xx_clk_selectors),
+	.clk_dividers = npcm8xx_clk_dividers,
+	.num_dividers = ARRAY_SIZE(npcm8xx_clk_dividers),
+	.refclk_id = NPCM8XX_CLK_REFCLK,
+	.pll0_id = NPCM8XX_CLK_PLL0,
+};
+
+static int npcm8xx_clk_probe(struct udevice *dev)
+{
+	struct npcm_clk_priv *priv = dev_get_priv(dev);
+
+	priv->base = dev_read_addr_ptr(dev);
+	if (!priv->base)
+		return -EINVAL;
+
+	priv->clk_data = &npcm8xx_clk_data;
+	priv->num_clks = NPCM8XX_NUM_CLOCKS;
+
+	return 0;
+}
+
+static const struct udevice_id npcm8xx_clk_ids[] = {
+	{ .compatible = "nuvoton,npcm845-clk" },
+	{ }
+};
+
+U_BOOT_DRIVER(clk_npcm) = {
+	.name           = "clk_npcm",
+	.id             = UCLASS_CLK,
+	.of_match       = npcm8xx_clk_ids,
+	.ops            = &npcm_clk_ops,
+	.priv_auto	= sizeof(struct npcm_clk_priv),
+	.probe          = npcm8xx_clk_probe,
+	.flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/core/regmap.c b/drivers/core/regmap.c
index 5f98f85..5ccbf9a 100644
--- a/drivers/core/regmap.c
+++ b/drivers/core/regmap.c
@@ -399,7 +399,7 @@
 	range = &map->ranges[range_num];
 
 	offset <<= map->reg_offset_shift;
-	if (offset + val_len > range->size) {
+	if (offset + val_len > range->size || offset + val_len < offset) {
 		debug("%s: offset/size combination invalid\n", __func__);
 		return -ERANGE;
 	}
@@ -538,7 +538,7 @@
 	range = &map->ranges[range_num];
 
 	offset <<= map->reg_offset_shift;
-	if (offset + val_len > range->size) {
+	if (offset + val_len > range->size || offset + val_len < offset) {
 		debug("%s: offset/size combination invalid\n", __func__);
 		return -ERANGE;
 	}
diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c
index 86603d4..1a9197b 100644
--- a/drivers/dma/ti/k3-udma.c
+++ b/drivers/dma/ti/k3-udma.c
@@ -14,6 +14,7 @@
 #include <malloc.h>
 #include <linux/bitops.h>
 #include <linux/dma-mapping.h>
+#include <linux/sizes.h>
 #include <dm.h>
 #include <dm/device_compat.h>
 #include <dm/devres.h>
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index c949f9d..2a60478 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -605,4 +605,10 @@
 	help
 	   Support for GPIOs on MCU connected to Turris Omnia via i2c.
 
+config FTGPIO010
+	bool "Faraday Technology FTGPIO010 driver"
+	depends on DM_GPIO
+	help
+	   Support for GPIOs on Faraday Technology's FTGPIO010 controller.
+
 endif
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 9d718a5..eee7908 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -75,3 +75,4 @@
 obj-$(CONFIG_ZYNQMP_GPIO_MODEPIN)	+= zynqmp_gpio_modepin.o
 obj-$(CONFIG_SLG7XL45106_I2C_GPO)	+= gpio_slg7xl45106.o
 obj-$(CONFIG_$(SPL_TPL_)TURRIS_OMNIA_MCU)	+= turris_omnia_mcu.o
+obj-$(CONFIG_FTGPIO010)		+= ftgpio010.o
diff --git a/drivers/gpio/ftgpio010.c b/drivers/gpio/ftgpio010.c
new file mode 100644
index 0000000..6c091d4
--- /dev/null
+++ b/drivers/gpio/ftgpio010.c
@@ -0,0 +1,111 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Faraday Technology's FTGPIO010 controller.
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <asm/io.h>
+#include <asm/gpio.h>
+
+struct ftgpio010_regs {
+	u32 out;
+	u32 in;
+	u32 direction;	// 1 - output
+	u32 reserved;
+	u32 set;
+	u32 clear;
+};
+
+struct ftgpio010_plat {
+	struct ftgpio010_regs __iomem *regs;
+};
+
+static int ftgpio010_direction_input(struct udevice *dev, unsigned int pin)
+{
+	struct ftgpio010_plat *plat = dev_get_plat(dev);
+	struct ftgpio010_regs *const regs = plat->regs;
+
+	clrbits_le32(&regs->direction, 1 << pin);
+	return 0;
+}
+
+static int ftgpio010_direction_output(struct udevice *dev, unsigned int pin,
+				      int val)
+{
+	struct ftgpio010_plat *plat = dev_get_plat(dev);
+	struct ftgpio010_regs *const regs = plat->regs;
+
+	/* change the data first, then the direction. to avoid glitch */
+	out_le32(val ? &regs->set : &regs->clear, 1 << pin);
+	setbits_le32(&regs->direction, 1 << pin);
+
+	return 0;
+}
+
+static int ftgpio010_get_value(struct udevice *dev, unsigned int pin)
+{
+	struct ftgpio010_plat *plat = dev_get_plat(dev);
+	struct ftgpio010_regs *const regs = plat->regs;
+
+	return in_le32(&regs->in) >> pin & 1;
+}
+
+static int ftgpio010_set_value(struct udevice *dev, unsigned int pin, int val)
+{
+	struct ftgpio010_plat *plat = dev_get_plat(dev);
+	struct ftgpio010_regs *const regs = plat->regs;
+
+	out_le32(val ? &regs->set : &regs->clear, 1 << pin);
+	return 0;
+}
+
+static int ftgpio010_get_function(struct udevice *dev, unsigned int pin)
+{
+	struct ftgpio010_plat *plat = dev_get_plat(dev);
+	struct ftgpio010_regs *const regs = plat->regs;
+
+	if (in_le32(&regs->direction) >> pin & 1)
+		return GPIOF_OUTPUT;
+	return GPIOF_INPUT;
+}
+
+static int ftgpio010_probe(struct udevice *dev)
+{
+	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+
+	uc_priv->gpio_count = ofnode_read_u32_default(dev_ofnode(dev),
+						      "nr-gpios", 32);
+	return 0;
+}
+
+static int ftgpio010_of_to_plat(struct udevice *dev)
+{
+	struct ftgpio010_plat *plat = dev_get_plat(dev);
+
+	plat->regs = dev_read_addr_ptr(dev);
+	return 0;
+}
+
+static const struct dm_gpio_ops ftgpio010_ops = {
+	.direction_input	= ftgpio010_direction_input,
+	.direction_output	= ftgpio010_direction_output,
+	.get_value		= ftgpio010_get_value,
+	.set_value		= ftgpio010_set_value,
+	.get_function		= ftgpio010_get_function,
+};
+
+static const struct udevice_id ftgpio010_ids[] = {
+	{ .compatible = "faraday,ftgpio010" },
+	{ }
+};
+
+U_BOOT_DRIVER(ftgpio010) = {
+	.name		= "ftgpio010",
+	.id		= UCLASS_GPIO,
+	.of_match	= ftgpio010_ids,
+	.ops		= &ftgpio010_ops,
+	.of_to_plat	= ftgpio010_of_to_plat,
+	.plat_auto	= sizeof(struct ftgpio010_plat),
+	.probe		= ftgpio010_probe,
+};
diff --git a/drivers/mtd/nand/raw/mxs_nand.c b/drivers/mtd/nand/raw/mxs_nand.c
index 7893e9d..65eab4c8 100644
--- a/drivers/mtd/nand/raw/mxs_nand.c
+++ b/drivers/mtd/nand/raw/mxs_nand.c
@@ -14,6 +14,7 @@
  */
 
 #include <common.h>
+#include <clk.h>
 #include <cpu_func.h>
 #include <dm.h>
 #include <dm/device_compat.h>
@@ -26,10 +27,12 @@
 #include <asm/io.h>
 #include <asm/mach-imx/regs-bch.h>
 #include <asm/mach-imx/regs-gpmi.h>
+#include <linux/delay.h>
 #include <linux/errno.h>
 #include <linux/mtd/rawnand.h>
 #include <linux/sizes.h>
 #include <linux/types.h>
+#include <linux/math64.h>
 
 #define	MXS_NAND_DMA_DESCRIPTOR_COUNT		4
 
@@ -49,6 +52,10 @@
 #endif
 
 #define	MXS_NAND_BCH_TIMEOUT			10000
+#define	USEC_PER_SEC				1000000
+#define	NSEC_PER_SEC				1000000000L
+
+#define TO_CYCLES(duration, period) DIV_ROUND_UP_ULL(duration, period)
 
 struct nand_ecclayout fake_ecc_layout;
 
@@ -1344,6 +1351,196 @@
 	return ret;
 }
 
+/*
+ * <1> Firstly, we should know what's the GPMI-clock means.
+ *     The GPMI-clock is the internal clock in the gpmi nand controller.
+ *     If you set 100MHz to gpmi nand controller, the GPMI-clock's period
+ *     is 10ns. Mark the GPMI-clock's period as GPMI-clock-period.
+ *
+ * <2> Secondly, we should know what's the frequency on the nand chip pins.
+ *     The frequency on the nand chip pins is derived from the GPMI-clock.
+ *     We can get it from the following equation:
+ *
+ *         F = G / (DS + DH)
+ *
+ *         F  : the frequency on the nand chip pins.
+ *         G  : the GPMI clock, such as 100MHz.
+ *         DS : GPMI_HW_GPMI_TIMING0:DATA_SETUP
+ *         DH : GPMI_HW_GPMI_TIMING0:DATA_HOLD
+ *
+ * <3> Thirdly, when the frequency on the nand chip pins is above 33MHz,
+ *     the nand EDO(extended Data Out) timing could be applied.
+ *     The GPMI implements a feedback read strobe to sample the read data.
+ *     The feedback read strobe can be delayed to support the nand EDO timing
+ *     where the read strobe may deasserts before the read data is valid, and
+ *     read data is valid for some time after read strobe.
+ *
+ *     The following figure illustrates some aspects of a NAND Flash read:
+ *
+ *                   |<---tREA---->|
+ *                   |             |
+ *                   |         |   |
+ *                   |<--tRP-->|   |
+ *                   |         |   |
+ *                  __          ___|__________________________________
+ *     RDN            \________/   |
+ *                                 |
+ *                                 /---------\
+ *     Read Data    --------------<           >---------
+ *                                 \---------/
+ *                                |     |
+ *                                |<-D->|
+ *     FeedbackRDN  ________             ____________
+ *                          \___________/
+ *
+ *          D stands for delay, set in the HW_GPMI_CTRL1:RDN_DELAY.
+ *
+ *
+ * <4> Now, we begin to describe how to compute the right RDN_DELAY.
+ *
+ *  4.1) From the aspect of the nand chip pins:
+ *        Delay = (tREA + C - tRP)               {1}
+ *
+ *        tREA : the maximum read access time.
+ *        C    : a constant to adjust the delay. default is 4000ps.
+ *        tRP  : the read pulse width, which is exactly:
+ *                   tRP = (GPMI-clock-period) * DATA_SETUP
+ *
+ *  4.2) From the aspect of the GPMI nand controller:
+ *         Delay = RDN_DELAY * 0.125 * RP        {2}
+ *
+ *         RP   : the DLL reference period.
+ *            if (GPMI-clock-period > DLL_THRETHOLD)
+ *                   RP = GPMI-clock-period / 2;
+ *            else
+ *                   RP = GPMI-clock-period;
+ *
+ *            Set the HW_GPMI_CTRL1:HALF_PERIOD if GPMI-clock-period
+ *            is greater DLL_THRETHOLD. In other SOCs, the DLL_THRETHOLD
+ *            is 16000ps, but in mx6q, we use 12000ps.
+ *
+ *  4.3) since {1} equals {2}, we get:
+ *
+ *                     (tREA + 4000 - tRP) * 8
+ *         RDN_DELAY = -----------------------     {3}
+ *                           RP
+ */
+static void mxs_compute_timings(struct nand_chip *chip,
+				const struct nand_sdr_timings *sdr)
+{
+	struct mxs_nand_info *nand_info = nand_get_controller_data(chip);
+	unsigned long clk_rate;
+	unsigned int dll_wait_time_us;
+	unsigned int dll_threshold_ps = nand_info->max_chain_delay;
+	unsigned int period_ps, reference_period_ps;
+	unsigned int data_setup_cycles, data_hold_cycles, addr_setup_cycles;
+	unsigned int tRP_ps;
+	bool use_half_period;
+	int sample_delay_ps, sample_delay_factor;
+	u16 busy_timeout_cycles;
+	u8 wrn_dly_sel;
+	u32 timing0;
+	u32 timing1;
+	u32 ctrl1n;
+
+	if (sdr->tRC_min >= 30000) {
+		/* ONFI non-EDO modes [0-3] */
+		clk_rate = 22000000;
+		wrn_dly_sel = GPMI_CTRL1_WRN_DLY_SEL_4_TO_8NS;
+	} else if (sdr->tRC_min >= 25000) {
+		/* ONFI EDO mode 4 */
+		clk_rate = 80000000;
+		wrn_dly_sel = GPMI_CTRL1_WRN_DLY_SEL_NO_DELAY;
+		debug("%s, setting ONFI onfi edo 4\n", __func__);
+	} else {
+		/* ONFI EDO mode 5 */
+		clk_rate = 100000000;
+		wrn_dly_sel = GPMI_CTRL1_WRN_DLY_SEL_NO_DELAY;
+		debug("%s, setting ONFI onfi edo 5\n", __func__);
+	}
+
+	/* SDR core timings are given in picoseconds */
+	period_ps = div_u64((u64)NSEC_PER_SEC * 1000, clk_rate);
+
+	addr_setup_cycles = TO_CYCLES(sdr->tALS_min, period_ps);
+	data_setup_cycles = TO_CYCLES(sdr->tDS_min, period_ps);
+	data_hold_cycles = TO_CYCLES(sdr->tDH_min, period_ps);
+	busy_timeout_cycles = TO_CYCLES(sdr->tWB_max + sdr->tR_max, period_ps);
+
+	timing0 = (addr_setup_cycles << GPMI_TIMING0_ADDRESS_SETUP_OFFSET) |
+		      (data_hold_cycles << GPMI_TIMING0_DATA_HOLD_OFFSET) |
+		      (data_setup_cycles << GPMI_TIMING0_DATA_SETUP_OFFSET);
+	timing1 = (busy_timeout_cycles * 4096) << GPMI_TIMING1_DEVICE_BUSY_TIMEOUT_OFFSET;
+
+	/*
+	 * Derive NFC ideal delay from {3}:
+	 *
+	 *                     (tREA + 4000 - tRP) * 8
+	 *         RDN_DELAY = -----------------------
+	 *                                RP
+	 */
+	if (period_ps > dll_threshold_ps) {
+		use_half_period = true;
+		reference_period_ps = period_ps / 2;
+	} else {
+		use_half_period = false;
+		reference_period_ps = period_ps;
+	}
+
+	tRP_ps = data_setup_cycles * period_ps;
+	sample_delay_ps = (sdr->tREA_max + 4000 - tRP_ps) * 8;
+	if (sample_delay_ps > 0)
+		sample_delay_factor = sample_delay_ps / reference_period_ps;
+	else
+		sample_delay_factor = 0;
+
+	ctrl1n = (wrn_dly_sel << GPMI_CTRL1_WRN_DLY_SEL_OFFSET);
+	if (sample_delay_factor)
+		ctrl1n |= (sample_delay_factor << GPMI_CTRL1_RDN_DELAY_OFFSET) |
+			GPMI_CTRL1_DLL_ENABLE |
+			(use_half_period ? GPMI_CTRL1_HALF_PERIOD : 0);
+
+	writel(timing0, &nand_info->gpmi_regs->hw_gpmi_timing0);
+	writel(timing1, &nand_info->gpmi_regs->hw_gpmi_timing1);
+
+	/*
+	 * Clear several CTRL1 fields, DLL must be disabled when setting
+	 * RDN_DELAY or HALF_PERIOD.
+	 */
+	writel(GPMI_CTRL1_CLEAR_MASK, &nand_info->gpmi_regs->hw_gpmi_ctrl1_clr);
+	writel(ctrl1n, &nand_info->gpmi_regs->hw_gpmi_ctrl1_set);
+
+	clk_set_rate(nand_info->gpmi_clk, clk_rate);
+
+	/* Wait 64 clock cycles before using the GPMI after enabling the DLL */
+	dll_wait_time_us = USEC_PER_SEC / clk_rate * 64;
+	if (!dll_wait_time_us)
+		dll_wait_time_us = 1;
+
+	/* Wait for the DLL to settle. */
+	udelay(dll_wait_time_us);
+}
+
+static int mxs_nand_setup_interface(struct mtd_info *mtd, int chipnr,
+				    const struct nand_data_interface *conf)
+{
+	struct nand_chip *chip = mtd_to_nand(mtd);
+	const struct nand_sdr_timings *sdr;
+
+	sdr = nand_get_sdr_timings(conf);
+	if (IS_ERR(sdr))
+		return PTR_ERR(sdr);
+
+	/* Stop here if this call was just a check */
+	if (chipnr < 0)
+		return 0;
+
+	/* Do the actual derivation of the controller timings */
+	mxs_compute_timings(chip, sdr);
+
+	return 0;
+}
+
 int mxs_nand_init_spl(struct nand_chip *nand)
 {
 	struct mxs_nand_info *nand_info;
@@ -1432,6 +1629,9 @@
 	nand->read_buf		= mxs_nand_read_buf;
 	nand->write_buf		= mxs_nand_write_buf;
 
+	if (nand_info->gpmi_clk)
+		nand->setup_data_interface = mxs_nand_setup_interface;
+
 	/* first scan to find the device and get the page size */
 	if (nand_scan_ident(mtd, CONFIG_SYS_MAX_NAND_DEVICE, NULL))
 		goto err_free_buffers;
diff --git a/drivers/mtd/nand/raw/mxs_nand_dt.c b/drivers/mtd/nand/raw/mxs_nand_dt.c
index b9833a6..a922a22 100644
--- a/drivers/mtd/nand/raw/mxs_nand_dt.c
+++ b/drivers/mtd/nand/raw/mxs_nand_dt.c
@@ -22,22 +22,27 @@
 
 struct mxs_nand_dt_data {
 	unsigned int max_ecc_strength_supported;
+	int max_chain_delay; /* See the async EDO mode */
 };
 
 static const struct mxs_nand_dt_data mxs_nand_imx6q_data = {
 	.max_ecc_strength_supported = 40,
+	.max_chain_delay = 12000,
 };
 
 static const struct mxs_nand_dt_data mxs_nand_imx6sx_data = {
 	.max_ecc_strength_supported = 62,
+	.max_chain_delay = 12000,
 };
 
 static const struct mxs_nand_dt_data mxs_nand_imx7d_data = {
 	.max_ecc_strength_supported = 62,
+	.max_chain_delay = 12000,
 };
 
 static const struct mxs_nand_dt_data mxs_nand_imx8qxp_data = {
 	.max_ecc_strength_supported = 62,
+	.max_chain_delay = 12000,
 };
 
 static const struct udevice_id mxs_nand_dt_ids[] = {
@@ -72,8 +77,10 @@
 	int ret;
 
 	data = (void *)dev_get_driver_data(dev);
-	if (data)
+	if (data) {
 		info->max_ecc_strength_supported = data->max_ecc_strength_supported;
+		info->max_chain_delay = data->max_chain_delay;
+	}
 
 	info->dev = dev;
 
@@ -92,70 +99,62 @@
 
 	info->use_minimum_ecc = dev_read_bool(dev, "fsl,use-minimum-ecc");
 
-	if (IS_ENABLED(CONFIG_CLK) && IS_ENABLED(CONFIG_IMX8)) {
+	if (IS_ENABLED(CONFIG_CLK) &&
+	    (IS_ENABLED(CONFIG_IMX8) || IS_ENABLED(CONFIG_IMX8M))) {
 		/* Assigned clock already set clock */
 		struct clk gpmi_clk;
 
-		ret = clk_get_by_name(dev, "gpmi_io", &gpmi_clk);
-		if (ret < 0) {
+		info->gpmi_clk = devm_clk_get(dev, "gpmi_io");
+
+		if (IS_ERR(info->gpmi_clk)) {
+			ret = PTR_ERR(info->gpmi_clk);
 			debug("Can't get gpmi io clk: %d\n", ret);
 			return ret;
 		}
 
-		ret = clk_enable(&gpmi_clk);
+		ret = clk_enable(info->gpmi_clk);
 		if (ret < 0) {
 			debug("Can't enable gpmi io clk: %d\n", ret);
 			return ret;
 		}
 
-		ret = clk_get_by_name(dev, "gpmi_apb", &gpmi_clk);
-		if (ret < 0) {
-			debug("Can't get gpmi_apb clk: %d\n", ret);
-			return ret;
-		}
+		if (IS_ENABLED(CONFIG_IMX8)) {
+			ret = clk_get_by_name(dev, "gpmi_apb", &gpmi_clk);
+			if (ret < 0) {
+				debug("Can't get gpmi_apb clk: %d\n", ret);
+				return ret;
+			}
 
-		ret = clk_enable(&gpmi_clk);
-		if (ret < 0) {
-			debug("Can't enable gpmi_apb clk: %d\n", ret);
-			return ret;
-		}
+			ret = clk_enable(&gpmi_clk);
+			if (ret < 0) {
+				debug("Can't enable gpmi_apb clk: %d\n", ret);
+				return ret;
+			}
 
-		ret = clk_get_by_name(dev, "gpmi_bch", &gpmi_clk);
-		if (ret < 0) {
-			debug("Can't get gpmi_bch clk: %d\n", ret);
-			return ret;
-		}
+			ret = clk_get_by_name(dev, "gpmi_bch", &gpmi_clk);
+			if (ret < 0) {
+				debug("Can't get gpmi_bch clk: %d\n", ret);
+				return ret;
+			}
 
-		ret = clk_enable(&gpmi_clk);
-		if (ret < 0) {
-			debug("Can't enable gpmi_bch clk: %d\n", ret);
-			return ret;
+			ret = clk_enable(&gpmi_clk);
+			if (ret < 0) {
+				debug("Can't enable gpmi_bch clk: %d\n", ret);
+				return ret;
+			}
 		}
 
-		ret = clk_get_by_name(dev, "gpmi_apb_bch", &gpmi_clk);
+		ret = clk_get_by_name(dev, "gpmi_bch_apb", &gpmi_clk);
 		if (ret < 0) {
-			debug("Can't get gpmi_apb_bch clk: %d\n", ret);
+			debug("Can't get gpmi_bch_apb clk: %d\n", ret);
 			return ret;
 		}
 
 		ret = clk_enable(&gpmi_clk);
 		if (ret < 0) {
-			debug("Can't enable gpmi_apb_bch clk: %d\n", ret);
+			debug("Can't enable gpmi_bch_apb clk: %d\n", ret);
 			return ret;
 		}
-
-		/* this clock is used for apbh_dma, since the apbh dma does not support DM,
-		  * we optionally enable it here
-		  */
-		ret = clk_get_by_name(dev, "gpmi_apbh_dma", &gpmi_clk);
-		if (ret < 0) {
-			debug("Can't get gpmi_apbh_dma clk: %d\n", ret);
-		} else {
-			ret = clk_enable(&gpmi_clk);
-			if (ret < 0) {
-				debug("Can't enable gpmi_apbh_dma clk: %d\n", ret);
-			}
-		}
 	}
 
 	return mxs_nand_init_ctrl(info);
diff --git a/drivers/mtd/nand/raw/nand.c b/drivers/mtd/nand/raw/nand.c
index 4b5560d..14bca12 100644
--- a/drivers/mtd/nand/raw/nand.c
+++ b/drivers/mtd/nand/raw/nand.c
@@ -19,7 +19,7 @@
 
 static struct mtd_info *nand_info[CONFIG_SYS_MAX_NAND_DEVICE];
 
-#ifndef CONFIG_SYS_NAND_SELF_INIT
+#if !CONFIG_IS_ENABLED(SYS_NAND_SELF_INIT)
 static struct nand_chip nand_chip[CONFIG_SYS_MAX_NAND_DEVICE];
 static ulong base_address[CONFIG_SYS_MAX_NAND_DEVICE] = CONFIG_SYS_NAND_BASE_LIST;
 #endif
diff --git a/drivers/mtd/nand/raw/pxa3xx_nand.c b/drivers/mtd/nand/raw/pxa3xx_nand.c
index 9c29e8a..fcd1b9c 100644
--- a/drivers/mtd/nand/raw/pxa3xx_nand.c
+++ b/drivers/mtd/nand/raw/pxa3xx_nand.c
@@ -330,89 +330,44 @@
 };
 #endif
 
-static struct nand_ecclayout ecc_layout_2KB_bch4bit = {
-	.eccbytes = 32,
-	.eccpos = {
-		32, 33, 34, 35, 36, 37, 38, 39,
-		40, 41, 42, 43, 44, 45, 46, 47,
-		48, 49, 50, 51, 52, 53, 54, 55,
-		56, 57, 58, 59, 60, 61, 62, 63},
-	.oobfree = { {2, 30} }
+struct marvell_hw_ecc_layout {
+	int			page_size;
+	int			strength;
+	unsigned int		ecc_size;
+	unsigned int		nfullchunks;
+	unsigned int		chunk_size;
+	unsigned int		spare_size;
+	unsigned int		last_chunk_size;
+	unsigned int		last_spare_size;
 };
 
-static struct nand_ecclayout ecc_layout_2KB_bch8bit = {
-	.eccbytes = 64,
-	.eccpos = {
-		32, 33, 34, 35, 36, 37, 38, 39,
-		40, 41, 42, 43, 44, 45, 46, 47,
-		48, 49, 50, 51, 52, 53, 54, 55,
-		56, 57, 58, 59, 60, 61, 62, 63,
-		64, 65, 66, 67, 68, 69, 70, 71,
-		72, 73, 74, 75, 76, 77, 78, 79,
-		80, 81, 82, 83, 84, 85, 86, 87,
-		88, 89, 90, 91, 92, 93, 94, 95},
-	.oobfree = { {1, 4}, {6, 26} }
-};
-
-static struct nand_ecclayout ecc_layout_4KB_bch4bit = {
-	.eccbytes = 64,
-	.eccpos = {
-		32,  33,  34,  35,  36,  37,  38,  39,
-		40,  41,  42,  43,  44,  45,  46,  47,
-		48,  49,  50,  51,  52,  53,  54,  55,
-		56,  57,  58,  59,  60,  61,  62,  63,
-		96,  97,  98,  99,  100, 101, 102, 103,
-		104, 105, 106, 107, 108, 109, 110, 111,
-		112, 113, 114, 115, 116, 117, 118, 119,
-		120, 121, 122, 123, 124, 125, 126, 127},
-	/* Bootrom looks in bytes 0 & 5 for bad blocks */
-	.oobfree = { {6, 26}, { 64, 32} }
-};
-
-static struct nand_ecclayout ecc_layout_8KB_bch4bit = {
-	.eccbytes = 128,
-	.eccpos = {
-		32,  33,  34,  35,  36,  37,  38,  39,
-		40,  41,  42,  43,  44,  45,  46,  47,
-		48,  49,  50,  51,  52,  53,  54,  55,
-		56,  57,  58,  59,  60,  61,  62,  63,
-
-		96,  97,  98,  99,  100, 101, 102, 103,
-		104, 105, 106, 107, 108, 109, 110, 111,
-		112, 113, 114, 115, 116, 117, 118, 119,
-		120, 121, 122, 123, 124, 125, 126, 127,
+static const struct marvell_hw_ecc_layout nfc_layouts[] = {
+	/* page_size strength ecc_size nfullchunks chunk_size spare_size last_chunk last_spare */
+	{     512,	1,	 8,	    1,	       512,	   8,	      0,	 0	},
+	{    2048,	1,	24,	    1,	      2048,	  40,	      0,	 0	},
 
-		160, 161, 162, 163, 164, 165, 166, 167,
-		168, 169, 170, 171, 172, 173, 174, 175,
-		176, 177, 178, 179, 180, 181, 182, 183,
-		184, 185, 186, 187, 188, 189, 190, 191,
+	{    2048,	4,	32,	    1,	      2048,	  32,	      0,	 0	},
+	{    2048,	8,	32,	    1,	      1024,	   0,	   1024,	32	},
+	{    2048,     12,	32,	    2,	       704,	   0,	    640,	 0	},
+	{    2048,     16,	32,	    4,	       512,	   0,	      0,	32	},
+	{    4096,	4,	32,	    2,	      2048,	  32,	      0,	 0	},
+	{    4096,	8,	32,	    4,	      1024,	   0,	      0,	64	},
+	{    4096,     12,	32,	    5,	       704,	   0,	    576,	32	},
+	{    4096,     16,	32,	    8,	       512,	   0,	      0,	32	},
 
-		224, 225, 226, 227, 228, 229, 230, 231,
-		232, 233, 234, 235, 236, 237, 238, 239,
-		240, 241, 242, 243, 244, 245, 246, 247,
-		248, 249, 250, 251, 252, 253, 254, 255},
-
-	/* Bootrom looks in bytes 0 & 5 for bad blocks */
-	.oobfree = { {1, 4}, {6, 26}, { 64, 32}, {128, 32}, {192, 32} }
+	{    8192,	4,	32,	    4,	      2048,	  32,	      0,	 0	},
+	{    8192,	8,	32,	    8,	      1024,	   0,	      0,       160	},
+	{    8192,     12,	32,	   11,	       704,	   0,	    448,	64	},
+	{    8192,     16,	32,	   16,	       512,	   0,	      0,	32	},
+	{ },
 };
 
-static struct nand_ecclayout ecc_layout_4KB_bch8bit = {
-	.eccbytes = 128,
-	.eccpos = {
-		32,  33,  34,  35,  36,  37,  38,  39,
-		40,  41,  42,  43,  44,  45,  46,  47,
-		48,  49,  50,  51,  52,  53,  54,  55,
-		56,  57,  58,  59,  60,  61,  62,  63},
+static struct nand_ecclayout ecc_layout_empty = {
+	.eccbytes = 0,
+	.eccpos = { },
 	.oobfree = { }
 };
 
-static struct nand_ecclayout ecc_layout_8KB_bch8bit = {
-	.eccbytes = 256,
-	.eccpos = {},
-	/* HW ECC handles all ECC data and all spare area is free for OOB */
-	.oobfree = {{0, 160} }
-};
-
 #define NDTR0_tCH(c)	(min((c), 7) << 19)
 #define NDTR0_tCS(c)	(min((c), 7) << 16)
 #define NDTR0_tWH(c)	(min((c), 7) << 11)
@@ -1549,113 +1504,47 @@
 			struct nand_ecc_ctrl *ecc,
 			int strength, int ecc_stepsize, int page_size)
 {
-	if (strength == 1 && ecc_stepsize == 512 && page_size == 2048) {
-		info->nfullchunks = 1;
-		info->ntotalchunks = 1;
-		info->chunk_size = 2048;
-		info->spare_size = 40;
-		info->ecc_size = 24;
-		ecc->mode = NAND_ECC_HW;
-		ecc->size = 512;
-		ecc->strength = 1;
+	int i = 0;
 
-	} else if (strength == 1 && ecc_stepsize == 512 && page_size == 512) {
-		info->nfullchunks = 1;
-		info->ntotalchunks = 1;
-		info->chunk_size = 512;
-		info->spare_size = 8;
-		info->ecc_size = 8;
-		ecc->mode = NAND_ECC_HW;
-		ecc->size = 512;
-		ecc->strength = 1;
+	/*  if ecc strength is 1 ecc algo is Hamming else bch */
+	info->ecc_bch = (strength == 1) ? 0 : 1;
 
-	/*
-	 * Required ECC: 4-bit correction per 512 bytes
-	 * Select: 16-bit correction per 2048 bytes
-	 */
-	} else if (strength == 4 && ecc_stepsize == 512 && page_size == 2048) {
-		info->ecc_bch = 1;
-		info->nfullchunks = 1;
-		info->ntotalchunks = 1;
-		info->chunk_size = 2048;
-		info->spare_size = 32;
-		info->ecc_size = 32;
-		ecc->mode = NAND_ECC_HW;
-		ecc->size = info->chunk_size;
-		ecc->layout = &ecc_layout_2KB_bch4bit;
-		ecc->strength = 16;
+	ecc->mode = NAND_ECC_HW;
 
-	} else if (strength == 4 && ecc_stepsize == 512 && page_size == 4096) {
-		info->ecc_bch = 1;
-		info->nfullchunks = 2;
-		info->ntotalchunks = 2;
-		info->chunk_size = 2048;
-		info->spare_size = 32;
-		info->ecc_size = 32;
-		ecc->mode = NAND_ECC_HW;
-		ecc->size = info->chunk_size;
-		ecc->layout = &ecc_layout_4KB_bch4bit;
-		ecc->strength = 16;
+	/* ecc->layout is not in use for pxa driver (but shouldn't be NULL)*/
+	if (info->ecc_bch == 1)
+		ecc->layout = &ecc_layout_empty;
 
-	} else if (strength == 4 && ecc_stepsize == 512 && page_size == 8192) {
-		info->ecc_bch = 1;
-		info->nfullchunks = 4;
-		info->ntotalchunks = 4;
-		info->chunk_size = 2048;
-		info->spare_size = 32;
-		info->ecc_size = 32;
-		ecc->mode = NAND_ECC_HW;
-		ecc->size = info->chunk_size;
-		ecc->layout = &ecc_layout_8KB_bch4bit;
-		ecc->strength = 16;
+	/* for bch actual ecc strength is 16 per chunk */
+	ecc->strength = (info->ecc_bch == 1) ? 16 : 1;
 
-	/*
-	 * Required ECC: 8-bit correction per 512 bytes
-	 * Select: 16-bit correction per 1024 bytes
-	 */
-	} else if (strength == 8 && ecc_stepsize == 512 && page_size == 2048) {
-		info->ecc_bch = 1;
-		info->nfullchunks = 1;
-		info->ntotalchunks = 2;
-		info->chunk_size = 1024;
-		info->spare_size = 0;
-		info->last_chunk_size = 1024;
-		info->last_spare_size = 32;
-		info->ecc_size = 32;
-		ecc->mode = NAND_ECC_HW;
-		ecc->size = info->chunk_size;
-		ecc->layout = &ecc_layout_2KB_bch8bit;
-		ecc->strength = 16;
+	while (nfc_layouts[i].strength) {
+		if (strength == nfc_layouts[i].strength && page_size == nfc_layouts[i].page_size) {
+			info->nfullchunks = nfc_layouts[i].nfullchunks;
+			info->chunk_size = nfc_layouts[i].chunk_size;
+			info->spare_size = nfc_layouts[i].spare_size;
+			info->last_chunk_size = nfc_layouts[i].last_chunk_size;
+			info->last_spare_size = nfc_layouts[i].last_spare_size;
+			info->ntotalchunks = (info->last_spare_size || info->last_chunk_size) ?
+					info->nfullchunks + 1 : info->nfullchunks;
+			info->ecc_size = nfc_layouts[i].ecc_size;
+			break;
+		}
+		++i;
+	}
 
-	} else if (strength == 8 && ecc_stepsize == 512 && page_size == 4096) {
-		info->ecc_bch = 1;
-		info->nfullchunks = 4;
-		info->ntotalchunks = 5;
-		info->chunk_size = 1024;
-		info->spare_size = 0;
-		info->last_chunk_size = 0;
-		info->last_spare_size = 64;
-		info->ecc_size = 32;
-		ecc->mode = NAND_ECC_HW;
-		ecc->size = info->chunk_size;
-		ecc->layout = &ecc_layout_4KB_bch8bit;
-		ecc->strength = 16;
+	/* for bch the ecc is calculated per chunk size and for Hamming it is 512 */
+	ecc->size = (info->ecc_bch) ? info->chunk_size : 512;
 
-	} else if (strength == 8 && ecc_stepsize == 512 && page_size == 8192) {
-		info->ecc_bch = 1;
-		info->nfullchunks = 8;
-		info->ntotalchunks = 9;
-		info->chunk_size = 1024;
-		info->spare_size = 0;
-		info->last_chunk_size = 0;
-		info->last_spare_size = 160;
-		info->ecc_size = 32;
-		ecc->mode = NAND_ECC_HW;
-		ecc->size = info->chunk_size;
-		ecc->layout = &ecc_layout_8KB_bch8bit;
-		ecc->strength = 16;
+	/* nand_scan_tail func perform  validity tests for ECC strength, and it
+	 * assumes that all chunks are with same size. in our case when ecc is 12
+	 * the chunk size is 704 but the last chunk is with different size so
+	 * we cheat it nand_scan_tail validity tests by set info->ecc_size value to 512
+	 */
+	if (strength == 12)
+		ecc->size = 512;
 
-	} else {
+	if (ecc_stepsize != 512 || !(nfc_layouts[i].strength)) {
 		dev_err(info->controller.active->mtd.dev,
 			"ECC strength %d at page size %d is not supported\n",
 			strength, page_size);
diff --git a/drivers/net/ti/am65-cpsw-nuss.c b/drivers/net/ti/am65-cpsw-nuss.c
index b79e062..f674b0b 100644
--- a/drivers/net/ti/am65-cpsw-nuss.c
+++ b/drivers/net/ti/am65-cpsw-nuss.c
@@ -21,6 +21,7 @@
 #include <net.h>
 #include <phy.h>
 #include <power-domain.h>
+#include <soc.h>
 #include <linux/bitops.h>
 #include <linux/soc/ti/ti-udma.h>
 
@@ -127,6 +128,8 @@
 	bool			has_phy;
 	ofnode			phy_node;
 	u32			phy_addr;
+
+	bool			mdio_manual_mode;
 };
 
 #ifdef PKTSIZE_ALIGN
@@ -541,6 +544,20 @@
 	.read_rom_hwaddr = am65_cpsw_read_rom_hwaddr,
 };
 
+static const struct soc_attr k3_mdio_soc_data[] = {
+	{ .family = "AM62X", .revision = "SR1.0" },
+	{ .family = "AM64X", .revision = "SR1.0" },
+	{ .family = "AM64X", .revision = "SR2.0" },
+	{ .family = "AM65X", .revision = "SR1.0" },
+	{ .family = "AM65X", .revision = "SR2.0" },
+	{ .family = "J7200", .revision = "SR1.0" },
+	{ .family = "J7200", .revision = "SR2.0" },
+	{ .family = "J721E", .revision = "SR1.0" },
+	{ .family = "J721E", .revision = "SR1.1" },
+	{ .family = "J721S2", .revision = "SR1.0" },
+	{ /* sentinel */ },
+};
+
 static int am65_cpsw_mdio_init(struct udevice *dev)
 {
 	struct am65_cpsw_priv *priv = dev_get_priv(dev);
@@ -552,7 +569,8 @@
 	cpsw_common->bus = cpsw_mdio_init(dev->name,
 					  cpsw_common->mdio_base,
 					  cpsw_common->bus_freq,
-					  clk_get_rate(&cpsw_common->fclk));
+					  clk_get_rate(&cpsw_common->fclk),
+					  priv->mdio_manual_mode);
 	if (!cpsw_common->bus)
 		return -EFAULT;
 
@@ -657,6 +675,10 @@
 	sprintf(portname, "%s%s", dev->parent->name, dev->name);
 	device_set_name(dev, portname);
 
+	priv->mdio_manual_mode = false;
+	if (soc_device_match(k3_mdio_soc_data))
+		priv->mdio_manual_mode = true;
+
 	ret = am65_cpsw_ofdata_parse_phy(dev);
 	if (ret)
 		goto out;
diff --git a/drivers/net/ti/cpsw.c b/drivers/net/ti/cpsw.c
index 8988c21..41cba79 100644
--- a/drivers/net/ti/cpsw.c
+++ b/drivers/net/ti/cpsw.c
@@ -922,7 +922,8 @@
 		idx = idx + 1;
 	}
 
-	priv->bus = cpsw_mdio_init(priv->dev->name, data->mdio_base, 0, 0);
+	priv->bus = cpsw_mdio_init(priv->dev->name, data->mdio_base, 0, 0,
+				   false);
 	if (!priv->bus)
 		return -EFAULT;
 
diff --git a/drivers/net/ti/cpsw_mdio.c b/drivers/net/ti/cpsw_mdio.c
index f4cb86d..a5ba73b 100644
--- a/drivers/net/ti/cpsw_mdio.c
+++ b/drivers/net/ti/cpsw_mdio.c
@@ -23,6 +23,11 @@
 #define CONTROL_FAULT_ENABLE	BIT(18)
 #define CONTROL_DIV_MASK	GENMASK(15, 0)
 
+#define MDIO_MAN_MDCLK_O        BIT(2)
+#define MDIO_MAN_OE             BIT(1)
+#define MDIO_MAN_PIN            BIT(0)
+#define MDIO_MANUALMODE         BIT(31)
+
 	u32	alive;
 	u32	link;
 	u32	linkintraw;
@@ -32,7 +37,9 @@
 	u32	userintmasked;
 	u32	userintmaskset;
 	u32	userintmaskclr;
-	u32	__reserved_1[20];
+	u32	manualif;
+	u32	poll;
+	u32	__reserved_1[18];
 
 	struct {
 		u32		access;
@@ -51,6 +58,13 @@
 #define PHY_REG_MASK		0x1f
 #define PHY_ID_MASK		0x1f
 
+#define MDIO_BITRANGE           0x8000
+#define C22_READ_PATTERN        0x6
+#define C22_WRITE_PATTERN       0x5
+#define C22_BITRANGE            0x8
+#define PHY_BITRANGE            0x10
+#define PHY_DATA_BITRANGE       0x8000
+
 /*
  * This timeout definition is a worst-case ultra defensive measure against
  * unexpected controller lock ups.  Ideally, we should never ever hit this
@@ -58,12 +72,239 @@
  */
 #define CPSW_MDIO_TIMEOUT            100 /* msecs */
 
+enum cpsw_mdio_manual {
+	MDIO_PIN = 0,
+	MDIO_OE,
+	MDIO_MDCLK,
+};
+
 struct cpsw_mdio {
 	struct cpsw_mdio_regs *regs;
 	struct mii_dev *bus;
 	int div;
 };
 
+static void cpsw_mdio_disable(struct cpsw_mdio *mdio)
+{
+	u32 reg;
+	/* Disable MDIO state machine */
+	reg = readl(&mdio->regs->control);
+	reg &= ~CONTROL_ENABLE;
+
+	writel(reg, &mdio->regs->control);
+}
+
+static void cpsw_mdio_enable_manual_mode(struct cpsw_mdio *mdio)
+{
+	u32 reg;
+
+	/* set manual mode */
+	reg = readl(&mdio->regs->poll);
+	reg |= MDIO_MANUALMODE;
+
+	writel(reg, &mdio->regs->poll);
+}
+
+static void cpsw_mdio_sw_set_bit(struct cpsw_mdio *mdio,
+				 enum cpsw_mdio_manual bit)
+{
+	u32 reg;
+
+	reg = readl(&mdio->regs->manualif);
+
+	switch (bit) {
+	case MDIO_OE:
+		reg |= MDIO_MAN_OE;
+		writel(reg, &mdio->regs->manualif);
+		break;
+	case MDIO_PIN:
+		reg |= MDIO_MAN_PIN;
+		writel(reg, &mdio->regs->manualif);
+		break;
+	case MDIO_MDCLK:
+		reg |= MDIO_MAN_MDCLK_O;
+		writel(reg, &mdio->regs->manualif);
+		break;
+	default:
+		break;
+	};
+}
+
+static void cpsw_mdio_sw_clr_bit(struct cpsw_mdio *mdio,
+				 enum cpsw_mdio_manual bit)
+{
+	u32 reg;
+
+	reg = readl(&mdio->regs->manualif);
+
+	switch (bit) {
+	case MDIO_OE:
+		reg &= ~MDIO_MAN_OE;
+		writel(reg, &mdio->regs->manualif);
+		break;
+	case MDIO_PIN:
+		reg &= ~MDIO_MAN_PIN;
+		writel(reg, &mdio->regs->manualif);
+		break;
+	case MDIO_MDCLK:
+		reg = readl(&mdio->regs->manualif);
+		reg &= ~MDIO_MAN_MDCLK_O;
+		writel(reg, &mdio->regs->manualif);
+		break;
+	default:
+		break;
+	};
+}
+
+static int cpsw_mdio_test_man_bit(struct cpsw_mdio *mdio,
+				  enum cpsw_mdio_manual bit)
+{
+	u32 reg;
+
+	reg = readl(&mdio->regs->manualif);
+	return test_bit(bit, &reg);
+}
+
+static void cpsw_mdio_toggle_man_bit(struct cpsw_mdio *mdio,
+				     enum cpsw_mdio_manual bit)
+{
+	cpsw_mdio_sw_clr_bit(mdio, bit);
+	cpsw_mdio_sw_set_bit(mdio, bit);
+}
+
+static void cpsw_mdio_man_send_pattern(struct cpsw_mdio *mdio,
+				       u32 bitrange, u32 val)
+{
+	u32 i;
+
+	for (i = bitrange; i; i = i >> 1) {
+		if (i & val)
+			cpsw_mdio_sw_set_bit(mdio, MDIO_PIN);
+		else
+			cpsw_mdio_sw_clr_bit(mdio, MDIO_PIN);
+
+		cpsw_mdio_toggle_man_bit(mdio, MDIO_MDCLK);
+	}
+}
+
+static void cpsw_mdio_sw_preamble(struct cpsw_mdio *mdio)
+{
+	u32 i;
+
+	cpsw_mdio_sw_clr_bit(mdio, MDIO_OE);
+
+	cpsw_mdio_sw_clr_bit(mdio, MDIO_MDCLK);
+	cpsw_mdio_sw_clr_bit(mdio, MDIO_MDCLK);
+	cpsw_mdio_sw_clr_bit(mdio, MDIO_MDCLK);
+	cpsw_mdio_sw_set_bit(mdio, MDIO_MDCLK);
+
+	for (i = 0; i < 32; i++) {
+		cpsw_mdio_sw_clr_bit(mdio, MDIO_MDCLK);
+		cpsw_mdio_sw_clr_bit(mdio, MDIO_MDCLK);
+		cpsw_mdio_sw_clr_bit(mdio, MDIO_MDCLK);
+		cpsw_mdio_toggle_man_bit(mdio, MDIO_MDCLK);
+	}
+}
+
+static int cpsw_mdio_sw_read(struct mii_dev *bus, int phy_id,
+			     int dev_addr, int phy_reg)
+{
+	struct cpsw_mdio *mdio = bus->priv;
+	u32 reg, i;
+	u8 ack;
+
+	if (phy_reg & ~PHY_REG_MASK || phy_id & ~PHY_ID_MASK)
+		return -EINVAL;
+
+	cpsw_mdio_disable(mdio);
+	cpsw_mdio_enable_manual_mode(mdio);
+	cpsw_mdio_sw_preamble(mdio);
+
+	cpsw_mdio_sw_clr_bit(mdio, MDIO_MDCLK);
+	cpsw_mdio_sw_set_bit(mdio, MDIO_OE);
+
+	/* Issue clause 22 MII read function {0,1,1,0} */
+	cpsw_mdio_man_send_pattern(mdio, C22_BITRANGE, C22_READ_PATTERN);
+
+	/* Send the device number MSB first */
+	cpsw_mdio_man_send_pattern(mdio, PHY_BITRANGE, phy_id);
+
+	/* Send the register number MSB first */
+	cpsw_mdio_man_send_pattern(mdio, PHY_BITRANGE, phy_reg);
+
+	/* Send turn around cycles */
+	cpsw_mdio_sw_clr_bit(mdio, MDIO_OE);
+
+	cpsw_mdio_toggle_man_bit(mdio, MDIO_MDCLK);
+
+	ack = cpsw_mdio_test_man_bit(mdio, MDIO_PIN);
+	cpsw_mdio_toggle_man_bit(mdio, MDIO_MDCLK);
+
+	reg = 0;
+	if (ack == 0) {
+		for (i = MDIO_BITRANGE; i; i = i >> 1) {
+			if (cpsw_mdio_test_man_bit(mdio, MDIO_PIN))
+				reg |= i;
+
+			cpsw_mdio_toggle_man_bit(mdio, MDIO_MDCLK);
+		}
+	} else {
+		for (i = MDIO_BITRANGE; i; i = i >> 1)
+			cpsw_mdio_toggle_man_bit(mdio, MDIO_MDCLK);
+
+		reg = 0xFFFF;
+	}
+
+	cpsw_mdio_sw_clr_bit(mdio, MDIO_MDCLK);
+	cpsw_mdio_sw_set_bit(mdio, MDIO_MDCLK);
+	cpsw_mdio_sw_set_bit(mdio, MDIO_MDCLK);
+	cpsw_mdio_toggle_man_bit(mdio, MDIO_MDCLK);
+
+	return reg;
+}
+
+static int cpsw_mdio_sw_write(struct mii_dev *bus, int phy_id,
+			      int dev_addr, int phy_reg, u16 phy_data)
+{
+	struct cpsw_mdio *mdio = bus->priv;
+
+	if ((phy_reg & ~PHY_REG_MASK) || (phy_id & ~PHY_ID_MASK))
+		return -EINVAL;
+
+	cpsw_mdio_disable(mdio);
+	cpsw_mdio_enable_manual_mode(mdio);
+	cpsw_mdio_sw_preamble(mdio);
+
+	cpsw_mdio_sw_clr_bit(mdio, MDIO_MDCLK);
+	cpsw_mdio_sw_set_bit(mdio, MDIO_OE);
+
+	/* Issue clause 22 MII write function {0,1,0,1} */
+	cpsw_mdio_man_send_pattern(mdio, C22_BITRANGE, C22_WRITE_PATTERN);
+
+	/* Send the device number MSB first */
+	cpsw_mdio_man_send_pattern(mdio, PHY_BITRANGE, phy_id);
+
+	/* Send the register number MSB first */
+	cpsw_mdio_man_send_pattern(mdio, PHY_BITRANGE, phy_reg);
+
+	/* set turn-around cycles */
+	cpsw_mdio_sw_set_bit(mdio, MDIO_PIN);
+	cpsw_mdio_toggle_man_bit(mdio, MDIO_MDCLK);
+	cpsw_mdio_sw_clr_bit(mdio, MDIO_PIN);
+	cpsw_mdio_toggle_man_bit(mdio, MDIO_MDCLK);
+
+	/* Send Register data MSB first */
+	cpsw_mdio_man_send_pattern(mdio, PHY_DATA_BITRANGE, phy_data);
+	cpsw_mdio_sw_clr_bit(mdio, MDIO_OE);
+
+	cpsw_mdio_sw_clr_bit(mdio, MDIO_MDCLK);
+	cpsw_mdio_sw_clr_bit(mdio, MDIO_MDCLK);
+	cpsw_mdio_sw_clr_bit(mdio, MDIO_MDCLK);
+	cpsw_mdio_toggle_man_bit(mdio, MDIO_MDCLK);
+
+	return 0;
+}
+
 /* wait until hardware is ready for another user access */
 static int cpsw_mdio_wait_for_user_access(struct cpsw_mdio *mdio)
 {
@@ -130,7 +371,7 @@
 }
 
 struct mii_dev *cpsw_mdio_init(const char *name, phys_addr_t mdio_base,
-			       u32 bus_freq, int fck_freq)
+			       u32 bus_freq, int fck_freq, bool manual_mode)
 {
 	struct cpsw_mdio *cpsw_mdio;
 	int ret;
@@ -172,8 +413,14 @@
 	 */
 	mdelay(1);
 
-	cpsw_mdio->bus->read = cpsw_mdio_read;
-	cpsw_mdio->bus->write = cpsw_mdio_write;
+	if (manual_mode) {
+		cpsw_mdio->bus->read = cpsw_mdio_sw_read;
+		cpsw_mdio->bus->write = cpsw_mdio_sw_write;
+	} else {
+		cpsw_mdio->bus->read = cpsw_mdio_read;
+		cpsw_mdio->bus->write = cpsw_mdio_write;
+	}
+
 	cpsw_mdio->bus->priv = cpsw_mdio;
 	snprintf(cpsw_mdio->bus->name, sizeof(cpsw_mdio->bus->name), name);
 
diff --git a/drivers/net/ti/cpsw_mdio.h b/drivers/net/ti/cpsw_mdio.h
index dbf4a2d..9b98763 100644
--- a/drivers/net/ti/cpsw_mdio.h
+++ b/drivers/net/ti/cpsw_mdio.h
@@ -11,7 +11,7 @@
 struct cpsw_mdio;
 
 struct mii_dev *cpsw_mdio_init(const char *name, phys_addr_t mdio_base,
-			       u32 bus_freq, int fck_freq);
+			       u32 bus_freq, int fck_freq, bool manual_mode);
 void cpsw_mdio_free(struct mii_dev *bus);
 u32 cpsw_mdio_get_alive(struct mii_dev *bus);
 
diff --git a/drivers/net/ti/keystone_net.c b/drivers/net/ti/keystone_net.c
index fbec69f..1bdbd59 100644
--- a/drivers/net/ti/keystone_net.c
+++ b/drivers/net/ti/keystone_net.c
@@ -571,7 +571,8 @@
 		mdio_bus = cpsw_mdio_init("ethernet-mdio",
 					  priv->mdio_base,
 					  EMAC_MDIO_CLOCK_FREQ,
-					  EMAC_MDIO_BUS_FREQ);
+					  EMAC_MDIO_BUS_FREQ,
+					  false);
 		if (!mdio_bus) {
 			pr_err("MDIO alloc failed\n");
 			return -ENOMEM;
diff --git a/drivers/phy/phy-uclass.c b/drivers/phy/phy-uclass.c
index 8b84da3..3fef513 100644
--- a/drivers/phy/phy-uclass.c
+++ b/drivers/phy/phy-uclass.c
@@ -455,6 +455,48 @@
 	return ret;
 }
 
+int generic_setup_phy(struct udevice *dev, struct phy *phy, int index)
+{
+	int ret = 0;
+
+	if (!phy)
+		return 0;
+
+	ret = generic_phy_get_by_index(dev, index, phy);
+	if (ret) {
+		if (ret != -ENOENT)
+			return ret;
+	} else {
+		ret = generic_phy_init(phy);
+		if (ret)
+			return ret;
+
+		ret = generic_phy_power_on(phy);
+		if (ret)
+			ret = generic_phy_exit(phy);
+	}
+
+	return ret;
+}
+
+int generic_shutdown_phy(struct phy *phy)
+{
+	int ret = 0;
+
+	if (!phy)
+		return 0;
+
+	if (generic_phy_valid(phy)) {
+		ret = generic_phy_power_off(phy);
+		if (ret)
+			return ret;
+
+		ret = generic_phy_exit(phy);
+	}
+
+	return ret;
+}
+
 UCLASS_DRIVER(phy) = {
 	.id		= UCLASS_PHY,
 	.name		= "phy",
diff --git a/drivers/timer/orion-timer.c b/drivers/timer/orion-timer.c
index cd63ea9..d0eab3c 100644
--- a/drivers/timer/orion-timer.c
+++ b/drivers/timer/orion-timer.c
@@ -28,6 +28,11 @@
 /* Common functions for early (boot) and DM based timer */
 static void orion_timer_init(void *base, enum input_clock_type type)
 {
+	/* Only init the timer once */
+	if (early_init_done)
+		return;
+	early_init_done = true;
+
 	writel(~0, base + TIMER0_VAL);
 	writel(~0, base + TIMER0_RELOAD);
 
@@ -51,11 +56,6 @@
 /* Early (e.g. bootstage etc) timer functions */
 static void notrace timer_early_init(void)
 {
-	/* Only init the timer once */
-	if (early_init_done)
-		return;
-	early_init_done = true;
-
 	if (IS_ENABLED(CONFIG_ARCH_MVEBU))
 		orion_timer_init((void *)MVEBU_TIMER_BASE, INPUT_CLOCK_25MHZ);
 	else
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
index dd09ee0..9c04403 100644
--- a/drivers/usb/gadget/Makefile
+++ b/drivers/usb/gadget/Makefile
@@ -21,7 +21,6 @@
 obj-$(CONFIG_USB_GADGET_DWC2_OTG_PHY) += dwc2_udc_otg_phy.o
 obj-$(CONFIG_USB_GADGET_FOTG210) += fotg210.o
 obj-$(CONFIG_USB_GADGET_MAX3420) += max3420_udc.o
-obj-$(CONFIG_CI_UDC)	+= ci_udc.o
 ifndef CONFIG_SPL_BUILD
 obj-$(CONFIG_USB_GADGET_DOWNLOAD) += g_dnl.o
 obj-$(CONFIG_USB_FUNCTION_THOR) += f_thor.o
@@ -33,14 +32,12 @@
 obj-$(CONFIG_USB_FUNCTION_ACM)	+= f_acm.o
 endif
 endif
-ifdef CONFIG_USB_ETHER
-obj-y += ether.o
+
+obj-$(CONFIG_CI_UDC) += ci_udc.o
+
+obj-$(CONFIG_USB_ETHER) += ether.o
 obj-$(CONFIG_USB_ETH_RNDIS) += rndis.o
-obj-$(CONFIG_CI_UDC)	+= ci_udc.o
-else
+
 # Devices not related to the new gadget layer depend on CONFIG_USB_DEVICE
-ifdef CONFIG_USB_DEVICE
-obj-y += core.o
-obj-y += ep0.o
-endif
-endif
+# This is really only N900 and USBTTY now.
+obj-$(CONFIG_USB_DEVICE) += core.o ep0.o
diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c
index d0e92c7..07b1681 100644
--- a/drivers/usb/gadget/f_fastboot.c
+++ b/drivers/usb/gadget/f_fastboot.c
@@ -544,6 +544,7 @@
 		case FASTBOOT_COMMAND_REBOOT_FASTBOOTD:
 		case FASTBOOT_COMMAND_REBOOT_RECOVERY:
 			fastboot_func->in_req->complete = compl_do_reset;
+			g_dnl_trigger_detach();
 			break;
 #if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT)
 		case FASTBOOT_COMMAND_ACMD:
diff --git a/drivers/usb/host/ehci-generic.c b/drivers/usb/host/ehci-generic.c
index 75c73bf..a765a30 100644
--- a/drivers/usb/host/ehci-generic.c
+++ b/drivers/usb/host/ehci-generic.c
@@ -96,7 +96,7 @@
 	if (err)
 		goto reset_err;
 
-	err = ehci_setup_phy(dev, &priv->phy, 0);
+	err = generic_setup_phy(dev, &priv->phy, 0);
 	if (err)
 		goto regulator_err;
 
@@ -111,7 +111,7 @@
 	return 0;
 
 phy_err:
-	ret = ehci_shutdown_phy(dev, &priv->phy);
+	ret = generic_shutdown_phy(&priv->phy);
 	if (ret)
 		dev_err(dev, "failed to shutdown usb phy (ret=%d)\n", ret);
 
@@ -141,7 +141,7 @@
 	if (ret)
 		return ret;
 
-	ret = ehci_shutdown_phy(dev, &priv->phy);
+	ret = generic_shutdown_phy(&priv->phy);
 	if (ret)
 		return ret;
 
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index d30f2a0..9139d61 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1767,69 +1767,3 @@
 };
 
 #endif
-
-#ifdef CONFIG_PHY
-int ehci_setup_phy(struct udevice *dev, struct phy *phy, int index)
-{
-	int ret;
-
-	if (!phy)
-		return 0;
-
-	ret = generic_phy_get_by_index(dev, index, phy);
-	if (ret) {
-		if (ret != -ENOENT) {
-			dev_err(dev, "failed to get usb phy\n");
-			return ret;
-		}
-	} else {
-		ret = generic_phy_init(phy);
-		if (ret) {
-			dev_dbg(dev, "failed to init usb phy\n");
-			return ret;
-		}
-
-		ret = generic_phy_power_on(phy);
-		if (ret) {
-			dev_dbg(dev, "failed to power on usb phy\n");
-			return generic_phy_exit(phy);
-		}
-	}
-
-	return 0;
-}
-
-int ehci_shutdown_phy(struct udevice *dev, struct phy *phy)
-{
-	int ret = 0;
-
-	if (!phy)
-		return 0;
-
-	if (generic_phy_valid(phy)) {
-		ret = generic_phy_power_off(phy);
-		if (ret) {
-			dev_dbg(dev, "failed to power off usb phy\n");
-			return ret;
-		}
-
-		ret = generic_phy_exit(phy);
-		if (ret) {
-			dev_dbg(dev, "failed to power off usb phy\n");
-			return ret;
-		}
-	}
-
-	return 0;
-}
-#else
-int ehci_setup_phy(struct udevice *dev, struct phy *phy, int index)
-{
-	return 0;
-}
-
-int ehci_shutdown_phy(struct udevice *dev, struct phy *phy)
-{
-	return 0;
-}
-#endif
diff --git a/drivers/usb/host/ehci-msm.c b/drivers/usb/host/ehci-msm.c
index d160cf0..dd0d153 100644
--- a/drivers/usb/host/ehci-msm.c
+++ b/drivers/usb/host/ehci-msm.c
@@ -56,7 +56,7 @@
 	hcor = (struct ehci_hcor *)((phys_addr_t)hccr +
 			HC_LENGTH(ehci_readl(&(hccr)->cr_capbase)));
 
-	ret = ehci_setup_phy(dev, &p->phy, 0);
+	ret = generic_setup_phy(dev, &p->phy, 0);
 	if (ret)
 		return ret;
 
@@ -81,7 +81,7 @@
 	/* Stop controller. */
 	clrbits_le32(&ehci->usbcmd, CMD_RUN);
 
-	ret = ehci_shutdown_phy(dev, &p->phy);
+	ret = generic_shutdown_phy(&p->phy);
 	if (ret)
 		return ret;
 
diff --git a/drivers/usb/host/ehci-mx6.c b/drivers/usb/host/ehci-mx6.c
index e30449b..fa2ca2a 100644
--- a/drivers/usb/host/ehci-mx6.c
+++ b/drivers/usb/host/ehci-mx6.c
@@ -726,7 +726,7 @@
 	mdelay(10);
 
 #if defined(CONFIG_PHY)
-	ret = ehci_setup_phy(dev, &priv->phy, 0);
+	ret = generic_setup_phy(dev, &priv->phy, 0);
 	if (ret)
 		goto err_regulator;
 #endif
@@ -743,7 +743,7 @@
 
 err_phy:
 #if defined(CONFIG_PHY)
-	ehci_shutdown_phy(dev, &priv->phy);
+	generic_shutdown_phy(&priv->phy);
 err_regulator:
 #endif
 #if CONFIG_IS_ENABLED(DM_REGULATOR)
@@ -767,7 +767,7 @@
 	ehci_deregister(dev);
 
 #if defined(CONFIG_PHY)
-	ehci_shutdown_phy(dev, &priv->phy);
+	generic_shutdown_phy(&priv->phy);
 #endif
 
 #if CONFIG_IS_ENABLED(DM_REGULATOR)
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c
index 1ab3061..e98ab31 100644
--- a/drivers/usb/host/ehci-pci.c
+++ b/drivers/usb/host/ehci-pci.c
@@ -31,7 +31,7 @@
 	int ret;
 	u32 cmd;
 
-	ret = ehci_setup_phy(dev, &priv->phy, 0);
+	ret = generic_setup_phy(dev, &priv->phy, 0);
 	if (ret)
 		return ret;
 
@@ -149,7 +149,7 @@
 	if (ret)
 		return ret;
 
-	return ehci_shutdown_phy(dev, &priv->phy);
+	return generic_shutdown_phy(&priv->phy);
 }
 
 static const struct udevice_id ehci_pci_ids[] = {
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index 5170044..5770d35 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -295,9 +295,5 @@
 int ehci_deregister(struct udevice *dev);
 extern struct dm_usb_ops ehci_usb_ops;
 
-/* EHCI PHY functions */
-int ehci_setup_phy(struct udevice *dev, struct phy *phy, int index);
-int ehci_shutdown_phy(struct udevice *dev, struct phy *phy);
-
 #include <linux/bitops.h>
 #endif /* USB_EHCI_H */
diff --git a/drivers/usb/host/ohci-generic.c b/drivers/usb/host/ohci-generic.c
index 5d23058..2d8d38c 100644
--- a/drivers/usb/host/ohci-generic.c
+++ b/drivers/usb/host/ohci-generic.c
@@ -23,56 +23,6 @@
 	int reset_count;	/* number of reset in reset list */
 };
 
-static int ohci_setup_phy(struct udevice *dev, int index)
-{
-	struct generic_ohci *priv = dev_get_priv(dev);
-	int ret;
-
-	ret = generic_phy_get_by_index(dev, index, &priv->phy);
-	if (ret) {
-		if (ret != -ENOENT) {
-			dev_err(dev, "failed to get usb phy\n");
-			return ret;
-		}
-	} else {
-		ret = generic_phy_init(&priv->phy);
-		if (ret) {
-			dev_dbg(dev, "failed to init usb phy\n");
-			return ret;
-		}
-
-		ret = generic_phy_power_on(&priv->phy);
-		if (ret) {
-			dev_dbg(dev, "failed to power on usb phy\n");
-			return generic_phy_exit(&priv->phy);
-		}
-	}
-
-	return 0;
-}
-
-static int ohci_shutdown_phy(struct udevice *dev)
-{
-	struct generic_ohci *priv = dev_get_priv(dev);
-	int ret = 0;
-
-	if (generic_phy_valid(&priv->phy)) {
-		ret = generic_phy_power_off(&priv->phy);
-		if (ret) {
-			dev_dbg(dev, "failed to power off usb phy\n");
-			return ret;
-		}
-
-		ret = generic_phy_exit(&priv->phy);
-		if (ret) {
-			dev_dbg(dev, "failed to power off usb phy\n");
-			return ret;
-		}
-	}
-
-	return 0;
-}
-
 static int ohci_usb_probe(struct udevice *dev)
 {
 	struct ohci_regs *regs = dev_read_addr_ptr(dev);
@@ -135,7 +85,7 @@
 		goto clk_err;
 	}
 
-	err = ohci_setup_phy(dev, 0);
+	err = generic_setup_phy(dev, &priv->phy, 0);
 	if (err)
 		goto reset_err;
 
@@ -146,7 +96,7 @@
 	return 0;
 
 phy_err:
-	ret = ohci_shutdown_phy(dev);
+	ret = generic_shutdown_phy(&priv->phy);
 	if (ret)
 		dev_err(dev, "failed to shutdown usb phy\n");
 
@@ -171,7 +121,7 @@
 	if (ret)
 		return ret;
 
-	ret = ohci_shutdown_phy(dev);
+	ret = generic_shutdown_phy(&priv->phy);
 	if (ret)
 		return ret;
 
diff --git a/examples/standalone/stubs.c b/examples/standalone/stubs.c
index ce05f41..6511557 100644
--- a/examples/standalone/stubs.c
+++ b/examples/standalone/stubs.c
@@ -14,7 +14,7 @@
  * from flash memory. The global_data address is passed as argv[-1]
  * to the application program.
  */
-static struct jt_funcs *jt;
+struct jt_funcs *jt;
 gd_t *global_data;
 
 #define EXPORT_FUNC(f, a, x, ...) \
diff --git a/include/clk.h b/include/clk.h
index 76bb64b..407513e 100644
--- a/include/clk.h
+++ b/include/clk.h
@@ -88,8 +88,9 @@
 	unsigned int count;
 };
 
-#if CONFIG_IS_ENABLED(OF_CONTROL) && CONFIG_IS_ENABLED(CLK)
 struct phandle_1_arg;
+
+#if CONFIG_IS_ENABLED(OF_CONTROL) && CONFIG_IS_ENABLED(CLK)
 /**
  * clk_get_by_phandle() - Get a clock by its phandle information (of-platadata)
  * @dev: Device containing the phandle
@@ -258,12 +259,26 @@
 void devm_clk_put(struct udevice *dev, struct clk *clk);
 
 #else
+
+static inline int clk_get_by_phandle(struct udevice *dev, const
+				     struct phandle_1_arg *cells,
+				     struct clk *clk)
+{
+	return -ENOSYS;
+}
+
 static inline int clk_get_by_index(struct udevice *dev, int index,
 				   struct clk *clk)
 {
 	return -ENOSYS;
 }
 
+static inline int clk_get_by_index_nodev(ofnode node, int index,
+					 struct clk *clk)
+{
+	return -ENOSYS;
+}
+
 static inline int clk_get_bulk(struct udevice *dev, struct clk_bulk *bulk)
 {
 	return -ENOSYS;
@@ -275,6 +290,17 @@
 	return -ENOSYS;
 }
 
+static inline struct clk *devm_clk_get(struct udevice *dev, const char *id)
+{
+	return ERR_PTR(-ENOSYS);
+}
+
+static inline struct clk *devm_clk_get_optional(struct udevice *dev,
+						const char *id)
+{
+	return ERR_PTR(-ENOSYS);
+}
+
 static inline int
 clk_get_by_name_nodev(ofnode node, const char *name, struct clk *clk)
 {
@@ -285,6 +311,10 @@
 {
 	return -ENOSYS;
 }
+
+static inline void devm_clk_put(struct udevice *dev, struct clk *clk)
+{
+}
 #endif
 
 /**
diff --git a/include/configs/arbel.h b/include/configs/arbel.h
new file mode 100644
index 0000000..f7deba4
--- /dev/null
+++ b/include/configs/arbel.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2022 Nuvoton Technology Corp.
+ */
+
+#ifndef __CONFIG_ARBEL_H
+#define __CONFIG_ARBEL_H
+
+#define CONFIG_SYS_SDRAM_BASE		0x0
+#define CONFIG_SYS_BOOTMAPSZ		(20 << 20)
+#define CONFIG_SYS_INIT_RAM_ADDR	CONFIG_SYS_SDRAM_BASE
+#define CONFIG_SYS_INIT_RAM_SIZE	0x8000
+
+/* Default environemnt variables */
+#define CONFIG_EXTRA_ENV_SETTINGS   "uimage_flash_addr=80200000\0"   \
+		"stdin=serial\0"   \
+		"stdout=serial\0"   \
+		"stderr=serial\0"    \
+		"ethact=gmac1\0"   \
+		"autostart=no\0"   \
+		"ethaddr=00:00:F7:A0:00:FC\0"    \
+		"eth1addr=00:00:F7:A0:00:FD\0"   \
+		"eth2addr=00:00:F7:A0:00:FE\0"    \
+		"eth3addr=00:00:F7:A0:00:FF\0"    \
+		"serverip=192.168.0.1\0"    \
+		"ipaddr=192.168.0.2\0"    \
+		"romboot=echo Booting Kernel from flash at 0x${uimage_flash_addr}; " \
+		"echo Using bootargs: ${bootargs};bootm ${uimage_flash_addr}\0" \
+		"earlycon=uart8250,mmio32,0xf0000000\0" \
+		"console=ttyS0,115200n8\0" \
+		"common_bootargs=setenv bootargs earlycon=${earlycon} root=/dev/ram " \
+		"console=${console} ramdisk_size=48000\0" \
+		"\0"
+
+#endif
diff --git a/include/configs/km/km_arm.h b/include/configs/km/km_arm.h
deleted file mode 100644
index a91e5e8..0000000
--- a/include/configs/km/km_arm.h
+++ /dev/null
@@ -1,158 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * (C) Copyright 2009
- * Marvell Semiconductor <www.marvell.com>
- * Prafulla Wadaskar <prafulla@marvell.com>
- *
- * (C) Copyright 2009
- * Stefan Roese, DENX Software Engineering, sr@denx.de.
- *
- * (C) Copyright 2010-2011
- * Heiko Schocher, DENX Software Engineering, hs@denx.de.
- */
-
-/*
- * for linking errors see
- * http://lists.denx.de/pipermail/u-boot/2009-July/057350.html
- */
-
-#ifndef _CONFIG_KM_ARM_H
-#define _CONFIG_KM_ARM_H
-
-#define CONFIG_NAND_ECC_BCH
-
-/* include common defines/options for all Keymile boards */
-#include "keymile-common.h"
-
-/* Increase max size of compressed kernel */
-
-#include "asm/arch/config.h"
-
-/* architecture specific default bootargs */
-#define CONFIG_KM_DEF_BOOT_ARGS_CPU					\
-		"bootcountaddr=${bootcountaddr} ${mtdparts}"		\
-		" boardid=0x${IVM_BoardId} hwkey=0x${IVM_HWKey}"
-
-#define CONFIG_KM_DEF_ENV_CPU						\
-	"u-boot=" CONFIG_HOSTNAME "/u-boot.kwb\0"		\
-	CONFIG_KM_UPDATE_UBOOT						\
-	"set_fdthigh=setenv fdt_high ${kernelmem}\0"			\
-	"checkfdt="							\
-		"if cramfsls fdt_0x${IVM_BoardId}_0x${IVM_HWKey}.dtb; "	\
-		"then true; else setenv cramfsloadfdt true; "		\
-		"setenv boot bootm ${load_addr_r}; "			\
-		"echo No FDT found, booting with the kernel "		\
-		"appended one; fi\0"					\
-	""
-
-/*
- * NAND Flash configuration
- */
-#define CONFIG_SYS_MAX_NAND_DEVICE	1
-
-/*
- * Other required minimal configurations
- */
-
-/*
- * Ethernet Driver configuration
- */
-#define PHY_ANEG_TIMEOUT	8000	/* PHY needs a longer autoneg timeout */
-#define CONFIG_MVGBE_PORTS	{1, 0}	/* enable port 0 only */
-#define CONFIG_PHY_BASE_ADR	0
-
-/*
- * I2C related stuff
- */
-#undef CONFIG_I2C_MVTWSI
-#define CONFIG_SYS_I2C_INIT_BOARD
-
-#define CONFIG_SYS_NUM_I2C_BUSES	6
-#define CONFIG_SYS_I2C_MAX_HOPS		1
-#define CONFIG_SYS_I2C_BUSES	{	{0, {I2C_NULL_HOP} }, \
-					{0, {{I2C_MUX_PCA9547, 0x70, 1} } }, \
-					{0, {{I2C_MUX_PCA9547, 0x70, 2} } }, \
-					{0, {{I2C_MUX_PCA9547, 0x70, 3} } }, \
-					{0, {{I2C_MUX_PCA9547, 0x70, 4} } }, \
-					{0, {{I2C_MUX_PCA9547, 0x70, 5} } }, \
-				}
-
-#ifndef __ASSEMBLY__
-#include <asm/arch/gpio.h>
-#include <linux/delay.h>
-#include <linux/stringify.h>
-extern void __set_direction(unsigned pin, int high);
-#define KM_KIRKWOOD_SDA_PIN	8
-#define KM_KIRKWOOD_SCL_PIN	9
-#define KM_KIRKWOOD_SOFT_I2C_GPIOS	0x0300
-#define KM_KIRKWOOD_ENV_WP	38
-
-#define I2C_ACTIVE	__set_direction(KM_KIRKWOOD_SDA_PIN, 0)
-#define I2C_TRISTATE	__set_direction(KM_KIRKWOOD_SDA_PIN, 1)
-#define I2C_READ	(kw_gpio_get_value(KM_KIRKWOOD_SDA_PIN) ? 1 : 0)
-#define I2C_SDA(bit)	kw_gpio_set_value(KM_KIRKWOOD_SDA_PIN, bit)
-#define I2C_SCL(bit)	kw_gpio_set_value(KM_KIRKWOOD_SCL_PIN, bit)
-#endif
-
-#define I2C_DELAY	udelay(1)
-#define I2C_SOFT_DECLARATIONS
-
-/*
- *  Environment variables configurations
- */
-#if defined CONFIG_KM_ENV_IS_IN_SPI_NOR
-#define CONFIG_ENV_TOTAL_SIZE		0x20000     /* no bracets! */
-#else
-#define CONFIG_SYS_EEPROM_WREN
-#define CONFIG_I2C_ENV_EEPROM_BUS 5 /* I2C2 (Mux-Port 5) */
-#endif
-
-#define KM_FLASH_GPIO_PIN	16
-
-#define	CONFIG_KM_UPDATE_UBOOT						\
-	"update="							\
-		"sf probe 0;sf erase 0 +${filesize};"			\
-		"sf write ${load_addr_r} 0 ${filesize};\0"
-
-#if defined CONFIG_KM_ENV_IS_IN_SPI_NOR
-#define CONFIG_KM_NEW_ENV						\
-	"newenv=sf probe 0;"						\
-		"sf erase " __stringify(CONFIG_ENV_OFFSET) " "		\
-		__stringify(CONFIG_ENV_TOTAL_SIZE)"\0"
-#else
-#define CONFIG_KM_NEW_ENV						\
-	"newenv=setenv addr 0x100000 && "				\
-		"i2c dev " __stringify(CONFIG_I2C_ENV_EEPROM_BUS) "; "  \
-		"mw.b ${addr} 0 4 && "					\
-		"eeprom write " __stringify(CONFIG_SYS_I2C_EEPROM_ADDR)	\
-		" ${addr} " __stringify(CONFIG_ENV_OFFSET) " 4 && "	\
-		"eeprom write " __stringify(CONFIG_SYS_I2C_EEPROM_ADDR)	\
-		" ${addr} " __stringify(CONFIG_ENV_OFFSET_REDUND) " 4\0"
-#endif
-
-#ifndef CONFIG_KM_BOARD_EXTRA_ENV
-#define CONFIG_KM_BOARD_EXTRA_ENV       ""
-#endif
-
-/*
- * Default environment variables
- */
-#define CONFIG_EXTRA_ENV_SETTINGS					\
-	CONFIG_KM_BOARD_EXTRA_ENV					\
-	CONFIG_KM_DEF_ENV						\
-	CONFIG_KM_NEW_ENV						\
-	"arch=arm\0"							\
-	""
-
-/* additions for new relocation code, must be added to all boards */
-#define CONFIG_SYS_SDRAM_BASE		0x00000000
-
-/* address for the bootcount (taken from end of RAM) */
-#define BOOTCOUNT_ADDR          (CONFIG_KM_RESERVED_PRAM)
-
-/* enable POST tests */
-#define CONFIG_POST	(CONFIG_SYS_POST_MEM_REGIONS)
-#define CONFIG_POST_SKIP_ENV_FLAGS
-#define CONFIG_POST_EXTERNAL_WORD_FUNCS
-
-#endif /* _CONFIG_KM_ARM_H */
diff --git a/include/configs/km_kirkwood.h b/include/configs/km_kirkwood.h
deleted file mode 100644
index 01482d5..0000000
--- a/include/configs/km_kirkwood.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * (C) Copyright 2009
- * Marvell Semiconductor <www.marvell.com>
- * Prafulla Wadaskar <prafulla@marvell.com>
- *
- * (C) Copyright 2009
- * Stefan Roese, DENX Software Engineering, sr@denx.de.
- *
- * (C) Copyright 2011-2012
- * Holger Brunck, Keymile GmbH Hannover, holger.brunck@keymile.com
- * Valentin Longchamp, Keymile AG, valentin.longchamp@keymile.com
- */
-
-/*
- * for linking errors see
- * http://lists.denx.de/pipermail/u-boot/2009-July/057350.html
- */
-
-#ifndef _CONFIG_KM_KIRKWOOD_H
-#define _CONFIG_KM_KIRKWOOD_H
-
-/* KM_KIRKWOOD */
-#if defined(CONFIG_KM_KIRKWOOD)
-#define CONFIG_HOSTNAME			"km_kirkwood"
-
-/* KM_KIRKWOOD_PCI */
-#elif defined(CONFIG_KM_KIRKWOOD_PCI)
-#define CONFIG_HOSTNAME			"km_kirkwood_pci"
-#define CONFIG_KM_UBI_PART_BOOT_OPTS		",2048"
-#define CONFIG_SYS_NAND_NO_SUBPAGE_WRITE
-
-/* KM_KIRKWOOD_128M16 */
-#elif defined(CONFIG_KM_KIRKWOOD_128M16)
-#define CONFIG_HOSTNAME			"km_kirkwood_128m16"
-
-/* KM_NUSA */
-#elif defined(CONFIG_KM_NUSA)
-
-#define CONFIG_HOSTNAME			"kmnusa"
-
-/* KMCOGE5UN */
-#elif defined(CONFIG_KM_COGE5UN)
-#define CONFIG_HOSTNAME			"kmcoge5un"
-
-/* KM_SUSE2 */
-#elif defined(CONFIG_KM_SUSE2)
-#define CONFIG_HOSTNAME			"kmsuse2"
-#define CONFIG_KM_UBI_PART_BOOT_OPTS		",2048"
-#define CONFIG_SYS_NAND_NO_SUBPAGE_WRITE
-#else
-#error ("Board unsupported")
-#endif
-
-/* include common defines/options for all arm based Keymile boards */
-#include "km/km_arm.h"
-
-#if defined(CONFIG_KM_PIGGY4_88E6352)
-/*
- * Some keymile boards like mgcoge5un & nusa1 have their PIGGY4 connected via
- * an Marvell 88E6352 simple switch.
- * In this case we have to change the default settings for the etherent mac.
- * There is NO ethernet phy. The ARM and Switch are conencted directly over
- * RGMII in MAC-MAC mode
- * In this case 1GBit full duplex and autoneg off
- */
-#define PORT_SERIAL_CONTROL_VALUE		( \
-	MVGBE_FORCE_LINK_PASS			    | \
-	MVGBE_DIS_AUTO_NEG_FOR_DUPLX		| \
-	MVGBE_DIS_AUTO_NEG_FOR_FLOW_CTRL	| \
-	MVGBE_ADV_NO_FLOW_CTRL			    | \
-	MVGBE_FORCE_FC_MODE_NO_PAUSE_DIS_TX	| \
-	MVGBE_FORCE_BP_MODE_NO_JAM		    | \
-	(1 << 9) /* Reserved bit has to be 1 */	| \
-	MVGBE_DO_NOT_FORCE_LINK_FAIL		| \
-	MVGBE_DIS_AUTO_NEG_SPEED_GMII		| \
-	MVGBE_DTE_ADV_0				        | \
-	MVGBE_MIIPHY_MAC_MODE			    | \
-	MVGBE_AUTO_NEG_NO_CHANGE		    | \
-	MVGBE_MAX_RX_PACKET_1552BYTE		| \
-	MVGBE_CLR_EXT_LOOPBACK			    | \
-	MVGBE_SET_FULL_DUPLEX_MODE		    | \
-	MVGBE_EN_FLOW_CTRL_TX_RX_IN_FULL_DUPLEX	|\
-	MVGBE_SET_GMII_SPEED_TO_1000	    |\
-	MVGBE_SET_MII_SPEED_TO_100)
-
-#endif
-
-#ifdef CONFIG_KM_PIGGY4_88E6061
-/*
- * Some keymile boards like mgcoge5un have their PIGGY4 connected via
- * an Marvell 88E6061 simple switch.
- * In this case we have to change the default settings for the
- * ethernet phy connected to the kirkwood.
- * In this case 100MB full duplex and autoneg off
- */
-#define PORT_SERIAL_CONTROL_VALUE		( \
-	MVGBE_FORCE_LINK_PASS			| \
-	MVGBE_DIS_AUTO_NEG_FOR_DUPLX		| \
-	MVGBE_DIS_AUTO_NEG_FOR_FLOW_CTRL	| \
-	MVGBE_ADV_NO_FLOW_CTRL			| \
-	MVGBE_FORCE_FC_MODE_NO_PAUSE_DIS_TX	| \
-	MVGBE_FORCE_BP_MODE_NO_JAM		| \
-	(1 << 9) /* Reserved bit has to be 1 */	| \
-	MVGBE_DO_NOT_FORCE_LINK_FAIL		| \
-	MVGBE_DIS_AUTO_NEG_SPEED_GMII		| \
-	MVGBE_DTE_ADV_0				| \
-	MVGBE_MIIPHY_MAC_MODE			| \
-	MVGBE_AUTO_NEG_NO_CHANGE		| \
-	MVGBE_MAX_RX_PACKET_1552BYTE		| \
-	MVGBE_CLR_EXT_LOOPBACK			| \
-	MVGBE_SET_FULL_DUPLEX_MODE		| \
-	MVGBE_DIS_FLOW_CTRL_TX_RX_IN_FULL_DUPLEX	|\
-	MVGBE_SET_GMII_SPEED_TO_10_100	|\
-	MVGBE_SET_MII_SPEED_TO_100)
-#endif
-
-#endif /* _CONFIG_KM_KIRKWOOD */
diff --git a/include/dt-bindings/clock/nuvoton,npcm845-clk.h b/include/dt-bindings/clock/nuvoton,npcm845-clk.h
new file mode 100644
index 0000000..7f754f7
--- /dev/null
+++ b/include/dt-bindings/clock/nuvoton,npcm845-clk.h
@@ -0,0 +1,52 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2022 Nuvoton Technology Corp.
+ *
+ * Device Tree binding constants for NPCM8XX clock controller.
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_NPCM8XX_H
+#define __DT_BINDINGS_CLOCK_NPCM8XX_H
+
+#define NPCM8XX_CLK_CPU		0
+#define NPCM8XX_CLK_GFX_PIXEL	1
+#define NPCM8XX_CLK_MC		2
+#define NPCM8XX_CLK_ADC		3
+#define NPCM8XX_CLK_AHB		4
+#define NPCM8XX_CLK_TIMER	5
+#define NPCM8XX_CLK_UART	6
+#define NPCM8XX_CLK_UART2	7
+#define NPCM8XX_CLK_MMC		8
+#define NPCM8XX_CLK_SPI3	9
+#define NPCM8XX_CLK_PCI		10
+#define NPCM8XX_CLK_AXI		11
+#define NPCM8XX_CLK_APB4	12
+#define NPCM8XX_CLK_APB3	13
+#define NPCM8XX_CLK_APB2	14
+#define NPCM8XX_CLK_APB1	15
+#define NPCM8XX_CLK_APB5	16
+#define NPCM8XX_CLK_CLKOUT	17
+#define NPCM8XX_CLK_GFX		18
+#define NPCM8XX_CLK_SU		19
+#define NPCM8XX_CLK_SU48	20
+#define NPCM8XX_CLK_SDHC	21
+#define NPCM8XX_CLK_SPI0	22
+#define NPCM8XX_CLK_SPI1	23
+#define NPCM8XX_CLK_SPIX	24
+#define NPCM8XX_CLK_RG		25
+#define NPCM8XX_CLK_RCP		26
+#define NPCM8XX_CLK_PRE_ADC	27
+#define NPCM8XX_CLK_ATB		28
+#define NPCM8XX_CLK_PRE_CLK	29
+#define NPCM8XX_CLK_TH		30
+#define NPCM8XX_CLK_REFCLK	31
+#define NPCM8XX_CLK_SYSBYPCK	32
+#define NPCM8XX_CLK_MCBYPCK	33
+#define NPCM8XX_CLK_PLL0	34
+#define NPCM8XX_CLK_PLL1	35
+#define NPCM8XX_CLK_PLL2	36
+#define NPCM8XX_CLK_PLL2DIV2	37
+
+#define NPCM8XX_NUM_CLOCKS	(NPCM8XX_CLK_PLL2DIV2 + 1)
+
+#endif
diff --git a/include/dt-bindings/reset/nuvoton,npcm8xx-reset.h b/include/dt-bindings/reset/nuvoton,npcm8xx-reset.h
new file mode 100644
index 0000000..a756798
--- /dev/null
+++ b/include/dt-bindings/reset/nuvoton,npcm8xx-reset.h
@@ -0,0 +1,124 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+// Copyright (c) 2020 Nuvoton Technology corporation.
+
+#ifndef _DT_BINDINGS_NPCM8XX_RESET_H
+#define _DT_BINDINGS_NPCM8XX_RESET_H
+
+#define NPCM8XX_RESET_IPSRST1		0x20
+#define NPCM8XX_RESET_IPSRST2		0x24
+#define NPCM8XX_RESET_IPSRST3		0x34
+#define NPCM8XX_RESET_IPSRST4		0x74
+
+/* Reset lines on IP1 reset module (NPCM8XX_RESET_IPSRST1) */
+#define NPCM8XX_RESET_GDMA0		3
+#define NPCM8XX_RESET_UDC1		5
+#define NPCM8XX_RESET_GMAC3		6
+#define NPCM8XX_RESET_UART_2_3		7
+#define NPCM8XX_RESET_UDC2		8
+#define NPCM8XX_RESET_PECI		9
+#define NPCM8XX_RESET_AES		10
+#define NPCM8XX_RESET_UART_0_1		11
+#define NPCM8XX_RESET_MC		12
+#define NPCM8XX_RESET_SMB2		13
+#define NPCM8XX_RESET_SMB3		14
+#define NPCM8XX_RESET_SMB4		15
+#define NPCM8XX_RESET_SMB5		16
+#define NPCM8XX_RESET_PWM_M0		18
+#define NPCM8XX_RESET_TIMER_0_4		19
+#define NPCM8XX_RESET_TIMER_5_9		20
+#define NPCM8XX_RESET_GMAC4		21
+#define NPCM8XX_RESET_UDC4		22
+#define NPCM8XX_RESET_UDC5		23
+#define NPCM8XX_RESET_UDC6		24
+#define NPCM8XX_RESET_UDC3		25
+#define NPCM8XX_RESET_ADC		27
+#define NPCM8XX_RESET_SMB6		28
+#define NPCM8XX_RESET_SMB7		29
+#define NPCM8XX_RESET_SMB0		30
+#define NPCM8XX_RESET_SMB1		31
+
+/* Reset lines on IP2 reset module (NPCM8XX_RESET_IPSRST2) */
+#define NPCM8XX_RESET_MFT0		0
+#define NPCM8XX_RESET_MFT1		1
+#define NPCM8XX_RESET_MFT2		2
+#define NPCM8XX_RESET_MFT3		3
+#define NPCM8XX_RESET_MFT4		4
+#define NPCM8XX_RESET_MFT5		5
+#define NPCM8XX_RESET_MFT6		6
+#define NPCM8XX_RESET_MFT7		7
+#define NPCM8XX_RESET_MMC		8
+#define NPCM8XX_RESET_GFX_SYS		10
+#define NPCM8XX_RESET_AHB_PCIBRG	11
+#define NPCM8XX_RESET_VDMA		12
+#define NPCM8XX_RESET_ECE		13
+#define NPCM8XX_RESET_VCD		14
+#define NPCM8XX_RESET_VIRUART1		16
+#define NPCM8XX_RESET_VIRUART2		17
+#define NPCM8XX_RESET_SIOX1		18
+#define NPCM8XX_RESET_SIOX2		19
+#define NPCM8XX_RESET_BT		20
+#define NPCM8XX_RESET_3DES		21
+#define NPCM8XX_RESET_PSPI2		23
+#define NPCM8XX_RESET_GMAC2		25
+#define NPCM8XX_RESET_USBH1		26
+#define NPCM8XX_RESET_GMAC1		28
+#define NPCM8XX_RESET_CP1		31
+
+/* Reset lines on IP3 reset module (NPCM8XX_RESET_IPSRST3) */
+#define NPCM8XX_RESET_PWM_M1		0
+#define NPCM8XX_RESET_SMB12		1
+#define NPCM8XX_RESET_SPIX		2
+#define NPCM8XX_RESET_SMB13		3
+#define NPCM8XX_RESET_UDC0		4
+#define NPCM8XX_RESET_UDC7		5
+#define NPCM8XX_RESET_UDC8		6
+#define NPCM8XX_RESET_UDC9		7
+#define NPCM8XX_RESET_USBHUB		8
+#define NPCM8XX_RESET_PCI_MAILBOX	9
+#define NPCM8XX_RESET_GDMA1		10
+#define NPCM8XX_RESET_GDMA2		11
+#define NPCM8XX_RESET_SMB14		12
+#define NPCM8XX_RESET_SHA		13
+#define NPCM8XX_RESET_SEC_ECC		14
+#define NPCM8XX_RESET_PCIE_RC		15
+#define NPCM8XX_RESET_TIMER_10_14	16
+#define NPCM8XX_RESET_RNG		17
+#define NPCM8XX_RESET_SMB15		18
+#define NPCM8XX_RESET_SMB8		19
+#define NPCM8XX_RESET_SMB9		20
+#define NPCM8XX_RESET_SMB10		21
+#define NPCM8XX_RESET_SMB11		22
+#define NPCM8XX_RESET_ESPI		23
+#define NPCM8XX_RESET_USBPHY1		24
+#define NPCM8XX_RESET_USBPHY2		25
+
+/* Reset lines on IP4 reset module (NPCM8XX_RESET_IPSRST4) */
+#define NPCM8XX_RESET_SMB16		0
+#define NPCM8XX_RESET_SMB17		1
+#define NPCM8XX_RESET_SMB18		2
+#define NPCM8XX_RESET_SMB19		3
+#define NPCM8XX_RESET_SMB20		4
+#define NPCM8XX_RESET_SMB21		5
+#define NPCM8XX_RESET_SMB22		6
+#define NPCM8XX_RESET_SMB23		7
+#define NPCM8XX_RESET_I3C0		8
+#define NPCM8XX_RESET_I3C1		9
+#define NPCM8XX_RESET_I3C2		10
+#define NPCM8XX_RESET_I3C3		11
+#define NPCM8XX_RESET_I3C4		12
+#define NPCM8XX_RESET_I3C5		13
+#define NPCM8XX_RESET_UART4		16
+#define NPCM8XX_RESET_UART5		17
+#define NPCM8XX_RESET_UART6		18
+#define NPCM8XX_RESET_PCIMBX2		19
+#define NPCM8XX_RESET_SMB24		22
+#define NPCM8XX_RESET_SMB25		23
+#define NPCM8XX_RESET_SMB26		24
+#define NPCM8XX_RESET_USBPHY3		25
+#define NPCM8XX_RESET_PCIRCPHY		27
+#define NPCM8XX_RESET_PWM_M2		28
+#define NPCM8XX_RESET_JTM1		29
+#define NPCM8XX_RESET_JTM2		30
+#define NPCM8XX_RESET_USBH2		31
+
+#endif
diff --git a/include/efi.h b/include/efi.h
index 6159f34..42f4e58 100644
--- a/include/efi.h
+++ b/include/efi.h
@@ -37,12 +37,14 @@
 #define EFIAPI __attribute__((ms_abi))
 #define efi_va_list __builtin_ms_va_list
 #define efi_va_start __builtin_ms_va_start
+#define efi_va_copy __builtin_ms_va_copy
 #define efi_va_arg __builtin_va_arg
 #define efi_va_end __builtin_ms_va_end
 #else
 #define EFIAPI asmlinkage
 #define efi_va_list va_list
 #define efi_va_start va_start
+#define efi_va_copy va_copy
 #define efi_va_arg va_arg
 #define efi_va_end va_end
 #endif /* __x86_64__ */
diff --git a/include/efi_driver.h b/include/efi_driver.h
index 2b62219..63a95e4 100644
--- a/include/efi_driver.h
+++ b/include/efi_driver.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0+ */
 /*
- *  EFI application loader
+ *  Internal structures for the EFI driver binding protocol
  *
  *  Copyright (c) 2017 Heinrich Schuchardt
  */
@@ -10,30 +10,39 @@
 
 #include <efi_loader.h>
 
-/*
- * Operations supported by an EFI driver with respect to the EFI uclass
+/**
+ * struct efi_driver_binding_extended_protocol - extended driver binding protocol
  *
- * @protocol		The GUID of the protocol which is consumed by the
+ * This structure adds internal fields to the driver binding protocol.
+ *
+ * @bp:		driver binding protocol
+ * @ops:	operations supported by the driver
+ */
+struct efi_driver_binding_extended_protocol {
+	struct efi_driver_binding_protocol bp;
+	const struct efi_driver_ops *ops;
+};
+
+/**
+ * struct efi_driver_ops - operations support by an EFI driver
+ *
+ * @protocol:		The GUID of the protocol which is consumed by the
  *			driver. This GUID is used by the EFI uclass in the
  *			supports() and start() methods of the
  *			EFI_DRIVER_BINDING_PROTOCOL.
- * @child_protocol	Protocol supported by the child handles generated by
+ * @child_protocol:	Protocol supported by the child handles generated by
  *			the EFI driver.
- * @bind		Function called by the EFI uclass to attach the
+ * @init:		Function called by the EFI uclass after installing the
+ *			driver binding protocol.
+ * @bind:		Function called by the EFI uclass to attach the
  *			driver to EFI driver to a handle.
  */
 struct efi_driver_ops {
 	const efi_guid_t *protocol;
 	const efi_guid_t *child_protocol;
-	int (*bind)(efi_handle_t handle, void *interface);
-};
-
-/*
- * This structure adds internal fields to the driver binding protocol.
- */
-struct efi_driver_binding_extended_protocol {
-	struct efi_driver_binding_protocol bp;
-	const struct efi_driver_ops *ops;
+	efi_status_t (*init)(struct efi_driver_binding_extended_protocol *this);
+	efi_status_t (*bind)(struct efi_driver_binding_extended_protocol *this,
+			     efi_handle_t handle, void *interface);
 };
 
 #endif /* _EFI_DRIVER_H */
diff --git a/include/efi_loader.h b/include/efi_loader.h
index ad01395..1bac3f4 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -10,6 +10,7 @@
 
 #include <common.h>
 #include <blk.h>
+#include <event.h>
 #include <log.h>
 #include <part_efi.h>
 #include <efi_api.h>
@@ -544,8 +545,6 @@
 void efi_try_purge_kaslr_seed(void *fdt);
 /* Called by bootefi to make console interface available */
 efi_status_t efi_console_register(void);
-/* Called by efi_init_early() to add block devices when probed */
-efi_status_t efi_disk_init(void);
 /* Called by efi_init_obj_list() to proble all block devices */
 efi_status_t efi_disks_register(void);
 /* Called by efi_init_obj_list() to install EFI_RNG_PROTOCOL */
@@ -652,21 +651,20 @@
 efi_status_t efi_remove_protocol(const efi_handle_t handle,
 				 const efi_guid_t *protocol,
 				 void *protocol_interface);
-/* Delete all protocols from a handle */
-efi_status_t efi_remove_all_protocols(const efi_handle_t handle);
 /* Install multiple protocol interfaces */
-efi_status_t EFIAPI efi_install_multiple_protocol_interfaces
-				(efi_handle_t *handle, ...);
+efi_status_t EFIAPI
+efi_install_multiple_protocol_interfaces(efi_handle_t *handle, ...);
+efi_status_t EFIAPI
+efi_uninstall_multiple_protocol_interfaces(efi_handle_t handle, ...);
 /* Get handles that support a given protocol */
 efi_status_t EFIAPI efi_locate_handle_buffer(
 			enum efi_locate_search_type search_type,
 			const efi_guid_t *protocol, void *search_key,
 			efi_uintn_t *no_handles, efi_handle_t **buffer);
-/* Close an previously opened protocol interface */
-efi_status_t EFIAPI efi_close_protocol(efi_handle_t handle,
-				       const efi_guid_t *protocol,
-				       efi_handle_t agent_handle,
-				       efi_handle_t controller_handle);
+/* Close a previously opened protocol interface */
+efi_status_t efi_close_protocol(efi_handle_t handle, const efi_guid_t *protocol,
+				efi_handle_t agent_handle,
+				efi_handle_t controller_handle);
 /* Open a protocol interface */
 efi_status_t EFIAPI efi_handle_protocol(efi_handle_t handle,
 					const efi_guid_t *protocol,
@@ -708,6 +706,7 @@
 int algo_to_len(const char *algo);
 
 int efi_link_dev(efi_handle_t handle, struct udevice *dev);
+int efi_unlink_dev(efi_handle_t handle);
 
 /**
  * efi_size_in_pages() - convert size in bytes to size in pages
@@ -748,6 +747,10 @@
 
 /* Called by board init to initialize the EFI drivers */
 efi_status_t efi_driver_init(void);
+/* Called when a block device is added */
+int efi_disk_probe(void *ctx, struct event *event);
+/* Called when a block device is removed */
+int efi_disk_remove(void *ctx, struct event *event);
 /* Called by board init to initialize the EFI memory map */
 int efi_memory_init(void);
 /* Adds new or overrides configuration table entry to the system table */
@@ -1014,9 +1017,10 @@
 /* runtime implementation of memcpy() */
 void efi_memcpy_runtime(void *dest, const void *src, size_t n);
 
-/* commonly used helper function */
+/* commonly used helper functions */
 u16 *efi_create_indexed_name(u16 *buffer, size_t buffer_size, const char *name,
 			     unsigned int index);
+efi_string_t efi_convert_string(const char *str);
 
 extern const struct efi_firmware_management_protocol efi_fmp_fit;
 extern const struct efi_firmware_management_protocol efi_fmp_raw;
diff --git a/include/generic-phy.h b/include/generic-phy.h
index d40ce58..f8eddef 100644
--- a/include/generic-phy.h
+++ b/include/generic-phy.h
@@ -342,6 +342,26 @@
  */
 int generic_phy_power_off_bulk(struct phy_bulk *bulk);
 
+/**
+ * generic_setup_phy() - Get, initialize and power on phy.
+ *
+ * @dev:	The consumer device.
+ * @phy:	A pointer to the PHY port
+ * @index:	The index in the list of available PHYs
+ *
+ * Return: 0 if OK, or negative error code.
+ */
+int generic_setup_phy(struct udevice *dev, struct phy *phy, int index);
+
+/**
+ * generic_shutdown_phy() - Power off and de-initialize phy.
+ *
+ * @phy:	A pointer to the PHY port.
+ *
+ * Return: 0 if OK, or negative error code.
+ */
+int generic_shutdown_phy(struct phy *phy);
+
 #else /* CONFIG_PHY */
 
 static inline int generic_phy_init(struct phy *phy)
@@ -407,6 +427,16 @@
 	return 0;
 }
 
+static inline int generic_setup_phy(struct udevice *dev, struct phy *phy, int index)
+{
+	return 0;
+}
+
+static inline int generic_shutdown_phy(struct phy *phy)
+{
+	return 0;
+}
+
 #endif /* CONFIG_PHY */
 
 /**
diff --git a/include/init.h b/include/init.h
index 50a8302..d40d11f 100644
--- a/include/init.h
+++ b/include/init.h
@@ -104,6 +104,19 @@
 int testdram(void);
 
 /**
+ * arch_setup_dest_addr() - Fix up initial reloc address
+ *
+ * This is called in generic board init sequence in common/board_f.c at the end
+ * of the setup_dest_addr() initcall. Each architecture could provide this
+ * function to make adjustments to the initial reloc address.
+ *
+ * If an implementation is not provided, it will just be a nop stub.
+ *
+ * Return: 0 if OK
+ */
+int arch_setup_dest_addr(void);
+
+/**
  * arch_reserve_stacks() - Reserve all necessary stacks
  *
  * This is used in generic board init sequence in common/board_f.c. Each
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index ff635bd..09f5269 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -122,7 +122,7 @@
  * @ecc: function returning an ECC region in the OOB area.
  *	 Should return -ERANGE if %section exceeds the total number of
  *	 ECC sections.
- * @free: function returning a free region in the OOB area.
+ * @rfree: function returning a free region in the OOB area.
  *	  Should return -ERANGE if %section exceeds the total number of
  *	  free sections.
  */
diff --git a/include/mxs_nand.h b/include/mxs_nand.h
index 741dc87..bb5b84b 100644
--- a/include/mxs_nand.h
+++ b/include/mxs_nand.h
@@ -12,6 +12,7 @@
 #include <asm/cache.h>
 #include <nand.h>
 #include <asm/mach-imx/dma.h>
+#include <clk.h>
 
 /**
  * @gf_len:                   The length of Galois Field. (e.g., 13 or 14)
@@ -43,6 +44,7 @@
 	struct nand_chip chip;
 	struct udevice *dev;
 	unsigned int	max_ecc_strength_supported;
+	int		max_chain_delay;
 	bool		use_minimum_ecc;
 	int		cur_chip;
 
@@ -59,6 +61,7 @@
 
 	struct mxs_gpmi_regs *gpmi_regs;
 	struct mxs_bch_regs *bch_regs;
+	struct clk *gpmi_clk;
 
 	/* Functions with altered behaviour */
 	int		(*hooked_read_oob)(struct mtd_info *mtd,
diff --git a/lib/efi_driver/efi_block_device.c b/lib/efi_driver/efi_block_device.c
index 3177ab6..add00ee 100644
--- a/lib/efi_driver/efi_block_device.c
+++ b/lib/efi_driver/efi_block_device.c
@@ -37,11 +37,11 @@
 #include <dm/root.h>
 #include <dm/tag.h>
 
-/*
- * EFI attributes of the udevice handled by this driver.
+/**
+ * struct efi_blk_plat - attributes of a block device
  *
- * handle	handle of the controller on which this driver is installed
- * io		block io protocol proxied by this driver
+ * @handle:	handle of the controller on which this driver is installed
+ * @io:		block io protocol proxied by this driver
  */
 struct efi_blk_plat {
 	efi_handle_t		handle;
@@ -49,7 +49,7 @@
 };
 
 /**
- * Read from block device
+ * efi_bl_read() - read from block device
  *
  * @dev:	device
  * @blknr:	first block to be read
@@ -78,7 +78,7 @@
 }
 
 /**
- * Write to block device
+ * efi_bl_write() - write to block device
  *
  * @dev:	device
  * @blknr:	first block to be write
@@ -108,45 +108,41 @@
 }
 
 /**
- * Create a block device for a handle
+ * efi_bl_create_block_device() - create a block device for a handle
  *
  * @handle:	handle
  * @interface:	block io protocol
- * Return:	0 = success
+ * Return:	status code
  */
-static int efi_bl_bind(efi_handle_t handle, void *interface)
+static efi_status_t
+efi_bl_create_block_device(efi_handle_t handle, void *interface)
 {
-	struct udevice *bdev, *parent = dm_root();
-	int ret, devnum;
+	struct udevice *bdev = NULL, *parent = dm_root();
+	efi_status_t ret;
+	int devnum;
 	char *name;
-	struct efi_object *obj = efi_search_obj(handle);
 	struct efi_block_io *io = interface;
 	struct efi_blk_plat *plat;
 
-	EFI_PRINT("%s: handle %p, interface %p\n", __func__, handle, io);
-
-	if (!obj)
-		return -ENOENT;
-
 	devnum = blk_find_max_devnum(UCLASS_EFI_LOADER);
 	if (devnum == -ENODEV)
 		devnum = 0;
 	else if (devnum < 0)
-		return devnum;
+		return EFI_OUT_OF_RESOURCES;
 
 	name = calloc(1, 18); /* strlen("efiblk#2147483648") + 1 */
 	if (!name)
-		return -ENOMEM;
+		return EFI_OUT_OF_RESOURCES;
 	sprintf(name, "efiblk#%d", devnum);
 
 	/* Create driver model udevice for the EFI block io device */
-	ret = blk_create_device(parent, "efi_blk", name, UCLASS_EFI_LOADER,
-				devnum, io->media->block_size,
-				(lbaint_t)io->media->last_block, &bdev);
-	if (ret)
-		return ret;
-	if (!bdev)
-		return -ENOENT;
+	if (blk_create_device(parent, "efi_blk", name, UCLASS_EFI_LOADER,
+			      devnum, io->media->block_size,
+			      (lbaint_t)io->media->last_block, &bdev)) {
+		ret = EFI_OUT_OF_RESOURCES;
+		free(name);
+		goto err;
+	}
 	/* Set the DM_FLAG_NAME_ALLOCED flag to avoid a memory leak */
 	device_set_name_alloced(bdev);
 
@@ -154,20 +150,78 @@
 	plat->handle = handle;
 	plat->io = interface;
 
-	/*
-	 * FIXME: necessary because we won't do almost nothing in
-	 * efi_disk_create() when called from device_probe().
-	 */
-	if (efi_link_dev(handle, bdev))
-		/* FIXME: cleanup for bdev */
-		return ret;
+	if (efi_link_dev(handle, bdev)) {
+		ret = EFI_OUT_OF_RESOURCES;
+		goto err;
+	}
 
-	ret = device_probe(bdev);
-	if (ret)
-		return ret;
+	if (device_probe(bdev)) {
+		ret = EFI_DEVICE_ERROR;
+		goto err;
+	}
 	EFI_PRINT("%s: block device '%s' created\n", __func__, bdev->name);
 
+	return EFI_SUCCESS;
+
+err:
+	efi_unlink_dev(handle);
+	if (bdev)
+		device_unbind(bdev);
+
+	return ret;
+}
+
+/**
+ * efi_bl_bind() - bind to a block io protocol
+ *
+ * @this:	driver binding protocol
+ * @handle:	handle
+ * @interface:	block io protocol
+ * Return:	status code
+ */
+static efi_status_t efi_bl_bind(
+			struct efi_driver_binding_extended_protocol *this,
+			efi_handle_t handle, void *interface)
+{
+	efi_status_t ret = EFI_SUCCESS;
+	struct efi_object *obj = efi_search_obj(handle);
+
+	EFI_PRINT("%s: handle %p, interface %p\n", __func__, handle, interface);
+
+	if (!obj || !interface)
+		return EFI_INVALID_PARAMETER;
+
+	if (!handle->dev)
+		ret = efi_bl_create_block_device(handle, interface);
+
+	return ret;
+}
+
+/**
+ * efi_bl_init() - initialize block device driver
+ *
+ * @this:	extended driver binding protocol
+ */
+static efi_status_t
+efi_bl_init(struct efi_driver_binding_extended_protocol *this)
+{
+	int ret;
+
+	ret = event_register("efi_disk add", EVT_DM_POST_PROBE,
+			     efi_disk_probe, this);
+	if (ret) {
+		log_err("Event registration for efi_disk add failed\n");
+		return EFI_OUT_OF_RESOURCES;
+	}
+
+	ret = event_register("efi_disk del", EVT_DM_PRE_REMOVE,
+			     efi_disk_remove, this);
+	if (ret) {
+		log_err("Event registration for efi_disk del failed\n");
+		return EFI_OUT_OF_RESOURCES;
+	}
+
-	return 0;
+	return EFI_SUCCESS;
 }
 
 /* Block device driver operators */
@@ -178,9 +232,9 @@
 
 /* Identify as block device driver */
 U_BOOT_DRIVER(efi_blk) = {
-	.name			= "efi_blk",
-	.id			= UCLASS_BLK,
-	.ops			= &efi_blk_ops,
+	.name		= "efi_blk",
+	.id		= UCLASS_BLK,
+	.ops		= &efi_blk_ops,
 	.plat_auto	= sizeof(struct efi_blk_plat),
 };
 
@@ -188,6 +242,7 @@
 static const struct efi_driver_ops driver_ops = {
 	.protocol	= &efi_block_io_guid,
 	.child_protocol = &efi_block_io_guid,
+	.init		= efi_bl_init,
 	.bind		= efi_bl_bind,
 };
 
diff --git a/lib/efi_driver/efi_uclass.c b/lib/efi_driver/efi_uclass.c
index 74dd003..45f9351 100644
--- a/lib/efi_driver/efi_uclass.c
+++ b/lib/efi_driver/efi_uclass.c
@@ -11,7 +11,7 @@
  * The uclass provides the bind, start, and stop entry points for the driver
  * binding protocol.
  *
- * In bind() and stop() it checks if the controller implements the protocol
+ * In supported() and bind() it checks if the controller implements the protocol
  * supported by the EFI driver. In the start() function it calls the bind()
  * function of the EFI driver. In the stop() function it destroys the child
  * controllers.
@@ -97,10 +97,9 @@
 
 	ret = check_node_type(controller_handle);
 
-	r = EFI_CALL(systab.boottime->close_protocol(
-				controller_handle, bp->ops->protocol,
-				this->driver_binding_handle,
-				controller_handle));
+	r = efi_close_protocol(controller_handle, bp->ops->protocol,
+			       this->driver_binding_handle,
+			       controller_handle);
 	if (r != EFI_SUCCESS)
 		ret = EFI_UNSUPPORTED;
 out:
@@ -144,18 +143,18 @@
 		goto out;
 	}
 	ret = check_node_type(controller_handle);
-	if (ret != EFI_SUCCESS) {
-		r = EFI_CALL(systab.boottime->close_protocol(
-				controller_handle, bp->ops->protocol,
-				this->driver_binding_handle,
-				controller_handle));
-		if (r != EFI_SUCCESS)
-			EFI_PRINT("Failure to close handle\n");
+	if (ret != EFI_SUCCESS)
+		goto err;
+	ret = bp->ops->bind(bp, controller_handle, interface);
+	if (ret == EFI_SUCCESS)
 		goto out;
-	}
 
-	/* TODO: driver specific stuff */
-	bp->ops->bind(controller_handle, interface);
+err:
+	r = efi_close_protocol(controller_handle, bp->ops->protocol,
+			       this->driver_binding_handle,
+			       controller_handle);
+	if (r != EFI_SUCCESS)
+		EFI_PRINT("Failure to close handle\n");
 
 out:
 	return EFI_EXIT(ret);
@@ -176,9 +175,8 @@
 	efi_guid_t *guid_controller = NULL;
 	efi_guid_t *guid_child_controller = NULL;
 
-	ret = EFI_CALL(systab.boottime->close_protocol(
-				controller_handle, guid_controller,
-				child_handle, child_handle));
+	ret = efi_close_protocol(controller_handle, guid_controller,
+				 child_handle, child_handle);
 	if (ret != EFI_SUCCESS) {
 		EFI_PRINT("Cannot close protocol\n");
 		return ret;
@@ -224,9 +222,10 @@
 			ret = disconnect_child(controller_handle,
 					       child_handle_buffer[i]);
 			if (ret != EFI_SUCCESS)
-				return ret;
+				goto out;
 		}
-		return EFI_SUCCESS;
+		ret = EFI_SUCCESS;
+			goto out;
 	}
 
 	/* Destroy all children */
@@ -245,14 +244,14 @@
 				goto out;
 		}
 	}
-	ret = EFI_CALL(systab.boottime->free_pool(entry_buffer));
+	ret = efi_free_pool(entry_buffer);
 	if (ret != EFI_SUCCESS)
 		log_err("Cannot free EFI memory pool\n");
 
 	/* Detach driver from controller */
-	ret = EFI_CALL(systab.boottime->close_protocol(
-			controller_handle, bp->ops->protocol,
-			this->driver_binding_handle, controller_handle));
+	ret = efi_close_protocol(controller_handle, bp->ops->protocol,
+				 this->driver_binding_handle,
+				 controller_handle);
 out:
 	return EFI_EXIT(ret);
 }
@@ -283,7 +282,7 @@
 	bp->bp.start = efi_uc_start;
 	bp->bp.stop = efi_uc_stop;
 	bp->bp.version = 0xffffffff;
-	bp->ops = drv->ops;
+	bp->ops = ops;
 
 	ret = efi_create_handle(&bp->bp.driver_binding_handle);
 	if (ret != EFI_SUCCESS) {
@@ -293,13 +292,20 @@
 	bp->bp.image_handle = bp->bp.driver_binding_handle;
 	ret = efi_add_protocol(bp->bp.driver_binding_handle,
 			       &efi_guid_driver_binding_protocol, bp);
-	if (ret != EFI_SUCCESS) {
-		efi_delete_handle(bp->bp.driver_binding_handle);
-		free(bp);
-		goto out;
+	if (ret != EFI_SUCCESS)
+		goto err;
+	if (ops->init) {
+		ret = ops->init(bp);
+		if (ret != EFI_SUCCESS)
+			goto err;
 	}
 out:
 	return ret;
+
+err:
+	efi_delete_handle(bp->bp.driver_binding_handle);
+	free(bp);
+	return ret;
 }
 
 /**
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index 1bfd094..a560215 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -1993,7 +1993,7 @@
 	if (ret != EFI_SUCCESS)
 		efi_free_pages(addr, pages);
 out:
-	EFI_CALL(efi_close_protocol(device, guid, efi_root, NULL));
+	efi_close_protocol(device, guid, efi_root, NULL);
 	if (ret == EFI_SUCCESS) {
 		*buffer = (void *)(uintptr_t)addr;
 		*size = buffer_size;
@@ -2290,45 +2290,70 @@
  * @agent_handle:      handle of the driver
  * @controller_handle: handle of the controller
  *
- * This function implements the CloseProtocol service.
+ * This is the function implementing the CloseProtocol service is for internal
+ * usage in U-Boot. For API usage wrapper efi_close_protocol_ext() is provided.
  *
  * See the Unified Extensible Firmware Interface (UEFI) specification for
  * details.
  *
  * Return: status code
  */
-efi_status_t EFIAPI efi_close_protocol(efi_handle_t handle,
-				       const efi_guid_t *protocol,
-				       efi_handle_t agent_handle,
-				       efi_handle_t controller_handle)
+efi_status_t efi_close_protocol(efi_handle_t handle, const efi_guid_t *protocol,
+				efi_handle_t agent_handle,
+				efi_handle_t controller_handle)
 {
 	struct efi_handler *handler;
 	struct efi_open_protocol_info_item *item;
 	struct efi_open_protocol_info_item *pos;
-	efi_status_t r;
-
-	EFI_ENTRY("%p, %pUs, %p, %p", handle, protocol, agent_handle,
-		  controller_handle);
+	efi_status_t ret;
 
 	if (!efi_search_obj(agent_handle) ||
-	    (controller_handle && !efi_search_obj(controller_handle))) {
-		r = EFI_INVALID_PARAMETER;
-		goto out;
-	}
-	r = efi_search_protocol(handle, protocol, &handler);
-	if (r != EFI_SUCCESS)
-		goto out;
+	    (controller_handle && !efi_search_obj(controller_handle)))
+		return EFI_INVALID_PARAMETER;
+	ret = efi_search_protocol(handle, protocol, &handler);
+	if (ret != EFI_SUCCESS)
+		return ret;
 
-	r = EFI_NOT_FOUND;
+	ret = EFI_NOT_FOUND;
 	list_for_each_entry_safe(item, pos, &handler->open_infos, link) {
 		if (item->info.agent_handle == agent_handle &&
 		    item->info.controller_handle == controller_handle) {
 			efi_delete_open_info(item);
-			r = EFI_SUCCESS;
+			ret = EFI_SUCCESS;
 		}
 	}
-out:
-	return EFI_EXIT(r);
+
+	return ret;
+}
+
+/**
+ * efi_close_protocol_ext() - close a protocol
+ * @handle:            handle on which the protocol shall be closed
+ * @protocol:          GUID of the protocol to close
+ * @agent_handle:      handle of the driver
+ * @controller_handle: handle of the controller
+ *
+ * This function implements the CloseProtocol service.
+ *
+ * See the Unified Extensible Firmware Interface (UEFI) specification for
+ * details.
+ *
+ * Return: status code
+ */
+static efi_status_t EFIAPI
+efi_close_protocol_ext(efi_handle_t handle, const efi_guid_t *protocol,
+		       efi_handle_t agent_handle,
+		       efi_handle_t controller_handle)
+{
+	efi_status_t ret;
+
+	EFI_ENTRY("%p, %pUs, %p, %p", handle, protocol, agent_handle,
+		  controller_handle);
+
+	ret = efi_close_protocol(handle, protocol,
+				 agent_handle, controller_handle);
+
+	return EFI_EXIT(ret);
 }
 
 /**
@@ -2590,35 +2615,31 @@
 }
 
 /**
- * efi_install_multiple_protocol_interfaces() - Install multiple protocol
+ * efi_install_multiple_protocol_interfaces_int() - Install multiple protocol
  *                                              interfaces
  * @handle: handle on which the protocol interfaces shall be installed
- * @...:    NULL terminated argument list with pairs of protocol GUIDS and
- *          interfaces
- *
- * This function implements the MultipleProtocolInterfaces service.
+ * @argptr: va_list of args
  *
- * See the Unified Extensible Firmware Interface (UEFI) specification for
- * details.
+ * Core functionality of efi_install_multiple_protocol_interfaces
+ * Must not be called directly
  *
  * Return: status code
  */
-efi_status_t EFIAPI efi_install_multiple_protocol_interfaces
-				(efi_handle_t *handle, ...)
+static efi_status_t EFIAPI
+efi_install_multiple_protocol_interfaces_int(efi_handle_t *handle,
+					     efi_va_list argptr)
 {
-	EFI_ENTRY("%p", handle);
-
-	efi_va_list argptr;
 	const efi_guid_t *protocol;
 	void *protocol_interface;
 	efi_handle_t old_handle;
-	efi_status_t r = EFI_SUCCESS;
+	efi_status_t ret = EFI_SUCCESS;
 	int i = 0;
+	efi_va_list argptr_copy;
 
 	if (!handle)
-		return EFI_EXIT(EFI_INVALID_PARAMETER);
+		return EFI_INVALID_PARAMETER;
 
-	efi_va_start(argptr, handle);
+	efi_va_copy(argptr_copy, argptr);
 	for (;;) {
 		protocol = efi_va_arg(argptr, efi_guid_t*);
 		if (!protocol)
@@ -2628,104 +2649,212 @@
 		if (!guidcmp(protocol, &efi_guid_device_path)) {
 			struct efi_device_path *dp = protocol_interface;
 
-			r = EFI_CALL(efi_locate_device_path(protocol, &dp,
-							    &old_handle));
-			if (r == EFI_SUCCESS &&
+			ret = EFI_CALL(efi_locate_device_path(protocol, &dp,
+							      &old_handle));
+			if (ret == EFI_SUCCESS &&
 			    dp->type == DEVICE_PATH_TYPE_END) {
 				EFI_PRINT("Path %pD already installed\n",
 					  protocol_interface);
-				r = EFI_ALREADY_STARTED;
+				ret = EFI_ALREADY_STARTED;
 				break;
 			}
 		}
-		r = EFI_CALL(efi_install_protocol_interface(
-						handle, protocol,
-						EFI_NATIVE_INTERFACE,
-						protocol_interface));
-		if (r != EFI_SUCCESS)
+		ret = EFI_CALL(efi_install_protocol_interface(handle, protocol,
+							      EFI_NATIVE_INTERFACE,
+							      protocol_interface));
+		if (ret != EFI_SUCCESS)
 			break;
 		i++;
 	}
-	efi_va_end(argptr);
-	if (r == EFI_SUCCESS)
-		return EFI_EXIT(r);
+	if (ret == EFI_SUCCESS)
+		goto out;
 
 	/* If an error occurred undo all changes. */
-	efi_va_start(argptr, handle);
 	for (; i; --i) {
-		protocol = efi_va_arg(argptr, efi_guid_t*);
-		protocol_interface = efi_va_arg(argptr, void*);
+		protocol = efi_va_arg(argptr_copy, efi_guid_t*);
+		protocol_interface = efi_va_arg(argptr_copy, void*);
 		EFI_CALL(efi_uninstall_protocol_interface(*handle, protocol,
 							  protocol_interface));
 	}
-	efi_va_end(argptr);
 
-	return EFI_EXIT(r);
+out:
+	efi_va_end(argptr_copy);
+	return ret;
+
 }
 
 /**
- * efi_uninstall_multiple_protocol_interfaces() - uninstall multiple protocol
- *                                                interfaces
- * @handle: handle from which the protocol interfaces shall be removed
+ * efi_install_multiple_protocol_interfaces() - Install multiple protocol
+ *                                              interfaces
+ * @handle: handle on which the protocol interfaces shall be installed
  * @...:    NULL terminated argument list with pairs of protocol GUIDS and
  *          interfaces
  *
- * This function implements the UninstallMultipleProtocolInterfaces service.
+ *
+ * This is the function for internal usage in U-Boot. For the API function
+ * implementing the InstallMultipleProtocol service see
+ * efi_install_multiple_protocol_interfaces_ext()
+ *
+ * Return: status code
+ */
+efi_status_t EFIAPI
+efi_install_multiple_protocol_interfaces(efi_handle_t *handle, ...)
+{
+	efi_status_t ret;
+	efi_va_list argptr;
+
+	efi_va_start(argptr, handle);
+	ret = efi_install_multiple_protocol_interfaces_int(handle, argptr);
+	efi_va_end(argptr);
+	return ret;
+}
+
+/**
+ * efi_install_multiple_protocol_interfaces_ext() - Install multiple protocol
+ *                                                  interfaces
+ * @handle: handle on which the protocol interfaces shall be installed
+ * @...:    NULL terminated argument list with pairs of protocol GUIDS and
+ *          interfaces
+ *
+ * This function implements the MultipleProtocolInterfaces service.
  *
  * See the Unified Extensible Firmware Interface (UEFI) specification for
  * details.
  *
  * Return: status code
  */
-static efi_status_t EFIAPI efi_uninstall_multiple_protocol_interfaces(
-			efi_handle_t handle, ...)
+static efi_status_t EFIAPI
+efi_install_multiple_protocol_interfaces_ext(efi_handle_t *handle, ...)
 {
 	EFI_ENTRY("%p", handle);
-
+	efi_status_t ret;
 	efi_va_list argptr;
+
+	efi_va_start(argptr, handle);
+	ret = efi_install_multiple_protocol_interfaces_int(handle, argptr);
+	efi_va_end(argptr);
+	return EFI_EXIT(ret);
+}
+
+/**
+ * efi_uninstall_multiple_protocol_interfaces_int() - wrapper for uninstall
+ *                                                  multiple protocol
+ *                                                  interfaces
+ * @handle: handle from which the protocol interfaces shall be removed
+ * @argptr: va_list of args
+ *
+ * Core functionality of efi_uninstall_multiple_protocol_interfaces
+ * Must not be called directly
+ *
+ * Return: status code
+ */
+static efi_status_t EFIAPI
+efi_uninstall_multiple_protocol_interfaces_int(efi_handle_t handle,
+					       efi_va_list argptr)
+{
 	const efi_guid_t *protocol;
 	void *protocol_interface;
-	efi_status_t r = EFI_SUCCESS;
+	efi_status_t ret;
 	size_t i = 0;
+	efi_va_list argptr_copy;
 
 	if (!handle)
-		return EFI_EXIT(EFI_INVALID_PARAMETER);
+		return EFI_INVALID_PARAMETER;
 
-	efi_va_start(argptr, handle);
+	efi_va_copy(argptr_copy, argptr);
 	for (;;) {
 		protocol = efi_va_arg(argptr, efi_guid_t*);
 		if (!protocol)
 			break;
 		protocol_interface = efi_va_arg(argptr, void*);
-		r = efi_uninstall_protocol(handle, protocol,
-					   protocol_interface);
-		if (r != EFI_SUCCESS)
+		ret = efi_uninstall_protocol(handle, protocol,
+					     protocol_interface);
+		if (ret != EFI_SUCCESS)
 			break;
 		i++;
 	}
-	efi_va_end(argptr);
-	if (r == EFI_SUCCESS) {
+	if (ret == EFI_SUCCESS) {
 		/* If the last protocol has been removed, delete the handle. */
 		if (list_empty(&handle->protocols)) {
 			list_del(&handle->link);
 			free(handle);
 		}
-		return EFI_EXIT(r);
+		goto out;
 	}
 
 	/* If an error occurred undo all changes. */
-	efi_va_start(argptr, handle);
 	for (; i; --i) {
-		protocol = efi_va_arg(argptr, efi_guid_t*);
-		protocol_interface = efi_va_arg(argptr, void*);
+		protocol = efi_va_arg(argptr_copy, efi_guid_t*);
+		protocol_interface = efi_va_arg(argptr_copy, void*);
 		EFI_CALL(efi_install_protocol_interface(&handle, protocol,
 							EFI_NATIVE_INTERFACE,
 							protocol_interface));
 	}
+	/*
+	 * If any errors are generated while the protocol interfaces are being
+	 * uninstalled, then the protocols uninstalled prior to the error will
+	 * be reinstalled using InstallProtocolInterface() and the status code
+	 * EFI_INVALID_PARAMETER is returned.
+	 */
+	ret = EFI_INVALID_PARAMETER;
+
+out:
+	efi_va_end(argptr_copy);
+	return ret;
+}
+
+/**
+ * efi_uninstall_multiple_protocol_interfaces() - uninstall multiple protocol
+ *                                                interfaces
+ * @handle: handle from which the protocol interfaces shall be removed
+ * @...:    NULL terminated argument list with pairs of protocol GUIDS and
+ *          interfaces
+ *
+ * This function implements the UninstallMultipleProtocolInterfaces service.
+ *
+ * This is the function for internal usage in U-Boot. For the API function
+ * implementing the UninstallMultipleProtocolInterfaces service see
+ * efi_uninstall_multiple_protocol_interfaces_ext()
+ *
+ * Return: status code
+ */
+efi_status_t EFIAPI
+efi_uninstall_multiple_protocol_interfaces(efi_handle_t handle, ...)
+{
+	efi_status_t ret;
+	efi_va_list argptr;
+
+	efi_va_start(argptr, handle);
+	ret = efi_uninstall_multiple_protocol_interfaces_int(handle, argptr);
 	efi_va_end(argptr);
+	return ret;
+}
 
-	/* In case of an error always return EFI_INVALID_PARAMETER */
-	return EFI_EXIT(EFI_INVALID_PARAMETER);
+/**
+ * efi_uninstall_multiple_protocol_interfaces_ext() - uninstall multiple protocol
+ *                                                    interfaces
+ * @handle: handle from which the protocol interfaces shall be removed
+ * @...:    NULL terminated argument list with pairs of protocol GUIDS and
+ *          interfaces
+ *
+ * This function implements the UninstallMultipleProtocolInterfaces service.
+ *
+ * See the Unified Extensible Firmware Interface (UEFI) specification for
+ * details.
+ *
+ * Return: status code
+ */
+static efi_status_t EFIAPI
+efi_uninstall_multiple_protocol_interfaces_ext(efi_handle_t handle, ...)
+{
+	EFI_ENTRY("%p", handle);
+	efi_status_t ret;
+	efi_va_list argptr;
+
+	efi_va_start(argptr, handle);
+	ret = efi_uninstall_multiple_protocol_interfaces_int(handle, argptr);
+	efi_va_end(argptr);
+	return EFI_EXIT(ret);
 }
 
 /**
@@ -3109,11 +3238,10 @@
 				if (info->info.agent_handle !=
 				    (efi_handle_t)image_obj)
 					continue;
-				r = EFI_CALL(efi_close_protocol
-						(efiobj, &protocol->guid,
-						 info->info.agent_handle,
-						 info->info.controller_handle
-						));
+				r = efi_close_protocol(
+						efiobj, &protocol->guid,
+						info->info.agent_handle,
+						info->info.controller_handle);
 				if (r !=  EFI_SUCCESS)
 					ret = r;
 				/*
@@ -3377,9 +3505,9 @@
 		r = EFI_CALL(binding_protocol->start(binding_protocol,
 						     controller_handle,
 						     remain_device_path));
-	EFI_CALL(efi_close_protocol(driver_image_handle,
-				    &efi_guid_driver_binding_protocol,
-				    driver_image_handle, NULL));
+	efi_close_protocol(driver_image_handle,
+			   &efi_guid_driver_binding_protocol,
+			   driver_image_handle, NULL);
 	return r;
 }
 
@@ -3730,9 +3858,9 @@
 			goto out;
 		}
 	}
-	EFI_CALL(efi_close_protocol(driver_image_handle,
-				    &efi_guid_driver_binding_protocol,
-				    driver_image_handle, NULL));
+	efi_close_protocol(driver_image_handle,
+			   &efi_guid_driver_binding_protocol,
+			   driver_image_handle, NULL);
 	r = EFI_SUCCESS;
 out:
 	if (!child_handle)
@@ -3779,15 +3907,15 @@
 	.connect_controller = efi_connect_controller,
 	.disconnect_controller = efi_disconnect_controller,
 	.open_protocol = efi_open_protocol,
-	.close_protocol = efi_close_protocol,
+	.close_protocol = efi_close_protocol_ext,
 	.open_protocol_information = efi_open_protocol_information,
 	.protocols_per_handle = efi_protocols_per_handle,
 	.locate_handle_buffer = efi_locate_handle_buffer,
 	.locate_protocol = efi_locate_protocol,
 	.install_multiple_protocol_interfaces =
-			efi_install_multiple_protocol_interfaces,
+			efi_install_multiple_protocol_interfaces_ext,
 	.uninstall_multiple_protocol_interfaces =
-			efi_uninstall_multiple_protocol_interfaces,
+			efi_uninstall_multiple_protocol_interfaces_ext,
 	.calculate_crc32 = efi_calculate_crc32,
 	.copy_mem = efi_copy_mem,
 	.set_mem = efi_set_mem,
diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c
index a6b98f0..397e393 100644
--- a/lib/efi_loader/efi_capsule.c
+++ b/lib/efi_loader/efi_capsule.c
@@ -159,12 +159,14 @@
 	efi_status_t ret;
 
 	for (i = 0, handle = handles; i < no_handles; i++, handle++) {
-		ret = EFI_CALL(efi_handle_protocol(
-				*handle,
-				&efi_guid_firmware_management_protocol,
-				(void **)&fmp));
+		struct efi_handler *fmp_handler;
+
+		ret = efi_search_protocol(
+				*handle, &efi_guid_firmware_management_protocol,
+				&fmp_handler);
 		if (ret != EFI_SUCCESS)
 			continue;
+		fmp = fmp_handler->protocol_interface;
 
 		/* get device's image info */
 		info_size = 0;
@@ -215,10 +217,6 @@
 skip:
 		efi_free_pool(package_version_name);
 		free(image_info);
-		EFI_CALL(efi_close_protocol(
-				(efi_handle_t)fmp,
-				&efi_guid_firmware_management_protocol,
-				NULL, NULL));
 		if (found)
 			return fmp;
 	}
@@ -636,17 +634,18 @@
 
 	if (IS_ENABLED(CONFIG_EFI_CAPSULE_FIRMWARE_FIT)) {
 		handle = NULL;
-		ret = EFI_CALL(efi_install_multiple_protocol_interfaces(
-				&handle, &efi_guid_firmware_management_protocol,
-				&efi_fmp_fit, NULL));
+		ret = efi_install_multiple_protocol_interfaces(&handle,
+							       &efi_guid_firmware_management_protocol,
+							       &efi_fmp_fit,
+							       NULL);
 	}
 
 	if (IS_ENABLED(CONFIG_EFI_CAPSULE_FIRMWARE_RAW)) {
 		handle = NULL;
-		ret = EFI_CALL(efi_install_multiple_protocol_interfaces(
-				&handle,
-				&efi_guid_firmware_management_protocol,
-				&efi_fmp_raw, NULL));
+		ret = efi_install_multiple_protocol_interfaces(&handle,
+							       &efi_guid_firmware_management_protocol,
+							       &efi_fmp_raw,
+							       NULL);
 	}
 
 	return ret;
diff --git a/lib/efi_loader/efi_console.c b/lib/efi_loader/efi_console.c
index cf9fbd9..3354b21 100644
--- a/lib/efi_loader/efi_console.c
+++ b/lib/efi_loader/efi_console.c
@@ -1278,12 +1278,14 @@
 	struct efi_device_path *dp;
 
 	/* Install protocols on root node */
-	r = EFI_CALL(efi_install_multiple_protocol_interfaces
-		     (&efi_root,
-		      &efi_guid_text_output_protocol, &efi_con_out,
-		      &efi_guid_text_input_protocol, &efi_con_in,
-		      &efi_guid_text_input_ex_protocol, &efi_con_in_ex,
-		      NULL));
+	r = efi_install_multiple_protocol_interfaces(&efi_root,
+						     &efi_guid_text_output_protocol,
+						     &efi_con_out,
+						     &efi_guid_text_input_protocol,
+						     &efi_con_in,
+						     &efi_guid_text_input_ex_protocol,
+						     &efi_con_in_ex,
+						     NULL);
 
 	/* Create console node and install device path protocols */
 	if (CONFIG_IS_ENABLED(DM_SERIAL)) {
diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c
index ebffb77..acae007 100644
--- a/lib/efi_loader/efi_device_path.c
+++ b/lib/efi_loader/efi_device_path.c
@@ -936,7 +936,8 @@
 		dpsize = sizeof(struct efi_device_path_hard_drive_path);
 	buf = dp_alloc(dpsize);
 
-	dp_part_node(buf, desc, part);
+	if (buf)
+		dp_part_node(buf, desc, part);
 
 	return buf;
 }
diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c
index 39ea1a6..cef4e45 100644
--- a/lib/efi_loader/efi_disk.c
+++ b/lib/efi_loader/efi_disk.c
@@ -395,7 +395,7 @@
 {
 	struct efi_disk_obj *diskobj;
 	struct efi_object *handle;
-	const efi_guid_t *guid = NULL;
+	const efi_guid_t *esp_guid = NULL;
 	efi_status_t ret;
 
 	/* Don't add empty devices */
@@ -415,6 +415,11 @@
 		struct efi_handler *handler;
 		void *protocol_interface;
 
+		if (!node) {
+			ret = EFI_OUT_OF_RESOURCES;
+			goto error;
+		}
+
 		/* Parent must expose EFI_BLOCK_IO_PROTOCOL */
 		ret = efi_search_protocol(parent, &efi_block_io_guid, &handler);
 		if (ret != EFI_SUCCESS)
@@ -434,7 +439,7 @@
 		efi_free_pool(node);
 		diskobj->media.last_block = part_info->size - 1;
 		if (part_info->bootable & PART_EFI_SYSTEM_PARTITION)
-			guid = &efi_system_partition_guid;
+			esp_guid = &efi_system_partition_guid;
 	} else {
 		diskobj->dp = efi_dp_from_part(desc, part);
 		diskobj->media.last_block = desc->lba - 1;
@@ -449,10 +454,16 @@
 	 * in this case.
 	 */
 	handle = &diskobj->header;
-	ret = EFI_CALL(efi_install_multiple_protocol_interfaces(
-			&handle, &efi_guid_device_path, diskobj->dp,
-			&efi_block_io_guid, &diskobj->ops,
-			guid, NULL, NULL));
+	ret = efi_install_multiple_protocol_interfaces(
+					&handle,
+					&efi_guid_device_path, diskobj->dp,
+					&efi_block_io_guid, &diskobj->ops,
+					/*
+					 * esp_guid must be last entry as it
+					 * can be NULL. Its interface is NULL.
+					 */
+					esp_guid, NULL,
+					NULL);
 	if (ret != EFI_SUCCESS)
 		goto error;
 
@@ -620,7 +631,7 @@
  *
  * @return	0 on success, -1 otherwise
  */
-static int efi_disk_probe(void *ctx, struct event *event)
+int efi_disk_probe(void *ctx, struct event *event)
 {
 	struct udevice *dev;
 	enum uclass_id id;
@@ -724,7 +735,7 @@
  *
  * @return	0 on success, -1 otherwise
  */
-static int efi_disk_remove(void *ctx, struct event *event)
+int efi_disk_remove(void *ctx, struct event *event)
 {
 	enum uclass_id id;
 	struct udevice *dev;
@@ -740,27 +751,6 @@
 		return 0;
 }
 
-efi_status_t efi_disk_init(void)
-{
-	int ret;
-
-	ret = event_register("efi_disk add", EVT_DM_POST_PROBE,
-			     efi_disk_probe, NULL);
-	if (ret) {
-		log_err("Event registration for efi_disk add failed\n");
-		return EFI_OUT_OF_RESOURCES;
-	}
-
-	ret = event_register("efi_disk del", EVT_DM_PRE_REMOVE,
-			     efi_disk_remove, NULL);
-	if (ret) {
-		log_err("Event registration for efi_disk del failed\n");
-		return EFI_OUT_OF_RESOURCES;
-	}
-
-	return EFI_SUCCESS;
-}
-
 /**
  * efi_disk_get_device_name() - get U-Boot device name associated with EFI handle
  *
@@ -800,7 +790,8 @@
 	if (is_partition) {
 		part_data = dev_get_uclass_plat(dev);
 		part = part_data->partnum;
-		count = snprintf(buf, size, "%s %d:%d", if_typename, diskid, part);
+		count = snprintf(buf, size, "%s %d:%u", if_typename, diskid,
+				 part);
 	} else {
 		count = snprintf(buf, size, "%s %d", if_typename, diskid);
 	}
diff --git a/lib/efi_loader/efi_helper.c b/lib/efi_loader/efi_helper.c
index 8ed564e..c71e87d 100644
--- a/lib/efi_loader/efi_helper.c
+++ b/lib/efi_loader/efi_helper.c
@@ -171,3 +171,22 @@
 	handle->dev = dev;
 	return dev_tag_set_ptr(dev, DM_TAG_EFI, handle);
 }
+
+/**
+ * efi_unlink_dev() - unlink udevice and handle
+ *
+ * @handle:	EFI handle to unlink
+ *
+ * Return:	0 on success, negative on failure
+ */
+int efi_unlink_dev(efi_handle_t handle)
+{
+	int ret;
+
+	ret = dev_tag_del(handle->dev, DM_TAG_EFI);
+	if (ret)
+		return ret;
+	handle->dev = NULL;
+
+	return 0;
+}
diff --git a/lib/efi_loader/efi_load_initrd.c b/lib/efi_loader/efi_load_initrd.c
index 3d6044f..87fde3f 100644
--- a/lib/efi_loader/efi_load_initrd.c
+++ b/lib/efi_loader/efi_load_initrd.c
@@ -208,14 +208,13 @@
 	if (ret != EFI_SUCCESS)
 		return ret;
 
-	ret = EFI_CALL(efi_install_multiple_protocol_interfaces
-		       (&efi_initrd_handle,
-			/* initramfs */
-			&efi_guid_device_path, &dp_lf2_handle,
-			/* LOAD_FILE2 */
-			&efi_guid_load_file2_protocol,
-			(void *)&efi_lf2_protocol,
-			NULL));
+	ret = efi_install_multiple_protocol_interfaces(&efi_initrd_handle,
+						       /* initramfs */
+						       &efi_guid_device_path, &dp_lf2_handle,
+						       /* LOAD_FILE2 */
+						       &efi_guid_load_file2_protocol,
+						       (void *)&efi_lf2_protocol,
+						       NULL);
 
 	return ret;
 }
diff --git a/lib/efi_loader/efi_load_options.c b/lib/efi_loader/efi_load_options.c
index 71454f0..3cfddee 100644
--- a/lib/efi_loader/efi_load_options.c
+++ b/lib/efi_loader/efi_load_options.c
@@ -27,23 +27,18 @@
 				  void *load_options)
 {
 	struct efi_loaded_image *loaded_image_info;
+	struct efi_handler *handler;
 	efi_status_t ret;
 
-	ret = EFI_CALL(systab.boottime->open_protocol(
-					handle,
-					&efi_guid_loaded_image,
-					(void **)&loaded_image_info,
-					efi_root, NULL,
-					EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL));
+	ret = efi_search_protocol(handle, &efi_guid_loaded_image, &handler);
+	loaded_image_info = handler->protocol_interface;
 	if (ret != EFI_SUCCESS)
 		return EFI_INVALID_PARAMETER;
 
 	loaded_image_info->load_options = load_options;
 	loaded_image_info->load_options_size = load_options_size;
 
-	return EFI_CALL(systab.boottime->close_protocol(handle,
-							&efi_guid_loaded_image,
-							efi_root, NULL));
+	return EFI_SUCCESS;
 }
 
 /**
diff --git a/lib/efi_loader/efi_root_node.c b/lib/efi_loader/efi_root_node.c
index 739c686..a4eb6f4 100644
--- a/lib/efi_loader/efi_root_node.c
+++ b/lib/efi_loader/efi_root_node.c
@@ -49,38 +49,38 @@
 	dp->end.length = sizeof(struct efi_device_path);
 
 	/* Create root node and install protocols */
-	ret = EFI_CALL(efi_install_multiple_protocol_interfaces
-			(&efi_root,
-			 /* Device path protocol */
-			 &efi_guid_device_path, dp,
+	ret = efi_install_multiple_protocol_interfaces
+		(&efi_root,
+		 /* Device path protocol */
+		 &efi_guid_device_path, dp,
 #if CONFIG_IS_ENABLED(EFI_DEVICE_PATH_TO_TEXT)
-			 /* Device path to text protocol */
-			 &efi_guid_device_path_to_text_protocol,
-			 (void *)&efi_device_path_to_text,
+		 /* Device path to text protocol */
+		 &efi_guid_device_path_to_text_protocol,
+		 &efi_device_path_to_text,
 #endif
-#ifdef CONFIG_EFI_DEVICE_PATH_UTIL
-			 /* Device path utilities protocol */
-			 &efi_guid_device_path_utilities_protocol,
-			 (void *)&efi_device_path_utilities,
+#if CONFIG_IS_ENABLED(EFI_DEVICE_PATH_UTIL)
+		 /* Device path utilities protocol */
+		 &efi_guid_device_path_utilities_protocol,
+		 &efi_device_path_utilities,
 #endif
-#ifdef CONFIG_EFI_DT_FIXUP
-			 /* Device-tree fix-up protocol */
-			 &efi_guid_dt_fixup_protocol,
-			 (void *)&efi_dt_fixup_prot,
+#if CONFIG_IS_ENABLED(EFI_DT_FIXUP)
+		 /* Device-tree fix-up protocol */
+		 &efi_guid_dt_fixup_protocol,
+		 &efi_dt_fixup_prot,
 #endif
 #if CONFIG_IS_ENABLED(EFI_UNICODE_COLLATION_PROTOCOL2)
-			 &efi_guid_unicode_collation_protocol2,
-			 (void *)&efi_unicode_collation_protocol2,
+		 &efi_guid_unicode_collation_protocol2,
+		 &efi_unicode_collation_protocol2,
 #endif
 #if CONFIG_IS_ENABLED(EFI_LOADER_HII)
-			 /* HII string protocol */
-			 &efi_guid_hii_string_protocol,
-			 (void *)&efi_hii_string,
-			 /* HII database protocol */
-			 &efi_guid_hii_database_protocol,
-			 (void *)&efi_hii_database,
+		 /* HII string protocol */
+		 &efi_guid_hii_string_protocol,
+		 &efi_hii_string,
+		 /* HII database protocol */
+		 &efi_guid_hii_database_protocol,
+		 &efi_hii_database,
 #endif
-			 NULL));
+		 NULL);
 	efi_root->type = EFI_OBJECT_TYPE_U_BOOT_FIRMWARE;
 	return ret;
 }
diff --git a/lib/efi_loader/efi_setup.c b/lib/efi_loader/efi_setup.c
index c633fcd..9d71893 100644
--- a/lib/efi_loader/efi_setup.c
+++ b/lib/efi_loader/efi_setup.c
@@ -198,7 +198,8 @@
 	if (ret != EFI_SUCCESS)
 		goto out;
 
-	ret = efi_disk_init();
+	/* Initialize EFI driver uclass */
+	ret = efi_driver_init();
 out:
 	return ret;
 }
@@ -319,11 +320,6 @@
 	if (ret != EFI_SUCCESS)
 		goto out;
 
-	/* Initialize EFI driver uclass */
-	ret = efi_driver_init();
-	if (ret != EFI_SUCCESS)
-		goto out;
-
 	if (IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_SUPPORT)) {
 		ret = efi_load_capsule_drivers();
 		if (ret != EFI_SUCCESS)
diff --git a/lib/efi_loader/efi_string.c b/lib/efi_loader/efi_string.c
index 8bf1e49..e21e09c 100644
--- a/lib/efi_loader/efi_string.c
+++ b/lib/efi_loader/efi_string.c
@@ -8,6 +8,7 @@
 #include <common.h>
 #include <charset.h>
 #include <efi_loader.h>
+#include <malloc.h>
 
 /**
  * efi_create_indexed_name - create a string name with an index
@@ -41,3 +42,26 @@
 
 	return p;
 }
+
+/**
+ * efi_convert_string - Convert an ASCII or UTF-8 string to UTF-16
+ * @str:	String to be converted
+ *
+ * Return: Converted string in UTF-16 format. The caller is responsible for
+ *         freeing this string when it is no longer needed.
+ */
+efi_string_t efi_convert_string(const char *str)
+{
+	efi_string_t str_16, tmp;
+	size_t sz_16;
+
+	sz_16 = utf8_utf16_strlen(str);
+	str_16 = calloc(sz_16 + 1, sizeof(u16));
+	if (!str_16)
+		return NULL;
+
+	tmp = str_16;
+	utf8_utf16_strcpy(&tmp, str);
+
+	return str_16;
+}
diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c
index 99ec3a5..a525ebf 100644
--- a/lib/efi_loader/efi_tcg2.c
+++ b/lib/efi_loader/efi_tcg2.c
@@ -2053,7 +2053,7 @@
 {
 	efi_status_t ret;
 	efi_handle_t handle;
-	struct efi_handler *dp_handler;
+	struct efi_handler *dp_handler, *io_handler;
 	struct efi_device_path *orig_device_path;
 	struct efi_device_path *device_path;
 	struct efi_device_path *dp;
@@ -2098,10 +2098,10 @@
 	if (ret != EFI_SUCCESS)
 		goto out1;
 
-	ret = EFI_CALL(efi_handle_protocol(handle,
-					   &efi_block_io_guid, (void **)&block_io));
+	ret = efi_search_protocol(handle, &efi_block_io_guid, &io_handler);
 	if (ret != EFI_SUCCESS)
 		goto out1;
+	block_io = io_handler->protocol_interface;
 
 	gpt_h = memalign(block_io->media->io_align, block_io->media->block_size);
 	if (!gpt_h) {
@@ -2164,12 +2164,8 @@
 	}
 
 	ret = tcg2_measure_event(dev, 5, EV_EFI_GPT_EVENT, event_size, (u8 *)event);
-	if (ret != EFI_SUCCESS)
-		goto out2;
 
 out2:
-	EFI_CALL(efi_close_protocol((efi_handle_t)block_io, &efi_block_io_guid,
-				    NULL, NULL));
 	free(gpt_h);
 	free(entry);
 	free(event);
diff --git a/lib/efi_selftest/efi_selftest_events.c b/lib/efi_selftest/efi_selftest_events.c
index 9007153..743a6b9 100644
--- a/lib/efi_selftest/efi_selftest_events.c
+++ b/lib/efi_selftest/efi_selftest_events.c
@@ -11,7 +11,7 @@
 
 #include <efi_selftest.h>
 
-static struct efi_event *event_notify;
+static struct efi_event *efi_st_event_notify;
 static struct efi_event *event_wait;
 static unsigned int timer_ticks;
 static struct efi_boot_services *boottime;
@@ -50,7 +50,7 @@
 
 	ret = boottime->create_event(EVT_TIMER | EVT_NOTIFY_SIGNAL,
 				     TPL_CALLBACK, notify, (void *)&timer_ticks,
-				     &event_notify);
+				     &efi_st_event_notify);
 	if (ret != EFI_SUCCESS) {
 		efi_st_error("could not create event\n");
 		return EFI_ST_FAILURE;
@@ -75,9 +75,9 @@
 {
 	efi_status_t ret;
 
-	if (event_notify) {
-		ret = boottime->close_event(event_notify);
-		event_notify = NULL;
+	if (efi_st_event_notify) {
+		ret = boottime->close_event(efi_st_event_notify);
+		efi_st_event_notify = NULL;
 		if (ret != EFI_SUCCESS) {
 			efi_st_error("could not close event\n");
 			return EFI_ST_FAILURE;
@@ -112,7 +112,8 @@
 
 	/* Set 10 ms timer */
 	timer_ticks = 0;
-	ret = boottime->set_timer(event_notify, EFI_TIMER_PERIODIC, 100000);
+	ret = boottime->set_timer(efi_st_event_notify, EFI_TIMER_PERIODIC,
+				  100000);
 	if (ret != EFI_SUCCESS) {
 		efi_st_error("Could not set timer\n");
 		return EFI_ST_FAILURE;
@@ -146,14 +147,15 @@
 		efi_st_error("Incorrect timing of events\n");
 		return EFI_ST_FAILURE;
 	}
-	ret = boottime->set_timer(event_notify, EFI_TIMER_STOP, 0);
+	ret = boottime->set_timer(efi_st_event_notify, EFI_TIMER_STOP, 0);
 	if (ret != EFI_SUCCESS) {
 		efi_st_error("Could not cancel timer\n");
 		return EFI_ST_FAILURE;
 	}
 	/* Set 10 ms timer */
 	timer_ticks = 0;
-	ret = boottime->set_timer(event_notify, EFI_TIMER_RELATIVE, 100000);
+	ret = boottime->set_timer(efi_st_event_notify, EFI_TIMER_RELATIVE,
+				  100000);
 	if (ret != EFI_SUCCESS) {
 		efi_st_error("Could not set timer\n");
 		return EFI_ST_FAILURE;
diff --git a/lib/efi_selftest/efi_selftest_exitbootservices.c b/lib/efi_selftest/efi_selftest_exitbootservices.c
index f5e0d9d..11b43fd 100644
--- a/lib/efi_selftest/efi_selftest_exitbootservices.c
+++ b/lib/efi_selftest/efi_selftest_exitbootservices.c
@@ -26,7 +26,7 @@
 };
 
 static struct efi_boot_services *boottime;
-static struct efi_event *event_notify;
+static struct efi_event *efi_st_event_notify;
 struct notification_record record;
 
 struct notification_context context_before = {
@@ -75,7 +75,7 @@
 	ret = boottime->create_event(EVT_SIGNAL_EXIT_BOOT_SERVICES,
 				     TPL_CALLBACK, ebs_notify,
 				     &context,
-				     &event_notify);
+				     &efi_st_event_notify);
 	if (ret != EFI_SUCCESS) {
 		efi_st_error("could not create event\n");
 		return EFI_ST_FAILURE;
@@ -83,7 +83,7 @@
 	ret = boottime->create_event_ex(0, TPL_CALLBACK, ebs_notify,
 					&context_before,
 					&guid_before_exit_boot_services,
-					&event_notify);
+					&efi_st_event_notify);
 	if (ret != EFI_SUCCESS) {
 		efi_st_error("could not create event\n");
 		return EFI_ST_FAILURE;
diff --git a/lib/efi_selftest/efi_selftest_tpl.c b/lib/efi_selftest/efi_selftest_tpl.c
index f4e4672..909c78a 100644
--- a/lib/efi_selftest/efi_selftest_tpl.c
+++ b/lib/efi_selftest/efi_selftest_tpl.c
@@ -10,8 +10,8 @@
 
 #include <efi_selftest.h>
 
-static struct efi_event *event_notify;
-static struct efi_event *event_wait;
+static struct efi_event *efi_st_event_notify;
+static struct efi_event *efi_st_event_wait;
 static unsigned int notification_count;
 static struct efi_boot_services *boottime;
 
@@ -49,13 +49,14 @@
 	ret = boottime->create_event(EVT_TIMER | EVT_NOTIFY_SIGNAL,
 				     TPL_CALLBACK, notify,
 				     (void *)&notification_count,
-				     &event_notify);
+				     &efi_st_event_notify);
 	if (ret != EFI_SUCCESS) {
 		efi_st_error("could not create event\n");
 		return EFI_ST_FAILURE;
 	}
 	ret = boottime->create_event(EVT_TIMER | EVT_NOTIFY_WAIT,
-				     TPL_NOTIFY, notify, NULL, &event_wait);
+				     TPL_NOTIFY, notify, NULL,
+				     &efi_st_event_wait);
 	if (ret != EFI_SUCCESS) {
 		efi_st_error("could not create event\n");
 		return EFI_ST_FAILURE;
@@ -74,17 +75,17 @@
 {
 	efi_status_t ret;
 
-	if (event_notify) {
-		ret = boottime->close_event(event_notify);
-		event_notify = NULL;
+	if (efi_st_event_notify) {
+		ret = boottime->close_event(efi_st_event_notify);
+		efi_st_event_notify = NULL;
 		if (ret != EFI_SUCCESS) {
 			efi_st_error("could not close event\n");
 			return EFI_ST_FAILURE;
 		}
 	}
-	if (event_wait) {
-		ret = boottime->close_event(event_wait);
-		event_wait = NULL;
+	if (efi_st_event_wait) {
+		ret = boottime->close_event(efi_st_event_wait);
+		efi_st_event_wait = NULL;
 		if (ret != EFI_SUCCESS) {
 			efi_st_error("could not close event\n");
 			return EFI_ST_FAILURE;
@@ -116,24 +117,26 @@
 
 	/* Set 10 ms timer */
 	notification_count = 0;
-	ret = boottime->set_timer(event_notify, EFI_TIMER_PERIODIC, 100000);
+	ret = boottime->set_timer(efi_st_event_notify, EFI_TIMER_PERIODIC,
+				  100000);
 	if (ret != EFI_SUCCESS) {
 		efi_st_error("Could not set timer\n");
 		return EFI_ST_FAILURE;
 	}
 	/* Set 100 ms timer */
-	ret = boottime->set_timer(event_wait, EFI_TIMER_RELATIVE, 1000000);
+	ret = boottime->set_timer(efi_st_event_wait, EFI_TIMER_RELATIVE,
+				  1000000);
 	if (ret != EFI_SUCCESS) {
 		efi_st_error("Could not set timer\n");
 		return EFI_ST_FAILURE;
 	}
 	index = 5;
-	ret = boottime->wait_for_event(1, &event_wait, &index);
+	ret = boottime->wait_for_event(1, &efi_st_event_wait, &index);
 	if (ret != EFI_SUCCESS) {
 		efi_st_error("Could not wait for event\n");
 		return EFI_ST_FAILURE;
 	}
-	ret = boottime->check_event(event_wait);
+	ret = boottime->check_event(efi_st_event_wait);
 	if (ret != EFI_NOT_READY) {
 		efi_st_error("Signaled state was not cleared.\n");
 		efi_st_printf("ret = %u\n", (unsigned int)ret);
@@ -150,7 +153,7 @@
 		efi_st_error("Incorrect timing of events\n");
 		return EFI_ST_FAILURE;
 	}
-	ret = boottime->set_timer(event_notify, EFI_TIMER_STOP, 0);
+	ret = boottime->set_timer(efi_st_event_notify, EFI_TIMER_STOP, 0);
 	if (ret != EFI_SUCCESS) {
 		efi_st_error("Could not cancel timer\n");
 		return EFI_ST_FAILURE;
@@ -163,19 +166,21 @@
 	}
 	/* Set 10 ms timer */
 	notification_count = 0;
-	ret = boottime->set_timer(event_notify, EFI_TIMER_PERIODIC, 100000);
+	ret = boottime->set_timer(efi_st_event_notify, EFI_TIMER_PERIODIC,
+				  100000);
 	if (ret != EFI_SUCCESS) {
 		efi_st_error("Could not set timer\n");
 		return EFI_ST_FAILURE;
 	}
 	/* Set 100 ms timer */
-	ret = boottime->set_timer(event_wait, EFI_TIMER_RELATIVE, 1000000);
+	ret = boottime->set_timer(efi_st_event_wait, EFI_TIMER_RELATIVE,
+				  1000000);
 	if (ret != EFI_SUCCESS) {
 		efi_st_error("Could not set timer\n");
 		return EFI_ST_FAILURE;
 	}
 	do {
-		ret = boottime->check_event(event_wait);
+		ret = boottime->check_event(efi_st_event_wait);
 	} while (ret == EFI_NOT_READY);
 	if (ret != EFI_SUCCESS) {
 		efi_st_error("Could not check event\n");
@@ -189,14 +194,14 @@
 		return EFI_ST_FAILURE;
 	}
 	/* Set 1 ms timer */
-	ret = boottime->set_timer(event_wait, EFI_TIMER_RELATIVE, 1000);
+	ret = boottime->set_timer(efi_st_event_wait, EFI_TIMER_RELATIVE, 1000);
 	if (ret != EFI_SUCCESS) {
 		efi_st_error("Could not set timer\n");
 		return EFI_ST_FAILURE;
 	}
 	/* Restore the old TPL level */
 	boottime->restore_tpl(TPL_APPLICATION);
-	ret = boottime->wait_for_event(1, &event_wait, &index);
+	ret = boottime->wait_for_event(1, &efi_st_event_wait, &index);
 	if (ret != EFI_SUCCESS) {
 		efi_st_error("Could not wait for event\n");
 		return EFI_ST_FAILURE;
@@ -208,7 +213,7 @@
 		efi_st_error("Queued timer event did not fire\n");
 		return EFI_ST_FAILURE;
 	}
-	ret = boottime->set_timer(event_wait, EFI_TIMER_STOP, 0);
+	ret = boottime->set_timer(efi_st_event_wait, EFI_TIMER_STOP, 0);
 	if (ret != EFI_SUCCESS) {
 		efi_st_error("Could not cancel timer\n");
 		return EFI_ST_FAILURE;
diff --git a/lib/efi_selftest/efi_selftest_watchdog.c b/lib/efi_selftest/efi_selftest_watchdog.c
index a352d4a..4d7ed5a 100644
--- a/lib/efi_selftest/efi_selftest_watchdog.c
+++ b/lib/efi_selftest/efi_selftest_watchdog.c
@@ -28,8 +28,8 @@
 	unsigned int timer_ticks;
 };
 
-static struct efi_event *event_notify;
-static struct efi_event *event_wait;
+static struct efi_event *efi_st_event_notify;
+static struct efi_event *efi_st_event_wait;
 static struct efi_boot_services *boottime;
 static struct notify_context notification_context;
 static bool watchdog_reset;
@@ -79,13 +79,14 @@
 	ret = boottime->create_event(EVT_TIMER | EVT_NOTIFY_SIGNAL,
 				     TPL_CALLBACK, notify,
 				     (void *)&notification_context,
-				     &event_notify);
+				     &efi_st_event_notify);
 	if (ret != EFI_SUCCESS) {
 		efi_st_error("could not create event\n");
 		return EFI_ST_FAILURE;
 	}
 	ret = boottime->create_event(EVT_TIMER | EVT_NOTIFY_WAIT,
-				     TPL_CALLBACK, notify, NULL, &event_wait);
+				     TPL_CALLBACK, notify, NULL,
+				     &efi_st_event_wait);
 	if (ret != EFI_SUCCESS) {
 		efi_st_error("could not create event\n");
 		return EFI_ST_FAILURE;
@@ -138,17 +139,17 @@
 		efi_st_error("Setting watchdog timer failed\n");
 		return EFI_ST_FAILURE;
 	}
-	if (event_notify) {
-		ret = boottime->close_event(event_notify);
-		event_notify = NULL;
+	if (efi_st_event_notify) {
+		ret = boottime->close_event(efi_st_event_notify);
+		efi_st_event_notify = NULL;
 		if (ret != EFI_SUCCESS) {
 			efi_st_error("Could not close event\n");
 			return EFI_ST_FAILURE;
 		}
 	}
-	if (event_wait) {
-		ret = boottime->close_event(event_wait);
-		event_wait = NULL;
+	if (efi_st_event_wait) {
+		ret = boottime->close_event(efi_st_event_wait);
+		efi_st_event_wait = NULL;
 		if (ret != EFI_SUCCESS) {
 			efi_st_error("Could not close event\n");
 			return EFI_ST_FAILURE;
@@ -181,21 +182,22 @@
 	}
 	if (watchdog_reset) {
 		/* Set 600 ms timer */
-		ret = boottime->set_timer(event_notify, EFI_TIMER_PERIODIC,
-					  6000000);
+		ret = boottime->set_timer(efi_st_event_notify,
+					  EFI_TIMER_PERIODIC, 6000000);
 		if (ret != EFI_SUCCESS) {
 			efi_st_error("Could not set timer\n");
 			return EFI_ST_FAILURE;
 		}
 	}
 	/* Set 1350 ms timer */
-	ret = boottime->set_timer(event_wait, EFI_TIMER_RELATIVE, 13500000);
+	ret = boottime->set_timer(efi_st_event_wait, EFI_TIMER_RELATIVE,
+				  13500000);
 	if (ret != EFI_SUCCESS) {
 		efi_st_error("Could not set timer\n");
 		return EFI_ST_FAILURE;
 	}
 
-	ret = boottime->wait_for_event(1, &event_wait, &index);
+	ret = boottime->wait_for_event(1, &efi_st_event_wait, &index);
 	if (ret != EFI_SUCCESS) {
 		efi_st_error("Could not wait for event\n");
 		return EFI_ST_FAILURE;
diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt
index 49e3b38..137b7f6 100644
--- a/scripts/config_whitelist.txt
+++ b/scripts/config_whitelist.txt
@@ -234,7 +234,6 @@
 CONFIG_IRAM_END
 CONFIG_IRAM_SIZE
 CONFIG_IRAM_TOP
-CONFIG_KM_BOARD_EXTRA_ENV
 CONFIG_KM_DEF_ARCH
 CONFIG_KM_DEF_BOOT_ARGS_CPU
 CONFIG_KM_DEF_ENV
diff --git a/test/py/tests/test_efi_secboot/conftest.py b/test/py/tests/test_efi_secboot/conftest.py
index db6b8d3..406131c 100644
--- a/test/py/tests/test_efi_secboot/conftest.py
+++ b/test/py/tests/test_efi_secboot/conftest.py
@@ -2,18 +2,12 @@
 # Copyright (c) 2019, Linaro Limited
 # Author: AKASHI Takahiro <takahiro.akashi@linaro.org>
 
-import os
-import os.path
-from subprocess import call, check_call, check_output, CalledProcessError
+""" Fixture for UEFI secure boot test """
+
+from subprocess import call, check_call, CalledProcessError
 import pytest
 from defs import *
 
-
-#
-# Fixture for UEFI secure boot test
-#
-
-
 @pytest.fixture(scope='session')
 def efi_boot_env(request, u_boot_config):
     """Set up a file system to be used in UEFI secure boot test.
diff --git a/tools/buildman/boards.py b/tools/buildman/boards.py
index 8a0971a..cdc4d9f 100644
--- a/tools/buildman/boards.py
+++ b/tools/buildman/boards.py
@@ -263,6 +263,17 @@
         if params['arch'] == 'arm' and params['cpu'] == 'armv8':
             params['arch'] = 'aarch64'
 
+        # fix-up for riscv
+        if params['arch'] == 'riscv':
+            try:
+                value = self._conf.syms.get('ARCH_RV32I').str_value
+            except:
+                value = ''
+            if value == 'y':
+                params['arch'] = 'riscv32'
+            else:
+                params['arch'] = 'riscv64'
+
         return params
 
 
diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile
index d3292e7..84b7777 100644
--- a/tools/docker/Dockerfile
+++ b/tools/docker/Dockerfile
@@ -2,7 +2,7 @@
 # This Dockerfile is used to build an image containing basic stuff to be used
 # to build U-Boot and run our test suites.
 
-FROM ubuntu:jammy-20220801
+FROM ubuntu:jammy-20221003
 MAINTAINER Tom Rini <trini@konsulko.com>
 LABEL Description=" This image is for building U-Boot inside a container"
 
@@ -24,6 +24,7 @@
 RUN wget -O - https://mirrors.edge.kernel.org/pub/tools/crosstool/files/bin/x86_64/11.1.0/x86_64-gcc-11.1.0-nolibc-nios2-linux.tar.xz | tar -C /opt -xJ
 RUN wget -O - https://mirrors.edge.kernel.org/pub/tools/crosstool/files/bin/x86_64/11.1.0/x86_64-gcc-11.1.0-nolibc-powerpc-linux.tar.xz | tar -C /opt -xJ
 RUN wget -O - https://mirrors.edge.kernel.org/pub/tools/crosstool/files/bin/x86_64/11.1.0/x86_64-gcc-11.1.0-nolibc-riscv64-linux.tar.xz | tar -C /opt -xJ
+RUN wget -O - https://mirrors.edge.kernel.org/pub/tools/crosstool/files/bin/x86_64/11.1.0/x86_64-gcc-11.1.0-nolibc-riscv32-linux.tar.xz | tar -C /opt -xJ
 RUN wget -O - https://mirrors.edge.kernel.org/pub/tools/crosstool/files/bin/x86_64/11.1.0/x86_64-gcc-11.1.0-nolibc-sh2-linux.tar.xz | tar -C /opt -xJ
 
 # Manually install other toolchains
@@ -217,6 +218,5 @@
 RUN /bin/echo -e "arc = /opt/arc_gnu_2021.03_prebuilt_uclibc_le_archs_linux_install" >> ~/.buildman
 RUN /bin/echo -e "\n[toolchain-prefix]\nxtensa = /opt/2020.07/xtensa-dc233c-elf/bin/xtensa-dc233c-elf-" >> ~/.buildman;
 RUN /bin/echo -e "\n[toolchain-alias]\nsh = sh2" >> ~/.buildman
-RUN /bin/echo -e "\nriscv = riscv64" >> ~/.buildman
 RUN /bin/echo -e "\nsandbox = x86_64" >> ~/.buildman
 RUN /bin/echo -e "\nx86 = i386" >> ~/.buildman;
diff --git a/tools/kwbimage.c b/tools/kwbimage.c
index 94b7685..6abb9f2 100644
--- a/tools/kwbimage.c
+++ b/tools/kwbimage.c
@@ -1969,6 +1969,9 @@
 	uint32_t size;
 	uint8_t csum;
 
+	if (header_size > 192*1024)
+		return -FDT_ERR_BADSTRUCTURE;
+
 	if (header_size > image_size)
 		return -FDT_ERR_BADSTRUCTURE;