Просмотр исходного кода

Merge tag 'xilinx-for-v2020.10-rc3' of https://gitlab.denx.de/u-boot/custodians/u-boot-microblaze

Xilinx changes for v2020.10-rc3

- Fix fdtfile variable setup
- Fix bootm_*/fdt_high/initrd_high variables handling
- Fix Kconfig dependencies for Xilinx drivers
- Fix booting u-boot from lowest memory
- Fix firmware payload argument count for Versal
- Fix dfu configurations
- Fix mio_bank property handling
- Fix and align code around ID detection
- Start to use ENV_VARS_UBOOT_RUNTIME_CONFIG
- Simplify logic around reading MAC from eeprom
- Decrease malloc length for zynqmp mini qspi
- Enable preboot for ZynqMP and Versal

i2c:
- Fix i2c eeprom partitions handling

mmc:
- Fix logic around HS mode enabling and use proper functions
Tom Rini 3 лет назад
Родитель
Сommit
2e6132d835
57 измененных файлов с 457 добавлено и 241 удалено
  1. 4 0
      arch/arm/Kconfig
  2. 1 1
      arch/arm/dts/avnet-ultrazedev-cc-v1.0-ultrazedev-som-v1.0.dts
  3. 1 1
      arch/arm/dts/avnet-ultrazedev-som-v1.0.dtsi
  4. 6 6
      arch/arm/dts/imx53-ppd-uboot.dtsi
  5. 5 5
      arch/arm/dts/imx6q-bx50v3-uboot.dtsi
  6. 1 1
      arch/arm/dts/versal-mini-emmc0.dts
  7. 1 1
      arch/arm/dts/versal-mini-emmc1.dts
  8. 1 1
      arch/arm/dts/zynqmp-e-a2197-00-revA.dts
  9. 1 1
      arch/arm/dts/zynqmp-g-a2197-00-revA.dts
  10. 2 2
      arch/arm/dts/zynqmp-m-a2197-01-revA.dts
  11. 2 2
      arch/arm/dts/zynqmp-m-a2197-02-revA.dts
  12. 2 2
      arch/arm/dts/zynqmp-m-a2197-03-revA.dts
  13. 2 2
      arch/arm/dts/zynqmp-p-a2197-00-revA.dts
  14. 2 2
      arch/arm/dts/zynqmp-topic-miamimp-xilinx-xdp-v1r1.dts
  15. 2 2
      arch/arm/dts/zynqmp-zc1751-xm015-dc1.dts
  16. 2 2
      arch/arm/dts/zynqmp-zcu100-revC.dts
  17. 1 1
      arch/arm/dts/zynqmp-zcu102-revA.dts
  18. 1 1
      arch/arm/dts/zynqmp-zcu104-revA.dts
  19. 1 1
      arch/arm/dts/zynqmp-zcu104-revC.dts
  20. 1 1
      arch/arm/dts/zynqmp-zcu106-revA.dts
  21. 1 1
      arch/arm/dts/zynqmp-zcu111-revA.dts
  22. 1 1
      arch/arm/dts/zynqmp-zcu1275-revB.dts
  23. 1 1
      arch/arm/dts/zynqmp-zcu1285-revA.dts
  24. 1 1
      arch/arm/dts/zynqmp-zcu208-revA.dts
  25. 1 1
      arch/arm/dts/zynqmp-zcu216-revA.dts
  26. 0 2
      arch/arm/mach-versal/include/mach/sys_proto.h
  27. 0 3
      arch/arm/mach-zynqmp/include/mach/sys_proto.h
  28. 13 0
      arch/sandbox/dts/test.dts
  29. 13 8
      board/xilinx/common/board.c
  30. 14 0
      board/xilinx/versal/Kconfig
  31. 1 0
      board/xilinx/versal/Makefile
  32. 4 1
      board/xilinx/versal/board.c
  33. 105 0
      board/xilinx/versal/cmds.c
  34. 9 0
      board/xilinx/zynq/board.c
  35. 41 75
      board/xilinx/zynqmp/zynqmp.c
  36. 1 0
      configs/sandbox_defconfig
  37. 4 0
      configs/xilinx_versal_virt_defconfig
  38. 2 0
      configs/xilinx_zynqmp_virt_defconfig
  39. 0 17
      drivers/clk/clk_versal.c
  40. 43 41
      drivers/firmware/firmware-zynqmp.c
  41. 1 1
      drivers/fpga/versalpl.c
  42. 2 2
      drivers/gpio/Kconfig
  43. 1 1
      drivers/i2c/Kconfig
  44. 10 4
      drivers/mailbox/zynqmp-ipi.c
  45. 8 7
      drivers/misc/i2c_eeprom.c
  46. 0 1
      drivers/mmc/Kconfig
  47. 8 5
      drivers/mmc/sdhci.c
  48. 1 1
      drivers/mmc/zynq_sdhci.c
  49. 3 3
      drivers/net/Kconfig
  50. 1 2
      include/configs/xilinx_versal.h
  51. 7 4
      include/configs/xilinx_zynqmp.h
  52. 1 1
      include/configs/xilinx_zynqmp_mini_qspi.h
  53. 0 1
      include/configs/zynq-common.h
  54. 17 0
      include/fdtdec.h
  55. 26 0
      include/zynqmp_firmware.h
  56. 69 21
      lib/fdtdec.c
  57. 8 0
      test/dm/bootcount.c

+ 4 - 0
arch/arm/Kconfig

@@ -1085,6 +1085,7 @@ config ARCH_VERSAL
 	select DM_SERIAL
 	select OF_CONTROL
 	imply BOARD_LATE_INIT
+	imply ENV_VARS_UBOOT_RUNTIME_CONFIG
 
 config ARCH_VF610
 	bool "Freescale Vybrid"
@@ -1120,6 +1121,7 @@ config ARCH_ZYNQ
 	imply CMD_CLK
 	imply CMD_DM
 	imply CMD_SPL
+	imply ENV_VARS_UBOOT_RUNTIME_CONFIG
 	imply FAT_WRITE
 
 config ARCH_ZYNQMP_R5
@@ -1159,6 +1161,7 @@ config ARCH_ZYNQMP
 	select ZYNQMP_IPI
 	imply BOARD_LATE_INIT
 	imply CMD_DM
+	imply ENV_VARS_UBOOT_RUNTIME_CONFIG
 	imply FAT_WRITE
 	imply MP
 	imply DM_USB_GADGET
@@ -1962,6 +1965,7 @@ source "board/vscom/baltos/Kconfig"
 source "board/xilinx/Kconfig"
 source "board/xilinx/zynq/Kconfig"
 source "board/xilinx/zynqmp/Kconfig"
+source "board/xilinx/versal/Kconfig"
 source "board/phytium/durian/Kconfig"
 source "board/xen/xenguest_arm64/Kconfig"
 

+ 1 - 1
arch/arm/dts/avnet-ultrazedev-cc-v1.0-ultrazedev-som-v1.0.dts

