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

- R-Car pinctrl updates
diff --git a/arch/arm/cpu/armv8/Makefile b/arch/arm/cpu/armv8/Makefile
index f7b4a5e..d85ddde 100644
--- a/arch/arm/cpu/armv8/Makefile
+++ b/arch/arm/cpu/armv8/Makefile
@@ -9,14 +9,16 @@
 ifndef CONFIG_$(SPL_TPL_)TIMER
 obj-$(CONFIG_SYS_ARCH_TIMER) += generic_timer.o
 endif
+ifndef CONFIG_$(SPL_)SYS_DCACHE_OFF
 obj-y	+= cache_v8.o
+obj-y	+= cache.o
+endif
 ifdef CONFIG_SPL_BUILD
 obj-$(CONFIG_ARMV8_SPL_EXCEPTION_VECTORS) += exceptions.o
 else
 obj-y	+= exceptions.o
 obj-y	+= exception_level.o
 endif
-obj-y	+= cache.o
 obj-y	+= tlb.o
 obj-y	+= transition.o
 ifndef CONFIG_ARMV8_PSCI
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 30b0540..55eaee2 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -152,6 +152,10 @@
 config 64BIT
 	bool
 
+config DMA_ADDR_T_64BIT
+	bool
+	default y if 64BIT
+
 config SIFIVE_CLINT
 	bool
 	depends on RISCV_MMODE || SPL_RISCV_MMODE
diff --git a/arch/riscv/dts/Makefile b/arch/riscv/dts/Makefile
index 3a6f96c..01331b0 100644
--- a/arch/riscv/dts/Makefile
+++ b/arch/riscv/dts/Makefile
@@ -3,6 +3,7 @@
 dtb-$(CONFIG_TARGET_AX25_AE350) += ae350_32.dtb ae350_64.dtb
 dtb-$(CONFIG_TARGET_SIFIVE_FU540) += hifive-unleashed-a00.dtb
 dtb-$(CONFIG_TARGET_SIPEED_MAIX) += k210-maix-bit.dtb
+dtb-$(CONFIG_TARGET_MICROCHIP_ICICLE) += microchip-mpfs-icicle-kit.dtb
 
 targets += $(dtb-y)
 
diff --git a/arch/riscv/dts/microchip-mpfs-icicle-kit-u-boot.dtsi b/arch/riscv/dts/microchip-mpfs-icicle-kit-u-boot.dtsi
new file mode 100644
index 0000000..f60283f
--- /dev/null
+++ b/arch/riscv/dts/microchip-mpfs-icicle-kit-u-boot.dtsi
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2020 Microchip Technology Inc.
+ * Padmarao Begari <padmarao.begari@microchip.com>
+ */
+
+/ {
+	aliases {
+		cpu1 = &cpu1;
+		cpu2 = &cpu2;
+		cpu3 = &cpu3;
+		cpu4 = &cpu4;
+	};
+};
diff --git a/arch/riscv/dts/microchip-mpfs-icicle-kit.dts b/arch/riscv/dts/microchip-mpfs-icicle-kit.dts
new file mode 100644
index 0000000..e2b9dec
--- /dev/null
+++ b/arch/riscv/dts/microchip-mpfs-icicle-kit.dts
@@ -0,0 +1,421 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/* Copyright (c) 2020 Microchip Technology Inc */
+
+/dts-v1/;
+#include "dt-bindings/clock/microchip-mpfs-clock.h"
+
+/* Clock frequency (in Hz) of the rtcclk */
+#define RTCCLK_FREQ		1000000
+
+/ {
+	#address-cells = <2>;
+	#size-cells = <2>;
+	model = "Microchip MPFS Icicle Kit";
+	compatible = "microchip,mpfs-icicle-kit";
+
+	aliases {
+		serial0 = &uart0;
+		ethernet0 = &emac1;
+	};
+
+	chosen {
+		stdout-path = "serial0";
+	};
+
+	cpucomplex: cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		timebase-frequency = <RTCCLK_FREQ>;
+		cpu0: cpu@0 {
+			clocks = <&clkcfg CLK_CPU>;
+			compatible = "sifive,e51", "sifive,rocket0", "riscv";
+			device_type = "cpu";
+			i-cache-block-size = <64>;
+			i-cache-sets = <128>;
+			i-cache-size = <16384>;
+			reg = <0>;
+			riscv,isa = "rv64imac";
+			status = "disabled";
+			operating-points = <
+				/* kHz	uV */
+				600000  1100000
+				300000   950000
+				150000   750000
+			>;
+			cpu0intc: interrupt-controller {
+				#interrupt-cells = <1>;
+				compatible = "riscv,cpu-intc";
+				interrupt-controller;
+			};
+		};
+		cpu1: cpu@1 {
+			clocks = <&clkcfg CLK_CPU>;
+			compatible = "sifive,u54-mc", "sifive,rocket0", "riscv";
+			d-cache-block-size = <64>;
+			d-cache-sets = <64>;
+			d-cache-size = <32768>;
+			d-tlb-sets = <1>;
+			d-tlb-size = <32>;
+			device_type = "cpu";
+			i-cache-block-size = <64>;
+			i-cache-sets = <64>;
+			i-cache-size = <32768>;
+			i-tlb-sets = <1>;
+			i-tlb-size = <32>;
+			mmu-type = "riscv,sv39";
+			reg = <1>;
+			riscv,isa = "rv64imafdc";
+			tlb-split;
+			status = "okay";
+			operating-points = <
+				/* kHz	uV */
+				600000  1100000
+				300000   950000
+				150000   750000
+			>;
+			cpu1intc: interrupt-controller {
+				#interrupt-cells = <1>;
+				compatible = "riscv,cpu-intc";
+				interrupt-controller;
+			};
+		};
+		cpu2: cpu@2 {
+			clocks = <&clkcfg CLK_CPU>;
+			compatible = "sifive,u54-mc", "sifive,rocket0", "riscv";
+			d-cache-block-size = <64>;
+			d-cache-sets = <64>;
+			d-cache-size = <32768>;
+			d-tlb-sets = <1>;
+			d-tlb-size = <32>;
+			device_type = "cpu";
+			i-cache-block-size = <64>;
+			i-cache-sets = <64>;
+			i-cache-size = <32768>;
+			i-tlb-sets = <1>;
+			i-tlb-size = <32>;
+			mmu-type = "riscv,sv39";
+			reg = <2>;
+			riscv,isa = "rv64imafdc";
+			tlb-split;
+			status = "okay";
+			operating-points = <
+				/* kHz	uV */
+				600000  1100000
+				300000   950000
+				150000   750000
+			>;
+			cpu2intc: interrupt-controller {
+				#interrupt-cells = <1>;
+				compatible = "riscv,cpu-intc";
+				interrupt-controller;
+			};
+		};
+		cpu3: cpu@3 {
+			clocks = <&clkcfg CLK_CPU>;
+			compatible = "sifive,u54-mc", "sifive,rocket0", "riscv";
+			d-cache-block-size = <64>;
+			d-cache-sets = <64>;
+			d-cache-size = <32768>;
+			d-tlb-sets = <1>;
+			d-tlb-size = <32>;
+			device_type = "cpu";
+			i-cache-block-size = <64>;
+			i-cache-sets = <64>;
+			i-cache-size = <32768>;
+			i-tlb-sets = <1>;
+			i-tlb-size = <32>;
+			mmu-type = "riscv,sv39";
+			reg = <3>;
+			riscv,isa = "rv64imafdc";
+			tlb-split;
+			status = "okay";
+			operating-points = <
+				/* kHz	uV */
+				600000  1100000
+				300000   950000
+				150000   750000
+			>;
+			cpu3intc: interrupt-controller {
+				#interrupt-cells = <1>;
+				compatible = "riscv,cpu-intc";
+				interrupt-controller;
+			};
+		};
+		cpu4: cpu@4 {
+			clocks = <&clkcfg CLK_CPU>;
+			compatible = "sifive,u54-mc", "sifive,rocket0", "riscv";
+			d-cache-block-size = <64>;
+			d-cache-sets = <64>;
+			d-cache-size = <32768>;
+			d-tlb-sets = <1>;
+			d-tlb-size = <32>;
+			device_type = "cpu";
+			i-cache-block-size = <64>;
+			i-cache-sets = <64>;
+			i-cache-size = <32768>;
+			i-tlb-sets = <1>;
+			i-tlb-size = <32>;
+			mmu-type = "riscv,sv39";
+			reg = <4>;
+			riscv,isa = "rv64imafdc";
+			tlb-split;
+			status = "okay";
+			operating-points = <
+				/* kHz	uV */
+				600000  1100000
+				300000   950000
+				150000   750000
+			>;
+			cpu4intc: interrupt-controller {
+				#interrupt-cells = <1>;
+				compatible = "riscv,cpu-intc";
+				interrupt-controller;
+			};
+		};
+	};
+	refclk: refclk {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <600000000>;
+		clock-output-names = "msspllclk";
+	};
+	ddr: memory@80000000 {
+		device_type = "memory";
+		reg = <0x0 0x80000000 0x0 0x40000000>;
+		clocks = <&clkcfg CLK_DDRC>;
+	};
+	soc: soc {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		compatible = "microchip,mpfs-icicle-kit", "simple-bus";
+		ranges;
+		clint0: clint@2000000 {
+			compatible = "riscv,clint0";
+			interrupts-extended = <&cpu0intc 3 &cpu0intc 7
+						&cpu1intc 3 &cpu1intc 7
+						&cpu2intc 3 &cpu2intc 7
+						&cpu3intc 3 &cpu3intc 7
+						&cpu4intc 3 &cpu4intc 7>;
+			reg = <0x0 0x2000000 0x0 0x10000>;
+			reg-names = "control";
+			clock-frequency = <RTCCLK_FREQ>;
+		};
+		cachecontroller: cache-controller@2010000 {
+			compatible = "sifive,fu540-c000-ccache", "cache";
+			cache-block-size = <64>;
+			cache-level = <2>;
+			cache-sets = <1024>;
+			cache-size = <2097152>;
+			cache-unified;
+			interrupt-parent = <&plic>;
+			interrupts = <1 2 3>;
+			reg = <0x0 0x2010000 0x0 0x1000>;
+		};
+		plic: interrupt-controller@c000000 {
+			#interrupt-cells = <1>;
+			compatible = "sifive,plic-1.0.0";
+			reg = <0x0 0xc000000 0x0 0x4000000>;
+			riscv,max-priority = <7>;
+			riscv,ndev = <186>;
+			interrupt-controller;
+			interrupts-extended = <
+				&cpu0intc 11
+				&cpu1intc 11 &cpu1intc 9
+				&cpu2intc 11 &cpu2intc 9
+				&cpu3intc 11 &cpu3intc 9
+				&cpu4intc 11 &cpu4intc 9>;
+		};
+		uart0: serial@20000000 {
+			compatible = "ns16550a";
+			reg = <0x0 0x20000000 0x0 0x400>;
+			reg-io-width = <4>;
+			reg-shift = <2>;
+			interrupt-parent = <&plic>;
+			interrupts = <90>;
+			clock-frequency = <150000000>;
+			clocks = <&clkcfg CLK_MMUART0>;
+			status = "okay";
+		};
+		clkcfg: clkcfg@20002000 {
+			compatible = "microchip,mpfs-clkcfg";
+			reg = <0x0 0x20002000 0x0 0x1000>;
+			reg-names = "mss_sysreg";
+			clocks = <&refclk>;
+			#clock-cells = <1>;
+			clock-output-names = "cpu", "axi", "ahb", "envm",
+					"mac0", "mac1", "mmc", "timer",
+					"mmuart0", "mmuart1", "mmuart2",
+					"mmuart3", "mmuart4", "spi0", "spi1",
+					"i2c0",	"i2c1", "can0", "can1", "usb",
+					"reserved", "rtc", "qspi", "gpio0",
+					"gpio1", "gpio2", "ddrc", "fic0",
+					"fic1", "fic2", "fic3", "athena",
+					"cfm";
+		};
+		emmc: mmc@20008000 {
+			compatible = "cdns,sd4hc";
+			reg = <0x0 0x20008000 0x0 0x1000>;
+			interrupt-parent = <&plic>;
+			interrupts = <88 89>;
+			pinctrl-names = "default";
+			clocks = <&clkcfg CLK_MMC>;
+			bus-width = <4>;
+			cap-mmc-highspeed;
+			mmc-ddr-3_3v;
+			max-frequency = <200000000>;
+			non-removable;
+			no-sd;
+			no-sdio;
+			voltage-ranges = <3300 3300>;
+			status = "okay";
+		};
+		sdcard: sd@20008000 {
+			compatible = "cdns,sd4hc";
+			reg = <0x0 0x20008000 0x0 0x1000>;
+			interrupt-parent = <&plic>;
+			interrupts = <88>;
+			pinctrl-names = "default";
+			clocks = <&clkcfg CLK_MMC>;
+			bus-width = <4>;
+			disable-wp;
+			cap-sd-highspeed;
+			card-detect-delay = <200>;
+			sd-uhs-sdr12;
+			sd-uhs-sdr25;
+			sd-uhs-sdr50;
+			sd-uhs-sdr104;
+			max-frequency = <200000000>;
+			status = "disabled";
+		};
+		uart1: serial@20100000 {
+			compatible = "ns16550a";
+			reg = <0x0 0x20100000 0x0 0x400>;
+			reg-io-width = <4>;
+			reg-shift = <2>;
+			interrupt-parent = <&plic>;
+			interrupts = <91>;
+			clock-frequency = <150000000>;
+			clocks = <&clkcfg CLK_MMUART1>;
+			status = "okay";
+		};
+		uart2: serial@20102000 {
+			compatible = "ns16550a";
+			reg = <0x0 0x20102000 0x0 0x400>;
+			reg-io-width = <4>;
+			reg-shift = <2>;
+			interrupt-parent = <&plic>;
+			interrupts = <92>;
+			clock-frequency = <150000000>;
+			clocks = <&clkcfg CLK_MMUART2>;
+			status = "okay";
+		};
+		uart3: serial@20104000 {
+			compatible = "ns16550a";
+			reg = <0x0 0x20104000 0x0 0x400>;
+			reg-io-width = <4>;
+			reg-shift = <2>;
+			interrupt-parent = <&plic>;
+			interrupts = <93>;
+			clock-frequency = <150000000>;
+			clocks = <&clkcfg CLK_MMUART3>;
+			status = "okay";
+		};
+		i2c0: i2c@2010a000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "microchip,mpfs-mss-i2c";
+			reg = <0x0 0x2010a000 0x0 0x1000>;
+			interrupt-parent = <&plic>;
+			interrupts = <58>;
+			clocks = <&clkcfg CLK_I2C0>;
+			status = "disabled";
+		};
+		i2c1: i2c@2010b000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "microchip,mpfs-mss-i2c";
+			reg = <0x0 0x2010b000 0x0 0x1000>;
+			interrupt-parent = <&plic>;
+			interrupts = <61>;
+			clocks = <&clkcfg CLK_I2C1>;
+			status = "disabled";
+			pac193x@10 {
+				compatible = "microchip,pac1934";
+				reg = <0x10>;
+				samp-rate = <64>;
+				status = "disabled";
+				ch1: channel0 {
+					uohms-shunt-res = <10000>;
+					rail-name = "VDD";
+					channel_enabled;
+				};
+				ch2: channel1 {
+					uohms-shunt-res = <10000>;
+					rail-name = "VDDA25";
+					channel_enabled;
+				};
+				ch3: channel2 {
+					uohms-shunt-res = <10000>;
+					rail-name = "VDD25";
+					channel_enabled;
+				};
+				ch4: channel3 {
+					uohms-shunt-res = <10000>;
+					rail-name = "VDDA";
+					channel_enabled;
+				};
+			};
+		};
+		emac0: ethernet@20110000 {
+			compatible = "microchip,mpfs-mss-gem";
+			reg = <0x0 0x20110000 0x0 0x2000>;
+			interrupt-parent = <&plic>;
+			interrupts = <64 65 66 67>;
+			local-mac-address = [56 34 00 FC 00 02];
+			phy-mode = "sgmii";
+			clocks = <&clkcfg CLK_MAC0>, <&clkcfg CLK_AXI>;
+			clock-names = "pclk", "hclk";
+			status = "disabled";
+
+			#address-cells = <1>;
+			#size-cells = <0>;
+			phy-handle = <&phy0>;
+			phy0: ethernet-phy@8 {
+				reg = <8>;
+				ti,fifo-depth = <0x01>;
+			};
+		};
+		emac1: ethernet@20112000 {
+			compatible = "microchip,mpfs-mss-gem";
+			reg = <0x0 0x20112000 0x0 0x2000>;
+			interrupt-parent = <&plic>;
+			interrupts = <70 71 72 73>;
+			local-mac-address = [00 00 00 00 00 00];
+			phy-mode = "sgmii";
+			clocks = <&clkcfg CLK_MAC1>, <&clkcfg CLK_AHB>;
+			clock-names = "pclk", "hclk";
+			status = "okay";
+
+			#address-cells = <1>;
+			#size-cells = <0>;
+			phy-handle = <&phy1>;
+			phy1: ethernet-phy@9 {
+				reg = <9>;
+				ti,fifo-depth = <0x01>;
+			};
+		};
+		gpio: gpio@20122000 {
+			compatible = "microchip,mpfs-mss-gpio";
+			interrupt-parent = <&plic>;
+			interrupts = <13 14 15 16 17 18 19 20 21 22 23 24 25 26
+					27 28 29 30 31 32 33 34 35 36 37 38 39
+					40 41 42 43 44>;
+			gpio-controller;
+			clocks = <&clkcfg CLK_GPIO2>;
+			reg = <0x00 0x20122000 0x0 0x1000>;
+			reg-names = "control";
+			#gpio-cells = <2>;
+			status = "disabled";
+		};
+	};
+};
diff --git a/arch/riscv/include/asm/types.h b/arch/riscv/include/asm/types.h
index 403cf9a..b800b2d 100644
--- a/arch/riscv/include/asm/types.h
+++ b/arch/riscv/include/asm/types.h
@@ -29,7 +29,11 @@
 
 #include <stddef.h>
 
+#ifdef CONFIG_DMA_ADDR_T_64BIT
+typedef u64 dma_addr_t;
+#else
 typedef u32 dma_addr_t;
+#endif
 
 typedef unsigned long phys_addr_t;
 typedef unsigned long phys_size_t;
diff --git a/board/microchip/mpfs_icicle/Kconfig b/board/microchip/mpfs_icicle/Kconfig
index bf8e1a1..4678462 100644
--- a/board/microchip/mpfs_icicle/Kconfig
+++ b/board/microchip/mpfs_icicle/Kconfig
@@ -20,7 +20,30 @@
 	def_bool y
 	select GENERIC_RISCV
 	select BOARD_EARLY_INIT_F
+	select BOARD_LATE_INIT
 	imply SMP
+	imply CLK_CCF
+	imply CLK_MPFS
 	imply SYS_NS16550
+	imply CMD_DHCP
+	imply CMD_EXT2
+	imply CMD_EXT4
+	imply CMD_FAT
+	imply CMD_FS_GENERIC
+	imply CMD_NET
+	imply CMD_PING
+	imply CMD_MMC
+	imply DOS_PARTITION
+	imply EFI_PARTITION
+	imply IP_DYN
+	imply ISO_PARTITION
+	imply MACB
+	imply MII
+	imply PHY_LIB
+	imply PHY_VITESSE
+	imply MMC
+	imply MMC_WRITE
+	imply MMC_SDHCI
+	imply MMC_SDHCI_CADENCE
 
 endif
diff --git a/board/microchip/mpfs_icicle/mpfs_icicle.c b/board/microchip/mpfs_icicle/mpfs_icicle.c
index 8381361..0e34409 100644
--- a/board/microchip/mpfs_icicle/mpfs_icicle.c
+++ b/board/microchip/mpfs_icicle/mpfs_icicle.c
@@ -6,10 +6,49 @@
 
 #include <common.h>
 #include <dm.h>
+#include <env.h>
 #include <init.h>
 #include <asm/io.h>
 
-#define MPFS_SYSREG_SOFT_RESET	((unsigned int *)0x20002088)
+DECLARE_GLOBAL_DATA_PTR;
+
+#define MPFS_SYSREG_SOFT_RESET		((unsigned int *)0x20002088)
+#define MPFS_SYS_SERVICE_CR		((unsigned int *)0x37020050)
+#define MPFS_SYS_SERVICE_SR		((unsigned int *)0x37020054)
+#define MPFS_SYS_SERVICE_MAILBOX	((unsigned char *)0x37020800)
+
+#define PERIPH_RESET_VALUE		0x1e8u
+#define SERVICE_CR_REQ			0x1u
+#define SERVICE_SR_BUSY			0x2u
+
+static void read_device_serial_number(u8 *response, u8 response_size)
+{
+	u8 idx;
+	u8 *response_buf;
+	unsigned int val;
+
+	response_buf = (u8 *)response;
+
+	writel(SERVICE_CR_REQ, MPFS_SYS_SERVICE_CR);
+	/*
+	 * REQ bit will remain set till the system controller starts
+	 * processing.
+	 */
+	do {
+		val = readl(MPFS_SYS_SERVICE_CR);
+	} while (SERVICE_CR_REQ == (val & SERVICE_CR_REQ));
+
+	/*
+	 * Once system controller starts processing the busy bit will
+	 * go high and service is completed when busy bit is gone low
+	 */
+	do {
+		val = readl(MPFS_SYS_SERVICE_SR);
+	} while (SERVICE_SR_BUSY == (val & SERVICE_SR_BUSY));
+
+	for (idx = 0; idx < response_size; idx++)
+		response_buf[idx] = readb(MPFS_SYS_SERVICE_MAILBOX + idx);
+}
 
 int board_init(void)
 {
@@ -22,10 +61,64 @@
 {
 	unsigned int val;
 
-	/* Reset uart peripheral */
+	/* Reset uart, mmc peripheral */
 	val = readl(MPFS_SYSREG_SOFT_RESET);
-	val = (val & ~(1u << 5u));
+	val = (val & ~(PERIPH_RESET_VALUE));
 	writel(val, MPFS_SYSREG_SOFT_RESET);
 
 	return 0;
 }
+
+int board_late_init(void)
+{
+	u32 ret;
+	u32 node;
+	u8 idx;
+	u8 device_serial_number[16] = { 0 };
+	unsigned char mac_addr[6];
+	char icicle_mac_addr[20];
+	void *blob = (void *)gd->fdt_blob;
+
+	node = fdt_path_offset(blob, "ethernet0");
+	if (node < 0) {
+		printf("No ethernet0 path offset\n");
+		return -ENODEV;
+	}
+
+	ret = fdtdec_get_byte_array(blob, node, "local-mac-address", mac_addr, 6);
+	if (ret) {
+		printf("No local-mac-address property\n");
+		return -EINVAL;
+	}
+
+	read_device_serial_number(device_serial_number, 16);
+
+	/* Update MAC address with device serial number */
+	mac_addr[0] = 0x00;
+	mac_addr[1] = 0x04;
+	mac_addr[2] = 0xA3;
+	mac_addr[3] = device_serial_number[2];
+	mac_addr[4] = device_serial_number[1];
+	mac_addr[5] = device_serial_number[0];
+
+	ret = fdt_setprop(blob, node, "local-mac-address", mac_addr, 6);
+	if (ret) {
+		printf("Error setting local-mac-address property\n");
+		return -ENODEV;
+	}
+
+	icicle_mac_addr[0] = '[';
+
+	sprintf(&icicle_mac_addr[1], "%pM", mac_addr);
+
+	icicle_mac_addr[18] = ']';
+	icicle_mac_addr[19] = '\0';
+
+	for (idx = 0; idx < 20; idx++) {
+		if (icicle_mac_addr[idx] == ':')
+			icicle_mac_addr[idx] = ' ';
+	}
+	env_set("icicle_mac_addr", icicle_mac_addr);
+
+	return 0;
+}
diff --git a/board/sipeed/maix/Kconfig b/board/sipeed/maix/Kconfig
index 4c42dd2..2cdea8e 100644
--- a/board/sipeed/maix/Kconfig
+++ b/board/sipeed/maix/Kconfig
@@ -53,4 +53,20 @@
 	imply CMD_GPIO
 	imply LED
 	imply LED_GPIO
+	imply SPI
+	imply DESIGNWARE_SPI
+	imply SPI_FLASH_GIGADEVICE
+	imply SPI_FLASH_WINBOND
+	imply DM_MTD
+	imply SPI_FLASH_MTD
+	imply CMD_MTD
+	imply ENV_IS_IN_SPI_FLASH
+	imply MMC
+	imply MMC_BROKEN_CD
+	imply MMC_SPI
+	imply CMD_MMC
+	imply DOS_PARTITION
+	imply EFI_PARTITION
+	imply CMD_PART
+	imply CMD_FS_GENERIC
 endif
diff --git a/cmd/Kconfig b/cmd/Kconfig
index 0107c0f..1b53e5b 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -122,6 +122,7 @@
 
 config CMD_CPU
 	bool "cpu"
+	depends on CPU
 	help
 	  Print information about available CPUs. This normally shows the
 	  number of CPUs, type (e.g. manufacturer, architecture, product or
diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c
index 1ba7b62..409ef9a 100644
--- a/cmd/bootmenu.c
+++ b/cmd/bootmenu.c
@@ -45,6 +45,7 @@
 	KEY_UP,
 	KEY_DOWN,
 	KEY_SELECT,
+	KEY_QUIT,
 };
 
 static char *bootmenu_getoption(unsigned short int n)
@@ -109,6 +110,9 @@
 			case '\r':
 				*key = KEY_SELECT;
 				break;
+			case 0x3: /* ^C */
+				*key = KEY_QUIT;
+				break;
 			default:
 				*key = KEY_NONE;
 				break;
@@ -136,13 +140,25 @@
 {
 	int c;
 
-	while (!tstc()) {
-		WATCHDOG_RESET();
-		mdelay(10);
+	if (*esc == 1) {
+		if (tstc()) {
+			c = getchar();
+		} else {
+			WATCHDOG_RESET();
+			mdelay(10);
+			if (tstc())
+				c = getchar();
+			else
+				c = '\e';
+		}
+	} else {
+		while (!tstc()) {
+			WATCHDOG_RESET();
+			mdelay(10);
+		}
+		c = getchar();
 	}
 
-	c = getchar();
-
 	switch (*esc) {
 	case 0:
 		/* First char of ANSI escape sequence '\e' */
@@ -157,7 +173,9 @@
 			*esc = 2;
 			*key = KEY_NONE;
 		} else {
-			*esc = 0;
+		/* Alone ESC key was pressed */
+			*key = KEY_QUIT;
+			*esc = (c == '\e') ? 1 : 0;
 		}
 		break;
 	case 2:
@@ -187,6 +205,10 @@
 	/* enter key was pressed */
 	if (c == '\r')
 		*key = KEY_SELECT;
+
+	/* ^C was pressed */
+	if (c == 0x3)
+		*key = KEY_QUIT;
 }
 
 static char *bootmenu_choice_entry(void *data)
@@ -222,6 +244,12 @@
 			for (i = 0; i < menu->active; ++i)
 				iter = iter->next;
 			return iter->key;
+		case KEY_QUIT:
+			/* Quit by choosing the last entry - U-Boot console */
+			iter = menu->first;
+			while (iter->next)
+				iter = iter->next;
+			return iter->key;
 		default:
 			break;
 		}
@@ -389,7 +417,7 @@
 	printf(ANSI_CURSOR_POSITION, menu->count + 5, 1);
 	puts(ANSI_CLEAR_LINE);
 	printf(ANSI_CURSOR_POSITION, menu->count + 6, 1);
-	puts("  Press UP/DOWN to move, ENTER to select");
+	puts("  Press UP/DOWN to move, ENTER to select, ESC/CTRL+C to quit");
 	puts(ANSI_CLEAR_LINE_TO_END);
 	printf(ANSI_CURSOR_POSITION, menu->count + 7, 1);
 	puts(ANSI_CLEAR_LINE);
diff --git a/cmd/disk.c b/cmd/disk.c
index 8060e75..0bc3808 100644
--- a/cmd/disk.c
+++ b/cmd/disk.c
@@ -120,7 +120,6 @@
 			return 1;
 		}
 		bootstage_mark(BOOTSTAGE_ID_IDE_FIT_READ_OK);
