Merge tag 'xilinx-for-v2024.10-rc1' of https://source.denx.de/u-boot/custodians/u-boot-microblaze into next

AMD/Xilinx changes for v2024.10-rc1

common:
- spl: Introduce SoC specific init function

xilinx:
- Enable FF-A and NVMEM
- Rename spl_board_init() to spl_soc_init()

zynqmp:
- DT alignments
- Enable reset from SPL
- Enable USB3 for KD240
- Align multiboot register on Kria for proper reboot
- Allow multiboot environment write even in saved environment
- Move zynqmp commands from board/ to arch/
- Clean up xilinx_zynqmp.h

versal:
- Do not prioritize boot device if driver is not enabled

versal-net:
- Setup location for redundant variables in SPI

versal2:
- Add support for new SOC

mmc:
- Fix tap delay for SD on Versal NET

spi:
- Add SPI_NOR_OCTAL_READ flag for mx66uw2g345gx0 flash part

gpio:
- Cover MODEPIN firmware dependency
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 39ad03ac..db692b2 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1235,6 +1235,18 @@
 	imply BOARD_LATE_INIT
 	imply ENV_VARS_UBOOT_RUNTIME_CONFIG
 
+config ARCH_VERSAL2
+	bool "Support AMD Versal Gen 2 Platform"
+	select ARM64
+	select CLK
+	select DM
+	select DM_MMC if MMC
+	select DM_SERIAL
+	select OF_CONTROL
+	imply BOARD_LATE_INIT
+	imply ENV_VARS_UBOOT_RUNTIME_CONFIG
+	imply ZYNQMP_FIRMWARE
+
 config ARCH_VERSAL_NET
 	bool "Support Xilinx Versal NET Platform"
 	select ARM64
@@ -1272,7 +1284,7 @@
 	select OF_CONTROL
 	select MTD
 	select SPI
-	select SPL_BOARD_INIT if SPL
+	select SPL_SOC_INIT if SPL
 	select SPL_CLK if SPL
 	select SPL_DM if SPL
 	select SPL_DM_SPI if SPL
@@ -1315,7 +1327,7 @@
 	imply FIRMWARE
 	select GICV2
 	select OF_CONTROL
-	select SPL_BOARD_INIT if SPL
+	select SPL_SOC_INIT if SPL
 	select SPL_CLK if SPL
 	select SPL_DM if SPL
 	select SPL_DM_SPI if SPI && SPL_DM
@@ -2317,6 +2329,8 @@
 
 source "arch/arm/mach-versal/Kconfig"
 
+source "arch/arm/mach-versal2/Kconfig"
+
 source "arch/arm/mach-versal-net/Kconfig"
 
 source "arch/arm/mach-zynqmp-r5/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 734c6d6..dbeedbe 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -90,6 +90,7 @@
 machine-$(CONFIG_ARCH_OCTEONTX2)	+= octeontx2
 machine-$(CONFIG_ARCH_UNIPHIER)		+= uniphier
 machine-$(CONFIG_ARCH_VERSAL)		+= versal
+machine-$(CONFIG_ARCH_VERSAL2)		+= versal2
 machine-$(CONFIG_ARCH_VERSAL_NET)	+= versal-net
 machine-$(CONFIG_ARCH_ZYNQ)		+= zynq
 machine-$(CONFIG_ARCH_ZYNQMP)		+= zynqmp
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 9389398..2be36cf 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -333,6 +333,8 @@
 	versal-mini-qspi-x2-single.dtb \
 	versal-mini-qspi-x2-stacked.dtb \
 	xilinx-versal-virt.dtb
+dtb-$(CONFIG_ARCH_VERSAL2) += \
+	amd-versal2-virt.dtb
 dtb-$(CONFIG_ARCH_VERSAL_NET) += \
 	versal-net-mini.dtb \
 	versal-net-mini-emmc.dtb \
diff --git a/arch/arm/dts/amd-versal2-virt.dts b/arch/arm/dts/amd-versal2-virt.dts
new file mode 100644
index 0000000..3b6cbba
--- /dev/null
+++ b/arch/arm/dts/amd-versal2-virt.dts
@@ -0,0 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Empty device tree for amd-versal2-virt board
+ *
+ * Copyright (C) 2024, Advanced Micro Devices, Inc.
+ */
+
+/dts-v1/;
+
+/ {
+};
diff --git a/arch/arm/dts/zynqmp-mini-nand.dts b/arch/arm/dts/zynqmp-mini-nand.dts
index 5889d43..e08a784 100644
--- a/arch/arm/dts/zynqmp-mini-nand.dts
+++ b/arch/arm/dts/zynqmp-mini-nand.dts
@@ -46,8 +46,8 @@
 			status = "okay";
 			reg = <0x0 0xff100000 0x1000>;
 			clock-names = "clk_sys", "clk_flash";
-			#address-cells = <2>;
-			#size-cells = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
 			arasan,has-mdma;
 			num-cs = <2>;
 			nand@0 {
diff --git a/arch/arm/dts/zynqmp.dtsi b/arch/arm/dts/zynqmp.dtsi
index 53a606c..34f592c 100644
--- a/arch/arm/dts/zynqmp.dtsi
+++ b/arch/arm/dts/zynqmp.dtsi
@@ -314,19 +314,76 @@
 		ranges;
 	};
 
