Browse Source

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

Xilinx changes for v2021.10-rc3

xilinx:
- Disable CONFIG_ARCH_FIXUP_FDT_MEMORY
- Print information about cpu via soc drivers and enable DISPLAY_CPUINFO
- Wire infrastructure for DTB_RESELECT and MULTI_DTB_FIT

zynq:
- Wire single QSPI
- Use power-source instead of io-standard properties
- Enable nor on zc770-xm012

zynqmp:
- Change handling around multi_boot()
- Setup offset for u-boot.itb in spi
- Generate run time dfu_alt_info for capsule update
- Use explicit values for enums (zynqmp_firmware.h)
- Enable RTC/SHA1/BUTTON/BUTTON_GPIO command
- Disable WDT driver by default
- Bind usb/scsi via preboot because of EFI
- DT updates/fixes
- Add soc driver
- Fix SPL SPI boot mode

versal:
- Add soc driver

sdhci:
- Update tap delay programming for zynq_sdhci driver

cmd:
- Fix RTC uclass handling in date command
- Update pwm help message
- Update reset help message

watchdog:
- Fix wwdt compilation

rtc:
- Deal with seq alias in rtc uclass
- Add zynqmp RTC driver

fdt:
- Add kernel-doc for fdt_fixup_memory_banks()
Tom Rini 2 years ago
parent
commit
b9cb74a5aa
49 changed files with 1395 additions and 294 deletions
  1. 4 0
      MAINTAINERS
  2. 3 0
      Makefile
  3. 2 0
      arch/arm/Kconfig
  4. 1 1
      arch/arm/dts/Makefile
  5. 1 1
      arch/arm/dts/zynq-cc108.dts
  6. 1 1
      arch/arm/dts/zynq-cse-qspi.dtsi
  7. 1 1
      arch/arm/dts/zynq-topic-miami.dts
  8. 19 11
      arch/arm/dts/zynq-zc702.dts
  9. 17 9
      arch/arm/dts/zynq-zc706.dts
  10. 8 0
      arch/arm/dts/zynq-zc770-xm010.dts
  11. 9 0
      arch/arm/dts/zynq-zc770-xm012.dts
  12. 8 0
      arch/arm/dts/zynq-zc770-xm013.dts
  13. 4 4
      arch/arm/dts/zynqmp-sck-kv-g-revA.dts
  14. 4 4
      arch/arm/dts/zynqmp-sck-kv-g-revB.dts
  15. 6 3
      arch/arm/dts/zynqmp-sm-k26-revA.dts
  16. 1 1
      arch/arm/dts/zynqmp-topic-miamimp-xilinx-xdp-v1r1.dts
  17. 5 0
      arch/arm/mach-versal/cpu.c
  18. 4 0
      arch/arm/mach-versal/include/mach/hardware.h
  19. 5 0
      arch/arm/mach-zynqmp/cpu.c
  20. 3 0
      arch/arm/mach-zynqmp/include/mach/hardware.h
  21. 49 2
      arch/arm/mach-zynqmp/mkimage_fit_atf.sh
  22. 155 29
      board/xilinx/common/board.c
  23. 0 2
      board/xilinx/zynqmp/Makefile
  24. 0 101
      board/xilinx/zynqmp/tap_delays.c
  25. 68 6
      board/xilinx/zynqmp/zynqmp.c
  26. 2 1
      cmd/boot.c
  27. 6 3
      cmd/date.c
  28. 4 3
      cmd/pwm.c
  29. 18 0
      common/fdt_support.c
  30. 2 1
      configs/xilinx_versal_virt_defconfig
  31. 1 0
      configs/xilinx_zynq_virt_defconfig
  32. 14 2
      configs/xilinx_zynqmp_virt_defconfig
  33. 8 2
      drivers/mmc/sdhci.c
  34. 204 40
      drivers/mmc/zynq_sdhci.c
  35. 9 0
      drivers/reset/Kconfig
  36. 1 0
      drivers/reset/Makefile
  37. 100 0
      drivers/reset/reset-zynqmp.c
  38. 7 0
      drivers/rtc/Kconfig
  39. 1 0
      drivers/rtc/Makefile
  40. 1 0
      drivers/rtc/rtc-uclass.c
  41. 158 0
      drivers/rtc/zynqmp_rtc.c
  42. 16 0
      drivers/soc/Kconfig
  43. 2 0
      drivers/soc/Makefile
  44. 76 0
      drivers/soc/soc_xilinx_versal.c
  45. 78 0
      drivers/soc/soc_xilinx_zynqmp.c
  46. 1 0
      drivers/watchdog/xilinx_wwdt.c
  47. 1 1
      include/sdhci.h
  48. 307 44
      include/zynqmp_firmware.h
  49. 0 21
      include/zynqmp_tap_delay.h

+ 4 - 0
MAINTAINERS

@@ -546,6 +546,7 @@ S:	Maintained
 T:	git https://source.denx.de/u-boot/custodians/u-boot-microblaze.git
 F:	arch/arm/mach-versal/
 F:	drivers/net/xilinx_axi_mrmac.*
+F:	drivers/soc/soc_xilinx_versal.c
 F:	drivers/watchdog/xilinx_wwdt.c
 N:	(?<!uni)versal
 
@@ -600,6 +601,9 @@ F:	drivers/mtd/nand/raw/zynq_nand.c
 F:	drivers/net/phy/xilinx_phy.c
 F:	drivers/net/zynq_gem.c
 F:	drivers/serial/serial_zynq.c
+F:	drivers/reset/reset-zynqmp.c
+F:	drivers/rtc/zynqmp_rtc.c
+F:	drivers/soc/soc_xilinx_zynqmp.c
 F:	drivers/spi/zynq_qspi.c
 F:	drivers/spi/zynq_spi.c
 F:	drivers/timer/cadence-ttc.c

+ 3 - 0
Makefile