-		fit_print_contents(fit_hdr);
 	}
 #endif
 
diff --git a/cmd/gpt.c b/cmd/gpt.c
index df75941..76a95ad 100644
--- a/cmd/gpt.c
+++ b/cmd/gpt.c
@@ -18,6 +18,7 @@
 #include <command.h>
 #include <part.h>
 #include <part_efi.h>
+#include <part.h>
 #include <exports.h>
 #include <uuid.h>
 #include <linux/ctype.h>
@@ -621,6 +622,152 @@
 	return ret;
 }
 
+/**
+ * gpt_enumerate() - Enumerate partition names into environment variable.
+ *
+ * Enumerate partition names. Partition names are stored in gpt_partition_list
+ * environment variable. Each partition name is delimited by space.
+ *
+ * @desc: block device descriptor
+ *
+ * @Return: '0' on success and -ve error on failure
+ */
+static int gpt_enumerate(struct blk_desc *desc)
+{
+	struct part_driver *first_drv, *part_drv;
+	int str_len = 0, tmp_len;
+	char part_list[2048];
+	int n_drvs;
+	char *ptr;
+
+	part_list[0] = 0;
+	n_drvs = part_driver_get_count();
+	if (!n_drvs) {
+		printf("Failed to get partition driver count\n");
+		return -ENOENT;
+	}
+
+	first_drv = part_driver_get_first();
+	for (part_drv = first_drv; part_drv != first_drv + n_drvs; part_drv++) {
+		struct disk_partition pinfo;
+		int ret;
+		int i;
+
+		for (i = 1; i < part_drv->max_entries; i++) {
+			ret = part_drv->get_info(desc, i, &pinfo);
+			if (ret) {
+				/* no more entries in table */
+				break;
+			}
+
+			ptr = &part_list[str_len];
+			tmp_len = strlen((const char *)pinfo.name);
+			str_len += tmp_len;
+			/* +1 for space */
+			str_len++;
+			if (str_len > sizeof(part_list)) {
+				printf("Error insufficient memory\n");
+				return -ENOMEM;
+			}
+			strcpy(ptr, (const char *)pinfo.name);
+			/* One byte for space(" ") delimiter */
+			ptr[tmp_len] = ' ';
+		}
+	}
+	if (*part_list)
+		part_list[strlen(part_list) - 1] = 0;
+	debug("setenv gpt_partition_list %s\n", part_list);
+
+	return env_set("gpt_partition_list", part_list);
+}
+
+/**
+ * gpt_setenv_part_variables() - setup partition environmental variables
+ *
+ * Setup the gpt_partition_name, gpt_partition_entry, gpt_partition_addr
+ * and gpt_partition_size environment variables.
+ *
+ * @pinfo: pointer to disk partition
+ * @i: partition entry
+ *
+ * @Return: '0' on success and -ENOENT on failure
+ */
+static int gpt_setenv_part_variables(struct disk_partition *pinfo, int i)
+{
+	int ret;
+
+	ret = env_set_hex("gpt_partition_addr", pinfo->start);
+	if (ret)
+		goto fail;
+
+	ret = env_set_hex("gpt_partition_size", pinfo->size);
+	if (ret)
+		goto fail;
+
+	ret = env_set_ulong("gpt_partition_entry", i);
+	if (ret)
+		goto fail;
+
+	ret = env_set("gpt_partition_name", (const char *)pinfo->name);
+	if (ret)
+		goto fail;
+
+	return 0;
+
+fail:
+	return -ENOENT;
+}
+
+/**
+ * gpt_setenv() - Dynamically setup environment variables.
+ *
+ * Dynamically setup environment variables for name, index, offset and size
+ * for partition in GPT table after running "gpt setenv" for a partition name.
+ *
+ * @desc: block device descriptor
+ * @name: partition name
+ *
+ * @Return: '0' on success and -ve err on failure
+ */
+static int gpt_setenv(struct blk_desc *desc, const char *name)
+{
+	struct part_driver *first_drv, *part_drv;
+	int n_drvs;
+	int ret = -1;
+
+	n_drvs = part_driver_get_count();
+	if (!n_drvs) {
+		printf("Failed to get partition driver count\n");
+		goto fail;
+	}
+
+	first_drv = part_driver_get_first();
+	for (part_drv = first_drv; part_drv != first_drv + n_drvs; part_drv++) {
+		struct disk_partition pinfo;
+		int i;
+
+		for (i = 1; i < part_drv->max_entries; i++) {
+			ret = part_drv->get_info(desc, i, &pinfo);
+			if (ret) {
+				/* no more entries in table */
+				break;
+			}
+
+			if (!strcmp(name, (const char *)pinfo.name)) {
+				/* match found, setup environment variables */
+				ret = gpt_setenv_part_variables(&pinfo, i);
+				if (ret)
+					goto fail;
+
+				return 0;
+			}
+		}
+	}
+
+fail:
+	return ret;
+}
+
 static int do_disk_guid(struct blk_desc *dev_desc, char * const namestr)
 {
 	int ret;
@@ -827,6 +974,10 @@
 	} else if ((strcmp(argv[1], "verify") == 0)) {
 		ret = gpt_verify(blk_dev_desc, argv[4]);
 		printf("Verify GPT: ");
+	} else if ((strcmp(argv[1], "setenv") == 0)) {
+		ret = gpt_setenv(blk_dev_desc, argv[4]);
+	} else if ((strcmp(argv[1], "enumerate") == 0)) {
+		ret = gpt_enumerate(blk_dev_desc);
 	} else if (strcmp(argv[1], "guid") == 0) {
 		ret = do_disk_guid(blk_dev_desc, argv[4]);
 #ifdef CONFIG_CMD_GPT_RENAME
@@ -857,7 +1008,17 @@
 	" to interface\n"
 	" Example usage:\n"
 	" gpt write mmc 0 $partitions\n"
+	"    - write the GPT to device\n"
 	" gpt verify mmc 0 $partitions\n"
+	"    - verify the GPT on device against $partitions\n"
+	" gpt setenv mmc 0 $name\n"
+	"    - setup environment variables for partition $name:\n"
+	"      gpt_partition_addr, gpt_partition_size,\n"
+	"      gpt_partition_name, gpt_partition_entry\n"
+	" gpt enumerate mmc 0\n"
+	"    - store list of partitions to gpt_partition_list environment variable\n"
+	" read <interface> <dev>\n"
+	"    - read GPT into a data structure for manipulation\n"
 	" gpt guid <interface> <dev>\n"
 	"    - print disk GUID\n"
 	" gpt guid <interface> <dev> <varname>\n"
diff --git a/common/Kconfig.boot b/common/Kconfig.boot
index 58e9854..4525a12 100644
--- a/common/Kconfig.boot
+++ b/common/Kconfig.boot
@@ -819,7 +819,10 @@
 	  This option adds the feature to only stop the autobooting,
 	  and therefore boot into the U-Boot prompt, when the input
 	  string / password matches a values that is encypted via
-	  a SHA256 hash and saved in the environment.
+	  a SHA256 hash and saved in the environment variable
+	  "bootstopkeysha256". If the value in that variable
+	  includes a ":", the portion prior to the ":" will be treated
+	  as a salt value.
 
 config AUTOBOOT_USE_MENUKEY
 	bool "Allow a specify key to run a menu from the environment"
diff --git a/common/Makefile b/common/Makefile
index bcf352d..daeea67 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -68,7 +68,6 @@
 endif
 obj-$(CONFIG_SPL_HASH_SUPPORT) += hash.o
 obj-$(CONFIG_TPL_HASH_SUPPORT) += hash.o
-obj-$(CONFIG_SPL_YMODEM_SUPPORT) += xyzModem.o
 obj-$(CONFIG_SPL_LOAD_FIT) += common_fit.o
 obj-$(CONFIG_SPL_NET_SUPPORT) += miiphyutil.o
 obj-$(CONFIG_$(SPL_TPL_)OF_LIBFDT) += fdt_support.o
diff --git a/common/autoboot.c b/common/autoboot.c
index e628baf..ddb6246 100644
--- a/common/autoboot.c
+++ b/common/autoboot.c
@@ -25,7 +25,7 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-#define MAX_DELAY_STOP_STR 32
+#define MAX_DELAY_STOP_STR 64
 
 #ifndef DEBUG_BOOTKEYS
 #define DEBUG_BOOTKEYS 0
@@ -80,6 +80,7 @@
 	u8 sha_env[SHA256_SUM_LEN];
 	u8 *sha;
 	char *presskey;
+	char *c;
 	const char *algo_name = "sha256";
 	u_int presskey_len = 0;
 	int abort = 0;
@@ -89,6 +90,14 @@
 	if (sha_env_str == NULL)
 		sha_env_str = AUTOBOOT_STOP_STR_SHA256;
 
+	presskey = malloc_cache_aligned(MAX_DELAY_STOP_STR);
+	c = strstr(sha_env_str, ":");
+	if (c && (c - sha_env_str < MAX_DELAY_STOP_STR)) {
+		/* preload presskey with salt */
+		memcpy(presskey, sha_env_str, c - sha_env_str);
+		presskey_len = c - sha_env_str;
+		sha_env_str = c + 1;
+	}
 	/*
 	 * Generate the binary value from the environment hash value
 	 * so that we can compare this value with the computed hash
@@ -100,7 +109,6 @@
 		return 0;
 	}
 
-	presskey = malloc_cache_aligned(MAX_DELAY_STOP_STR);
 	sha = malloc_cache_aligned(SHA256_SUM_LEN);
 	size = SHA256_SUM_LEN;
 	/*
diff --git a/common/cli_readline.c b/common/cli_readline.c
index 47b8762..5c158d0 100644
--- a/common/cli_readline.c
+++ b/common/cli_readline.c
@@ -493,8 +493,10 @@
 		}
 #endif
 		default:
-			cread_add_char(ichar, insert, &num, &eol_num, buf,
-				       *len);
+			if (ichar >= ' ' && ichar <= '~') {
+				cread_add_char(ichar, insert, &num, &eol_num,
+					       buf, *len);
+			}
 			break;
 		}
 	}
diff --git a/common/command.c b/common/command.c
index 068cb55..3fe6791 100644
--- a/common/command.c
+++ b/common/command.c
@@ -16,6 +16,8 @@
 #include <log.h>
 #include <linux/ctype.h>
 
+DECLARE_GLOBAL_DATA_PTR;
+
 /*
  * Use puts() instead of printf() to avoid printf buffer overflow
  * for long help messages
@@ -488,9 +490,6 @@
 }
 #endif
 
-#if defined(CONFIG_NEEDS_MANUAL_RELOC)
-DECLARE_GLOBAL_DATA_PTR;
-
 void fixup_cmdtable(struct cmd_tbl *cmdtp, int size)
 {
 	int	i;
@@ -535,7 +534,6 @@
 		cmdtp++;
 	}
 }
-#endif
 
 int cmd_always_repeatable(struct cmd_tbl *cmdtp, int flag, int argc,
 			  char *const argv[], int *repeatable)
diff --git a/common/console.c b/common/console.c
index b15f732..f3cc45c 100644
--- a/common/console.c
+++ b/common/console.c
@@ -1029,11 +1029,6 @@
 
 	gd->flags |= GD_FLG_DEVINIT;	/* device initialization completed */
 
-#if 0
-	/* If nothing usable installed, use only the initial console */
-	if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL))
-		return 0;
-#endif
 	print_pre_console_buffer(flushpoint);
 	return 0;
 }
@@ -1105,11 +1100,6 @@
 
 	gd->flags |= GD_FLG_DEVINIT;	/* device initialization completed */
 
-#if 0
-	/* If nothing usable installed, use only the initial console */
-	if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL))
-		return 0;
-#endif
 	print_pre_console_buffer(flushpoint);
 	return 0;
 }
diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c
index 795e292..a6ad094 100644
--- a/common/spl/spl_fit.c
+++ b/common/spl/spl_fit.c
@@ -684,8 +684,11 @@
 
 		ret = spl_load_fit_image(info, sector, fit, base_offset, node,
 					 &image_info);
-		if (ret < 0)
-			continue;
+		if (ret < 0) {
+			printf("%s: can't load image loadables index %d (ret = %d)\n",
+			       __func__, index, ret);
+			return ret;
+		}
 
 		if (!spl_fit_image_get_os(fit, node, &os_type))
 			debug("Loadable is %s\n", genimg_get_os_name(os_type));
diff --git a/configs/microchip_mpfs_icicle_defconfig b/configs/microchip_mpfs_icicle_defconfig
index 2977966..9abbc18 100644
--- a/configs/microchip_mpfs_icicle_defconfig
+++ b/configs/microchip_mpfs_icicle_defconfig
@@ -1,12 +1,15 @@
 CONFIG_RISCV=y
 CONFIG_ENV_SIZE=0x2000
 CONFIG_TARGET_MICROCHIP_ICICLE=y
-CONFIG_NR_CPUS=5
 CONFIG_ARCH_RV64I=y
+CONFIG_RISCV_SMODE=y
+CONFIG_SBI_V01=y
+CONFIG_DEFAULT_DEVICE_TREE="microchip-mpfs-icicle-kit"
+CONFIG_DISTRO_DEFAULTS=y
+CONFIG_DISPLAY_CPUINFO=y
+CONFIG_DISPLAY_BOARDINFO=y
 CONFIG_FIT=y
-CONFIG_BOOTDELAY=3
 CONFIG_SYS_PROMPT="RISC-V # "
-CONFIG_OF_PRIOR_STAGE=y
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_BOOTP_SEND_HOSTNAME=y
 CONFIG_DM_MTD=y
diff --git a/configs/sipeed_maix_bitm_defconfig b/configs/sipeed_maix_bitm_defconfig
index 459bf0d..210848c 100644
--- a/configs/sipeed_maix_bitm_defconfig
+++ b/configs/sipeed_maix_bitm_defconfig
@@ -1,8 +1,19 @@
 CONFIG_RISCV=y
+CONFIG_ENV_SIZE=0x1000
+CONFIG_ENV_OFFSET=0xfff000
+CONFIG_ENV_SECT_SIZE=0x1000
 CONFIG_TARGET_SIPEED_MAIX=y
 CONFIG_ARCH_RV64I=y
 CONFIG_STACK_SIZE=0x100000
+CONFIG_USE_BOOTCOMMAND=y
+CONFIG_BOOTCOMMAND="run k210_bootcmd"
+CONFIG_HUSH_PARSER=y
+CONFIG_MTDIDS_DEFAULT="nor0=spi3:0"
+CONFIG_MTDPARTS_DEFAULT="nor0:1M(u-boot),0x1000@0xfff000(env)"
 # CONFIG_NET is not set
 # CONFIG_INPUT is not set
+CONFIG_SF_DEFAULT_BUS=3
 # CONFIG_DM_ETH is not set
+CONFIG_FS_EXT4=y
+CONFIG_FS_FAT=y
 # CONFIG_EFI_LOADER is not set
diff --git a/disk/part_efi.c b/disk/part_efi.c
index 60b1c1d..2f92266 100644
--- a/disk/part_efi.c
+++ b/disk/part_efi.c
@@ -247,10 +247,11 @@
 		uuid_bin = (unsigned char *)gpt_pte[i].partition_type_guid.b;
 		uuid_bin_to_str(uuid_bin, uuid, UUID_STR_FORMAT_GUID);
 		printf("\ttype:\t%s\n", uuid);
-#ifdef CONFIG_PARTITION_TYPE_GUID
-		if (!uuid_guid_get_str(uuid_bin, uuid))
-			printf("\ttype:\t%s\n", uuid);
-#endif
+		if (CONFIG_IS_ENABLED(PARTITION_TYPE_GUID)) {
+			const char *type = uuid_guid_get_str(uuid_bin);
+			if (type)
+				printf("\ttype:\t%s\n", type);
+		}
 		uuid_bin = (unsigned char *)gpt_pte[i].unique_partition_guid.b;
 		uuid_bin_to_str(uuid_bin, uuid, UUID_STR_FORMAT_GUID);
 		printf("\tguid:\t%s\n", uuid);
diff --git a/doc/README.fdt-overlays b/doc/README.fdt-overlays
deleted file mode 100644
index 39139cb..0000000
--- a/doc/README.fdt-overlays
+++ /dev/null
@@ -1,114 +0,0 @@
-U-Boot FDT Overlay usage
-=============================================
-
-Overlays Syntax
----------------
-
-Overlays require slightly different syntax compared to traditional overlays.
-Please refer to dt-object-internal.txt in the dtc sources for information
-regarding the internal format of overlays:
-https://git.kernel.org/pub/scm/utils/dtc/dtc.git/tree/Documentation/dt-object-internal.txt
-
-Building Overlays
------------------
-
-In a nutshell overlays provides a means to manipulate a symbol a previous dtb
-or overlay has defined. It requires both the base and all the overlays
-to be compiled with the -@ command line switch so that symbol information is
-included.
-
-Note support for -@ option can only be found in dtc version 1.4.4 or newer.
-Only version 4.14 or higher of the Linux kernel includes a built in version
-of dtc that meets this requirement.
-
-Building an overlay follows the same process as building a traditional dtb.
-
-For example:
-
-base.dts
---------
-
-	/dts-v1/;
-	/ {
-		foo: foonode {
-			foo-property;
-		};
-	};
-
-	$ dtc -@ -I dts -O dtb -o base.dtb base.dts
-
-bar.dts
--------
-
-	/dts-v1/;
-	/plugin/;
-	/ {
-		fragment@1 {
-			target = <&foo>;
-			__overlay__ {
-				overlay-1-property;
-				bar: barnode {
-					bar-property;
-				};
-			};
-		};
-	};
-
-	$ dtc -@ -I dts -O dtb -o bar.dtb bar.dts
-
-Ways to Utilize Overlays in U-boot
-----------------------------------
-
-There are two ways to apply overlays in U-boot.
-1. Include and define overlays within a FIT image and have overlays
-   automatically applied.
-
-2. Manually load and apply overlays
-
-The remainder of this document will discuss using overlays via the manual
-approach. For information on using overlays as part of a FIT image please see:
-doc/uImage.FIT/overlay-fdt-boot.txt
-
-Manually Loading and Applying Overlays
---------------------------------------
-
-1. Figure out where to place both the base device tree blob and the
-overlay. Make sure you have enough space to grow the base tree without
-overlapping anything.
-
-=> setenv fdtaddr 0x87f00000
-=> setenv fdtovaddr 0x87fc0000
-
-2. Load the base blob and overlay blobs
-
-=> load ${devtype} ${bootpart} ${fdtaddr} ${bootdir}/base.dtb
-=> load ${devtype} ${bootpart} ${fdtovaddr} ${bootdir}/overlay.dtb
-
-3. Set it as the working fdt tree.
-
-=> fdtaddr $fdtaddr
-
-4. Grow it enough so it can 'fit' all the applied overlays
-
-=> fdt resize 8192
-
-5. You are now ready to apply the overlay.
-
-=> fdt apply $fdtovaddr
-
-6. Boot system like you would do with a traditional dtb.
-
-For bootm:
-
-=> bootm ${kerneladdr} - ${fdtaddr}
-
-For bootz:
-
-=> bootz ${kerneladdr} - ${fdtaddr}
-
-Please note that in case of an error, both the base and overlays are going
-to be invalidated, so keep copies to avoid reloading.
-
-Pantelis Antoniou
-pantelis.antoniou@konsulko.com
-11/7/2017
diff --git a/doc/README.gpt b/doc/README.gpt
index facd7af..ac975f6 100644
--- a/doc/README.gpt
+++ b/doc/README.gpt
@@ -251,22 +251,24 @@
 	type=0FC63DAF-8483-4772-8E79-3D69D8477DE4;"
 
 Some strings can be also used at the place of known GUID :
-	"system" = PARTITION_SYSTEM_GUID
-	           (C12A7328-F81F-11D2-BA4B-00A0C93EC93B)
-	"mbr"    = LEGACY_MBR_PARTITION_GUID
-	           (024DEE41-33E7-11D3-9D69-0008C781F39F)
-	"msft"   = PARTITION_MSFT_RESERVED_GUID
-	           (E3C9E316-0B5C-4DB8-817D-F92DF00215AE)
-	"data"   = PARTITION_BASIC_DATA_GUID
-	            (EBD0A0A2-B9E5-4433-87C0-68B6B72699C7)
-	"linux"  = PARTITION_LINUX_FILE_SYSTEM_DATA_GUID
-	           (0FC63DAF-8483-4772-8E79-3D69D8477DE4)
-	"raid"   = PARTITION_LINUX_RAID_GUID
-	           (A19D880F-05FC-4D3B-A006-743F0F84911E)
-	"swap"   = PARTITION_LINUX_SWAP_GUID
-	           (0657FD6D-A4AB-43C4-84E5-0933C84B4F4F)
-	"lvm"    = PARTITION_LINUX_LVM_GUID
-	           (E6D6D379-F507-44C2-A23C-238F2A3DF928)
+	"system"          = PARTITION_SYSTEM_GUID
+	                    (C12A7328-F81F-11D2-BA4B-00A0C93EC93B)
+	"mbr"             = LEGACY_MBR_PARTITION_GUID
+	                    (024DEE41-33E7-11D3-9D69-0008C781F39F)
+	"msft"            = PARTITION_MSFT_RESERVED_GUID
+	                    (E3C9E316-0B5C-4DB8-817D-F92DF00215AE)
+	"data"            = PARTITION_BASIC_DATA_GUID
+	                     (EBD0A0A2-B9E5-4433-87C0-68B6B72699C7)
+	"linux"           = PARTITION_LINUX_FILE_SYSTEM_DATA_GUID
+	                    (0FC63DAF-8483-4772-8E79-3D69D8477DE4)
+	"raid"            = PARTITION_LINUX_RAID_GUID
+	                    (A19D880F-05FC-4D3B-A006-743F0F84911E)
+	"swap"            = PARTITION_LINUX_SWAP_GUID
+	                    (0657FD6D-A4AB-43C4-84E5-0933C84B4F4F)
+	"lvm"             = PARTITION_LINUX_LVM_GUID
+	                    (E6D6D379-F507-44C2-A23C-238F2A3DF928)
+	"u-boot-env"      = PARTITION_U_BOOT_ENVIRONMENT
+	                    (3DE21764-95BD-54BD-A5C3-4ABE786F38A8)
 
     "uuid_disk=...;name=u-boot,size=60MiB,uuid=...;
 	name=kernel,size=60MiB,uuid=...,type=linux;"