-	remoteproc {
+	rproc_lockstep: remoteproc@ffe00000 {
 		compatible = "xlnx,zynqmp-r5fss";
 		xlnx,cluster-mode = <1>;
+		xlnx,tcm-mode = <1>;
 
-		r5f-0 {
+		#address-cells = <2>;
+		#size-cells = <2>;
+
+		ranges = <0x0 0x0 0x0 0xffe00000 0x0 0x10000>,
+			 <0x0 0x20000 0x0 0xffe20000 0x0 0x10000>,
+			 <0x0 0x10000 0x0 0xffe10000 0x0 0x10000>,
+			 <0x0 0x30000 0x0 0xffe30000 0x0 0x10000>;
+
+		r5f@0 {
+			compatible = "xlnx,zynqmp-r5f";
+			reg = <0x0 0x0 0x0 0x10000>,
+			      <0x0 0x20000 0x0 0x10000>,
+			      <0x0 0x10000 0x0 0x10000>,
+			      <0x0 0x30000 0x0 0x10000>;
+			reg-names = "atcm0", "btcm0", "atcm1", "btcm1";
+			power-domains = <&zynqmp_firmware PD_RPU_0>,
+					<&zynqmp_firmware PD_R5_0_ATCM>,
+					<&zynqmp_firmware PD_R5_0_BTCM>,
+					<&zynqmp_firmware PD_R5_1_ATCM>,
+					<&zynqmp_firmware PD_R5_1_BTCM>;
+			memory-region = <&rproc_0_fw_image>;
+		};
+
+		r5f@1 {
+			compatible = "xlnx,zynqmp-r5f";
+			reg = <0x1 0x0 0x0 0x10000>, <0x1 0x20000 0x0 0x10000>;
+			reg-names = "atcm0", "btcm0";
+			power-domains = <&zynqmp_firmware PD_RPU_1>,
+					<&zynqmp_firmware PD_R5_1_ATCM>,
+					<&zynqmp_firmware PD_R5_1_BTCM>;
+			memory-region = <&rproc_1_fw_image>;
+		};
+	};
+
+	rproc_split: remoteproc-split@ffe00000 {
+		status = "disabled";
+		compatible = "xlnx,zynqmp-r5fss";
+		xlnx,cluster-mode = <0>;
+		xlnx,tcm-mode = <0>;
+
+		#address-cells = <2>;
+		#size-cells = <2>;
+
+		ranges = <0x0 0x0 0x0 0xffe00000 0x0 0x10000>,
+			 <0x0 0x20000 0x0 0xffe20000 0x0 0x10000>,
+			 <0x1 0x0 0x0 0xffe90000 0x0 0x10000>,
+			 <0x1 0x20000 0x0 0xffeb0000 0x0 0x10000>;
+
+		r5f@0 {
 			compatible = "xlnx,zynqmp-r5f";
-			power-domains = <&zynqmp_firmware PD_RPU_0>;
+			reg = <0x0 0x0 0x0 0x10000>, <0x0 0x20000 0x0 0x10000>;
+			reg-names = "atcm0", "btcm0";
+			power-domains = <&zynqmp_firmware PD_RPU_0>,
+					<&zynqmp_firmware PD_R5_0_ATCM>,
+					<&zynqmp_firmware PD_R5_0_BTCM>;
 			memory-region = <&rproc_0_fw_image>;
 		};
 
-		r5f-1 {
+		r5f@1 {
 			compatible = "xlnx,zynqmp-r5f";
-			power-domains = <&zynqmp_firmware PD_RPU_1>;
+			reg = <0x1 0x0 0x0 0x10000>, <0x1 0x20000 0x0 0x10000>;
+			reg-names = "atcm0", "btcm0";
+			power-domains = <&zynqmp_firmware PD_RPU_1>,
+					<&zynqmp_firmware PD_R5_1_ATCM>,
+					<&zynqmp_firmware PD_R5_1_BTCM>;
 			memory-region = <&rproc_1_fw_image>;
 		};
 	};
diff --git a/arch/arm/mach-versal2/Kconfig b/arch/arm/mach-versal2/Kconfig
new file mode 100644
index 0000000..3f18e33
--- /dev/null
+++ b/arch/arm/mach-versal2/Kconfig
@@ -0,0 +1,55 @@
+# SPDX-License-Identifier: GPL-2.0
+
+if ARCH_VERSAL2
+
+config SYS_BOARD
+	string "Board name"
+	default "versal2"
+
+config SYS_VENDOR
+	string "Vendor name"
+	default "amd"
+
+config SYS_SOC
+	default "versal2"
+
+config SYS_CONFIG_NAME
+	string "Board configuration name"
+	default "amd_versal2"
+	help
+	  This option contains information about board configuration name.
+	  Based on this option include/configs/<CONFIG_SYS_CONFIG_NAME>.h header
+	  will be used for board configuration.
+
+config COUNTER_FREQUENCY
+	int "Timer clock frequency"
+	default 0
+	help
+	  Setup time clock frequency for certain platform
+
+config IOU_SWITCH_DIVISOR0
+	hex "IOU switch divisor0"
+	default 0x20
+	help
+	  Setup time clock divisor for input clock.
+
+config SYS_MEM_RSVD_FOR_MMU
+	bool "Reserve memory for MMU Table"
+	help
+	  If defined this option is used to setup different space for
+	  MMU table than the one which will be allocated during
+	  relocation.
+
+config GICV3
+	def_bool y
+
+config SYS_MALLOC_LEN
+	default 0x2000000
+
+config ZYNQ_SDHCI_MAX_FREQ
+	default 200000000
+
+source "board/xilinx/Kconfig"
+source "board/amd/versal2/Kconfig"
+
+endif
diff --git a/arch/arm/mach-versal2/Makefile b/arch/arm/mach-versal2/Makefile
new file mode 100644
index 0000000..96497b1
--- /dev/null
+++ b/arch/arm/mach-versal2/Makefile
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Copyright (C) 2021 - 2022, Xilinx, Inc.
+# Copyright (C) 2022 - 2024, Advanced Micro Devices, Inc.
+#
+# Michal Simek <michal.simek@amd.com>
+#
+
+obj-y	+= clk.o
+obj-y	+= cpu.o
diff --git a/arch/arm/mach-versal2/clk.c b/arch/arm/mach-versal2/clk.c
new file mode 100644
index 0000000..e73ae9a
--- /dev/null
+++ b/arch/arm/mach-versal2/clk.c
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2016 - 2022,  Xilinx, Inc.
+ * Copyright (C) 2022 - 2024, Advanced Micro Devices, Inc.
+ *
+ * Michal Simek <michal.simek@amd.com>
+ */
+
+#include <init.h>
+#include <time.h>
+#include <asm/global_data.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifdef CONFIG_CLOCKS
+/**
+ * set_cpu_clk_info - Initialize clock framework
+ *
+ * Return: 0 always.
+ *
+ * This function is called from common code after relocation and sets up the
+ * clock framework. The framework must not be used before this function had been
+ * called.
+ */
+int set_cpu_clk_info(void)
+{
+	gd->cpu_clk = get_tbclk();
+
+	gd->bd->bi_arm_freq = gd->cpu_clk / 1000000;
+	gd->bd->bi_dsp_freq = 0;
+
+	return 0;
+}
+#endif
diff --git a/arch/arm/mach-versal2/cpu.c b/arch/arm/mach-versal2/cpu.c
new file mode 100644
index 0000000..2dfcadb
--- /dev/null
+++ b/arch/arm/mach-versal2/cpu.c
@@ -0,0 +1,93 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 - 2022, Xilinx, Inc.
+ * Copyright (C) 2022 - 2024, Advanced Micro Devices, Inc.
+ *
+ * Michal Simek <michal.simek@amd.com>
+ */
+
+#include <init.h>
+#include <asm/armv8/mmu.h>
+#include <asm/cache.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/cache.h>
+#include <dm/platdata.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define VERSAL2_MEM_MAP_USED	5
+
+#define DRAM_BANKS CONFIG_NR_DRAM_BANKS
+
+/* +1 is end of list which needs to be empty */
+#define VERSAL2_MEM_MAP_MAX (VERSAL2_MEM_MAP_USED + DRAM_BANKS + 1)
+
+static struct mm_region versal2_mem_map[VERSAL2_MEM_MAP_MAX] = {
+	{
+		.virt = 0x80000000UL,
+		.phys = 0x80000000UL,
+		.size = 0x70000000UL,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+			 PTE_BLOCK_NON_SHARE |
+			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
+	}, {
+		.virt = 0xf0000000UL,
+		.phys = 0xf0000000UL,
+		.size = 0x0fe00000UL,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+			 PTE_BLOCK_NON_SHARE |
+			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
+	}, {
+		.virt = 0x400000000UL,
+		.phys = 0x400000000UL,
+		.size = 0x200000000UL,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+			 PTE_BLOCK_NON_SHARE |
+			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
+	}, {
+		.virt = 0x600000000UL,
+		.phys = 0x600000000UL,
+		.size = 0x800000000UL,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+			 PTE_BLOCK_INNER_SHARE
+	}, {
+		.virt = 0xe00000000UL,
+		.phys = 0xe00000000UL,
+		.size = 0xf200000000UL,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+			 PTE_BLOCK_NON_SHARE |
+			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
+	}
+};
+
+void mem_map_fill(void)
+{
+	int banks = VERSAL2_MEM_MAP_USED;
+
+	for (int i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+		/* Zero size means no more DDR that's this is end */
+		if (!gd->bd->bi_dram[i].size)
+			break;
+
+		versal2_mem_map[banks].virt = gd->bd->bi_dram[i].start;
+		versal2_mem_map[banks].phys = gd->bd->bi_dram[i].start;
+		versal2_mem_map[banks].size = gd->bd->bi_dram[i].size;
+		versal2_mem_map[banks].attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+					      PTE_BLOCK_INNER_SHARE;
+		banks = banks + 1;
+	}
+}
+
+struct mm_region *mem_map = versal2_mem_map;
+
+u64 get_page_table_size(void)
+{
+	return 0x14000;
+}
+
+U_BOOT_DRVINFO(soc_amd_versal2) = {
+	.name = "soc_amd_versal2",
+};
diff --git a/arch/arm/mach-versal2/include/mach/hardware.h b/arch/arm/mach-versal2/include/mach/hardware.h
new file mode 100644
index 0000000..42e3061
--- /dev/null
+++ b/arch/arm/mach-versal2/include/mach/hardware.h
@@ -0,0 +1,97 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2016 - 2022, Xilinx, Inc.
+ * Copyright (C) 2022 - 2024, Advanced Micro Devices, Inc.
+ */
+
+#ifndef __ASSEMBLY__
+#include <linux/bitops.h>
+#endif
+
+struct crlapb_regs {
+	u32 reserved0[67];
+	u32 cpu_r5_ctrl;
+	u32 reserved;
+	u32 iou_switch_ctrl; /* 0x114 */
+	u32 reserved1[13];
+	u32 timestamp_ref_ctrl; /* 0x14c */
+	u32 reserved3[108];
+	u32 rst_cpu_r5;
+	u32 reserved2[17];
+	u32 rst_timestamp; /* 0x348 */
+};
+
+struct iou_scntrs_regs {
+	u32 counter_control_register; /* 0x0 */
+	u32 reserved0[7];
+	u32 base_frequency_id_register; /* 0x20 */
+};
+
+struct crp_regs {
+	u32 reserved0[128];
+	u32 boot_mode_usr;	/* 0x200 */
+};
+
+#define VERSAL2_CRL_APB_BASEADDR		0xEB5E0000
+#define VERSAL2_CRP_BASEADDR			0xF1260000
+#define VERSAL2_IOU_SCNTR_SECURE		0xEC920000
+
+#define CRL_APB_TIMESTAMP_REF_CTRL_CLKACT_BIT	BIT(25)
+#define IOU_SWITCH_CTRL_CLKACT_BIT		BIT(25)
+#define IOU_SWITCH_CTRL_DIVISOR0_SHIFT		8
+#define IOU_SCNTRS_CONTROL_EN			1
+
+#define crlapb_base ((struct crlapb_regs *)VERSAL2_CRL_APB_BASEADDR)
+#define crp_base ((struct crp_regs *)VERSAL2_CRP_BASEADDR)
+#define iou_scntr_secure ((struct iou_scntrs_regs *)VERSAL2_IOU_SCNTR_SECURE)
+
+#define PMC_TAP	0xF11A0000
+
+#define PMC_TAP_IDCODE		(PMC_TAP + 0)
+#define PMC_TAP_VERSION		(PMC_TAP + 0x4)
+# define PMC_VERSION_MASK	GENMASK(7, 0)
+# define PS_VERSION_MASK	GENMASK(15, 8)
+# define PS_VERSION_PRODUCTION	0x20
+# define RTL_VERSION_MASK	GENMASK(23, 16)
+# define PLATFORM_MASK		GENMASK(27, 24)
+# define PLATFORM_VERSION_MASK	GENMASK(31, 28)
+#define PMC_TAP_USERCODE	(PMC_TAP + 0x8)
+
+/* Bootmode setting values */
+#define BOOT_MODES_MASK	0x0000000F
+#define QSPI_MODE_24BIT	0x00000001
+#define QSPI_MODE_32BIT	0x00000002
+#define SD_MODE		0x00000003 /* sd 0 */
+#define SD_MODE1	0x00000005 /* sd 1 */
+#define EMMC_MODE	0x00000006
+#define USB_MODE	0x00000007
+#define OSPI_MODE	0x00000008
+#define SELECTMAP_MODE	0x0000000A
+#define SD1_LSHFT_MODE	0x0000000E /* SD1 Level shifter */
+#define JTAG_MODE	0x00000000
+#define BOOT_MODE_USE_ALT	0x100
+#define BOOT_MODE_ALT_SHIFT	12
+
+enum versal2_platform {
+	VERSAL2_SILICON = 0,
+	VERSAL2_SPP = 1,
+	VERSAL2_EMU = 2,
+	VERSAL2_QEMU = 3,
+	VERSAL2_SPP_MMD = 5,
+	VERSAL2_EMU_MMD = 6,
+};
+
+#define VERSAL2_SLCR_BASEADDR	0xF1060000
+#define VERSAL_AXI_MUX_SEL	(VERSAL2_SLCR_BASEADDR + 0x504)
+#define VERSAL_OSPI_LINEAR_MODE	BIT(1)
+
+#define FLASH_RESET_GPIO	0xc
+#define WPROT_CRP	0xF126001C
+#define RST_GPIO	0xF1260318
+#define WPROT_LPD_MIO	0xFF080728
+#define WPROT_PMC_MIO	0xF1060828
+#define BOOT_MODE_DIR	0xF1020204
+#define BOOT_MODE_OUT	0xF1020208
+#define MIO_PIN_12	0xF1060030
+#define BANK0_OUTPUT	0xF1020040
+#define BANK0_TRI	0xF1060200
diff --git a/arch/arm/mach-versal2/include/mach/sys_proto.h b/arch/arm/mach-versal2/include/mach/sys_proto.h
new file mode 100644
index 0000000..7b1726a
--- /dev/null
+++ b/arch/arm/mach-versal2/include/mach/sys_proto.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2021 - 2022, Xilinx, Inc.
+ * Copyright (C) 2022 - 2024, Advanced Micro Devices, Inc.
+ */
+
+#include <linux/build_bug.h>
+
+void mem_map_fill(void);
diff --git a/arch/arm/mach-zynq/spl.c b/arch/arm/mach-zynq/spl.c
index 8ef12ed..dc964dc 100644
--- a/arch/arm/mach-zynq/spl.c
+++ b/arch/arm/mach-zynq/spl.c
@@ -31,8 +31,8 @@
 	arch_cpu_init();
 }
 
-#ifdef CONFIG_SPL_BOARD_INIT
-void spl_board_init(void)
+#ifdef CONFIG_SPL_SOC_INIT
+void spl_soc_init(void)
 {
 	preloader_console_init();
 #if defined(CONFIG_ARCH_EARLY_INIT_R) && defined(CONFIG_SPL_FPGA)
diff --git a/arch/arm/mach-zynqmp/Kconfig b/arch/arm/mach-zynqmp/Kconfig
index 0d2238a..aea1362 100644
--- a/arch/arm/mach-zynqmp/Kconfig
+++ b/arch/arm/mach-zynqmp/Kconfig
@@ -189,7 +189,18 @@
 
 endchoice
 
+config CMD_ZYNQMP
+	bool "Enable ZynqMP specific commands"
+	depends on ZYNQMP_FIRMWARE
+	default y
+	help
+	  Enable ZynqMP specific commands like "zynqmp secure"
+	  which is used for zynqmp secure image verification.
+	  The secure image is a xilinx specific BOOT.BIN with
+	  either authentication or encryption or both encryption
+	  and authentication feature enabled while generating
+	  BOOT.BIN using Xilinx bootgen tool.
+
 source "board/xilinx/Kconfig"
-source "board/xilinx/zynqmp/Kconfig"
 
 endif
diff --git a/arch/arm/mach-zynqmp/Makefile b/arch/arm/mach-zynqmp/Makefile
index 8f897a3..38be162 100644
--- a/arch/arm/mach-zynqmp/Makefile
+++ b/arch/arm/mach-zynqmp/Makefile
@@ -8,3 +8,7 @@
 obj-$(CONFIG_SPL_BUILD) += spl.o handoff.o psu_spl_init.o
 obj-$(CONFIG_SPL_ZYNQMP_DRAM_ECC_INIT) += ecc_spl_init.o
 obj-$(CONFIG_$(SPL_)ZYNQMP_PSU_INIT_ENABLED)	+= psu_spl_init.o
+
+ifndef CONFIG_SPL_BUILD
+obj-$(CONFIG_CMD_ZYNQMP) += zynqmp.o
+endif # !CONFIG_SPL_BUILD
diff --git a/arch/arm/mach-zynqmp/spl.c b/arch/arm/mach-zynqmp/spl.c
index 6b67245..4a2d240 100644
--- a/arch/arm/mach-zynqmp/spl.c
+++ b/arch/arm/mach-zynqmp/spl.c
@@ -56,8 +56,8 @@
 # define MODE_RESET	PS_MODE1
 #endif
 
-#ifdef CONFIG_SPL_BOARD_INIT
-void spl_board_init(void)
+#ifdef CONFIG_SPL_SOC_INIT
+void spl_soc_init(void)
 {
 	preloader_console_init();
 	ps_mode_reset(MODE_RESET);
diff --git a/board/xilinx/zynqmp/cmds.c b/arch/arm/mach-zynqmp/zynqmp.c
similarity index 100%
rename from board/xilinx/zynqmp/cmds.c
rename to arch/arm/mach-zynqmp/zynqmp.c
diff --git a/board/amd/common b/board/amd/common
new file mode 120000
index 0000000..cd4d172
--- /dev/null
+++ b/board/amd/common
@@ -0,0 +1 @@
+../xilinx/common/
\ No newline at end of file
diff --git a/board/amd/versal2/Kconfig b/board/amd/versal2/Kconfig
new file mode 100644
index 0000000..ab46af6
--- /dev/null
+++ b/board/amd/versal2/Kconfig
@@ -0,0 +1,16 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Copyright (C) 2020 - 2022, Xilinx, Inc.
+# Copyright (C) 2022 - 2024, Advanced Micro Devices, Inc.
+#
+if ARCH_VERSAL2
+
+config CMD_VERSAL2
+	bool "Enable Versal Gen 2 specific commands"
+	default y
+	depends on ZYNQMP_FIRMWARE
+	help
+	  Select this to enable AMD Versal Gen 2 specific commands.
+	  Commands like versal2 loadpdi are enabled by this.
+
+endif
diff --git a/board/amd/versal2/MAINTAINERS b/board/amd/versal2/MAINTAINERS
new file mode 100644
index 0000000..af7913d
--- /dev/null
+++ b/board/amd/versal2/MAINTAINERS
@@ -0,0 +1,7 @@
+XILINX_VERSAL2 BOARDS
+M:	Michal Simek <michal.simek@amd.com>
+S:	Maintained
+T:	git https://gitlab.denx.de/u-boot/custodians/u-boot-microblaze.git
+F:	arch/arm/dts/versal2*
+F:	board/amd/
+F:	configs/amd*
diff --git a/board/amd/versal2/Makefile b/board/amd/versal2/Makefile
new file mode 100644
index 0000000..3a04451
--- /dev/null
+++ b/board/amd/versal2/Makefile
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Copyright (C) 2021 - 2022, Xilinx, Inc.
+# Copyright (C) 2022 - 2024, Advanced Micro Devices, Inc.
+#
+# Michal Simek <michal.simek@amd.com>
+#
+
+obj-y	:= board.o
+
+obj-$(CONFIG_CMD_VERSAL2)   += cmds.o
diff --git a/board/amd/versal2/board.c b/board/amd/versal2/board.c
new file mode 100644
index 0000000..5651d51
--- /dev/null
+++ b/board/amd/versal2/board.c
@@ -0,0 +1,343 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 - 2022, Xilinx, Inc.
+ * Copyright (C) 2022 - 2024, Advanced Micro Devices, Inc.
+ *
+ * Michal Simek <michal.simek@amd.com>
+ */
+
+#include <cpu_func.h>
+#include <fdtdec.h>
+#include <init.h>
+#include <env_internal.h>
+#include <log.h>
+#include <malloc.h>
+#include <time.h>
+#include <asm/cache.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/sys_proto.h>
+#include <dm/device.h>
+#include <dm/uclass.h>
+#include "../../xilinx/common/board.h"
+
+#include <linux/bitfield.h>
+#include <debug_uart.h>
+#include <generated/dt.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int board_init(void)
+{
+	printf("EL Level:\tEL%d\n", current_el());
+
+	return 0;
+}
+
+static u32 platform_id, platform_version;
+
+char *soc_name_decode(void)
+{
+	char *name, *platform_name;
+
+	switch (platform_id) {
+	case VERSAL2_SPP:
+		platform_name = "spp";
+		break;
+	case VERSAL2_EMU:
+		platform_name = "emu";
+		break;
+	case VERSAL2_SPP_MMD:
+		platform_name = "spp-mmd";
+		break;
+	case VERSAL2_EMU_MMD:
+		platform_name = "emu-mmd";
+		break;
+	case VERSAL2_QEMU:
+		platform_name = "qemu";
+		break;
+	default:
+		return NULL;
+	}
+
+	/*
+	 * --rev. are 6 chars
+	 * max platform name is qemu which is 4 chars
+	 * platform version number are 1+1
+	 * Plus 1 char for \n
+	 */
+	name = calloc(1, strlen(CONFIG_SYS_BOARD) + 13);
+	if (!name)
+		return NULL;
+
+	sprintf(name, "%s-%s-rev%d.%d-el%d", CONFIG_SYS_BOARD,
+		platform_name, platform_version / 10,
+		platform_version % 10, current_el());
+
+	return name;
+}
+
+bool soc_detection(void)
+{
+	u32 version, ps_version;
+
+	version = readl(PMC_TAP_VERSION);
+	platform_id = FIELD_GET(PLATFORM_MASK, version);
+	ps_version = FIELD_GET(PS_VERSION_MASK, version);
+
+	debug("idcode %x, version %x, usercode %x\n",
+	      readl(PMC_TAP_IDCODE), version,
+	      readl(PMC_TAP_USERCODE));
+
+	debug("pmc_ver %lx, ps version %x, rtl version %lx\n",
+	      FIELD_GET(PMC_VERSION_MASK, version),
+	      ps_version,
+	      FIELD_GET(RTL_VERSION_MASK, version));
+
+	platform_version = FIELD_GET(PLATFORM_VERSION_MASK, version);
+
+	debug("Platform id: %d version: %d.%d\n", platform_id,
+	      platform_version / 10, platform_version % 10);
+
+	return true;
+}
+
+int board_early_init_r(void)
+{
+	u32 val;
+
+	if (current_el() != 3)
+		return 0;
+
+	debug("iou_switch ctrl div0 %x\n",
+	      readl(&crlapb_base->iou_switch_ctrl));
+
+	writel(IOU_SWITCH_CTRL_CLKACT_BIT |
+	       (CONFIG_IOU_SWITCH_DIVISOR0 << IOU_SWITCH_CTRL_DIVISOR0_SHIFT),
+	       &crlapb_base->iou_switch_ctrl);
+
+	/* Global timer init - Program time stamp reference clk */
+	val = readl(&crlapb_base->timestamp_ref_ctrl);
+	val |= CRL_APB_TIMESTAMP_REF_CTRL_CLKACT_BIT;
+	writel(val, &crlapb_base->timestamp_ref_ctrl);
+
+	debug("ref ctrl 0x%x\n",
+	      readl(&crlapb_base->timestamp_ref_ctrl));
+
+	/* Clear reset of timestamp reg */
+	writel(0, &crlapb_base->rst_timestamp);
+
+	/*
+	 * Program freq register in System counter and
+	 * enable system counter.
+	 */
+	writel(CONFIG_COUNTER_FREQUENCY,
+	       &iou_scntr_secure->base_frequency_id_register);
+
+	debug("counter val 0x%x\n",
+	      readl(&iou_scntr_secure->base_frequency_id_register));
+
+	writel(IOU_SCNTRS_CONTROL_EN,
+	       &iou_scntr_secure->counter_control_register);
+
+	debug("scntrs control 0x%x\n",
+	      readl(&iou_scntr_secure->counter_control_register));
+	debug("timer 0x%llx\n", get_ticks());
+	debug("timer 0x%llx\n", get_ticks());
+
+	return 0;
+}
+
+static u8 versal_net_get_bootmode(void)
+{
+	u8 bootmode;
+	u32 reg = 0;
+
+	reg = readl(&crp_base->boot_mode_usr);
+
+	if (reg >> BOOT_MODE_ALT_SHIFT)
+		reg >>= BOOT_MODE_ALT_SHIFT;
+
+	bootmode = reg & BOOT_MODES_MASK;
+
+	return bootmode;
+}
+
+static int boot_targets_setup(void)
+{
+	u8 bootmode;
+	struct udevice *dev;
+	int bootseq = -1;
+	int bootseq_len = 0;
+	int env_targets_len = 0;
+	const char *mode = NULL;
+	char *new_targets;
+	char *env_targets;
+
+	bootmode = versal_net_get_bootmode();
+
+	puts("Bootmode: ");
+	switch (bootmode) {
+	case USB_MODE:
+		puts("USB_MODE\n");
+		mode = "usb_dfu0 usb_dfu1";
+		break;
+	case JTAG_MODE:
+		puts("JTAG_MODE\n");
+		mode = "jtag pxe dhcp";
+		break;
+	case QSPI_MODE_24BIT:
+		puts("QSPI_MODE_24\n");
+		if (uclass_get_device_by_name(UCLASS_SPI,
+					      "spi@f1030000", &dev)) {
+			debug("QSPI driver for QSPI device is not present\n");
+			break;
+		}
+		mode = "xspi";
+		bootseq = dev_seq(dev);
+		break;
+	case QSPI_MODE_32BIT:
+		puts("QSPI_MODE_32\n");
+		if (uclass_get_device_by_name(UCLASS_SPI,
+					      "spi@f1030000", &dev)) {
+			debug("QSPI driver for QSPI device is not present\n");
+			break;
+		}
+		mode = "xspi";
+		bootseq = dev_seq(dev);
+		break;
+	case OSPI_MODE:
+		puts("OSPI_MODE\n");
+		if (uclass_get_device_by_name(UCLASS_SPI,
+					      "spi@f1010000", &dev)) {
+			debug("OSPI driver for OSPI device is not present\n");
+			break;
+		}
+		mode = "xspi";
+		bootseq = dev_seq(dev);
+		break;
+	case EMMC_MODE:
+		puts("EMMC_MODE\n");
+		mode = "mmc";
+		bootseq = dev_seq(dev);
+		break;
+	case SELECTMAP_MODE:
+		puts("SELECTMAP_MODE\n");
+		break;
+	case SD_MODE:
+		puts("SD_MODE\n");
+		if (uclass_get_device_by_name(UCLASS_MMC,
+					      "mmc@f1040000", &dev)) {
+			debug("SD0 driver for SD0 device is not present\n");
+			break;
+		}
+		debug("mmc0 device found at %p, seq %d\n", dev, dev_seq(dev));
+
+		mode = "mmc";
+		bootseq = dev_seq(dev);
+		break;
+	case SD1_LSHFT_MODE:
+		puts("LVL_SHFT_");
+		fallthrough;
+	case SD_MODE1:
+		puts("SD_MODE1\n");
+		if (uclass_get_device_by_name(UCLASS_MMC,
+					      "mmc@f1050000", &dev)) {
+			debug("SD1 driver for SD1 device is not present\n");
+			break;
+		}
+		debug("mmc1 device found at %p, seq %d\n", dev, dev_seq(dev));
+
+		mode = "mmc";
+		bootseq = dev_seq(dev);
+		break;
+	default:
+		printf("Invalid Boot Mode:0x%x\n", bootmode);
+		break;
+	}
+
+	if (mode) {
+		if (bootseq >= 0) {
+			bootseq_len = snprintf(NULL, 0, "%i", bootseq);
+			debug("Bootseq len: %x\n", bootseq_len);
+		}
+
+		/*
+		 * One terminating char + one byte for space between mode
+		 * and default boot_targets
+		 */
+		env_targets = env_get("boot_targets");
+		if (env_targets)
+			env_targets_len = strlen(env_targets);
+
+		new_targets = calloc(1, strlen(mode) + env_targets_len + 2 +
+				     bootseq_len);
+		if (!new_targets)
+			return -ENOMEM;
+
+		if (bootseq >= 0)
+			sprintf(new_targets, "%s%x %s", mode, bootseq,
+				env_targets ? env_targets : "");
+		else
+			sprintf(new_targets, "%s %s", mode,
+				env_targets ? env_targets : "");
+
+		env_set("boot_targets", new_targets);
+	}
+
+	return 0;
+}
+
+int board_late_init(void)
+{
+	int ret;
+
+	if (!(gd->flags & GD_FLG_ENV_DEFAULT)) {
+		debug("Saved variables - Skipping\n");
+		return 0;
+	}
+
+	if (!IS_ENABLED(CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG))
+		return 0;
+
+	if (IS_ENABLED(CONFIG_DISTRO_DEFAULTS)) {
+		ret = boot_targets_setup();
+		if (ret)
+			return ret;
+	}
+
+	return board_late_init_xilinx();
+}
+
+int dram_init_banksize(void)
+{
+	int ret;
+
+	ret = fdtdec_setup_memory_banksize();
+	if (ret)
+		return ret;
+
+	mem_map_fill();
+
+	return 0;
+}
+
+int dram_init(void)
+{
+	int ret;
+
+	if (IS_ENABLED(CONFIG_SYS_MEM_RSVD_FOR_MMU))
+		ret = fdtdec_setup_mem_size_base();
+	else
+		ret = fdtdec_setup_mem_size_base_lowest();
+
+	if (ret)
+		return -EINVAL;
+
+	return 0;
+}
+
+void reset_cpu(void)
+{
+}
diff --git a/board/amd/versal2/cmds.c b/board/amd/versal2/cmds.c
new file mode 100644
index 0000000..fbd9991
--- /dev/null
+++ b/board/amd/versal2/cmds.c
@@ -0,0 +1,81 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2024, Advanced Micro Devices, Inc.
+ *
+ * Michal Simek <michal.simek@amd.com>
+ */
+
+#include <cpu_func.h>
+#include <command.h>
+#include <log.h>
+#include <memalign.h>
+#include <versalpl.h>
+#include <vsprintf.h>
+#include <zynqmp_firmware.h>
+
+/**
+ * do_versal2_load_pdi - Handle the "versal2 load pdi" command-line command
+ * @cmdtp:      Command data struct pointer
+ * @flag:       Command flag
+ * @argc:       Command-line argument count
+ * @argv:       Array of command-line arguments
+ *
+ * Processes the versal2 load pdi command
+ *
+ * Return: return 0 on success, Error value if command fails.
+ * CMD_RET_USAGE incase of incorrect/missing parameters.
+ */
+static int do_versal2_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[1], NULL, 16);
+	if (!addr) {
+		debug("pdi_load: zero pdi_data address\n");
+		return CMD_RET_USAGE;
+	}
+
+	len = hextoul(argv[2], NULL);
+	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 cmd_process_error(cmdtp, ret);
+}
+
+static char versal2_help_text[] =
+	"loadpdi addr len - Load pdi image\n"
+	"load pdi image at ddr address 'addr' with pdi image size 'len'\n"
+;
+
+U_BOOT_CMD_WITH_SUBCMDS(versal2, "Versal Gen 2 sub-system", versal2_help_text,
+			U_BOOT_SUBCMD_MKENT(loadpdi, 3, 1,
+					    do_versal2_load_pdi));
diff --git a/board/xilinx/Kconfig b/board/xilinx/Kconfig
index 5c4ad8f..c7df4ab 100644
--- a/board/xilinx/Kconfig
+++ b/board/xilinx/Kconfig
@@ -42,7 +42,7 @@
 
 config XILINX_OF_BOARD_DTB_ADDR
 	hex "Default DTB pickup address"
-	default 0x1000 if ARCH_VERSAL || ARCH_VERSAL_NET
+	default 0x1000 if ARCH_VERSAL || ARCH_VERSAL_NET || ARCH_VERSAL2
 	default 0x8000 if MICROBLAZE
 	default 0x100000 if ARCH_ZYNQ || ARCH_ZYNQMP
 	default 0x23000000 if TARGET_XILINX_MBV
@@ -52,10 +52,10 @@
 
 config BOOT_SCRIPT_OFFSET
 	hex "Boot script offset"
-	depends on ARCH_ZYNQ || ARCH_ZYNQMP || ARCH_VERSAL || ARCH_VERSAL_NET || MICROBLAZE || TARGET_XILINX_MBV
+	depends on ARCH_ZYNQ || ARCH_ZYNQMP || ARCH_VERSAL || ARCH_VERSAL_NET || ARCH_VERSAL2 || MICROBLAZE || TARGET_XILINX_MBV
 	default 0xFC0000 if ARCH_ZYNQ || MICROBLAZE
 	default 0x3E80000 if ARCH_ZYNQMP
-	default 0x7F80000 if ARCH_VERSAL || ARCH_VERSAL_NET
+	default 0x7F80000 if ARCH_VERSAL || ARCH_VERSAL_NET || ARCH_VERSAL2
 	default 0 if TARGET_XILINX_MBV
 	help
 	   Specifies distro boot script offset in NAND/QSPI/NOR flash.
diff --git a/board/xilinx/versal/board.c b/board/xilinx/versal/board.c
index 77ba783..3947467 100644
--- a/board/xilinx/versal/board.c
+++ b/board/xilinx/versal/board.c
@@ -150,14 +150,29 @@
 		break;
 	case QSPI_MODE_24BIT:
 		puts("QSPI_MODE_24\n");
+		if (uclass_get_device_by_name(UCLASS_SPI,
+					      "spi@f1030000", &dev)) {
+			debug("QSPI driver for QSPI device is not present\n");
+			break;
+		}
 		mode = "xspi0";
 		break;
 	case QSPI_MODE_32BIT:
 		puts("QSPI_MODE_32\n");
+		if (uclass_get_device_by_name(UCLASS_SPI,
+					      "spi@f1030000", &dev)) {
+			debug("QSPI driver for QSPI device is not present\n");
+			break;
+		}
 		mode = "xspi0";
 		break;
 	case OSPI_MODE:
 		puts("OSPI_MODE\n");
+		if (uclass_get_device_by_name(UCLASS_SPI,
+					      "spi@f1010000", &dev)) {
+			debug("OSPI driver for OSPI device is not present\n");
+			break;
+		}
 		mode = "xspi0";
 		break;
 	case EMMC_MODE:
diff --git a/board/xilinx/zynqmp/Kconfig b/board/xilinx/zynqmp/Kconfig
deleted file mode 100644
index ffa2f02..0000000
--- a/board/xilinx/zynqmp/Kconfig
+++ /dev/null
@@ -1,19 +0,0 @@
-# Copyright (c) 2018, Xilinx, Inc.
-#
-# SPDX-License-Identifier: GPL-2.0
-
-if ARCH_ZYNQMP
-
-config CMD_ZYNQMP
-	bool "Enable ZynqMP specific commands"
-	depends on ZYNQMP_FIRMWARE
-	default y
-	help
-	  Enable ZynqMP specific commands like "zynqmp secure"
-	  which is used for zynqmp secure image verification.
-	  The secure image is a xilinx specific BOOT.BIN with
-	  either authentication or encryption or both encryption
-	  and authentication feature enabled while generating
-	  BOOT.BIN using Xilinx bootgen tool.
-
-endif
diff --git a/board/xilinx/zynqmp/Makefile b/board/xilinx/zynqmp/Makefile
index 204e4fa..9ab50ec 100644
--- a/board/xilinx/zynqmp/Makefile
+++ b/board/xilinx/zynqmp/Makefile
@@ -40,10 +40,6 @@
 endif
 endif
 
-ifndef CONFIG_SPL_BUILD
-obj-$(CONFIG_CMD_ZYNQMP) += cmds.o
-endif
-
 # Suppress "warning: function declaration isn't a prototype"
 CFLAGS_REMOVE_psu_init_gpl.o := -Wstrict-prototypes
 
diff --git a/board/xilinx/zynqmp/zynqmp-sm-k24-revA/psu_init_gpl.c b/board/xilinx/zynqmp/zynqmp-sm-k24-revA/psu_init_gpl.c
index 166e614..274203f 100644
--- a/board/xilinx/zynqmp/zynqmp-sm-k24-revA/psu_init_gpl.c
+++ b/board/xilinx/zynqmp/zynqmp-sm-k24-revA/psu_init_gpl.c
@@ -528,8 +528,8 @@
 	psu_mask_write(0xFF180124, 0x000000FEU, 0x00000002U);
 	psu_mask_write(0xFF180128, 0x000000FEU, 0x00000002U);
 	psu_mask_write(0xFF18012C, 0x000000FEU, 0x00000002U);
-	psu_mask_write(0xFF180130, 0x000000FEU, 0x000000C0U);
-	psu_mask_write(0xFF180134, 0x000000FEU, 0x000000C0U);
+	psu_mask_write(0xFF180130, 0x000000FEU, 0x00000000U);
+	psu_mask_write(0xFF180134, 0x000000FEU, 0x00000000U);
 	psu_mask_write(0xFF180204, 0xFFFFFFFFU, 0x50000000U);
 	psu_mask_write(0xFF180208, 0xFFFFFFFFU, 0x00B02020U);
 	psu_mask_write(0xFF18020C, 0x00003FFFU, 0x00000FC0U);
@@ -569,21 +569,16 @@
 	psu_mask_write(0xFD1A0100, 0x0001807CU, 0x00000000U);
 	psu_mask_write(0xFF5E0238, 0x001A0000U, 0x00000000U);
 	psu_mask_write(0xFF5E023C, 0x0093C018U, 0x00000000U);
-	psu_mask_write(0xFF5E0230, 0x00000008U, 0x00000000U);
+	psu_mask_write(0xFF5E0230, 0x00000002U, 0x00000000U);
 	psu_mask_write(0xFF5E0238, 0x00000001U, 0x00000000U);
 	psu_mask_write(0xFF180390, 0x00000004U, 0x00000004U);
 	psu_mask_write(0xFF5E023C, 0x00000400U, 0x00000000U);
-	psu_mask_write(0xFF5E0238, 0x00000040U, 0x00000000U);
-	psu_mask_write(0xFF180310, 0x00008000U, 0x00000000U);
-	psu_mask_write(0xFF180320, 0x33840000U, 0x02840000U);
-	psu_mask_write(0xFF18031C, 0x7FFE0000U, 0x64500000U);
-	psu_mask_write(0xFF180358, 0x00000008U, 0x00000008U);
-	psu_mask_write(0xFF180324, 0x03C00000U, 0x00000000U);
+	psu_mask_write(0xFF5E0238, 0x00000080U, 0x00000000U);
 	psu_mask_write(0xFF5E0238, 0x00000400U, 0x00000000U);
 	psu_mask_write(0xFF5E0238, 0x00008000U, 0x00000000U);
 	psu_mask_write(0xFF5E0238, 0x00000010U, 0x00000000U);
 	psu_mask_write(0xFF5E0238, 0x00007800U, 0x00000000U);
-	psu_mask_write(0xFF5E0238, 0x00000004U, 0x00000000U);
+	psu_mask_write(0xFF5E0238, 0x00000006U, 0x00000000U);
 	psu_mask_write(0xFF5E0238, 0x00040000U, 0x00000000U);
 	psu_mask_write(0xFF4B0024, 0x000000FFU, 0x000000FFU);
 	psu_mask_write(0xFFCA5000, 0x00001FFFU, 0x00000000U);
@@ -591,13 +586,15 @@
 	psu_mask_write(0xFFA60040, 0x80000000U, 0x80000000U);
 	psu_mask_write(0xFF260020, 0xFFFFFFFFU, 0x05F5DD18U);
 	psu_mask_write(0xFF260000, 0x00000001U, 0x00000001U);
-	psu_mask_write(0xFF5E0250, 0x00000F0FU, 0x00000202U);
+	psu_mask_write(0xFF0A0284, 0x03FFFFFFU, 0x01000000U);
+	psu_mask_write(0xFF0A0288, 0x03FFFFFFU, 0x01000000U);
+	psu_mask_write(0xFF0A0014, 0x03FF03FFU, 0x02FF0100U);
 
 	mask_delay(1);
-	psu_mask_write(0xFF5E0250, 0x00000F0FU, 0x00000002U);
+	psu_mask_write(0xFF0A0014, 0x03FF03FFU, 0x02FF0000U);
 
 	mask_delay(5);
-	psu_mask_write(0xFF5E0250, 0x00000F0FU, 0x00000202U);
+	psu_mask_write(0xFF0A0014, 0x03FF03FFU, 0x02FF0100U);
 
 	return 1;
 }
diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c
index c4050af..b4c15b0 100644
--- a/board/xilinx/zynqmp/zynqmp.c
+++ b/board/xilinx/zynqmp/zynqmp.c
@@ -285,6 +285,18 @@
 #if !CONFIG_IS_ENABLED(SYSRESET)
 void reset_cpu(void)
 {
+	if (!IS_ENABLED(CONFIG_ZYNQMP_FIRMWARE)) {
+		log_warning("reset failed: ZYNQMP_FIRMWARE disabled");
+		return;
+	}
+
+	/* In case of !CONFIG_ZYNQMP_FIRMWARE the call to 'xilinx_pm_request()'
+	 * will be removed by the compiler due to the early return.
+	 * If CONFIG_ZYNQMP_FIRMWARE is defined in SPL 'xilinx_pm_request()'
+	 * will send command over IPI and requires pmufw to be present.
+	 */
+	xilinx_pm_request(PM_RESET_ASSERT, ZYNQMP_PM_RESET_SOFT,
+			  PM_RESET_ACTION_ASSERT, 0, 0, NULL);
 }
 #endif
 
@@ -519,6 +531,10 @@
 	usb_ether_init();
 #endif
 
+	multiboot = multi_boot();
+	if (multiboot >= 0)
+		env_set_hex("multiboot", multiboot);
+
 	if (!(gd->flags & GD_FLG_ENV_DEFAULT)) {
 		debug("Saved variables - Skipping\n");
 		return 0;
@@ -531,10 +547,6 @@
 	if (ret)
 		return ret;
 
-	multiboot = multi_boot();
-	if (multiboot >= 0)
-		env_set_hex("multiboot", multiboot);
-
 	if (IS_ENABLED(CONFIG_DISTRO_DEFAULTS)) {
 		ret = boot_targets_setup();
 		if (ret)
diff --git a/board/xilinx/zynqmp/zynqmp_kria.env b/board/xilinx/zynqmp/zynqmp_kria.env
index 846eceb..69e333c 100644
--- a/board/xilinx/zynqmp/zynqmp_kria.env
+++ b/board/xilinx/zynqmp/zynqmp_kria.env
@@ -65,6 +65,7 @@
 tpm_setup=tpm autostart;
 
 board_setup=\
+zynqmp mmio_write 0xFFCA0010 0xfff 0; \
 if test ${card1_name} = SCK-KV-G; then run kv260_setup; fi;\
 if test ${card1_name} = SCK-KR-G; then run kr260_setup; fi;\
 if test ${card1_name} = SCK-KD-G; then run kd240_setup; fi;\
diff --git a/common/spl/Kconfig b/common/spl/Kconfig
index e088940..af43b5f 100644
--- a/common/spl/Kconfig
+++ b/common/spl/Kconfig
@@ -272,6 +272,13 @@
 	help
 	  The address in memory that SPL will be running from.
 
+config SPL_SOC_INIT
+	bool "Call SoC-specific initialization in SPL"
+	help
+	  If this option is enabled, U-Boot will call the function
+	  spl_soc_init() from board_init_r(). This function should be
+	  provided by the SoC vendor.
+
 config SPL_BOARD_INIT
 	bool "Call board-specific initialization in SPL"
 	help
diff --git a/common/spl/spl.c b/common/spl/spl.c
index 9a879e9..7794ddc 100644
--- a/common/spl/spl.c
+++ b/common/spl/spl.c
@@ -710,6 +710,9 @@
 		}
 	}
 
+	if (CONFIG_IS_ENABLED(SOC_INIT))
+		spl_soc_init();
+
 	if (CONFIG_IS_ENABLED(BOARD_INIT))
 		spl_board_init();
 
diff --git a/configs/amd_versal2_virt_defconfig b/configs/amd_versal2_virt_defconfig
new file mode 100644
index 0000000..2d611f8
--- /dev/null
+++ b/configs/amd_versal2_virt_defconfig
@@ -0,0 +1,151 @@
+CONFIG_ARM=y
+CONFIG_COUNTER_FREQUENCY=375000
+CONFIG_POSITION_INDEPENDENT=y
+CONFIG_SYS_INIT_SP_BSS_OFFSET=1572864
+CONFIG_ARCH_VERSAL2=y
+CONFIG_TEXT_BASE=0x8000000
+CONFIG_SYS_MALLOC_F_LEN=0x100000
+CONFIG_DEFAULT_DEVICE_TREE="amd-versal2-virt"
+CONFIG_OF_LIBFDT_OVERLAY=y
+CONFIG_DM_RESET=y
+CONFIG_DEBUG_UART_BASE=0xf1920000
+CONFIG_DEBUG_UART_CLOCK=100000000
+CONFIG_CMD_FRU=y
+CONFIG_SYS_LOAD_ADDR=0x8000000
+CONFIG_DEBUG_UART=y
+CONFIG_SYS_MEMTEST_START=0x00000000
+CONFIG_SYS_MEMTEST_END=0x00001000
+CONFIG_REMAKE_ELF=y
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_SYS_BOOTM_LEN=0x6400000
+CONFIG_DISTRO_DEFAULTS=y
+CONFIG_BOOTDELAY=5
+# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
+CONFIG_USE_PREBOOT=y
+CONFIG_SYS_PBSIZE=2073
+CONFIG_BOARD_EARLY_INIT_R=y
+CONFIG_CLOCKS=y
+CONFIG_SYS_PROMPT="versal2> "
+CONFIG_CMD_BOOTMENU=y
+CONFIG_CMD_GREPENV=y
+CONFIG_CMD_NVEDIT_EFI=y
+CONFIG_CMD_MEMTEST=y
+CONFIG_SYS_ALT_MEMTEST=y
+CONFIG_CMD_SHA1SUM=y
+CONFIG_CMD_CLK=y
+CONFIG_CMD_DFU=y
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_MTD=y
+CONFIG_CMD_SF_TEST=y
+CONFIG_CMD_SPI=y
+CONFIG_CMD_UFS=y
+CONFIG_CMD_USB=y
+CONFIG_BOOTP_MAY_FAIL=y
+CONFIG_BOOTP_BOOTFILESIZE=y
+CONFIG_CMD_TFTPPUT=y
+CONFIG_CMD_CACHE=y
+CONFIG_CMD_EFIDEBUG=y
+CONFIG_CMD_TIME=y
+CONFIG_CMD_RNG=y
+CONFIG_CMD_KASLRSEED=y
+CONFIG_CMD_TIMER=y
+CONFIG_CMD_SMC=y
+CONFIG_CMD_TPM=y
+CONFIG_CMD_SCMI=y
+CONFIG_CMD_EXT4_WRITE=y
+CONFIG_CMD_SQUASHFS=y
+CONFIG_CMD_MTDPARTS=y
+CONFIG_CMD_UBI=y
+CONFIG_PARTITION_TYPE_GUID=y
+CONFIG_OF_BOARD=y
+CONFIG_DTB_RESELECT=y
+CONFIG_MULTI_DTB_FIT=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_NETCONSOLE=y
+CONFIG_IP_DEFRAG=y
+CONFIG_SYS_FAULT_ECHO_LINK_DOWN=y
+CONFIG_TFTP_BLOCKSIZE=4096
+CONFIG_CLK_CCF=y
+CONFIG_CLK_SCMI=y
+CONFIG_DFU_RAM=y
+CONFIG_ARM_FFA_TRANSPORT=y
+CONFIG_DM_I2C=y
+CONFIG_SYS_I2C_CADENCE=y
+CONFIG_I2C_MUX=y
+CONFIG_I2C_MUX_PCA954x=y
+CONFIG_DM_MAILBOX=y
+CONFIG_ZYNQMP_IPI=y
+CONFIG_MISC=y
+CONFIG_I2C_EEPROM=y
+CONFIG_SUPPORT_EMMC_BOOT=y
+CONFIG_MMC_IO_VOLTAGE=y
+CONFIG_MMC_UHS_SUPPORT=y
+CONFIG_MMC_HS400_SUPPORT=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_ZYNQ=y
+CONFIG_ZYNQ_SDHCI_MIN_FREQ=100000
+CONFIG_MTD=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_ISSI=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_MT35XU=y
+CONFIG_SPI_FLASH_SST=y
+CONFIG_SPI_FLASH_WINBOND=y
+# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
+CONFIG_SPI_FLASH_MTD=y
+CONFIG_PHY_MARVELL=y
+CONFIG_PHY_NATSEMI=y
+CONFIG_PHY_REALTEK=y
+CONFIG_PHY_TI_DP83867=y
+CONFIG_PHY_VITESSE=y
+CONFIG_PHY_FIXED=y
+CONFIG_DM_ETH_PHY=y
+CONFIG_PHY_GIGE=y
+CONFIG_XILINX_AXIEMAC=y
+CONFIG_ZYNQ_GEM=y
+CONFIG_POWER_DOMAIN=y
+CONFIG_RESET_SCMI=y
+CONFIG_SCSI=y
+CONFIG_DEBUG_UART_PL011=y
+CONFIG_DEBUG_UART_ANNOUNCE=y
+CONFIG_DEBUG_UART_SKIP_INIT=y
+CONFIG_ARM_DCC=y
+CONFIG_PL01X_SERIAL=y
+CONFIG_XILINX_UARTLITE=y
+CONFIG_SOC_DEVICE=y
+CONFIG_SOC_AMD_VERSAL2=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_CADENCE_QSPI=y
+CONFIG_CADENCE_OSPI_VERSAL=y
+CONFIG_ZYNQ_SPI=y
+CONFIG_ZYNQMP_GQSPI=y
+CONFIG_TPM2_TIS_SPI=y
+CONFIG_USB=y
+CONFIG_DM_USB_GADGET=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_DWC3=y
+CONFIG_USB_DWC3=y
+CONFIG_USB_DWC3_GENERIC=y
+CONFIG_USB_ULPI_VIEWPORT=y
+CONFIG_USB_ULPI=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_MANUFACTURER="Xilinx"
+CONFIG_USB_GADGET_VENDOR_NUM=0x03FD
+CONFIG_USB_GADGET_PRODUCT_NUM=0x0300
+CONFIG_USB_GADGET_DOWNLOAD=y
+CONFIG_USB_FUNCTION_THOR=y
+CONFIG_UFS=y
+CONFIG_CADENCE_UFS=y
+CONFIG_VIRTIO_MMIO=y
+CONFIG_VIRTIO_NET=y
+CONFIG_VIRTIO_BLK=y
+CONFIG_TPM=y
diff --git a/configs/xilinx_versal_net_virt_defconfig b/configs/xilinx_versal_net_virt_defconfig
index 4207974..377081c 100644
--- a/configs/xilinx_versal_net_virt_defconfig
+++ b/configs/xilinx_versal_net_virt_defconfig
@@ -8,6 +8,7 @@
 CONFIG_DEFAULT_DEVICE_TREE="xilinx-versal-net-virt"
 CONFIG_OF_LIBFDT_OVERLAY=y
 CONFIG_DM_RESET=y
+CONFIG_ENV_OFFSET_REDUND=0x7F00000
 CONFIG_CMD_FRU=y
 CONFIG_SYS_LOAD_ADDR=0x8000000
 CONFIG_SYS_MEMTEST_START=0x00000000
@@ -72,6 +73,7 @@
 CONFIG_TFTP_BLOCKSIZE=4096
 CONFIG_CLK_VERSAL=y
 CONFIG_DFU_RAM=y
+CONFIG_ARM_FFA_TRANSPORT=y
 CONFIG_ZYNQ_GPIO=y
 CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_CADENCE=y
@@ -80,6 +82,7 @@
 CONFIG_DM_MAILBOX=y
 CONFIG_ZYNQMP_IPI=y
 CONFIG_MISC=y
+CONFIG_NVMEM=y
 CONFIG_I2C_EEPROM=y
 CONFIG_SUPPORT_EMMC_BOOT=y
 CONFIG_MMC_IO_VOLTAGE=y
diff --git a/configs/xilinx_versal_virt_defconfig b/configs/xilinx_versal_virt_defconfig
index 06c192c..59fdd30 100644
--- a/configs/xilinx_versal_virt_defconfig
+++ b/configs/xilinx_versal_virt_defconfig
@@ -74,6 +74,7 @@
 CONFIG_DFU_TIMEOUT=y
 CONFIG_DFU_RAM=y
 CONFIG_SYS_DFU_DATA_BUF_SIZE=0x1800000
+CONFIG_ARM_FFA_TRANSPORT=y
 CONFIG_FPGA_XILINX=y
 CONFIG_FPGA_VERSALPL=y
 CONFIG_DM_I2C=y
@@ -83,6 +84,7 @@
 CONFIG_DM_MAILBOX=y
 CONFIG_ZYNQMP_IPI=y
 CONFIG_MISC=y
+CONFIG_NVMEM=y
 CONFIG_I2C_EEPROM=y
 CONFIG_SUPPORT_EMMC_BOOT=y
 CONFIG_MMC_IO_VOLTAGE=y
diff --git a/configs/xilinx_zynq_virt_defconfig b/configs/xilinx_zynq_virt_defconfig
index f30fbdf..9be904f 100644
--- a/configs/xilinx_zynq_virt_defconfig
+++ b/configs/xilinx_zynq_virt_defconfig
@@ -107,6 +107,7 @@
 CONFIG_LED=y
 CONFIG_LED_GPIO=y
 CONFIG_MISC=y
+CONFIG_NVMEM=y
 CONFIG_I2C_EEPROM=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_ZYNQ=y
diff --git a/configs/xilinx_zynqmp_kria_defconfig b/configs/xilinx_zynqmp_kria_defconfig
index 8c60325..3d1cfe8 100644
--- a/configs/xilinx_zynqmp_kria_defconfig
+++ b/configs/xilinx_zynqmp_kria_defconfig
@@ -134,6 +134,7 @@
 CONFIG_FASTBOOT_FLASH=y
 CONFIG_FASTBOOT_FLASH_MMC_DEV=0
 CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
+CONFIG_ARM_FFA_TRANSPORT=y
 CONFIG_FPGA_XILINX=y
 CONFIG_FPGA_ZYNQMPPL=y
 CONFIG_GPIO_HOG=y
diff --git a/configs/xilinx_zynqmp_virt_defconfig b/configs/xilinx_zynqmp_virt_defconfig
index 8918797..a9e6503 100644
--- a/configs/xilinx_zynqmp_virt_defconfig
+++ b/configs/xilinx_zynqmp_virt_defconfig
@@ -134,6 +134,7 @@
 CONFIG_FASTBOOT_FLASH=y
 CONFIG_FASTBOOT_FLASH_MMC_DEV=0
 CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
+CONFIG_ARM_FFA_TRANSPORT=y
 CONFIG_FPGA_XILINX=y
 CONFIG_FPGA_ZYNQMPPL=y
 CONFIG_GPIO_HOG=y
@@ -147,6 +148,7 @@
 CONFIG_LED=y
 CONFIG_LED_GPIO=y
 CONFIG_MISC=y
+CONFIG_NVMEM=y
 CONFIG_I2C_EEPROM=y
 CONFIG_SUPPORT_EMMC_BOOT=y
 CONFIG_MMC_IO_VOLTAGE=y
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index b050585..fcca694 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -487,7 +487,7 @@
 config ZYNQ_GPIO
 	bool "Zynq GPIO driver"
 	depends on DM_GPIO
-	default y if ARCH_ZYNQ || ARCH_ZYNQMP || ARCH_VERSAL
+	default y if ARCH_ZYNQ || ARCH_ZYNQMP || ARCH_VERSAL || ARCH_VERSAL2
 	help
 	  Supports GPIO access on Zynq SoC.
 
@@ -639,7 +639,7 @@
 
 config ZYNQMP_GPIO_MODEPIN
 	bool "ZynqMP gpio modepin"
-	depends on DM_GPIO
+	depends on DM_GPIO && ZYNQMP_FIRMWARE
 	help
 	  This config enables the ZynqMP gpio modepin driver. ZynqMP modepin
 	  driver will set and get the status of PS_MODE pins. These modepins
diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index 47f24e0..67d5ac1 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -54,7 +54,7 @@
 
 config ZYNQMP_IPI
 	bool "Xilinx ZynqMP IPI controller support"
-	depends on DM_MAILBOX && (ARCH_ZYNQMP || ARCH_VERSAL || ARCH_VERSAL_NET)
+	depends on DM_MAILBOX && (ARCH_ZYNQMP || ARCH_VERSAL || ARCH_VERSAL_NET || ARCH_VERSAL2)
 	help
 	  This enables support for the Xilinx ZynqMP Inter Processor Interrupt
 	  communication controller.
diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c
index 898be5a..28d2b45 100644
--- a/drivers/mmc/zynq_sdhci.c
+++ b/drivers/mmc/zynq_sdhci.c
@@ -122,7 +122,8 @@
 	return 1;
 }
 