@@ -51,7 +51,7 @@
 /* microSD card slot */
 &sdhci1 {
 	status = "okay";
-	xlnx,mio_bank = <1>;
+	xlnx,mio-bank = <1>;
 	clock-frequency = <199998000>;
 	max-frequency = <50000000>;
 	no-1-8-v;

+ 1 - 1
arch/arm/dts/avnet-ultrazedev-som-v1.0.dtsi

@@ -51,6 +51,6 @@
 /* Micron MTFC8GAKAJCN-4M 8 GB eMMC */
 &sdhci0 {
 	status = "okay";
-	xlnx,mio_bank = <0>;
+	xlnx,mio-bank = <0>;
 	clock-frequency = <199998000>;
 };

+ 6 - 6
arch/arm/dts/imx53-ppd-uboot.dtsi

@@ -24,15 +24,15 @@
 &eeprom {
 	partitions {
 		compatible = "fixed-partitions";
+		#address-cells = <1>;
+		#size-cells = <1>;
 
-		vpd {
-			offset = <0>;
-			size = <1022>;
+		vpd@0 {
+			reg = <0 1022>;
 		};
 
-		bootcount: bootcount {
-			offset = <1022>;
-			size = <2>;
+		bootcount: bootcount@1022 {
+			reg = <1022 2>;
 		};
 	};
 };

+ 5 - 5
arch/arm/dts/imx6q-bx50v3-uboot.dtsi

@@ -23,15 +23,15 @@
 &eeprom {
 	partitions {
 		compatible = "fixed-partitions";
+		#address-cells = <1>;
+		#size-cells = <1>;
 
-		vpd {
-			offset = <0>;
-			size = <1022>;
+		vpd@0 {
+			reg = <0 1022>;
 		};
 
 		bootcount: bootcount {
-			offset = <1022>;
-			size = <2>;
+			reg = <1022 2>;
 		};
 	};
 };

+ 1 - 1
arch/arm/dts/versal-mini-emmc0.dts

@@ -43,7 +43,7 @@
 			clocks = <&clk25 &clk25>;
 			xlnx,device_id = <0>;
 			no-1-8-v;
-			xlnx,mio_bank = <0>;
+			xlnx,mio-bank = <0>;
 			#stream-id-cells = <1>;
 		};
 	};

+ 1 - 1
arch/arm/dts/versal-mini-emmc1.dts

@@ -43,7 +43,7 @@
 			clocks = <&clk25 &clk25>;
 			xlnx,device_id = <1>;
 			no-1-8-v;
-			xlnx,mio_bank = <0>;
+			xlnx,mio-bank = <0>;
 			#stream-id-cells = <1>;
 		};
 	};

+ 1 - 1
arch/arm/dts/zynqmp-e-a2197-00-revA.dts

@@ -131,7 +131,7 @@
 	status = "okay";
 	no-1-8-v;
 	disable-wp;
-	xlnx,mio_bank = <1>;
+	xlnx,mio-bank = <1>;
 };
 
 &gem0 {

+ 1 - 1
arch/arm/dts/zynqmp-g-a2197-00-revA.dts

@@ -70,7 +70,7 @@
 	non-removable;
 	disable-wp;
 	bus-width = <8>;
-	xlnx,mio_bank = <0>;
+	xlnx,mio-bank = <0>;
 };
 
 &uart0 { /* uart0 MIO38-39 */

+ 2 - 2
arch/arm/dts/zynqmp-m-a2197-01-revA.dts

@@ -89,7 +89,7 @@
 	non-removable;
 	disable-wp;
 	bus-width = <8>;
-	xlnx,mio_bank = <0>; /* FIXME tap delay */
+	xlnx,mio-bank = <0>; /* FIXME tap delay */
 };
 
 &uart0 { /* uart0 MIO38-39 */
@@ -106,7 +106,7 @@
 	status = "disable";
 	no-1-8-v;
 	disable-wp;
-	xlnx,mio_bank = <1>;
+	xlnx,mio-bank = <1>;
 };
 
 &gem0 {

+ 2 - 2
arch/arm/dts/zynqmp-m-a2197-02-revA.dts

@@ -85,7 +85,7 @@
 	non-removable;
 	disable-wp;
 	bus-width = <8>;
-	xlnx,mio_bank = <0>; /* FIXME tap delay */
+	xlnx,mio-bank = <0>; /* FIXME tap delay */
 };
 
 &uart0 { /* uart0 MIO38-39 */
@@ -102,7 +102,7 @@
 	status = "disable";
 	no-1-8-v;
 	disable-wp;
-	xlnx,mio_bank = <1>;
+	xlnx,mio-bank = <1>;
 };
 
 &gem0 {

+ 2 - 2
arch/arm/dts/zynqmp-m-a2197-03-revA.dts

@@ -85,7 +85,7 @@
 	non-removable;
 	disable-wp;
 	bus-width = <8>;
-	xlnx,mio_bank = <0>; /* FIXME tap delay */
+	xlnx,mio-bank = <0>; /* FIXME tap delay */
 };
 
 &uart0 { /* uart0 MIO38-39 */
@@ -102,7 +102,7 @@
 	status = "disable";
 	no-1-8-v;
 	disable-wp;
-	xlnx,mio_bank = <1>;
+	xlnx,mio-bank = <1>;
 };
 
 &gem0 {

+ 2 - 2
arch/arm/dts/zynqmp-p-a2197-00-revA.dts

@@ -50,7 +50,7 @@
 	non-removable;
 	disable-wp;
 	bus-width = <8>;
-	xlnx,mio_bank = <0>;
+	xlnx,mio-bank = <0>;
 };
 
 &uart0 { /* uart0 MIO38-39 */
@@ -67,7 +67,7 @@
 	status = "okay";
 	no-1-8-v;
 	disable-wp;
-	xlnx,mio_bank = <1>;
+	xlnx,mio-bank = <1>;
 };
 
 &gem0 {

+ 2 - 2
arch/arm/dts/zynqmp-topic-miamimp-xilinx-xdp-v1r1.dts

@@ -97,13 +97,13 @@
 	non-removable;
 	disable-wp; /* We don't have a write-protect detection */
 	bus-width = <8>;
-	xlnx,mio_bank = <0>;
+	xlnx,mio-bank = <0>;
 };
 
 /* SD1 with level shifter */
 &sdhci1 {
 	status = "okay";
-	xlnx,mio_bank = <1>;
+	xlnx,mio-bank = <1>;
 	disable-wp; /* We don't have a write-protect detection */
 	bus-width = <4>;
 };

+ 2 - 2
arch/arm/dts/zynqmp-zc1751-xm015-dc1.dts

@@ -148,7 +148,7 @@
 &sdhci0 {
 	status = "okay";
 	bus-width = <8>;
-	xlnx,mio_bank = <0>;
+	xlnx,mio-bank = <0>;
 };
 
 /* SD1 with level shifter */
@@ -158,7 +158,7 @@
 	 * This property should be removed for supporting UHS mode
 	 */
 	no-1-8-v;
-	xlnx,mio_bank = <1>;
+	xlnx,mio-bank = <1>;
 };
 
 &uart0 {

+ 2 - 2
arch/arm/dts/zynqmp-zcu100-revC.dts

@@ -259,13 +259,13 @@
 	status = "okay";
 	no-1-8-v;
 	disable-wp;
-	xlnx,mio_bank = <0>;
+	xlnx,mio-bank = <0>;
 };
 
 &sdhci1 {
 	status = "okay";
 	bus-width = <0x4>;
-	xlnx,mio_bank = <0>;
+	xlnx,mio-bank = <0>;
 	non-removable;
 	disable-wp;
 	cap-power-off-card;

+ 1 - 1
arch/arm/dts/zynqmp-zcu102-revA.dts

@@ -660,7 +660,7 @@
 	 * removed for supporting UHS mode
 	 */
 	no-1-8-v;
-	xlnx,mio_bank = <1>;
+	xlnx,mio-bank = <1>;
 };
 
 &serdes {

+ 1 - 1
arch/arm/dts/zynqmp-zcu104-revA.dts

@@ -249,7 +249,7 @@
 &sdhci1 {
 	status = "okay";
 	no-1-8-v;
-	xlnx,mio_bank = <1>;
+	xlnx,mio-bank = <1>;
 	disable-wp;
 };
 

+ 1 - 1
arch/arm/dts/zynqmp-zcu104-revC.dts

@@ -262,7 +262,7 @@
 &sdhci1 {
 	status = "okay";
 	no-1-8-v;
-	xlnx,mio_bank = <1>;
+	xlnx,mio-bank = <1>;
 	disable-wp;
 };
 

+ 1 - 1
arch/arm/dts/zynqmp-zcu106-revA.dts

@@ -657,7 +657,7 @@
 	 * This property should be removed for supporting UHS mode
 	 */
 	no-1-8-v;
-	xlnx,mio_bank = <1>;
+	xlnx,mio-bank = <1>;
 };
 
 &serdes {

+ 1 - 1
arch/arm/dts/zynqmp-zcu111-revA.dts

@@ -568,7 +568,7 @@
 	 * This property should be removed for supporting UHS mode
 	 */
 	no-1-8-v;
-	xlnx,mio_bank = <1>;
+	xlnx,mio-bank = <1>;
 };
 
 &serdes {

+ 1 - 1
arch/arm/dts/zynqmp-zcu1275-revB.dts

@@ -80,5 +80,5 @@
 	 * removed for supporting UHS mode
 	 */
 	no-1-8-v;
-	xlnx,mio_bank = <1>;
+	xlnx,mio-bank = <1>;
 };