diff --git a/doc/board/emulation/qemu-riscv.rst b/doc/board/emulation/qemu-riscv.rst
index 3acd406..4b8e104 100644
--- a/doc/board/emulation/qemu-riscv.rst
+++ b/doc/board/emulation/qemu-riscv.rst
@@ -73,7 +73,7 @@
 
     git clone https://github.com/riscv/opensbi.git
     cd opensbi
-    make PLATFORM=qemu/virt
+    make PLATFORM=generic
 
 See the OpenSBI documentation for full details:
 https://github.com/riscv/opensbi/blob/master/docs/platform/qemu_virt.md
diff --git a/doc/board/freescale/b4860qds.rst b/doc/board/freescale/b4860qds.rst
index 37d7d08..de14d85 100644
--- a/doc/board/freescale/b4860qds.rst
+++ b/doc/board/freescale/b4860qds.rst
@@ -134,7 +134,7 @@
 -------------------------
 
 Switch Settings
----------------
+^^^^^^^^^^^^^^^
 
 .. code-block:: none
 
@@ -167,7 +167,7 @@
 -------------------------
 
 Switch Settings
----------------
+^^^^^^^^^^^^^^^
 
 .. code-block:: none
 
diff --git a/doc/board/index.rst b/doc/board/index.rst
index 915f1be..08c167b 100644
--- a/doc/board/index.rst
+++ b/doc/board/index.rst
@@ -17,6 +17,7 @@
    google/index
    intel/index
    kontron/index
+   microchip/index
    renesas/index
    rockchip/index
    sifive/index
