Merge tag 'arc-updates-for-2018.07-rc2' of git://git.denx.de/u-boot-arc

Here we just add a tool for HSDK flashable images preparation
together with extensive documentation for HSDK board.

This will help real-life users to update U-Boot on the board.
diff --git a/arch/arm/cpu/armv8/fwcall.c b/arch/arm/cpu/armv8/fwcall.c
index c5aa41a..0ba3dad 100644
--- a/arch/arm/cpu/armv8/fwcall.c
+++ b/arch/arm/cpu/armv8/fwcall.c
@@ -143,15 +143,12 @@
 			efi_status_t reset_status,
 			unsigned long data_size, void *reset_data)
 {
-	switch (reset_type) {
-	case EFI_RESET_COLD:
-	case EFI_RESET_WARM:
-	case EFI_RESET_PLATFORM_SPECIFIC:
+	if (reset_type == EFI_RESET_COLD ||
+	    reset_type == EFI_RESET_WARM ||
+	    reset_type == EFI_RESET_PLATFORM_SPECIFIC) {
 		psci_system_reset();
-		break;
-	case EFI_RESET_SHUTDOWN:
+	} else if (reset_type == EFI_RESET_SHUTDOWN) {
 		psci_system_off();
-		break;
 	}
 
 	while (1) { }
diff --git a/arch/arm/cpu/armv8/zynqmp/cpu.c b/arch/arm/cpu/armv8/zynqmp/cpu.c
index e122be5..1279dc8 100644
--- a/arch/arm/cpu/armv8/zynqmp/cpu.c
+++ b/arch/arm/cpu/armv8/zynqmp/cpu.c
@@ -212,8 +212,12 @@
 {
 	u32 data;
 	u32 value_local = value;
+	int ret;
 
-	zynqmp_mmio_read(address, &data);
+	ret = zynqmp_mmio_read(address, &data);
+	if (ret)
+		return ret;
+
 	data &= ~mask;
 	value_local &= mask;
 	value_local |= data;
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 078c21b..493652e 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -147,7 +147,8 @@
 	zynq-zturn.dtb \
 	zynq-zybo.dtb
 dtb-$(CONFIG_ARCH_ZYNQMP) += \
-	zynqmp-mini-emmc.dtb			\
+	zynqmp-mini-emmc0.dtb			\
+	zynqmp-mini-emmc1.dtb			\
 	zynqmp-mini-nand.dtb			\
 	zynqmp-zcu100-revC.dtb			\
 	zynqmp-zcu102-revA.dtb			\
diff --git a/arch/arm/dts/zynq-zc702.dts b/arch/arm/dts/zynq-zc702.dts
index bb22466..12e3561 100644
--- a/arch/arm/dts/zynq-zc702.dts
+++ b/arch/arm/dts/zynq-zc702.dts
@@ -30,8 +30,6 @@
 
 	gpio-keys {
 		compatible = "gpio-keys";
-		#address-cells = <1>;
-		#size-cells = <0>;
 		autorepeat;
 		sw14 {
 			label = "sw14";
diff --git a/arch/arm/dts/zynq-zturn.dts b/arch/arm/dts/zynq-zturn.dts
index 8aa384b..cc41efc 100644
--- a/arch/arm/dts/zynq-zturn.dts
+++ b/arch/arm/dts/zynq-zturn.dts
@@ -49,8 +49,6 @@
 
 	gpio-keys {
 		compatible = "gpio-keys";
-		#address-cells = <1>;
-		#size-cells = <0>;
 		autorepeat;
 		K1 {
 			label = "K1";
diff --git a/arch/arm/dts/zynqmp-mini-emmc.dts b/arch/arm/dts/zynqmp-mini-emmc0.dts
similarity index 77%
rename from arch/arm/dts/zynqmp-mini-emmc.dts
rename to arch/arm/dts/zynqmp-mini-emmc0.dts
index e5b3c5f..24dd1ab 100644
--- a/arch/arm/dts/zynqmp-mini-emmc.dts
+++ b/arch/arm/dts/zynqmp-mini-emmc0.dts
@@ -18,7 +18,6 @@
 	aliases {
 		serial0 = &dcc;
 		mmc0 = &sdhci0;
-		mmc1 = &sdhci1;
 	};
 
 	chosen {
@@ -36,6 +35,12 @@
 		u-boot,dm-pre-reloc;
 	};
 
+	clk_xin: clk_xin {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <200000000>;
+	};
+
 	amba: amba {
 		compatible = "simple-bus";
 		#address-cells = <2>;
@@ -50,15 +55,6 @@
 			clock-names = "clk_xin", "clk_ahb";
 			xlnx,device_id = <0>;
 		};
-
-		sdhci1: sdhci@ff170000 {
-			u-boot,dm-pre-reloc;
-			compatible = "xlnx,zynqmp-8.9a", "arasan,sdhci-8.9a";
-			status = "disabled";
-			reg = <0x0 0xff170000 0x0 0x1000>;
-			clock-names = "clk_xin", "clk_ahb";
-			xlnx,device_id = <1>;
-		};
 	};
 };
 
@@ -69,7 +65,3 @@
 &sdhci0 {
 	status = "okay";
 };
-
-&sdhci1 {
-	status = "okay";
-};
diff --git a/arch/arm/dts/zynqmp-mini-emmc.dts b/arch/arm/dts/zynqmp-mini-emmc1.dts
similarity index 72%
copy from arch/arm/dts/zynqmp-mini-emmc.dts
copy to arch/arm/dts/zynqmp-mini-emmc1.dts
index e5b3c5f..d1549b6 100644
--- a/arch/arm/dts/zynqmp-mini-emmc.dts
+++ b/arch/arm/dts/zynqmp-mini-emmc1.dts
@@ -17,8 +17,7 @@
 
 	aliases {
 		serial0 = &dcc;
-		mmc0 = &sdhci0;
-		mmc1 = &sdhci1;
+		mmc0 = &sdhci1;
 	};
 
 	chosen {
@@ -36,27 +35,24 @@
 		u-boot,dm-pre-reloc;
 	};
 
+	clk_xin: clk_xin {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <200000000>;
+	};
+
 	amba: amba {
 		compatible = "simple-bus";
 		#address-cells = <2>;
 		#size-cells = <2>;
 		ranges;
 
-		sdhci0: sdhci@ff160000 {
-			u-boot,dm-pre-reloc;
-			compatible = "xlnx,zynqmp-8.9a", "arasan,sdhci-8.9a";
-			status = "disabled";
-			reg = <0x0 0xff160000 0x0 0x1000>;
-			clock-names = "clk_xin", "clk_ahb";
-			xlnx,device_id = <0>;
-		};
-
 		sdhci1: sdhci@ff170000 {
 			u-boot,dm-pre-reloc;
 			compatible = "xlnx,zynqmp-8.9a", "arasan,sdhci-8.9a";
 			status = "disabled";
 			reg = <0x0 0xff170000 0x0 0x1000>;
-			clock-names = "clk_xin", "clk_ahb";
+			clock-names = "clk_xin", "clk_xin";
 			xlnx,device_id = <1>;
 		};
 	};
@@ -66,10 +62,6 @@
 	status = "okay";
 };
 
-&sdhci0 {
-	status = "okay";
-};
-
 &sdhci1 {
 	status = "okay";
 };
diff --git a/arch/arm/dts/zynqmp-zcu100-revC.dts b/arch/arm/dts/zynqmp-zcu100-revC.dts
index c6aaa08..6e575a0 100644
--- a/arch/arm/dts/zynqmp-zcu100-revC.dts
+++ b/arch/arm/dts/zynqmp-zcu100-revC.dts
@@ -48,8 +48,6 @@
 
 	gpio-keys {
 		compatible = "gpio-keys";
-		#address-cells = <1>;
-		#size-cells = <0>;
 		autorepeat;
 		sw4 {
 			label = "sw4";
diff --git a/arch/arm/dts/zynqmp-zcu102-revA.dts b/arch/arm/dts/zynqmp-zcu102-revA.dts
index b7c638b..ddc3fba 100644
--- a/arch/arm/dts/zynqmp-zcu102-revA.dts
+++ b/arch/arm/dts/zynqmp-zcu102-revA.dts
@@ -45,8 +45,6 @@
 
 	gpio-keys {
 		compatible = "gpio-keys";
-		#address-cells = <1>;
-		#size-cells = <0>;
 		autorepeat;
 		sw19 {
 			label = "sw19";
diff --git a/arch/arm/dts/zynqmp-zcu106-revA.dts b/arch/arm/dts/zynqmp-zcu106-revA.dts
index bbcd260..a30268b 100644
--- a/arch/arm/dts/zynqmp-zcu106-revA.dts
+++ b/arch/arm/dts/zynqmp-zcu106-revA.dts
@@ -45,8 +45,6 @@
 
 	gpio-keys {
 		compatible = "gpio-keys";
-		#address-cells = <1>;
-		#size-cells = <0>;
 		autorepeat;
 		sw19 {
 			label = "sw19";
diff --git a/arch/arm/dts/zynqmp-zcu111-revA.dts b/arch/arm/dts/zynqmp-zcu111-revA.dts
index aa9055b..6c1a0f7 100644
--- a/arch/arm/dts/zynqmp-zcu111-revA.dts
+++ b/arch/arm/dts/zynqmp-zcu111-revA.dts
@@ -45,8 +45,6 @@
 
 	gpio-keys {
 		compatible = "gpio-keys";
-		#address-cells = <1>;
-		#size-cells = <0>;
 		autorepeat;
 		sw19 {
 			label = "sw19";
diff --git a/arch/arm/mach-bcm283x/reset.c b/arch/arm/mach-bcm283x/reset.c
index f8a1775..7712d46 100644
--- a/arch/arm/mach-bcm283x/reset.c
+++ b/arch/arm/mach-bcm283x/reset.c
@@ -59,13 +59,11 @@
 {
 	u32 val;
 
-	switch (reset_type) {
-	case EFI_RESET_COLD:
-	case EFI_RESET_WARM:
-	case EFI_RESET_PLATFORM_SPECIFIC:
+	if (reset_type == EFI_RESET_COLD ||
+	    reset_type == EFI_RESET_WARM ||
+	    reset_type == EFI_RESET_PLATFORM_SPECIFIC) {
 		reset_cpu(0);
-		break;
-	case EFI_RESET_SHUTDOWN:
+	} else if (reset_type == EFI_RESET_SHUTDOWN) {
 		/*
 		 * We set the watchdog hard reset bit here to distinguish this reset
 		 * from the normal (full) reset. bootcode.bin will not reboot after a
@@ -76,7 +74,6 @@
 		val |= BCM2835_WDOG_RSTS_RASPBERRYPI_HALT;
 		writel(val, &wdog_regs->rsts);
 		reset_cpu(0);
-		break;
 	}
 
 	while (1) { }
diff --git a/board/xilinx/zynq/board.c b/board/xilinx/zynq/board.c
index e4f86d1..1106f5c 100644
--- a/board/xilinx/zynq/board.c
+++ b/board/xilinx/zynq/board.c
@@ -9,6 +9,7 @@
 #include <fdtdec.h>
 #include <fpga.h>
 #include <mmc.h>
+#include <watchdog.h>
 #include <wdt.h>
 #include <zynqpl.h>
 #include <asm/arch/hardware.h>
diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c
index 080fb59..81c10fc 100644
--- a/board/xilinx/zynqmp/zynqmp.c
+++ b/board/xilinx/zynqmp/zynqmp.c
@@ -596,6 +596,8 @@
 
 	new_targets = calloc(1, strlen(mode) + env_targets_len + 2 +
 			     bootseq_len);
+	if (!new_targets)
+		return -ENOMEM;
 
 	if (bootseq >= 0)
 		sprintf(new_targets, "%s%x %s", mode, bootseq,
diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index 707d159..f55a40d 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -263,6 +263,7 @@
 {
 	struct efi_loaded_image loaded_image_info = {};
 	struct efi_object loaded_image_info_obj = {};
+	struct efi_object mem_obj = {};
 	struct efi_device_path *memdp = NULL;
 	efi_status_t ret;
 
@@ -279,6 +280,12 @@
 		/* actual addresses filled in after efi_load_pe() */
 		memdp = efi_dp_from_mem(0, 0, 0);
 		device_path = image_path = memdp;
+		efi_add_handle(&mem_obj);
+
+		ret = efi_add_protocol(mem_obj.handle, &efi_guid_device_path,
+				       device_path);
+		if (ret != EFI_SUCCESS)
+			goto exit;
 	} else {
 		assert(device_path && image_path);
 	}
@@ -343,6 +350,8 @@
 exit:
 	/* image has returned, loaded-image obj goes *poof*: */
 	list_del(&loaded_image_info_obj.link);
+	if (mem_obj.handle)
+		list_del(&mem_obj.link);
 
 	return ret;
 }
diff --git a/configs/xilinx_zynqmp_mini_emmc_defconfig b/configs/xilinx_zynqmp_mini_emmc0_defconfig
similarity index 94%
rename from configs/xilinx_zynqmp_mini_emmc_defconfig
rename to configs/xilinx_zynqmp_mini_emmc0_defconfig
index a1ab39e..ffb9693 100644
--- a/configs/xilinx_zynqmp_mini_emmc_defconfig
+++ b/configs/xilinx_zynqmp_mini_emmc0_defconfig
@@ -3,7 +3,7 @@
 CONFIG_ARCH_ZYNQMP=y
 CONFIG_SYS_TEXT_BASE=0x10000
 # CONFIG_CMD_ZYNQMP is not set
-CONFIG_DEFAULT_DEVICE_TREE="zynqmp-mini-emmc"
+CONFIG_DEFAULT_DEVICE_TREE="zynqmp-mini-emmc0"
 CONFIG_ENV_VARS_UBOOT_CONFIG=y
 CONFIG_FIT=y
 CONFIG_BOOTDELAY=-1
@@ -45,4 +45,5 @@
 # CONFIG_DM_DEVICE_REMOVE is not set
 CONFIG_DM_MMC=y
 CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_ZYNQ=y
 # CONFIG_EFI_LOADER is not set
diff --git a/configs/xilinx_zynqmp_mini_emmc_defconfig b/configs/xilinx_zynqmp_mini_emmc1_defconfig
similarity index 94%
copy from configs/xilinx_zynqmp_mini_emmc_defconfig
copy to configs/xilinx_zynqmp_mini_emmc1_defconfig
index a1ab39e..edca32d 100644
--- a/configs/xilinx_zynqmp_mini_emmc_defconfig
+++ b/configs/xilinx_zynqmp_mini_emmc1_defconfig
@@ -3,7 +3,7 @@
 CONFIG_ARCH_ZYNQMP=y
 CONFIG_SYS_TEXT_BASE=0x10000
 # CONFIG_CMD_ZYNQMP is not set
-CONFIG_DEFAULT_DEVICE_TREE="zynqmp-mini-emmc"
+CONFIG_DEFAULT_DEVICE_TREE="zynqmp-mini-emmc1"
 CONFIG_ENV_VARS_UBOOT_CONFIG=y
 CONFIG_FIT=y
 CONFIG_BOOTDELAY=-1
@@ -45,4 +45,5 @@
 # CONFIG_DM_DEVICE_REMOVE is not set
 CONFIG_DM_MMC=y
 CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_ZYNQ=y
 # CONFIG_EFI_LOADER is not set
diff --git a/configs/xilinx_zynqmp_r5_defconfig b/configs/xilinx_zynqmp_r5_defconfig
index 52b3f75..9e667ff 100644
--- a/configs/xilinx_zynqmp_r5_defconfig
+++ b/configs/xilinx_zynqmp_r5_defconfig
@@ -5,10 +5,12 @@
 CONFIG_DEBUG_UART_CLOCK=100000000
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-r5"
 CONFIG_DEBUG_UART=y
+CONFIG_BOOTSTAGE=y
 # CONFIG_DISPLAY_CPUINFO is not set
 CONFIG_SYS_PROMPT="ZynqMP r5> "
 # CONFIG_CMD_FLASH is not set
 # CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_BOOTSTAGE=y
 CONFIG_OF_EMBED=y
 CONFIG_DEBUG_UART_ZYNQ=y
 CONFIG_ZYNQ_SERIAL=y
diff --git a/configs/xilinx_zynqmp_zcu102_rev1_0_defconfig b/configs/xilinx_zynqmp_zcu102_rev1_0_defconfig
index 9b0f9df..49a14d8 100644
--- a/configs/xilinx_zynqmp_zcu102_rev1_0_defconfig
+++ b/configs/xilinx_zynqmp_zcu102_rev1_0_defconfig
@@ -35,6 +35,7 @@
 CONFIG_CMD_GPT=y
 CONFIG_CMD_I2C=y
 CONFIG_CMD_MMC=y
+CONFIG_CMD_SDRAM=y
 CONFIG_CMD_USB=y
 CONFIG_CMD_TFTPPUT=y
 CONFIG_CMD_TIME=y
diff --git a/configs/xilinx_zynqmp_zcu102_revA_defconfig b/configs/xilinx_zynqmp_zcu102_revA_defconfig
index 8def1c5..05dad41 100644
--- a/configs/xilinx_zynqmp_zcu102_revA_defconfig
+++ b/configs/xilinx_zynqmp_zcu102_revA_defconfig
@@ -34,6 +34,7 @@
 CONFIG_CMD_GPT=y
 CONFIG_CMD_I2C=y
 CONFIG_CMD_MMC=y
+CONFIG_CMD_SDRAM=y
 CONFIG_CMD_USB=y
 CONFIG_CMD_TFTPPUT=y
 CONFIG_CMD_TIME=y
diff --git a/configs/xilinx_zynqmp_zcu102_revB_defconfig b/configs/xilinx_zynqmp_zcu102_revB_defconfig
index 618f1ed..b3711b4 100644
--- a/configs/xilinx_zynqmp_zcu102_revB_defconfig
+++ b/configs/xilinx_zynqmp_zcu102_revB_defconfig
@@ -34,6 +34,7 @@
 CONFIG_CMD_GPT=y
 CONFIG_CMD_I2C=y
 CONFIG_CMD_MMC=y
+CONFIG_CMD_SDRAM=y
 CONFIG_CMD_USB=y
 CONFIG_CMD_TFTPPUT=y
 CONFIG_CMD_TIME=y
diff --git a/disk/part_efi.c b/disk/part_efi.c
index 5c1039f..2945892 100644
--- a/disk/part_efi.c
+++ b/disk/part_efi.c
@@ -23,6 +23,11 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+/*
+ * GUID for basic data partions.
+ */
+static const efi_guid_t partition_basic_data_guid = PARTITION_BASIC_DATA_GUID;
+
 #ifdef CONFIG_HAVE_BLOCK_DEVICE
 /**
  * efi_crc32() - EFI version of crc32 function
@@ -502,12 +507,12 @@
 		} else {
 			/* default partition type GUID */
 			memcpy(bin_type_guid,
-			       &PARTITION_BASIC_DATA_GUID, 16);
+			       &partition_basic_data_guid, 16);
 		}
 #else
 		/* partition type GUID */
 		memcpy(gpt_e[i].partition_type_guid.b,
-			&PARTITION_BASIC_DATA_GUID, 16);
+			&partition_basic_data_guid, 16);
 #endif
 
 #if CONFIG_IS_ENABLED(PARTITION_UUIDS)
diff --git a/drivers/gpio/zynq_gpio.c b/drivers/gpio/zynq_gpio.c
index 9663294..8d84e3f 100644
--- a/drivers/gpio/zynq_gpio.c
+++ b/drivers/gpio/zynq_gpio.c
@@ -111,9 +111,9 @@
 struct zynq_platform_data {
 	const char *label;
 	u16 ngpio;
-	int max_bank;
-	int bank_min[ZYNQMP_GPIO_MAX_BANK];
-	int bank_max[ZYNQMP_GPIO_MAX_BANK];
+	u32 max_bank;
+	u32 bank_min[ZYNQMP_GPIO_MAX_BANK];
+	u32 bank_max[ZYNQMP_GPIO_MAX_BANK];
 };
 
 static const struct zynq_platform_data zynqmp_gpio_def = {
@@ -165,7 +165,7 @@
 					  struct udevice *dev)
 {
 	struct zynq_gpio_privdata *priv = dev_get_priv(dev);
-	int bank;
+	u32 bank;
 
 	for (bank = 0; bank < priv->p_data->max_bank; bank++) {
 		if ((pin_num >= priv->p_data->bank_min[bank]) &&
@@ -188,7 +188,7 @@
 {
 	struct zynq_gpio_privdata *priv = dev_get_priv(dev);
 
-	return (gpio >= 0) && (gpio < priv->p_data->ngpio);
+	return gpio < priv->p_data->ngpio;
 }
 
 static int check_gpio(unsigned gpio, struct udevice *dev)
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index 40e28ab..cdeba91 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -161,8 +161,8 @@
 	/* We shouldn't wait for data inihibit for stop commands, even
 	   though they might use busy signaling */
 	if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION ||
-	    cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK ||
-	    cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK_HS200)
+	    ((cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK ||
+	      cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK_HS200) && !data))
 		mask &= ~SDHCI_DATA_INHIBIT;
 
 	while (sdhci_readl(host, SDHCI_PRESENT_STATE) & mask) {
@@ -184,8 +184,8 @@
 	sdhci_writel(host, SDHCI_INT_ALL_MASK, SDHCI_INT_STATUS);
 
 	mask = SDHCI_INT_RESPONSE;
-	if (cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK ||
-	    cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK_HS200)
+	if ((cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK ||
+	     cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK_HS200) && !data)
 		mask = SDHCI_INT_DATA_AVAIL;
 
 	if (!(cmd->resp_type & MMC_RSP_PRESENT))
diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c
index 5b6d525..b05334d 100644
--- a/drivers/mmc/zynq_sdhci.c
+++ b/drivers/mmc/zynq_sdhci.c
@@ -92,7 +92,7 @@
 	u32 ctrl;
 	struct sdhci_host *host;
 	struct arasan_sdhci_priv *priv = dev_get_priv(mmc->dev);
-	u8 tuning_loop_counter = SDHCI_TUNING_LOOP_COUNT;
+	char tuning_loop_counter = SDHCI_TUNING_LOOP_COUNT;
 	u8 deviceid;
 
 	debug("%s\n", __func__);
diff --git a/drivers/serial/serial_zynq.c b/drivers/serial/serial_zynq.c
index 3650af2..a191772 100644
--- a/drivers/serial/serial_zynq.c
+++ b/drivers/serial/serial_zynq.c
@@ -15,14 +15,16 @@
 #include <linux/compiler.h>
 #include <serial.h>
 
-#define ZYNQ_UART_SR_TXEMPTY	(1 << 3) /* TX FIFO empty */
-#define ZYNQ_UART_SR_TXACTIVE	(1 << 11)  /* TX active */
-#define ZYNQ_UART_SR_RXEMPTY	0x00000002 /* RX FIFO empty */
+DECLARE_GLOBAL_DATA_PTR;
 
-#define ZYNQ_UART_CR_TX_EN	0x00000010 /* TX enabled */
-#define ZYNQ_UART_CR_RX_EN	0x00000004 /* RX enabled */
-#define ZYNQ_UART_CR_TXRST	0x00000002 /* TX logic reset */
-#define ZYNQ_UART_CR_RXRST	0x00000001 /* RX logic reset */
+#define ZYNQ_UART_SR_TXACTIVE	BIT(11) /* TX active */
+#define ZYNQ_UART_SR_TXFULL	BIT(4) /* TX FIFO full */
+#define ZYNQ_UART_SR_RXEMPTY	BIT(1) /* RX FIFO empty */
+
+#define ZYNQ_UART_CR_TX_EN	BIT(4) /* TX enabled */
+#define ZYNQ_UART_CR_RX_EN	BIT(2) /* RX enabled */
+#define ZYNQ_UART_CR_TXRST	BIT(1) /* TX logic reset */
+#define ZYNQ_UART_CR_RXRST	BIT(0) /* RX logic reset */
 
 #define ZYNQ_UART_MR_PARITY_NONE	0x00000020  /* No parity mode */
 
@@ -93,7 +95,7 @@
 
 static int _uart_zynq_serial_putc(struct uart_zynq *regs, const char c)
 {
-	if (!(readl(&regs->channel_sts) & ZYNQ_UART_SR_TXEMPTY))
+	if (readl(&regs->channel_sts) & ZYNQ_UART_SR_TXFULL)
 		return -EAGAIN;
 
 	writel(c, &regs->tx_rx_fifo);
@@ -101,7 +103,7 @@
 	return 0;
 }
 
-int zynq_serial_setbrg(struct udevice *dev, int baudrate)
+static int zynq_serial_setbrg(struct udevice *dev, int baudrate)
 {
 	struct zynq_uart_priv *priv = dev_get_priv(dev);
 	unsigned long clock;
@@ -137,6 +139,10 @@
 {
 	struct zynq_uart_priv *priv = dev_get_priv(dev);
 
+	/* No need to reinitialize the UART after relocation */
+	if (gd->flags & GD_FLG_RELOC)
+		return 0;
+
 	_uart_zynq_serial_init(priv->regs);
 
 	return 0;
diff --git a/drivers/timer/cadence-ttc.c b/drivers/timer/cadence-ttc.c
index 3541e5c..4125a07 100644
--- a/drivers/timer/cadence-ttc.c
+++ b/drivers/timer/cadence-ttc.c
@@ -31,6 +31,28 @@
 	struct cadence_ttc_regs *regs;
 };
 
+#if CONFIG_IS_ENABLED(BOOTSTAGE)
+ulong timer_get_boot_us(void)
+{
+	u64 ticks = 0;
+	u32 rate = 1;
+	u64 us;
+	int ret;
+
+	ret = dm_timer_init();
+	if (!ret) {
+		/* The timer is available */
+		rate = timer_get_rate(gd->timer);
+		timer_get_count(gd->timer, &ticks);
+	} else {
+		return 0;
+	}
+
+	us = (ticks * 1000) / rate;
+	return us;
+}
+#endif
+
 static int cadence_ttc_get_count(struct udevice *dev, u64 *count)
 {
 	struct cadence_ttc_priv *priv = dev_get_priv(dev);
diff --git a/include/configs/xilinx_zynqmp_zcu102.h b/include/configs/xilinx_zynqmp_zcu102.h
index ca11b97..ad6bc3d 100644
--- a/include/configs/xilinx_zynqmp_zcu102.h
+++ b/include/configs/xilinx_zynqmp_zcu102.h
@@ -39,6 +39,9 @@
 #define CONFIG_ZYNQ_EEPROM_BUS		5
 #define CONFIG_ZYNQ_GEM_EEPROM_ADDR	0x54
 
+#define CONFIG_SPD_EEPROM
+#define CONFIG_DDR_SPD
+
 #include <configs/xilinx_zynqmp.h>
 
 #endif /* __CONFIG_ZYNQMP_ZCU102_H */
diff --git a/include/efi.h b/include/efi.h
index 98bddba..e30a3c5 100644
--- a/include/efi.h
+++ b/include/efi.h
@@ -89,12 +89,11 @@
 typedef void *efi_handle_t;
 
 #define EFI_GUID(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) \
-	((efi_guid_t) \
 	{{ (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, \
 		((a) >> 24) & 0xff, \
 		(b) & 0xff, ((b) >> 8) & 0xff, \
 		(c) & 0xff, ((c) >> 8) & 0xff, \
-		(d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) } })
+		(d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) } }
 
 /* Generic EFI table header */
 struct efi_table_hdr {
diff --git a/include/pe.h b/include/pe.h
index d73eb14..36e1908 100644
--- a/include/pe.h
+++ b/include/pe.h
@@ -201,10 +201,13 @@
 #define IMAGE_REL_BASED_MIPS_JMPADDR            5
 #define IMAGE_REL_BASED_ARM_MOV32A              5 /* yes, 5 too */
 #define IMAGE_REL_BASED_ARM_MOV32               5 /* yes, 5 too */
+#define IMAGE_REL_BASED_RISCV_HI20		5 /* yes, 5 too */
 #define IMAGE_REL_BASED_SECTION                 6
 #define IMAGE_REL_BASED_REL                     7
 #define IMAGE_REL_BASED_ARM_MOV32T              7 /* yes, 7 too */
 #define IMAGE_REL_BASED_THUMB_MOV32             7 /* yes, 7 too */
+#define IMAGE_REL_BASED_RISCV_LOW12I		7 /* yes, 7 too */
+#define IMAGE_REL_BASED_RISCV_LOW12S		8
 #define IMAGE_REL_BASED_MIPS_JMPADDR16          9
 #define IMAGE_REL_BASED_IA64_IMM64              9 /* yes, 9 too */
 #define IMAGE_REL_BASED_DIR64                   10
diff --git a/lib/efi_loader/efi_image_loader.c b/lib/efi_loader/efi_image_loader.c
index 3cffe9e..ecdb77e 100644
--- a/lib/efi_loader/efi_image_loader.c
+++ b/lib/efi_loader/efi_image_loader.c
@@ -126,6 +126,20 @@
 			case IMAGE_REL_BASED_DIR64:
 				*x64 += (uint64_t)delta;
 				break;
+#ifdef __riscv
+			case IMAGE_REL_BASED_RISCV_HI20:
+				*x32 = ((*x32 & 0xfffff000) + (uint32_t)delta) |
+					(*x32 & 0x00000fff);
+				break;
+			case IMAGE_REL_BASED_RISCV_LOW12I:
+			case IMAGE_REL_BASED_RISCV_LOW12S:
+				/* We know that we're 4k aligned */
+				if (delta & 0xfff) {
+					printf("Unsupported reloc offset\n");
+					return EFI_LOAD_ERROR;
+				}
+				break;
+#endif
 			default:
 				printf("Unknown Relocation off %x type %x\n",
 				       offset, type);
diff --git a/lib/efi_loader/efi_runtime.c b/lib/efi_loader/efi_runtime.c
index 65f2bcf..4874eb6 100644
--- a/lib/efi_loader/efi_runtime.c
+++ b/lib/efi_loader/efi_runtime.c
@@ -28,6 +28,10 @@
 static efi_status_t __efi_runtime EFIAPI efi_device_error(void);
 static efi_status_t __efi_runtime EFIAPI efi_invalid_parameter(void);
 
+/*
+ * TODO(sjg@chromium.org): These defines and structs should come from the elf
+ * header for each arch (or a generic header) rather than being repeated here.
+ */
 #if defined(CONFIG_ARM64)
 #define R_RELATIVE	1027
 #define R_MASK		0xffffffffULL
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 2a7d734..f8c3fff 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -385,8 +385,14 @@
 
 EFI_LDS_PATH = $(srctree)/arch/$(ARCH)/lib/$(EFI_LDS)
 
-$(obj)/%_efi.so: $(obj)/%.o arch/$(ARCH)/lib/$(EFI_CRT0) \
-		arch/$(ARCH)/lib/$(EFI_RELOC)
+$(obj)/efi_crt0.o: $(srctree)/arch/$(ARCH)/lib/$(EFI_CRT0:.o=.S)
+	$(call if_changed_dep,as_o_S)
+
+$(obj)/efi_reloc.o: $(srctree)/arch/$(ARCH)/lib/$(EFI_RELOC:.o=.c) $(recordmcount_source) FORCE
+	$(call cmd,force_checksrc)
+	$(call if_changed_rule,cc_o_c)
+
+$(obj)/%_efi.so: $(obj)/%.o $(obj)/efi_crt0.o $(obj)/efi_reloc.o
 	$(call cmd,efi_ld)
 
 # ACPI
diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl
index ef018b5..252f138 100644
--- a/scripts/Makefile.spl
+++ b/scripts/Makefile.spl
@@ -167,8 +167,14 @@
 MKIMAGEFLAGS_boot.bin = -T zynqimage -R $(srctree)/$(CONFIG_BOOT_INIT_FILE)
 endif
 ifdef CONFIG_ARCH_ZYNQMP
+ifneq ($(CONFIG_PMUFW_INIT_FILE),"")
+spl/boot.bin: zynqmp-check-pmufw
+zynqmp-check-pmufw: FORCE
+	( cd $(srctree) && test -r $(CONFIG_PMUFW_INIT_FILE) ) \
+		|| ( echo "Cannot read $(CONFIG_PMUFW_INIT_FILE)" && false )
+endif
 MKIMAGEFLAGS_boot.bin = -T zynqmpimage -R $(srctree)/$(CONFIG_BOOT_INIT_FILE) \
-	-n $(srctree)/$(CONFIG_PMUFW_INIT_FILE)
+	-n "$(shell cd $(srctree); readlink -f $(CONFIG_PMUFW_INIT_FILE))"
 endif
 
 spl/boot.bin: $(obj)/u-boot-spl.bin FORCE