+ 1 - 1
arch/arm/dts/zynqmp-zcu1285-revA.dts

@@ -245,5 +245,5 @@
 	 * This property should be removed for supporting UHS mode
 	 */
 	no-1-8-v;
-	xlnx,mio_bank = <1>;
+	xlnx,mio-bank = <1>;
 };

+ 1 - 1
arch/arm/dts/zynqmp-zcu208-revA.dts

@@ -565,7 +565,7 @@
 	 * This property should be removed for supporting UHS mode
 	 */
 	no-1-8-v;
-	xlnx,mio_bank = <1>;
+	xlnx,mio-bank = <1>;
 };
 
 &serdes {

+ 1 - 1
arch/arm/dts/zynqmp-zcu216-revA.dts

@@ -569,7 +569,7 @@
 	 * This property should be removed for supporting UHS mode
 	 */
 	no-1-8-v;
-	xlnx,mio_bank = <1>;
+	xlnx,mio-bank = <1>;
 };
 
 &serdes {

+ 0 - 2
arch/arm/mach-versal/include/mach/sys_proto.h

@@ -8,7 +8,5 @@ enum {
 	TCM_SPLIT,
 };
 
-#define PAYLOAD_ARG_CNT	4U
-
 void tcm_init(u8 mode);
 void mem_map_fill(void);

+ 0 - 3
arch/arm/mach-zynqmp/include/mach/sys_proto.h

@@ -7,8 +7,6 @@
 #ifndef _ASM_ARCH_SYS_PROTO_H
 #define _ASM_ARCH_SYS_PROTO_H
 
-#define PAYLOAD_ARG_CNT		5
-
 #define ZYNQMP_CSU_SILICON_VER_MASK	0xF
 #define KEY_PTR_LEN	32
 
@@ -51,7 +49,6 @@ int zynqmp_mmio_read(const u32 address, u32 *value);
 
 void initialize_tcm(bool mode);
 void mem_map_fill(void);
-int chip_id(unsigned char id);
 #if defined(CONFIG_SYS_MEM_RSVD_FOR_MMU) || defined(CONFIG_DEFINE_TCM_OCM_MMAP)
 void tcm_init(u8 mode);
 #endif

+ 13 - 0
arch/sandbox/dts/test.dts

@@ -415,6 +415,14 @@
 			reg = <0x2c>;
 			compatible = "i2c-eeprom";
 			sandbox,emul = <&emul_eeprom>;
+			partitions {
+				compatible = "fixed-partitions";
+				#address-cells = <1>;
+				#size-cells = <1>;
+				bootcount_i2c: bootcount@10 {
+					reg = <10 2>;
+				};
+			};
 		};
 
 		rtc_0: rtc@43 {
@@ -462,6 +470,11 @@
 		offset = <0x13>;
 	};
 
+	bootcount {
+		compatible = "u-boot,bootcount-i2c-eeprom";
+		i2c-eeprom = <&bootcount_i2c>;
+	};
+
 	adc@0 {
 		compatible = "sandbox,adc";
 		vdd-supply = <&buck2>;

+ 13 - 8
board/xilinx/common/board.c

@@ -13,11 +13,10 @@
 #include <linux/sizes.h>
 #include "board.h"
 
+#if defined(CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET)
 int zynq_board_read_rom_ethaddr(unsigned char *ethaddr)
 {
 	int ret = -EINVAL;
-
-#if defined(CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET)
 	struct udevice *dev;
 	ofnode eeprom;
 
@@ -37,10 +36,10 @@ int zynq_board_read_rom_ethaddr(unsigned char *ethaddr)
 		debug("%s: I2C EEPROM MAC address read failed\n", __func__);
 	else
 		debug("%s: I2C EEPROM MAC %pM\n", __func__, ethaddr);
-#endif
 
 	return ret;
 }
+#endif
 
 #if defined(CONFIG_OF_BOARD) || defined(CONFIG_OF_SEPARATE)
 void *board_fdt_blob_setup(void)
@@ -78,13 +77,19 @@ void *board_fdt_blob_setup(void)
 
 int board_late_init_xilinx(void)
 {
-	ulong initrd_hi;
+	u32 ret = 0;
+	phys_size_t bootm_size = gd->ram_size;
+
+	if (CONFIG_IS_ENABLED(ARCH_ZYNQ))
+		bootm_size = min(bootm_size, (phys_size_t)(SZ_512M + SZ_256M));
 
-	env_set_hex("script_offset_f", CONFIG_BOOT_SCRIPT_OFFSET);
+	ret |= env_set_hex("script_offset_f", CONFIG_BOOT_SCRIPT_OFFSET);
 
-	initrd_hi = gd->start_addr_sp - CONFIG_STACK_SIZE;
-	initrd_hi = round_down(initrd_hi, SZ_16M);
-	env_set_addr("initrd_high", (void *)initrd_hi);
+	ret |= env_set_addr("bootm_low", (void *)gd->ram_base);
+	ret |= env_set_addr("bootm_size", (void *)bootm_size);
+
+	if (ret)
+		printf("%s: Saving run time variables FAILED\n", __func__);
 
 	return 0;
 }

+ 14 - 0
board/xilinx/versal/Kconfig

@@ -0,0 +1,14 @@
+# Copyright (c) 2020, Xilinx, Inc.
+#
+# SPDX-License-Identifier: GPL-2.0
+
+if ARCH_VERSAL
+
+config CMD_VERSAL
+	bool "Enable Versal specific commands"
+	default y
+	depends on ZYNQMP_FIRMWARE
+	help
+	  Enable Versal specific commands.
+
+endif

+ 1 - 0
board/xilinx/versal/Makefile

@@ -5,4 +5,5 @@
 #
 
 obj-y	:= board.o
+obj-$(CONFIG_CMD_VERSAL)	+= cmds.o
 obj-y	+= ../common/board.o

+ 4 - 1
board/xilinx/versal/board.c

@@ -116,6 +116,9 @@ int board_late_init(void)
 		return 0;
 	}
 
+	if (!CONFIG_IS_ENABLED(ENV_VARS_UBOOT_RUNTIME_CONFIG))
+		return 0;
+
 	bootmode = versal_get_bootmode();
 
 	puts("Bootmode: ");