@@ -1169,6 +1169,8 @@ MKIMAGEFLAGS_fit-dtb.blob = -f auto -A $(ARCH) -T firmware -C none -O u-boot \
 	-a 0 -e 0 -E \
 	$(patsubst %,-b arch/$(ARCH)/dts/%.dtb,$(subst ",,$(CONFIG_OF_LIST))) -d /dev/null
 
+MKIMAGEFLAGS_fit-dtb.blob += -B 0x8
+
 ifneq ($(EXT_DTB),)
 u-boot-fit-dtb.bin: u-boot-nodtb.bin $(EXT_DTB)
 		$(call if_changed,cat)
@@ -1431,6 +1433,7 @@ MKIMAGEFLAGS_u-boot.itb =
 else
 MKIMAGEFLAGS_u-boot.itb = -E
 endif
+MKIMAGEFLAGS_u-boot.itb += -B 0x8
 
 ifdef U_BOOT_ITS
 u-boot.itb: u-boot-nodtb.bin \

+ 2 - 0
arch/arm/Kconfig

@@ -1064,6 +1064,7 @@ config ARCH_VERSAL
 	select DM_SERIAL
 	select GPIO_EXTRA_HEADER
 	select OF_CONTROL
+	select SOC_DEVICE
 	imply BOARD_LATE_INIT
 	imply ENV_VARS_UBOOT_RUNTIME_CONFIG
 
@@ -1142,6 +1143,7 @@ config ARCH_ZYNQMP
 	select SPL_SEPARATE_BSS if SPL
 	select SUPPORT_SPL
 	select ZYNQMP_IPI
+	select SOC_DEVICE
 	imply BOARD_LATE_INIT
 	imply CMD_DM
 	imply ENV_VARS_UBOOT_RUNTIME_CONFIG

+ 1 - 1
arch/arm/dts/Makefile

@@ -1133,7 +1133,7 @@ dtb-$(CONFIG_TARGET_EA_LPC3250DEVKITV2) += lpc3250-ea3250.dtb
 targets += $(dtb-y)
 
 # Add any required device tree compiler flags here
-DTC_FLAGS +=
+DTC_FLAGS += -a 0x8
 
 PHONY += dtbs
 dtbs: $(addprefix $(obj)/, $(dtb-y))

+ 1 - 1
arch/arm/dts/zynq-cc108.dts

@@ -58,7 +58,7 @@
 	is-dual = <0>;
 	num-cs = <1>;
 	flash@0 { /* 16 MB */
-		compatible = "n25q128a11";
+		compatible = "n25q128a11", "jedec,spi-nor";
 		reg = <0x0>;
 		spi-max-frequency = <50000000>;
 		spi-tx-bus-width = <1>;

+ 1 - 1
arch/arm/dts/zynq-cse-qspi.dtsi

@@ -60,7 +60,7 @@
 			#size-cells = <0>;
 			num-cs = <1>;
 			flash0: flash@0 {
-				compatible = "n25q128a11";
+				compatible = "n25q128a11", "jedec,spi-nor";
 				reg = <0x0>;
 				spi-tx-bus-width = <1>;
 				spi-rx-bus-width = <4>;

+ 1 - 1
arch/arm/dts/zynq-topic-miami.dts

@@ -36,7 +36,7 @@
 	is-dual = <0>;
 	num-cs = <1>;
 	flash@0 {
-		compatible = "st,m25p80", "n25q256a";
+		compatible = "st,m25p80", "n25q256a", "jedec,spi-nor";
 		m25p,fast-read;
 		reg = <0x0>;
 		spi-tx-bus-width = <1>;

+ 19 - 11
arch/arm/dts/zynq-zc702.dts

@@ -213,7 +213,7 @@
 		conf {
 			groups = "can0_9_grp";
 			slew-rate = <0>;
-			io-standard = <1>;
+			power-source = <1>;
 		};
 
 		conf-rx {
@@ -236,7 +236,7 @@
 		conf {
 			groups = "ethernet0_0_grp";
 			slew-rate = <0>;
-			io-standard = <4>;
+			power-source = <4>;
 		};
 
 		conf-rx {
@@ -259,7 +259,7 @@
 		conf-mdio {
 			groups = "mdio0_0_grp";
 			slew-rate = <0>;
-			io-standard = <1>;
+			power-source = <1>;
 			bias-disable;
 		};
 	};
@@ -277,7 +277,7 @@
 				 "gpio0_10_grp", "gpio0_11_grp", "gpio0_12_grp",
 				 "gpio0_13_grp", "gpio0_14_grp";
 			slew-rate = <0>;
-			io-standard = <1>;
+			power-source = <1>;
 		};
 
 		conf-pull-up {
@@ -301,7 +301,7 @@
 			groups = "i2c0_10_grp";
 			bias-pull-up;
 			slew-rate = <0>;
-			io-standard = <1>;
+			power-source = <1>;
 		};
 	};
 
@@ -314,7 +314,7 @@
 		conf {
 			groups = "gpio0_50_grp", "gpio0_51_grp";
 			slew-rate = <0>;
-			io-standard = <1>;
+			power-source = <1>;
 		};
 	};
 
@@ -327,7 +327,7 @@
 		conf {
 			groups = "sdio0_2_grp";
 			slew-rate = <0>;
-			io-standard = <1>;
+			power-source = <1>;
 			bias-disable;
 		};
 
@@ -341,7 +341,7 @@
 			bias-high-impedance;
 			bias-pull-up;
 			slew-rate = <0>;
-			io-standard = <1>;
+			power-source = <1>;
 		};
 
 		mux-wp {
@@ -354,7 +354,7 @@
 			bias-high-impedance;
 			bias-pull-up;
 			slew-rate = <0>;
-			io-standard = <1>;
+			power-source = <1>;
 		};
 	};
 
@@ -367,7 +367,7 @@
 		conf {
 			groups = "uart1_10_grp";
 			slew-rate = <0>;
-			io-standard = <1>;
+			power-source = <1>;
 		};
 
 		conf-rx {
@@ -390,7 +390,7 @@
 		conf {
 			groups = "usb0_0_grp";
 			slew-rate = <0>;
-			io-standard = <1>;
+			power-source = <1>;
 		};
 
 		conf-rx {
@@ -409,6 +409,14 @@
 &qspi {
 	u-boot,dm-pre-reloc;
 	status = "okay";
+	num-cs = <1>;
+	flash@0 {
+		compatible = "n25q128a11", "jedec,spi-nor";
+		reg = <0x0>;
+		spi-tx-bus-width = <1>;
+		spi-rx-bus-width = <4>;
+		spi-max-frequency = <50000000>;
+	};
 };
 
 &sdhci0 {

+ 17 - 9
arch/arm/dts/zynq-zc706.dts

@@ -151,7 +151,7 @@
 		conf {
 			groups = "ethernet0_0_grp";
 			slew-rate = <0>;
-			io-standard = <4>;
+			power-source = <4>;
 		};
 
 		conf-rx {
@@ -174,7 +174,7 @@
 		conf-mdio {
 			groups = "mdio0_0_grp";
 			slew-rate = <0>;
-			io-standard = <1>;
+			power-source = <1>;
 			bias-disable;
 		};
 	};
@@ -188,7 +188,7 @@
 		conf {
 			groups = "gpio0_7_grp", "gpio0_46_grp", "gpio0_47_grp";
 			slew-rate = <0>;
-			io-standard = <1>;
+			power-source = <1>;
 		};
 
 		conf-pull-up {
@@ -212,7 +212,7 @@
 			groups = "i2c0_10_grp";
 			bias-pull-up;
 			slew-rate = <0>;
-			io-standard = <1>;
+			power-source = <1>;
 		};
 	};
 
@@ -225,7 +225,7 @@
 		conf {
 			groups = "sdio0_2_grp";
 			slew-rate = <0>;
-			io-standard = <1>;
+			power-source = <1>;
 			bias-disable;
 		};
 
@@ -239,7 +239,7 @@
 			bias-high-impedance;
 			bias-pull-up;
 			slew-rate = <0>;
-			io-standard = <1>;
+			power-source = <1>;
 		};
 
 		mux-wp {
@@ -252,7 +252,7 @@
 			bias-high-impedance;
 			bias-pull-up;
 			slew-rate = <0>;
-			io-standard = <1>;
+			power-source = <1>;
 		};
 	};
 
@@ -265,7 +265,7 @@
 		conf {
 			groups = "uart1_10_grp";
 			slew-rate = <0>;
-			io-standard = <1>;
+			power-source = <1>;
 		};
 
 		conf-rx {
@@ -288,7 +288,7 @@
 		conf {
 			groups = "usb0_0_grp";
 			slew-rate = <0>;
-			io-standard = <1>;
+			power-source = <1>;
 		};
 
 		conf-rx {
@@ -307,6 +307,14 @@
 &qspi {
 	u-boot,dm-pre-reloc;
 	status = "okay";
+	num-cs = <1>;
+	flash@0 {
+		compatible = "n25q128a11", "jedec,spi-nor";
+		reg = <0x0>;
+		spi-tx-bus-width = <1>;
+		spi-rx-bus-width = <4>;
+		spi-max-frequency = <50000000>;
+	};
 };
 
 &sdhci0 {

+ 8 - 0
arch/arm/dts/zynq-zc770-xm010.dts

@@ -62,6 +62,14 @@
 
 &qspi {
 	status = "okay";
+	num-cs = <1>;
+	flash@0 {
+		compatible = "n25q128a11", "jedec,spi-nor";
+		reg = <0x0>;
+		spi-tx-bus-width = <1>;
+		spi-rx-bus-width = <4>;
+		spi-max-frequency = <50000000>;
+	};
 };
 
 &sdhci0 {

+ 9 - 0
arch/arm/dts/zynq-zc770-xm012.dts

@@ -53,6 +53,15 @@
 	};
 };
 
+&nor0 {
+	status = "okay";
+	bank-width = <1>;
+};
+
+&smcc {
+	status = "okay";
+};
+
 &spi1 {
 	status = "okay";
 	num-cs = <4>;

+ 8 - 0
arch/arm/dts/zynq-zc770-xm013.dts

@@ -61,6 +61,14 @@
 
 &qspi {
 	status = "okay";
+	num-cs = <1>;
+	flash@0 {
+		compatible = "n25q128a11", "jedec,spi-nor";
+		reg = <0x0>;
+		spi-tx-bus-width = <1>;
+		spi-rx-bus-width = <4>;
+		spi-max-frequency = <50000000>;
+	};
 };
 
 &spi0 {

+ 4 - 4
arch/arm/dts/zynqmp-sck-kv-g-revA.dts

@@ -12,10 +12,10 @@
  * Michal Simek <michal.simek@xilinx.com>
  */
 
- #include <dt-bindings/gpio/gpio.h>
- #include <dt-bindings/net/ti-dp83867.h>
- #include <dt-bindings/phy/phy.h>
- #include <dt-bindings/pinctrl/pinctrl-zynqmp.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/net/ti-dp83867.h>
+#include <dt-bindings/phy/phy.h>
+#include <dt-bindings/pinctrl/pinctrl-zynqmp.h>
 
 /dts-v1/;
 /plugin/;

+ 4 - 4
arch/arm/dts/zynqmp-sck-kv-g-revB.dts

@@ -7,10 +7,10 @@
  * Michal Simek <michal.simek@xilinx.com>
  */
 
- #include <dt-bindings/gpio/gpio.h>
- #include <dt-bindings/net/ti-dp83867.h>
- #include <dt-bindings/phy/phy.h>
- #include <dt-bindings/pinctrl/pinctrl-zynqmp.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/net/ti-dp83867.h>
+#include <dt-bindings/phy/phy.h>
+#include <dt-bindings/pinctrl/pinctrl-zynqmp.h>
 
 /dts-v1/;
 /plugin/;

+ 6 - 3
arch/arm/dts/zynqmp-sm-k26-revA.dts

@@ -60,13 +60,13 @@
 
 	leds {
 		compatible = "gpio-leds";
-		ds35 {
+		ds35-led {
 			label = "heartbeat";
 			gpios = <&gpio 7 GPIO_ACTIVE_HIGH>;
 			linux,default-trigger = "heartbeat";
 		};
 
-		ds36 {
+		ds36-led {
 			label = "vbus_det";
 			gpios = <&gpio 8 GPIO_ACTIVE_HIGH>;
 			default-state = "on";
@@ -183,7 +183,7 @@
 	};
 };
 
-&sdhci0 { /* MIO13-23 - 16GB emmc MTFC16GAPALBH-IT - U133A*/
+&sdhci0 { /* MIO13-23 - 16GB emmc MTFC16GAPALBH-IT - U133A */
 	status = "okay";
 	non-removable;
 	disable-wp;
@@ -204,17 +204,20 @@
 
 &i2c1 {
 	status = "okay";
+	u-boot,dm-pre-reloc;
 	clock-frequency = <400000>;
 	scl-gpios = <&gpio 24 GPIO_ACTIVE_HIGH>;
 	sda-gpios = <&gpio 25 GPIO_ACTIVE_HIGH>;
 
 	eeprom: eeprom@50 { /* u46 - also at address 0x58 */
+		u-boot,dm-pre-reloc;
 		compatible = "st,24c64", "atmel,24c64"; /* st m24c64 */
 		reg = <0x50>;
 		/* WP pin EE_WP_EN connected to slg7x644092@68 */
 	};
 
 	eeprom_cc: eeprom@51 { /* required by spec - also at address 0x59 */
+		u-boot,dm-pre-reloc;
 		compatible = "st,24c64", "atmel,24c64"; /* st m24c64 */
 		reg = <0x51>;
 	};

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

@@ -58,7 +58,7 @@
 	status = "okay";
 	is-dual = <1>;
 	flash@0 {
-		compatible = "st,m25p80", "n25q256a";
+		compatible = "st,m25p80", "n25q256a", "jedec,spi-nor";
 		m25p,fast-read;
 		reg = <0x0>;
 		spi-tx-bus-width = <1>;

+ 5 - 0
arch/arm/mach-versal/cpu.c

@@ -13,6 +13,7 @@
 #include <asm/arch/hardware.h>
 #include <asm/arch/sys_proto.h>
 #include <asm/cache.h>
+#include <dm/platdata.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -120,3 +121,7 @@ int arm_reserve_mmu(void)
 	return 0;
 }
 #endif
+
+U_BOOT_DRVINFO(soc_xilinx_versal) = {
+	.name = "soc_xilinx_versal",
+};

+ 4 - 0
arch/arm/mach-versal/include/mach/hardware.h

@@ -65,6 +65,10 @@ struct crp_regs {
 
 #define crp_base ((struct crp_regs *)VERSAL_CRP_BASEADDR)
 
+#define VERSAL_PS_PMC_VERSION	0xF11A0004
+#define VERSAL_PS_VER_MASK	GENMASK(7, 0)
+#define VERSAL_PS_VER_SHIFT	12
+
 /* Bootmode setting values */
 #define BOOT_MODES_MASK	0x0000000F
 #define QSPI_MODE_24BIT	0x00000001

+ 5 - 0
arch/arm/mach-zynqmp/cpu.c

@@ -15,6 +15,7 @@
 #include <asm/io.h>
 #include <zynqmp_firmware.h>
 #include <asm/cache.h>
+#include <dm/platdata.h>
 
 #define ZYNQ_SILICON_VER_MASK	0xF000
 #define ZYNQ_SILICON_VER_SHIFT	12
@@ -218,3 +219,7 @@ int zynqmp_mmio_read(const u32 address, u32 *value)
 
 	return ret;
 }
+
+U_BOOT_DRVINFO(soc_xilinx_zynqmp) = {
+	.name = "soc_xilinx_zynqmp",
+};

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

@@ -69,6 +69,9 @@ struct iou_scntr_secure {
 
 #define iou_scntr_secure ((struct iou_scntr_secure *)ZYNQMP_IOU_SCNTR_SECURE)
 
+#define ZYNQMP_PS_VERSION	0xFFCA0044
+#define ZYNQMP_PS_VER_MASK	GENMASK(1, 0)
+
 /* Bootmode setting values */
 #define BOOT_MODES_MASK	0x0000000F
 #define QSPI_MODE_24BIT	0x00000001

+ 49 - 2
arch/arm/mach-zynqmp/mkimage_fit_atf.sh

@@ -57,7 +57,7 @@ cat << __HEADER_EOF
 /dts-v1/;
 
 / {
-	description = "Configuration to load ATF before U-Boot";
+	description = "Configuration for Xilinx ZynqMP SoC";
 
 	images {
 		uboot {
@@ -78,7 +78,7 @@ __HEADER_EOF
 if [ -f $BL31 ]; then
 cat << __ATF
 		atf {
-			description = "ARM Trusted Firmware";
+			description = "Trusted Firmware-A";
 			data = /incbin/("$BL31");
 			type = "firmware";
 			os = "arm-trusted-firmware";
@@ -111,6 +111,51 @@ cat << __TEE
 __TEE
 fi
 
+MULTI_DTB=`awk '/CONFIG_MULTI_DTB_FIT / { print $3 }' include/generated/autoconf.h`
+
+if [ 1"$MULTI_DTB" -eq 11 ]; then
+	cat << __FDT_IMAGE_EOF
+		fdt_1 {
+			description = "Multi DTB fit image";
+			data = /incbin/("fit-dtb.blob");
+			type = "flat_dt";
+			arch = "arm64";
+			compression = "none";
+			$DTB_LOAD
+			hash {
+				algo = "md5";
+			};
+		};
+	};
+	configurations {
+		default = "config_1";
+__FDT_IMAGE_EOF
+
+if [ ! -f $BL31 ]; then
+cat << __CONF_SECTION1_EOF
+		config_1 {
+			description = "Multi DTB without TF-A";
+			firmware = "uboot";
+			loadables = "fdt_1";
+		};
+__CONF_SECTION1_EOF
+else
+cat << __CONF_SECTION1_EOF
+		config_1 {
+			description = "Multi DTB with TF-A";
+			firmware = "atf";
+			loadables = "uboot", "fdt_1";
+		};
+__CONF_SECTION1_EOF
+fi
+
+cat << __ITS_EOF
+	};
+};
+__ITS_EOF
+
+else
+
 DEFAULT=1
 cnt=1
 for dtname in $DT
@@ -181,3 +226,5 @@ cat << __ITS_EOF
 	};
 };
 __ITS_EOF
+
+fi

+ 155 - 29
board/xilinx/common/board.c

@@ -18,6 +18,8 @@
 #include <i2c_eeprom.h>
 #include <net.h>
 #include <generated/dt.h>
+#include <soc.h>
+#include <linux/ctype.h>
 
 #include "fru.h"
 
@@ -67,7 +69,7 @@ struct xilinx_board_description {
 };
 
 static int highest_id = -1;
-static struct xilinx_board_description **board_info;
+static struct xilinx_board_description *board_info;
 
 #define XILINX_I2C_DETECTION_BITS	sizeof(struct fru_common_hdr)
 
@@ -167,7 +169,7 @@ static bool xilinx_detect_legacy(u8 *buffer)
 static int xilinx_read_eeprom_fru(struct udevice *dev, char *name,
 				  struct xilinx_board_description *desc)
 {
-	int ret, eeprom_size;
+	int i, ret, eeprom_size;
 	u8 *fru_content;
 
 	/* FIXME this is shortcut - if eeprom type is wrong it will fail */
@@ -184,21 +186,23 @@ static int xilinx_read_eeprom_fru(struct udevice *dev, char *name,
 			  eeprom_size);
 	if (ret) {
 		debug("%s: I2C EEPROM read failed\n", __func__);
-		free(fru_content);
-		return ret;
+		goto end;
 	}
 
-	printf("Xilinx I2C FRU format at %s:\n", name);
 	fru_capture((unsigned long)fru_content);
-	ret = fru_display(0);
-	if (ret) {
-		printf("FRU format decoding failed.\n");
-		return ret;
+	if (gd->flags & GD_FLG_RELOC || (_DEBUG && CONFIG_IS_ENABLED(DTB_RESELECT))) {
+		printf("Xilinx I2C FRU format at %s:\n", name);
+		ret = fru_display(0);
+		if (ret) {
+			printf("FRU format decoding failed.\n");
+			goto end;
+		}
 	}
 
 	if (desc->header == EEPROM_HEADER_MAGIC) {
 		debug("Information already filled\n");
-		return -EINVAL;
+		ret = -EINVAL;
+		goto end;
 	}
 
 	/* It is clear that FRU was captured and structures were filled */
@@ -206,13 +210,19 @@ static int xilinx_read_eeprom_fru(struct udevice *dev, char *name,
 		sizeof(desc->manufacturer));
 	strncpy(desc->name, (char *)fru_data.brd.product_name,
 		sizeof(desc->name));
+	for (i = 0; i < sizeof(desc->name); i++) {
+		if (desc->name[i] == ' ')
+			desc->name[i] = '\0';
+	}
 	strncpy(desc->revision, (char *)fru_data.brd.rev,
 		sizeof(desc->revision));
 	strncpy(desc->serial, (char *)fru_data.brd.serial_number,
 		sizeof(desc->serial));
 	desc->header = EEPROM_HEADER_MAGIC;
 
-	return 0;
+end:
+	free(fru_content);
+	return ret;
 }
 
 static bool xilinx_detect_fru(u8 *buffer)
@@ -275,7 +285,7 @@ static int xilinx_read_eeprom_single(char *name,
 
 __maybe_unused int xilinx_read_eeprom(void)
 {
-	int id, ret;
+	int id;
 	char name_buf[8]; /* 8 bytes should be enough for nvmem+number */
 	struct xilinx_board_description *desc;
 
@@ -284,7 +294,7 @@ __maybe_unused int xilinx_read_eeprom(void)
 	if (highest_id < 0)
 		return -EINVAL;
 
-	board_info = calloc(1, sizeof(desc) * highest_id);
+	board_info = calloc(1, sizeof(*desc) * (highest_id + 1));
 	if (!board_info)
 		return -ENOMEM;
 
@@ -295,21 +305,10 @@ __maybe_unused int xilinx_read_eeprom(void)
 		snprintf(name_buf, sizeof(name_buf), "nvmem%d", id);
 
 		/* Alloc structure */
-		desc = board_info[id];
-		if (!desc) {
-			desc = calloc(1, sizeof(*desc));
-			if (!desc)
-				return -ENOMEM;
-
-			board_info[id] = desc;
-		}
+		desc = &board_info[id];
 
 		/* Ignoring return value for supporting multiple chips */
-		ret = xilinx_read_eeprom_single(name_buf, desc);
-		if (ret) {
-			free(desc);
-			board_info[id] = NULL;
-		}
+		xilinx_read_eeprom_single(name_buf, desc);
 	}
 
 	/*
@@ -395,7 +394,7 @@ int board_late_init_xilinx(void)
 	ret |= env_set_addr("bootm_size", (void *)bootm_size);
 
 	for (id = 0; id <= highest_id; id++) {
-		desc = board_info[id];
+		desc = &board_info[id];
 		if (desc && desc->header == EEPROM_HEADER_MAGIC) {
 			if (desc->manufacturer[0])
 				ret |= env_set_by_index("manufacturer", id,
@@ -431,12 +430,139 @@ int board_late_init_xilinx(void)
 }
 #endif
 
+static char *board_name = DEVICE_TREE;
+
 int __maybe_unused board_fit_config_name_match(const char *name)
 {
-	debug("%s: Check %s, default %s\n", __func__, name, DEVICE_TREE);
+	debug("%s: Check %s, default %s\n", __func__, name, board_name);
 
-	if (!strcmp(name, DEVICE_TREE))
+	if (!strcmp(name, board_name))
 		return 0;
 
 	return -1;
 }
+
+#if defined(CONFIG_DISPLAY_CPUINFO) && !defined(CONFIG_ARCH_ZYNQ)
+int print_cpuinfo(void)
+{
+	struct udevice *soc;
+	char name[SOC_MAX_STR_SIZE];
+	int ret;
+
+	ret = soc_get(&soc);
+	if (ret) {
+		printf("CPU:   UNKNOWN\n");
+		return 0;
+	}
+
+	ret = soc_get_family(soc, name, SOC_MAX_STR_SIZE);
+	if (ret)
+		printf("CPU:   %s\n", name);
+
+	ret = soc_get_revision(soc, name, SOC_MAX_STR_SIZE);
+	if (ret)
+		printf("Silicon: %s\n", name);
+
+	return 0;
+}
+#endif
+
+#if CONFIG_IS_ENABLED(DTB_RESELECT)
+#define MAX_NAME_LENGTH	50
+
+char * __maybe_unused __weak board_name_decode(void)
+{
+	char *board_local_name;
+	struct xilinx_board_description *desc;
+	int i, id;
+
+	board_local_name = calloc(1, MAX_NAME_LENGTH);
+	if (!board_info)
+		return NULL;
+
+	for (id = 0; id <= highest_id; id++) {
+		desc = &board_info[id];
+
+		/* No board description */
+		if (!desc)
+			goto error;
+
+		/* Board is not detected */
+		if (desc->header != EEPROM_HEADER_MAGIC)
+			continue;
+
+		/* The first string should be soc name */
+		if (!id)
+			strcat(board_local_name, CONFIG_SYS_BOARD);
+
+		/*
+		 * For two purpose here:
+		 * soc_name- eg: zynqmp-
+		 * and between base board and CC eg: ..revA-sck...
+		 */
+		strcat(board_local_name, "-");
+
+		if (desc->name[0]) {
+			/* For DT composition name needs to be lowercase */
+			for (i = 0; i < sizeof(desc->name); i++)
+				desc->name[i] = tolower(desc->name[i]);
+
+			strcat(board_local_name, desc->name);
+		}
+		if (desc->revision[0]) {
+			strcat(board_local_name, "-rev");
+
+			/* And revision needs to be uppercase */
+			for (i = 0; i < sizeof(desc->revision); i++)
+				desc->revision[i] = toupper(desc->revision[i]);
+
+			strcat(board_local_name, desc->revision);
+		}
+	}
+
+	/*
+	 * Longer strings will end up with buffer overflow and potential
+	 * attacks that's why check it
+	 */
+	if (strlen(board_local_name) >= MAX_NAME_LENGTH)
+		panic("Board name can't be determined\n");
+
+	if (strlen(board_local_name))
+		return board_local_name;
+
+error:
+	free(board_local_name);
+	return NULL;
+}
+
+bool __maybe_unused __weak board_detection(void)
+{
+	if (CONFIG_IS_ENABLED(DM_I2C) && CONFIG_IS_ENABLED(I2C_EEPROM)) {
+		int ret;
+
+		ret = xilinx_read_eeprom();
+		return !ret ? true : false;
+	}
+
+	return false;
+}
+
+int embedded_dtb_select(void)
+{
+	if (board_detection()) {
+		char *board_local_name;
+
+		board_local_name = board_name_decode();
+		if (board_local_name) {
+			board_name = board_local_name;
+			printf("Detected name: %s\n", board_name);
+
+			/* Time to change DTB on fly */
+			/* Both ways should work here */
+			/* fdtdec_resetup(&rescan); */
+			fdtdec_setup();
+		}
+	}
+	return 0;
+}
+#endif

+ 0 - 2
board/xilinx/zynqmp/Makefile

@@ -44,8 +44,6 @@ $(obj)/pm_cfg_obj.o: $(shell cd $(srctree); readlink -f $(CONFIG_ZYNQMP_SPL_PM_C
 endif
 endif
 
-obj-$(CONFIG_MMC_SDHCI_ZYNQ) += tap_delays.o
-
 ifndef CONFIG_SPL_BUILD
 obj-$(CONFIG_CMD_ZYNQMP) += cmds.o
 endif

+ 0 - 101
board/xilinx/zynqmp/tap_delays.c

@@ -1,101 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Xilinx ZynqMP SoC Tap Delay Programming
- *
- * Copyright (C) 2018 Xilinx, Inc.
- */
-
-#include <common.h>
-#include <zynqmp_tap_delay.h>
-#include <asm/arch/sys_proto.h>
-#include <linux/delay.h>
-#include <mmc.h>
-
-#define SD_DLL_CTRL			0xFF180358
-#define SD_ITAP_DLY			0xFF180314
-#define SD_OTAP_DLY			0xFF180318
-#define SD0_DLL_RST_MASK		0x00000004
-#define SD0_DLL_RST			0x00000004
-#define SD1_DLL_RST_MASK		0x00040000
-#define SD1_DLL_RST			0x00040000
-#define SD0_ITAPCHGWIN_MASK		0x00000200
-#define SD0_ITAPCHGWIN			0x00000200
-#define SD1_ITAPCHGWIN_MASK		0x02000000
-#define SD1_ITAPCHGWIN			0x02000000
-#define SD0_ITAPDLYENA_MASK		0x00000100
-#define SD0_ITAPDLYENA			0x00000100
-#define SD1_ITAPDLYENA_MASK		0x01000000
-#define SD1_ITAPDLYENA			0x01000000
-#define SD0_ITAPDLYSEL_MASK		0x000000FF
-#define SD1_ITAPDLYSEL_MASK		0x00FF0000
-#define SD0_OTAPDLYSEL_MASK		0x0000003F
-#define SD1_OTAPDLYSEL_MASK		0x003F0000
-
-void zynqmp_dll_reset(u8 deviceid)
-{
-	/* Issue DLL Reset */
-	if (deviceid == 0)
-		zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST_MASK,
-				  SD0_DLL_RST);
-	else
-		zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST_MASK,
-				  SD1_DLL_RST);
-
-	mdelay(1);
-
-	/* Release DLL Reset */
-	if (deviceid == 0)
-		zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST_MASK, 0x0);
-	else
-		zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST_MASK, 0x0);
-}
-
-void arasan_zynqmp_set_in_tapdelay(u8 deviceid, u32 itap_delay)
-{
-	if (deviceid == 0) {
-		zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST_MASK, SD0_DLL_RST);
-
-		/* Program ITAP delay */
-		zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPCHGWIN_MASK,
-				  SD0_ITAPCHGWIN);
-		zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPDLYENA_MASK,
-				  SD0_ITAPDLYENA);
-		zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPDLYSEL_MASK, itap_delay);
-		zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPCHGWIN_MASK, 0x0);
-
-		zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST_MASK, 0x0);
-	} else {
-		zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST_MASK, SD1_DLL_RST);
-
-		/* Program ITAP delay */
-		zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPCHGWIN_MASK,
-				  SD1_ITAPCHGWIN);
-		zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPDLYENA_MASK,
-				  SD1_ITAPDLYENA);
-		zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPDLYSEL_MASK,
-				  (itap_delay << 16));
-		zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPCHGWIN_MASK, 0x0);
-
-		zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST_MASK, 0x0);
-	}
-}
-
-void arasan_zynqmp_set_out_tapdelay(u8 deviceid, u32 otap_delay)
-{
-	if (deviceid == 0) {
-		zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST_MASK, SD0_DLL_RST);
-
-		/* Program OTAP delay */
-		zynqmp_mmio_write(SD_OTAP_DLY, SD0_OTAPDLYSEL_MASK, otap_delay);
-
-		zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST_MASK, 0x0);
-	} else {
-		zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST_MASK, SD1_DLL_RST);
-
-		/* Program OTAP delay */
-		zynqmp_mmio_write(SD_OTAP_DLY, SD1_OTAPDLYSEL_MASK,
-				  (otap_delay << 16));
-
-		zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST_MASK, 0x0);
-	}
-}