diff --git a/doc/board/microchip/index.rst b/doc/board/microchip/index.rst
new file mode 100644
index 0000000..affc5a9
--- /dev/null
+++ b/doc/board/microchip/index.rst
@@ -0,0 +1,9 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+Microchip
+=========
+
+.. toctree::
+   :maxdepth: 2
+
+   mpfs_icicle
diff --git a/doc/board/microchip/mpfs_icicle.rst b/doc/board/microchip/mpfs_icicle.rst
new file mode 100644
index 0000000..7489761
--- /dev/null
+++ b/doc/board/microchip/mpfs_icicle.rst
@@ -0,0 +1,810 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+Microchip PolarFire SoC Icicle Kit
+==================================
+
+RISC-V PolarFire SoC
+--------------------
+The PolarFire SoC is the 4+1 64-bit RISC-V SoC from Microchip.
+
+The Icicle Kit development platform is based on PolarFire SoC and capable
+of running Linux.
+
+Mainline support
+----------------
+The support for following drivers are already enabled:
+
+1. NS16550 UART Driver.
+2. Microchip Clock Driver.
+3. Cadence MACB ethernet driver for networking support.
+4. Cadence MMC Driver for eMMC/SD support.
+
+Booting from eMMC using HSS
+---------------------------
+
+Building U-Boot
+---------------
+
+1. Add the RISC-V toolchain to your PATH.
+2. Setup ARCH & cross compilation environment variable:
+
+.. code-block:: none
+
+   export CROSS_COMPILE=<riscv64 toolchain prefix>
+
+3. make microchip_mpfs_icicle_defconfig
+4. make
+
+Flashing
+--------
+
+The current U-Boot port is supported in S-mode only and loaded from DRAM.
+
+A prior stage M-mode firmware/bootloader (e.g HSS with OpenSBI) is required to
+boot the u-boot.bin in S-mode.
+
+Currently, the u-boot.bin is used as a payload of the HSS firmware (Microchip
+boot-flow) and OpenSBI generic platform fw_payload.bin (with u-boot.bin embedded)
+as HSS payload (Custom boot-flow)
+
+Microchip boot-flow
+-------------------
+HSS with OpenSBI (M-Mode) -> U-Boot (S-Mode) -> Linux (S-Mode)
+
+Build the HSS (Hart Software Services) - Microchip boot-flow
+------------------------------------------------------------
+(Note: HSS git repo is at https://github.com/polarfire-soc/hart-software-services)
+
+1. Configure
+
+.. code-block:: none
+
+   make BOARD=icicle-kit-es config
+
+Alternatively, copy the default config for Microchip boot-flow.
+
+.. code-block:: none
+
+   cp boards/icicle-kit-es/def_config .config
+
+2. make BOARD=icicle-kit-es
+3. In the Default subdirectory, the standard build will create hss.elf and
+   various binary formats (hss.hex and hss.bin).
+
+The FPGA design will use the hss.hex or hss.bin.
+
+FPGA design with HSS programming file
+-------------------------------------
+https://github.com/polarfire-soc/polarfire-soc-documentation/blob/master/boards/mpfs-icicle-kit-es/updating-icicle-kit/updating-icicle-kit-design-and-linux.md
+
+The HSS firmware runs from the PolarFire SoC eNVM on reset.
+
+Creating the HSS payload - Microchip boot-flow
+----------------------------------------------
+1. You will be creating a payload from `u-boot-dtb.bin`.
+   Copy this file to the HSS/tools/hss-payload-generator/test directory.
+2. Go to hss-payload-generator source directory.
+
+.. code-block:: none
+
+   cd hart-software-services/tools/hss-payload-generator
+
+3. Edit test/uboot.yaml file for hart entry points and correct name of the binary file.
+
+	hart-entry-points: {u54_1: '0x80200000', u54_2: '0x80200000', u54_3: '0x80200000', u54_4: '0x80200000'}
+
+	payloads:
+	test/u-boot-dtb.bin: {exec-addr: '0x80200000', owner-hart: u54_1, secondary-hart: u54_2, secondary-hart: u54_3, secondary-hart: u54_4, priv-mode: prv_s}
+
+4. Generate payload
+
+.. code-block:: none
+
+   ./hss-payload-generator -c test/uboot.yaml payload.bin
+
+Once the payload binary is generated, it should be copied to the eMMC.
+
+Please refer to HSS documenation to build the HSS firmware for payload.
+(Note: HSS git repo is at https://github.com/polarfire-soc/hart-software-services/blob/master/tools/hss-payload-generator/README.md)
+
+Custom boot-flow
+----------------
+HSS without OpenSBI (M-Mode) -> OpenSBI (M-Mode) -> U-Boot (S-Mode) -> Linux (S-Mode)
+
+Build OpenSBI
+-------------
+
+1. Get the OpenSBI source
+
+.. code-block:: none
+
+   git clone https://github.com/riscv/opensbi.git
+   cd opensbi
+
+2. Build
+
+.. code-block:: none
+
+   make PLATFORM=generic FW_PAYLOAD_PATH=<u-boot-directory>/u-boot.bin
+   FW_FDT_PATH=<u-boot-directory>/arch/riscv/dts/microchip-mpfs-icicle-kit-.dtb
+
+3. Output "fw_payload.bin" file available at
+   "<opensbi-directory>/build/platform/generic/firmware/fw_payload.bin"
+
+Build the HSS (Hart Software Services)- Custom boot-flow
+--------------------------------------------------------
+(Note: HSS git repo is at https://github.com/polarfire-soc/hart-software-services)
+
+1. Configure
+
+.. code-block:: none
+
+   make BOARD=icicle-kit-es config
+
+Alternatively, copy the default custom config for Custom boot-flow.
+
+.. code-block:: none
+
+   cp boards/icicle-kit-es/def_config_custom .config
+
+2. make BOARD=icicle-kit-es
+3. In the Default subdirectory, the standard build will create hss.elf and
+   various binary formats (hss.hex and hss.bin).
+
+The FPGA design will use the hss.hex or hss.bin.
+
+Creating the HSS payload - Custom boot-flow
+-------------------------------------------
+1. You will be creating a payload from `fw_payload.bin`.
+   Copy this file to the HSS/tools/hss-payload-generator/test directory.
+2. Go to hss-payload-generator source directory.
+
+.. code-block:: none
+
+   cd hart-software-services/tools/hss-payload-generator
+
+3. Edit test/uboot.yaml file for hart entry points and correct name of the binary file.
+
+	hart-entry-points: {u54_1: '0x80000000', u54_2: '0x80000000', u54_3: '0x80000000', u54_4: '0x80000000'}
+
+	payloads:
+	test/fw_payload.bin: {exec-addr: '0x80000000', owner-hart: u54_1, secondary-hart: u54_2, secondary-hart: u54_3, secondary-hart: u54_4, priv-mode: prv_m}
+
+4. Generate payload
+
+.. code-block:: none
+
+   ./hss-payload-generator -c test/uboot.yaml payload.bin
+
+Once the payload binary is generated, it should be copied to the eMMC.
+
+Please refer to HSS documenation to build the HSS firmware for payload.
+(Note: HSS git repo is at https://github.com/polarfire-soc/hart-software-services/blob/master/tools/hss-payload-generator/README.md
+and also refer the HSS payload generator at https://github.com/polarfire-soc/polarfire-soc-documentation/blob/master/software-development/hss-payloads.md)
+
+eMMC
+----
+Program eMMC with payload binary is explained in the PolarFire SoC documentation.
+(Note: PolarFire SoC Documentation git repo is at https://github.com/polarfire-soc/polarfire-soc-documentation/blob/master/boards/mpfs-icicle-kit-es/updating-icicle-kit/updating-icicle-kit-design-and-linux.md#eMMC)
+
+Once the payload image is copied to the eMMC, press CTRL+C in the HSS command
+line interface, then type 'boot' and enter to boot the newly copied image.
+
+.. code-block:: none
+
+    sudo dd if=<payload_binary> of=/dev/sdX bs=512
+
+GUID type
+---------
+The HSS always picks up HSS payload from a GPT partition with
+GIUD type "21686148-6449-6E6F-744E-656564454649" or sector '0' of the eMMC if no
+GPT partition.
+
+Booting
+-------
+You should see the U-Boot prompt on UART0.
+
+Sample boot log from MPFS Icicle Kit
+------------------------------------
+
+.. code-block:: none
+
+   U-Boot 2021.01-00314-g7303332537-dirty (Jan 14 2021 - 10:09:43 +0530)
+
+   CPU:   rv64imafdc
+   Model: Microchip MPFS Icicle Kit
+   DRAM:  1 GiB
+   MMC:   sdhc@20008000: 0
+   In:    serial@20100000
+   Out:   serial@20100000
+   Err:   serial@20100000
+   Net:   eth0: ethernet@20112000
+   Hit any key to stop autoboot:  0
+
+Now you can configure your networking, tftp server and use tftp boot method to
+load uImage (with initramfs).
+
+.. code-block:: none
+
+   RISC-V # setenv kernel_addr_r 0x80200000
+   RISC-V # setenv fdt_addr_r 0x82200000
+
+   RISC-V # setenv ipaddr 192.168.1.5
+   RISC-V # setenv netmask 255.255.255.0
+   RISC-V # setenv serverip 192.168.1.3
+   RISC-V # setenv gateway 192.168.1.1
+
+   RISC-V # tftpboot ${kernel_addr_r} uImage
+   ethernet@20112000: PHY present at 9
+   ethernet@20112000: Starting autonegotiation...
+   ethernet@20112000: Autonegotiation complete
+   ethernet@20112000: link up, 1000Mbps full-duplex (lpa: 0x7800)
+   Using ethernet@20112000 device
+   TFTP from server 192.168.1.3; our IP address is 192.168.1.5
+   Filename 'uImage'.
+   Load address: 0x80200000
+   Loading: #################################################################
+	    #################################################################
+	    #################################################################
+	    #################################################################
+	    #################################################################
+	    #################################################################
+	    #################################################################
+	    #################################################################
+	    #################################################################
+	    #################################################################
+	    #################################################################
+	    #################################################################
+	    #################################################################
+	    #################################################################
+	    #################################################################
+	    ############
+	    6.4 MiB/s
+   done
+   Bytes transferred = 14482480 (dcfc30 hex)
+
+   RISC-V # tftpboot ${fdt_addr_r} microchip-mpfs-icicle-kit.dtb
+   ethernet@20112000: PHY present at 9
+   ethernet@20112000: Starting autonegotiation...
+   ethernet@20112000: Autonegotiation complete
+   ethernet@20112000: link up, 1000Mbps full-duplex (lpa: 0x7800)
+   Using ethernet@20112000 device
+   TFTP from server 192.168.1.3; our IP address is 192.168.1.5
+   Filename 'microchip-mpfs-icicle-kit.dtb'.
+   Load address: 0x82200000
+   Loading: #
+			2.5 MiB/s
+   done
+   Bytes transferred = 10282 (282a hex)
+
+   RISC-V # bootm ${kernel_addr_r} - ${fdt_addr_r}
+   ## Booting kernel from Legacy Image at 80200000 ...
+		Image Name:   Linux
+		Image Type:   RISC-V Linux Kernel Image (uncompressed)
+		Data Size:    14482416 Bytes = 13.8 MiB
+		Load Address: 80200000
+		Entry Point:  80200000
+		Verifying Checksum ... OK
+   ## Flattened Device Tree blob at 82200000
+		Booting using the fdt blob at 0x82200000
+		Loading Kernel Image
+		Using Device Tree in place at 000000008fffa000, end 000000008ffff829 ... OK
+
+   Starting kernel ...
+
+   [    0.000000] OF: fdt: Ignoring memory range 0x80000000 - 0x80200000
+   [    0.000000] Linux version 5.6.17 (padmarao@padmarao-VirtualBox) (gcc version 7.2.0 (GCC)) #2 SMP Tue Jun 16 21:27:50 IST 2020
+   [    0.000000] initrd not found or empty - disabling initrd
+   [    0.000000] Zone ranges:
+   [    0.000000]   DMA32    [mem 0x0000000080200000-0x00000000bfffffff]
+   [    0.000000]   Normal   empty
+   [    0.000000] Movable zone start for each node
+   [    0.000000] Early memory node ranges
+   [    0.000000]   node   0: [mem 0x0000000080200000-0x00000000bfffffff]
+   [    0.000000] Initmem setup node 0 [mem 0x0000000080200000-0x00000000bfffffff]
+   [    0.000000] software IO TLB: mapped [mem 0xbb1f5000-0xbf1f5000] (64MB)
+   [    0.000000] elf_hwcap is 0x112d
+   [    0.000000] percpu: Embedded 14 pages/cpu s24856 r0 d32488 u57344
+   [    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 258055
+   [    0.000000] Kernel command line: console=ttyS0,115200n8
+   [    0.000000] Dentry cache hash table entries: 131072 (order: 8, 1048576 bytes, linear)
+   [    0.000000] Inode-cache hash table entries: 65536 (order: 7, 524288 bytes, linear)
+   [    0.000000] Sorting __ex_table...
+   [    0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
+   [    0.000000] Memory: 950308K/1046528K available (3289K kernel code, 212K rwdata, 900K rodata, 9476K init, 250K bss, 96220K reserved, 0K cma-reserved)
+   [    0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1
+   [    0.000000] rcu: Hierarchical RCU implementation.
+   [    0.000000] rcu: 	RCU event tracing is enabled.
+   [    0.000000] rcu: 	RCU restricting CPUs from NR_CPUS=8 to nr_cpu_ids=4.
+   [    0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 10 jiffies.
+   [    0.000000] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=4
+   [    0.000000] NR_IRQS: 0, nr_irqs: 0, preallocated irqs: 0
+   [    0.000000] plic: mapped 186 interrupts with 4 handlers for 9 contexts.
+   [    0.000000] riscv_timer_init_dt: Registering clocksource cpuid [0] hartid [1]
+   [    0.000000] clocksource: riscv_clocksource: mask: 0xffffffffffffffff max_cycles: 0x1d854df40, max_idle_ns: 3526361616960 ns
+   [    0.000015] sched_clock: 64 bits at 1000kHz, resolution 1000ns, wraps every 2199023255500ns
+   [    0.000311] Calibrating delay loop (skipped), value calculated using timer frequency.. 2.00 BogoMIPS (lpj=10000)
+   [    0.000349] pid_max: default: 32768 minimum: 301
+   [    0.000846] Mount-cache hash table entries: 2048 (order: 2, 16384 bytes, linear)
+   [    0.000964] Mountpoint-cache hash table entries: 2048 (order: 2, 16384 bytes, linear)
+   [    0.005630] rcu: Hierarchical SRCU implementation.
+   [    0.006901] smp: Bringing up secondary CPUs ...
+   [    0.012545] smp: Brought up 1 node, 4 CPUs
+   [    0.014431] devtmpfs: initialized
+   [    0.020526] random: get_random_bytes called from setup_net+0x36/0x192 with crng_init=0
+   [    0.020928] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
+   [    0.020999] futex hash table entries: 1024 (order: 4, 65536 bytes, linear)
+   [    0.022768] NET: Registered protocol family 16
+   [    0.035478] microchip-pfsoc-clkcfg 20002000.clkcfg: Registered PFSOC core clocks
+   [    0.048429] SCSI subsystem initialized
+   [    0.049694] pps_core: LinuxPPS API ver. 1 registered
+   [    0.049719] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
+   [    0.049780] PTP clock support registered
+   [    0.051781] clocksource: Switched to clocksource riscv_clocksource
+   [    0.055326] NET: Registered protocol family 2
+   [    0.056922] tcp_listen_portaddr_hash hash table entries: 512 (order: 1, 8192 bytes, linear)
+   [    0.057053] TCP established hash table entries: 8192 (order: 4, 65536 bytes, linear)
+   [    0.057648] TCP bind hash table entries: 8192 (order: 5, 131072 bytes, linear)
+   [    0.058579] TCP: Hash tables configured (established 8192 bind 8192)
+   [    0.059648] UDP hash table entries: 512 (order: 2, 16384 bytes, linear)
+   [    0.059837] UDP-Lite hash table entries: 512 (order: 2, 16384 bytes, linear)
+   [    0.060707] NET: Registered protocol family 1
+   [    0.266229] workingset: timestamp_bits=62 max_order=18 bucket_order=0
+   [    0.287107] io scheduler mq-deadline registered
+   [    0.287140] io scheduler kyber registered
+   [    0.429601] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
+   [    0.433979] printk: console [ttyS0] disabled
+   [    0.434154] 20000000.serial: ttyS0 at MMIO 0x20000000 (irq = 18, base_baud = 9375000) is a 16550A
+   [    0.928039] printk: console [ttyS0] enabled
+   [    0.939804] libphy: Fixed MDIO Bus: probed
+   [    0.948702] libphy: MACB_mii_bus: probed
+   [    0.993698] macb 20112000.ethernet eth0: Cadence GEM rev 0x0107010c at 0x20112000 irq 21 (56:34:12:00:fc:00)
+   [    1.006751] mousedev: PS/2 mouse device common for all mice
+   [    1.013803] i2c /dev entries driver
+   [    1.019451] sdhci: Secure Digital Host Controller Interface driver
+   [    1.027242] sdhci: Copyright(c) Pierre Ossman
+   [    1.032731] sdhci-pltfm: SDHCI platform and OF driver helper
+   [    1.091826] mmc0: SDHCI controller on 20008000.sdhc [20008000.sdhc] using ADMA 64-bit
+   [    1.102738] NET: Registered protocol family 17
+   [    1.170326] Freeing unused kernel memory: 9476K
+   [    1.176067] This architecture does not have kernel memory protection.
+   [    1.184157] Run /init as init process
+   Starting logging: OK
+   Starting mdev...
+   /etc/init.d/S10mdev: line 21: can't create /proc/sys/kernel/hotplug: nonexiste[    1.331981] mmc0: mmc_select_hs200 failed, error -74
+   nt directory
+   [    1.355011] mmc0: new MMC card at address 0001
+   [    1.363981] mmcblk0: mmc0:0001 DG4008 7.28 GiB
+   [    1.372248] mmcblk0boot0: mmc0:0001 DG4008 partition 1 4.00 MiB
+   [    1.382292] mmcblk0boot1: mmc0:0001 DG4008 partition 2 4.00 MiB
+   [    1.390265] mmcblk0rpmb: mmc0:0001 DG4008 partition 3 4.00 MiB, chardev (251:0)
+   [    1.425234] GPT:Primary header thinks Alt. header is not at the end of the disk.
+   [    1.434656] GPT:2255809 != 15273599
+   [    1.439038] GPT:Alternate GPT header not at the end of the disk.
+   [    1.446671] GPT:2255809 != 15273599
+   [    1.451048] GPT: Use GNU Parted to correct GPT errors.
+   [    1.457755]  mmcblk0: p1 p2 p3
+   sort: /sys/devices/platform/Fixed: No such file or directory
+   modprobe: can't change directory to '/lib/modules': No such file or directory
+   Initializing random number generator... [    2.830198] random: dd: uninitialized urandom read (512 bytes read)
+   done.
+   Starting network...
+   [    3.061867] macb 20112000.ethernet eth0: PHY [20112000.ethernet-ffffffff:09] driver [Vitesse VSC8662] (irq=POLL)
+   [    3.074674] macb 20112000.ethernet eth0: configuring for phy/sgmii link mode
+   [    3.084263] pps pps0: new PPS source ptp0
+   [    3.089710] macb 20112000.ethernet: gem-ptp-timer ptp clock registered.
+   udhcpc (v1.24.2) started
+   Sending discover...
+   Sending discover...
+   [    6.380169] macb 20112000.ethernet eth0: Link is Up - 1Gbps/Full - flow control tx
+   Sending discover...
+   Sending select for 192.168.1.2...
+   Lease of 192.168.1.2 obtained, lease time 86400
+   deleting routers
+   adding dns 192.168.1.1
+   Starting dropbear sshd: [   11.385619] random: dropbear: uninitialized urandom read (32 bytes read)
+   OK
+
+   Welcome to Buildroot
+   buildroot login: root
+   Password:
+   #
+
+Booting U-Boot and Linux from eMMC
+----------------------------------
+
+FPGA design with HSS programming file and Linux Image
+-----------------------------------------------------
+https://github.com/polarfire-soc/polarfire-soc-documentation/blob/master/boards/mpfs-icicle-kit-es/updating-icicle-kit/updating-icicle-kit-design-and-linux.md
+
+The HSS firmware runs from the PolarFire SoC eNVM on reset.
+
+eMMC
+----
+Program eMMC with payload binary and Linux image is explained in the
+PolarFire SoC documentation.
+The payload binary should be copied to partition 2 of the eMMC.
+
+(Note: PolarFire SoC Documentation git repo is at https://github.com/polarfire-soc/polarfire-soc-documentation/blob/master/boards/mpfs-icicle-kit-es/updating-icicle-kit/updating-icicle-kit-design-and-linux.md#eMMC)
+
+Once the Linux image and payload binary is copied to the eMMC, press CTRL+C
+in the HSS command line interface, then type 'boot' and enter to boot the newly
+copied payload and Linux image.
+
+.. code-block:: none
+
+    zcat <linux-image>.wic.gz | sudo dd of=/dev/sdX bs=4096 iflag=fullblock oflag=direct conv=fsync status=progress
+
+    sudo dd if=<payload_binary> of=/dev/sdX2 bs=512
+
+You should see the U-Boot prompt on UART0.
+
+GUID type
+---------
+The HSS always picks up the HSS payload from a GPT partition with
+GIUD type "21686148-6449-6E6F-744E-656564454649" or sector '0' of the eMMC if no
+GPT partition.
+
+Sample boot log from MPFS Icicle Kit
+------------------------------------
+
+.. code-block:: none
+
+   U-Boot 2021.01-00314-g7303332537-dirty (Jan 14 2021 - 10:09:43 +0530)
+
+   CPU:   rv64imafdc
+   Model: Microchip MPFS Icicle Kit
+   DRAM:  1 GiB
+   MMC:   sdhc@20008000: 0
+   In:    serial@20100000
+   Out:   serial@20100000
+   Err:   serial@20100000
+   Net:   eth0: ethernet@20112000
+   Hit any key to stop autoboot:  0
+
+   RISC-V # mmc info
+   Device: sdhc@20008000
+   Manufacturer ID: 45
+   OEM: 100
+   Name: DG400
+   Bus Speed: 52000000
+   Mode: MMC High Speed (52MHz)
+   Rd Block Len: 512
+   MMC version 5.1
+   High Capacity: Yes
+   Capacity: 7.3 GiB
+   Bus Width: 4-bit
+   Erase Group Size: 512 KiB
+   HC WP Group Size: 8 MiB
+   User Capacity: 7.3 GiB WRREL
+   Boot Capacity: 4 MiB ENH
+   RPMB Capacity: 4 MiB ENH
+
+   RISC-V # mmc part
+   Partition Map for MMC device 0  --   Partition Type: EFI
+
+   Part	Start LBA	End LBA		Name
+		Attributes
+		Type GUID
+		Partition GUID
+	1	0x00002000	0x0000b031	"boot"
+		attrs:	0x0000000000000004
+		type:	ebd0a0a2-b9e5-4433-87c0-68b6b72699c7
+		guid:	99ff6a94-f2e7-44dd-a7df-f3a2da106ef9
+	2	0x0000b032	0x0000f031	"primary"
+		attrs:	0x0000000000000000
+		type:	21686148-6449-6e6f-744e-656564454649
+		guid:	12006052-e64b-4423-beb0-b956ea00f1ba
+	3	0x00010000	0x00226b9f	"root"
+		attrs:	0x0000000000000000
+		type:	0fc63daf-8483-4772-8e79-3d69d8477de4
+		guid:	dd2c5619-2272-4c3c-8dc2-e21942e17ce6
+
+   RISC-V # load mmc 0 ${ramdisk_addr_r} fitimage
+   RISC-V # bootm ${ramdisk_addr_r}
+   ## Loading kernel from FIT Image at 88300000 ...
+   Using 'conf@microchip_icicle-kit-es-a000-microchip.dtb' configuration
+   Trying 'kernel@1' kernel subimage
+     Description:  Linux kernel
+     Type:         Kernel Image
+     Compression:  gzip compressed
+     Data Start:   0x883000fc
+     Data Size:    3574555 Bytes = 3.4 MiB
+     Architecture: RISC-V
+     OS:           Linux
+     Load Address: 0x80200000
+     Entry Point:  0x80200000
+     Hash algo:    sha256
+     Hash value:   21f18d72cf2f0a7192220abb577ad25c77c26960052d779aa02bf55dbf0a6403
+   Verifying Hash Integrity ... sha256+ OK
+   ## Loading fdt from FIT Image at 88300000 ...
+   Using 'conf@microchip_icicle-kit-es-a000-microchip.dtb' configuration
+   Trying 'fdt@microchip_icicle-kit-es-a000-microchip.dtb' fdt subimage
+     Description:  Flattened Device Tree blob
+     Type:         Flat Device Tree
+     Compression:  uncompressed
+     Data Start:   0x88668d44
+     Data Size:    9760 Bytes = 9.5 KiB
+     Architecture: RISC-V
+     Load Address: 0x82200000
+     Hash algo:    sha256
+     Hash value:   5c3a9f30d41b6b8e53b47916e1f339b3a4d454006554d1f7e1f552ed62409f4b
+   Verifying Hash Integrity ... sha256+ OK
+   Loading fdt from 0x88668d48 to 0x82200000
+   Booting using the fdt blob at 0x82200000
+   Uncompressing Kernel Image
+   Loading Device Tree to 000000008fffa000, end 000000008ffff61f ... OK
+
+   Starting kernel ...
+
+   [    0.000000] OF: fdt: Ignoring memory range 0x80000000 - 0x80200000
+   [    0.000000] Linux version 5.6.16 (oe-user@oe-host) (gcc version 9.3.0 (GCC)) #1 SMP Fri Oct 9 11:49:47 UTC 2020
+   [    0.000000] earlycon: sbi0 at I/O port 0x0 (options '')
+   [    0.000000] printk: bootconsole [sbi0] enabled
+   [    0.000000] Zone ranges:
+   [    0.000000]   DMA32    [mem 0x0000000080200000-0x00000000bfffffff]
+   [    0.000000]   Normal   empty
+   [    0.000000] Movable zone start for each node
+   [    0.000000] Early memory node ranges
+   [    0.000000]   node   0: [mem 0x0000000080200000-0x00000000bfffffff]
+   [    0.000000] Zeroed struct page in unavailable ranges: 512 pages
+   [    0.000000] Initmem setup node 0 [mem 0x0000000080200000-0x00000000bfffffff]
+   [    0.000000] software IO TLB: mapped [mem 0xb9e00000-0xbde00000] (64MB)
+   [    0.000000] CPU with hartid=0 is not available
+   [    0.000000] CPU with hartid=0 is not available
+   [    0.000000] elf_hwcap is 0x112d
+   [    0.000000] percpu: Embedded 17 pages/cpu s29784 r8192 d31656 u69632
+   [    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 258055
+   [    0.000000] Kernel command line: earlycon=sbi root=/dev/mmcblk0p3 rootwait console=ttyS0,115200n8 uio_pdrv_genirq.of_id=generic-uio
+   [    0.000000] Dentry cache hash table entries: 131072 (order: 8, 1048576 bytes, linear)
+   [    0.000000] Inode-cache hash table entries: 65536 (order: 7, 524288 bytes, linear)
+   [    0.000000] Sorting __ex_table...
+   [    0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
+   [    0.000000] Memory: 941440K/1046528K available (4118K kernel code, 280K rwdata, 1687K rodata, 169K init, 273K bss, 105088K reserved, 0K cma-reserved)
+   [    0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1
+   [    0.000000] rcu: Hierarchical RCU implementation.
+   [    0.000000] rcu: 	RCU event tracing is enabled.
+   [    0.000000] rcu: 	RCU restricting CPUs from NR_CPUS=5 to nr_cpu_ids=4.
+   [    0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 10 jiffies.
+   [    0.000000] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=4
+   [    0.000000] NR_IRQS: 0, nr_irqs: 0, preallocated irqs: 0
+   [    0.000000] plic: mapped 53 interrupts with 4 handlers for 9 contexts.
+   [    0.000000] riscv_timer_init_dt: Registering clocksource cpuid [0] hartid [1]
+   [    0.000000] clocksource: riscv_clocksource: mask: 0xffffffffffffffff max_cycles: 0x1d854df40, max_idle_ns: 3526361616960 ns
+   [    0.000015] sched_clock: 64 bits at 1000kHz, resolution 1000ns, wraps every 2199023255500ns
+   [    0.008679] Console: colour dummy device 80x25
+   [    0.013112] Calibrating delay loop (skipped), value calculated using timer frequency.. 2.00 BogoMIPS (lpj=10000)
+   [    0.023368] pid_max: default: 32768 minimum: 301
+   [    0.028314] Mount-cache hash table entries: 2048 (order: 2, 16384 bytes, linear)
+   [    0.035766] Mountpoint-cache hash table entries: 2048 (order: 2, 16384 bytes, linear)
+   [    0.047099] rcu: Hierarchical SRCU implementation.
+   [    0.052813] smp: Bringing up secondary CPUs ...
+   [    0.061581] smp: Brought up 1 node, 4 CPUs
+   [    0.067069] devtmpfs: initialized
+   [    0.073621] random: get_random_u32 called from bucket_table_alloc.isra.0+0x4e/0x150 with crng_init=0
+   [    0.074409] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
+   [    0.093399] futex hash table entries: 1024 (order: 4, 65536 bytes, linear)
+   [    0.101879] NET: Registered protocol family 16
+   [    0.110336] microchip-pfsoc-clkcfg 20002000.clkcfg: Registered PFSOC core clocks
+   [    0.132717] usbcore: registered new interface driver usbfs
+   [    0.138225] usbcore: registered new interface driver hub
+   [    0.143813] usbcore: registered new device driver usb
+   [    0.148939] pps_core: LinuxPPS API ver. 1 registered
+   [    0.153929] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
+   [    0.163071] PTP clock support registered
+   [    0.168521] clocksource: Switched to clocksource riscv_clocksource
+   [    0.174927] VFS: Disk quotas dquot_6.6.0
+   [    0.179016] VFS: Dquot-cache hash table entries: 512 (order 0, 4096 bytes)
+   [    0.205536] NET: Registered protocol family 2
+   [    0.210944] tcp_listen_portaddr_hash hash table entries: 512 (order: 1, 8192 bytes, linear)
+   [    0.219393] TCP established hash table entries: 8192 (order: 4, 65536 bytes, linear)
+   [    0.227497] TCP bind hash table entries: 8192 (order: 5, 131072 bytes, linear)
+   [    0.235440] TCP: Hash tables configured (established 8192 bind 8192)
+   [    0.242537] UDP hash table entries: 512 (order: 2, 16384 bytes, linear)
+   [    0.249285] UDP-Lite hash table entries: 512 (order: 2, 16384 bytes, linear)
+   [    0.256690] NET: Registered protocol family 1
+   [    0.262585] workingset: timestamp_bits=62 max_order=18 bucket_order=0
+   [    0.281036] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 249)
+   [    0.288481] io scheduler mq-deadline registered
+   [    0.292983] io scheduler kyber registered
+   [    0.298895] microsemi,mss-gpio 20122000.gpio: Microsemi MSS GPIO registered 32 GPIOs
+   [    0.453723] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
+   [    0.462911] printk: console [ttyS0] disabled
+   [    0.467216] 20100000.serial: ttyS0 at MMIO 0x20100000 (irq = 12, base_baud = 9375000) is a 16550A
+   [    0.476201] printk: console [ttyS0] enabled
+   [    0.476201] printk: console [ttyS0] enabled
+   [    0.484576] printk: bootconsole [sbi0] disabled
+   [    0.484576] printk: bootconsole [sbi0] disabled
+   [    0.494920] 20102000.serial: ttyS1 at MMIO 0x20102000 (irq = 13, base_baud = 9375000) is a 16550A
+   [    0.505068] 20104000.serial: ttyS2 at MMIO 0x20104000 (irq = 14, base_baud = 9375000) is a 16550A
+   [    0.533336] loop: module loaded
+   [    0.572284] Rounding down aligned max_sectors from 4294967295 to 4294967288
+   [    0.580000] db_root: cannot open: /etc/target
+   [    0.585413] libphy: Fixed MDIO Bus: probed
+   [    0.591526] libphy: MACB_mii_bus: probed
+   [    0.598060] macb 20112000.ethernet eth0: Cadence GEM rev 0x0107010c at 0x20112000 irq 17 (56:34:12:00:fc:00)
+   [    0.608352] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
+   [    0.615001] ehci-platform: EHCI generic platform driver
+   [    0.620446] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
+   [    0.626632] ohci-platform: OHCI generic platform driver
+   [    0.632326] usbcore: registered new interface driver cdc_acm
+   [    0.637996] cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters
+   [    0.646459] i2c /dev entries driver
+   [    0.650852] microsemi-mss-i2c 2010b000.i2c: Microsemi I2C Probe Complete
+   [    0.658010] sdhci: Secure Digital Host Controller Interface driver
+   [    0.664326] sdhci: Copyright(c) Pierre Ossman
+   [    0.668754] sdhci-pltfm: SDHCI platform and OF driver helper
+   [    0.706845] mmc0: SDHCI controller on 20008000.sdhc [20008000.sdhc] using ADMA 64-bit
+   [    0.715052] usbcore: registered new interface driver usbhid
+   [    0.720722] usbhid: USB HID core driver
+   [    0.725174] pac193x 0-0010: Chip revision: 0x03
+   [    0.733339] pac193x 0-0010: :pac193x_prep_iio_channels: Channel 0 active
+   [    0.740127] pac193x 0-0010: :pac193x_prep_iio_channels: Channel 1 active
+   [    0.746881] pac193x 0-0010: :pac193x_prep_iio_channels: Channel 2 active
+   [    0.753686] pac193x 0-0010: :pac193x_prep_iio_channels: Channel 3 active
+   [    0.760495] pac193x 0-0010: :pac193x_prep_iio_channels: Active chip channels: 25
+   [    0.778006] NET: Registered protocol family 10
+   [    0.784929] Segment Routing with IPv6
+   [    0.788875] sit: IPv6, IPv4 and MPLS over IPv4 tunneling driver
+   [    0.795743] NET: Registered protocol family 17
+   [    0.801191] hctosys: unable to open rtc device (rtc0)
+   [    0.807774] Waiting for root device /dev/mmcblk0p3...
+   [    0.858506] mmc0: mmc_select_hs200 failed, error -74
+   [    0.865764] mmc0: new MMC card at address 0001
+   [    0.872564] mmcblk0: mmc0:0001 DG4008 7.28 GiB
+   [    0.878777] mmcblk0boot0: mmc0:0001 DG4008 partition 1 4.00 MiB
+   [    0.886182] mmcblk0boot1: mmc0:0001 DG4008 partition 2 4.00 MiB
+   [    0.892633] mmcblk0rpmb: mmc0:0001 DG4008 partition 3 4.00 MiB, chardev (247:0)
+   [    0.919029] GPT:Primary header thinks Alt. header is not at the end of the disk.
+   [    0.926448] GPT:2255841 != 15273599
+   [    0.930019] GPT:Alternate GPT header not at the end of the disk.
+   [    0.936029] GPT:2255841 != 15273599
+   [    0.939583] GPT: Use GNU Parted to correct GPT errors.
+   [    0.944800]  mmcblk0: p1 p2 p3
+   [    0.966696] EXT4-fs (mmcblk0p3): INFO: recovery required on readonly filesystem
+   [    0.974105] EXT4-fs (mmcblk0p3): write access will be enabled during recovery
+   [    1.052362] random: fast init done
+   [    1.057961] EXT4-fs (mmcblk0p3): recovery complete
+   [    1.065734] EXT4-fs (mmcblk0p3): mounted filesystem with ordered data mode. Opts: (null)
+   [    1.074002] VFS: Mounted root (ext4 filesystem) readonly on device 179:3.
+   [    1.081654] Freeing unused kernel memory: 168K
+   [    1.086108] This architecture does not have kernel memory protection.
+   [    1.092629] Run /sbin/init as init process
+   [    1.702217] systemd[1]: System time before build time, advancing clock.
+   [    1.754192] systemd[1]: systemd 244.3+ running in system mode. (+PAM -AUDIT -SELINUX +IMA -APPARMOR -SMACK +SYSVINIT +UTMP -LIBCRYPTSETUP -GCRYPT -GNUTLS +ACL +XZ -LZ4 -SECCOMP +BLKID -ELFUTILS +KMOD -IDN2 -IDN -PCRE2 default-hierarchy=hybrid)
+   [    1.776361] systemd[1]: Detected architecture riscv64.
+
+   Welcome to OpenEmbedded nodistro.0!
+
+   [    1.829651] systemd[1]: Set hostname to <icicle-kit-es>.
+   [    2.648597] random: systemd: uninitialized urandom read (16 bytes read)
+   [    2.657485] systemd[1]: Created slice system-getty.slice.
+   [  OK  ] Created slice system-getty.slice.
+   [    2.698779] random: systemd: uninitialized urandom read (16 bytes read)
+   [    2.706317] systemd[1]: Created slice system-serial\x2dgetty.slice.
+   [  OK  ] Created slice system-serial\x2dgetty.slice.
+   [    2.748716] random: systemd: uninitialized urandom read (16 bytes read)
+   [    2.756098] systemd[1]: Created slice User and Session Slice.
+   [  OK  ] Created slice User and Session Slice.
+   [    2.789065] systemd[1]: Started Dispatch Password Requests to Console Directory Watch.
+   [  OK  ] Started Dispatch Password …ts to Console Directory Watch.
+   [    2.828974] systemd[1]: Started Forward Password Requests to Wall Directory Watch.
+   [  OK  ] Started Forward Password R…uests to Wall Directory Watch.
+   [    2.869009] systemd[1]: Reached target Paths.
+   [  OK  ] Reached target Paths.
+   [    2.898808] systemd[1]: Reached target Remote File Systems.
+   [  OK  ] Reached target Remote File Systems.
+   [    2.938771] systemd[1]: Reached target Slices.
+   [  OK  ] Reached target Slices.
+   [    2.968754] systemd[1]: Reached target Swap.
+   [  OK  ] Reached target Swap.
+   [    2.999283] systemd[1]: Listening on initctl Compatibility Named Pipe.
+   [  OK  ] Listening on initctl Compatibility Named Pipe.
+   [    3.060458] systemd[1]: Condition check resulted in Journal Audit Socket being skipped.
+   [    3.069826] systemd[1]: Listening on Journal Socket (/dev/log).
+   [  OK  ] Listening on Journal Socket (/dev/log).
+   [    3.109601] systemd[1]: Listening on Journal Socket.
+   [  OK  ] Listening on Journal Socket.
+   [    3.149868] systemd[1]: Listening on Network Service Netlink Socket.
+   [  OK  ] Listening on Network Service Netlink Socket.
+   [    3.189419] systemd[1]: Listening on udev Control Socket.
+   [  OK  ] Listening on udev Control Socket.
+   [    3.229179] systemd[1]: Listening on udev Kernel Socket.
+   [  OK  ] Listening on udev Kernel Socket.
+   [    3.269520] systemd[1]: Condition check resulted in Huge Pages File System being skipped.
+   [    3.278477] systemd[1]: Condition check resulted in POSIX Message Queue File System being skipped.
+   [    3.288200] systemd[1]: Condition check resulted in Kernel Debug File System being skipped.
+   [    3.302570] systemd[1]: Mounting Temporary Directory (/tmp)...
+            Mounting Temporary Directory (/tmp)...
+   [    3.339226] systemd[1]: Condition check resulted in Create list of static device nodes for the current kernel being skipped.
+   [    3.355883] systemd[1]: Starting File System Check on Root Device...
+            Starting File System Check on Root Device...
+   [    3.407220] systemd[1]: Starting Journal Service...
+            Starting Journal Service...
+   [    3.422441] systemd[1]: Condition check resulted in Load Kernel Modules being skipped.
+   [    3.431770] systemd[1]: Condition check resulted in FUSE Control File System being skipped.
+   [    3.446415] systemd[1]: Mounting Kernel Configuration File System...
+            Mounting Kernel Configuration File System...
+   [    3.458983] systemd[1]: Starting Apply Kernel Variables...
+            Starting Apply Kernel Variables...
+   [    3.471368] systemd[1]: Starting udev Coldplug all Devices...
+            Starting udev Coldplug all Devices...
+   [    3.491071] systemd[1]: Mounted Temporary Directory (/tmp).
+   [  OK      3.498114] systemd[1]: Mounted Kernel Configuration File System.
+   0m] Mounted Temporary Directory (/tmp).
+   [  OK  ] Mounted Kernel Configuration File System.
+   [    3.550853] systemd[1]: Started Apply Kernel Variables.
+   [  OK      3.557535] systemd[1]: Started Journal Service.
+   0m] Started Apply Kernel Variables.
+   [  OK  ] Started Journal Service.
+   [  OK  ] Started udev Coldplug all Devices.
+   [  OK  ] Started File System Check on Root Device.
+            Starting Remount Root and Kernel File Systems...
+   [    8.133469] EXT4-fs (mmcblk0p3): re-mounted. Opts: (null)
+   [  OK  ] Started Remount Root and Kernel File Systems.
+            Starting Flush Journal to Persistent Storage...
+   [    8.215327] systemd-journald[77]: Received client request to flush runtime journal.
+            Starting Create Static Device Nodes in /dev...
+   [  OK  ] Started Flush Journal to Persistent Storage.
+   [  OK  ] Started Create Static Device Nodes in /dev.
+   [  OK  ] Reached target Local File Systems (Pre).
+            Mounting /var/volatile...
+            Starting udev Kernel Device Manager...
+   [  OK  ] Mounted /var/volatile.
+            Starting Load/Save Random Seed...
+   [  OK  ] Reached target Local File Systems.
+            Starting Create Volatile Files and Directories...
+   [  OK  ] Started udev Kernel Device Manager.
+   [  OK  ] Started Create Volatile Files and Directories.
+            Starting Network Time Synchronization...
+            Starting Update UTMP about System Boot/Shutdown...
+   [  OK  ] Started Update UTMP about System Boot/Shutdown.
+   [  OK  ] Started Network Time Synchronization.
+   [   11.618575] random: crng init done
+   [   11.622007] random: 7 urandom warning(s) missed due to ratelimiting
+   [  OK  ] Started Load/Save Random Seed.
+   [  OK  ] Reached target System Initialization.
+   [  OK  ] Started Daily Cleanup of Temporary Directories.
+   [  OK  ] Reached target System Time Set.
+   [  OK  ] Reached target System Time Synchronized.
+   [  OK  ] Reached target Timers.
+   [  OK  ] Listening on D-Bus System Message Bus Socket.
+   [  OK  ] Listening on dropbear.socket.
+   [  OK  ] Reached target Sockets.
+   [  OK  ] Reached target Basic System.
+   [  OK  ] Started D-Bus System Message Bus.
+            Starting IPv6 Packet Filtering Framework...
+            Starting IPv4 Packet Filtering Framework...
+            Starting Login Service...
+   [  OK  ] Started IPv6 Packet Filtering Framework.
+   [  OK  ] Started IPv4 Packet Filtering Framework.
+   [  OK  ] Reached target Network (Pre).
+            Starting Network Service...
+   [  OK  ] Started Login Service.
+   [   12.602455] macb 20112000.ethernet eth0: PHY [20112000.ethernet-ffffffff:09] driver [Vitesse VSC8662] (irq=POLL)
+   [   12.612795] macb 20112000.ethernet eth0: configuring for phy/sgmii link mode
+   [   12.622153] pps pps0: new PPS source ptp0
+   [  OK     12.626725] macb 20112000.ethernet: gem-ptp-timer ptp clock registered.
+   0m] Started Network Service.
+            Starting Network Name Resolution...
+   [  OK  ] Started Network Name Resolution.
+   [  OK  ] Reached target Network.
+   [  OK  ] Reached target Host and Network Name Lookups.
+   [  OK  ] Started Collectd.
+   [  OK  ] Started Collectd.
+            Starting Permit User Sessions...
+   [  OK  ] Started Permit User Sessions.
+   [  OK  ] Started Getty on tty1.
+   [  OK  ] Started Serial Getty on ttyS0.
+   [  OK  ] Reached target Login Prompts.
+   [  OK  ] Reached target Multi-User System.
+            Starting Update UTMP about System Runlevel Changes...
+   [  OK  ] Started Update UTMP about System Runlevel Changes.
+
+   OpenEmbedded nodistro.0 icicle-kit-es ttyS0
+
+   icicle-kit-es login: [   15.795564] macb 20112000.ethernet eth0: Link is Up - 1Gbps/Full - flow control tx
+   [   15.803306] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
+
+   icicle-kit-es login: root
+   root@icicle-kit-es:~#
diff --git a/doc/board/sifive/fu540.rst b/doc/board/sifive/fu540.rst
index 1ce9ab1..4e4c852 100644
--- a/doc/board/sifive/fu540.rst
+++ b/doc/board/sifive/fu540.rst
@@ -12,6 +12,7 @@
 
 Mainline support
 ----------------
+
 The support for following drivers are already enabled:
 
 1. SiFive UART Driver.
@@ -24,7 +25,7 @@
 ---------------------------
 
 Building
---------
+~~~~~~~~
 
 1. Add the RISC-V toolchain to your PATH.
 2. Setup ARCH & cross compilation environment variable:
@@ -37,7 +38,7 @@
 4. make
 
 Flashing
---------
+~~~~~~~~
 
 The current U-Boot port is supported in S-mode only and loaded from DRAM.
 
@@ -63,11 +64,12 @@
     sudo dd if=<prior_stage_firmware_binary> of=/dev/disk2s1 bs=1024
 
 Booting
--------
+~~~~~~~
+
 Once you plugin the sdcard and power up, you should see the U-Boot prompt.
 
 Sample boot log from HiFive Unleashed board
--------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 .. code-block:: none
 
@@ -417,7 +419,7 @@
 ---------------------------------
 
 Building
---------
+~~~~~~~~
 
 Before building U-Boot SPL, OpenSBI must be built first. OpenSBI can be
 cloned and built for FU540 as below:
@@ -441,7 +443,7 @@
 
 
 Flashing
---------
+~~~~~~~~
 
 ZSBL loads the U-Boot SPL (u-boot-spl.bin) from a partition with GUID type
 5B193300-FC78-40CD-8002-E86C45580B47
@@ -471,11 +473,12 @@
 	sudo dd if=u-boot.itb of=/dev/sda seek=2082
 
 Booting
--------
+~~~~~~~
+
 Once you plugin the sdcard and power up, you should see the U-Boot prompt.
 
 Sample boot log from HiFive Unleashed board
--------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 .. code-block:: none
 
diff --git a/doc/board/sipeed/maix.rst b/doc/board/sipeed/maix.rst
index 92f2d11..bf945b3 100644
--- a/doc/board/sipeed/maix.rst
+++ b/doc/board/sipeed/maix.rst
@@ -70,6 +70,7 @@
     U-Boot 2020.04-rc2-00087-g2221cc09c1-dirty (Feb 28 2020 - 13:53:09 -0500)
 
     DRAM:  8 MiB
+    MMC:   spi@53000000:slot@0: 0
     In:    serial@38000000
     Out:   serial@38000000
     Err:   serial@38000000
@@ -118,14 +119,115 @@
 
 The file to flash is build/platform/kendryte/k210/firmware/fw_payload.bin.
 
+Booting
+^^^^^^^
+
+The default boot process is to load and boot the files ``/uImage`` and
+``/k210.dtb`` off of the first partition of the MMC. For Linux, this will result
+in an output like
+
+.. code-block:: none
+
+    U-Boot 2020.10-00691-gd1d651d988-dirty (Oct 16 2020 - 17:05:24 -0400)
+
+    DRAM:  8 MiB
+    MMC:   spi@53000000:slot@0: 0
+    Loading Environment from SPIFlash... SF: Detected w25q128fw with page size 256 Bytes, erase size 4 KiB, total 16 MiB
+    OK
+    In:    serial@38000000
+    Out:   serial@38000000
+    Err:   serial@38000000
+    Hit any key to stop autoboot:  0
+    1827380 bytes read in 1044 ms (1.7 MiB/s)
+    13428 bytes read in 10 ms (1.3 MiB/s)
+    ## Booting kernel from Legacy Image at 80060000 ...
+       Image Name:   linux
+       Image Type:   RISC-V Linux Kernel Image (uncompressed)
+       Data Size:    1827316 Bytes = 1.7 MiB
+       Load Address: 80000000
+       Entry Point:  80000000
+       Verifying Checksum ... OK
+    ## Flattened Device Tree blob at 80400000
+       Booting using the fdt blob at 0x80400000
+       Loading Kernel Image
+       Loading Device Tree to 00000000803f9000, end 00000000803ff473 ... OK
+
+    Starting kernel ...
+
+    [    0.000000] Linux version 5.9.0-00021-g6dcc2f0814c6-dirty (sean@godwin) (riscv64-linux-gnu-gcc (GCC) 10.2.0, GNU ld (GNU Binutils) 2.35) #34 SMP Fri Oct 16 14:40:57 EDT 2020
+    [    0.000000] earlycon: sifive0 at MMIO 0x0000000038000000 (options '115200n8')
+    [    0.000000] printk: bootconsole [sifive0] enabled
+    [    0.000000] Zone ranges:
+    [    0.000000]   DMA32    [mem 0x0000000080000000-0x00000000807fffff]
+    [    0.000000]   Normal   empty
+    [    0.000000] Movable zone start for each node
+    [    0.000000] Early memory node ranges
+    [    0.000000]   node   0: [mem 0x0000000080000000-0x00000000807fffff]
+    [    0.000000] Initmem setup node 0 [mem 0x0000000080000000-0x00000000807fffff]
+    [    0.000000] riscv: ISA extensions acdfgim
+    [    0.000000] riscv: ELF capabilities acdfim
+    [    0.000000] percpu: max_distance=0x18000 too large for vmalloc space 0x0
+    [    0.000000] percpu: Embedded 12 pages/cpu s18848 r0 d30304 u49152
+    [    0.000000] Built 1 zonelists, mobility grouping off.  Total pages: 2020
+    [    0.000000] Kernel command line: earlycon console=ttySIF0
+    [    0.000000] Dentry cache hash table entries: 1024 (order: 1, 8192 bytes, linear)
+    [    0.000000] Inode-cache hash table entries: 512 (order: 0, 4096 bytes, linear)
+    [    0.000000] Sorting __ex_table...
+    [    0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
+    [    0.000000] Memory: 6004K/8192K available (1139K kernel code, 126K rwdata, 198K rodata, 90K init, 81K bss, 2188K reserved, 0K cma-reserved)
+    [    0.000000] rcu: Hierarchical RCU implementation.
+    [    0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies.
+    [    0.000000] NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
+    [    0.000000] riscv-intc: 64 local interrupts mapped
+    [    0.000000] plic: interrupt-controller@C000000: mapped 65 interrupts with 2 handlers for 2 contexts.
+    [    0.000000] random: get_random_bytes called from 0x00000000800019a8 with crng_init=0
+    [    0.000000] k210-clk: clock-controller
+    [    0.000000] k210-clk: clock-controller: fixed-rate 26 MHz osc base clock
+    [    0.000000] clint: clint@2000000: timer running at 7800000 Hz
+    [    0.000000] clocksource: clint_clocksource: mask: 0xffffffffffffffff max_cycles: 0x3990be68b, max_idle_ns: 881590404272 ns
+    [    0.000014] sched_clock: 64 bits at 7MHz, resolution 128ns, wraps every 4398046511054ns
+    [    0.008450] Console: colour dummy device 80x25
+    [    0.012494] Calibrating delay loop (skipped), value calculated using timer frequency.. 15.60 BogoMIPS (lpj=31200)
+    [    0.022693] pid_max: default: 4096 minimum: 301
+    [    0.027352] Mount-cache hash table entries: 512 (order: 0, 4096 bytes, linear)
+    [    0.034428] Mountpoint-cache hash table entries: 512 (order: 0, 4096 bytes, linear)
+    [    0.045099] rcu: Hierarchical SRCU implementation.
+    [    0.050048] smp: Bringing up secondary CPUs ...
+    [    0.055417] smp: Brought up 1 node, 2 CPUs
+    [    0.059602] devtmpfs: initialized
+    [    0.082796] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns
+    [    0.091820] futex hash table entries: 16 (order: -2, 1024 bytes, linear)
+    [    0.098507] pinctrl core: initialized pinctrl subsystem
+    [    0.140938] clocksource: Switched to clocksource clint_clocksource
+    [    0.247216] workingset: timestamp_bits=62 max_order=11 bucket_order=0
+    [    0.277392] k210-fpioa 502b0000.pinmux: K210 FPIOA pin controller
+    [    0.291724] k210-sysctl 50440000.syscon: K210 system controller
+    [    0.305317] k210-rst 50440000.syscon:reset-controller: K210 reset controller
+    [    0.313808] 38000000.serial: ttySIF0 at MMIO 0x38000000 (irq = 1, base_baud = 115200) is a SiFive UART v0
+    [    0.322712] printk: console [ttySIF0] enabled
+    [    0.322712] printk: console [ttySIF0] enabled
+    [    0.331328] printk: bootconsole [sifive0] disabled
+    [    0.331328] printk: bootconsole [sifive0] disabled
+    [    0.353347] Freeing unused kernel memory: 88K
+    [    0.357004] This architecture does not have kernel memory protection.
+    [    0.363397] Run /init as init process
+
+Loading, Booting, and Storing Images
+------------------------------------
+
+.. _loading:
+
 Loading Images
 ^^^^^^^^^^^^^^
 
-To load a kernel, transfer it over serial.
+Serial
+""""""
+
+Use the ``loady`` command to load images over serial.
 
 .. code-block:: none
 
-    => loady 80000000 1500000
+    => loady $loadaddr 1500000
     ## Switch baudrate to 1500000 bps and press ENTER ...
 
     *** baud: 1500000
@@ -150,6 +252,61 @@
     *** baud: 115200 ***
     =>
 
+This command does not set ``$filesize``, so it may need to be set manually.
+
+SPI Flash
+"""""""""
+
+To load an image off of SPI flash, first set up a partition as described in
+:ref:`partitions`. Then, use ``mtd`` to load that partition
+
+.. code-block:: none
+
+    => sf probe
+    SF: Detected w25q128fw with page size 256 Bytes, erase size 4 KiB, total 16 MiB
+    => mtd read linux $loadaddr
+    Reading 2097152 byte(s) at offset 0x00000000
+
+This command does not set ``$filesize``, so it may need to be set manually.
+
+MMC
+"""
+
+The MMC device number is 0. To list partitions on the device, use ``part``:
+
+.. code-block:: none
+
+    => part list mmc 0
+
+    Partition Map for MMC device 0  --   Partition Type: EFI
+
+    Part    Start LBA       End LBA          Name
+            Attributes
+            Type GUID
+            Partition GUID
+      1     0x00000800      0x039effde      "boot"
+            attrs:  0x0000000000000000
+            type:   c12a7328-f81f-11d2-ba4b-00a0c93ec93b
+            guid:   96161f7d-7113-4cc7-9a24-08ab7fc5cb72
+
+To list files, use ``ls``:
+
+.. code-block:: none
+
+    => ls mmc 0:1
+    <DIR>       4096 .
+    <DIR>       4096 ..
+    <DIR>      16384 lost+found
+               13428 k210.dtb
+             1827380 uImage
+
+To load a file, use ``load``:
+
+.. code-block:: none
+
+    => load mmc 0:1 $loadaddr uImage
+    1827380 bytes read in 1049 ms (1.7 MiB/s)
+
 Running Programs
 ^^^^^^^^^^^^^^^^
 
@@ -160,20 +317,6 @@
 
 .. code-block:: none
 
-    => loady
-    ## Ready for binary (ymodem) download to 0x80000000 at 115200 bps...
-    C
-    *** file: ./examples/standalone/hello_world.bin
-    $ sz -vv ./examples/standalone/hello_world.bin
-    Sending: hello_world.bin
-    Bytes Sent:   4864   BPS:649
-    Sending:
-    Ymodem sectors/kbytes sent:   0/ 0k
-    Transfer complete
-
-    *** exit status: 0 ***
-    (CAN) packets, 5 retries
-    ## Total Size      = 0x000012f8 = 4856 Bytes
     => go 80000000
     ## Starting application at 0x80000000 ...
     Example expects ABI version 9
@@ -184,51 +327,127 @@
     argv[1] = "<NULL>"
     Hit any key to exit ...
 
+Note that this will only start a program on one hart. As-of this writing it is
+only possible to start a program on multiple harts using the ``bootm`` command.
+
 Legacy Images
 """""""""""""
 
-To run legacy images, use the ``bootm`` command:
+To create a legacy image, use ``tools/mkimage``:
 
 .. code-block:: none
 
-    $ tools/mkimage -A riscv -O u-boot -T standalone -C none -a 80000000 -e 80000000 -d examples/standalone/hello_world.bin hello_world.img
-    Image Name:
-    Created:      Thu Mar  5 12:04:10 2020
-    Image Type:   RISC-V U-Boot Standalone Program (uncompressed)
-    Data Size:    4856 Bytes = 4.74 KiB = 0.00 MiB
+    $ tools/mkimage -A riscv -O linux -T kernel -C none -a 0x80000000 -e 0x80000000 -n linux -d ../linux-git/arch/riscv/boot/Image uImage
+    Image Name:   linux
+    Created:      Fri Oct 16 17:36:32 2020
+    Image Type:   RISC-V Linux Kernel Image (uncompressed)
+    Data Size:    1827316 Bytes = 1784.49 KiB = 1.74 MiB
     Load Address: 80000000
     Entry Point:  80000000
 
-    $ picocom -b 115200 /dev/ttyUSB0
-    => loady
-    ## Ready for binary (ymodem) download to 0x80000000 at 115200 bps...
-    C
-    *** file: hello_world.img
-    $ sz -vv hello_world.img
-    Sending: hello_world.img
-    Bytes Sent:   4992   BPS:665
-    Sending:
-    Ymodem sectors/kbytes sent:   0/ 0k
-    Transfer complete
+The ``bootm`` command also requires an FDT, even if the image doesn't require
+one. After loading the image to ``$loadaddr`` and the FDT to ``$fdt_addr_r``,
+boot with:
 
-    *** exit status: 0 ***
-    CAN) packets, 3 retries
-    ## Total Size      = 0x00001338 = 4920 Bytes
-    => bootm
-    ## Booting kernel from Legacy Image at 80000000 ...
-       Image Name:
-       Image Type:   RISC-V U-Boot Standalone Program (uncompressed)
-       Data Size:    4856 Bytes = 4.7 KiB
+.. code-block:: none
+
+    => bootm $loadaddr - $fdt_addr_r
+    ## Booting kernel from Legacy Image at 80060000 ...
+       Image Name:   linux
+       Image Type:   RISC-V Linux Kernel Image (uncompressed)
+       Data Size:    1827316 Bytes = 1.7 MiB
        Load Address: 80000000
        Entry Point:  80000000
        Verifying Checksum ... OK
-       Loading Standalone Program
-    Example expects ABI version 9
-    Actual U-Boot ABI version 9
-    Hello World
-    argc = 0
-    argv[0] = "<NULL>"
-    Hit any key to exit ...
+    ## Flattened Device Tree blob at 80400000
+       Booting using the fdt blob at 0x80400000
+       Loading Kernel Image
+       Loading Device Tree to 00000000803f9000, end 00000000803ff473 ... OK
+
+    Starting kernel ...
+
+The FDT is verified after the kernel is relocated, so it must be loaded high
+enough so that it won't be overwritten. The default values for ``$loadaddr``
+and ``$fdt_addr_r`` should provide ample headroom for most use-cases.
+
+Flashing Images
+^^^^^^^^^^^^^^^
+
+SPI Flash
+"""""""""
+
+To flash data to SPI flash, first load it using one of the methods in
+:ref:`loading`. Addiotionally, create some partitions as described in
+:ref:`partitions`. Then use the ``mtd`` command:
+
+.. code-block:: none
+
+    => sf probe
+    SF: Detected w25q128fw with page size 256 Bytes, erase size 4 KiB, total 16 MiB
+    => mtd write linux $loadaddr 0 $filesize
+    Writing 2478162 byte(s) at offset 0x00000000
+
+Note that in order to write a bootable image, a header and tailer must be added.
+
+MMC
+"""
+
+MMC writes are unsupported for now.
+
+SPI Flash
+^^^^^^^^^
+
+Sipeed MAIX boards typically provide around 16 MiB of SPI NOR flash. U-Boot is
+stored in the first 1 MiB or so of this flash. U-Boot's environment is stored at
+the end of flash.
+
+.. _partitions:
+
+Partitions
+""""""""""
+
+There is no set data layout. The default partition layout only allocates
+partitions for U-Boot and its default environment
+
+.. code-block:: none
+
+    => mtd list
+    List of MTD devices:
+    * nor0
+      - type: NOR flash
+      - block size: 0x1000 bytes
+      - min I/O: 0x1 bytes
+      - 0x000000000000-0x000001000000 : "nor0"
+          - 0x000000000000-0x000000100000 : "u-boot"
+          - 0x000000fff000-0x000001000000 : "env"
+
+As an example, to allocate 2MiB for Linux and (almost) 13 MiB for other data,
+set the ``mtdparts`` like:
+
+.. code-block:: none
+
+    => env set mtdparts nor0:1M(u-boot),2M(linux),0xcff000(data),0x1000@0xfff000(env)
+    => mtd list
+    List of MTD devices:
+    * nor0
+      - type: NOR flash
+      - block size: 0x1000 bytes
+      - min I/O: 0x1 bytes
+      - 0x000000000000-0x000001000000 : "nor0"
+          - 0x000000000000-0x000000100000 : "u-boot"
+          - 0x000000100000-0x000000300000 : "linux"
+          - 0x000000300000-0x000000fff000 : "data"
+          - 0x000000fff000-0x000001000000 : "env"
+
+To make these changes permanent, save the environment:
+
+.. code-block:: none
+
+    => env save
+    Saving Environment to SPIFlash... Erasing SPI flash...Writing to SPI flash...done
+    OK
+
+U-Boot will always load the environment from the last 4 KiB of flash.
 
 Pin Assignment
 --------------
diff --git a/doc/usage/base.rst b/doc/usage/base.rst
new file mode 100644
index 0000000..db9cd4d
--- /dev/null
+++ b/doc/usage/base.rst
@@ -0,0 +1,23 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+base command
+============
+
+Synopsis
+--------
+
+::
+
+    base [address]
+
+Description
+-----------
+
+The *base* command sets or displays the address offset used by the memory
+commands *cmp, cp, md, mdc, mm, ms, mw, mwc*.
+
+All other commands ignore the address defined by *base*.
+
+address
+    new base address as hexadecimal number. If no value is provided, the current
+    value is displayed.
diff --git a/doc/usage/fdt_overlays.rst b/doc/usage/fdt_overlays.rst
new file mode 100644
index 0000000..ea39713
--- /dev/null
+++ b/doc/usage/fdt_overlays.rst
@@ -0,0 +1,134 @@
+.. SPDX-License-Identifier: GPL-2.0+
+.. Copyright (c) 2017, Pantelis Antoniou <pantelis.antoniou@konsulko.com>
+
+Device Tree Overlays
+====================
+
+Overlay Syntax
+--------------
+
+Device-tree overlays require a slightly different syntax compared to traditional
+device-trees. Please refer to dt-object-internal.txt in the device-tree compiler
+sources for information regarding the internal format of overlays:
+https://git.kernel.org/pub/scm/utils/dtc/dtc.git/tree/Documentation/dt-object-internal.txt
+
+Building Overlays
+-----------------
+
+In a nutshell overlays provides a means to manipulate a symbol a previous
+device-tree or device-tree overlay has defined. It requires both the base
+device-tree and all the overlays to be compiled with the *-@* command line
+switch of the device-tree compiler so that symbol information is included.
+
+Note
+    Support for *-@* option can only be found in dtc version 1.4.4 or newer.
+    Only version 4.14 or higher of the Linux kernel includes a built in version
+    of dtc that meets this requirement.
+
+Building a binary device-tree overlay follows the same process as building a
+traditional binary device-tree. For example:
+
+**base.dts**
+
+::
+
+	/dts-v1/;
+	/ {
+		foo: foonode {
+			foo-property;
+		};
+	};
+
+.. code-block:: console
+
+	$ dtc -@ -I dts -O dtb -o base.dtb base.dts
+
+**overlay.dts**
+
+::
+
+	/dts-v1/;
+	/plugin/;
+	/ {
+		fragment@1 {
+			target = <&foo>;
+			__overlay__ {
+				overlay-1-property;
+				bar: barnode {
+					bar-property;
+				};
+			};
+		};
+	};
+
+.. code-block:: console
+
+	$ dtc -@ -I dts -O dtb -o overlay.dtbo overlay.dts
+
+Ways to Utilize Overlays in U-Boot
+----------------------------------
+
+There are two ways to apply overlays in U-Boot.
+
+* Include and define overlays within a FIT image and have overlays
+  automatically applied.
+
+* Manually load and apply overlays
+
+The remainder of this document will discuss using overlays via the manual
+approach. For information on using overlays as part of a FIT image please see:
+doc/uImage.FIT/overlay-fdt-boot.txt
+
+Manually Loading and Applying Overlays
+--------------------------------------
+
+1. Figure out where to place both the base device tree blob and the
+   overlay. Make sure you have enough space to grow the base tree without
+   overlapping anything.
+
+::
+
+    => setenv fdtaddr 0x87f00000
+    => setenv fdtovaddr 0x87fc0000
+
+2. Load the base binary device-tree and the binary device-tree overlay.
+
+::
+
+    => load ${devtype} ${bootpart} ${fdtaddr} ${bootdir}/base.dtb
+    => load ${devtype} ${bootpart} ${fdtovaddr} ${bootdir}/overlay.dtbo
+
+3. Set the base binary device-tree as the working fdt tree.
+
+::
+
+    => fdtaddr $fdtaddr
+
+4. Grow it enough so it can encompass all applied overlays
+
+::
+
+    => fdt resize 8192
+
+5. You are now ready to apply the overlay.
+
+::
+
+    => fdt apply $fdtovaddr
+
+6. Boot system like you would do with a traditional dtb.
+
+For bootm:
+
+::
+
+    => bootm ${kerneladdr} - ${fdtaddr}
+
+For bootz:
+
+::
+
+    => bootz ${kerneladdr} - ${fdtaddr}
+
+Please note that in case of an error, both the base and overlays are going
+to be invalidated, so keep copies to avoid reloading.
diff --git a/doc/usage/index.rst b/doc/usage/index.rst
index 5869fba..6def250 100644
--- a/doc/usage/index.rst
+++ b/doc/usage/index.rst
@@ -2,7 +2,9 @@
 ==========
 
 .. toctree::
+   :maxdepth: 1
 
+   fdt_overlays
    netconsole
 
 Shell commands
@@ -11,6 +13,7 @@
 .. toctree::
    :maxdepth: 1
 
+   base
    bootefi
    bootmenu
    button
diff --git a/doc/usage/pstore.rst b/doc/usage/pstore.rst
index 8c4e527..1c83745 100644
--- a/doc/usage/pstore.rst
+++ b/doc/usage/pstore.rst
@@ -1,8 +1,17 @@
 .. SPDX-License-Identifier: GPL-2.0+
 
-PStore command
+pstore command
 ==============
 
+Synopsis
+--------
+
+::
+
+    pstore set <addr> <len> [record-size] [console-size] [ftrace-size] [pmsg_size] [ecc-size]
+    pstore display [record-type] [nb]
+    pstore save <interface> <dev[:part]> <directory-path>
+
 Design
 ------
 
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index db06f27..4aeaa0c 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -165,6 +165,7 @@
 source "drivers/clk/imx/Kconfig"
 source "drivers/clk/kendryte/Kconfig"
 source "drivers/clk/meson/Kconfig"
+source "drivers/clk/microchip/Kconfig"
 source "drivers/clk/mvebu/Kconfig"
 source "drivers/clk/owl/Kconfig"
 source "drivers/clk/renesas/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index f8383e5..645709b 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -30,6 +30,7 @@
 obj-$(CONFIG_CLK_HSDK) += clk-hsdk-cgu.o
 obj-$(CONFIG_CLK_K210) += kendryte/
 obj-$(CONFIG_CLK_MPC83XX) += mpc83xx_clk.o
+obj-$(CONFIG_CLK_MPFS) += microchip/
 obj-$(CONFIG_CLK_OCTEON) += clk_octeon.o
 obj-$(CONFIG_CLK_OWL) += owl/
 obj-$(CONFIG_CLK_RENESAS) += renesas/
diff --git a/drivers/clk/microchip/Kconfig b/drivers/clk/microchip/Kconfig
new file mode 100644
index 0000000..b702415
--- /dev/null
+++ b/drivers/clk/microchip/Kconfig
@@ -0,0 +1,5 @@
+config CLK_MPFS
+	bool "Clock support for Microchip PolarFire SoC"
+	depends on CLK && CLK_CCF
+	help
+	  This enables support clock driver for Microchip PolarFire SoC platform.
diff --git a/drivers/clk/microchip/Makefile b/drivers/clk/microchip/Makefile
new file mode 100644
index 0000000..904b345
--- /dev/null
+++ b/drivers/clk/microchip/Makefile
@@ -0,0 +1 @@
+obj-y += mpfs_clk.o mpfs_clk_cfg.o mpfs_clk_periph.o
diff --git a/drivers/clk/microchip/mpfs_clk.c b/drivers/clk/microchip/mpfs_clk.c
new file mode 100644
index 0000000..722c79b
--- /dev/null
+++ b/drivers/clk/microchip/mpfs_clk.c
@@ -0,0 +1,123 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2020 Microchip Technology Inc.
+ * Padmarao Begari <padmarao.begari@microchip.com>
+ */
+#include <common.h>
+#include <clk.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <log.h>
+#include <dm/device.h>
+#include <dm/devres.h>
+#include <dm/uclass.h>
+#include <linux/err.h>
+
+#include "mpfs_clk.h"
+
+/* All methods are delegated to CCF clocks */
+
+static ulong mpfs_clk_get_rate(struct clk *clk)
+{
+	struct clk *c;
+	int err = clk_get_by_id(clk->id, &c);
+
+	if (err)
+		return err;
+	return clk_get_rate(c);
+}
+
+static ulong mpfs_clk_set_rate(struct clk *clk, unsigned long rate)
+{
+	struct clk *c;
+	int err = clk_get_by_id(clk->id, &c);
+
+	if (err)
+		return err;
+	return clk_set_rate(c, rate);
+}
+
+static int mpfs_clk_set_parent(struct clk *clk, struct clk *parent)
+{
+	struct clk *c, *p;
+	int err = clk_get_by_id(clk->id, &c);
+
+	if (err)
+		return err;
+
+	err = clk_get_by_id(parent->id, &p);
+	if (err)
+		return err;
+
+	return clk_set_parent(c, p);
+}
+
+static int mpfs_clk_endisable(struct clk *clk, bool enable)
+{
+	struct clk *c;
+	int err = clk_get_by_id(clk->id, &c);
+
+	if (err)
+		return err;
+	return enable ? clk_enable(c) : clk_disable(c);
+}
+
+static int mpfs_clk_enable(struct clk *clk)
+{
+	return mpfs_clk_endisable(clk, true);
+}
+
+static int mpfs_clk_disable(struct clk *clk)
+{
+	return mpfs_clk_endisable(clk, false);
+}
+
+static int mpfs_clk_probe(struct udevice *dev)
+{
+	int ret;
+	void __iomem *base;
+	u32 clk_rate;
+	const char *parent_clk_name;
+	struct clk *clk = dev_get_priv(dev);
+
+	base = dev_read_addr_ptr(dev);
+	if (!base)
+		return -EINVAL;
+
+	ret = clk_get_by_index(dev, 0, clk);
+	if (ret)
+		return ret;
+
+	dev_read_u32(clk->dev, "clock-frequency", &clk_rate);
+	parent_clk_name = clk->dev->name;
+
+	ret = mpfs_clk_register_cfgs(base, clk_rate, parent_clk_name);
+	if (ret)
+		return ret;
+
+	ret = mpfs_clk_register_periphs(base, clk_rate, "clk_ahb");
+
+	return ret;
+}
+
+static const struct clk_ops mpfs_clk_ops = {
+	.set_rate = mpfs_clk_set_rate,
+	.get_rate = mpfs_clk_get_rate,
+	.set_parent = mpfs_clk_set_parent,
+	.enable = mpfs_clk_enable,
+	.disable = mpfs_clk_disable,
+};
+
+static const struct udevice_id mpfs_of_match[] = {
+	{ .compatible = "microchip,mpfs-clkcfg" },
+	{ }
+};
+
+U_BOOT_DRIVER(mpfs_clk) = {
+	.name = "mpfs_clk",
+	.id = UCLASS_CLK,
+	.of_match = mpfs_of_match,
+	.ops = &mpfs_clk_ops,
+	.probe = mpfs_clk_probe,
+	.priv_auto = sizeof(struct clk),
+};
diff --git a/drivers/clk/microchip/mpfs_clk.h b/drivers/clk/microchip/mpfs_clk.h
new file mode 100644
index 0000000..8e3fc55
--- /dev/null
+++ b/drivers/clk/microchip/mpfs_clk.h
@@ -0,0 +1,44 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2020 Microchip Technology Inc.
+ * Padmarao Begari <padmarao.begari@microchip.com>
+ */
+#ifndef __MICROCHIP_MPFS_CLK_H
+#define __MICROCHIP_MPFS_CLK_H
+
+#include <linux/clk-provider.h>
+/**
+ * mpfs_clk_register_cfgs() - register configuration clocks
+ *
+ * @base: base address of the mpfs system register.
+ * @clk_rate: the mpfs pll clock rate.
+ * @parent_name: a pointer to parent clock name.
+ * @return zero on success, or a negative error code.
+ */
+int mpfs_clk_register_cfgs(void __iomem *base, u32 clk_rate,
+			   const char *parent_name);
+/**
+ * mpfs_clk_register_periphs() - register peripheral clocks
+ *
+ * @base: base address of the mpfs system register.
+ * @clk_rate: the mpfs pll clock rate.
+ * @parent_name: a pointer to parent clock name.
+ * @return zero on success, or a negative error code.
+ */
+int mpfs_clk_register_periphs(void __iomem *base, u32 clk_rate,
+			      const char *parent_name);
+/**
+ * divider_get_val() - get the clock divider value
+ *
+ * @rate: requested clock rate.
+ * @parent_rate: parent clock rate.
+ * @table: a pointer to clock divider table.
+ * @width: width of the divider bit field.
+ * @flags: common clock framework flags.
+ * @return divider value on success, or a negative error code.
+ */
+int divider_get_val(unsigned long rate, unsigned long parent_rate,
+		    const struct clk_div_table *table,
+		    u8 width, unsigned long flags);
+
+#endif	/* __MICROCHIP_MPFS_CLK_H */
diff --git a/drivers/clk/microchip/mpfs_clk_cfg.c b/drivers/clk/microchip/mpfs_clk_cfg.c
new file mode 100644
index 0000000..fefddd1
--- /dev/null
+++ b/drivers/clk/microchip/mpfs_clk_cfg.c
@@ -0,0 +1,152 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2020 Microchip Technology Inc.
+ * Padmarao Begari <padmarao.begari@microchip.com>
+ */
+#include <common.h>
+#include <clk.h>
+#include <clk-uclass.h>
+#include <asm/io.h>
+#include <dm/device.h>
+#include <dm/devres.h>
+#include <dm/uclass.h>
+#include <dt-bindings/clock/microchip-mpfs-clock.h>
+#include <linux/err.h>
+
+#include "mpfs_clk.h"
+
+#define MPFS_CFG_CLOCK "mpfs_cfg_clock"
+
+#define REG_CLOCK_CONFIG_CR 0x08
+
+/* CPU and AXI clock divisors */
+static const struct clk_div_table mpfs_div_cpu_axi_table[] = {
+	{ 0, 1 }, { 1, 2 }, { 2, 4 }, { 3, 8 },
+	{ 0, 0 }
+};
+
+/* AHB clock divisors */
+static const struct clk_div_table mpfs_div_ahb_table[] = {
+	{ 1, 2 }, { 2, 4}, { 3, 8 },
+	{ 0, 0 }
+};
+
+/**
+ * struct mpfs_cfg_clock - per instance of configuration clock
+ * @id: index of a configuration clock
+ * @name: name of a configuration clock
+ * @shift: shift to the divider bit field of a configuration clock
+ * @width: width of the divider bit field of a configation clock
+ * @table: clock divider table instance
+ * @flags: common clock framework flags
+ */
+struct mpfs_cfg_clock {
+	unsigned int id;
+	const char *name;
+	u8 shift;
+	u8 width;
+	const struct clk_div_table *table;
+	unsigned long flags;
+};
+
+/**
+ * struct mpfs_cfg_hw_clock - hardware configuration clock (cpu, axi, ahb)
+ * @cfg: configuration clock instance
+ * @sys_base: base address of the mpfs system register
+ * @prate: the pll clock rate
+ * @hw: clock instance
+ */
+struct mpfs_cfg_hw_clock {
+	struct mpfs_cfg_clock cfg;
+	void __iomem *sys_base;
+	u32 prate;
+	struct clk hw;
+};
+
+#define to_mpfs_cfg_clk(_hw) container_of(_hw, struct mpfs_cfg_hw_clock, hw)
+
+static ulong mpfs_cfg_clk_recalc_rate(struct clk *hw)
+{
+	struct mpfs_cfg_hw_clock *cfg_hw = to_mpfs_cfg_clk(hw);
+	struct mpfs_cfg_clock *cfg = &cfg_hw->cfg;
+	void __iomem *base_addr = cfg_hw->sys_base;
+	unsigned long rate;
+	u32 val;
+
+	val = readl(base_addr + REG_CLOCK_CONFIG_CR) >> cfg->shift;
+	val &= clk_div_mask(cfg->width);
+	rate = cfg_hw->prate / (1u << val);
+	hw->rate = rate;
+
+	return rate;
+}
+
+static ulong mpfs_cfg_clk_set_rate(struct clk *hw, ulong rate)
+{
+	struct mpfs_cfg_hw_clock *cfg_hw = to_mpfs_cfg_clk(hw);
+	struct mpfs_cfg_clock *cfg = &cfg_hw->cfg;
+	void __iomem *base_addr = cfg_hw->sys_base;
+	u32  val;
+	int divider_setting;
+
+	divider_setting = divider_get_val(rate, cfg_hw->prate, cfg->table, cfg->width, cfg->flags);
+
+	if (divider_setting < 0)
+		return divider_setting;
+
+	val = readl(base_addr + REG_CLOCK_CONFIG_CR);
+	val &= ~(clk_div_mask(cfg->width) << cfg_hw->cfg.shift);
+	val |= divider_setting << cfg->shift;
+	writel(val, base_addr + REG_CLOCK_CONFIG_CR);
+
+	return clk_get_rate(hw);
+}
+
+#define CLK_CFG(_id, _name, _shift, _width, _table, _flags) {	\
+		.cfg.id = _id,					\
+		.cfg.name = _name,				\
+		.cfg.shift = _shift,				\
+		.cfg.width = _width,				\
+		.cfg.table = _table,				\
+		.cfg.flags = _flags,				\
+	}
+
+static struct mpfs_cfg_hw_clock mpfs_cfg_clks[] = {
+	CLK_CFG(CLK_CPU, "clk_cpu", 0, 2, mpfs_div_cpu_axi_table, 0),
+	CLK_CFG(CLK_AXI, "clk_axi", 2, 2, mpfs_div_cpu_axi_table, 0),
+	CLK_CFG(CLK_AHB, "clk_ahb", 4, 2, mpfs_div_ahb_table, 0),
+};
+
+int mpfs_clk_register_cfgs(void __iomem *base, u32 clk_rate,
+			   const char *parent_name)
+{
+	int ret;
+	int i, id, num_clks;
+	const char *name;
+	struct clk *hw;
+
+	num_clks = ARRAY_SIZE(mpfs_cfg_clks);
+	for (i = 0; i < num_clks; i++) {
+		hw = &mpfs_cfg_clks[i].hw;
+		mpfs_cfg_clks[i].sys_base = base;
+		mpfs_cfg_clks[i].prate = clk_rate;
+		name = mpfs_cfg_clks[i].cfg.name;
+		ret = clk_register(hw, MPFS_CFG_CLOCK, name, parent_name);
+		if (ret)
+			ERR_PTR(ret);
+		id = mpfs_cfg_clks[i].cfg.id;
+		clk_dm(id, hw);
+	}
+	return 0;
+}
+
+const struct clk_ops mpfs_cfg_clk_ops = {
+	.set_rate = mpfs_cfg_clk_set_rate,
+	.get_rate = mpfs_cfg_clk_recalc_rate,
+};
+
+U_BOOT_DRIVER(mpfs_cfg_clock) = {
+	.name	= MPFS_CFG_CLOCK,
+	.id	= UCLASS_CLK,
+	.ops	= &mpfs_cfg_clk_ops,
+};
diff --git a/drivers/clk/microchip/mpfs_clk_periph.c b/drivers/clk/microchip/mpfs_clk_periph.c
new file mode 100644
index 0000000..61d90eb
--- /dev/null
+++ b/drivers/clk/microchip/mpfs_clk_periph.c
@@ -0,0 +1,187 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2020 Microchip Technology Inc.
+ * Padmarao Begari <padmarao.begari@microchip.com>
+ */
+#include <common.h>
+#include <clk.h>
+#include <clk-uclass.h>
+#include <asm/io.h>
+#include <dm/device.h>
+#include <dm/devres.h>
+#include <dm/uclass.h>
+#include <dt-bindings/clock/microchip-mpfs-clock.h>
+#include <linux/err.h>
+
+#include "mpfs_clk.h"
+
+#define MPFS_PERIPH_CLOCK "mpfs_periph_clock"
+
+#define REG_CLOCK_CONFIG_CR 0x08
+#define REG_SUBBLK_CLOCK_CR 0x84
+#define REG_SUBBLK_RESET_CR 0x88
+
+#define CFG_CPU_SHIFT   0x0
+#define CFG_AXI_SHIFT   0x2
+#define CFG_AHB_SHIFT   0x4
+#define CFG_WIDTH       0x2
+
+/**
+ * struct mpfs_periph_clock - per instance of peripheral clock
+ * @id: index of a peripheral clock
+ * @name: name of a peripheral clock
+ * @shift: shift to a peripheral clock bit field
+ * @flags: common clock framework flags
+ */
+struct mpfs_periph_clock {
+	unsigned int id;
+	const char *name;
+	u8 shift;
+	unsigned long flags;
+};
+
+/**
+ * struct mpfs_periph_hw_clock - hardware peripheral clock
+ * @periph: peripheral clock instance
+ * @sys_base: base address of the mpfs system register
+ * @prate: the pll clock rate
+ * @hw: clock instance
+ */
+struct mpfs_periph_hw_clock {
+	struct mpfs_periph_clock periph;
+	void __iomem *sys_base;
+	u32 prate;
+	struct clk hw;
+};
+
+#define to_mpfs_periph_clk(_hw) container_of(_hw, struct mpfs_periph_hw_clock, hw)
+
+static int mpfs_periph_clk_enable(struct clk *hw)
+{
+	struct mpfs_periph_hw_clock *periph_hw = to_mpfs_periph_clk(hw);
+	struct mpfs_periph_clock *periph = &periph_hw->periph;
+	void __iomem *base_addr = periph_hw->sys_base;
+	u32 reg, val;
+
+	if (periph->flags != CLK_IS_CRITICAL) {
+		reg = readl(base_addr + REG_SUBBLK_RESET_CR);
+		val = reg & ~(1u << periph->shift);
+		writel(val, base_addr + REG_SUBBLK_RESET_CR);
+
+		reg = readl(base_addr + REG_SUBBLK_CLOCK_CR);
+		val = reg | (1u << periph->shift);
+		writel(val, base_addr + REG_SUBBLK_CLOCK_CR);
+	}
+
+	return 0;
+}
+
+static int mpfs_periph_clk_disable(struct clk *hw)
+{
+	struct mpfs_periph_hw_clock *periph_hw = to_mpfs_periph_clk(hw);
+	struct mpfs_periph_clock *periph = &periph_hw->periph;
+	void __iomem *base_addr = periph_hw->sys_base;
+	u32 reg, val;
+
+	if (periph->flags != CLK_IS_CRITICAL) {
+		reg = readl(base_addr + REG_SUBBLK_RESET_CR);
+		val = reg | (1u << periph->shift);
+		writel(val, base_addr + REG_SUBBLK_RESET_CR);
+
+		reg = readl(base_addr + REG_SUBBLK_CLOCK_CR);
+		val = reg & ~(1u << periph->shift);
+		writel(val, base_addr + REG_SUBBLK_CLOCK_CR);
+	}
+
+	return 0;
+}
+
+static ulong mpfs_periph_clk_recalc_rate(struct clk *hw)
+{
+	struct mpfs_periph_hw_clock *periph_hw = to_mpfs_periph_clk(hw);
+	void __iomem *base_addr = periph_hw->sys_base;
+	unsigned long rate;
+	u32 val;
+
+	val = readl(base_addr + REG_CLOCK_CONFIG_CR) >> CFG_AHB_SHIFT;
+	val &= clk_div_mask(CFG_WIDTH);
+	rate = periph_hw->prate / (1u << val);
+	hw->rate = rate;
+
+	return rate;
+}
+
+#define CLK_PERIPH(_id, _name, _shift, _flags) {	\
+		.periph.id = _id,			\
+		.periph.name = _name,			\
+		.periph.shift = _shift,			\
+		.periph.flags = _flags,			\
+	}
+
+static struct mpfs_periph_hw_clock mpfs_periph_clks[] = {
+	CLK_PERIPH(CLK_ENVM, "clk_periph_envm", 0, CLK_IS_CRITICAL),
+	CLK_PERIPH(CLK_MAC0, "clk_periph_mac0", 1, 0),
+	CLK_PERIPH(CLK_MAC1, "clk_periph_mac1", 2, 0),
+	CLK_PERIPH(CLK_MMC, "clk_periph_mmc", 3, 0),
+	CLK_PERIPH(CLK_TIMER, "clk_periph_timer", 4, 0),
+	CLK_PERIPH(CLK_MMUART0, "clk_periph_mmuart0", 5, 0),
+	CLK_PERIPH(CLK_MMUART1, "clk_periph_mmuart1", 6, 0),
+	CLK_PERIPH(CLK_MMUART2, "clk_periph_mmuart2", 7, 0),
+	CLK_PERIPH(CLK_MMUART3, "clk_periph_mmuart3", 8, 0),
+	CLK_PERIPH(CLK_MMUART4, "clk_periph_mmuart4", 9, 0),
+	CLK_PERIPH(CLK_SPI0, "clk_periph_spi0", 10, 0),
+	CLK_PERIPH(CLK_SPI1, "clk_periph_spi1", 11, 0),
+	CLK_PERIPH(CLK_I2C0, "clk_periph_i2c0", 12, 0),
+	CLK_PERIPH(CLK_I2C1, "clk_periph_i2c1", 13, 0),
+	CLK_PERIPH(CLK_CAN0, "clk_periph_can0", 14, 0),
+	CLK_PERIPH(CLK_CAN1, "clk_periph_can1", 15, 0),
+	CLK_PERIPH(CLK_USB, "clk_periph_usb", 16, 0),
+	CLK_PERIPH(CLK_RTC, "clk_periph_rtc", 18, 0),
+	CLK_PERIPH(CLK_QSPI, "clk_periph_qspi", 19, 0),
+	CLK_PERIPH(CLK_GPIO0, "clk_periph_gpio0", 20, 0),
+	CLK_PERIPH(CLK_GPIO1, "clk_periph_gpio1", 21, 0),
+	CLK_PERIPH(CLK_GPIO2, "clk_periph_gpio2", 22, 0),
+	CLK_PERIPH(CLK_DDRC, "clk_periph_ddrc", 23, CLK_IS_CRITICAL),
+	CLK_PERIPH(CLK_FIC0, "clk_periph_fic0", 24, 0),
+	CLK_PERIPH(CLK_FIC1, "clk_periph_fic1", 25, 0),
+	CLK_PERIPH(CLK_FIC2, "clk_periph_fic2", 26, 0),
+	CLK_PERIPH(CLK_FIC3, "clk_periph_fic3", 27, 0),
+	CLK_PERIPH(CLK_ATHENA, "clk_periph_athena", 28, 0),
+	CLK_PERIPH(CLK_CFM, "clk_periph_cfm", 29, 0),
+};
+
+int mpfs_clk_register_periphs(void __iomem *base, u32 clk_rate,
+			      const char *parent_name)
+{
+	int ret;
+	int i, id, num_clks;
+	const char *name;
+	struct clk *hw;
+
+	num_clks = ARRAY_SIZE(mpfs_periph_clks);
+	for (i = 0; i < num_clks; i++)  {
+		hw = &mpfs_periph_clks[i].hw;
+		mpfs_periph_clks[i].sys_base = base;
+		mpfs_periph_clks[i].prate = clk_rate;
+		name = mpfs_periph_clks[i].periph.name;
+		ret = clk_register(hw, MPFS_PERIPH_CLOCK, name, parent_name);
+		if (ret)
+			ERR_PTR(ret);
+		id = mpfs_periph_clks[i].periph.id;
+		clk_dm(id, hw);
+	}
+
+	return 0;
+}
+
+const struct clk_ops mpfs_periph_clk_ops = {
+	.enable = mpfs_periph_clk_enable,
+	.disable = mpfs_periph_clk_disable,
+	.get_rate = mpfs_periph_clk_recalc_rate,
+};
+
+U_BOOT_DRIVER(mpfs_periph_clock) = {
+	.name	= MPFS_PERIPH_CLOCK,
+	.id	= UCLASS_CLK,
+	.ops	= &mpfs_periph_clk_ops,
+};
diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c
index cdb975d..f38122d 100644
--- a/drivers/core/uclass.c
+++ b/drivers/core/uclass.c
@@ -757,6 +757,25 @@
 }
 #endif
 
+int uclass_probe_all(enum uclass_id id)
+{
+	struct udevice *dev;
+	int ret;
+
+	ret = uclass_first_device(id, &dev);
+	if (ret || !dev)
+		return ret;
+
+	/* Scanning uclass to probe all devices */
+	while (dev) {
+		ret = uclass_next_device(&dev);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
 UCLASS_DRIVER(nop) = {
 	.id		= UCLASS_NOP,
 	.name		= "nop",
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 1a4dec3..0d1f94c 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -9,8 +9,6 @@
  */
 
 #ifndef __UBOOT__
-#include <log.h>
-#include <dm/devres.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/ptrace.h>
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index e287c29..2225b33 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -83,7 +83,16 @@
 	u32	ctrl;
 };
 
-#define DMA_DESC_BYTES(n)	(n * sizeof(struct macb_dma_desc))
+struct macb_dma_desc_64 {
+	u32 addrh;
+	u32 unused;
+};
+
+#define HW_DMA_CAP_32B		0
+#define HW_DMA_CAP_64B		1
+
+#define DMA_DESC_SIZE		16
+#define DMA_DESC_BYTES(n)	((n) * DMA_DESC_SIZE)
 #define MACB_TX_DMA_DESC_SIZE	(DMA_DESC_BYTES(MACB_TX_RING_SIZE))
 #define MACB_RX_DMA_DESC_SIZE	(DMA_DESC_BYTES(MACB_RX_RING_SIZE))
 #define MACB_TX_DUMMY_DMA_DESC_SIZE	(DMA_DESC_BYTES(1))
@@ -137,6 +146,7 @@
 
 struct macb_config {
 	unsigned int		dma_burst_length;
+	unsigned int		hw_dma_cap;
 
 	int			(*clk_init)(struct udevice *dev, ulong rate);
 };
@@ -307,6 +317,24 @@
 
 #if defined(CONFIG_CMD_NET)
 
+static struct macb_dma_desc_64 *macb_64b_desc(struct macb_dma_desc *desc)
+{
+	return (struct macb_dma_desc_64 *)((void *)desc
+		+ sizeof(struct macb_dma_desc));
+}
+
+static void macb_set_addr(struct macb_device *macb, struct macb_dma_desc *desc,
+			  ulong addr)
+{
+	struct macb_dma_desc_64 *desc_64;
+
+	if (macb->config->hw_dma_cap & HW_DMA_CAP_64B) {
+		desc_64 = macb_64b_desc(desc);
+		desc_64->addrh = upper_32_bits(addr);
+	}
+	desc->addr = lower_32_bits(addr);
+}
+
 static int _macb_send(struct macb_device *macb, const char *name, void *packet,
 		      int length)
 {
@@ -325,8 +353,12 @@
 		macb->tx_head++;
 	}
 
+	if (macb->config->hw_dma_cap & HW_DMA_CAP_64B)
+		tx_head = tx_head * 2;
+
 	macb->tx_ring[tx_head].ctrl = ctrl;
-	macb->tx_ring[tx_head].addr = paddr;
+	macb_set_addr(macb, &macb->tx_ring[tx_head], paddr);
+
 	barrier();
 	macb_flush_ring_desc(macb, TX);
 	macb_writel(macb, NCR, MACB_BIT(TE) | MACB_BIT(RE) | MACB_BIT(TSTART));
@@ -363,19 +395,28 @@
 			       unsigned int new_tail)
 {
 	unsigned int i;
+	unsigned int count;
 
 	i = macb->rx_tail;
 
 	macb_invalidate_ring_desc(macb, RX);
 	while (i > new_tail) {
-		macb->rx_ring[i].addr &= ~MACB_BIT(RX_USED);
+		if (macb->config->hw_dma_cap & HW_DMA_CAP_64B)
+			count = i * 2;
+		else
+			count = i;
+		macb->rx_ring[count].addr &= ~MACB_BIT(RX_USED);
 		i++;
 		if (i > MACB_RX_RING_SIZE)
 			i = 0;
 	}
 
 	while (i < new_tail) {
-		macb->rx_ring[i].addr &= ~MACB_BIT(RX_USED);
+		if (macb->config->hw_dma_cap & HW_DMA_CAP_64B)
+			count = i * 2;
+		else
+			count = i;
+		macb->rx_ring[count].addr &= ~MACB_BIT(RX_USED);
 		i++;
 	}
 
@@ -390,16 +431,25 @@
 	void *buffer;
 	int length;
 	u32 status;
+	u8 flag = false;
 
 	macb->wrapped = false;
 	for (;;) {
 		macb_invalidate_ring_desc(macb, RX);
 
+		if (macb->config->hw_dma_cap & HW_DMA_CAP_64B)
+			next_rx_tail = next_rx_tail * 2;
+
 		if (!(macb->rx_ring[next_rx_tail].addr & MACB_BIT(RX_USED)))
 			return -EAGAIN;
 
 		status = macb->rx_ring[next_rx_tail].ctrl;
 		if (status & MACB_BIT(RX_SOF)) {
+			if (macb->config->hw_dma_cap & HW_DMA_CAP_64B) {
+				next_rx_tail = next_rx_tail / 2;
+				flag = true;
+			}
+
 			if (next_rx_tail != macb->rx_tail)
 				reclaim_rx_buffers(macb, next_rx_tail);
 			macb->wrapped = false;
@@ -426,11 +476,22 @@
 				*packetp = buffer;
 			}
 
+			if (macb->config->hw_dma_cap & HW_DMA_CAP_64B) {
+				if (!flag)
+					next_rx_tail = next_rx_tail / 2;
+			}
+
 			if (++next_rx_tail >= MACB_RX_RING_SIZE)
 				next_rx_tail = 0;
 			macb->next_rx_tail = next_rx_tail;
 			return length;
 		} else {
+			if (macb->config->hw_dma_cap & HW_DMA_CAP_64B) {
+				if (!flag)
+					next_rx_tail = next_rx_tail / 2;
+				flag = false;
+			}
+
 			if (++next_rx_tail >= MACB_RX_RING_SIZE) {
 				macb->wrapped = true;
 				next_rx_tail = 0;
@@ -470,6 +531,12 @@
 	int i;
 	u16 phy_id;
 
+	phy_id = macb_mdio_read(macb, macb->phy_addr, MII_PHYSID1);
+	if (phy_id != 0xffff) {
+		printf("%s: PHY present at %d\n", name, macb->phy_addr);
+		return 0;
+	}
+
 	/* Search for PHY... */
 	for (i = 0; i < 32; i++) {
 		macb->phy_addr = i;
@@ -718,6 +785,7 @@
 {
 	int i, num_queues = 1;
 	u32 queue_mask;
+	unsigned long paddr;
 
 	/* bit 0 is never set but queue 0 always exists */
 	queue_mask = gem_readl(macb, DCFG6) & 0xff;
@@ -731,10 +799,18 @@
 	macb->dummy_desc->addr = 0;
 	flush_dcache_range(macb->dummy_desc_dma, macb->dummy_desc_dma +
 			ALIGN(MACB_TX_DUMMY_DMA_DESC_SIZE, PKTALIGN));
+	paddr = macb->dummy_desc_dma;
 
-	for (i = 1; i < num_queues; i++)
-		gem_writel_queue_TBQP(macb, macb->dummy_desc_dma, i - 1);
-
+	for (i = 1; i < num_queues; i++) {
+		gem_writel_queue_TBQP(macb, lower_32_bits(paddr), i - 1);
+		gem_writel_queue_RBQP(macb, lower_32_bits(paddr), i - 1);
+		if (macb->config->hw_dma_cap & HW_DMA_CAP_64B) {
+			gem_writel_queue_TBQPH(macb, upper_32_bits(paddr),
+					       i - 1);
+			gem_writel_queue_RBQPH(macb, upper_32_bits(paddr),
+					       i - 1);
+		}
+	}
 	return 0;
 }
 
@@ -760,6 +836,9 @@
 		dmacfg &= ~GEM_BIT(ENDIA_DESC);
 
 	dmacfg &= ~GEM_BIT(ADDR64);
+	if (macb->config->hw_dma_cap & HW_DMA_CAP_64B)
+		dmacfg |= GEM_BIT(ADDR64);
+
 	gem_writel(macb, DMACFG, dmacfg);
 }
 
@@ -775,6 +854,7 @@
 	unsigned long paddr;
 	int ret;
 	int i;
+	int count;
 
 	/*
 	 * macb_halt should have been called at some point before now,
@@ -786,20 +866,28 @@
 	for (i = 0; i < MACB_RX_RING_SIZE; i++) {
 		if (i == (MACB_RX_RING_SIZE - 1))
 			paddr |= MACB_BIT(RX_WRAP);
-		macb->rx_ring[i].addr = paddr;
-		macb->rx_ring[i].ctrl = 0;
+		if (macb->config->hw_dma_cap & HW_DMA_CAP_64B)
+			count = i * 2;
+		else
+			count = i;
+		macb->rx_ring[count].ctrl = 0;
+		macb_set_addr(macb, &macb->rx_ring[count], paddr);
 		paddr += macb->rx_buffer_size;
 	}
 	macb_flush_ring_desc(macb, RX);
 	macb_flush_rx_buffer(macb);
 
 	for (i = 0; i < MACB_TX_RING_SIZE; i++) {
-		macb->tx_ring[i].addr = 0;
+		if (macb->config->hw_dma_cap & HW_DMA_CAP_64B)
+			count = i * 2;
+		else
+			count = i;
+		macb_set_addr(macb, &macb->tx_ring[count], 0);
 		if (i == (MACB_TX_RING_SIZE - 1))
-			macb->tx_ring[i].ctrl = MACB_BIT(TX_USED) |
+			macb->tx_ring[count].ctrl = MACB_BIT(TX_USED) |
 				MACB_BIT(TX_WRAP);
 		else
-			macb->tx_ring[i].ctrl = MACB_BIT(TX_USED);
+			macb->tx_ring[count].ctrl = MACB_BIT(TX_USED);
 	}
 	macb_flush_ring_desc(macb, TX);
 
@@ -812,8 +900,12 @@
 	gem_writel(macb, DMACFG, MACB_ZYNQ_GEM_DMACR_INIT);
 #endif
 
-	macb_writel(macb, RBQP, macb->rx_ring_dma);
-	macb_writel(macb, TBQP, macb->tx_ring_dma);
+	macb_writel(macb, RBQP, lower_32_bits(macb->rx_ring_dma));
+	macb_writel(macb, TBQP, lower_32_bits(macb->tx_ring_dma));
+	if (macb->config->hw_dma_cap & HW_DMA_CAP_64B) {
+		macb_writel(macb, RBQPH, upper_32_bits(macb->rx_ring_dma));
+		macb_writel(macb, TBQPH, upper_32_bits(macb->tx_ring_dma));
+	}
 
 	if (macb_is_gem(macb)) {
 		/* Initialize DMA properties */
@@ -1217,6 +1309,7 @@
 
 static const struct macb_config default_gem_config = {
 	.dma_burst_length = 16,
+	.hw_dma_cap = HW_DMA_CAP_32B,
 	.clk_init = NULL,
 };
 
@@ -1224,11 +1317,12 @@
 {
 	struct eth_pdata *pdata = dev_get_plat(dev);
 	struct macb_device *macb = dev_get_priv(dev);
+	struct ofnode_phandle_args phandle_args;
 	const char *phy_mode;
 	int ret;
 
+	phy_mode = dev_read_prop(dev, "phy-mode", NULL);
+
-	phy_mode = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "phy-mode",
-			       NULL);
 	if (phy_mode)
 		macb->phy_interface = phy_get_interface_by_name(phy_mode);
 	if (macb->phy_interface == -1) {
@@ -1236,6 +1330,12 @@
 		return -EINVAL;
 	}
 
+	/* Read phyaddr from DT */
+	if (!dev_read_phandle_with_args(dev, "phy-handle", NULL, 0, 0,
+					&phandle_args))
+		macb->phy_addr = ofnode_read_u32_default(phandle_args.node,
+							 "reg", -1);
+
 	macb->regs = (void *)pdata->iobase;
 
 	macb->is_big_endian = (cpu_to_be32(0x12345678) == 0x12345678);
@@ -1304,13 +1404,21 @@
 	return macb_late_eth_of_to_plat(dev);
 }
 
+static const struct macb_config microchip_config = {
+	.dma_burst_length = 16,
+	.hw_dma_cap = HW_DMA_CAP_64B,
+	.clk_init = NULL,
+};
+
 static const struct macb_config sama5d4_config = {
 	.dma_burst_length = 4,
+	.hw_dma_cap = HW_DMA_CAP_32B,
 	.clk_init = NULL,
 };
 
 static const struct macb_config sifive_config = {
 	.dma_burst_length = 16,
+	.hw_dma_cap = HW_DMA_CAP_32B,
 	.clk_init = macb_sifive_clk_init,
 };
 
@@ -1324,6 +1432,8 @@
 	{ .compatible = "cdns,zynq-gem" },
 	{ .compatible = "sifive,fu540-c000-gem",
 	  .data = (ulong)&sifive_config },
+	{ .compatible = "microchip,mpfs-mss-gem",
+	  .data = (ulong)&microchip_config },
 	{ }
 };
 
diff --git a/drivers/net/macb.h b/drivers/net/macb.h
index 9b16383..72b84ae 100644
--- a/drivers/net/macb.h
+++ b/drivers/net/macb.h
@@ -768,5 +768,11 @@
 #define GEM_RX_CSUM_CHECKED_MASK		2
 #define gem_writel_queue_TBQP(port, value, queue_num)	\
 	writel((value), (port)->regs + GEM_TBQP(queue_num))
+#define gem_writel_queue_TBQPH(port, value, queue_num)	\
+	writel((value), (port)->regs + GEM_TBQPH(queue_num))
+#define gem_writel_queue_RBQP(port, value, queue_num)	\
+	writel((value), (port)->regs + GEM_RBQP(queue_num))
+#define gem_writel_queue_RBQPH(port, value, queue_num)	\
+	writel((value), (port)->regs + GEM_RBQPH(queue_num))
 
 #endif /* __DRIVERS_MACB_H__ */
diff --git a/drivers/power/regulator/Kconfig b/drivers/power/regulator/Kconfig
index d431102..fbbea18 100644
--- a/drivers/power/regulator/Kconfig
+++ b/drivers/power/regulator/Kconfig
@@ -18,7 +18,7 @@
 
 config SPL_DM_REGULATOR
 	bool "Enable regulators for SPL"
-	depends on DM_REGULATOR
+	depends on DM_REGULATOR && SPL_POWER_SUPPORT
 	---help---
 	Regulators are seldom needed in SPL. Even if they are accessed, some
 	code space can be saved by accessing the PMIC registers directly.
diff --git a/drivers/ram/k3-j721e/lpddr4.c b/drivers/ram/k3-j721e/lpddr4.c
index fc80fb1..68043d7 100644
--- a/drivers/ram/k3-j721e/lpddr4.c
+++ b/drivers/ram/k3-j721e/lpddr4.c
@@ -719,7 +719,7 @@
 
 		/* MISRA compliance (Shifting operation) check */
 		if (fieldshift < WORD_SHIFT) {
-			if (((ctlirqstatus >> fieldshift) & BIT_MASK) > 0U) {
+			if ((ctlirqstatus >> fieldshift) & LPDDR4_BIT_MASK) {
 				*irqstatus = true;
 			} else {
 				*irqstatus = false;
@@ -746,11 +746,11 @@
 		if (localinterrupt > WORD_SHIFT) {
 			localinterrupt =
 			    (localinterrupt - (uint32_t) WORD_SHIFT);
-			regval = ((uint32_t) BIT_MASK << localinterrupt);
+			regval = (uint32_t)LPDDR4_BIT_MASK << localinterrupt;
 			CPS_REG_WRITE(&(ctlregbase->LPDDR4__INT_ACK_1__REG),
 				      regval);
 		} else {
-			regval = ((uint32_t) BIT_MASK << localinterrupt);
+			regval = (uint32_t)LPDDR4_BIT_MASK << localinterrupt;
 			CPS_REG_WRITE(&(ctlregbase->LPDDR4__INT_ACK_0__REG),
 				      regval);
 		}
@@ -823,7 +823,7 @@
 		phyindepirqstatus =
 		    CPS_REG_READ(&(ctlregbase->LPDDR4__PI_INT_STATUS__REG));
 		*irqstatus =
-		    (((phyindepirqstatus >> (uint32_t) intr) & BIT_MASK) > 0U);
+		    !!((phyindepirqstatus >> (uint32_t)intr) & LPDDR4_BIT_MASK);
 	}
 	return result;
 }
@@ -841,7 +841,7 @@
 		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
 
 		/* Write 1 to the requested bit to ACk the interrupt */
-		regval = ((uint32_t) BIT_MASK << ui32shiftinterrupt);
+		regval = (uint32_t)LPDDR4_BIT_MASK << ui32shiftinterrupt;
 		CPS_REG_WRITE(&(ctlregbase->LPDDR4__PI_INT_ACK__REG), regval);
 	}
 
@@ -894,7 +894,7 @@
 	    (volatile uint32_t
 	     *)(&(ctlregbase->LPDDR4__PHY_WRLVL_ERROR_OBS_0__REG));
 	/* PHY_WRLVL_ERROR_OBS_X[1:0] should be zero */
-	errbitmask = (BIT_MASK << 1) | (BIT_MASK);
+	errbitmask = (LPDDR4_BIT_MASK << 1) | LPDDR4_BIT_MASK;
 	for (snum = 0U; snum < DSLICE_NUM; snum++) {
 		regval = CPS_REG_READ(regaddress);
 		if ((regval & errbitmask) != 0U) {
@@ -1054,7 +1054,7 @@
 			     lpddr4_debuginfo * debuginfo, bool * errfoundptr)
 {
 
-	uint32_t errbitmask = (BIT_MASK << 0x1U) | (BIT_MASK);
+	uint32_t errbitmask = (LPDDR4_BIT_MASK << 0x1U) | LPDDR4_BIT_MASK;
 	/* Check PLL observation registers for PLL lock errors */
 
 	debuginfo->pllerror =
diff --git a/drivers/ram/k3-j721e/lpddr4_private.h b/drivers/ram/k3-j721e/lpddr4_private.h
index 42c9234..3d5017e 100644
--- a/drivers/ram/k3-j721e/lpddr4_private.h
+++ b/drivers/ram/k3-j721e/lpddr4_private.h
@@ -14,9 +14,9 @@
 #define VERSION_0  (0x54d5da40U)
 #define VERSION_1  (0xc1865a1U)
 
-#define BIT_MASK    (0x1U)
-#define BYTE_MASK   (0xffU)
-#define NIBBLE_MASK (0xfU)
+#define LPDDR4_BIT_MASK	(0x1U)
+#define BYTE_MASK	(0xffU)
+#define NIBBLE_MASK	(0xfU)
 
 #define WORD_SHIFT (32U)
 #define WORD_MASK (0xffffffffU)
@@ -46,11 +46,15 @@
 #define IO_CALIB_DONE ((uint32_t)0x1U << 23U)
 #define IO_CALIB_FIELD ((uint32_t)NIBBLE_MASK << 28U)
 #define IO_CALIB_STATE ((uint32_t)0xBU << 28U)
-#define RX_CAL_DONE ((uint32_t)BIT_MASK << 4U)
-#define CA_TRAIN_RL (((uint32_t)BIT_MASK << 5U) | ((uint32_t)BIT_MASK << 4U))
+#define RX_CAL_DONE ((uint32_t)LPDDR4_BIT_MASK << 4U)
+#define CA_TRAIN_RL (((uint32_t)LPDDR4_BIT_MASK << 5U) | \
+		     ((uint32_t)LPDDR4_BIT_MASK << 4U))
 #define WR_LVL_STATE (((uint32_t)NIBBLE_MASK) << 13U)
-#define GATE_LVL_ERROR_FIELDS (((uint32_t)BIT_MASK << 7U) | ((uint32_t)BIT_MASK << 6U))
-#define READ_LVL_ERROR_FIELDS ((((uint32_t)NIBBLE_MASK) << 28U) | (((uint32_t)BYTE_MASK) << 16U))
-#define DQ_LVL_STATUS (((uint32_t)BIT_MASK << 26U) | (((uint32_t)BYTE_MASK) << 18U))
+#define GATE_LVL_ERROR_FIELDS (((uint32_t)LPDDR4_BIT_MASK << 7U) | \
+			       ((uint32_t)LPDDR4_BIT_MASK << 6U))
+#define READ_LVL_ERROR_FIELDS ((((uint32_t)NIBBLE_MASK) << 28U) | \
+			       (((uint32_t)BYTE_MASK) << 16U))
+#define DQ_LVL_STATUS (((uint32_t)LPDDR4_BIT_MASK << 26U) | \
+		       (((uint32_t)BYTE_MASK) << 18U))
 
 #endif  /* LPDDR4_PRIV_H */
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index b4805a2..1294943 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -134,6 +134,22 @@
 
 	  If unsure, say N.
 
+config SERIAL_PROBE_ALL
+	bool "Probe all available serial devices"
+	depends on DM_SERIAL
+	default n
+	help
+	  The serial subsystem only probes for a single serial device,
+	  but does not probe for other remaining serial devices.
+	  With this option set, we make probing and searching for
+	  all available devices optional.
+	  Normally, U-Boot talks to one serial port at a time, but SBSA
+	  compliant UART devices like PL011 require initialization
+	  by firmware and to let the kernel use serial port for sending
+	  and receiving the characters.
+
+	  If unsure, say N.
+
 config SPL_DM_SERIAL
 	bool "Enable Driver Model for serial drivers in SPL"
 	depends on DM_SERIAL && SPL_DM
diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c
index 58a6541..ead0193 100644
--- a/drivers/serial/serial-uclass.c
+++ b/drivers/serial/serial-uclass.c
@@ -172,6 +172,15 @@
 /* Called after relocation */
 int serial_initialize(void)
 {
+	/* Scanning uclass to probe devices */
+	if (IS_ENABLED(CONFIG_SERIAL_PROBE_ALL)) {
+		int ret;
+
+		ret  = uclass_probe_all(UCLASS_SERIAL);
+		if (ret)
+			return ret;
+	}
+
 	return serial_init();
 }
 
diff --git a/drivers/timer/andes_plmt_timer.c b/drivers/timer/andes_plmt_timer.c
index db2cf86..a3797b2 100644
--- a/drivers/timer/andes_plmt_timer.c
+++ b/drivers/timer/andes_plmt_timer.c
@@ -18,11 +18,30 @@
 /* mtime register */
 #define MTIME_REG(base)			((ulong)(base))
 
-static u64 andes_plmt_get_count(struct udevice *dev)
+static u64 notrace andes_plmt_get_count(struct udevice *dev)
 {
 	return readq((void __iomem *)MTIME_REG(dev_get_priv(dev)));
 }
 
+#if CONFIG_IS_ENABLED(RISCV_MMODE) && IS_ENABLED(CONFIG_TIMER_EARLY)
+/**
+ * timer_early_get_rate() - Get the timer rate before driver model
+ */
+unsigned long notrace timer_early_get_rate(void)
+{
+	return RISCV_MMODE_TIMER_FREQ;
+}
+
+/**
+ * timer_early_get_count() - Get the timer count before driver model
+ *
+ */
+u64 notrace timer_early_get_count(void)
+{
+	return readq((void __iomem *)MTIME_REG(RISCV_MMODE_TIMERBASE));
+}
+#endif
+
 static const struct timer_ops andes_plmt_ops = {
 	.get_count = andes_plmt_get_count,
 };
diff --git a/drivers/timer/riscv_timer.c b/drivers/timer/riscv_timer.c
index 21ae184..3627ed7 100644
--- a/drivers/timer/riscv_timer.c
+++ b/drivers/timer/riscv_timer.c
@@ -16,7 +16,7 @@
 #include <timer.h>
 #include <asm/csr.h>
 
-static u64 riscv_timer_get_count(struct udevice *dev)
+static u64 notrace riscv_timer_get_count(struct udevice *dev)
 {
 	__maybe_unused u32 hi, lo;
 
@@ -31,6 +31,25 @@
 	return ((u64)hi << 32) | lo;
 }
 
+#if CONFIG_IS_ENABLED(RISCV_SMODE) && IS_ENABLED(CONFIG_TIMER_EARLY)
+/**
+ * timer_early_get_rate() - Get the timer rate before driver model
+ */
+unsigned long notrace timer_early_get_rate(void)
+{
+	return RISCV_SMODE_TIMER_FREQ;
+}
+
+/**
+ * timer_early_get_count() - Get the timer count before driver model
+ *
+ */
+u64 notrace timer_early_get_count(void)
+{
+	return riscv_timer_get_count(NULL);
+}
+#endif
+
 static int riscv_timer_probe(struct udevice *dev)
 {
 	struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
diff --git a/drivers/timer/sifive_clint_timer.c b/drivers/timer/sifive_clint_timer.c
index de23b85..de7b4b9 100644
--- a/drivers/timer/sifive_clint_timer.c
+++ b/drivers/timer/sifive_clint_timer.c
@@ -15,11 +15,30 @@
 /* mtime register */
 #define MTIME_REG(base)			((ulong)(base) + 0xbff8)
 
-static u64 sifive_clint_get_count(struct udevice *dev)
+static u64 notrace sifive_clint_get_count(struct udevice *dev)
 {
 	return readq((void __iomem *)MTIME_REG(dev_get_priv(dev)));
 }
 
+#if CONFIG_IS_ENABLED(RISCV_MMODE) && IS_ENABLED(CONFIG_TIMER_EARLY)
+/**
+ * timer_early_get_rate() - Get the timer rate before driver model
+ */
+unsigned long notrace timer_early_get_rate(void)
+{
+	return RISCV_MMODE_TIMER_FREQ;
+}
+
+/**
+ * timer_early_get_count() - Get the timer count before driver model
+ *
+ */
+u64 notrace timer_early_get_count(void)
+{
+	return readq((void __iomem *)MTIME_REG(RISCV_MMODE_TIMERBASE));
+}
+#endif
+
 static const struct timer_ops sifive_clint_ops = {
 	.get_count = sifive_clint_get_count,
 };
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index d39d9b2..d782eb8 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -199,7 +199,7 @@
 
 config SIMPLE_PANEL
 	bool "Enable simple panel support"
-	depends on PANEL
+	depends on PANEL && BACKLIGHT
 	default y
 	help
 	  This turns on a simple panel driver that enables a compatible
diff --git a/dts/Makefile b/dts/Makefile
index 94967cf..cb31113 100644
--- a/dts/Makefile
+++ b/dts/Makefile
@@ -33,7 +33,7 @@
 $(DTB): arch-dtbs
 	$(Q)test -e $@ || (						\
 	echo >&2;							\
-	echo >&2 "Device Tree Source is not correctly specified.";	\
+	echo >&2 "Device Tree Source ($@) is not correctly specified.";	\
 	echo >&2 "Please define 'CONFIG_DEFAULT_DEVICE_TREE'";		\
 	echo >&2 "or build with 'DEVICE_TREE=<device_tree>' argument";	\
 	echo >&2;							\
diff --git a/include/configs/ax25-ae350.h b/include/configs/ax25-ae350.h
index b2606e7..bd9c371 100644
--- a/include/configs/ax25-ae350.h
+++ b/include/configs/ax25-ae350.h
@@ -17,6 +17,11 @@
 #endif
 #endif
 
+#define RISCV_MMODE_TIMERBASE           0xe6000000
+#define RISCV_MMODE_TIMER_FREQ          60000000
+
+#define RISCV_SMODE_TIMER_FREQ          60000000
+
 /*
  * CPU and Board Configuration Options
  */
diff --git a/include/configs/microchip_mpfs_icicle.h b/include/configs/microchip_mpfs_icicle.h
index 8a74705..2499037 100644
--- a/include/configs/microchip_mpfs_icicle.h
+++ b/include/configs/microchip_mpfs_icicle.h
@@ -7,53 +7,34 @@
 #ifndef __CONFIG_H
 #define __CONFIG_H
 
-/*
- * CPU and Board Configuration Options
- */
+#include <linux/sizes.h>
 
-/*
- * Miscellaneous configurable options
- */
-#define CONFIG_SYS_CBSIZE	1024 /* Console I/O Buffer Size */
+#define CONFIG_SYS_SDRAM_BASE       0x80000000
+#define CONFIG_SYS_INIT_SP_ADDR     (CONFIG_SYS_SDRAM_BASE + SZ_2M)
 
-/*
- * Print Buffer Size
- */
-#define CONFIG_SYS_PBSIZE	\
-	(CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16)
+#define CONFIG_SYS_LOAD_ADDR        (CONFIG_SYS_SDRAM_BASE + SZ_2M)
 
-/*
- * max number of command args
- */
-#define CONFIG_SYS_MAXARGS	16
+#define CONFIG_SYS_MALLOC_LEN       SZ_8M
 
-/*
- * Boot Argument Buffer Size
- */
-#define CONFIG_SYS_BARGSIZE	CONFIG_SYS_CBSIZE
+#define CONFIG_SYS_BOOTM_LEN        SZ_64M
 
-/*
- * Size of malloc() pool
- * 512kB is suggested, (CONFIG_ENV_SIZE + 128 * 1024) was not enough
- */
-#define CONFIG_SYS_MALLOC_LEN	(512 << 10)
+#define CONFIG_STANDALONE_LOAD_ADDR 0x80200000
 
-/*
- * Physical Memory Map
- */
-#define PHYS_SDRAM_0		0x80000000 /* SDRAM Bank #1 */
-#define PHYS_SDRAM_0_SIZE	0x40000000 /* 1 GB */
-#define CONFIG_SYS_SDRAM_BASE	PHYS_SDRAM_0
+/* Environment options */
 
-/* Init Stack Pointer */
-#define CONFIG_SYS_INIT_SP_ADDR	(CONFIG_SYS_SDRAM_BASE + 0x200000)
+#define BOOT_TARGET_DEVICES(func) \
+	func(MMC, mmc, 0) \
+	func(DHCP, dhcp, na)
 
-#define CONFIG_SYS_LOAD_ADDR	0x80000000 /* SDRAM */
-
-/*
- * memtest works on DRAM
- */
+#include <config_distro_bootcmd.h>
 
-/* When we use RAM as ENV */
+#define CONFIG_EXTRA_ENV_SETTINGS \
+	"bootm_size=0x10000000\0" \
+	"kernel_addr_r=0x84000000\0" \
+	"fdt_addr_r=0x88000000\0" \
+	"scriptaddr=0x88100000\0" \
+	"pxefile_addr_r=0x88200000\0" \
+	"ramdisk_addr_r=0x88300000\0" \
+	BOOTENV
 
 #endif /* __CONFIG_H */
diff --git a/include/configs/qemu-riscv.h b/include/configs/qemu-riscv.h
index a2f3358..5291de8 100644
--- a/include/configs/qemu-riscv.h
+++ b/include/configs/qemu-riscv.h
@@ -29,6 +29,11 @@
 
 #define CONFIG_STANDALONE_LOAD_ADDR	0x80200000
 
+#define RISCV_MMODE_TIMERBASE		0x2000000
+#define RISCV_MMODE_TIMER_FREQ		1000000
+
+#define RISCV_SMODE_TIMER_FREQ		1000000
+
 /* Environment options */
 
 #ifndef CONFIG_SPL_BUILD
diff --git a/include/configs/sifive-fu540.h b/include/configs/sifive-fu540.h
index c1c79db..0d69d1c 100644
--- a/include/configs/sifive-fu540.h
+++ b/include/configs/sifive-fu540.h
@@ -36,6 +36,11 @@
 
 #define CONFIG_STANDALONE_LOAD_ADDR	0x80200000
 
+#define RISCV_MMODE_TIMERBASE		0x2000000
+#define RISCV_MMODE_TIMER_FREQ		1000000
+
+#define RISCV_SMODE_TIMER_FREQ		1000000
+
 /* Environment options */
 
 #ifndef CONFIG_SPL_BUILD
diff --git a/include/configs/sipeed-maix.h b/include/configs/sipeed-maix.h
index 36ff522..08acb25 100644
--- a/include/configs/sipeed-maix.h
+++ b/include/configs/sipeed-maix.h
@@ -24,10 +24,13 @@
 #ifndef CONFIG_EXTRA_ENV_SETTINGS
 #define CONFIG_EXTRA_ENV_SETTINGS \
 	"loadaddr=0x80060000\0" \
-	"fdt_addr_r=0x80028000\0" \
+	"fdt_addr_r=0x80400000\0" \
 	"scriptaddr=0x80020000\0" \
 	"kernel_addr_r=0x80060000\0" \
-	"fdtfile=kendryte/" CONFIG_DEFAULT_DEVICE_TREE ".dtb\0"
+	"fdtfile=kendryte/" CONFIG_DEFAULT_DEVICE_TREE ".dtb\0" \
+	"k210_bootcmd=load mmc 0:1 $loadaddr /uImage && " \
+		"load mmc 0:1 $fdt_addr_r /k210.dtb && " \
+		"bootm $loadaddr - $fdt_addr_r\0"
 #endif
 
 #endif /* CONFIGS_SIPEED_MAIX_H */
diff --git a/include/dm/uclass.h b/include/dm/uclass.h
index b5f066d..d956837 100644
--- a/include/dm/uclass.h
+++ b/include/dm/uclass.h
@@ -377,6 +377,17 @@
 				struct udevice **devp);
 
 /**
+ * uclass_probe_all() - Probe all devices based on an uclass ID
+ *
+ * This function probes all devices associated with a uclass by
+ * looking for its ID.
+ *
+ * @id: uclass ID to look up
+ * @return 0 if OK, other -ve on error
+ */
+int uclass_probe_all(enum uclass_id id);
+
+/**
  * uclass_id_foreach_dev() - Helper function to iteration through devices
  *
  * This creates a for() loop which works through the available devices in
diff --git a/include/dt-bindings/clock/microchip-mpfs-clock.h b/include/dt-bindings/clock/microchip-mpfs-clock.h
new file mode 100644
index 0000000..55fe646
--- /dev/null
+++ b/include/dt-bindings/clock/microchip-mpfs-clock.h
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
+/*
+ * Copyright (C) 2020 Microchip Technology Inc.
+ * Padmarao Begari <padmarao.begari@microchip.com>
+ */
+
+#ifndef _DT_BINDINGS_CLK_MICROCHIP_MPFS_H_
+#define _DT_BINDINGS_CLK_MICROCHIP_MPFS_H_
+
+#define CLK_CPU		0
+#define CLK_AXI		1
+#define CLK_AHB		2
+
+#define CLK_ENVM	3
+#define CLK_MAC0	4
+#define CLK_MAC1	5
+#define CLK_MMC		6
+#define CLK_TIMER	7
+#define CLK_MMUART0	8
+#define CLK_MMUART1	9
+#define CLK_MMUART2	10
+#define CLK_MMUART3	11
+#define CLK_MMUART4	12
+#define CLK_SPI0	13
+#define CLK_SPI1	14
+#define CLK_I2C0	15
+#define CLK_I2C1	16
+#define CLK_CAN0	17
+#define CLK_CAN1	18
+#define CLK_USB		19
+#define CLK_RESERVED	20
+#define CLK_RTC		21
+#define CLK_QSPI	22
+#define CLK_GPIO0	23
+#define CLK_GPIO1	24
+#define CLK_GPIO2	25
+#define CLK_DDRC	26
+#define CLK_FIC0	27
+#define CLK_FIC1	28
+#define CLK_FIC2	29
+#define CLK_FIC3	30
+#define CLK_ATHENA	31
+#define CLK_CFM		32
+
+#endif	/* _DT_BINDINGS_CLK_MICROCHIP_MPFS_H_ */
diff --git a/include/log.h b/include/log.h
index 6bce560..2d27f9f 100644
--- a/include/log.h
+++ b/include/log.h
@@ -156,6 +156,9 @@
  */
 #if CONFIG_IS_ENABLED(LOG)
 #define _LOG_MAX_LEVEL CONFIG_VAL(LOG_MAX_LEVEL)
+#define log_emer(_fmt...)	log(LOG_CATEGORY, LOGL_EMERG, ##_fmt)
+#define log_alert(_fmt...)	log(LOG_CATEGORY, LOGL_ALERT, ##_fmt)
+#define log_crit(_fmt...)	log(LOG_CATEGORY, LOGL_CRIT, ##_fmt)
 #define log_err(_fmt...)	log(LOG_CATEGORY, LOGL_ERR, ##_fmt)
 #define log_warning(_fmt...)	log(LOG_CATEGORY, LOGL_WARNING, ##_fmt)
 #define log_notice(_fmt...)	log(LOG_CATEGORY, LOGL_NOTICE, ##_fmt)
@@ -163,12 +166,17 @@
 #define log_debug(_fmt...)	log(LOG_CATEGORY, LOGL_DEBUG, ##_fmt)
 #define log_content(_fmt...)	log(LOG_CATEGORY, LOGL_DEBUG_CONTENT, ##_fmt)
 #define log_io(_fmt...)		log(LOG_CATEGORY, LOGL_DEBUG_IO, ##_fmt)
+#define log_cont(_fmt...)	log(LOGC_CONT, LOGL_CONT, ##_fmt)
 #else
 #define _LOG_MAX_LEVEL LOGL_INFO
+#define log_emerg(_fmt, ...)	printf(_fmt, ##__VA_ARGS__)
+#define log_alert(_fmt, ...)	printf(_fmt, ##__VA_ARGS__)
+#define log_crit(_fmt, ...)	printf(_fmt, ##__VA_ARGS__)
 #define log_err(_fmt, ...)	printf(_fmt, ##__VA_ARGS__)
 #define log_warning(_fmt, ...)	printf(_fmt, ##__VA_ARGS__)
 #define log_notice(_fmt, ...)	printf(_fmt, ##__VA_ARGS__)
 #define log_info(_fmt, ...)	printf(_fmt, ##__VA_ARGS__)
+#define log_cont(_fmt, ...)	printf(_fmt, ##__VA_ARGS__)
 #define log_debug(_fmt, ...)	debug(_fmt, ##__VA_ARGS__)
 #define log_content(_fmt...)	log_nop(LOG_CATEGORY, \
 					LOGL_DEBUG_CONTENT, ##_fmt)
@@ -217,10 +225,9 @@
 #if !_DEBUG && CONFIG_IS_ENABLED(LOG)
 
 #define debug_cond(cond, fmt, args...)			\
-	do {						\
-		if (1)					\
-			log(LOG_CATEGORY, LOGL_DEBUG, fmt, ##args); \
-	} while (0)
+({							\
+	log(LOG_CATEGORY, LOGL_DEBUG, fmt, ##args);	\
+})
 
 #else /* _DEBUG */
 
@@ -229,11 +236,11 @@
  * computed by a preprocessor in the best case, allowing for the best
  * optimization.
  */
-#define debug_cond(cond, fmt, args...)			\
-	do {						\
-		if (cond)				\
-			printf(pr_fmt(fmt), ##args);	\
-	} while (0)
+#define debug_cond(cond, fmt, args...)		\
+({						\
+	if (cond)				\
+		printf(pr_fmt(fmt), ##args);	\
+})
 
 #endif /* _DEBUG */
 
diff --git a/include/part.h b/include/part.h
index fac3636..815515a 100644
--- a/include/part.h
+++ b/include/part.h
@@ -9,6 +9,7 @@
 #include <blk.h>
 #include <ide.h>
 #include <uuid.h>
+#include <linker_lists.h>
 #include <linux/list.h>
 
 struct block_drvr {
@@ -481,5 +482,33 @@
 
 #endif
 
+#ifdef CONFIG_PARTITIONS
+/**
+ * part_driver_get_count() - get partition driver count
+ *
+ * @return - number of partition drivers
+ */
+static inline int part_driver_get_count(void)
+{
+	return ll_entry_count(struct part_driver, part_driver);
+}
+
+/**
+ * part_driver_get_first() - get first partition driver
+ *
+ * @return - pointer to first partition driver on success, otherwise NULL
+ */
+static inline struct part_driver *part_driver_get_first(void)
+{
+	return ll_entry_start(struct part_driver, part_driver);
+}
+
+#else
+static inline int part_driver_get_count(void)
+{ return 0; }
+
+static inline struct part_driver *part_driver_get_first(void)
+{ return NULL; }
+#endif /* CONFIG_PARTITIONS */
 
 #endif /* _PART_H */
diff --git a/include/part_efi.h b/include/part_efi.h
index 1929e44..c68529b 100644
--- a/include/part_efi.h
+++ b/include/part_efi.h
@@ -56,6 +56,9 @@
 #define PARTITION_LINUX_LVM_GUID \
 	EFI_GUID( 0xe6d6d379, 0xf507, 0x44c2, \
 		0xa2, 0x3c, 0x23, 0x8f, 0x2a, 0x3d, 0xf9, 0x28)
+#define PARTITION_U_BOOT_ENVIRONMENT \
+	EFI_GUID( 0x3de21764, 0x95bd, 0x54bd, \
+		0xa5, 0xc3, 0x4a, 0xbe, 0x78, 0x6f, 0x38, 0xa8)
 
 /* linux/include/efi.h */
 typedef u16 efi_char16_t;
diff --git a/include/test/ut.h b/include/test/ut.h
index 3f2ee75..17400c7 100644
--- a/include/test/ut.h
+++ b/include/test/ut.h
@@ -338,4 +338,22 @@
  */
 long ut_check_delta(ulong last);
 
+/**
+ * ut_silence_console() - Silence the console if requested by the user
+ *
+ * This stops test output from appear on the console. It is the default on
+ * sandbox, unless the -v flag is given. For other boards, this does nothing.
+ *
+ * @uts: Test state (in case in future we want to keep state here)
+ */
+void ut_silence_console(struct unit_test_state *uts);
+
+/**
+ * ut_unsilence_console() - Unsilence the console after a test
+ *
+ * This restarts console output again and turns off console recording. This
+ * happens on all boards, including sandbox.
+ */
+void ut_unsilence_console(struct unit_test_state *uts);
+
 #endif
diff --git a/include/uuid.h b/include/uuid.h
index 73c5a89..0c653cb 100644
--- a/include/uuid.h
+++ b/include/uuid.h
@@ -39,10 +39,8 @@
 		    int str_format);
 void uuid_bin_to_str(const unsigned char *uuid_bin, char *uuid_str,
 		     int str_format);
-#ifdef CONFIG_PARTITION_TYPE_GUID
 int uuid_guid_get_bin(const char *guid_str, unsigned char *guid_bin);
-int uuid_guid_get_str(const unsigned char *guid_bin, char *guid_str);
-#endif
+const char *uuid_guid_get_str(const unsigned char *guid_bin);
 void gen_rand_uuid(unsigned char *uuid_bin);
 void gen_rand_uuid_str(char *uuid_str, int str_format);
 #endif
diff --git a/lib/Kconfig b/lib/Kconfig
index a704568..b35a71a 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -210,6 +210,7 @@
 config TRACE
 	bool "Support for tracing of function calls and timing"
 	imply CMD_TRACE
+	select TIMER_EARLY
 	help
 	  Enables function tracing within U-Boot. This allows recording of call
 	  traces including timing information. The command can write data to
@@ -695,8 +696,8 @@
 config LIB_ELF
 	bool
 	help
-	  Supoort basic elf loading/validating functions.
-	  This supports fir 32 bit and 64 bit versions.
+	  Support basic elf loading/validating functions.
+	  This supports for 32 bit and 64 bit versions.
 
 endmenu
 
diff --git a/lib/aes.c b/lib/aes.c
index c998aec..05ec235 100644
--- a/lib/aes.c
+++ b/lib/aes.c
@@ -619,7 +619,7 @@
 static void debug_print_vector(char *name, u32 num_bytes, u8 *data)
 {
 #ifdef DEBUG
-	printf("%s [%d] @0x%08x", name, num_bytes, (u32)data);
+	printf("%s [%d] @0x%p", name, num_bytes, data);
 	print_buffer(0, data, 1, num_bytes, 16);
 #endif
 }
diff --git a/lib/string.c b/lib/string.c
index ae7835f..73b9841 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -567,7 +567,19 @@
 {
 	char *tmp, *s;
 
-	if (dest <= src) {
+	if (dest <= src || (src + count) <= dest) {
+	/*
+	 * Use the fast memcpy implementation (ARCH optimized or lib/string.c) when it is possible:
+	 * - when dest is before src (assuming that memcpy is doing forward-copying)
+	 * - when destination don't overlap the source buffer (src + count <= dest)
+	 *
+	 * WARNING: the first optimisation cause an issue, when __HAVE_ARCH_MEMCPY is defined,
+	 *          __HAVE_ARCH_MEMMOVE is not defined and if the memcpy ARCH-specific
+	 *          implementation is not doing a forward-copying.
+	 *
+	 * No issue today because memcpy is doing a forward-copying in lib/string.c and for ARM32
+	 * architecture; no other arches use __HAVE_ARCH_MEMCPY without __HAVE_ARCH_MEMMOVE.
+	 */
 		memcpy(dest, src, count);
 	} else {
 		tmp = (char *) dest + count;
diff --git a/lib/uuid.c b/lib/uuid.c
index e62d5ca..54a93aa 100644
--- a/lib/uuid.c
+++ b/lib/uuid.c
@@ -96,7 +96,8 @@
 	{"linux",	PARTITION_LINUX_FILE_SYSTEM_DATA_GUID},
 	{"raid",	PARTITION_LINUX_RAID_GUID},
 	{"swap",	PARTITION_LINUX_SWAP_GUID},
-	{"lvm",		PARTITION_LINUX_LVM_GUID}
+	{"lvm",		PARTITION_LINUX_LVM_GUID},
+	{"u-boot-env",	PARTITION_U_BOOT_ENVIRONMENT},
 };
 
 /*
@@ -122,20 +123,19 @@
  * uuid_guid_get_str() - this function get string for GUID.
  *
  * @param guid_bin - pointer to string with partition type guid [16B]
- * @param guid_str - pointer to allocated partition type string [7B]
+ *
+ * Returns NULL if the type GUID is not known.
  */
-int uuid_guid_get_str(const unsigned char *guid_bin, char *guid_str)
+const char *uuid_guid_get_str(const unsigned char *guid_bin)
 {
 	int i;
 
-	*guid_str = 0;
 	for (i = 0; i < ARRAY_SIZE(list_guid); i++) {
 		if (!memcmp(list_guid[i].guid.b, guid_bin, 16)) {
-			strcpy(guid_str, list_guid[i].string);
-			return 0;
+			return list_guid[i].string;
 		}
 	}
-	return -ENODEV;
+	return NULL;
 }
 #endif
 
diff --git a/lib/zlib/deflate.c b/lib/zlib/deflate.c
index 1fe58d5..6347335 100644
--- a/lib/zlib/deflate.c
+++ b/lib/zlib/deflate.c
@@ -1284,7 +1284,7 @@
     }
     if (z_verbose > 1) {
         fprintf(stderr,"\\[%d,%d]", start-match, length);
-        do { putc(s->window[start++], stderr); } while (--length != 0);
+	do { putc(s->window[start++]); } while (--length != 0);
     }
 }
 #else
diff --git a/lib/zlib/trees.c b/lib/zlib/trees.c
index 3e09517..700c62f 100644
--- a/lib/zlib/trees.c
+++ b/lib/zlib/trees.c
@@ -38,7 +38,7 @@
 #include "deflate.h"
 
 #ifdef DEBUG
-#  include <ctype.h>
+#  include <linux/ctype.h>
 #endif
 
 /* ===========================================================================
diff --git a/test/Makefile b/test/Makefile
index d4323f9..3c7bc8b 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -2,7 +2,7 @@
 #
 # (C) Copyright 2012 The Chromium Authors
 
-ifneq ($(CONFIG_SANDBOX),)
+ifneq ($(CONFIG_$(SPL_)BLOBLIST),)
 obj-$(CONFIG_$(SPL_)CMDLINE) += bloblist.o
 endif
 obj-$(CONFIG_$(SPL_)CMDLINE) += bootm.o
diff --git a/test/bloblist.c b/test/bloblist.c
index 0bb9e2d..900299d 100644
--- a/test/bloblist.c
+++ b/test/bloblist.c
@@ -7,7 +7,6 @@
 #include <bloblist.h>
 #include <log.h>
 #include <mapmem.h>
-#include <asm/state.h>
 #include <test/suites.h>
 #include <test/test.h>
 #include <test/ut.h>
@@ -240,7 +239,6 @@
 /* Test the 'bloblist info' command */
 static int bloblist_test_cmd_info(struct unit_test_state *uts)
 {
-	struct sandbox_state *state = state_get_current();
 	struct bloblist_hdr *hdr;
 	char *data, *data2;
 
@@ -250,8 +248,7 @@
 	data2 = bloblist_ensure(TEST_TAG2, TEST_SIZE2);
 
 	console_record_reset_enable();
-	if (!state->show_test_output)
-		gd->flags |= GD_FLG_SILENT;
+	ut_silence_console(uts);
 	console_record_reset();
 	run_command("bloblist info", 0);
 	ut_assert_nextline("base:     %lx", (ulong)map_to_sysmem(hdr));
@@ -259,7 +256,7 @@
 	ut_assert_nextline("alloced:  70     112 Bytes");
 	ut_assert_nextline("free:     390    912 Bytes");
 	ut_assert_console_end();
-	gd->flags &= ~(GD_FLG_SILENT | GD_FLG_RECORD);
+	ut_unsilence_console(uts);
 
 	return 0;
 }
@@ -268,7 +265,6 @@
 /* Test the 'bloblist list' command */
 static int bloblist_test_cmd_list(struct unit_test_state *uts)
 {
-	struct sandbox_state *state = state_get_current();
 	struct bloblist_hdr *hdr;
 	char *data, *data2;
 
@@ -278,8 +274,7 @@
 	data2 = bloblist_ensure(TEST_TAG2, TEST_SIZE2);
 
 	console_record_reset_enable();
-	if (!state->show_test_output)
-		gd->flags |= GD_FLG_SILENT;
+	ut_silence_console(uts);
 	console_record_reset();
 	run_command("bloblist list", 0);
 	ut_assert_nextline("Address       Size  Tag Name");
@@ -288,7 +283,7 @@
 	ut_assert_nextline("%08lx  %8x    2 SPL hand-off",
 			   (ulong)map_to_sysmem(data2), TEST_SIZE2);
 	ut_assert_console_end();
-	gd->flags &= ~(GD_FLG_SILENT | GD_FLG_RECORD);
+	ut_unsilence_console(uts);
 
 	return 0;
 }
diff --git a/test/cmd/mem.c b/test/cmd/mem.c
index fa6770e..fbaa8a4 100644
--- a/test/cmd/mem.c
+++ b/test/cmd/mem.c
@@ -15,6 +15,6 @@
 	struct unit_test *tests = ll_entry_start(struct unit_test, mem_test);
 	const int n_ents = ll_entry_count(struct unit_test, mem_test);
 
-	return cmd_ut_category("cmd_mem", "cmd_mem_", tests, n_ents, argc,
+	return cmd_ut_category("cmd_mem", "mem_test_", tests, n_ents, argc,
 			       argv);
 }
diff --git a/test/lib/Makefile b/test/lib/Makefile
index 98a9abf..97c11e3 100644
--- a/test/lib/Makefile
+++ b/test/lib/Makefile
@@ -7,7 +7,7 @@
 obj-$(CONFIG_EFI_SECURE_BOOT) += efi_image_region.o
 obj-y += hexdump.o
 obj-y += lmb.o
-obj-y += test_print.o
+obj-$(CONFIG_CONSOLE_RECORD) += test_print.o
 obj-$(CONFIG_SSCANF) += sscanf.o
 obj-y += string.o
 obj-$(CONFIG_ERRNO_STR) += test_errno_str.o
diff --git a/test/log/Makefile b/test/log/Makefile
index 88bc573..afdafa5 100644
--- a/test/log/Makefile
+++ b/test/log/Makefile
@@ -8,6 +8,7 @@
 ifdef CONFIG_UT_LOG
 
 obj-y += test-main.o
+obj-y += pr_cont_test.o
 
 ifdef CONFIG_SANDBOX
 obj-$(CONFIG_LOG_SYSLOG) += syslog_test.o
diff --git a/test/log/pr_cont_test.c b/test/log/pr_cont_test.c
new file mode 100644
index 0000000..236eff4
--- /dev/null
+++ b/test/log/pr_cont_test.c
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2021, Heinrich Schuchardt <xypron.glpk@gmx.de>
+ *
+ * Test continuation of log messages using pr_cont().
+ */
+
+#include <common.h>
+#include <console.h>
+#include <test/log.h>
+#include <test/test.h>
+#include <test/suites.h>
+#include <test/ut.h>
+#include <linux/printk.h>
+
+#define BUFFSIZE 64
+
+#undef CONFIG_LOGLEVEL
+#define CONFIG_LOGLEVEL 4
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static int log_test_pr_cont(struct unit_test_state *uts)
+{
+	int log_fmt;
+	int log_level;
+
+	log_fmt = gd->log_fmt;
+	log_level = gd->default_log_level;
+
+	/* Write two messages, the second continuing the first */
+	gd->log_fmt = BIT(LOGF_MSG);
+	gd->default_log_level = LOGL_INFO;
+	console_record_reset_enable();
+	pr_err("ea%d ", 1);
+	pr_cont("cc%d\n", 2);
+	gd->default_log_level = log_level;
+	gd->log_fmt = log_fmt;
+	gd->flags &= ~GD_FLG_RECORD;
+	ut_assertok(ut_check_console_line(uts, "ea1 cc2"));
+	ut_assertok(ut_check_console_end(uts));
+
+	return 0;
+}
+LOG_TEST(log_test_pr_cont);
diff --git a/test/str_ut.c b/test/str_ut.c
index ef1205d..cd50455 100644
--- a/test/str_ut.c
+++ b/test/str_ut.c
@@ -19,7 +19,7 @@
 /* Declare a new str test */
 #define STR_TEST(_name, _flags)		UNIT_TEST(_name, _flags, str_test)
 
-static int str_test_upper(struct unit_test_state *uts)
+static int str_upper(struct unit_test_state *uts)
 {
 	char out[TEST_STR_SIZE];
 
@@ -55,7 +55,7 @@
 
 	return 0;
 }
-STR_TEST(str_test_upper, 0);
+STR_TEST(str_upper, 0);
 
 static int run_strtoul(struct unit_test_state *uts, const char *str, int base,
 		       ulong expect_val, int expect_endp_offset, bool upper)
diff --git a/test/ut.c b/test/ut.c
index 95bdd66..44ed1ba 100644
--- a/test/ut.c
+++ b/test/ut.c
@@ -8,6 +8,9 @@
 #include <common.h>
 #include <console.h>
 #include <malloc.h>
+#ifdef CONFIG_SANDBOX
+#include <asm/state.h>
+#endif
 #include <test/test.h>
 #include <test/ut.h>
 
@@ -114,3 +117,18 @@
 
 	return upto == total_bytes ? 0 : 1;
 }
+
+void ut_silence_console(struct unit_test_state *uts)
+{
+#ifdef CONFIG_SANDBOX
+	struct sandbox_state *state = state_get_current();
+
+	if (!state->show_test_output)
+		gd->flags |= GD_FLG_SILENT;
+#endif
+}
+
+void ut_unsilence_console(struct unit_test_state *uts)
+{
+	gd->flags &= ~(GD_FLG_SILENT | GD_FLG_RECORD);
+}