-#if defined(CONFIG_ARCH_ZYNQMP) || defined(CONFIG_ARCH_VERSAL) || defined(CONFIG_ARCH_VERSAL_NET)
+#if defined(CONFIG_ARCH_ZYNQMP) || defined(CONFIG_ARCH_VERSAL) || \
+    defined(CONFIG_ARCH_VERSAL_NET) || defined(CONFIG_ARCH_VERSAL2)
 /* Default settings for ZynqMP Clock Phases */
 static const u32 zynqmp_iclk_phases[] = {0, 63, 63, 0, 63,  0,
 					 0, 183, 54,  0, 0};
@@ -156,7 +157,7 @@
 	[MMC_HS_400] = MMC_TIMING_MMC_HS400,
 };
 
-#if defined(CONFIG_ARCH_VERSAL_NET)
+#if defined(CONFIG_ARCH_VERSAL_NET) || defined(CONFIG_ARCH_VERSAL2)
 /**
  * arasan_phy_set_delaychain - Set eMMC delay chain based Input/Output clock
  *
@@ -865,7 +866,9 @@
 		ret = sdhci_zynqmp_sdcardclk_set_phase(host, oclk_phase);
 		if (ret)
 			return ret;
-	} else if (IS_ENABLED(CONFIG_ARCH_VERSAL) &&
+	} else if ((IS_ENABLED(CONFIG_ARCH_VERSAL) ||
+		    IS_ENABLED(CONFIG_ARCH_VERSAL_NET) ||
+		    IS_ENABLED(CONFIG_ARCH_VERSAL2)) &&
 		   device_is_compatible(dev, "xlnx,versal-8.9a")) {
 		ret = sdhci_versal_sampleclk_set_phase(host, iclk_phase);
 		if (ret)
@@ -874,7 +877,8 @@
 		ret = sdhci_versal_sdcardclk_set_phase(host, oclk_phase);
 		if (ret)
 			return ret;
-	} else if (IS_ENABLED(CONFIG_ARCH_VERSAL_NET) &&
+	} else if ((IS_ENABLED(CONFIG_ARCH_VERSAL_NET) ||
+		    IS_ENABLED(CONFIG_ARCH_VERSAL2)) &&
 		   device_is_compatible(dev, "xlnx,versal-net-emmc")) {
 		if (mmc->clock >= MIN_PHY_CLK_HZ)
 			if (iclk_phase == VERSAL_NET_EMMC_ICLK_PHASE_DDR52_DLY_CHAIN)
@@ -941,7 +945,9 @@
 		}
 	}
 
-	if (IS_ENABLED(CONFIG_ARCH_VERSAL) &&
+	if ((IS_ENABLED(CONFIG_ARCH_VERSAL) ||
+	     IS_ENABLED(CONFIG_ARCH_VERSAL_NET) ||
+	     IS_ENABLED(CONFIG_ARCH_VERSAL2)) &&
 	    device_is_compatible(dev, "xlnx,versal-8.9a")) {
 		for (i = 0; i <= MMC_TIMING_MMC_HS400; i++) {
 			clk_data->clk_phase_in[i] = versal_iclk_phases[i];
@@ -949,7 +955,8 @@
 		}
 	}
 
-	if (IS_ENABLED(CONFIG_ARCH_VERSAL_NET) &&
+	if ((IS_ENABLED(CONFIG_ARCH_VERSAL_NET) ||
+	     IS_ENABLED(CONFIG_ARCH_VERSAL2)) &&
 	    device_is_compatible(dev, "xlnx,versal-net-emmc")) {
 		for (i = 0; i <= MMC_TIMING_MMC_HS400; i++) {
 			clk_data->clk_phase_in[i] = versal_net_emmc_iclk_phases[i];
@@ -985,7 +992,7 @@
 	.platform_execute_tuning	= &arasan_sdhci_execute_tuning,
 	.set_delay = &arasan_sdhci_set_tapdelay,
 	.set_control_reg = &sdhci_set_control_reg,
-#if defined(CONFIG_ARCH_VERSAL_NET)
+#if defined(CONFIG_ARCH_VERSAL_NET) || defined(CONFIG_ARCH_VERSAL2)
 	.config_dll = &arasan_sdhci_config_dll,
 #endif
 };
@@ -1193,7 +1200,8 @@
 
 	priv->host->name = dev->name;
 
-#if defined(CONFIG_ARCH_ZYNQMP) || defined(CONFIG_ARCH_VERSAL) || defined(CONFIG_ARCH_VERSAL_NET)
+#if defined(CONFIG_ARCH_ZYNQMP) || defined(CONFIG_ARCH_VERSAL) || defined(CONFIG_ARCH_VERSAL_NET) || \
+    defined(CONFIG_ARCH_VERSAL2)
 	priv->host->ops = &arasan_ops;
 	arasan_dt_parse_clk_phases(dev);
 #endif
diff --git a/drivers/mtd/spi/spi-nor-ids.c b/drivers/mtd/spi/spi-nor-ids.c
index 684206e..2206d73 100644
--- a/drivers/mtd/spi/spi-nor-ids.c
+++ b/drivers/mtd/spi/spi-nor-ids.c
@@ -274,7 +274,7 @@
 	{ INFO("mx66l2g45g",  0xc2201c, 0, 64 * 1024, 4096, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
 	{ INFO("mx25l1633e", 0xc22415, 0, 64 * 1024,   32, SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES | SECT_4K) },
 	{ INFO("mx25r6435f", 0xc22817, 0, 64 * 1024,   128,  SECT_4K) },
-	{ INFO("mx66uw2g345gx0", 0xc2943c, 0, 64 * 1024, 4096, SECT_4K | SPI_NOR_OCTAL_DTR_READ | SPI_NOR_4B_OPCODES) },
+	{ INFO("mx66uw2g345gx0", 0xc2943c, 0, 64 * 1024, 4096, SECT_4K | SPI_NOR_OCTAL_DTR_READ | SPI_NOR_4B_OPCODES | SPI_NOR_OCTAL_READ) },
 	{ INFO("mx66lm1g45g",    0xc2853b, 0, 64 * 1024, 2048, SECT_4K | SPI_NOR_OCTAL_DTR_READ | SPI_NOR_4B_OPCODES) },
 	{ INFO("mx25lm51245g",   0xc2853a, 0, 64 * 1024, 1024, SECT_4K | SPI_NOR_OCTAL_DTR_READ | SPI_NOR_4B_OPCODES) },
 	{ INFO("mx25lw51245g",   0xc2863a, 0, 64 * 1024, 1024, SECT_4K | SPI_NOR_OCTAL_DTR_READ | SPI_NOR_4B_OPCODES) },
diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
index 03433bc0..cee506f 100644
--- a/drivers/soc/Kconfig
+++ b/drivers/soc/Kconfig
@@ -9,6 +9,14 @@
 	  need different parameters or quirks enabled depending on the
 	  specific device variant in use.
 
+config SOC_AMD_VERSAL2
+	bool "Enable SoC Device ID driver for AMD Versal Gen 2"
+	depends on SOC_DEVICE && ARCH_VERSAL2
+	help
+	  Enable this option to select SoC device id driver for AMD Versal Gen 2.
+	  This allows other drivers to verify the SoC familiy & revision using
+	  matching SoC attributes.
+
 config SOC_DEVICE_TI_K3
 	depends on SOC_DEVICE && ARCH_K3
 	bool "Enable SoC Device ID driver for TI K3 SoCs"
diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
index 610bf81..5ec89a0 100644
--- a/drivers/soc/Makefile
+++ b/drivers/soc/Makefile
@@ -2,6 +2,7 @@
 #
 # Makefile for the U-Boot SOC specific device drivers.
 
+obj-$(CONFIG_SOC_AMD_VERSAL2) += soc_amd_versal2.o
 obj-$(CONFIG_SOC_SAMSUNG) += samsung/
 obj-$(CONFIG_SOC_TI) += ti/
 obj-$(CONFIG_SOC_DEVICE) += soc-uclass.o
diff --git a/drivers/soc/soc_amd_versal2.c b/drivers/soc/soc_amd_versal2.c
new file mode 100644
index 0000000..66bcb22
--- /dev/null
+++ b/drivers/soc/soc_amd_versal2.c
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * AMD Versal Gen 2 SOC driver
+ *
+ * Copyright (C) 2022 - 2024, Advanced Micro Devices, Inc.
+ */
+
+#include <dm.h>
+#include <soc.h>
+#include <zynqmp_firmware.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+
+#include <linux/bitfield.h>
+
+/*
+ * v1 -> 0x10 - ES1
+ * v2 -> 0x20 - Production
+ */
+static const char versal2_family[] = "Versal Gen 2";
+
+struct soc_amd_versal2_priv {
+	const char *family;
+	char revision;
+};
+
+static int soc_amd_versal2_get_family(struct udevice *dev, char *buf, int size)
+{
+	struct soc_amd_versal2_priv *priv = dev_get_priv(dev);
+
+	return snprintf(buf, size, "%s", priv->family);
+}
+
+static int soc_amd_versal2_get_revision(struct udevice *dev, char *buf, int size)
+{
+	struct soc_amd_versal2_priv *priv = dev_get_priv(dev);
+
+	return snprintf(buf, size, "v%d", priv->revision);
+}
+
+static const struct soc_ops soc_amd_versal2_ops = {
+	.get_family = soc_amd_versal2_get_family,
+	.get_revision = soc_amd_versal2_get_revision,
+};
+
+static int soc_amd_versal2_probe(struct udevice *dev)
+{
+	struct soc_amd_versal2_priv *priv = dev_get_priv(dev);
+	u32 ret_payload[PAYLOAD_ARG_CNT];
+	int ret;
+
+	priv->family = versal2_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(PMC_TAP_VERSION);
+		if (!ret_payload[2])
+			return -EINVAL;
+	}
+
+	priv->revision = FIELD_GET(PS_VERSION_MASK, ret_payload[2]);
+
+	return 0;
+}
+
+U_BOOT_DRIVER(soc_amd_versal2) = {
+	.name		= "soc_amd_versal2",
+	.id		= UCLASS_SOC,
+	.ops		= &soc_amd_versal2_ops,
+	.probe		= soc_amd_versal2_probe,
+	.priv_auto	= sizeof(struct soc_amd_versal2_priv),
+	.flags		= DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 35030ab..cd785ae 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -156,7 +156,7 @@
 
 config CADENCE_OSPI_VERSAL
 	bool "Configure Versal OSPI"
-	depends on (ARCH_VERSAL || ARCH_VERSAL_NET) && CADENCE_QSPI
+	depends on (ARCH_VERSAL || ARCH_VERSAL_NET || ARCH_VERSAL2) && CADENCE_QSPI
 	imply DM_GPIO
 	help
 	  This option is used to enable Versal OSPI DMA operations which
diff --git a/drivers/spi/cadence_qspi.c b/drivers/spi/cadence_qspi.c
index 75e5223..9c466f8 100644
--- a/drivers/spi/cadence_qspi.c
+++ b/drivers/spi/cadence_qspi.c
@@ -253,7 +253,8 @@
 
 	/* Versal and Versal-NET use spi calibration to set read delay */
 	if (CONFIG_IS_ENABLED(ARCH_VERSAL) ||
-	    CONFIG_IS_ENABLED(ARCH_VERSAL_NET))
+	    CONFIG_IS_ENABLED(ARCH_VERSAL_NET) ||
+	    CONFIG_IS_ENABLED(ARCH_VERSAL2))
 		if (priv->read_delay >= 0)
 			priv->read_delay = -1;
 