+ 68 - 6
board/xilinx/zynqmp/zynqmp.c

@@ -8,6 +8,7 @@
 #include <command.h>
 #include <cpu_func.h>
 #include <debug_uart.h>
+#include <dfu.h>
 #include <env.h>
 #include <env_internal.h>
 #include <init.h>
@@ -19,6 +20,7 @@
 #include <ahci.h>
 #include <scsi.h>
 #include <malloc.h>
+#include <memalign.h>
 #include <wdt.h>
 #include <asm/arch/clk.h>
 #include <asm/arch/hardware.h>
@@ -346,13 +348,14 @@ int board_early_init_f(void)
 
 static int multi_boot(void)
 {
-	u32 multiboot;
-
-	multiboot = readl(&csu_base->multi_boot);
+	u32 multiboot = 0;
+	int ret;
 
-	printf("Multiboot:\t%d\n", multiboot);
+	ret = zynqmp_mmio_read((ulong)&csu_base->multi_boot, &multiboot);
+	if (ret)
+		return -EINVAL;
 
-	return 0;
+	return multiboot;
 }
 
 #define PS_SYSMON_ANALOG_BUS_VAL	0x3210
@@ -392,7 +395,7 @@ int board_init(void)
 #endif
 
 	if (current_el() == 3)
-		multi_boot();
+		printf("Multiboot:\t%d\n", multi_boot());
 
 	return 0;
 }
@@ -467,6 +470,9 @@ ulong board_get_usable_ram_top(ulong total_size)
 	phys_addr_t reg;
 	struct lmb lmb;
 
+	if (!IS_ALIGNED((ulong)gd->fdt_blob, 0x8))
+		panic("Not 64bit aligned DT location: %p\n", gd->fdt_blob);
+
 	/* found enough not-reserved memory to relocated U-Boot */
 	lmb_init(&lmb);
 	lmb_add(&lmb, gd->ram_base, gd->ram_size);
@@ -515,6 +521,9 @@ static u8 __maybe_unused zynqmp_get_bootmode(void)
 	if (ret)
 		return -EINVAL;
 
+	debug("HW boot mode: %x\n", reg & BOOT_MODES_MASK);
+	debug("ALT boot mode: %x\n", reg >> BOOT_MODE_ALT_SHIFT);
+
 	if (reg >> BOOT_MODE_ALT_SHIFT)
 		reg >>= BOOT_MODE_ALT_SHIFT;
 
@@ -735,6 +744,7 @@ int board_late_init(void)
 			env_targets ? env_targets : "");
 
 	env_set("boot_targets", new_targets);
+	free(new_targets);
 
 	reset_reason();
 
@@ -816,3 +826,55 @@ enum env_location env_get_location(enum env_operation op, int prio)
 		return ENVL_NOWHERE;
 	}
 }
+
+#if defined(CONFIG_SET_DFU_ALT_INFO)
+
+#define DFU_ALT_BUF_LEN		SZ_1K
+
+void set_dfu_alt_info(char *interface, char *devstr)
+{
+	u8 multiboot;
+	int bootseq = 0;
+
+	ALLOC_CACHE_ALIGN_BUFFER(char, buf, DFU_ALT_BUF_LEN);
+
+	if (env_get("dfu_alt_info"))
+		return;
+
+	memset(buf, 0, sizeof(buf));
+
+	multiboot = multi_boot();
+	debug("Multiboot: %d\n", multiboot);
+
+	switch (zynqmp_get_bootmode()) {
+	case EMMC_MODE:
+	case SD_MODE:
+	case SD1_LSHFT_MODE:
+	case SD_MODE1:
+		bootseq = mmc_get_env_dev();
+		if (!multiboot)
+			snprintf(buf, DFU_ALT_BUF_LEN,
+				 "mmc %d:1=boot.bin fat %d 1;"
+				 "u-boot.itb fat %d 1",
+				 bootseq, bootseq, bootseq);
+		else
+			snprintf(buf, DFU_ALT_BUF_LEN,
+				 "mmc %d:1=boot%04d.bin fat %d 1;"
+				 "u-boot.itb fat %d 1",
+				 bootseq, multiboot, bootseq, bootseq);
+		break;
+	case QSPI_MODE_24BIT:
+	case QSPI_MODE_32BIT:
+		snprintf(buf, DFU_ALT_BUF_LEN,
+			 "sf 0:0=boot.bin raw %x 0x1500000;"
+			 "u-boot.itb raw 0x%x 0x500000",
+			 multiboot * SZ_32K, CONFIG_SYS_SPI_U_BOOT_OFFS);
+		break;
+	default:
+		return;
+	}
+
+	env_set("dfu_alt_info", buf);
+	puts("DFU alt info setting: done\n");
+}
+#endif