@@ -229,7 +232,7 @@ int dram_init_banksize(void)
 
 int dram_init(void)
 {
-	if (fdtdec_setup_mem_size_base() != 0)
+	if (fdtdec_setup_mem_size_base_lowest() != 0)
 		return -EINVAL;
 
 	return 0;

+ 105 - 0
board/xilinx/versal/cmds.c

@@ -0,0 +1,105 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * (C) Copyright 2020 Xilinx, Inc.
+ * Michal Simek <michal.simek@xilinx.com>
+ */
+
+#include <cpu_func.h>
+#include <command.h>
+#include <common.h>
+#include <log.h>
+#include <memalign.h>
+#include <versalpl.h>
+#include <zynqmp_firmware.h>
+
+static int do_versal_load_pdi(struct cmd_tbl *cmdtp, int flag, int argc,
+			      char * const argv[])
+{
+	u32 buf_lo, buf_hi;
+	u32 ret_payload[PAYLOAD_ARG_CNT];
+	ulong addr, *pdi_buf;
+	size_t len;
+	int ret;
+
+	if (argc != cmdtp->maxargs) {
+		debug("pdi_load: incorrect parameters passed\n");
+		return CMD_RET_USAGE;
+	}
+
+	addr = simple_strtol(argv[2], NULL, 16);
+	if (!addr) {
+		debug("pdi_load: zero pdi_data address\n");
+		return CMD_RET_USAGE;
+	}
+
+	len = simple_strtoul(argv[3], NULL, 16);
+	if (!len) {
+		debug("pdi_load: zero size\n");
+		return CMD_RET_USAGE;
+	}
+
+	pdi_buf = (ulong *)ALIGN((ulong)addr, ARCH_DMA_MINALIGN);
+	if ((ulong)addr != (ulong)pdi_buf) {
+		memcpy((void *)pdi_buf, (void *)addr, len);
+		debug("Pdi addr:0x%lx aligned to 0x%lx\n",
+		      addr, (ulong)pdi_buf);
+	}
+
+	flush_dcache_range((ulong)pdi_buf, (ulong)pdi_buf + len);
+
+	buf_lo = lower_32_bits((ulong)pdi_buf);
+	buf_hi = upper_32_bits((ulong)pdi_buf);
+
+	ret = xilinx_pm_request(VERSAL_PM_LOAD_PDI, VERSAL_PM_PDI_TYPE, buf_lo,
+				buf_hi, 0, ret_payload);
+	if (ret)
+		printf("PDI load failed with err: 0x%08x\n", ret);
+
+	return ret;
+}
+
+static struct cmd_tbl cmd_versal_sub[] = {
+	U_BOOT_CMD_MKENT(loadpdi, 4, 1, do_versal_load_pdi, "", ""),
+};
+
+/**
+ * do_versal - Handle the "versal" command-line command
+ * @cmdtp:      Command data struct pointer
+ * @flag:       Command flag
+ * @argc:       Command-line argument count
+ * @argv:       Array of command-line arguments
+ *
+ * Processes the versal specific commands
+ *
+ * Return: return 0 on success, Error value if command fails.
+ * CMD_RET_USAGE incase of incorrect/missing parameters.
+ */
+static int do_versal(struct cmd_tbl *cmdtp, int flag, int argc,
+		     char *const argv[])
+{
+	struct cmd_tbl *c;
+	int ret = CMD_RET_USAGE;
+
+	if (argc < 2)
+		return CMD_RET_USAGE;
+
+	c = find_cmd_tbl(argv[1], &cmd_versal_sub[0],
+			 ARRAY_SIZE(cmd_versal_sub));
+	if (c)
+		ret = c->cmd(c, flag, argc, argv);
+
+	return cmd_process_error(c, ret);
+}
+
+#ifdef CONFIG_SYS_LONGHELP
+static char versal_help_text[] =
+	"loadpdi addr len - Load pdi image\n"
+	"load pdi image at ddr address 'addr' with pdi image size 'len'\n"
+;
+#endif
+
+U_BOOT_CMD(versal, 4, 1, do_versal,
+	   "versal sub-system",
+	   versal_help_text
+)
+

+ 9 - 0
board/xilinx/zynq/board.c

@@ -6,6 +6,7 @@
 
 #include <common.h>
 #include <init.h>
+#include <log.h>
 #include <dm/uclass.h>
 #include <env.h>
 #include <fdtdec.h>
@@ -33,6 +34,14 @@ int board_late_init(void)
 	char *new_targets;
 	char *env_targets;
 
+	if (!(gd->flags & GD_FLG_ENV_DEFAULT)) {
+		debug("Saved variables - Skipping\n");
+		return 0;
+	}
+
+	if (!CONFIG_IS_ENABLED(ENV_VARS_UBOOT_RUNTIME_CONFIG))
+		return 0;
+
 	switch ((zynq_slcr_get_boot_mode()) & ZYNQ_BM_MASK) {
 	case ZYNQ_BM_QSPI:
 		mode = "qspi";

+ 41 - 75
board/xilinx/zynqmp/zynqmp.c

@@ -197,67 +197,6 @@ static const struct {
 };
 #endif
 
-int chip_id(unsigned char id)
-{
-	struct pt_regs regs;
-	int val = -EINVAL;
-
-	if (current_el() != 3) {
-		regs.regs[0] = ZYNQMP_SIP_SVC_CSU_DMA_CHIPID;
-		regs.regs[1] = 0;
-		regs.regs[2] = 0;
-		regs.regs[3] = 0;
-
-		smc_call(&regs);
-
-		/*
-		 * SMC returns:
-		 * regs[0][31:0]  = status of the operation
-		 * regs[0][63:32] = CSU.IDCODE register
-		 * regs[1][31:0]  = CSU.version register
-		 * regs[1][63:32] = CSU.IDCODE2 register
-		 */
-		switch (id) {
-		case IDCODE:
-			regs.regs[0] = upper_32_bits(regs.regs[0]);
-			regs.regs[0] &= ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK |
-					ZYNQMP_CSU_IDCODE_SVD_MASK;
-			regs.regs[0] >>= ZYNQMP_CSU_IDCODE_SVD_SHIFT;
-			val = regs.regs[0];
-			break;
-		case VERSION:
-			regs.regs[1] = lower_32_bits(regs.regs[1]);
-			regs.regs[1] &= ZYNQMP_CSU_SILICON_VER_MASK;
-			val = regs.regs[1];
-			break;
-		case IDCODE2:
-			regs.regs[1] = lower_32_bits(regs.regs[1]);
-			regs.regs[1] >>= ZYNQMP_CSU_VERSION_EMPTY_SHIFT;
-			val = regs.regs[1];
-			break;
-		default:
-			printf("%s, Invalid Req:0x%x\n", __func__, id);
-		}
-	} else {
-		switch (id) {
-		case IDCODE:
-			val = readl(ZYNQMP_CSU_IDCODE_ADDR);
-			val &= ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK |
-			       ZYNQMP_CSU_IDCODE_SVD_MASK;
-			val >>= ZYNQMP_CSU_IDCODE_SVD_SHIFT;
-			break;
-		case VERSION:
-			val = readl(ZYNQMP_CSU_VER_ADDR);
-			val &= ZYNQMP_CSU_SILICON_VER_MASK;
-			break;
-		default:
-			printf("%s, Invalid Req:0x%x\n", __func__, id);
-		}
-	}
-
-	return val;
-}
-
 #define ZYNQMP_VERSION_SIZE		9
 #define ZYNQMP_PL_STATUS_BIT		9
 #define ZYNQMP_IPDIS_VCU_BIT		8
@@ -274,9 +213,28 @@ static char *zynqmp_get_silicon_idcode_name(void)
 	u32 i, id, ver, j;
 	char *buf;
 	static char name[ZYNQMP_VERSION_SIZE];
+	u32 ret_payload[PAYLOAD_ARG_CNT];
+
+	xilinx_pm_request(PM_GET_CHIPID, 0, 0, 0, 0, ret_payload);
+
+	/*
+	 * Firmware returns:
+	 * payload[0][31:0]  = status of the operation
+	 * payload[1]] = IDCODE
+	 * payload[2][19:0]  = Version
+	 * payload[2][28:20] = EXTENDED_IDCODE
+	 * payload[2][29] = PL_INIT
+	 */
+
+	/* Get IDCODE field */
+	id = ret_payload[1];
+	id &= ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK | ZYNQMP_CSU_IDCODE_SVD_MASK;
+	id >>=	ZYNQMP_CSU_IDCODE_SVD_SHIFT;
 
-	id = chip_id(IDCODE);
-	ver = chip_id(IDCODE2);
+	/* Shift silicon version info */
+	ver = ret_payload[2] >> ZYNQMP_CSU_VERSION_EMPTY_SHIFT;
+
+	debug("%s, ID: 0x%0X, Ver: 0x%0X\r\n", __func__, id, ver);
 
 	for (i = 0; i < ARRAY_SIZE(zynqmp_devices); i++) {
 		if (zynqmp_devices[i].id == id) {
@@ -387,12 +345,10 @@ int board_init(void)
 #if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \
     !defined(CONFIG_SPL_BUILD) || (defined(CONFIG_SPL_FPGA_SUPPORT) && \
     defined(CONFIG_SPL_BUILD))
-	if (current_el() != 3) {
-		zynqmppl.name = zynqmp_get_silicon_idcode_name();
-		printf("Chip ID:\t%s\n", zynqmppl.name);
-		fpga_init();
-		fpga_add(fpga_xilinx, &zynqmppl);
-	}
+	zynqmppl.name = zynqmp_get_silicon_idcode_name();
+	printf("Chip ID:\t%s\n", zynqmppl.name);
+	fpga_init();
+	fpga_add(fpga_xilinx, &zynqmppl);
 #endif
 
 	if (current_el() == 3)
@@ -541,23 +497,30 @@ static int set_fdtfile(void)
 	char *compatible, *fdtfile;
 	const char *suffix = ".dtb";
 	const char *vendor = "xilinx/";
+	int fdt_compat_len;
 
 	if (env_get("fdtfile"))
 		return 0;
 
-	compatible = (char *)fdt_getprop(gd->fdt_blob, 0, "compatible", NULL);
-	if (compatible) {
+	compatible = (char *)fdt_getprop(gd->fdt_blob, 0, "compatible",
+					 &fdt_compat_len);
+	if (compatible && fdt_compat_len) {
+		char *name;
+
 		debug("Compatible: %s\n", compatible);
 
-		/* Discard vendor prefix */
-		strsep(&compatible, ",");
+		name = strchr(compatible, ',');
+		if (!name)
+			return -EINVAL;
 
-		fdtfile = calloc(1, strlen(vendor) + strlen(compatible) +
+		name++;
+
+		fdtfile = calloc(1, strlen(vendor) + strlen(name) +
 				 strlen(suffix) + 1);
 		if (!fdtfile)
 			return -ENOMEM;
 
-		sprintf(fdtfile, "%s%s%s", vendor, compatible, suffix);
+		sprintf(fdtfile, "%s%s%s", vendor, name, suffix);
 
 		env_set("fdtfile", fdtfile);
 		free(fdtfile);
@@ -605,6 +568,9 @@ int board_late_init(void)
 		return 0;
 	}
 
+	if (!CONFIG_IS_ENABLED(ENV_VARS_UBOOT_RUNTIME_CONFIG))
+		return 0;
+
 	ret = set_fdtfile();
 	if (ret)
 		return ret;

+ 1 - 0
configs/sandbox_defconfig

@@ -119,6 +119,7 @@ CONFIG_DM_BOOTCOUNT=y
 CONFIG_DM_BOOTCOUNT_RTC=y
 CONFIG_BUTTON=y
 CONFIG_BUTTON_GPIO=y
+CONFIG_DM_BOOTCOUNT_I2C_EEPROM=y
 CONFIG_CLK=y
 CONFIG_CLK_COMPOSITE_CCF=y
 CONFIG_SANDBOX_CLK_CCF=y

+ 4 - 0
configs/xilinx_versal_virt_defconfig

@@ -9,6 +9,7 @@ CONFIG_DISTRO_DEFAULTS=y
 CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_BOOTDELAY=5
+CONFIG_USE_PREBOOT=y
 # CONFIG_DISPLAY_CPUINFO is not set
 CONFIG_BOARD_EARLY_INIT_R=y
 CONFIG_SYS_PROMPT="Versal> "
@@ -43,6 +44,9 @@ CONFIG_FPGA_VERSALPL=y
 CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_CADENCE=y
 CONFIG_MISC=y
+CONFIG_I2C_EEPROM=y
+CONFIG_SYS_I2C_EEPROM_ADDR=0x0
+CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW=0x0
 CONFIG_MMC_IO_VOLTAGE=y
 CONFIG_MMC_UHS_SUPPORT=y
 CONFIG_MMC_HS400_SUPPORT=y

+ 2 - 0
configs/xilinx_zynqmp_virt_defconfig

@@ -15,6 +15,7 @@ CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_SPL_LOAD_FIT=y
 CONFIG_SPL_LOAD_FIT_ADDRESS=0x10000000
+CONFIG_USE_PREBOOT=y
 # CONFIG_DISPLAY_CPUINFO is not set
 CONFIG_BOARD_EARLY_INIT_F=y
 CONFIG_BOARD_EARLY_INIT_R=y
@@ -65,6 +66,7 @@ CONFIG_SPL_DM_SEQ_ALIAS=y
 CONFIG_SCSI_AHCI=y
 CONFIG_SATA_CEVA=y
 CONFIG_CLK_ZYNQMP=y
+CONFIG_DFU_TFTP=y
 CONFIG_DFU_RAM=y
 CONFIG_USB_FUNCTION_FASTBOOT=y
 CONFIG_FASTBOOT_FLASH=y

+ 0 - 17
drivers/clk/clk_versal.c

@@ -68,23 +68,6 @@
 #define CLOCK_NODE_TYPE_DIV	4
 #define CLOCK_NODE_TYPE_GATE	6
 
-enum pm_query_id {
-	PM_QID_INVALID,
-	PM_QID_CLOCK_GET_NAME,
-	PM_QID_CLOCK_GET_TOPOLOGY,
-	PM_QID_CLOCK_GET_FIXEDFACTOR_PARAMS,
-	PM_QID_CLOCK_GET_PARENTS,
-	PM_QID_CLOCK_GET_ATTRIBUTES,
-	PM_QID_PINCTRL_GET_NUM_PINS,
-	PM_QID_PINCTRL_GET_NUM_FUNCTIONS,
-	PM_QID_PINCTRL_GET_NUM_FUNCTION_GROUPS,
-	PM_QID_PINCTRL_GET_FUNCTION_NAME,
-	PM_QID_PINCTRL_GET_FUNCTION_GROUPS,
-	PM_QID_PINCTRL_GET_PIN_GROUPS,
-	PM_QID_CLOCK_GET_NUM_CLOCKS,
-	PM_QID_CLOCK_GET_MAX_DIVISOR,
-};
-
 enum clk_type {
 	CLK_TYPE_OUTPUT,
 	CLK_TYPE_EXTERNAL,

+ 43 - 41
drivers/firmware/firmware-zynqmp.c

@@ -37,6 +37,7 @@ static int ipi_req(const u32 *req, size_t req_len, u32 *res, size_t res_maxlen)
 	if (!(zynqmp_power.tx_chan.dev) || !(&zynqmp_power.rx_chan.dev))
 		return -EINVAL;
 
+	debug("%s, Sending IPI message with ID: 0x%0x\n", __func__, req[0]);
 	msg.buf = (u32 *)req;
 	msg.len = req_len;
 	ret = mbox_send(&zynqmp_power.tx_chan, &msg);
@@ -54,14 +55,6 @@ static int ipi_req(const u32 *req, size_t req_len, u32 *res, size_t res_maxlen)
 	return ret;
 }
 
-static int send_req(const u32 *req, size_t req_len, u32 *res, size_t res_maxlen)
-{
-	if (IS_ENABLED(CONFIG_SPL_BUILD) || current_el() == 3)
-		return ipi_req(req, req_len, res, res_maxlen);
-
-	return xilinx_pm_request(req[0], 0, 0, 0, 0, res);
-}
-
 unsigned int zynqmp_firmware_version(void)
 {
 	int ret;
@@ -74,9 +67,9 @@ unsigned int zynqmp_firmware_version(void)
 	 * asking PMUFW again.
 	 **/
 	if (pm_api_version == ZYNQMP_PM_VERSION_INVALID) {
-		const u32 request[] = { PM_GET_API_VERSION };
 
-		ret = send_req(request, ARRAY_SIZE(request), ret_payload, 2);
+		ret = xilinx_pm_request(PM_GET_API_VERSION, 0, 0, 0, 0,
+					ret_payload);
 		if (ret)
 			panic("PMUFW is not found - Please load it!\n");
 
@@ -97,16 +90,13 @@ unsigned int zynqmp_firmware_version(void)
  */
 void zynqmp_pmufw_load_config_object(const void *cfg_obj, size_t size)
 {
-	const u32 request[] = {
-		PM_SET_CONFIGURATION,
-		(u32)((u64)cfg_obj)
-	};
-	u32 response = 0;
 	int err;
+	u32 ret_payload[PAYLOAD_ARG_CNT];
 
 	printf("Loading new PMUFW cfg obj (%ld bytes)\n", size);
 
-	err = send_req(request, ARRAY_SIZE(request), &response, 1);
+	err = xilinx_pm_request(PM_SET_CONFIGURATION, (u32)(u64)cfg_obj, 0, 0,
+				0, ret_payload);
 	if (err == XST_PM_NO_ACCESS) {
 		printf("PMUFW no permission to change config object\n");
 		return;
@@ -115,10 +105,10 @@ void zynqmp_pmufw_load_config_object(const void *cfg_obj, size_t size)
 	if (err)
 		printf("Cannot load PMUFW configuration object (%d)\n", err);
 
-	if (response)
-		printf("PMUFW returned 0x%08x status!\n", response);
+	if (ret_payload[0])
+		printf("PMUFW returned 0x%08x status!\n", ret_payload[0]);
 
-	if ((err || response) && IS_ENABLED(CONFIG_SPL_BUILD))
+	if ((err || ret_payload[0]) && IS_ENABLED(CONFIG_SPL_BUILD))
 		panic("PMUFW config object loading failed in EL3\n");
 }
 
@@ -164,32 +154,44 @@ U_BOOT_DRIVER(zynqmp_power) = {
 int __maybe_unused xilinx_pm_request(u32 api_id, u32 arg0, u32 arg1, u32 arg2,
 				     u32 arg3, u32 *ret_payload)
 {
-	/*
-	 * Added SIP service call Function Identifier
-	 * Make sure to stay in x0 register
-	 */
-	struct pt_regs regs;
+	debug("%s at EL%d, API ID: 0x%0x\n", __func__, current_el(), api_id);
 
-	if (current_el() == 3) {
-		printf("%s: Can't call SMC from EL3 context\n", __func__);
+	if (IS_ENABLED(CONFIG_SPL_BUILD) || current_el() == 3) {
+#if defined(CONFIG_ZYNQMP_IPI)
+		/*
+		 * Use fixed payload and arg size as the EL2 call. The firmware
+		 * is capable to handle PMUFW_PAYLOAD_ARG_CNT bytes but the
+		 * firmware API is limited by the SMC call size
+		 */
+		u32 regs[] = {api_id, arg0, arg1, arg2, arg3};
+
+		ipi_req(regs, PAYLOAD_ARG_CNT, ret_payload, PAYLOAD_ARG_CNT);
+#else
 		return -EPERM;
-	}
-
-	regs.regs[0] = PM_SIP_SVC | api_id;
-	regs.regs[1] = ((u64)arg1 << 32) | arg0;
-	regs.regs[2] = ((u64)arg3 << 32) | arg2;
-
-	smc_call(&regs);
+#endif
+	} else {
+		/*
+		 * Added SIP service call Function Identifier
+		 * Make sure to stay in x0 register
+		 */
+		struct pt_regs regs;
+
+		regs.regs[0] = PM_SIP_SVC | api_id;
+		regs.regs[1] = ((u64)arg1 << 32) | arg0;
+		regs.regs[2] = ((u64)arg3 << 32) | arg2;
+
+		smc_call(&regs);
+
+		if (ret_payload) {
+			ret_payload[0] = (u32)regs.regs[0];
+			ret_payload[1] = upper_32_bits(regs.regs[0]);
+			ret_payload[2] = (u32)regs.regs[1];
+			ret_payload[3] = upper_32_bits(regs.regs[1]);
+			ret_payload[4] = (u32)regs.regs[2];
+		}
 
-	if (ret_payload) {
-		ret_payload[0] = (u32)regs.regs[0];
-		ret_payload[1] = upper_32_bits(regs.regs[0]);
-		ret_payload[2] = (u32)regs.regs[1];
-		ret_payload[3] = upper_32_bits(regs.regs[1]);
-		ret_payload[4] = (u32)regs.regs[2];
 	}
-
-	return regs.regs[0];
+	return (ret_payload) ? ret_payload[0] : 0;
 }
 
 static const struct udevice_id zynqmp_firmware_ids[] = {

+ 1 - 1
drivers/fpga/versalpl.c

@@ -32,7 +32,7 @@ static int versal_load(xilinx_desc *desc, const void *buf, size_t bsize,
 	ulong bin_buf;
 	int ret;
 	u32 buf_lo, buf_hi;
-	u32 ret_payload[5];
+	u32 ret_payload[PAYLOAD_ARG_CNT];
 
 	bin_buf = versal_align_dma_buffer((ulong *)buf, bsize);
 

+ 2 - 2
drivers/gpio/Kconfig

@@ -381,8 +381,8 @@ config MVEBU_GPIO
 
 config ZYNQ_GPIO
 	bool "Zynq GPIO driver"
-	depends on DM_GPIO && (ARCH_ZYNQ || ARCH_ZYNQMP || ARCH_VERSAL)
-	default y
+	depends on DM_GPIO
+	default y if ARCH_ZYNQ || ARCH_ZYNQMP || ARCH_VERSAL
 	help
 	  Supports GPIO access on Zynq SoC.
 

+ 1 - 1
drivers/i2c/Kconfig

@@ -88,7 +88,7 @@ config SYS_I2C_FSL
 
 config SYS_I2C_CADENCE
 	tristate "Cadence I2C Controller"
-	depends on DM_I2C && (ARCH_ZYNQ || ARM64)
+	depends on DM_I2C
 	help
 	  Say yes here to select Cadence I2C Host Controller. This controller is
 	  e.g. used by Xilinx Zynq.

+ 10 - 4
drivers/mailbox/zynqmp-ipi.c

@@ -24,10 +24,12 @@
 struct ipi_int_regs {
 	u32 trig; /* 0x0  */
 	u32 obs;  /* 0x4  */
-	u32 ist;  /* 0x8  */
-	u32 imr;  /* 0xC  */
-	u32 ier;  /* 0x10 */
-	u32 idr;  /* 0x14 */
+	u32 dummy0;
+	u32 dummy1;
+	u32 isr;  /* 0x10  */
+	u32 imr;  /* 0x14  */
+	u32 ier;  /* 0x18 */
+	u32 idr;  /* 0x1C */
 };
 
 #define ipi_int_apu ((struct ipi_int_regs *)IPI_INT_REG_BASE_APU)
@@ -66,6 +68,10 @@ static int zynqmp_ipi_recv(struct mbox_chan *chan, void *data)
 	struct zynqmp_ipi *zynqmp = dev_get_priv(chan->dev);
 	u32 *mbx = (u32 *)zynqmp->local_res_regs;
 
+	/*
+	 * PMU Firmware does not trigger IPI interrupt for API call responses so
+	 * there is no need to check ISR flags
+	 */
 	for (size_t i = 0; i < msg->len; i++)
 		msg->buf[i] = readl(&mbx[i]);
 

+ 8 - 7
drivers/misc/i2c_eeprom.c

@@ -301,19 +301,20 @@ static int i2c_eeprom_partition_probe(struct udevice *dev)
 static int i2c_eeprom_partition_ofdata_to_platdata(struct udevice *dev)
 {
 	struct i2c_eeprom_partition *priv = dev_get_priv(dev);
-	u32 offset, size;
+	u32 reg[2];
 	int ret;
 
-	ret = dev_read_u32(dev, "offset", &offset);
+	ret = dev_read_u32_array(dev, "reg", reg, 2);
 	if (ret)
 		return ret;
 
-	ret = dev_read_u32(dev, "size", &size);
-	if (ret)
-		return ret;
+	if (!reg[1])
+		return -EINVAL;
+
+	priv->offset = reg[0];
+	priv->size = reg[1];
 
-	priv->offset = offset;
-	priv->size = size;
+	debug("%s: base %x, size %x\n", __func__, priv->offset, priv->size);
 
 	return 0;
 }

+ 0 - 1
drivers/mmc/Kconfig

@@ -653,7 +653,6 @@ config TEGRA124_MMC_DISABLE_EXT_LOOPBACK
 
 config MMC_SDHCI_ZYNQ
 	bool "Arasan SDHCI controller support"
-	depends on ARCH_ZYNQ || ARCH_ZYNQMP || ARCH_VERSAL
 	depends on DM_MMC && OF_CONTROL && BLK
 	depends on MMC_SDHCI
 	help

+ 8 - 5
drivers/mmc/sdhci.c

@@ -748,9 +748,9 @@ int sdhci_setup_cfg(struct mmc_config *cfg, struct sdhci_host *host,
 					    "sdhci-caps-mask", 0);
 	dt_caps = dev_read_u64_default(host->mmc->dev,
 				       "sdhci-caps", 0);
-	caps = ~(u32)dt_caps_mask &
+	caps = ~lower_32_bits(dt_caps_mask) &
 	       sdhci_readl(host, SDHCI_CAPABILITIES);
-	caps |= (u32)dt_caps;
+	caps |= lower_32_bits(dt_caps);
 #else
 	caps = sdhci_readl(host, SDHCI_CAPABILITIES);
 #endif
@@ -793,9 +793,9 @@ int sdhci_setup_cfg(struct mmc_config *cfg, struct sdhci_host *host,
 	/* Check whether the clock multiplier is supported or not */
 	if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) {
 #if CONFIG_IS_ENABLED(DM_MMC)
-		caps_1 = ~(u32)(dt_caps_mask >> 32) &
+		caps_1 = ~upper_32_bits(dt_caps_mask) &
 			 sdhci_readl(host, SDHCI_CAPABILITIES_1);
-		caps_1 |= (u32)(dt_caps >> 32);
+		caps_1 |= upper_32_bits(dt_caps);
 #else
 		caps_1 = sdhci_readl(host, SDHCI_CAPABILITIES_1);
 #endif
@@ -843,7 +843,10 @@ int sdhci_setup_cfg(struct mmc_config *cfg, struct sdhci_host *host,
 	if (host->quirks & SDHCI_QUIRK_BROKEN_VOLTAGE)
 		cfg->voltages |= host->voltages;
 
-	cfg->host_caps |= MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_4BIT;
+	if (caps & SDHCI_CAN_DO_HISPD)
+		cfg->host_caps |= MMC_MODE_HS | MMC_MODE_HS_52MHz;
+
+	cfg->host_caps |= MMC_MODE_4BIT;
 
 	/* Since Host Controller Version3.0 */
 	if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) {

+ 1 - 1
drivers/mmc/zynq_sdhci.c

@@ -276,7 +276,7 @@ static int arasan_sdhci_ofdata_to_platdata(struct udevice *dev)
 		return PTR_ERR(priv->host->ioaddr);
 
 	priv->deviceid = dev_read_u32_default(dev, "xlnx,device_id", -1);
-	priv->bank = dev_read_u32_default(dev, "xlnx,mio_bank", -1);
+	priv->bank = dev_read_u32_default(dev, "xlnx,mio-bank", 0);
 
 	return 0;
 }

+ 3 - 3
drivers/net/Kconfig

@@ -519,7 +519,7 @@ config TULIP
 	  This driver supports DEC DC2114x Fast ethernet chips.
 
 config XILINX_AXIEMAC
-	depends on DM_ETH && (MICROBLAZE || ARCH_ZYNQ || ARCH_ZYNQMP)
+	depends on DM_ETH
 	select PHYLIB
 	select MII
 	bool "Xilinx AXI Ethernet"
@@ -527,7 +527,7 @@ config XILINX_AXIEMAC
 	  This MAC is present in Xilinx Microblaze, Zynq and ZynqMP SoCs.
 
 config XILINX_EMACLITE
-	depends on DM_ETH && (MICROBLAZE || ARCH_ZYNQ || ARCH_ZYNQMP || MIPS)
+	depends on DM_ETH
 	select PHYLIB
 	select MII
 	bool "Xilinx Ethernetlite"
@@ -535,7 +535,7 @@ config XILINX_EMACLITE
 	  This MAC is present in Xilinx Microblaze, Zynq and ZynqMP SoCs.
 
 config ZYNQ_GEM
-	depends on DM_ETH && (ARCH_ZYNQ || ARCH_ZYNQMP || ARCH_VERSAL)
+	depends on DM_ETH
 	select PHYLIB
 	bool "Xilinx Ethernet GEM"
 	help

+ 1 - 2
include/configs/xilinx_versal.h

@@ -54,7 +54,7 @@
 #define DFU_ALT_INFO_RAM \
 	"dfu_ram_info=" \
 	"setenv dfu_alt_info " \
-	"Image ram $kernel_addr_r $kernel_size_r\\\\;" \
+	"Image ram 80000 $kernel_size_r\\\\;" \
 	"system.dtb ram $fdt_addr_r $fdt_size_r\0" \
 	"dfu_ram=run dfu_ram_info && dfu 0 ram 0\0" \
 	"thor_ram=run dfu_ram_info && thordown 0 ram 0\0"
@@ -79,7 +79,6 @@
 #define CONFIG_CLOCKS
 
 #define ENV_MEM_LAYOUT_SETTINGS \
-	"fdt_high=10000000\0" \
 	"fdt_addr_r=0x40000000\0" \
 	"fdt_size_r=0x400000\0" \
 	"pxefile_addr_r=0x10000000\0" \

+ 7 - 4
include/configs/xilinx_zynqmp.h

@@ -58,10 +58,12 @@
 #define DFU_ALT_INFO_RAM \
 	"dfu_ram_info=" \
 	"setenv dfu_alt_info " \
-	"Image ram $kernel_addr $kernel_size\\\\;" \
-	"system.dtb ram $fdt_addr $fdt_size\0" \
+	"Image ram 80000 $kernel_size_r\\\\;" \
+	"system.dtb ram $fdt_addr_r $fdt_size_r\0" \
 	"dfu_ram=run dfu_ram_info && dfu 0 ram 0\0" \
-	"thor_ram=run dfu_ram_info && thordown 0 ram 0\0"
+	"thor_ram=run dfu_ram_info && thordown 0 ram 0\0" \
+	"dfu_ram_tftp=run dfu_ram_info && setenv updatefile boot && " \
+	"setenv loadaddr 10000000 && dfu tftp ram 0\0"
 
 #define DFU_ALT_INFO  \
 		DFU_ALT_INFO_RAM
@@ -99,10 +101,11 @@
 #define CONFIG_CLOCKS
 
 #define ENV_MEM_LAYOUT_SETTINGS \
-	"fdt_high=10000000\0" \
 	"fdt_addr_r=0x40000000\0" \
+	"fdt_size_r=0x400000\0" \
 	"pxefile_addr_r=0x10000000\0" \
 	"kernel_addr_r=0x18000000\0" \
+	"kernel_size_r=0x10000000\0" \
 	"scriptaddr=0x20000000\0" \
 	"ramdisk_addr_r=0x02100000\0" \
 	"script_size_f=0x80000\0" \

+ 1 - 1
include/configs/xilinx_zynqmp_mini_qspi.h

@@ -13,6 +13,6 @@
 #include <configs/xilinx_zynqmp_mini.h>
 
 #define CONFIG_SYS_INIT_SP_ADDR	(CONFIG_SYS_TEXT_BASE + 0x20000)
-#define CONFIG_SYS_MALLOC_LEN	0x2000
+#define CONFIG_SYS_MALLOC_LEN	0x1a00
 
 #endif /* __CONFIG_ZYNQMP_MINI_QSPI_H */

+ 0 - 1
include/configs/zynq-common.h

@@ -196,7 +196,6 @@
 /* Default environment */
 #ifndef CONFIG_EXTRA_ENV_SETTINGS
 #define CONFIG_EXTRA_ENV_SETTINGS	\
-	"fdt_high=0x20000000\0"		\
 	"scriptaddr=0x20000\0"	\
 	"script_size_f=0x40000\0"	\
 	"fdt_addr_r=0x1f00000\0"        \

+ 17 - 0
include/fdtdec.h

@@ -926,6 +926,23 @@ int fdtdec_decode_display_timing(const void *blob, int node, int index,
  */
 int fdtdec_setup_mem_size_base(void);
 
+/**
+ * fdtdec_setup_mem_size_base_lowest() - decode and setup gd->ram_size and
+ * gd->ram_start by lowest available memory base
+ *
+ * Decode the /memory 'reg' property to determine the lowest start of the memory
+ * bank bank and populate the global data with it.
+ *
+ * This function should be called from a boards dram_init(). This helper
+ * function allows for boards to query the device tree for DRAM size and start
+ * address instead of hard coding the value in the case where the memory size
+ * and start address cannot be detected automatically.
+ *
+ * @return 0 if OK, -EINVAL if the /memory node or reg property is missing or
+ * invalid
+ */
+int fdtdec_setup_mem_size_base_lowest(void);
+
 /**
  * fdtdec_setup_memory_banksize() - decode and populate gd->bd->bi_dram
  *

+ 26 - 0
include/zynqmp_firmware.h

@@ -62,6 +62,23 @@ enum pm_api_id {
 	PM_API_MAX,
 };
 
+enum pm_query_id {
+	PM_QID_INVALID = 0,
+	PM_QID_CLOCK_GET_NAME = 1,
+	PM_QID_CLOCK_GET_TOPOLOGY = 2,
+	PM_QID_CLOCK_GET_FIXEDFACTOR_PARAMS = 3,
+	PM_QID_CLOCK_GET_PARENTS = 4,
+	PM_QID_CLOCK_GET_ATTRIBUTES = 5,
+	PM_QID_PINCTRL_GET_NUM_PINS = 6,
+	PM_QID_PINCTRL_GET_NUM_FUNCTIONS = 7,
+	PM_QID_PINCTRL_GET_NUM_FUNCTION_GROUPS = 8,
+	PM_QID_PINCTRL_GET_FUNCTION_NAME = 9,
+	PM_QID_PINCTRL_GET_FUNCTION_GROUPS = 10,
+	PM_QID_PINCTRL_GET_PIN_GROUPS = 11,
+	PM_QID_CLOCK_GET_NUM_CLOCKS = 12,
+	PM_QID_CLOCK_GET_MAX_DIVISOR = 13,
+};
+
 #define PM_SIP_SVC      0xc2000000
 
 #define ZYNQMP_PM_VERSION_MAJOR         1
@@ -77,6 +94,15 @@ enum pm_api_id {
 
 #define PMUFW_V1_0      ((1 << ZYNQMP_PM_VERSION_MAJOR_SHIFT) | 0)
 
+/*
+ * Return payload size
+ * Not every firmware call expects the same amount of return bytes, however the
+ * firmware driver always copies 5 bytes from RX buffer to the ret_payload
+ * buffer. Therefore allocating with this defined value is recommended to avoid
+ * overflows.
+ */
+#define PAYLOAD_ARG_CNT	5U
+
 unsigned int zynqmp_firmware_version(void);
 void zynqmp_pmufw_load_config_object(const void *cfg_obj, size_t size);
 int xilinx_pm_request(u32 api_id, u32 arg0, u32 arg1, u32 arg2,

+ 69 - 21
lib/fdtdec.c

@@ -24,6 +24,7 @@
 #include <asm/sections.h>
 #include <linux/ctype.h>
 #include <linux/lzo.h>
+#include <linux/ioport.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -1032,16 +1033,17 @@ int fdtdec_decode_display_timing(const void *blob, int parent, int index,
 
 int fdtdec_setup_mem_size_base(void)
 {
-	int ret, mem;
-	struct fdt_resource res;
+	int ret;
+	ofnode mem;
+	struct resource res;
 
-	mem = fdt_path_offset(gd->fdt_blob, "/memory");
-	if (mem < 0) {
+	mem = ofnode_path("/memory");
+	if (!ofnode_valid(mem)) {
 		debug("%s: Missing /memory node\n", __func__);
 		return -EINVAL;
 	}
 
-	ret = fdt_get_resource(gd->fdt_blob, mem, "reg", 0, &res);
+	ret = ofnode_read_resource(mem, 0, &res);
 	if (ret != 0) {
 		debug("%s: Unable to decode first memory bank\n", __func__);
 		return -EINVAL;
@@ -1057,42 +1059,42 @@ int fdtdec_setup_mem_size_base(void)
 
 #if defined(CONFIG_NR_DRAM_BANKS)
 
-static int get_next_memory_node(const void *blob, int mem)
+ofnode get_next_memory_node(ofnode mem)
 {
 	do {
-		mem = fdt_node_offset_by_prop_value(gd->fdt_blob, mem,
-						    "device_type", "memory", 7);
-	} while (!fdtdec_get_is_enabled(blob, mem));
+		mem = ofnode_by_prop_value(mem, "device_type", "memory", 7);
+	} while (!ofnode_is_available(mem));
 
 	return mem;
 }
 
 int fdtdec_setup_memory_banksize(void)
 {
-	int bank, ret, mem, reg = 0;
-	struct fdt_resource res;
+	int bank, ret, reg = 0;
+	struct resource res;
+	ofnode mem = ofnode_null();
 
-	mem = get_next_memory_node(gd->fdt_blob, -1);
-	if (mem < 0) {
+	mem = get_next_memory_node(mem);
+	if (!ofnode_valid(mem)) {
 		debug("%s: Missing /memory node\n", __func__);
 		return -EINVAL;
 	}
 
 	for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) {
-		ret = fdt_get_resource(gd->fdt_blob, mem, "reg", reg++, &res);
-		if (ret == -FDT_ERR_NOTFOUND) {
+		ret = ofnode_read_resource(mem, reg++, &res);
+		if (ret < 0) {
 			reg = 0;
-			mem = get_next_memory_node(gd->fdt_blob, mem);
-			if (mem == -FDT_ERR_NOTFOUND)
+			mem = get_next_memory_node(mem);
+			if (ofnode_valid(mem))
 				break;
 
-			ret = fdt_get_resource(gd->fdt_blob, mem, "reg", reg++, &res);
-			if (ret == -FDT_ERR_NOTFOUND)
+			ret = ofnode_read_resource(mem, reg++, &res);
+			if (ret < 0)
 				break;
 		}
-		if (ret != 0) {
+
+		if (ret != 0)
 			return -EINVAL;
-		}
 
 		gd->bd->bi_dram[bank].start = (phys_addr_t)res.start;
 		gd->bd->bi_dram[bank].size =
@@ -1106,6 +1108,52 @@ int fdtdec_setup_memory_banksize(void)
 
 	return 0;
 }
+
+int fdtdec_setup_mem_size_base_lowest(void)
+{
+	int bank, ret, reg = 0;
+	struct resource res;
+	unsigned long base;
+	phys_size_t size;
+	ofnode mem = ofnode_null();
+
+	gd->ram_base = (unsigned long)~0;
+
+	mem = get_next_memory_node(mem);
+	if (!ofnode_valid(mem)) {
+		debug("%s: Missing /memory node\n", __func__);
+		return -EINVAL;
+	}
+
+	for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) {
+		ret = ofnode_read_resource(mem, reg++, &res);
+		if (ret < 0) {
+			reg = 0;
+			mem = get_next_memory_node(mem);
+			if (ofnode_valid(mem))
+				break;
+
+			ret = ofnode_read_resource(mem, reg++, &res);
+			if (ret < 0)
+				break;
+		}
+
+		if (ret != 0)
+			return -EINVAL;
+
+		base = (unsigned long)res.start;
+		size = (phys_size_t)(res.end - res.start + 1);
+
+		if (gd->ram_base > base && size) {
+			gd->ram_base = base;
+			gd->ram_size = size;
+			debug("%s: Initial DRAM base %lx size %lx\n",
+			      __func__, base, (unsigned long)size);
+		}
+	}
+
+	return 0;
+}
 #endif
 
 #if CONFIG_IS_ENABLED(MULTI_DTB_FIT)

+ 8 - 0
test/dm/bootcount.c

@@ -25,6 +25,14 @@ static int dm_test_bootcount(struct unit_test_state *uts)
 	ut_assertok(dm_bootcount_get(dev, &val));
 	ut_assert(val == 0xab);
 
+	ut_assertok(uclass_get_device(UCLASS_BOOTCOUNT, 1, &dev));
+	ut_assertok(dm_bootcount_set(dev, 0));
+	ut_assertok(dm_bootcount_get(dev, &val));
+	ut_assert(val == 0);
+	ut_assertok(dm_bootcount_set(dev, 0xab));
+	ut_assertok(dm_bootcount_get(dev, &val));
+	ut_assert(val == 0xab);
+
 	return 0;
 }