diff --git a/drivers/spi/zynqmp_gqspi.c b/drivers/spi/zynqmp_gqspi.c
index 61349a4..ae795e5 100644
--- a/drivers/spi/zynqmp_gqspi.c
+++ b/drivers/spi/zynqmp_gqspi.c
@@ -106,7 +106,8 @@
 #define TAP_DLY_BYPASS_LQSPI_RX_SHIFT	2
 #define GQSPI_DATA_DLY_ADJ_OFST		0x000001F8
 #define IOU_TAPDLY_BYPASS_OFST !(IS_ENABLED(CONFIG_ARCH_VERSAL) || \
-				 IS_ENABLED(CONFIG_ARCH_VERSAL_NET)) ? \
+				 IS_ENABLED(CONFIG_ARCH_VERSAL_NET) || \
+				 IS_ENABLED(CONFIG_ARCH_VERSAL2)) ? \
 				0xFF180390 : 0xF103003C
 #define GQSPI_LPBK_DLY_ADJ_LPBK_MASK	0x00000020
 #define GQSPI_FREQ_37_5MHZ		37500000
@@ -316,7 +317,8 @@
 		  __func__, clk_rate, baudrateval, reqhz);
 
 	if (!(IS_ENABLED(CONFIG_ARCH_VERSAL) ||
-	      IS_ENABLED(CONFIG_ARCH_VERSAL_NET))) {
+	      IS_ENABLED(CONFIG_ARCH_VERSAL_NET) ||
+	      IS_ENABLED(CONFIG_ARCH_VERSAL2))) {
 		if (reqhz <= GQSPI_FREQ_40MHZ) {
 			tapdlybypass = TAP_DLY_BYPASS_LQSPI_RX_VALUE <<
 					TAP_DLY_BYPASS_LQSPI_RX_SHIFT;
diff --git a/env/Kconfig b/env/Kconfig
index 9641abe..451bab4 100644
--- a/env/Kconfig
+++ b/env/Kconfig
@@ -570,7 +570,7 @@
 	default 0xF0000 if ARCH_SUNXI
 	default 0xE0000 if ARCH_ZYNQ
 	default 0x1E00000 if ARCH_ZYNQMP
-	default 0x7F40000 if ARCH_VERSAL || ARCH_VERSAL_NET
+	default 0x7F40000 if ARCH_VERSAL || ARCH_VERSAL_NET || ARCH_VERSAL2
 	default 0x0 if ARC
 	default 0x140000 if ARCH_AT91
 	default 0x260000 if ARCH_OMAP2PLUS
@@ -605,7 +605,7 @@
 	default 0x10000 if ARCH_SUNXI
 	default 0x8000 if ARCH_ROCKCHIP && ENV_IS_IN_MMC
 	default 0x2000 if ARCH_ROCKCHIP && ENV_IS_IN_SPI_FLASH
-	default 0x8000 if ARCH_ZYNQMP || ARCH_VERSAL || ARCH_VERSAL_NET
+	default 0x8000 if ARCH_ZYNQMP || ARCH_VERSAL || ARCH_VERSAL_NET || ARCH_VERSAL2
 	default 0x4000 if ARC
 	default 0x1f000
 	help
@@ -615,7 +615,7 @@
 	hex "Environment Sector-Size"
 	depends on ENV_IS_IN_FLASH || ENV_IS_IN_SPI_FLASH
 	default 0x2000 if ARCH_ROCKCHIP
-	default 0x40000 if ARCH_ZYNQMP || ARCH_VERSAL || ARCH_VERSAL_NET
+	default 0x40000 if ARCH_ZYNQMP || ARCH_VERSAL || ARCH_VERSAL_NET || ARCH_VERSAL2
 	default 0x20000 if ARCH_ZYNQ || ARCH_OMAP2PLUS || ARCH_AT91
 	default 0x20000 if MICROBLAZE && ENV_IS_IN_SPI_FLASH
 	default 0x10000 if ARCH_SUNXI && ENV_IS_IN_SPI_FLASH
diff --git a/include/configs/amd_versal2.h b/include/configs/amd_versal2.h
new file mode 100644
index 0000000..6a40bbd
--- /dev/null
+++ b/include/configs/amd_versal2.h
@@ -0,0 +1,143 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Configuration for AMD Versal Gen 2
+ * Copyright (C) 2016 - 2022, Xilinx, Inc.
+ * Copyright (C) 2022 - 2024, Advanced Micro Devices, Inc.
+ *
+ * Michal Simek <michal.simek@amd.com>
+ *
+ * Based on Configuration for Xilinx ZynqMP
+ */
+
+#ifndef __AMD_VERSAL2_H
+#define __AMD_VERSAL2_H
+
+/* FIXME this is causing issue at least on IPP */
+/* #define CONFIG_ARMV8_SWITCH_TO_EL1 */
+
+/* Generic Interrupt Controller Definitions */
+#define GICD_BASE	0xF9000000
+#define GICR_BASE	0xF9060000
+
+/* Serial setup */
+#define CFG_SYS_BAUDRATE_TABLE \
+	{ 4800, 9600, 19200, 38400, 57600, 115200 }
+
+#if defined(CONFIG_CMD_DFU)
+#define DFU_DEFAULT_POLL_TIMEOUT	300
+#define DFU_ALT_INFO_RAM \
+	"dfu_ram_info=" \
+	"setenv dfu_alt_info " \
+	"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"
+
+#define DFU_ALT_INFO  \
+		DFU_ALT_INFO_RAM
+#endif
+
+#if !defined(DFU_ALT_INFO)
+# define DFU_ALT_INFO
+#endif
+
+/* Ethernet driver */
+#if defined(CONFIG_ZYNQ_GEM)
+# define PHY_ANEG_TIMEOUT	20000
+#endif
+
+#define ENV_MEM_LAYOUT_SETTINGS \
+	"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" \
+	"kernel_comp_addr_r=0x30000000\0" \
+	"kernel_comp_size=0x3C00000\0" \
+	"ramdisk_addr_r=0x02100000\0" \
+	"script_size_f=0x80000\0"
+
+#if defined(CONFIG_DISTRO_DEFAULTS)
+
+#if defined(CONFIG_MMC_SDHCI_ZYNQ)
+# define BOOT_TARGET_DEVICES_MMC(func)	func(MMC, mmc, 0) func(MMC, mmc, 1)
+#else
+# define BOOT_TARGET_DEVICES_MMC(func)
+#endif
+
+#if defined(CONFIG_CMD_PXE) && defined(CONFIG_CMD_DHCP)
+# define BOOT_TARGET_DEVICES_PXE(func)	func(PXE, pxe, na)
+#else
+# define BOOT_TARGET_DEVICES_PXE(func)
+#endif
+
+#if defined(CONFIG_CMD_DHCP)
+# define BOOT_TARGET_DEVICES_DHCP(func)	func(DHCP, dhcp, na)
+#else
+# define BOOT_TARGET_DEVICES_DHCP(func)
+#endif
+
+#if defined(CONFIG_ZYNQMP_GQSPI) || defined(CONFIG_CADENCE_OSPI_VERSAL)
+# define BOOT_TARGET_DEVICES_XSPI(func)	func(XSPI, xspi, 0) func(XSPI, xspi, 1)
+# define BOOTENV_DEV_SHARED_XSPI \
+	"xspi_boot=sf probe $devnum_xspi:0 0 0 && " \
+	"sf read $scriptaddr $script_offset_f $script_size_f && " \
+	"echo XSPI: Trying to boot script at ${scriptaddr} && " \
+	"source ${scriptaddr}; echo XSPI: SCRIPT FAILED: continuing...;\0"
+#else
+# define BOOT_TARGET_DEVICES_XSPI(func)
+# define BOOTENV_DEV_SHARED_XSPI
+#endif
+
+#define BOOTENV_DEV_XSPI(devtypeu, devtypel, instance) \
+	"bootcmd_" #devtypel #instance "=" \
+	"devnum_xspi=" #instance "; run " #devtypel "_boot\0" \
+
+#define BOOTENV_DEV_NAME_XSPI(devtypeu, devtypel, instance) \
+	""
+
+#define BOOT_TARGET_DEVICES_JTAG(func)	func(JTAG, jtag, na)
+
+#define BOOTENV_DEV_JTAG(devtypeu, devtypel, instance) \
+	"bootcmd_jtag=echo JTAG: Trying to boot script at ${scriptaddr} && " \
+		"source ${scriptaddr}; echo JTAG: SCRIPT FAILED: continuing...;\0"
+
+#define BOOTENV_DEV_NAME_JTAG(devtypeu, devtypel, instance) \
+	"jtag "
+
+#define BOOT_TARGET_DEVICES_DFU_USB(func)  func(DFU_USB, dfu_usb, 0)
+
+#define BOOTENV_DEV_DFU_USB(devtypeu, devtypel, instance) \
+	"bootcmd_dfu_usb=setenv dfu_alt_info boot.scr ram $scriptaddr " \
+	"$script_size_f; dfu 0 ram 0 && " \
+	"echo DFU: Trying to boot script at ${scriptaddr} && " \
+	"source ${scriptaddr}; " \
+	"echo DFU: SCRIPT FAILED: continuing...;\0"
+
+#define BOOTENV_DEV_NAME_DFU_USB(devtypeu, devtypel, instance) \
+	""
+
+#define BOOT_TARGET_DEVICES(func) \
+	BOOT_TARGET_DEVICES_JTAG(func) \
+	BOOT_TARGET_DEVICES_MMC(func) \
+	BOOT_TARGET_DEVICES_XSPI(func) \
+	BOOT_TARGET_DEVICES_DFU_USB(func) \
+	BOOT_TARGET_DEVICES_PXE(func) \
+	BOOT_TARGET_DEVICES_DHCP(func)
+
+#include <config_distro_bootcmd.h>
+
+#else /* CONFIG_DISTRO_DEFAULTS */
+# define BOOTENV
+#endif /* CONFIG_DISTRO_DEFAULTS */
+
+/* Initial environment variables */
+#ifndef CFG_EXTRA_ENV_SETTINGS
+#define CFG_EXTRA_ENV_SETTINGS \
+	ENV_MEM_LAYOUT_SETTINGS \
+	BOOTENV \
+	BOOTENV_DEV_SHARED_XSPI \
+	DFU_ALT_INFO
+#endif
+
+#endif /* __AMD_VERSAL2_H */
diff --git a/include/configs/xilinx_zynqmp.h b/include/configs/xilinx_zynqmp.h
index f76b3c6..de0db7b 100644
--- a/include/configs/xilinx_zynqmp.h
+++ b/include/configs/xilinx_zynqmp.h
@@ -42,8 +42,6 @@
 # define PARTS_DEFAULT
 #endif
 
-/* Console I/O Buffer Size */
-
 /* Ethernet driver */
 
 #define ENV_MEM_LAYOUT_SETTINGS \
@@ -201,10 +199,6 @@
 # define CFG_SYS_SPI_ARGS_SIZE	0xa0000
 #endif
 
-/* u-boot is like dtb */
-
-/* ATF is my kernel image */
-
 #ifdef CONFIG_SPL_SYS_MALLOC_SIMPLE
 # error "Disable CONFIG_SPL_SYS_MALLOC_SIMPLE. Full malloc needs to be used"
 #endif
diff --git a/include/dt-bindings/power/xlnx-zynqmp-power.h b/include/dt-bindings/power/xlnx-zynqmp-power.h
index e7eb096..618024c 100644
--- a/include/dt-bindings/power/xlnx-zynqmp-power.h
+++ b/include/dt-bindings/power/xlnx-zynqmp-power.h
@@ -6,16 +6,12 @@
 #ifndef _DT_BINDINGS_ZYNQMP_POWER_H
 #define _DT_BINDINGS_ZYNQMP_POWER_H
 
-#define		PD_RPU_0	6
-#define		PD_RPU_1	7
-#define		PD_OCM_BANK_0	11
-#define		PD_OCM_BANK_1	12
-#define		PD_OCM_BANK_2	13
-#define		PD_OCM_BANK_3	14
-#define		PD_TCM_BANK_0	15
-#define		PD_TCM_BANK_1	16
-#define		PD_TCM_BANK_2	17
-#define		PD_TCM_BANK_3	18
+#define		PD_RPU_0	7
+#define		PD_RPU_1	8
+#define		PD_R5_0_ATCM	15
+#define		PD_R5_0_BTCM	16
+#define		PD_R5_1_ATCM	17
+#define		PD_R5_1_BTCM	18
 #define		PD_USB_0	22
 #define		PD_USB_1	23
 #define		PD_TTC_0	24
@@ -45,6 +41,5 @@
 #define		PD_CAN_1	48
 #define		PD_GPU		58
 #define		PD_PCIE		59
-#define		PD_PL		69
 
 #endif
diff --git a/include/spl.h b/include/spl.h
index 043875f..5dfdf77 100644
--- a/include/spl.h
+++ b/include/spl.h
@@ -817,6 +817,14 @@
 int spl_init(void);
 
 /*
+ * spl_soc_init() - Do architecture-specific init in SPL
+ *
+ * If SPL_SOC_INIT is enabled, this is called from board_init_r() before
+ * jumping to the next phase.
+ */
+void spl_soc_init(void);
+
+/*
  * spl_board_init() - Do board-specific init in SPL
  *
  * If xPL_BOARD_INIT is enabled, this is called from board_init_r() before