+ 2 - 1
cmd/boot.c

@@ -58,7 +58,8 @@ U_BOOT_CMD(
 U_BOOT_CMD(
 	reset, 2, 0,	do_reset,
 	"Perform RESET of the CPU",
-	""
+	"- cold boot without level specifier\n"
+	"reset -w - warm reset if implemented"
 );
 
 #ifdef CONFIG_CMD_POWEROFF

+ 6 - 3
cmd/date.c

@@ -41,10 +41,13 @@ static int do_date(struct cmd_tbl *cmdtp, int flag, int argc,
 #ifdef CONFIG_DM_RTC
 	struct udevice *dev;
 
-	rcode = uclass_get_device(UCLASS_RTC, 0, &dev);
+	rcode = uclass_get_device_by_seq(UCLASS_RTC, 0, &dev);
 	if (rcode) {
-		printf("Cannot find RTC: err=%d\n", rcode);
-		return CMD_RET_FAILURE;
+		rcode = uclass_get_device(UCLASS_RTC, 0, &dev);
+		if (rcode) {
+			printf("Cannot find RTC: err=%d\n", rcode);
+			return CMD_RET_FAILURE;
+		}
 	}
 #elif defined(CONFIG_SYS_I2C_LEGACY)
 	old_bus = i2c_get_bus_num();

+ 4 - 3
cmd/pwm.c

@@ -108,7 +108,8 @@ static int do_pwm(struct cmd_tbl *cmdtp, int flag, int argc,
 
 U_BOOT_CMD(pwm, 6, 0, do_pwm,
 	   "control pwm channels",
-	   "pwm <invert> <pwm_dev_num> <channel> <polarity>\n"
-	   "pwm <config> <pwm_dev_num> <channel> <period_ns> <duty_ns>\n"
-	   "pwm <enable/disable> <pwm_dev_num> <channel>\n"
+	   "invert <pwm_dev_num> <channel> <polarity> - invert polarity\n"
+	   "pwm config <pwm_dev_num> <channel> <period_ns> <duty_ns> - config PWM\n"
+	   "pwm enable <pwm_dev_num> <channel> - enable PWM output\n"
+	   "pwm disable <pwm_dev_num> <channel> - eisable PWM output\n"
 	   "Note: All input values are in decimal");

+ 18 - 0
common/fdt_support.c

@@ -420,6 +420,24 @@ static int fdt_pack_reg(const void *fdt, void *buf, u64 *address, u64 *size,
 #else
 #define MEMORY_BANKS_MAX 4
 #endif
+
+/**
+ * fdt_fixup_memory_banks - Update DT memory node
+ * @blob: Pointer to DT blob
+ * @start: Pointer to memory start addresses array
+ * @size: Pointer to memory sizes array
+ * @banks: Number of memory banks
+ *
+ * Return: 0 on success, negative value on failure
+ *
+ * Based on the passed number of banks and arrays, the function is able to
+ * update existing DT memory nodes to match run time detected/changed memory
+ * configuration. Implementation is handling one specific case with only one
+ * memory node where multiple tuples could be added/updated.
+ * The case where multiple memory nodes with a single tuple (base, size) are
+ * used, this function is only updating the first memory node without removing
+ * others.
+ */
 int fdt_fixup_memory_banks(void *blob, u64 start[], u64 size[], int banks)
 {
 	int err, nodeoffset;

+ 2 - 1
configs/xilinx_versal_virt_defconfig

@@ -13,9 +13,9 @@ CONFIG_COUNTER_FREQUENCY=100000000
 CONFIG_DISTRO_DEFAULTS=y
 CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
+# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
 CONFIG_BOOTDELAY=5
 CONFIG_USE_PREBOOT=y
-# CONFIG_DISPLAY_CPUINFO is not set
 CONFIG_BOARD_EARLY_INIT_R=y
 CONFIG_SYS_PROMPT="Versal> "
 CONFIG_CMD_BOOTMENU=y
@@ -95,6 +95,7 @@ CONFIG_ZYNQ_GEM=y
 CONFIG_ARM_DCC=y
 CONFIG_PL01X_SERIAL=y
 CONFIG_XILINX_UARTLITE=y
+CONFIG_SOC_XILINX_VERSAL=y
 CONFIG_SPI=y
 CONFIG_DM_SPI=y
 CONFIG_ZYNQ_SPI=y

+ 1 - 0
configs/xilinx_zynq_virt_defconfig

@@ -22,6 +22,7 @@ CONFIG_SPL_LOAD_FIT=y
 CONFIG_SPL_LOAD_FIT_ADDRESS=0x10000000
 # CONFIG_USE_SPL_FIT_GENERATOR is not set
 CONFIG_LEGACY_IMAGE_FORMAT=y
+# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
 CONFIG_USE_PREBOOT=y
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_FPGA=y

+ 14 - 2
configs/xilinx_zynqmp_virt_defconfig

@@ -5,8 +5,12 @@ CONFIG_SYS_TEXT_BASE=0x8000000
 CONFIG_SYS_MALLOC_F_LEN=0x8000
 CONFIG_SYS_MEMTEST_START=0x00000000
 CONFIG_SYS_MEMTEST_END=0x00001000
+CONFIG_SYS_SPI_U_BOOT_OFFS=0x100000
 CONFIG_DM_GPIO=y
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu100-revC"
+CONFIG_SPL_STACK_R_ADDR=0x18000000
+CONFIG_SPL_SIZE_LIMIT=0x2a000
+CONFIG_SPL_SIZE_LIMIT_PROVIDE_STACK=0x0
 CONFIG_SPL=y
 CONFIG_SPL_SPI_FLASH_SUPPORT=y
 CONFIG_SPL_SPI_SUPPORT=y
@@ -20,10 +24,12 @@ CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_SPL_LOAD_FIT=y
 CONFIG_SPL_LOAD_FIT_ADDRESS=0x10000000
+# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
 CONFIG_USE_PREBOOT=y
-# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_PREBOOT="run scsi_init;usb start"
 CONFIG_BOARD_EARLY_INIT_F=y
 CONFIG_BOARD_EARLY_INIT_R=y
+CONFIG_SPL_STACK_R=y
 CONFIG_SPL_FPGA=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_RAM_SUPPORT=y
@@ -36,6 +42,7 @@ CONFIG_CMD_THOR_DOWNLOAD=y
 CONFIG_CMD_NVEDIT_EFI=y
 CONFIG_CMD_MEMTEST=y
 CONFIG_SYS_ALT_MEMTEST=y
+CONFIG_CMD_SHA1SUM=y
 CONFIG_CMD_BIND=y
 CONFIG_CMD_CLK=y
 CONFIG_CMD_DFU=y
@@ -59,6 +66,7 @@ CONFIG_CMD_TFTPPUT=y
 CONFIG_CMD_BMP=y
 CONFIG_CMD_CACHE=y
 CONFIG_CMD_EFIDEBUG=y
+CONFIG_CMD_RTC=y
 CONFIG_CMD_TIME=y
 CONFIG_CMD_GETTIME=y
 CONFIG_CMD_TIMER=y
@@ -85,6 +93,8 @@ CONFIG_NETCONSOLE=y
 CONFIG_SPL_DM_SEQ_ALIAS=y
 CONFIG_SCSI_AHCI=y
 CONFIG_SATA_CEVA=y
+CONFIG_BUTTON=y
+CONFIG_BUTTON_GPIO=y
 CONFIG_CLK_ZYNQMP=y
 CONFIG_DFU_TFTP=y
 CONFIG_DFU_TIMEOUT=y
@@ -93,6 +103,7 @@ CONFIG_DFU_NAND=y
 CONFIG_DFU_RAM=y
 CONFIG_DFU_SF=y
 CONFIG_DFU_MTD=y
+CONFIG_SET_DFU_ALT_INFO=y
 CONFIG_SYS_DFU_DATA_BUF_SIZE=0x1800000
 CONFIG_USB_FUNCTION_FASTBOOT=y
 CONFIG_FASTBOOT_FLASH=y
@@ -149,11 +160,13 @@ CONFIG_DM_REGULATOR=y
 CONFIG_DM_REGULATOR_FIXED=y
 CONFIG_DM_RTC=y
 CONFIG_RTC_EMULATION=y
+CONFIG_RTC_ZYNQMP=y
 CONFIG_SCSI=y
 CONFIG_DM_SCSI=y
 CONFIG_ARM_DCC=y
 CONFIG_XILINX_UARTLITE=y
 CONFIG_ZYNQ_SERIAL=y
+CONFIG_SOC_XILINX_ZYNQMP=y
 CONFIG_SPI=y
 CONFIG_ZYNQ_SPI=y
 CONFIG_ZYNQMP_GQSPI=y
@@ -187,7 +200,6 @@ CONFIG_BMP_16BPP=y
 CONFIG_BMP_24BPP=y
 CONFIG_BMP_32BPP=y
 CONFIG_WDT=y
-CONFIG_WDT_CDNS=y
 CONFIG_PANIC_HANG=y
 CONFIG_TPM=y
 CONFIG_SPL_GZIP=y

+ 8 - 2
drivers/mmc/sdhci.c

@@ -366,6 +366,7 @@ int sdhci_set_clock(struct mmc *mmc, unsigned int clock)
 {
 	struct sdhci_host *host = mmc->priv;
 	unsigned int div, clk = 0, timeout;
+	int ret;
 
 	/* Wait max 20 ms */
 	timeout = 200;
@@ -386,8 +387,13 @@ int sdhci_set_clock(struct mmc *mmc, unsigned int clock)
 	if (clock == 0)
 		return 0;
 
-	if (host->ops && host->ops->set_delay)
-		host->ops->set_delay(host);
+	if (host->ops && host->ops->set_delay) {
+		ret = host->ops->set_delay(host);
+		if (ret) {
+			printf("%s: Error while setting tap delay\n", __func__);
+			return ret;
+		}
+	}
 
 	if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) {
 		/*

+ 204 - 40
drivers/mmc/zynq_sdhci.c

@@ -15,9 +15,10 @@
 #include <dm/device_compat.h>
 #include <linux/err.h>
 #include <linux/libfdt.h>
+#include <asm/cache.h>
 #include <malloc.h>
 #include <sdhci.h>
-#include <zynqmp_tap_delay.h>
+#include <zynqmp_firmware.h>
 
 #define SDHCI_ARASAN_ITAPDLY_REGISTER	0xF0F8
 #define SDHCI_ARASAN_ITAPDLY_SEL_MASK	GENMASK(7, 0)
@@ -30,6 +31,20 @@
 #define SDHCI_TUNING_LOOP_COUNT		40
 #define MMC_BANK2			0x2
 
+#define SD_DLL_CTRL			0xFF180358
+#define SD_ITAP_DLY			0xFF180314
+#define SD_OTAP_DLY			0xFF180318
+#define SD0_DLL_RST			BIT(2)
+#define SD1_DLL_RST			BIT(18)
+#define SD0_ITAPCHGWIN			BIT(9)
+#define SD1_ITAPCHGWIN			BIT(25)
+#define SD0_ITAPDLYENA			BIT(8)
+#define SD1_ITAPDLYENA			BIT(24)
+#define SD0_ITAPDLYSEL_MASK		GENMASK(7, 0)
+#define SD1_ITAPDLYSEL_MASK		GENMASK(23, 16)
+#define SD0_OTAPDLYSEL_MASK		GENMASK(5, 0)
+#define SD1_OTAPDLYSEL_MASK		GENMASK(21, 16)
+
 struct arasan_sdhci_clk_data {
 	int clk_phase_in[MMC_TIMING_MMC_HS400 + 1];
 	int clk_phase_out[MMC_TIMING_MMC_HS400 + 1];
@@ -48,6 +63,12 @@ struct arasan_sdhci_priv {
 	u8 no_1p8;
 };
 
+/* For Versal platforms zynqmp_mmio_write() won't be available */
+__weak int zynqmp_mmio_write(const u32 address, const u32 mask, const u32 value)
+{
+	return 0;
+}
+
 #if defined(CONFIG_ARCH_ZYNQMP) || defined(CONFIG_ARCH_VERSAL)
 /* Default settings for ZynqMP Clock Phases */
 static const u32 zynqmp_iclk_phases[] = {0, 63, 63, 0, 63,  0,
@@ -75,26 +96,126 @@ static const u8 mode2timing[] = {
 	[MMC_HS_200] = MMC_TIMING_MMC_HS200,
 };
 
-static void arasan_zynqmp_dll_reset(struct sdhci_host *host, u8 deviceid)
+static inline int arasan_zynqmp_set_in_tapdelay(u8 node_id, u32 itap_delay)
 {
-	u16 clk;
+	int ret;
+
+	if (IS_ENABLED(CONFIG_SPL_BUILD) || current_el() == 3) {
+		if (node_id == NODE_SD_0) {
+			ret = zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPCHGWIN,
+						SD0_ITAPCHGWIN);
+			if (ret)
+				return ret;
+
+			ret = zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPDLYENA,
+						SD0_ITAPDLYENA);
+			if (ret)
+				return ret;
+
+			ret = zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPDLYSEL_MASK,
+						itap_delay);
+			if (ret)
+				return ret;
+
+			ret = zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPCHGWIN, 0);
+			if (ret)
+				return ret;
+		}
+		ret = zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPCHGWIN,
+					SD1_ITAPCHGWIN);
+		if (ret)
+			return ret;
+
+		ret = zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPDLYENA,
+					SD1_ITAPDLYENA);
+		if (ret)
+			return ret;
+
+		ret = zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPDLYSEL_MASK,
+					(itap_delay << 16));
+		if (ret)
+			return ret;
+
+		ret = zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPCHGWIN, 0);
+		if (ret)
+			return ret;
+	} else {
+		return xilinx_pm_request(PM_IOCTL, (u32)node_id,
+					 IOCTL_SET_SD_TAPDELAY,
+					 PM_TAPDELAY_INPUT, itap_delay, NULL);
+	}
+
+	return 0;
+}
+
+static inline int arasan_zynqmp_set_out_tapdelay(u8 node_id, u32 otap_delay)
+{
+	if (IS_ENABLED(CONFIG_SPL_BUILD) || current_el() == 3) {
+		if (node_id == NODE_SD_0)
+			return zynqmp_mmio_write(SD_OTAP_DLY,
+						 SD0_OTAPDLYSEL_MASK,
+						 otap_delay);
+
+		return zynqmp_mmio_write(SD_OTAP_DLY, SD1_OTAPDLYSEL_MASK,
+					 (otap_delay << 16));
+	} else {
+		return xilinx_pm_request(PM_IOCTL, (u32)node_id,
+					 IOCTL_SET_SD_TAPDELAY,
+					 PM_TAPDELAY_OUTPUT, otap_delay, NULL);
+	}
+}
+
+static inline int zynqmp_dll_reset(u8 node_id, u32 type)
+{
+	if (IS_ENABLED(CONFIG_SPL_BUILD) || current_el() == 3) {
+		if (node_id == NODE_SD_0)
+			return zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST,
+						 type == PM_DLL_RESET_ASSERT ?
+						 SD0_DLL_RST : 0);
+
+		return zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST,
+					 type == PM_DLL_RESET_ASSERT ?
+					 SD1_DLL_RST : 0);
+	} else {
+		return xilinx_pm_request(PM_IOCTL, (u32)node_id,
+					 IOCTL_SD_DLL_RESET, type, 0, NULL);
+	}
+}
+
+static int arasan_zynqmp_dll_reset(struct sdhci_host *host, u8 node_id)
+{
+	struct mmc *mmc = (struct mmc *)host->mmc;
+	struct udevice *dev = mmc->dev;
 	unsigned long timeout;
+	int ret;
+	u16 clk;
 
 	clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
 	clk &= ~(SDHCI_CLOCK_CARD_EN);
 	sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
 
 	/* Issue DLL Reset */
-	zynqmp_dll_reset(deviceid);
+	ret = zynqmp_dll_reset(node_id, PM_DLL_RESET_ASSERT);
+	if (ret) {
+		dev_err(dev, "dll_reset assert failed with err: %d\n", ret);
+		return ret;
+	}
+
+	/* Allow atleast 1ms delay for proper DLL reset */
+	mdelay(1);
+	ret = zynqmp_dll_reset(node_id, PM_DLL_RESET_RELEASE);
+	if (ret) {
+		dev_err(dev, "dll_reset release failed with err: %d\n", ret);
+		return ret;
+	}
 
 	/* Wait max 20 ms */
 	timeout = 100;
 	while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL))
 				& SDHCI_CLOCK_INT_STABLE)) {
 		if (timeout == 0) {
-			dev_err(mmc_dev(host->mmc),
-				": Internal clock never stabilised.\n");
-			return;
+			dev_err(dev, ": Internal clock never stabilised.\n");
+			return -EBUSY;
 		}
 		timeout--;
 		udelay(1000);
@@ -102,6 +223,8 @@ static void arasan_zynqmp_dll_reset(struct sdhci_host *host, u8 deviceid)
 
 	clk |= SDHCI_CLOCK_CARD_EN;
 	sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
+
+	return 0;
 }
 
 static int arasan_sdhci_execute_tuning(struct mmc *mmc, u8 opcode)
@@ -112,12 +235,11 @@ static int arasan_sdhci_execute_tuning(struct mmc *mmc, u8 opcode)
 	struct sdhci_host *host;
 	struct arasan_sdhci_priv *priv = dev_get_priv(mmc->dev);
 	char tuning_loop_counter = SDHCI_TUNING_LOOP_COUNT;
-	u8 deviceid;
+	u8 node_id = priv->deviceid ? NODE_SD_1 : NODE_SD_0;
 
 	debug("%s\n", __func__);
 
 	host = priv->host;
-	deviceid = priv->deviceid;
 
 	ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
 	ctrl |= SDHCI_CTRL_EXEC_TUNING;
@@ -125,7 +247,7 @@ static int arasan_sdhci_execute_tuning(struct mmc *mmc, u8 opcode)
 
 	mdelay(1);
 
-	arasan_zynqmp_dll_reset(host, deviceid);
+	arasan_zynqmp_dll_reset(host, node_id);
 
 	sdhci_writel(host, SDHCI_INT_DATA_AVAIL, SDHCI_INT_ENABLE);
 	sdhci_writel(host, SDHCI_INT_DATA_AVAIL, SDHCI_SIGNAL_ENABLE);
@@ -171,7 +293,7 @@ static int arasan_sdhci_execute_tuning(struct mmc *mmc, u8 opcode)
 	}
 
 	udelay(1);
-	arasan_zynqmp_dll_reset(host, deviceid);
+	arasan_zynqmp_dll_reset(host, node_id);
 
 	/* Enable only interrupts served by the SD controller */
 	sdhci_writel(host, SDHCI_INT_DATA_MASK | SDHCI_INT_CMD_MASK,
@@ -194,10 +316,13 @@ static int arasan_sdhci_execute_tuning(struct mmc *mmc, u8 opcode)
 static int sdhci_zynqmp_sdcardclk_set_phase(struct sdhci_host *host,
 					    int degrees)
 {
-	struct arasan_sdhci_priv *priv = dev_get_priv(host->mmc->dev);
 	struct mmc *mmc = (struct mmc *)host->mmc;
+	struct udevice *dev = mmc->dev;
+	struct arasan_sdhci_priv *priv = dev_get_priv(mmc->dev);
+	u8 node_id = priv->deviceid ? NODE_SD_1 : NODE_SD_0;
 	u8 tap_delay, tap_max = 0;
 	int timing = mode2timing[mmc->selected_mode];
+	int ret;
 
 	/*
 	 * This is applicable for SDHCI_SPEC_300 and above
@@ -233,7 +358,19 @@ static int sdhci_zynqmp_sdcardclk_set_phase(struct sdhci_host *host,
 	/* Limit output tap_delay value to 6 bits */
 	tap_delay &= SDHCI_ARASAN_OTAPDLY_SEL_MASK;
 
-	arasan_zynqmp_set_out_tapdelay(priv->deviceid, tap_delay);
+	/* Set the Clock Phase */
+	ret = arasan_zynqmp_set_out_tapdelay(node_id, tap_delay);
+	if (ret) {
+		dev_err(dev, "Error setting output Tap Delay\n");
+		return ret;
+	}
+
+	/* Release DLL Reset */
+	ret = zynqmp_dll_reset(node_id, PM_DLL_RESET_RELEASE);
+	if (ret) {
+		dev_err(dev, "dll_reset release failed with err: %d\n", ret);
+		return ret;
+	}
 
 	return 0;
 }
@@ -250,10 +387,13 @@ static int sdhci_zynqmp_sdcardclk_set_phase(struct sdhci_host *host,
 static int sdhci_zynqmp_sampleclk_set_phase(struct sdhci_host *host,
 					    int degrees)
 {
-	struct arasan_sdhci_priv *priv = dev_get_priv(host->mmc->dev);
 	struct mmc *mmc = (struct mmc *)host->mmc;
+	struct udevice *dev = mmc->dev;
+	struct arasan_sdhci_priv *priv = dev_get_priv(mmc->dev);
+	u8 node_id = priv->deviceid ? NODE_SD_1 : NODE_SD_0;
 	u8 tap_delay, tap_max = 0;
 	int timing = mode2timing[mmc->selected_mode];
+	int ret;
 
 	/*
 	 * This is applicable for SDHCI_SPEC_300 and above
@@ -263,6 +403,13 @@ static int sdhci_zynqmp_sampleclk_set_phase(struct sdhci_host *host,
 	if (SDHCI_GET_VERSION(host) < SDHCI_SPEC_300)
 		return 0;
 
+	/* Assert DLL Reset */
+	ret = zynqmp_dll_reset(node_id, PM_DLL_RESET_ASSERT);
+	if (ret) {
+		dev_err(dev, "dll_reset assert failed with err: %d\n", ret);
+		return ret;
+	}
+
 	switch (timing) {
 	case MMC_TIMING_MMC_HS:
 	case MMC_TIMING_SD_HS:
@@ -289,7 +436,11 @@ static int sdhci_zynqmp_sampleclk_set_phase(struct sdhci_host *host,
 	/* Limit input tap_delay value to 8 bits */
 	tap_delay &= SDHCI_ARASAN_ITAPDLY_SEL_MASK;
 
-	arasan_zynqmp_set_in_tapdelay(priv->deviceid, tap_delay);
+	ret = arasan_zynqmp_set_in_tapdelay(node_id, tap_delay);
+	if (ret) {
+		dev_err(dev, "Error setting Input Tap Delay\n");
+		return ret;
+	}
 
 	return 0;
 }
@@ -422,7 +573,7 @@ static int sdhci_versal_sampleclk_set_phase(struct sdhci_host *host,
 	return 0;
 }
 
-static void arasan_sdhci_set_tapdelay(struct sdhci_host *host)
+static int arasan_sdhci_set_tapdelay(struct sdhci_host *host)
 {
 	struct arasan_sdhci_priv *priv = dev_get_priv(host->mmc->dev);
 	struct arasan_sdhci_clk_data *clk_data = &priv->clk_data;
@@ -431,18 +582,31 @@ static void arasan_sdhci_set_tapdelay(struct sdhci_host *host)
 	u8 timing = mode2timing[mmc->selected_mode];
 	u32 iclk_phase = clk_data->clk_phase_in[timing];
 	u32 oclk_phase = clk_data->clk_phase_out[timing];
+	int ret;
 
 	dev_dbg(dev, "%s, host:%s, mode:%d\n", __func__, host->name, timing);
 
 	if (IS_ENABLED(CONFIG_ARCH_ZYNQMP) &&
 	    device_is_compatible(dev, "xlnx,zynqmp-8.9a")) {
-		sdhci_zynqmp_sampleclk_set_phase(host, iclk_phase);
-		sdhci_zynqmp_sdcardclk_set_phase(host, oclk_phase);
+		ret = sdhci_zynqmp_sampleclk_set_phase(host, iclk_phase);
+		if (ret)
+			return ret;
+
+		ret = sdhci_zynqmp_sdcardclk_set_phase(host, oclk_phase);
+		if (ret)
+			return ret;
 	} else if (IS_ENABLED(CONFIG_ARCH_VERSAL) &&
 		   device_is_compatible(dev, "xlnx,versal-8.9a")) {
-		sdhci_versal_sampleclk_set_phase(host, iclk_phase);
-		sdhci_versal_sdcardclk_set_phase(host, oclk_phase);
+		ret = sdhci_versal_sampleclk_set_phase(host, iclk_phase);
+		if (ret)
+			return ret;
+
+		ret = sdhci_versal_sdcardclk_set_phase(host, oclk_phase);
+		if (ret)
+			return ret;
 	}
+
+	return 0;
 }
 
 static void arasan_dt_read_clk_phase(struct udevice *dev, unsigned char timing,
@@ -526,29 +690,10 @@ static void arasan_dt_parse_clk_phases(struct udevice *dev)
 				 "clk-phase-mmc-hs400");
 }
 
-static void arasan_sdhci_set_control_reg(struct sdhci_host *host)
-{
-	struct mmc *mmc = (struct mmc *)host->mmc;
-	u32 reg;
-
-	if (!IS_SD(mmc))
-		return;
-
-	if (mmc->signal_voltage == MMC_SIGNAL_VOLTAGE_180) {
-		reg = sdhci_readw(host, SDHCI_HOST_CONTROL2);
-		reg |= SDHCI_CTRL_VDD_180;
-		sdhci_writew(host, reg, SDHCI_HOST_CONTROL2);
-	}
-
-	if (mmc->selected_mode > SD_HS &&
-	    mmc->selected_mode <= MMC_HS_200)
-		sdhci_set_uhs_timing(host);
-}
-
 static const struct sdhci_ops arasan_ops = {
 	.platform_execute_tuning	= &arasan_sdhci_execute_tuning,
 	.set_delay = &arasan_sdhci_set_tapdelay,
-	.set_control_reg = &arasan_sdhci_set_control_reg,
+	.set_control_reg = &sdhci_set_control_reg,
 };
 #endif
 
@@ -612,6 +757,25 @@ static int arasan_sdhci_probe(struct udevice *dev)
 		return ret;
 	upriv->mmc = host->mmc;
 
+	/*
+	 * WORKAROUND: Versal platforms have an issue with card detect state.
+	 * Due to this, host controller is switching off voltage to sd card
+	 * causing sd card timeout error. Workaround this by adding a wait for
+	 * 1000msec till the card detect state gets stable.
+	 */
+	if (IS_ENABLED(CONFIG_ARCH_VERSAL)) {
+		u32 timeout = 1000;
+
+		while (((sdhci_readl(host, SDHCI_PRESENT_STATE) &
+			 SDHCI_CARD_STATE_STABLE) == 0) && timeout--) {
+			mdelay(1);
+		}
+		if (!timeout) {
+			dev_err(dev, "Sdhci card detect state not stable\n");
+			return -ETIMEDOUT;
+		}
+	}
+
 	return sdhci_probe(dev);
 }
 

+ 9 - 0
drivers/reset/Kconfig

@@ -197,4 +197,13 @@ config RESET_SCMI
 	  Enable this option if you want to support reset controller
 	  devices exposed by a SCMI agent based on SCMI reset domain
 	  protocol communication with a SCMI server.
+
+config RESET_ZYNQMP
+	bool "Reset Driver for Xilinx ZynqMP SoC's"
+	depends on DM_RESET && ZYNQMP_FIRMWARE
+	help
+	  Support for reset controller on Xilinx ZynqMP SoC. Driver is only
+	  passing request via Xilinx firmware interface to TF-A and PMU
+	  firmware.
+
 endmenu

+ 1 - 0
drivers/reset/Makefile

@@ -29,3 +29,4 @@ obj-$(CONFIG_RESET_SIFIVE) += reset-sifive.o
 obj-$(CONFIG_RESET_SYSCON) += reset-syscon.o
 obj-$(CONFIG_RESET_RASPBERRYPI) += reset-raspberrypi.o
 obj-$(CONFIG_RESET_SCMI) += reset-scmi.o
+obj-$(CONFIG_RESET_ZYNQMP) += reset-zynqmp.o

+ 100 - 0
drivers/reset/reset-zynqmp.c

@@ -0,0 +1,100 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 Xilinx, Inc. - Michal Simek
+ */
+
+#define LOG_CATEGORY UCLASS_RESET
+
+#include <common.h>
+#include <dm.h>
+#include <dm/device_compat.h>
+#include <reset-uclass.h>
+#include <zynqmp_firmware.h>
+
+#define ZYNQMP_NR_RESETS	(ZYNQMP_PM_RESET_END - ZYNQMP_PM_RESET_START)
+#define ZYNQMP_RESET_ID		ZYNQMP_PM_RESET_START
+
+struct zynqmp_reset_priv {
+	u32 reset_id;
+	u32 nr_reset;
+};
+
+static int zynqmp_pm_reset_assert(const u32 reset,
+				  const enum zynqmp_pm_reset_action assert_flag)
+{
+	return xilinx_pm_request(PM_RESET_ASSERT, reset, assert_flag, 0, 0,
+				 NULL);
+}
+
+static int zynqmp_reset_assert(struct reset_ctl *rst)
+{
+	struct zynqmp_reset_priv *priv = dev_get_priv(rst->dev);
+
+	dev_dbg(rst->dev, "%s(rst=%p) (id=%lu)\n", __func__, rst, rst->id);
+
+	return zynqmp_pm_reset_assert(priv->reset_id + rst->id,
+				      PM_RESET_ACTION_ASSERT);
+}
+
+static int zynqmp_reset_deassert(struct reset_ctl *rst)
+{
+	struct zynqmp_reset_priv *priv = dev_get_priv(rst->dev);
+
+	dev_dbg(rst->dev, "%s(rst=%p) (id=%lu)\n", __func__, rst, rst->id);
+
+	return zynqmp_pm_reset_assert(priv->reset_id + rst->id,
+				      PM_RESET_ACTION_RELEASE);
+}
+
+static int zynqmp_reset_request(struct reset_ctl *rst)
+{
+	struct zynqmp_reset_priv *priv = dev_get_priv(rst->dev);
+
+	dev_dbg(rst->dev, "%s(rst=%p) (id=%lu) (nr_reset=%d)\n", __func__,
+		rst, rst->id, priv->nr_reset);
+
+	if (rst->id > priv->nr_reset)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int zynqmp_reset_free(struct reset_ctl *rst)
+{
+	struct zynqmp_reset_priv *priv = dev_get_priv(rst->dev);
+
+	dev_dbg(rst->dev, "%s(rst=%p) (id=%lu) (nr_reset=%d)\n", __func__,
+		rst, rst->id, priv->nr_reset);
+
+	return 0;
+}
+
+static int zynqmp_reset_probe(struct udevice *dev)
+{
+	struct zynqmp_reset_priv *priv = dev_get_priv(dev);
+
+	priv->reset_id = ZYNQMP_RESET_ID;
+	priv->nr_reset = ZYNQMP_NR_RESETS;
+	return 0;
+}
+
+const struct reset_ops zynqmp_reset_ops = {
+	.request = zynqmp_reset_request,
+	.rfree = zynqmp_reset_free,
+	.rst_assert = zynqmp_reset_assert,
+	.rst_deassert = zynqmp_reset_deassert,
+};
+
+static const struct udevice_id zynqmp_reset_ids[] = {
+	{ .compatible = "xlnx,zynqmp-reset" },
+	{ }
+};
+
+U_BOOT_DRIVER(zynqmp_reset) = {
+	.name		= "zynqmp_reset",
+	.id		= UCLASS_RESET,
+	.of_match	= zynqmp_reset_ids,
+	.ops		= &zynqmp_reset_ops,
+	.probe		= zynqmp_reset_probe,
+	.priv_auto	= sizeof(struct zynqmp_reset_priv),
+};

+ 7 - 0
drivers/rtc/Kconfig

@@ -195,4 +195,11 @@ config RTC_DAVINCI
 	  Say "yes" here to support the on chip real time clock
 	  present on TI OMAP1, AM33xx, DA8xx/OMAP-L13x, AM43xx and DRA7xx.
 
+config RTC_ZYNQMP
+	bool "Enable ZynqMP RTC driver"
+	depends on ARCH_ZYNQMP
+	help
+	  Say "yes" here to support the on chip real time clock
+	  present on Xilinx ZynqMP SoC.
+
 endmenu

+ 1 - 0
drivers/rtc/Makefile

@@ -57,3 +57,4 @@ obj-$(CONFIG_RTC_STM32) += stm32_rtc.o
 obj-$(CONFIG_SANDBOX) += sandbox_rtc.o
 obj-$(CONFIG_RTC_X1205) += x1205.o
 obj-$(CONFIG_RTC_ABX80X) += abx80x.o
+obj-$(CONFIG_RTC_ZYNQMP) += zynqmp_rtc.o

+ 1 - 0
drivers/rtc/rtc-uclass.c

@@ -176,6 +176,7 @@ int rtc_write32(struct udevice *dev, unsigned int reg, u32 value)
 UCLASS_DRIVER(rtc) = {
 	.name		= "rtc",
 	.id		= UCLASS_RTC,
+	.flags		= DM_UC_FLAG_SEQ_ALIAS,
 #if !CONFIG_IS_ENABLED(OF_PLATDATA)
 	.post_bind	= dm_scan_fdt_dev,
 #endif

+ 158 - 0
drivers/rtc/zynqmp_rtc.c

@@ -0,0 +1,158 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021, Xilinx, Inc.
+ */
+
+#define LOG_CATEGORY UCLASS_RTC
+
+#include <common.h>
+#include <dm.h>
+#include <rtc.h>
+#include <asm/io.h>
+
+/* RTC Registers */
+#define RTC_SET_TM_WR		0x00
+#define RTC_SET_TM_RD		0x04
+#define RTC_CALIB_WR		0x08
+#define RTC_CUR_TM		0x10
+#define RTC_INT_STS		0x20
+#define RTC_CTRL		0x40
+
+#define RTC_INT_SEC		BIT(0)
+#define RTC_BATT_EN		BIT(31)
+#define RTC_CALIB_DEF		0x198233
+#define RTC_CALIB_MASK		0x1FFFFF
+
+struct zynqmp_rtc_priv {
+	fdt_addr_t	base;
+	unsigned int	calibval;
+};
+
+static int zynqmp_rtc_get(struct udevice *dev, struct rtc_time *tm)
+{
+	struct zynqmp_rtc_priv *priv = dev_get_priv(dev);
+	u32 status;
+	unsigned long read_time;
+
+	status = readl(priv->base + RTC_INT_STS);
+
+	if (status & RTC_INT_SEC) {
+		/*
+		 * RTC has updated the CURRENT_TIME with the time written into
+		 * SET_TIME_WRITE register.
+		 */
+		read_time = readl(priv->base + RTC_CUR_TM);
+	} else {
+		/*
+		 * Time written in SET_TIME_WRITE has not yet updated into
+		 * the seconds read register, so read the time from the
+		 * SET_TIME_WRITE instead of CURRENT_TIME register.
+		 * Since we add +1 sec while writing, we need to -1 sec while
+		 * reading.
+		 */
+		read_time = readl(priv->base + RTC_SET_TM_RD) - 1;
+	}
+
+	rtc_to_tm(read_time, tm);
+
+	return 0;
+}
+
+static int zynqmp_rtc_set(struct udevice *dev, const struct rtc_time *tm)
+{
+	struct zynqmp_rtc_priv *priv = dev_get_priv(dev);
+	unsigned long new_time = 0;
+
+	if (tm)
+		/*
+		 * The value written will be updated after 1 sec into the
+		 * seconds read register, so we need to program time +1 sec
+		 * to get the correct time on read.
+		 */
+		new_time = rtc_mktime(tm) + 1;
+
+	/*
+	 * Writing into calibration register will clear the Tick Counter and
+	 * force the next second to be signaled exactly in 1 second period
+	 */
+	priv->calibval &= RTC_CALIB_MASK;
+	writel(priv->calibval, (priv->base + RTC_CALIB_WR));
+
+	writel(new_time, priv->base + RTC_SET_TM_WR);
+
+	/*
+	 * Clear the rtc interrupt status register after setting the
+	 * time. During a read_time function, the code should read the
+	 * RTC_INT_STATUS register and if bit 0 is still 0, it means
+	 * that one second has not elapsed yet since RTC was set and
+	 * the current time should be read from SET_TIME_READ register;
+	 * otherwise, CURRENT_TIME register is read to report the time
+	 */
+	writel(RTC_INT_SEC, priv->base + RTC_INT_STS);
+
+	return 0;
+}
+
+static int zynqmp_rtc_reset(struct udevice *dev)
+{
+	return zynqmp_rtc_set(dev, NULL);
+}
+
+static int zynqmp_rtc_init(struct udevice *dev)
+{
+	struct zynqmp_rtc_priv *priv = dev_get_priv(dev);
+	u32 rtc_ctrl;
+
+	/* Enable RTC switch to battery when VCC_PSAUX is not available */
+	rtc_ctrl = readl(priv->base + RTC_CTRL);
+	rtc_ctrl |= RTC_BATT_EN;
+	writel(rtc_ctrl, priv->base + RTC_CTRL);
+
+	/*
+	 * Based on crystal freq of 33.330 KHz
+	 * set the seconds counter and enable, set fractions counter
+	 * to default value suggested as per design spec
+	 * to correct RTC delay in frequency over period of time.
+	 */
+	priv->calibval &= RTC_CALIB_MASK;
+	writel(priv->calibval, (priv->base + RTC_CALIB_WR));
+
+	return 0;
+}
+
+static int zynqmp_rtc_probe(struct udevice *dev)
+{
+	struct zynqmp_rtc_priv *priv = dev_get_priv(dev);
+	int ret;
+
+	priv->base = dev_read_addr(dev);
+	if (priv->base == FDT_ADDR_T_NONE)
+		return -EINVAL;
+
+	priv->calibval = dev_read_u32_default(dev, "calibration",
+					      RTC_CALIB_DEF);
+
+	ret = zynqmp_rtc_init(dev);
+
+	return ret;
+}
+
+static const struct rtc_ops zynqmp_rtc_ops = {
+	.get = zynqmp_rtc_get,
+	.set = zynqmp_rtc_set,
+	.reset = zynqmp_rtc_reset,
+};
+
+static const struct udevice_id zynqmp_rtc_ids[] = {
+	{ .compatible = "xlnx,zynqmp-rtc" },
+	{ }
+};
+
+U_BOOT_DRIVER(rtc_zynqmp) = {
+	.name = "rtc-zynqmp",
+	.id = UCLASS_RTC,
+	.probe = zynqmp_rtc_probe,
+	.of_match = zynqmp_rtc_ids,
+	.ops = &zynqmp_rtc_ops,
+	.priv_auto = sizeof(struct zynqmp_rtc_priv),
+};

+ 16 - 0
drivers/soc/Kconfig

@@ -16,6 +16,22 @@ config SOC_DEVICE_TI_K3
 	  This allows Texas Instruments Keystone 3 SoCs to identify
 	  specifics about the SoC in use.
 
+config SOC_XILINX_ZYNQMP
+	bool "Enable SoC Device ID driver for Xilinx ZynqMP"
+	depends on SOC_DEVICE && ARCH_ZYNQMP
+	help
+	  Enable this option to select SoC device id driver for Xilinx ZynqMP.
+	  This allows other drivers to verify the SoC familiy & revision
+	  using matching SoC attributes.
+
+config SOC_XILINX_VERSAL
+	bool "Enable SoC Device ID driver for Xilinx Versal"
+	depends on SOC_DEVICE && ARCH_VERSAL
+	help
+	  Enable this option to select SoC device id driver for Xilinx Versal.
+	  This allows other drivers to verify the SoC familiy & revision using
+	  matching SoC attributes.
+
 source "drivers/soc/ti/Kconfig"
 
 endmenu

+ 2 - 0
drivers/soc/Makefile

@@ -6,3 +6,5 @@ obj-$(CONFIG_SOC_TI) += ti/
 obj-$(CONFIG_SOC_DEVICE) += soc-uclass.o
 obj-$(CONFIG_SOC_DEVICE_TI_K3) += soc_ti_k3.o
 obj-$(CONFIG_SANDBOX) += soc_sandbox.o
+obj-$(CONFIG_SOC_XILINX_ZYNQMP) += soc_xilinx_zynqmp.o
+obj-$(CONFIG_SOC_XILINX_VERSAL) += soc_xilinx_versal.o

+ 76 - 0
drivers/soc/soc_xilinx_versal.c

@@ -0,0 +1,76 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Versal SOC driver
+ *
+ * Copyright (C) 2021 Xilinx, Inc.
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <soc.h>
+#include <zynqmp_firmware.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+
+/*
+ * v1 -> 0x10 - ES1
+ * v2 -> 0x20 - Production
+ */
+static const char versal_family[] = "Versal";
+
+struct soc_xilinx_versal_priv {
+	const char *family;
+	char revision;
+};
+
+static int soc_xilinx_versal_get_family(struct udevice *dev, char *buf, int size)
+{
+	struct soc_xilinx_versal_priv *priv = dev_get_priv(dev);
+
+	return snprintf(buf, size, "%s", priv->family);
+}
+
+static int soc_xilinx_versal_get_revision(struct udevice *dev, char *buf, int size)
+{
+	struct soc_xilinx_versal_priv *priv = dev_get_priv(dev);
+
+	return snprintf(buf, size, "v%d", priv->revision);
+}
+
+static const struct soc_ops soc_xilinx_versal_ops = {
+	.get_family = soc_xilinx_versal_get_family,
+	.get_revision = soc_xilinx_versal_get_revision,
+};
+
+static int soc_xilinx_versal_probe(struct udevice *dev)
+{
+	struct soc_xilinx_versal_priv *priv = dev_get_priv(dev);
+	u32 ret_payload[4];
+	int ret;
+
+	priv->family = versal_family;
+
+	if (IS_ENABLED(CONFIG_ZYNQMP_FIRMWARE)) {
+		ret = xilinx_pm_request(PM_GET_CHIPID, 0, 0, 0, 0,
+					ret_payload);
+		if (ret)
+			return ret;
+	} else {
+		ret_payload[2] = readl(VERSAL_PS_PMC_VERSION);
+		if (!ret_payload[2])
+			return -EINVAL;
+	}
+
+	priv->revision = ret_payload[2] >> VERSAL_PS_VER_SHIFT;
+
+	return 0;
+}
+
+U_BOOT_DRIVER(soc_xilinx_versal) = {
+	.name		= "soc_xilinx_versal",
+	.id		= UCLASS_SOC,
+	.ops		= &soc_xilinx_versal_ops,
+	.probe		= soc_xilinx_versal_probe,
+	.priv_auto	= sizeof(struct soc_xilinx_versal_priv),
+	.flags		= DM_FLAG_PRE_RELOC,
+};

+ 78 - 0
drivers/soc/soc_xilinx_zynqmp.c

@@ -0,0 +1,78 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx ZynqMP SOC driver
+ *
+ * Copyright (C) 2021 Xilinx, Inc.
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <asm/cache.h>
+#include <soc.h>
+#include <zynqmp_firmware.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/arch/hardware.h>
+
+/*
+ * Zynqmp has 4 silicon revisions
+ * v0 -> 0(XCZU9EG-ES1)
+ * v1 -> 1(XCZU3EG-ES1, XCZU15EG-ES1)
+ * v2 -> 2(XCZU7EV-ES1, XCZU9EG-ES2, XCZU19EG-ES1)
+ * v3 -> 3(Production Level)
+ */
+static const char zynqmp_family[] = "ZynqMP";
+
+struct soc_xilinx_zynqmp_priv {
+	const char *family;
+	char revision;
+};
+
+static int soc_xilinx_zynqmp_get_family(struct udevice *dev, char *buf, int size)
+{
+	struct soc_xilinx_zynqmp_priv *priv = dev_get_priv(dev);
+
+	return snprintf(buf, size, "%s", priv->family);
+}
+
+static int soc_xilinx_zynqmp_get_revision(struct udevice *dev, char *buf, int size)
+{
+	struct soc_xilinx_zynqmp_priv *priv = dev_get_priv(dev);
+
+	return snprintf(buf, size, "v%d", priv->revision);
+}
+
+static const struct soc_ops soc_xilinx_zynqmp_ops = {
+	.get_family = soc_xilinx_zynqmp_get_family,
+	.get_revision = soc_xilinx_zynqmp_get_revision,
+};
+
+static int soc_xilinx_zynqmp_probe(struct udevice *dev)
+{
+	struct soc_xilinx_zynqmp_priv *priv = dev_get_priv(dev);
+	u32 ret_payload[4];
+	int ret;
+
+	priv->family = zynqmp_family;
+
+	if (IS_ENABLED(CONFIG_SPL_BUILD) || current_el() == 3 ||
+	    !IS_ENABLED(CONFIG_ZYNQMP_FIRMWARE))
+		ret = zynqmp_mmio_read(ZYNQMP_PS_VERSION, &ret_payload[2]);
+	else
+		ret = xilinx_pm_request(PM_GET_CHIPID, 0, 0, 0, 0,
+					ret_payload);
+	if (ret < 0)
+		return ret;
+
+	priv->revision = ret_payload[2] & ZYNQMP_PS_VER_MASK;
+
+	return 0;
+}
+
+U_BOOT_DRIVER(soc_xilinx_zynqmp) = {
+	.name		= "soc_xilinx_zynqmp",
+	.id		= UCLASS_SOC,
+	.ops		= &soc_xilinx_zynqmp_ops,
+	.probe		= soc_xilinx_zynqmp_probe,
+	.priv_auto	= sizeof(struct soc_xilinx_zynqmp_priv),
+	.flags		= DM_FLAG_PRE_RELOC,
+};

+ 1 - 0
drivers/watchdog/xilinx_wwdt.c

@@ -14,6 +14,7 @@
 #include <regmap.h>
 #include <wdt.h>
 #include <linux/compat.h>
+#include <dm/device_compat.h>
 #include <linux/io.h>
 
 /* Refresh Register Masks */

+ 1 - 1
include/sdhci.h

@@ -268,7 +268,7 @@ struct sdhci_ops {
 	int	(*set_ios_post)(struct sdhci_host *host);
 	void	(*set_clock)(struct sdhci_host *host, u32 div);
 	int (*platform_execute_tuning)(struct mmc *host, u8 opcode);
-	void (*set_delay)(struct sdhci_host *host);
+	int (*set_delay)(struct sdhci_host *host);
 	int	(*deferred_probe)(struct sdhci_host *host);
 };
 

+ 307 - 44
include/zynqmp_firmware.h

@@ -10,58 +10,156 @@
 
 enum pm_api_id {
 	PM_GET_API_VERSION = 1,
-	PM_SET_CONFIGURATION,
-	PM_GET_NODE_STATUS,
-	PM_GET_OPERATING_CHARACTERISTIC,
-	PM_REGISTER_NOTIFIER,
-	PM_REQUEST_SUSPEND,
-	PM_SELF_SUSPEND,
-	PM_FORCE_POWERDOWN,
-	PM_ABORT_SUSPEND,
-	PM_REQUEST_WAKEUP,
-	PM_SET_WAKEUP_SOURCE,
-	PM_SYSTEM_SHUTDOWN,
-	PM_REQUEST_NODE,
-	PM_RELEASE_NODE,
-	PM_SET_REQUIREMENT,
-	PM_SET_MAX_LATENCY,
-	PM_RESET_ASSERT,
-	PM_RESET_GET_STATUS,
-	PM_MMIO_WRITE,
-	PM_MMIO_READ,
-	PM_PM_INIT_FINALIZE,
-	PM_FPGA_LOAD,
-	PM_FPGA_GET_STATUS,
-	PM_GET_CHIPID,
+	PM_SET_CONFIGURATION = 2,
+	PM_GET_NODE_STATUS = 3,
+	PM_GET_OPERATING_CHARACTERISTIC = 4,
+	PM_REGISTER_NOTIFIER = 5,
+	/* API for suspending */
+	PM_REQUEST_SUSPEND = 6,
+	PM_SELF_SUSPEND = 7,
+	PM_FORCE_POWERDOWN = 8,
+	PM_ABORT_SUSPEND = 9,
+	PM_REQUEST_WAKEUP = 10,
+	PM_SET_WAKEUP_SOURCE = 11,
+	PM_SYSTEM_SHUTDOWN = 12,
+	PM_REQUEST_NODE = 13,
+	PM_RELEASE_NODE = 14,
+	PM_SET_REQUIREMENT = 15,
+	PM_SET_MAX_LATENCY = 16,
+	/* Direct control API functions: */
+	PM_RESET_ASSERT = 17,
+	PM_RESET_GET_STATUS = 18,
+	PM_MMIO_WRITE = 19,
+	PM_MMIO_READ = 20,
+	PM_PM_INIT_FINALIZE = 21,
+	PM_FPGA_LOAD = 22,
+	PM_FPGA_GET_STATUS = 23,
+	PM_GET_CHIPID = 24,
+	/* ID 25 is been used by U-boot to process secure boot images */
+	/* Secure library generic API functions */
 	PM_SECURE_SHA = 26,
-	PM_SECURE_RSA,
-	PM_PINCTRL_REQUEST,
-	PM_PINCTRL_RELEASE,
-	PM_PINCTRL_GET_FUNCTION,
-	PM_PINCTRL_SET_FUNCTION,
-	PM_PINCTRL_CONFIG_PARAM_GET,
-	PM_PINCTRL_CONFIG_PARAM_SET,
-	PM_IOCTL,
-	PM_QUERY_DATA,
-	PM_CLOCK_ENABLE,
-	PM_CLOCK_DISABLE,
-	PM_CLOCK_GETSTATE,
-	PM_CLOCK_SETDIVIDER,
-	PM_CLOCK_GETDIVIDER,
-	PM_CLOCK_SETRATE,
-	PM_CLOCK_GETRATE,
-	PM_CLOCK_SETPARENT,
-	PM_CLOCK_GETPARENT,
-	PM_SECURE_IMAGE,
+	PM_SECURE_RSA = 27,
+	PM_PINCTRL_REQUEST = 28,
+	PM_PINCTRL_RELEASE = 29,
+	PM_PINCTRL_GET_FUNCTION = 30,
+	PM_PINCTRL_SET_FUNCTION = 31,
+	PM_PINCTRL_CONFIG_PARAM_GET = 32,
+	PM_PINCTRL_CONFIG_PARAM_SET = 33,
+	PM_IOCTL = 34,
+	PM_QUERY_DATA = 35,
+	PM_CLOCK_ENABLE = 36,
+	PM_CLOCK_DISABLE = 37,
+	PM_CLOCK_GETSTATE = 38,
+	PM_CLOCK_SETDIVIDER = 39,
+	PM_CLOCK_GETDIVIDER = 40,
+	PM_CLOCK_SETRATE = 41,
+	PM_CLOCK_GETRATE = 42,
+	PM_CLOCK_SETPARENT = 43,
+	PM_CLOCK_GETPARENT = 44,
+	PM_SECURE_IMAGE = 45,
 	PM_FPGA_READ = 46,
-	PM_SECURE_AES,
+	PM_SECURE_AES = 47,
 	PM_CLOCK_PLL_GETPARAM = 49,
+	/* PM_REGISTER_ACCESS API */
 	PM_REGISTER_ACCESS = 52,
-	PM_EFUSE_ACCESS,
+	PM_EFUSE_ACCESS = 53,
 	PM_FEATURE_CHECK = 63,
 	PM_API_MAX,
 };
 
+enum pm_node_id {
+	NODE_UNKNOWN = 0,
+	NODE_APU = 1,
+	NODE_APU_0 = 2,
+	NODE_APU_1 = 3,
+	NODE_APU_2 = 4,
+	NODE_APU_3 = 5,
+	NODE_RPU = 6,
+	NODE_RPU_0 = 7,
+	NODE_RPU_1 = 8,
+	NODE_PLD = 9,
+	NODE_FPD = 10,
+	NODE_OCM_BANK_0 = 11,
+	NODE_OCM_BANK_1 = 12,
+	NODE_OCM_BANK_2 = 13,
+	NODE_OCM_BANK_3 = 14,
+	NODE_TCM_0_A = 15,
+	NODE_TCM_0_B = 16,
+	NODE_TCM_1_A = 17,
+	NODE_TCM_1_B = 18,
+	NODE_L2 = 19,
+	NODE_GPU_PP_0 = 20,
+	NODE_GPU_PP_1 = 21,
+	NODE_USB_0 = 22,
+	NODE_USB_1 = 23,
+	NODE_TTC_0 = 24,
+	NODE_TTC_1 = 25,
+	NODE_TTC_2 = 26,
+	NODE_TTC_3 = 27,
+	NODE_SATA = 28,
+	NODE_ETH_0 = 29,
+	NODE_ETH_1 = 30,
+	NODE_ETH_2 = 31,
+	NODE_ETH_3 = 32,
+	NODE_UART_0 = 33,
+	NODE_UART_1 = 34,
+	NODE_SPI_0 = 35,
+	NODE_SPI_1 = 36,
+	NODE_I2C_0 = 37,
+	NODE_I2C_1 = 38,
+	NODE_SD_0 = 39,
+	NODE_SD_1 = 40,
+	NODE_DP = 41,
+	NODE_GDMA = 42,
+	NODE_ADMA = 43,
+	NODE_NAND = 44,
+	NODE_QSPI = 45,
+	NODE_GPIO = 46,
+	NODE_CAN_0 = 47,
+	NODE_CAN_1 = 48,
+	NODE_EXTERN = 49,
+	NODE_APLL = 50,
+	NODE_VPLL = 51,
+	NODE_DPLL = 52,
+	NODE_RPLL = 53,
+	NODE_IOPLL = 54,
+	NODE_DDR = 55,
+	NODE_IPI_APU = 56,
+	NODE_IPI_RPU_0 = 57,
+	NODE_GPU = 58,
+	NODE_PCIE = 59,
+	NODE_PCAP = 60,
+	NODE_RTC = 61,
+	NODE_LPD = 62,
+	NODE_VCU = 63,
+	NODE_IPI_RPU_1 = 64,
+	NODE_IPI_PL_0 = 65,
+	NODE_IPI_PL_1 = 66,
+	NODE_IPI_PL_2 = 67,
+	NODE_IPI_PL_3 = 68,
+	NODE_PL = 69,
+	NODE_GEM_TSU = 70,
+	NODE_SWDT_0 = 71,
+	NODE_SWDT_1 = 72,
+	NODE_CSU = 73,
+	NODE_PJTAG = 74,
+	NODE_TRACE = 75,
+	NODE_TESTSCAN = 76,
+	NODE_PMU = 77,
+	NODE_MAX = 78,
+};
+
+enum tap_delay_type {
+	PM_TAPDELAY_INPUT = 0,
+	PM_TAPDELAY_OUTPUT = 1,
+};
+
+enum dll_reset_type {
+	PM_DLL_RESET_ASSERT = 0,
+	PM_DLL_RESET_RELEASE = 1,
+	PM_DLL_RESET_PULSE = 2,
+};
+
 enum pm_query_id {
 	PM_QID_INVALID = 0,
 	PM_QID_CLOCK_GET_NAME = 1,
@@ -79,6 +177,171 @@ enum pm_query_id {
 	PM_QID_CLOCK_GET_MAX_DIVISOR = 13,
 };
 
+enum zynqmp_pm_reset_action {
+	PM_RESET_ACTION_RELEASE = 0,
+	PM_RESET_ACTION_ASSERT = 1,
+	PM_RESET_ACTION_PULSE = 2,
+};
+
+enum zynqmp_pm_reset {
+	ZYNQMP_PM_RESET_START = 1000,
+	ZYNQMP_PM_RESET_PCIE_CFG = ZYNQMP_PM_RESET_START,
+	ZYNQMP_PM_RESET_PCIE_BRIDGE = 1001,
+	ZYNQMP_PM_RESET_PCIE_CTRL = 1002,
+	ZYNQMP_PM_RESET_DP = 1003,
+	ZYNQMP_PM_RESET_SWDT_CRF = 1004,
+	ZYNQMP_PM_RESET_AFI_FM5 = 1005,
+	ZYNQMP_PM_RESET_AFI_FM4 = 1006,
+	ZYNQMP_PM_RESET_AFI_FM3 = 1007,
+	ZYNQMP_PM_RESET_AFI_FM2 = 1008,
+	ZYNQMP_PM_RESET_AFI_FM1 = 1009,
+	ZYNQMP_PM_RESET_AFI_FM0 = 1010,
+	ZYNQMP_PM_RESET_GDMA = 1011,
+	ZYNQMP_PM_RESET_GPU_PP1 = 1012,
+	ZYNQMP_PM_RESET_GPU_PP0 = 1013,
+	ZYNQMP_PM_RESET_GPU = 1014,
+	ZYNQMP_PM_RESET_GT = 1015,
+	ZYNQMP_PM_RESET_SATA = 1016,
+	ZYNQMP_PM_RESET_ACPU3_PWRON = 1017,
+	ZYNQMP_PM_RESET_ACPU2_PWRON = 1018,
+	ZYNQMP_PM_RESET_ACPU1_PWRON = 1019,
+	ZYNQMP_PM_RESET_ACPU0_PWRON = 1020,
+	ZYNQMP_PM_RESET_APU_L2 = 1021,
+	ZYNQMP_PM_RESET_ACPU3 = 1022,
+	ZYNQMP_PM_RESET_ACPU2 = 1023,
+	ZYNQMP_PM_RESET_ACPU1 = 1024,
+	ZYNQMP_PM_RESET_ACPU0 = 1025,
+	ZYNQMP_PM_RESET_DDR = 1026,
+	ZYNQMP_PM_RESET_APM_FPD = 1027,
+	ZYNQMP_PM_RESET_SOFT = 1028,
+	ZYNQMP_PM_RESET_GEM0 = 1029,
+	ZYNQMP_PM_RESET_GEM1 = 1030,
+	ZYNQMP_PM_RESET_GEM2 = 1031,
+	ZYNQMP_PM_RESET_GEM3 = 1032,
+	ZYNQMP_PM_RESET_QSPI = 1033,
+	ZYNQMP_PM_RESET_UART0 = 1034,
+	ZYNQMP_PM_RESET_UART1 = 1035,
+	ZYNQMP_PM_RESET_SPI0 = 1036,
+	ZYNQMP_PM_RESET_SPI1 = 1037,
+	ZYNQMP_PM_RESET_SDIO0 = 1038,
+	ZYNQMP_PM_RESET_SDIO1 = 1039,
+	ZYNQMP_PM_RESET_CAN0 = 1040,
+	ZYNQMP_PM_RESET_CAN1 = 1041,
+	ZYNQMP_PM_RESET_I2C0 = 1042,
+	ZYNQMP_PM_RESET_I2C1 = 1043,
+	ZYNQMP_PM_RESET_TTC0 = 1044,
+	ZYNQMP_PM_RESET_TTC1 = 1045,
+	ZYNQMP_PM_RESET_TTC2 = 1046,
+	ZYNQMP_PM_RESET_TTC3 = 1047,
+	ZYNQMP_PM_RESET_SWDT_CRL = 1048,
+	ZYNQMP_PM_RESET_NAND = 1049,
+	ZYNQMP_PM_RESET_ADMA = 1050,
+	ZYNQMP_PM_RESET_GPIO = 1051,
+	ZYNQMP_PM_RESET_IOU_CC = 1052,
+	ZYNQMP_PM_RESET_TIMESTAMP = 1053,
+	ZYNQMP_PM_RESET_RPU_R50 = 1054,
+	ZYNQMP_PM_RESET_RPU_R51 = 1055,
+	ZYNQMP_PM_RESET_RPU_AMBA = 1056,
+	ZYNQMP_PM_RESET_OCM = 1057,
+	ZYNQMP_PM_RESET_RPU_PGE = 1058,
+	ZYNQMP_PM_RESET_USB0_CORERESET = 1059,
+	ZYNQMP_PM_RESET_USB1_CORERESET = 1060,
+	ZYNQMP_PM_RESET_USB0_HIBERRESET = 1061,
+	ZYNQMP_PM_RESET_USB1_HIBERRESET = 1062,
+	ZYNQMP_PM_RESET_USB0_APB = 1063,
+	ZYNQMP_PM_RESET_USB1_APB = 1064,
+	ZYNQMP_PM_RESET_IPI = 1065,
+	ZYNQMP_PM_RESET_APM_LPD = 1066,
+	ZYNQMP_PM_RESET_RTC = 1067,
+	ZYNQMP_PM_RESET_SYSMON = 1068,
+	ZYNQMP_PM_RESET_AFI_FM6 = 1069,
+	ZYNQMP_PM_RESET_LPD_SWDT = 1070,
+	ZYNQMP_PM_RESET_FPD = 1071,
+	ZYNQMP_PM_RESET_RPU_DBG1 = 1072,
+	ZYNQMP_PM_RESET_RPU_DBG0 = 1073,
+	ZYNQMP_PM_RESET_DBG_LPD = 1074,
+	ZYNQMP_PM_RESET_DBG_FPD = 1075,
+	ZYNQMP_PM_RESET_APLL = 1076,
+	ZYNQMP_PM_RESET_DPLL = 1077,
+	ZYNQMP_PM_RESET_VPLL = 1078,
+	ZYNQMP_PM_RESET_IOPLL = 1079,
+	ZYNQMP_PM_RESET_RPLL = 1080,
+	ZYNQMP_PM_RESET_GPO3_PL_0 = 1081,
+	ZYNQMP_PM_RESET_GPO3_PL_1 = 1082,
+	ZYNQMP_PM_RESET_GPO3_PL_2 = 1083,
+	ZYNQMP_PM_RESET_GPO3_PL_3 = 1084,
+	ZYNQMP_PM_RESET_GPO3_PL_4 = 1085,
+	ZYNQMP_PM_RESET_GPO3_PL_5 = 1086,
+	ZYNQMP_PM_RESET_GPO3_PL_6 = 1087,
+	ZYNQMP_PM_RESET_GPO3_PL_7 = 1088,
+	ZYNQMP_PM_RESET_GPO3_PL_8 = 1089,
+	ZYNQMP_PM_RESET_GPO3_PL_9 = 1090,
+	ZYNQMP_PM_RESET_GPO3_PL_10 = 1091,
+	ZYNQMP_PM_RESET_GPO3_PL_11 = 1092,
+	ZYNQMP_PM_RESET_GPO3_PL_12 = 1093,
+	ZYNQMP_PM_RESET_GPO3_PL_13 = 1094,
+	ZYNQMP_PM_RESET_GPO3_PL_14 = 1095,
+	ZYNQMP_PM_RESET_GPO3_PL_15 = 1096,
+	ZYNQMP_PM_RESET_GPO3_PL_16 = 1097,
+	ZYNQMP_PM_RESET_GPO3_PL_17 = 1098,
+	ZYNQMP_PM_RESET_GPO3_PL_18 = 1099,
+	ZYNQMP_PM_RESET_GPO3_PL_19 = 1100,
+	ZYNQMP_PM_RESET_GPO3_PL_20 = 1101,
+	ZYNQMP_PM_RESET_GPO3_PL_21 = 1102,
+	ZYNQMP_PM_RESET_GPO3_PL_22 = 1103,
+	ZYNQMP_PM_RESET_GPO3_PL_23 = 1104,
+	ZYNQMP_PM_RESET_GPO3_PL_24 = 1105,
+	ZYNQMP_PM_RESET_GPO3_PL_25 = 1106,
+	ZYNQMP_PM_RESET_GPO3_PL_26 = 1107,
+	ZYNQMP_PM_RESET_GPO3_PL_27 = 1108,
+	ZYNQMP_PM_RESET_GPO3_PL_28 = 1109,
+	ZYNQMP_PM_RESET_GPO3_PL_29 = 1110,
+	ZYNQMP_PM_RESET_GPO3_PL_30 = 1111,
+	ZYNQMP_PM_RESET_GPO3_PL_31 = 1112,
+	ZYNQMP_PM_RESET_RPU_LS = 1113,
+	ZYNQMP_PM_RESET_PS_ONLY = 1114,
+	ZYNQMP_PM_RESET_PL = 1115,
+	ZYNQMP_PM_RESET_PS_PL0 = 1116,
+	ZYNQMP_PM_RESET_PS_PL1 = 1117,
+	ZYNQMP_PM_RESET_PS_PL2 = 1118,
+	ZYNQMP_PM_RESET_PS_PL3 = 1119,
+	ZYNQMP_PM_RESET_END = ZYNQMP_PM_RESET_PS_PL3
+};
+
+enum pm_ioctl_id {
+	IOCTL_GET_RPU_OPER_MODE = 0,
+	IOCTL_SET_RPU_OPER_MODE = 1,
+	IOCTL_RPU_BOOT_ADDR_CONFIG = 2,
+	IOCTL_TCM_COMB_CONFIG = 3,
+	IOCTL_SET_TAPDELAY_BYPASS = 4,
+	IOCTL_SET_SGMII_MODE = 5,
+	IOCTL_SD_DLL_RESET = 6,
+	IOCTL_SET_SD_TAPDELAY = 7,
+	IOCTL_SET_PLL_FRAC_MODE = 8,
+	IOCTL_GET_PLL_FRAC_MODE = 9,
+	IOCTL_SET_PLL_FRAC_DATA = 10,
+	IOCTL_GET_PLL_FRAC_DATA = 11,
+	IOCTL_WRITE_GGS = 12,
+	IOCTL_READ_GGS = 13,
+	IOCTL_WRITE_PGGS = 14,
+	IOCTL_READ_PGGS = 15,
+	/* IOCTL for ULPI reset */
+	IOCTL_ULPI_RESET = 16,
+	/* Set healthy bit value*/
+	IOCTL_SET_BOOT_HEALTH_STATUS = 17,
+	IOCTL_AFI = 18,
+	/* Probe counter read/write */
+	IOCTL_PROBE_COUNTER_READ = 19,
+	IOCTL_PROBE_COUNTER_WRITE = 20,
+	IOCTL_OSPI_MUX_SELECT = 21,
+	/* IOCTL for USB power request */
+	IOCTL_USB_SET_STATE = 22,
+	/* IOCTL to get last reset reason */
+	IOCTL_GET_LAST_RESET_REASON = 23,
+	/* AIE ISR Clear */
+	IOCTL_AIE_ISR_CLEAR = 24,
+};
+
 #define PM_SIP_SVC      0xc2000000
 
 #define ZYNQMP_PM_VERSION_MAJOR         1

+ 0 - 21
include/zynqmp_tap_delay.h

@@ -1,21 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Xilinx ZynqMP SoC Tap Delay Programming
- *
- * Copyright (C) 2018 Xilinx, Inc.
- */
-
-#ifndef __ZYNQMP_TAP_DELAY_H__
-#define __ZYNQMP_TAP_DELAY_H__
-
-#ifdef CONFIG_ARCH_ZYNQMP
-void zynqmp_dll_reset(u8 deviceid);
-void arasan_zynqmp_set_in_tapdelay(u8 device_id, u32 itap_delay);
-void arasan_zynqmp_set_out_tapdelay(u8 device_id, u32 otap_delay);
-#else
-inline void zynqmp_dll_reset(u8 deviceid) {}
-inline void arasan_zynqmp_set_in_tapdelay(u8 device_id, u32 itap_delay) {}
-inline void arasan_zynqmp_set_out_tapdelay(u8 device_id, u32 otap_delay) {}
-#endif
-
-#endif