[PATCH v1 03/17] arch: arm: mach-socfpga: add new platform agilex5 mach-socfpga enablement

Jit Loon Lim jit.loon.lim at intel.com
Wed Jun 21 05:15:56 CEST 2023


This is for new platform enablement for agilex5.
Add platform related files to enable new product.

Signed-off-by: Jit Loon Lim <jit.loon.lim at intel.com>
---
 arch/arm/mach-socfpga/Kconfig                 |  37 +++
 arch/arm/mach-socfpga/Makefile                |  69 ++++-
 arch/arm/mach-socfpga/board.c                 |  65 ++++-
 arch/arm/mach-socfpga/clock_manager_agilex5.c |  82 ++++++
 arch/arm/mach-socfpga/firewall.c              | 107 -------
 arch/arm/mach-socfpga/lowlevel_init_agilex5.S |  61 ++++
 arch/arm/mach-socfpga/lowlevel_init_soc64.S   | 167 ++++++++++-
 arch/arm/mach-socfpga/mailbox_s10.c           |  21 ++
 arch/arm/mach-socfpga/misc.c                  |  19 +-
 arch/arm/mach-socfpga/misc_soc64.c            |  33 ++-
 arch/arm/mach-socfpga/mmu-arm64_s10.c         |  43 ++-
 arch/arm/mach-socfpga/reset_manager_s10.c     | 271 +++++++++++++++---
 arch/arm/mach-socfpga/secure_reg_helper.c     |   4 +-
 arch/arm/mach-socfpga/smmu_agilex5.c          |  34 +++
 arch/arm/mach-socfpga/smmu_s10.c              | 126 ++++++++
 arch/arm/mach-socfpga/spl_agilex5.c           | 180 ++++++++++++
 arch/arm/mach-socfpga/spl_soc64.c             | 188 +++++++++++-
 arch/arm/mach-socfpga/u-boot-spl-soc64.lds    |  93 ++++++
 arch/arm/mach-socfpga/wrap_handoff_soc64.c    |   7 +-
 19 files changed, 1429 insertions(+), 178 deletions(-)
 create mode 100644 arch/arm/mach-socfpga/clock_manager_agilex5.c
 delete mode 100644 arch/arm/mach-socfpga/firewall.c
 create mode 100644 arch/arm/mach-socfpga/lowlevel_init_agilex5.S
 create mode 100644 arch/arm/mach-socfpga/smmu_agilex5.c
 create mode 100644 arch/arm/mach-socfpga/smmu_s10.c
 create mode 100644 arch/arm/mach-socfpga/spl_agilex5.c
 create mode 100644 arch/arm/mach-socfpga/u-boot-spl-soc64.lds

diff --git a/arch/arm/mach-socfpga/Kconfig b/arch/arm/mach-socfpga/Kconfig
index 503c82d388..562c3796ec 100644
--- a/arch/arm/mach-socfpga/Kconfig
+++ b/arch/arm/mach-socfpga/Kconfig
@@ -44,6 +44,15 @@ config TEXT_BASE
 	default 0x01000040 if TARGET_SOCFPGA_ARRIA10
 	default 0x01000040 if TARGET_SOCFPGA_GEN5
 
+config ARMV8_PSCI_NR_CPUS
+	default 4 if TARGET_SOCFPGA_SOC64
+
+config ARMV8_SECURE_BASE
+	default 0x00001000 if TARGET_SOCFPGA_SOC64 && ARMV8_PSCI
+
+config SYS_HAS_ARMV8_SECURE_BASE
+	default y if TARGET_SOCFPGA_SOC64 && ARMV8_PSCI
+
 config TARGET_SOCFPGA_AGILEX
 	bool
 	select ARMV8_MULTIENTRY
@@ -51,10 +60,31 @@ config TARGET_SOCFPGA_AGILEX
 	select BINMAN if SPL_ATF
 	select CLK
 	select FPGA_INTEL_SDM_MAILBOX
+	select GICV2
+	select NCORE_CACHE
+	select SPL_CLK if SPL
+	select TARGET_SOCFPGA_SOC64
+
+config TARGET_SOCFPGA_AGILEX5
+	bool
+	select BINMAN if SPL_ATF
+	select CLK
+	select FPGA_INTEL_SDM_MAILBOX
+	select GICV3
 	select NCORE_CACHE
 	select SPL_CLK if SPL
 	select TARGET_SOCFPGA_SOC64
 
+config TARGET_SOCFPGA_AGILEX5_EMU
+	bool "Enable build that bootable only on Agilex5 Emulator"
+	help
+	 This is to use for Agilex5 Emulator.
+
+config TARGET_SOCFPGA_AGILEX5_SIMICS
+	bool "Enable build that bootable only on Agilex5 Simics platform"
+	help
+	 This is to use for Agilex5 Simics.
+
 config TARGET_SOCFPGA_ARRIA5
 	bool
 	select TARGET_SOCFPGA_GEN5
@@ -126,6 +156,10 @@ config TARGET_SOCFPGA_AGILEX_SOCDK
 	bool "Intel SOCFPGA SoCDK (Agilex)"
 	select TARGET_SOCFPGA_AGILEX
 
+config TARGET_SOCFPGA_AGILEX5_SOCDK
+	bool "Intel SOCFPGA SoCDK (Agilex5)"
+	select TARGET_SOCFPGA_AGILEX5
+
 config TARGET_SOCFPGA_ARIES_MCVEVK
 	bool "Aries MCVEVK (Cyclone V)"
 	select TARGET_SOCFPGA_CYCLONE5
@@ -199,6 +233,7 @@ config TARGET_SOCFPGA_TERASIC_SOCKIT
 endchoice
 
 config SYS_BOARD
+	default "agilex5-socdk" if TARGET_SOCFPGA_AGILEX5_SOCDK
 	default "agilex-socdk" if TARGET_SOCFPGA_AGILEX_SOCDK
 	default "arria5-socdk" if TARGET_SOCFPGA_ARRIA5_SOCDK
 	default "arria10-socdk" if TARGET_SOCFPGA_ARRIA10_SOCDK
@@ -220,6 +255,7 @@ config SYS_BOARD
 	default "vining_fpga" if TARGET_SOCFPGA_SOFTING_VINING_FPGA
 
 config SYS_VENDOR
+	default "intel" if TARGET_SOCFPGA_AGILEX5_SOCDK
 	default "intel" if TARGET_SOCFPGA_AGILEX_SOCDK
 	default "intel" if TARGET_SOCFPGA_N5X_SOCDK
 	default "altera" if TARGET_SOCFPGA_ARRIA5_SOCDK
@@ -242,6 +278,7 @@ config SYS_SOC
 	default "socfpga"
 
 config SYS_CONFIG_NAME
+	default "socfpga_agilex5_socdk" if TARGET_SOCFPGA_AGILEX5_SOCDK
 	default "socfpga_agilex_socdk" if TARGET_SOCFPGA_AGILEX_SOCDK
 	default "socfpga_arria5_secu1" if TARGET_SOCFPGA_ARRIA5_SECU1
 	default "socfpga_arria5_socdk" if TARGET_SOCFPGA_ARRIA5_SOCDK
diff --git a/arch/arm/mach-socfpga/Makefile b/arch/arm/mach-socfpga/Makefile
index ec38b64dd4..771e7ce77d 100644
--- a/arch/arm/mach-socfpga/Makefile
+++ b/arch/arm/mach-socfpga/Makefile
@@ -35,10 +35,22 @@ obj-y	+= mailbox_s10.o
 obj-y	+= misc_soc64.o
 obj-y	+= mmu-arm64_s10.o
 obj-y	+= reset_manager_s10.o
+obj-y	+= smmu_s10.o
 obj-y	+= system_manager_soc64.o
 obj-y	+= timer_s10.o
 obj-y	+= wrap_handoff_soc64.o
 obj-y	+= wrap_pll_config_soc64.o
+ifndef CONFIG_SPL_BUILD
+obj-y   += rsu.o
+obj-y   += rsu_ll_qspi.o
+obj-y   += rsu_misc.o
+obj-y	+= rsu_s10.o
+obj-$(CONFIG_ARMV8_PSCI) += psci.o
+obj-$(CONFIG_ARMV8_PSCI) += smc_ecc_dbe_s10.o
+obj-$(CONFIG_ARMV8_PSCI) += smc_fpga_reconfig_s10.o
+obj-$(CONFIG_ARMV8_PSCI) += smc_registers_s10.o
+obj-$(CONFIG_ARMV8_PSCI) += smc_rsu_s10.o
+endif
 endif
 
 ifdef CONFIG_TARGET_SOCFPGA_AGILEX
@@ -49,11 +61,46 @@ obj-y	+= misc_soc64.o
 obj-y	+= mmu-arm64_s10.o
 obj-y	+= reset_manager_s10.o
 obj-$(CONFIG_SOCFPGA_SECURE_VAB_AUTH)	+= secure_vab.o
+obj-y	+= smmu_s10.o
 obj-y	+= system_manager_soc64.o
 obj-y	+= timer_s10.o
 obj-$(CONFIG_SOCFPGA_SECURE_VAB_AUTH)	+= vab.o
 obj-y	+= wrap_handoff_soc64.o
 obj-y	+= wrap_pll_config_soc64.o
+ifndef CONFIG_SPL_BUILD
+obj-y   += rsu.o
+obj-y   += rsu_ll_qspi.o
+obj-y   += rsu_misc.o
+obj-y	+= rsu_s10.o
+obj-$(CONFIG_ARMV8_PSCI) += psci.o
+obj-$(CONFIG_ARMV8_PSCI) += smc_ecc_dbe_s10.o
+obj-$(CONFIG_ARMV8_PSCI) += smc_fpga_reconfig_s10.o
+obj-$(CONFIG_ARMV8_PSCI) += smc_registers_s10.o
+obj-$(CONFIG_ARMV8_PSCI) += smc_rsu_s10.o
+endif
+endif
+
+ifdef CONFIG_TARGET_SOCFPGA_AGILEX5
+obj-y	+= clock_manager_agilex5.o
+obj-y	+= lowlevel_init_agilex5.o
+obj-y	+= mailbox_s10.o
+obj-y	+= misc_soc64.o
+obj-y	+= mmu-arm64_s10.o
+obj-y	+= reset_manager_s10.o
+obj-$(CONFIG_SOCFPGA_SECURE_VAB_AUTH)	+= secure_vab.o
+obj-y	+= smmu_agilex5.o
+obj-y	+= system_manager_soc64.o
+obj-y	+= timer_s10.o
+obj-$(CONFIG_SOCFPGA_SECURE_VAB_AUTH)	+= vab.o
+obj-y	+= wrap_handoff_soc64.o
+obj-y	+= wrap_pll_config_soc64.o
+ifndef CONFIG_SPL_BUILD
+obj-$(CONFIG_ARMV8_PSCI) += psci.o
+obj-$(CONFIG_ARMV8_PSCI) += smc_ecc_dbe_s10.o
+obj-$(CONFIG_ARMV8_PSCI) += smc_fpga_reconfig_s10.o
+obj-$(CONFIG_ARMV8_PSCI) += smc_registers_s10.o
+obj-$(CONFIG_ARMV8_PSCI) += smc_rsu_s10.o
+endif
 endif
 
 ifdef CONFIG_TARGET_SOCFPGA_N5X
@@ -64,11 +111,22 @@ obj-y	+= misc_soc64.o
 obj-y	+= mmu-arm64_s10.o
 obj-y	+= reset_manager_s10.o
 obj-$(CONFIG_SOCFPGA_SECURE_VAB_AUTH)	+= secure_vab.o
+obj-y	+= smmu_s10.o
 obj-y	+= system_manager_soc64.o
 obj-y	+= timer_s10.o
 obj-$(CONFIG_SOCFPGA_SECURE_VAB_AUTH)	+= vab.o
 obj-y	+= wrap_handoff_soc64.o
 obj-y	+= wrap_pll_config_soc64.o
+ifndef CONFIG_SPL_BUILD
+obj-y   += rsu.o
+obj-y   += rsu_ll_qspi.o
+obj-y   += rsu_misc.o
+obj-y	+= rsu_s10.o
+obj-$(CONFIG_ARMV8_PSCI) += psci.o
+obj-$(CONFIG_ARMV8_PSCI) += smc_ecc_dbe_s10.o
+obj-$(CONFIG_ARMV8_PSCI) += smc_registers_s10.o
+obj-$(CONFIG_ARMV8_PSCI) += smc_rsu_s10.o
+endif
 endif
 
 ifdef CONFIG_SPL_BUILD
@@ -79,21 +137,24 @@ obj-y	+= wrap_iocsr_config.o
 obj-y	+= wrap_pinmux_config.o
 obj-y	+= wrap_sdram_config.o
 endif
-ifdef CONFIG_TARGET_SOCFPGA_SOC64
-obj-y	+= firewall.o
-obj-y	+= spl_soc64.o
-endif
 ifdef CONFIG_TARGET_SOCFPGA_ARRIA10
 obj-y	+= spl_a10.o
 endif
 ifdef CONFIG_TARGET_SOCFPGA_STRATIX10
 obj-y	+= spl_s10.o
+obj-y	+= spl_soc64.o
 endif
 ifdef CONFIG_TARGET_SOCFPGA_AGILEX
 obj-y	+= spl_agilex.o
+obj-y	+= spl_soc64.o
 endif
 ifdef CONFIG_TARGET_SOCFPGA_N5X
 obj-y	+= spl_n5x.o
+obj-y	+= spl_soc64.o
+endif
+ifdef CONFIG_TARGET_SOCFPGA_AGILEX5
+obj-y	+= spl_agilex5.o
+obj-y	+= spl_soc64.o
 endif
 else
 obj-$(CONFIG_SPL_ATF) += secure_reg_helper.o
diff --git a/arch/arm/mach-socfpga/board.c b/arch/arm/mach-socfpga/board.c
index 09e09192fb..140a520ab7 100644
--- a/arch/arm/mach-socfpga/board.c
+++ b/arch/arm/mach-socfpga/board.c
@@ -7,9 +7,11 @@
 
 #include <common.h>
 #include <asm/arch/clock_manager.h>
+#include <asm/arch/mailbox_s10.h>
 #include <asm/arch/misc.h>
 #include <asm/arch/reset_manager.h>
 #include <asm/arch/secure_vab.h>
+#include <asm/arch/smc_api.h>
 #include <asm/global_data.h>
 #include <asm/io.h>
 #include <errno.h>
@@ -23,6 +25,8 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+#define DEFAULT_JTAG_USERCODE 0xFFFFFFFF
+
 void s_init(void) {
 #ifndef CONFIG_ARM64
 	/*
@@ -46,7 +50,7 @@ void s_init(void) {
 int board_init(void)
 {
 	/* Address of boot parameters for ATAG (if ATAG is used) */
-	gd->bd->bi_boot_params = CFG_SYS_SDRAM_BASE + 0x100;
+	gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
 
 	return 0;
 }
@@ -92,13 +96,55 @@ int g_dnl_board_usb_cable_connected(void)
 }
 #endif
 
-#ifdef CONFIG_SPL_BUILD
-__weak int board_fit_config_name_match(const char *name)
+u8 socfpga_get_board_id(void)
 {
-	/* Just empty function now - can't decide what to choose */
-	debug("%s: %s\n", __func__, name);
+	u8 board_id = 0;
+	u32 jtag_usercode;
+	int err;
 
-	return 0;
+#if !IS_ENABLED(CONFIG_SPL_BUILD) && IS_ENABLED(CONFIG_SPL_ATF)
+	err = smc_get_usercode(&jtag_usercode);
+#else
+	u32 resp_len = 1;
+
+	err = mbox_send_cmd(MBOX_ID_UBOOT, MBOX_GET_USERCODE, MBOX_CMD_DIRECT, 0,
+			    NULL, 0, &resp_len, &jtag_usercode);
+#endif
+
+	if (err) {
+		puts("Fail to read JTAG Usercode. Default Board ID to 0\n");
+		return board_id;
+	}
+
+	debug("Valid JTAG Usercode: %u\n", jtag_usercode);
+
+	if (jtag_usercode == DEFAULT_JTAG_USERCODE) {
+		debug("JTAG Usercode is not set. Default Board ID to 0\n");
+	} else if (jtag_usercode >= 0 && jtag_usercode <= 255) {
+		board_id = jtag_usercode;
+		debug("Valid JTAG Usercode. Set Board ID to %u\n", board_id);
+	} else {
+		puts("Board ID is not in range 0 to 255\n");
+	}
+
+	return board_id;
+}
+
+#if IS_ENABLED(CONFIG_SPL_BUILD) && IS_ENABLED(CONFIG_TARGET_SOCFPGA_SOC64)
+int board_fit_config_name_match(const char *name)
+{
+	char board_name[10];
+
+#if IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX5_SIMICS) || \
+IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX5_EMU)
+	sprintf(board_name, "board_%u", 0); /* Hardcoded board ID since Simics no support */
+#else
+	sprintf(board_name, "board_%u", socfpga_get_board_id());
+#endif
+
+	debug("Board name: %s\n", board_name);
+
+	return strcmp(name, board_name);
 }
 #endif
 
@@ -116,6 +162,8 @@ void board_fit_image_post_process(const void *fit, int node, void **p_image,
 #if !IS_ENABLED(CONFIG_SPL_BUILD) && IS_ENABLED(CONFIG_FIT)
 void board_prep_linux(struct bootm_headers *images)
 {
+	bool use_fit = false;
+
 	if (!images->fit_uname_cfg) {
 		if (IS_ENABLED(CONFIG_SOCFPGA_SECURE_VAB_AUTH) &&
 		    !IS_ENABLED(CONFIG_SOCFPGA_SECURE_VAB_AUTH_ALLOW_NON_FIT_IMAGE)) {
@@ -127,14 +175,17 @@ void board_prep_linux(struct bootm_headers *images)
 			hang();
 		}
 	} else {
+		use_fit = true;
 		/* Update fdt_addr in enviroment variable */
 		env_set_hex("fdt_addr", (ulong)images->ft_addr);
 		debug("images->ft_addr = 0x%08lx\n", (ulong)images->ft_addr);
 	}
 
-	if (IS_ENABLED(CONFIG_CADENCE_QSPI)) {
+	if (use_fit && IS_ENABLED(CONFIG_CADENCE_QSPI)) {
 		if (env_get("linux_qspi_enable"))
 			run_command(env_get("linux_qspi_enable"), 0);
+		if (env_get("rsu_status"))
+			run_command(env_get("rsu_status"), 0);
 	}
 }
 #endif
diff --git a/arch/arm/mach-socfpga/clock_manager_agilex5.c b/arch/arm/mach-socfpga/clock_manager_agilex5.c
new file mode 100644
index 0000000000..46b6bc5d40
--- /dev/null
+++ b/arch/arm/mach-socfpga/clock_manager_agilex5.c
@@ -0,0 +1,82 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019-2022 Intel Corporation <www.intel.com>
+ *
+ */
+
+#include <clk.h>
+#include <common.h>
+#include <dm.h>
+#include <log.h>
+#include <malloc.h>
+#include <asm/arch/clock_manager.h>
+#include <asm/arch/system_manager.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <dt-bindings/clock/agilex5-clock.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static ulong cm_get_rate_dm(u32 id)
+{
+	struct udevice *dev;
+	struct clk clk;
+	ulong rate;
+	int ret;
+
+	ret = uclass_get_device_by_driver(UCLASS_CLK,
+					  DM_DRIVER_GET(socfpga_agilex5_clk),
+					  &dev);
+	if (ret)
+		return 0;
+
+	clk.id = id;
+	ret = clk_request(dev, &clk);
+	if (ret < 0)
+		return 0;
+
+	rate = clk_get_rate(&clk);
+
+	clk_free(&clk);
+
+	if ((rate == (unsigned long)-ENOSYS) ||
+	    (rate == (unsigned long)-ENXIO) ||
+	    (rate == (unsigned long)-EIO)) {
+		debug("%s id %u: clk_get_rate err: %ld\n",
+		      __func__, id, rate);
+		return 0;
+	}
+
+	return rate;
+}
+
+static u32 cm_get_rate_dm_khz(u32 id)
+{
+	return cm_get_rate_dm(id) / 1000;
+}
+
+unsigned long cm_get_mpu_clk_hz(void)
+{
+	return cm_get_rate_dm(AGILEX5_MPU_CLK);
+}
+
+unsigned int cm_get_l4_sys_free_clk_hz(void)
+{
+	return cm_get_rate_dm(AGILEX5_L4_SYS_FREE_CLK);
+}
+
+void cm_print_clock_quick_summary(void)
+{
+	printf("MPU       %10d kHz\n",
+	       cm_get_rate_dm_khz(AGILEX5_MPU_CLK));
+	printf("L4 Main	    %8d kHz\n",
+	       cm_get_rate_dm_khz(AGILEX5_L4_MAIN_CLK));
+	printf("L4 sys free %8d kHz\n",
+	       cm_get_rate_dm_khz(AGILEX5_L4_SYS_FREE_CLK));
+	printf("L4 MP       %8d kHz\n",
+	       cm_get_rate_dm_khz(AGILEX5_L4_MP_CLK));
+	printf("L4 SP       %8d kHz\n",
+	       cm_get_rate_dm_khz(AGILEX5_L4_SP_CLK));
+	printf("SDMMC       %8d kHz\n",
+	       cm_get_rate_dm_khz(AGILEX5_SDMMC_CLK));
+}
diff --git a/arch/arm/mach-socfpga/firewall.c b/arch/arm/mach-socfpga/firewall.c
deleted file mode 100644
index 69229dc651..0000000000
--- a/arch/arm/mach-socfpga/firewall.c
+++ /dev/null
@@ -1,107 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (C) 2016-2019 Intel Corporation <www.intel.com>
- *
- */
-
-#include <asm/io.h>
-#include <common.h>
-#include <asm/arch/firewall.h>
-#include <asm/arch/system_manager.h>
-
-static void firewall_l4_per_disable(void)
-{
-	const struct socfpga_firwall_l4_per *firwall_l4_per_base =
-		(struct socfpga_firwall_l4_per *)SOCFPGA_FIREWALL_L4_PER;
-	u32 i;
-	const u32 *addr[] = {
-			&firwall_l4_per_base->nand,
-			&firwall_l4_per_base->nand_data,
-			&firwall_l4_per_base->usb0,
-			&firwall_l4_per_base->usb1,
-			&firwall_l4_per_base->spim0,
-			&firwall_l4_per_base->spim1,
-			&firwall_l4_per_base->emac0,
-			&firwall_l4_per_base->emac1,
-			&firwall_l4_per_base->emac2,
-			&firwall_l4_per_base->sdmmc,
-			&firwall_l4_per_base->gpio0,
-			&firwall_l4_per_base->gpio1,
-			&firwall_l4_per_base->i2c0,
-			&firwall_l4_per_base->i2c1,
-			&firwall_l4_per_base->i2c2,
-			&firwall_l4_per_base->i2c3,
-			&firwall_l4_per_base->i2c4,
-			&firwall_l4_per_base->timer0,
-			&firwall_l4_per_base->timer1,
-			&firwall_l4_per_base->uart0,
-			&firwall_l4_per_base->uart1
-			};
-
-	/*
-	 * The following lines of code will enable non-secure access
-	 * to nand, usb, spi, emac, sdmmc, gpio, i2c, timers and uart. This
-	 * is needed as most OS run in non-secure mode. Thus we need to
-	 * enable non-secure access to these peripherals in order for the
-	 * OS to use these peripherals.
-	 */
-	for (i = 0; i < ARRAY_SIZE(addr); i++)
-		writel(FIREWALL_L4_DISABLE_ALL, addr[i]);
-}
-
-static void firewall_l4_sys_disable(void)
-{
-	const struct socfpga_firwall_l4_sys *firwall_l4_sys_base =
-		(struct socfpga_firwall_l4_sys *)SOCFPGA_FIREWALL_L4_SYS;
-	u32 i;
-	const u32 *addr[] = {
-			&firwall_l4_sys_base->dma_ecc,
-			&firwall_l4_sys_base->emac0rx_ecc,
-			&firwall_l4_sys_base->emac0tx_ecc,
-			&firwall_l4_sys_base->emac1rx_ecc,
-			&firwall_l4_sys_base->emac1tx_ecc,
-			&firwall_l4_sys_base->emac2rx_ecc,
-			&firwall_l4_sys_base->emac2tx_ecc,
-			&firwall_l4_sys_base->nand_ecc,
-			&firwall_l4_sys_base->nand_read_ecc,
-			&firwall_l4_sys_base->nand_write_ecc,
-			&firwall_l4_sys_base->ocram_ecc,
-			&firwall_l4_sys_base->sdmmc_ecc,
-			&firwall_l4_sys_base->usb0_ecc,
-			&firwall_l4_sys_base->usb1_ecc,
-			&firwall_l4_sys_base->clock_manager,
-			&firwall_l4_sys_base->io_manager,
-			&firwall_l4_sys_base->reset_manager,
-			&firwall_l4_sys_base->system_manager,
-			&firwall_l4_sys_base->watchdog0,
-			&firwall_l4_sys_base->watchdog1,
-			&firwall_l4_sys_base->watchdog2,
-			&firwall_l4_sys_base->watchdog3
-		};
-
-	for (i = 0; i < ARRAY_SIZE(addr); i++)
-		writel(FIREWALL_L4_DISABLE_ALL, addr[i]);
-}
-
-static void firewall_bridge_disable(void)
-{
-	/* disable lwsocf2fpga and soc2fpga bridge security */
-	writel(FIREWALL_BRIDGE_DISABLE_ALL, SOCFPGA_FIREWALL_SOC2FPGA);
-	writel(FIREWALL_BRIDGE_DISABLE_ALL, SOCFPGA_FIREWALL_LWSOC2FPGA);
-}
-
-void firewall_setup(void)
-{
-	firewall_l4_per_disable();
-	firewall_l4_sys_disable();
-	firewall_bridge_disable();
-
-	/* disable SMMU security */
-	writel(FIREWALL_L4_DISABLE_ALL, SOCFPGA_FIREWALL_TCU);
-
-	/* enable non-secure interface to DMA330 DMA and peripherals */
-	writel(SYSMGR_DMA_IRQ_NS | SYSMGR_DMA_MGR_NS,
-	       socfpga_get_sysmgr_addr() + SYSMGR_SOC64_DMA);
-	writel(SYSMGR_DMAPERIPH_ALL_NS,
-	       socfpga_get_sysmgr_addr() + SYSMGR_SOC64_DMA_PERIPH);
-}
diff --git a/arch/arm/mach-socfpga/lowlevel_init_agilex5.S b/arch/arm/mach-socfpga/lowlevel_init_agilex5.S
new file mode 100644
index 0000000000..15e5066767
--- /dev/null
+++ b/arch/arm/mach-socfpga/lowlevel_init_agilex5.S
@@ -0,0 +1,61 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (C) 2022-2023 Intel Corporation <www.intel.com>
+ *
+ */
+
+#include <asm-offsets.h>
+#include <config.h>
+#include <linux/linkage.h>
+#include <asm/macro.h>
+#include <asm/arch/reset_manager_soc64.h>
+
+#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_ARMV8_PSCI)
+.align 3
+_el3_exception_vectors:
+	.quad el3_exception_vectors;
+#endif
+
+ENTRY(lowlevel_init)
+	mov	x29, lr			/* Save LR */
+
+#ifdef CONFIG_SPL_BUILD
+	branch_if_slave x0, 3f
+
+	/* Check rstmgr.stat for warm reset status */
+	ldr	w1, =SOCFPGA_RSTMGR_ADDRESS
+	ldr	w0, [x1]
+	/* Check whether any L4 watchdogs or SDM had triggered warm reset */
+	ldr	x2, =RSTMGR_L4WD_MPU_WARMRESET_MASK
+	ands	x0, x0, x2
+	/*
+	 * If current Reset Manager's status is warm reset just reload the
+	 * .data section by copying the data from data preserve section.
+	 * Otherwise, copy the .data section to the data preserve section to
+	 * keep an original copy of .data section. This ensure SPL is
+	 * reentrant after warm reset.
+	 */
+	b.ne	reload_data_section
+	/* Copy from .data to preserved .data to backup the SPL state */
+	ldr	x0, =__data_start
+	ldr	x1, =__preserve_data_start
+	ldr	x2, =__preserve_data_end
+	b	copy_loop
+reload_data_section:
+	/* Copy from preserved .data to .data to restore the SPL state */
+	ldr	x0, =__preserve_data_start
+	ldr	x1, =__data_start
+	ldr	x2, =__data_end
+copy_loop:
+	ldr	w3, [x0]
+	add	x0, x0, #4
+	str	w3, [x1]
+	add	x1, x1, #4
+	cmp	x1, x2
+	b.ne	copy_loop
+3:
+#endif
+
+	mov	lr, x29			/* Restore LR */
+	ret
+ENDPROC(lowlevel_init)
diff --git a/arch/arm/mach-socfpga/lowlevel_init_soc64.S b/arch/arm/mach-socfpga/lowlevel_init_soc64.S
index 875927cc4d..5680553f68 100644
--- a/arch/arm/mach-socfpga/lowlevel_init_soc64.S
+++ b/arch/arm/mach-socfpga/lowlevel_init_soc64.S
@@ -1,7 +1,7 @@
-/*
- * Copyright (C) 2020 Intel Corporation. All rights reserved
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (C) 2022-2023 Intel Corporation <www.intel.com>
  *
- * SPDX-License-Identifier:    GPL-2.0
  */
 
 #include <asm-offsets.h>
@@ -9,11 +9,101 @@
 #include <linux/linkage.h>
 #include <asm/macro.h>
 
+#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_ARMV8_PSCI)
+.align 3
+_el3_exception_vectors:
+	.quad el3_exception_vectors;
+#endif
+
 ENTRY(lowlevel_init)
 	mov	x29, lr			/* Save LR */
 
+#ifdef CONFIG_SPL_BUILD
+	/* Check for L2 reset magic word */
+	ldr	x4, =L2_RESET_DONE_REG
+	ldr	x5, [x4]
+	ldr	x1, =L2_RESET_DONE_STATUS
+	cmp	x1, x5
+	/* No L2 reset, skip warm reset */
+	b.ne	skipwarmreset
+	/* Put all slaves CPUs into WFI mode */
+	branch_if_slave x0, put_cpu_in_wfi
+	/* L2 reset completed */
+	str	xzr, [x4]
+	/* Clear previous CPU release address */
+	ldr	x4, =CPU_RELEASE_ADDR
+	str	wzr, [x4]
+	/* Master CPU (CPU0) request for warm reset */
+	mrs	x1, rmr_el3
+	orr	x1, x1, #0x02
+	msr	rmr_el3, x1
+	isb
+	dsb	sy
+put_cpu_in_wfi:
+	wfi
+	b	put_cpu_in_wfi
+skipwarmreset:
+#endif
+
 #if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
 #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_ATF)
+
+	/*
+	 * In ATF flow, need to clear the old CPU address when cold reset
+	 * being triggered, but shouldn't clear CPU address if it is reset
+	 * by CPU-ON, so that the core can correctly jump to ATF code after
+	 * reset by CPU-ON. CPU-ON trigger the reset via mpumodrst.
+	 *
+	 * Hardware will set 1 to core*_irq in mpurststat register in
+	 * reset manager if the core is reset by mpumodrst.
+	 *
+	 * The following code will check the mpurststat to identify if the
+	 * core is reset by mpumodrst, and it will skip CPU address clearing
+	 * if the core is reset by mpumodrst. At last, the code need to clear
+	 * the core*_irq by set it to 1. So that it can reflect the correct
+	 * and latest status in next reset.
+	 */
+
+	/* Check if it is a master core off/on from kernel using boot scratch
+	 * cold register 8 bit 19. This bit is set by ATF.
+	 */
+	ldr	x4, =BOOT_SCRATCH_COLD8
+	ldr	x5, [x4]
+	and	x6, x5, #0x80000
+	cbnz	x6, wait_for_atf_master
+
+	/* Retrieve mpurststat register in reset manager */
+	ldr	x4, =SOCFPGA_RSTMGR_ADDRESS
+	ldr	w5, [x4, #0x04]
+
+	/* Set mask based on current core id */
+	mrs	x0, mpidr_el1
+	and	x1, x0, #0xF
+	ldr	x2, =0x00000100
+	lsl	x2, x2, x1
+
+	/* Skip if core*_irq register is set */
+	and	x6, x5, x2
+	cbnz	x6, skip_clear_cpu_address
+
+	/*
+	 * Reach here means core*_irq is 0, means the core is
+	 * reset by cold, warm or watchdog reset.
+	 * Clear previous CPU release address
+	 */
+	ldr	x4, =CPU_RELEASE_ADDR
+	str	wzr, [x4]
+	b	skip_clear_core_irq
+
+skip_clear_cpu_address:
+	/* Clear core*_irq register by writing 1 */
+	ldr	x4, =SOCFPGA_RSTMGR_ADDRESS
+	str	w2, [x4, #0x04]
+
+skip_clear_core_irq:
+	/* Master CPU (CPU0) does not need to wait for atf */
+	branch_if_master x0, master_cpu
+
 wait_for_atf:
 	ldr	x4, =CPU_RELEASE_ADDR
 	ldr	x5, [x4]
@@ -21,6 +111,16 @@ wait_for_atf:
 	br	x5
 slave_wait_atf:
 	branch_if_slave x0, wait_for_atf
+
+wait_for_atf_master:
+	ldr	x4, =CPU_RELEASE_ADDR
+	ldr	x5, [x4]
+	cbz	x5, master_wait_atf
+	br	x5
+master_wait_atf:
+	branch_if_master x0, wait_for_atf_master
+
+master_cpu:
 #else
 	branch_if_slave x0, 1f
 #endif
@@ -52,6 +152,18 @@ slave_wait_atf:
 	bl	gic_wait_for_interrupt
 #endif
 
+#if defined(CONFIG_SPL_BUILD) && !defined(CONFIG_SPL_ATF)
+	/*
+	 * Read the u-boot's PSCI exception handler's vector base
+	 * address from the sysmgr.boot_scratch_cold6 & 7 and update
+	 * their VBAR_EL3 respectively.
+	 */
+wait_vbar_el3:
+	ldr	x4, =VBAR_EL3_BASE_ADDR
+	ldr	x5, [x4]
+	cbz	x5, wait_vbar_el3
+	msr	vbar_el3, x5
+#endif
 	/*
 	 * All slaves will enter EL2 and optionally EL1.
 	 */
@@ -71,6 +183,55 @@ lowlevel_in_el1:
 #endif /* CONFIG_ARMV8_MULTIENTRY */
 
 2:
+#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_ARMV8_PSCI)
+	/*
+	 * Write the u-boot PSCI exception handler's vector base address
+	 * into a sysmgr.boot_scratch_cold6 & 7 so that other slave cpus
+	 * are able to get the vector base address and update their VBAR_EL3
+	 * respectively.
+	 */
+	adr	x0, _el3_exception_vectors
+	ldr	x5, [x0]
+	ldr	x4, =VBAR_EL3_BASE_ADDR
+	str	x5, [x4]
+#endif
+
+#ifdef CONFIG_SPL_BUILD
+	branch_if_slave x0, 3f
+
+	/* Check rstmgr.stat for warm reset status */
+	ldr	x1, =SOCFPGA_RSTMGR_ADDRESS
+	ldr	x0, [x1]
+	/* Check whether any L4 watchdogs or MPUs had triggered warm reset */
+	ldr	x2, =0x000F0F00
+	ands	x0, x0, x2
+	/*
+	 * If current Reset Manager's status is warm reset just reload the
+	 * .data section by copying the data from data preserve section.
+	 * Otherwise, copy the .data section to the data preserve section to
+	 * keep an original copy of .data section. This ensure SPL is
+	 * reentrant after warm reset.
+	 */
+	b.ne	reload_data_section
+	/* Copy from .data to preserved .data to backup the SPL state */
+	ldr	x0, =__data_start
+	ldr	x1, =__preserve_data_start
+	ldr	x2, =__preserve_data_end
+	b	copy_loop
+reload_data_section:
+	/* Copy from preserved .data to .data to restore the SPL state */
+	ldr	x0, =__preserve_data_start
+	ldr	x1, =__data_start
+	ldr	x2, =__data_end
+copy_loop:
+	ldr	w3, [x0]
+	add	x0, x0, #4
+	str	w3, [x1]
+	add	x1, x1, #4
+	cmp	x1, x2
+	b.ne	copy_loop
+3:
+#endif
 	mov	lr, x29			/* Restore LR */
 	ret
 ENDPROC(lowlevel_init)
diff --git a/arch/arm/mach-socfpga/mailbox_s10.c b/arch/arm/mach-socfpga/mailbox_s10.c
index 101af23855..7846596c17 100644
--- a/arch/arm/mach-socfpga/mailbox_s10.c
+++ b/arch/arm/mach-socfpga/mailbox_s10.c
@@ -7,7 +7,9 @@
 #include <common.h>
 #include <asm/arch/clock_manager.h>
 #include <asm/arch/mailbox_s10.h>
+#include <asm/arch/smc_api.h>
 #include <asm/arch/system_manager.h>
+#include <asm/arch/timer.h>
 #include <asm/global_data.h>
 #include <asm/io.h>
 #include <asm/secure.h>
@@ -454,6 +456,14 @@ static __always_inline int mbox_get_fpga_config_status_common(u32 cmd)
 	return MBOX_CFGSTAT_STATE_CONFIG;
 }
 
+#ifdef CONFIG_ARMV8_PSCI
+int  __secure mbox_hps_stage_notify_psci(u32 execution_stage)
+{
+	return mbox_send_cmd_psci(MBOX_ID_UBOOT, MBOX_HPS_STAGE_NOTIFY,
+			     MBOX_CMD_DIRECT, 1, &execution_stage, 0, 0, NULL);
+}
+#endif
+
 int mbox_get_fpga_config_status(u32 cmd)
 {
 	return mbox_get_fpga_config_status_common(cmd);
@@ -479,6 +489,17 @@ int __secure mbox_send_cmd_psci(u8 id, u32 cmd, u8 is_indirect, u32 len,
 					  urgent, resp_buf_len, resp_buf);
 }
 
+int mbox_hps_stage_notify(u32 execution_stage)
+{
+#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_ATF)
+	return smc_send_mailbox(MBOX_HPS_STAGE_NOTIFY, 1, &execution_stage,
+				0, 0, NULL);
+#else
+	return mbox_send_cmd(MBOX_ID_UBOOT, MBOX_HPS_STAGE_NOTIFY,
+			     MBOX_CMD_DIRECT, 1, &execution_stage, 0, 0, NULL);
+#endif
+}
+
 int mbox_send_cmd_only(u8 id, u32 cmd, u8 is_indirect, u32 len, u32 *arg)
 {
 	return mbox_send_cmd_only_common(id, cmd, is_indirect, len, arg);
diff --git a/arch/arm/mach-socfpga/misc.c b/arch/arm/mach-socfpga/misc.c
index 5b5a81a255..024b714ecb 100644
--- a/arch/arm/mach-socfpga/misc.c
+++ b/arch/arm/mach-socfpga/misc.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- *  Copyright (C) 2012-2017 Altera Corporation <www.altera.com>
+ *  Copyright (C) 2012-2023 Altera Corporation <www.altera.com>
  */
 
 #include <common.h>
@@ -34,7 +34,7 @@ phys_addr_t socfpga_sysmgr_base __section(".data");
 
 #ifdef CONFIG_SYS_L2_PL310
 static const struct pl310_regs *const pl310 =
-	(struct pl310_regs *)CFG_SYS_PL310_BASE;
+	(struct pl310_regs *)CONFIG_SYS_PL310_BASE;
 #endif
 
 struct bsel bsel_str[] = {
@@ -164,7 +164,10 @@ int arch_cpu_init(void)
 	 * timeout value is still active which might too short for Linux
 	 * booting.
 	 */
+#if !(IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX5_SIMICS) || \
+IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX5_EMU))
 	hw_watchdog_init();
+#endif
 #else
 	/*
 	 * If the HW watchdog is NOT enabled, make sure it is not running,
@@ -208,10 +211,11 @@ static int do_bridge(struct cmd_tbl *cmdtp, int flag, int argc,
 }
 
 U_BOOT_CMD(bridge, 3, 1, do_bridge,
-	   "SoCFPGA HPS FPGA bridge control",
-	   "enable [mask] - Enable HPS-to-FPGA, FPGA-to-HPS, LWHPS-to-FPGA bridges\n"
-	   "bridge disable [mask] - Enable HPS-to-FPGA, FPGA-to-HPS, LWHPS-to-FPGA bridges\n"
-	   ""
+	"SoCFPGA HPS FPGA bridge control",
+	"enable [mask] - Enable HPS-to-FPGA (Bit 0), LWHPS-to-FPGA (Bit 1), FPGA-to-HPS (Bit 2), F2SDRAM0 (Bit 3), F2SDRAM1 (Bit 4), F2SDRAM2 (Bit 5) bridges \n"
+	"bridge disable [mask] - Disable HPS-to-FPGA (Bit 0), LWHPS-to-FPGA (Bit 1), FPGA-to-HPS (Bit 2), F2SDRAM0 (Bit 3), F2SDRAM1 (Bit 4), F2SDRAM2 (Bit 5) bridges\n"
+	"Bit 3, Bit 4 and Bit 5 bridges only available in Stratix 10\n"
+	""
 );
 
 #endif
@@ -257,6 +261,9 @@ void socfpga_get_managers_addr(void)
 #elif IS_ENABLED(CONFIG_TARGET_SOCFPGA_N5X)
 	ret = socfpga_get_base_addr("intel,n5x-clkmgr",
 				    &socfpga_clkmgr_base);
+#elif IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX5)
+	ret = socfpga_get_base_addr("intel,agilex5-clkmgr",
+				    &socfpga_clkmgr_base);
 #else
 	ret = socfpga_get_base_addr("altr,clk-mgr", &socfpga_clkmgr_base);
 #endif
diff --git a/arch/arm/mach-socfpga/misc_soc64.c b/arch/arm/mach-socfpga/misc_soc64.c
index 2acdfad07b..7dd6f834e1 100644
--- a/arch/arm/mach-socfpga/misc_soc64.c
+++ b/arch/arm/mach-socfpga/misc_soc64.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Copyright (C) 2016-2018 Intel Corporation <www.intel.com>
+ * Copyright (C) 2016-2023 Intel Corporation <www.intel.com>
  *
  */
 
@@ -18,8 +18,12 @@
 #include <log.h>
 #include <mach/clock_manager.h>
 
+#define RSU_DEFAULT_LOG_LEVEL  7
+
 DECLARE_GLOBAL_DATA_PTR;
 
+u8 socfpga_get_board_id(void);
+
 /*
  * FPGA programming support for SoC FPGA Stratix 10
  */
@@ -47,8 +51,11 @@ static Altera_desc altera_fpga[] = {
 #if defined(CONFIG_DISPLAY_CPUINFO)
 int print_cpuinfo(void)
 {
+#if IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX5)
+	puts("CPU:   Intel FPGA SoCFPGA Platform (ARMv8 64bit Cortex-A55/A76)\n");
+#else
 	puts("CPU:   Intel FPGA SoCFPGA Platform (ARMv8 64bit Cortex-A53)\n");
-
+#endif
 	return 0;
 }
 #endif
@@ -56,11 +63,26 @@ int print_cpuinfo(void)
 #ifdef CONFIG_ARCH_MISC_INIT
 int arch_misc_init(void)
 {
+#if !(IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX5_SIMICS) || \
+IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX5_EMU))
 	char qspi_string[13];
+	char level[4];
+	char id[3];
+
+	snprintf(level, sizeof(level), "%u", RSU_DEFAULT_LOG_LEVEL);
 
 	sprintf(qspi_string, "<0x%08x>", cm_get_qspi_controller_clk_hz());
 	env_set("qspi_clock", qspi_string);
 
+	/* for RSU, set log level to default if log level is not set */
+	if (!env_get("rsu_log_level"))
+		env_set("rsu_log_level", level);
+
+	/* Export board_id as environment variable */
+	sprintf(id, "%u", socfpga_get_board_id());
+	env_set("board_id", id);
+#endif
+
 	return 0;
 }
 #endif
@@ -87,5 +109,10 @@ void do_bridge_reset(int enable, unsigned int mask)
 		return;
 	}
 
-	socfpga_bridges_reset(enable);
+	socfpga_bridges_reset(enable, mask);
+}
+
+void arch_preboot_os(void)
+{
+	mbox_hps_stage_notify(HPS_EXECUTION_STATE_OS);
 }
diff --git a/arch/arm/mach-socfpga/mmu-arm64_s10.c b/arch/arm/mach-socfpga/mmu-arm64_s10.c
index a55b7b7cf3..0951233cad 100644
--- a/arch/arm/mach-socfpga/mmu-arm64_s10.c
+++ b/arch/arm/mach-socfpga/mmu-arm64_s10.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Copyright (C) 2016-2018 Intel Corporation <www.intel.com>
+ * Copyright (C) 2016-2022 Intel Corporation <www.intel.com>
  *
  */
 
@@ -10,6 +10,46 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+#if IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX5)
+static struct mm_region socfpga_agilex5_mem_map[] = {
+	{
+		/* OCRAM 1MB but available 256KB */
+		.virt	= 0x00000000UL,
+		.phys	= 0x00000000UL,
+		.size	= 0x00040000UL,
+		.attrs	= PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+				PTE_BLOCK_INNER_SHARE,
+	}, {
+		/* DEVICE */
+		.virt	= 0x10808000UL,
+		.phys	= 0x10808000UL,
+		.size	= 0x0F7F8000UL,
+		.attrs	= PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+				PTE_BLOCK_NON_SHARE |
+				PTE_BLOCK_PXN | PTE_BLOCK_UXN,
+	}, {
+		/* FPGA 1.5GB */
+		.virt	= 0x20000000UL,
+		.phys	= 0x20000000UL,
+		.size	= 0x60000000UL,
+		.attrs	= PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+				PTE_BLOCK_NON_SHARE |
+				PTE_BLOCK_PXN | PTE_BLOCK_UXN,
+	}, {
+		/* MEM 2GB */
+		.virt	= 0x80000000UL,
+		.phys	= 0x80000000UL,
+		.size	= 0x80000000UL,
+		.attrs	= PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+				PTE_BLOCK_INNER_SHARE,
+	}, {
+		/* List terminator */
+	},
+};
+
+struct mm_region *mem_map = socfpga_agilex5_mem_map;
+
+#else
 static struct mm_region socfpga_stratix10_mem_map[] = {
 	{
 		/* MEM 2GB*/
@@ -70,3 +110,4 @@ static struct mm_region socfpga_stratix10_mem_map[] = {
 };
 
 struct mm_region *mem_map = socfpga_stratix10_mem_map;
+#endif
diff --git a/arch/arm/mach-socfpga/reset_manager_s10.c b/arch/arm/mach-socfpga/reset_manager_s10.c
index f47fec10a0..1bf6a74648 100644
--- a/arch/arm/mach-socfpga/reset_manager_s10.c
+++ b/arch/arm/mach-socfpga/reset_manager_s10.c
@@ -1,22 +1,58 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Copyright (C) 2016-2018 Intel Corporation <www.intel.com>
+ * Copyright (C) 2016-2023 Intel Corporation <www.intel.com>
  *
  */
 
 #include <common.h>
+#include <errno.h>
 #include <hang.h>
 #include <asm/global_data.h>
 #include <asm/io.h>
+#include <asm/secure.h>
 #include <asm/arch/reset_manager.h>
 #include <asm/arch/smc_api.h>
 #include <asm/arch/system_manager.h>
+#include <asm/arch/timer.h>
 #include <dt-bindings/reset/altr,rst-mgr-s10.h>
+#include <exports.h>
 #include <linux/iopoll.h>
 #include <linux/intel-smc.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
+#define TIMEOUT_300MS     300
+
+/* F2S manager registers */
+#define F2SDRAM_SIDEBAND_FLAGINSTATUS0	0x14
+#define F2SDRAM_SIDEBAND_FLAGOUTSET0	0x50
+#define F2SDRAM_SIDEBAND_FLAGOUTCLR0	0x54
+
+static __always_inline int wait_for_bit(u32 *reg, const u32 mask, bool set,
+					unsigned int timeout_ms)
+{
+	u32 val;
+	int timeout = timeout_ms;
+
+	while (1) {
+		val = readl(reg);
+
+		if (!set)
+			val = ~val;
+
+		if ((val & mask) == mask)
+			return 0;
+
+		if (!timeout)
+			break;
+
+		timeout--;
+		__socfpga_udelay(1000);
+	}
+
+	return -ETIMEDOUT;
+}
+
 /* Assert or de-assert SoCFPGA reset manager reset. */
 void socfpga_per_reset(u32 reset, int set)
 {
@@ -57,66 +93,221 @@ void socfpga_per_reset_all(void)
 	writel(0xffffffff, socfpga_get_rstmgr_addr() + RSTMGR_SOC64_PER1MODRST);
 }
 
-void socfpga_bridges_reset(int enable)
+static __always_inline void socfpga_f2s_bridges_reset(int enable,
+						      unsigned int mask)
 {
-#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_ATF)
-	u64 arg = enable;
+	int ret;
+	u32 brg_mask;
+	u32 flagout_idlereq = 0;
+	u32 flagoutset_fdrain = 0;
+	u32 flagoutset_en = 0;
+	u32 flaginstatus_idleack = 0;
+	u32 flaginstatus_respempty = 0;
+
+	if (CONFIG_IS_ENABLED(TARGET_SOCFPGA_STRATIX10)) {
+		/* Support fpga2soc and f2sdram */
+		brg_mask = mask & (RSTMGR_BRGMODRST_FPGA2SOC_MASK |
+				   RSTMGR_BRGMODRST_F2SDRAM0_MASK |
+				   RSTMGR_BRGMODRST_F2SDRAM1_MASK |
+				   RSTMGR_BRGMODRST_F2SDRAM2_MASK);
+
+		if (brg_mask & RSTMGR_BRGMODRST_F2SDRAM0_MASK) {
+			flagout_idlereq |= BIT(0);
+			flaginstatus_idleack |= BIT(1);
+			flagoutset_fdrain |= BIT(2);
+			flagoutset_en |= BIT(1);
+			flaginstatus_respempty |= BIT(3);
+		}
+
+		if (brg_mask & RSTMGR_BRGMODRST_F2SDRAM1_MASK) {
+			flagout_idlereq |= BIT(3);
+			flaginstatus_idleack |= BIT(5);
+			flagoutset_fdrain |= BIT(5);
+			flagoutset_en |= BIT(4);
+			flaginstatus_respempty |= BIT(7);
+		}
 
-	int ret = invoke_smc(INTEL_SIP_SMC_HPS_SET_BRIDGES, &arg, 1, NULL, 0);
-	if (ret) {
-		printf("SMC call failed with error %d in %s.\n", ret, __func__);
+		if (brg_mask & RSTMGR_BRGMODRST_F2SDRAM2_MASK) {
+			flagout_idlereq |= BIT(6);
+			flaginstatus_idleack |= BIT(9);
+			flagoutset_fdrain |= BIT(8);
+			flagoutset_en |= BIT(7);
+			flaginstatus_respempty |= BIT(11);
+		}
+	} else {
+		/* Support fpga2soc only */
+		brg_mask = mask & RSTMGR_BRGMODRST_FPGA2SOC_MASK;
+		if (brg_mask & RSTMGR_BRGMODRST_FPGA2SOC_MASK) {
+			flagout_idlereq |= BIT(0);
+			flaginstatus_idleack |= BIT(1);
+			flagoutset_fdrain |= BIT(2);
+			flagoutset_en |= BIT(1);
+			flaginstatus_respempty |= BIT(3);
+		}
+	}
+
+	/* mask is not set, return here */
+	if (!brg_mask)
 		return;
+
+	if (enable) {
+		clrbits_le32(socfpga_get_rstmgr_addr() + RSTMGR_SOC64_BRGMODRST,
+			     brg_mask);
+		setbits_le32(SOCFPGA_F2SDRAM_MGR_ADDRESS +
+			     F2SDRAM_SIDEBAND_FLAGOUTCLR0,
+			     flagout_idlereq);
+
+		/* Wait for mpfe noc idleack to 0 */
+		wait_for_bit((u32 *)(SOCFPGA_F2SDRAM_MGR_ADDRESS +
+			     F2SDRAM_SIDEBAND_FLAGINSTATUS0),
+			     flaginstatus_idleack, false, TIMEOUT_300MS);
+
+		setbits_le32(SOCFPGA_F2SDRAM_MGR_ADDRESS +
+			     F2SDRAM_SIDEBAND_FLAGOUTCLR0,
+			     flagoutset_fdrain);
+		setbits_le32(SOCFPGA_F2SDRAM_MGR_ADDRESS +
+			     F2SDRAM_SIDEBAND_FLAGOUTSET0, flagoutset_en);
+
+		__socfpga_udelay(1); /* wait 1us */
+	} else {
+		if (readl((socfpga_get_rstmgr_addr() +
+		    RSTMGR_SOC64_BRGMODRST) & brg_mask)) {
+			/* Bridge cannot be reset twice */
+			return;
+		}
+
+		setbits_le32(socfpga_get_rstmgr_addr() + RSTMGR_SOC64_HDSKEN,
+			     RSTMGR_HDSKEN_FPGAHSEN);
+		setbits_le32(socfpga_get_rstmgr_addr() + RSTMGR_SOC64_HDSKREQ,
+			     RSTMGR_HDSKREQ_FPGAHSREQ);
+
+		/* Wait for FPGA ack the handshake request to 1 */
+		wait_for_bit((u32 *)(socfpga_get_rstmgr_addr() +
+			     RSTMGR_SOC64_HDSKACK), RSTMGR_HDSKREQ_FPGAHSREQ,
+			     true, TIMEOUT_300MS);
+
+		setbits_le32(SOCFPGA_F2SDRAM_MGR_ADDRESS +
+			     F2SDRAM_SIDEBAND_FLAGOUTCLR0, flagoutset_en);
+
+		__socfpga_udelay(1);
+
+		/* Requests MPFE NoC to idle */
+		setbits_le32(SOCFPGA_F2SDRAM_MGR_ADDRESS +
+			     F2SDRAM_SIDEBAND_FLAGOUTSET0, flagout_idlereq);
+
+		/* Force F2S bridge to drain */
+		setbits_le32(SOCFPGA_F2SDRAM_MGR_ADDRESS +
+			     F2SDRAM_SIDEBAND_FLAGOUTSET0, flagoutset_fdrain);
+
+		/* Wait for respond queue empty status to 1 (resp idle) */
+		ret = wait_for_bit((u32 *)(SOCFPGA_F2SDRAM_MGR_ADDRESS +
+					   F2SDRAM_SIDEBAND_FLAGINSTATUS0),
+					   flaginstatus_respempty, true,
+					   TIMEOUT_300MS);
+
+		/* Confirm again */
+		if (!ret)
+			ret = wait_for_bit((u32 *)
+					   (SOCFPGA_F2SDRAM_MGR_ADDRESS +
+					   F2SDRAM_SIDEBAND_FLAGINSTATUS0),
+					   flaginstatus_respempty, true,
+					   TIMEOUT_300MS);
+
+		setbits_le32(socfpga_get_rstmgr_addr() + RSTMGR_SOC64_BRGMODRST,
+			     brg_mask & ~RSTMGR_BRGMODRST_FPGA2SOC_MASK);
+		clrbits_le32(socfpga_get_rstmgr_addr() + RSTMGR_SOC64_HDSKREQ,
+			     RSTMGR_HDSKREQ_FPGAHSREQ);
+		setbits_le32(SOCFPGA_F2SDRAM_MGR_ADDRESS +
+			     F2SDRAM_SIDEBAND_FLAGOUTCLR0,
+			     flagout_idlereq);
+	}
+}
+
+static __always_inline void socfpga_s2f_bridges_reset(int enable,
+						      unsigned int mask)
+{
+	unsigned int noc_mask = 0;
+	unsigned int brg_mask = 0;
+
+	if (mask & RSTMGR_BRGMODRST_SOC2FPGA_MASK) {
+		noc_mask = SYSMGR_NOC_H2F_MSK;
+		brg_mask = RSTMGR_BRGMODRST_SOC2FPGA_MASK;
 	}
-#else
-	u32 reg;
+
+	if (mask & RSTMGR_BRGMODRST_LWSOC2FPGA_MASK) {
+		noc_mask |= SYSMGR_NOC_LWH2F_MSK;
+		brg_mask |= RSTMGR_BRGMODRST_LWSOC2FPGA_MASK;
+	}
+
+	/* s2f mask is not set, return here */
+	if (!brg_mask)
+		return;
 
 	if (enable) {
 		/* clear idle request to all bridges */
 		setbits_le32(socfpga_get_sysmgr_addr() +
-			     SYSMGR_SOC64_NOC_IDLEREQ_CLR, ~0);
+			     SYSMGR_SOC64_NOC_IDLEREQ_CLR, noc_mask);
 
-		/* Release all bridges from reset state */
+		/* Release SOC2FPGA bridges from reset state */
 		clrbits_le32(socfpga_get_rstmgr_addr() + RSTMGR_SOC64_BRGMODRST,
-			     ~0);
+			     brg_mask);
 
-		/* Poll until all idleack to 0 */
-		read_poll_timeout(readl, reg, !reg, 1000, 300000,
-				  socfpga_get_sysmgr_addr() +
-				  SYSMGR_SOC64_NOC_IDLEACK);
+		/* Wait for all NOC master ack to 0 */
+		wait_for_bit((u32 *)(socfpga_get_sysmgr_addr() +
+			     SYSMGR_SOC64_NOC_IDLEACK), noc_mask, false,
+			     TIMEOUT_300MS);
 	} else {
 		/* set idle request to all bridges */
-		writel(~0,
-		       socfpga_get_sysmgr_addr() +
-		       SYSMGR_SOC64_NOC_IDLEREQ_SET);
+		setbits_le32(socfpga_get_sysmgr_addr() +
+			     SYSMGR_SOC64_NOC_IDLEREQ_SET, noc_mask);
 
 		/* Enable the NOC timeout */
 		writel(1, socfpga_get_sysmgr_addr() + SYSMGR_SOC64_NOC_TIMEOUT);
 
-		/* Poll until all idleack to 1 */
-		read_poll_timeout(readl, reg,
-				  reg == (SYSMGR_NOC_H2F_MSK |
-					  SYSMGR_NOC_LWH2F_MSK),
-				  1000, 300000,
-				  socfpga_get_sysmgr_addr() +
-				  SYSMGR_SOC64_NOC_IDLEACK);
-
-		/* Poll until all idlestatus to 1 */
-		read_poll_timeout(readl, reg,
-				  reg == (SYSMGR_NOC_H2F_MSK |
-					  SYSMGR_NOC_LWH2F_MSK),
-				  1000, 300000,
-				  socfpga_get_sysmgr_addr() +
-				  SYSMGR_SOC64_NOC_IDLESTATUS);
-
-		/* Reset all bridges (except NOR DDR scheduler & F2S) */
+		/* Wait for all NOC master ack to 1 */
+		wait_for_bit((u32 *)(socfpga_get_sysmgr_addr() +
+			     SYSMGR_SOC64_NOC_IDLEACK), noc_mask, true,
+			     TIMEOUT_300MS);
+
+		/* Wait for all NOC master idlestatus to 1 */
+		wait_for_bit((u32 *)(socfpga_get_sysmgr_addr() +
+			     SYSMGR_SOC64_NOC_IDLESTATUS), noc_mask, true,
+			     TIMEOUT_300MS);
+
+		/* Reset all SOC2FPGA bridges */
 		setbits_le32(socfpga_get_rstmgr_addr() + RSTMGR_SOC64_BRGMODRST,
-			     ~(RSTMGR_BRGMODRST_DDRSCH_MASK |
-			       RSTMGR_BRGMODRST_FPGA2SOC_MASK));
+			     brg_mask);
 
 		/* Disable NOC timeout */
 		writel(0, socfpga_get_sysmgr_addr() + SYSMGR_SOC64_NOC_TIMEOUT);
 	}
-#endif
+}
+
+void socfpga_bridges_reset(int enable, unsigned int mask)
+{
+	if (!IS_ENABLED(CONFIG_SPL_BUILD) && IS_ENABLED(CONFIG_SPL_ATF)) {
+		u64 arg[2];
+		int ret;
+
+		/* Set bit-1 to indicate has mask value in arg[1]. */
+		arg[0] = (enable & BIT(0)) | BIT(1);
+		arg[1] = mask;
+
+		ret = invoke_smc(INTEL_SIP_SMC_HPS_SET_BRIDGES, arg,
+				 ARRAY_SIZE(arg), NULL, 0);
+		if (ret)
+			printf("Failed to %s the HPS bridges, error %d\n",
+			       enable ? "enable" : "disable", ret);
+	} else {
+		socfpga_s2f_bridges_reset(enable, mask);
+		socfpga_f2s_bridges_reset(enable, mask);
+	}
+}
+
+void __secure socfpga_bridges_reset_psci(int enable, unsigned int mask)
+{
+	socfpga_s2f_bridges_reset(enable, mask);
+	socfpga_f2s_bridges_reset(enable, mask);
 }
 
 /*
@@ -125,7 +316,7 @@ void socfpga_bridges_reset(int enable)
 int cpu_has_been_warmreset(void)
 {
 	return readl(socfpga_get_rstmgr_addr() + RSTMGR_SOC64_STATUS) &
-			RSTMGR_L4WD_MPU_WARMRESET_MASK;
+			(RSTMGR_L4WD_MPU_WARMRESET_MASK);
 }
 
 void print_reset_info(void)
diff --git a/arch/arm/mach-socfpga/secure_reg_helper.c b/arch/arm/mach-socfpga/secure_reg_helper.c
index 0d4f45f33d..23595d242a 100644
--- a/arch/arm/mach-socfpga/secure_reg_helper.c
+++ b/arch/arm/mach-socfpga/secure_reg_helper.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Copyright (C) 2020 Intel Corporation <www.intel.com>
+ * Copyright (C) 2020-2022 Intel Corporation <www.intel.com>
  *
  */
 
@@ -18,9 +18,11 @@
 int socfpga_secure_convert_reg_id_to_addr(u32 id, phys_addr_t *reg_addr)
 {
 	switch (id) {
+#if !IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX5)
 	case SOCFPGA_SECURE_REG_SYSMGR_SOC64_SDMMC:
 		*reg_addr = socfpga_get_sysmgr_addr() + SYSMGR_SOC64_SDMMC;
 		break;
+#endif
 	case SOCFPGA_SECURE_REG_SYSMGR_SOC64_EMAC0:
 		*reg_addr = socfpga_get_sysmgr_addr() + SYSMGR_SOC64_EMAC0;
 		break;
diff --git a/arch/arm/mach-socfpga/smmu_agilex5.c b/arch/arm/mach-socfpga/smmu_agilex5.c
new file mode 100644
index 0000000000..05e74926aa
--- /dev/null
+++ b/arch/arm/mach-socfpga/smmu_agilex5.c
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2023 Intel Corporation. All rights reserved
+ *
+ */
+
+#include <common.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <asm/arch/firewall.h>
+#include <asm/arch/smmu_agilex5.h>
+#include <asm/arch/system_manager.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static inline void setup_smmu_firewall(void)
+{
+	u32 i;
+
+	/* Off the DDR secure transaction for all TBU supported peripherals */
+	for (i = SYSMGR_DMA0_SID_ADDR; i < SYSMGR_TSN2_SID_ADDR; i +=
+	     SOCFPGA_NEXT_TBU_PERIPHERAL) {
+		/* skip this, future use register */
+		if (i == SYSMGR_USB3_SID_ADDR)
+			continue;
+
+		writel(SECURE_TRANS_RESET, (uintptr_t)i);
+	}
+}
+
+void socfpga_init_smmu(void)
+{
+	setup_smmu_firewall();
+}
diff --git a/arch/arm/mach-socfpga/smmu_s10.c b/arch/arm/mach-socfpga/smmu_s10.c
new file mode 100644
index 0000000000..106834cc9a
--- /dev/null
+++ b/arch/arm/mach-socfpga/smmu_s10.c
@@ -0,0 +1,126 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018-2023 Intel Corporation <www.intel.com>
+ *
+ */
+
+#include <common.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <asm/arch/firewall.h>
+#include <asm/arch/smmu_s10.h>
+#include <asm/arch/system_manager.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static const struct smmu_stream_id dev_stream_id[] = {
+	{SYSMGR_EMAC0_SID_ADDR, 0x01, EMAC_W_OFST, EMAC_R_OFST},
+	{SYSMGR_EMAC1_SID_ADDR, 0x02, EMAC_W_OFST, EMAC_R_OFST},
+	{SYSMGR_EMAC2_SID_ADDR, 0x03, EMAC_W_OFST, EMAC_R_OFST},
+	{SYSMGR_NAND_SID_ADDR,  0x04, NAND_W_OFST, NAND_R_OFST},
+	{SYSMGR_SDMMC_SID_ADDR, 0x05, SDMMC_OFST, SDMMC_OFST},
+	{SYSMGR_USB0_SID_ADDR,  0x06, USB_OFST, USB_OFST},
+	{SYSMGR_USB1_SID_ADDR,  0x07, USB_OFST, USB_OFST},
+	{SYSMGR_DMA_SID_ADDR,   0x08, DMA_W_OFST, DMA_R_OFST},
+	{SYSMGR_ETR_SID_ADDR,   0x09, ETR_W_OFST, ETR_R_OFST},
+};
+
+static void set_smmu_streamid(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(dev_stream_id); i++) {
+		u32 mask = SMMU_SET_STREAMID(0x3FF,
+					 dev_stream_id[i].r_bit_ofst,
+					 dev_stream_id[i].w_bit_ofst);
+		u32 value = SMMU_SET_STREAMID(dev_stream_id[i].sid,
+					 dev_stream_id[i].r_bit_ofst,
+					 dev_stream_id[i].w_bit_ofst);
+
+		clrbits_le32(dev_stream_id[i].addr, mask);
+		setbits_le32(dev_stream_id[i].addr, value);
+	}
+}
+
+/*
+ * Need to set the Secure bit (to make it non-secure) on each peripheral
+ * so that SMMU can access the peripheral
+ */
+static void set_smmu_accessible_reg(void)
+{
+	setbits_le32(socfpga_get_sysmgr_addr() + SYSMGR_SOC64_EMAC0,
+		     BIT(27) | BIT(25));
+	setbits_le32(socfpga_get_sysmgr_addr() + SYSMGR_SOC64_EMAC1,
+		     BIT(27) | BIT(25));
+	setbits_le32(socfpga_get_sysmgr_addr() + SYSMGR_SOC64_EMAC2,
+		     BIT(27) | BIT(25));
+	setbits_le32(socfpga_get_sysmgr_addr() + SYSMGR_SOC64_NANDGRP_L3MASTER,
+		     BIT(21) | BIT(17));
+	setbits_le32(socfpga_get_sysmgr_addr() + SYSMGR_SOC64_SDMMC_L3MASTER,
+		     BIT(5));
+	setbits_le32(socfpga_get_sysmgr_addr() + SYSMGR_SOC64_USB0_L3MASTER,
+		     BIT(9));
+	setbits_le32(socfpga_get_sysmgr_addr() + SYSMGR_SOC64_USB1_L3MASTER,
+		     BIT(9));
+}
+
+static inline void setup_smmu_firewall(void)
+{
+	/* Enable nonsecure SMMU accesses */
+	writel(FIREWALL_L4_DISABLE_ALL, SOCFPGA_FIREWALL_TCU);
+}
+
+void socfpga_init_smmu(void)
+{
+	setup_smmu_firewall();
+	set_smmu_streamid();
+	set_smmu_accessible_reg();
+}
+
+int is_smmu_bypass(void)
+{
+	return readl(SOCFPGA_SMMU_ADDRESS + SMMU_SCR0) & SMMU_SCR0_CLIENTPD;
+}
+
+int is_smmu_stream_id_enabled(u32 stream_id)
+{
+	int i;
+	u32 smrg_num;
+	u32 smr, s2cr, sid_mask;
+	u32 cb, cb_index, cb_num;
+
+	if (is_smmu_bypass())
+		return 0;
+
+	/* Get number of Stream Mapping Register Groups */
+	smrg_num = readl(SOCFPGA_SMMU_ADDRESS + SMMU_SIDR0) &
+		   SMMU_SIDR0_NUMSMRG_MASK;
+
+	/* Get number of Context Bank */
+	cb_num = readl(SOCFPGA_SMMU_ADDRESS + SMMU_SIDR1) &
+		 SMMU_SIDR1_NUMCB_MASK;
+
+	for (i = 0; i < smrg_num; i++) {
+		smr = readl(SOCFPGA_SMMU_ADDRESS + SMMU_GR0_SMR((u64)i));
+		sid_mask = (smr & SMMU_SMR_MASK) >> 16;
+
+		/* Skip if Stream ID is invalid or not matched */
+		if (!(smr & SMMU_SMR_VALID) || (smr & sid_mask) != stream_id)
+			continue;
+
+		/* Get Context Bank index from valid matching Stream ID */
+		s2cr = readl(SOCFPGA_SMMU_ADDRESS + SMMU_GR0_S2CR((u64)i));
+		cb_index = s2cr & SMMU_S2CR_CBNDX;
+
+		/* Skip if Context Bank is invalid or not Translation mode */
+		if (cb_index >= cb_num || (s2cr & SMMU_S2CR_TYPE))
+			continue;
+
+		cb = readl(SOCFPGA_SMMU_ADDRESS + SMMU_GR0_CB((u64)cb_index,
+							      SMMU_CB_SCTLR));
+		/* Return MMU enable status for this Context Bank */
+		return (cb & SMMU_CB_SCTLR_M);
+	}
+
+	return 0;
+}
diff --git a/arch/arm/mach-socfpga/spl_agilex5.c b/arch/arm/mach-socfpga/spl_agilex5.c
new file mode 100644
index 0000000000..da91bf5917
--- /dev/null
+++ b/arch/arm/mach-socfpga/spl_agilex5.c
@@ -0,0 +1,180 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019-2023 Intel Corporation <www.intel.com>
+ *
+ */
+
+#include <init.h>
+#include <log.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <asm/u-boot.h>
+#include <asm/utils.h>
+#include <common.h>
+#include <hang.h>
+#include <image.h>
+#include <spl.h>
+#include <asm/arch/clock_manager.h>
+#include <asm/arch/firewall.h>
+#include <asm/arch/mailbox_s10.h>
+#include <asm/arch/misc.h>
+#include <asm/arch/reset_manager.h>
+#include <asm/arch/smmu_s10.h>
+#include <asm/arch/system_manager.h>
+#include <wdt.h>
+#include <dm/uclass.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define USE_HARDCODED_HANDOFF
+
+#ifdef USE_HARDCODED_HANDOFF
+static const u32 hardcoded_handoff_data[402] = {
+0x544f4f42, 0x01000500, 0x00000000, 0x00000000, 0x58554d50, 0x90010000,
+0x00000000, 0x00000000, 0x00000000, 0x03000000, 0x04000000, 0x03000000,
+0x08000000, 0x03000000, 0x0c000000, 0x03000000, 0x10000000, 0x03000000,
+0x14000000, 0x03000000, 0x18000000, 0x03000000, 0x1c000000, 0x03000000,
+0x20000000, 0x03000000, 0x24000000, 0x03000000, 0x28000000, 0x03000000,
+0x2c000000, 0x03000000, 0x30000000, 0x03000000, 0x34000000, 0x03000000,
+0x38000000, 0x03000000, 0x3c000000, 0x03000000, 0x40000000, 0x00000000,
+0x44000000, 0x00000000, 0x48000000, 0x00000000, 0x4c000000, 0x00000000,
+0x50000000, 0x00000000, 0x54000000, 0x00000000, 0x58000000, 0x04000000,
+0x5c000000, 0x04000000, 0x60000000, 0x08000000, 0x64000000, 0x08000000,
+0x68000000, 0x05000000, 0x6c000000, 0x05000000, 0x70000000, 0x08000000,
+0x74000000, 0x08000000, 0x78000000, 0x04000000, 0x7c000000, 0x04000000,
+0x80000000, 0x07000000, 0x84000000, 0x07000000, 0x88000000, 0x07000000,
+0x8c000000, 0x07000000, 0x90000000, 0x01000000, 0x94000000, 0x01000000,
+0x98000000, 0x01000000, 0x9c000000, 0x01000000, 0x00010000, 0x01000000,
+0x04010000, 0x01000000, 0x08010000, 0x09000000, 0x0c010000, 0x08000000,
+0x10010000, 0x08000000, 0x14010000, 0x08000000, 0x18010000, 0x05000000,
+0x1c010000, 0x05000000, 0x54434f49, 0x90010000, 0x00000000, 0x00000000,
+0x00000000, 0x34000000, 0x04000000, 0x14000000, 0x08000000, 0x34000000,
+0x0c000000, 0x34000000, 0x10000000, 0x34000000, 0x14000000, 0x34000000,
+0x18000000, 0x34000000, 0x1c000000, 0x34000000, 0x20000000, 0x34000000,
+0x24000000, 0x34000000, 0x28000000, 0x34000000, 0x2c000000, 0x34000000,
+0x30000000, 0x16000000, 0x34000000, 0x14000000, 0x38000000, 0x34000000,
+0x3c000000, 0x34000000, 0x40000000, 0x14000000, 0x44000000, 0x14000000,
+0x48000000, 0x34000000, 0x4c000000, 0x34000000, 0x50000000, 0x14000000,
+0x54000000, 0x14000000, 0x58000000, 0x34000000, 0x5c000000, 0x34000000,
+0x60000000, 0x35000000, 0x64000000, 0x35000000, 0x68000000, 0x16000000,
+0x6c000000, 0x34000000, 0xd0000000, 0x35000000, 0xd4000000, 0x35000000,
+0xd8000000, 0x3e000000, 0xdc000000, 0x3e000000, 0xe0000000, 0x34000000,
+0xe4000000, 0x34000000, 0xe8000000, 0x16000000, 0xec000000, 0x34000000,
+0xf0000000, 0x34000000, 0xf4000000, 0x34000000, 0xf8000000, 0x14000000,
+0xfc000000, 0x34000000, 0x00010000, 0x34000000, 0x04010000, 0x34000000,
+0x08010000, 0x34000000, 0x0c010000, 0x35000000, 0x10010000, 0x35000000,
+0x14010000, 0x35000000, 0x18010000, 0x3e000000, 0x1c010000, 0x16000000,
+0x41475046, 0xc0000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x04000000, 0x00000000, 0x08000000, 0x00000000, 0x0c000000, 0x00000000,
+0x10000000, 0x00000000, 0x14000000, 0x00000000, 0x18000000, 0x00000000,
+0x1c000000, 0x00000000, 0x20000000, 0x00000000, 0x28000000, 0x00000000,
+0x2c000000, 0x00000000, 0x30000000, 0x00000000, 0x34000000, 0x00000000,
+#if IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX5_EMU)
+0x38000000, 0x01000000, 0x3c000000, 0x00000000, 0x40000000, 0x00000000,
+#else
+0x38000000, 0x00000000, 0x3c000000, 0x00000000, 0x40000000, 0x00000000,
+#endif
+0x44000000, 0x00000000, 0x48000000, 0x00000000, 0x50000000, 0x00000000,
+0x54000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x59414c44, 0x90010000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x04000000, 0x00000000, 0x08000000, 0x00000000, 0x0c000000, 0x00000000,
+0x10000000, 0x00000000, 0x14000000, 0x00000000, 0x18000000, 0x00000000,
+0x1c000000, 0x00000000, 0x20000000, 0x00000000, 0x24000000, 0x00000000,
+0x28000000, 0x00000000, 0x2c000000, 0x00000000, 0x30000000, 0x00110000,
+0x34000000, 0x00000000, 0x38000000, 0x00000000, 0x3c000000, 0x00000000,
+0x40000000, 0x00000000, 0x44000000, 0x00000000, 0x48000000, 0x00000000,
+0x4c000000, 0x00000000, 0x50000000, 0x00000000, 0x54000000, 0x00000000,
+0x58000000, 0x00000000, 0x5c000000, 0x00000000, 0x60000000, 0x00000000,
+0x64000000, 0x00000000, 0x68000000, 0x00000000, 0x6c000000, 0x00000000,
+0x70000000, 0x00000000, 0x74000000, 0x00000000, 0x78000000, 0x00000000,
+0x7c000000, 0x00000000, 0x80000000, 0x00000000, 0x84000000, 0x00000000,
+0x88000000, 0x00000000, 0x8c000000, 0x00000000, 0x90000000, 0x00000000,
+0x94000000, 0x00000000, 0x98000000, 0x00000000, 0x9c000000, 0x00000000,
+0xa0000000, 0x00000000, 0xa4000000, 0x00000000, 0xa8000000, 0x00000000,
+0xac000000, 0x00000000, 0xb0000000, 0x00000000, 0xb4000000, 0x00000000,
+0xb8000000, 0x00000000, 0xbC000000, 0x00000000, 0x534b4c43, 0xA0000000,
+0x00000000, 0x00000000, 0x00000000, 0x98002618, 0x03010016, 0x00000000,
+0x02000008, 0x04000008, 0x03000008, 0x09000008, 0x90000000, 0x00000000,
+0x01000000, 0x03010015, 0x00000000, 0x02000008, 0x03000008, 0x7d000008,
+0x06000008, 0x78000000, 0x01000100, 0x09000000, 0x00000100, 0x01000000,
+0x00000100, 0x00000100, 0x00000100, 0x13000000, 0x01000000, 0x00000100,
+0x00000000, 0x00000000, 0x00000000, 0x40787d01, 0x40787d01, 0x00000000,
+0x00000000, 0x00000000, 0x49524550, 0x14000000, 0x00000000, 0x00000000,
+0x40000000, 0x4d524453, 0x14000000, 0x00000000, 0x00000000, 0x00000000
+};
+#endif
+
+#define HARDCODED_HANDOFF_DATA_SIZE	(sizeof(hardcoded_handoff_data) / sizeof(u32))
+
+void board_init_f(ulong dummy)
+{
+	int ret;
+	struct udevice *dev;
+
+	ret = spl_early_init();
+	if (ret)
+		hang();
+
+	socfpga_get_managers_addr();
+
+#ifdef USE_HARDCODED_HANDOFF
+	/* Write hardcoded handoff value into OCRAM handoff area */
+	u32 i;
+
+	for (i = 0; i < HARDCODED_HANDOFF_DATA_SIZE; i++)
+		writel(hardcoded_handoff_data[i],
+		       (u32 *)SOC64_HANDOFF_BASE + i);
+#endif
+
+	sysmgr_pinmux_init();
+
+	if (!(IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX5_SIMICS) ||
+	      IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX5_EMU))) {
+		/* Ensure watchdog is paused when debugging is happening */
+		writel(SYSMGR_WDDBG_PAUSE_ALL_CPU,
+		       socfpga_get_sysmgr_addr() + SYSMGR_SOC64_WDDBG);
+	}
+
+	timer_init();
+
+	ret = uclass_get_device(UCLASS_CLK, 0, &dev);
+	if (ret) {
+		debug("Clock init failed: %d\n", ret);
+		hang();
+	}
+
+	if (!(IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX5_SIMICS) ||
+	      IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX5_EMU))) {
+		/*
+		 * Enable watchdog as early as possible before initializing other
+		 * component. Watchdog need to be enabled after clock driver because
+		 * it will retrieve the clock frequency from clock driver.
+		 */
+		if (CONFIG_IS_ENABLED(WDT))
+			initr_watchdog();
+	}
+
+	preloader_console_init();
+	print_reset_info();
+	cm_print_clock_quick_summary();
+
+	ret = uclass_get_device_by_name(UCLASS_NOP, "socfpga-secreg", &dev);
+	if (ret) {
+		printf("Firewall & secure settings init failed: %d\n", ret);
+		hang();
+	}
+
+#if CONFIG_IS_ENABLED(ALTERA_SDRAM)
+	ret = uclass_get_device(UCLASS_RAM, 0, &dev);
+	if (ret) {
+		debug("DRAM init failed: %d\n", ret);
+		hang();
+	}
+#endif
+
+	mbox_init();
+
+#ifdef CONFIG_CADENCE_QSPI
+	mbox_qspi_open();
+#endif
+}
diff --git a/arch/arm/mach-socfpga/spl_soc64.c b/arch/arm/mach-socfpga/spl_soc64.c
index ba6efc1d86..a4ac906ffd 100644
--- a/arch/arm/mach-socfpga/spl_soc64.c
+++ b/arch/arm/mach-socfpga/spl_soc64.c
@@ -1,25 +1,203 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- *  Copyright (C) 2020 Intel Corporation. All rights reserved
+ *  Copyright (C) 2020-2022 Intel Corporation. All rights reserved
  *
  */
 
+#include <asm/io.h>
+#include <asm/u-boot.h>
+#include <asm/utils.h>
 #include <common.h>
+#include <debug_uart.h>
+#include <dm.h>
+#include <dm/ofnode.h>
+#include <image.h>
+#include <log.h>
 #include <spl.h>
+#include <asm/arch/clock_manager.h>
+#include <asm/arch/firewall.h>
+#include <asm/arch/mailbox_s10.h>
+#include <asm/arch/reset_manager.h>
+#include <asm/arch/system_manager.h>
+#include <asm/arch/smmu_s10.h>
+#include <watchdog.h>
+#include <dm/uclass.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
 u32 spl_boot_device(void)
 {
+	int ret, size;
+	ofnode node;
+	const fdt32_t *phandle_p;
+	u32 phandle;
+	struct udevice *dev;
+
+	node = ofnode_path("/chosen");
+	if (!ofnode_valid(node)) {
+		debug("%s: /chosen node was not found.\n", __func__);
+		goto fallback;
+	}
+
+	phandle_p = ofnode_get_property(node, "u-boot,boot0", &size);
+	if (!phandle_p) {
+		debug("%s: u-boot,boot0 property was not found.\n",
+		      __func__);
+		goto fallback;
+	}
+
+	phandle = fdt32_to_cpu(*phandle_p);
+
+	node = ofnode_get_by_phandle(phandle);
+
+	ret = device_get_global_by_ofnode(node, &dev);
+	if (ret) {
+		debug("%s: Boot device at not found, error: %d\n", __func__,
+		      ret);
+		goto fallback;
+	}
+
+	debug("%s: Found boot device %s\n", __func__, dev->name);
+
+	switch (device_get_uclass_id(dev)) {
+	case UCLASS_SPI_FLASH:
+		return BOOT_DEVICE_SPI;
+	case UCLASS_MTD:
+		return BOOT_DEVICE_NAND;
+	case UCLASS_MMC:
+		return BOOT_DEVICE_MMC1;
+	default:
+		debug("%s: Booting from device uclass '%s' is not supported\n",
+		      __func__, dev_get_uclass_name(dev));
+	}
+
+fallback:
+	/* Return default boot device */
 	return BOOT_DEVICE_MMC1;
 }
 
 #if IS_ENABLED(CONFIG_SPL_MMC)
 u32 spl_boot_mode(const u32 boot_device)
 {
-	if (IS_ENABLED(CONFIG_SPL_FS_FAT) || IS_ENABLED(CONFIG_SPL_FS_EXT4))
-		return MMCSD_MODE_FS;
-	else
-		return MMCSD_MODE_RAW;
+#if defined(CONFIG_SPL_FS_FAT) || defined(CONFIG_SPL_FS_EXT4)
+	return MMCSD_MODE_FS;
+#else
+	return MMCSD_MODE_RAW;
+#endif
 }
 #endif
+
+/* board specific function prior loading SSBL / U-Boot */
+void spl_perform_fixups(struct spl_image_info *spl_image)
+{
+	/* Setup and Initialize SMMU */
+	socfpga_init_smmu();
+
+#if !(IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX5_SIMICS) || \
+IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX5_EMU))
+	mbox_hps_stage_notify(HPS_EXECUTION_STATE_SSBL);
+#endif
+}
+
+/* This function is to map specified node onto SPL boot devices */
+static int spl_node_to_boot_device(int node)
+{
+	const void *blob = gd->fdt_blob;
+	struct udevice *parent;
+	const char *prop;
+
+	if (!uclass_get_device_by_of_offset(UCLASS_MMC, node, &parent))
+		return BOOT_DEVICE_MMC1;
+	else if (!uclass_get_device_by_of_offset(UCLASS_SPI_FLASH, node, &parent))
+		return BOOT_DEVICE_SPI;
+	else if (!uclass_get_device_by_of_offset(UCLASS_MTD, node, &parent))
+		return BOOT_DEVICE_NAND;
+
+	prop = fdt_getprop(blob, node, "device_type", NULL);
+	if (prop) {
+		if (!strcmp(prop, "memory"))
+			return BOOT_DEVICE_RAM;
+
+		printf("%s: unknown device_type %s\n", __func__, prop);
+	}
+
+	return -1;
+}
+
+static void default_spl_boot_list(u32 *spl_boot_list, int length)
+{
+	spl_boot_list[0] = BOOT_DEVICE_MMC1;
+
+	if (length > 1)
+		spl_boot_list[1] = BOOT_DEVICE_SPI;
+
+	if (length > 2)
+		spl_boot_list[2] = BOOT_DEVICE_NAND;
+}
+
+void board_boot_order(u32 *spl_boot_list)
+{
+	int idx = 0;
+	const void *blob = gd->fdt_blob;
+	int chosen_node = fdt_path_offset(blob, "/chosen");
+	const char *conf;
+	int elem;
+	int boot_device;
+	int node;
+	int length;
+
+	/* expect valid initialized spl_boot_list */
+	if (!spl_boot_list)
+		return;
+
+	length = 1;
+	while (spl_boot_list[length] == spl_boot_list[length - 1])
+		length++;
+
+	debug("%s: chosen_node is %d\n", __func__, chosen_node);
+	if (chosen_node < 0) {
+		printf("%s: /chosen not found, using default\n", __func__);
+		default_spl_boot_list(spl_boot_list, length);
+		return;
+	}
+
+	for (elem = 0;
+	    (conf = fdt_stringlist_get(blob, chosen_node,
+			"u-boot,spl-boot-order", elem, NULL));
+	    elem++) {
+		if (idx >= length) {
+			printf("%s: limit %d to spl_boot_list exceeded\n", __func__,
+			       length);
+			break;
+		}
+
+		/* Resolve conf item as a path in device tree */
+		node = fdt_path_offset(blob, conf);
+		if (node < 0) {
+			debug("%s: could not find %s in FDT\n", __func__, conf);
+			continue;
+		}
+
+		/* Try to map spl node back onto SPL boot devices */
+		boot_device = spl_node_to_boot_device(node);
+		if (boot_device < 0) {
+			debug("%s: could not map node @%x to a boot-device\n",
+			      __func__, node);
+			continue;
+		}
+
+		spl_boot_list[idx] = boot_device;
+		debug("%s: spl_boot_list[%d] = %u\n", __func__, idx,
+		      spl_boot_list[idx]);
+		idx++;
+	}
+
+	if (idx == 0) {
+		if (!conf && !elem) {
+			printf("%s: spl-boot-order invalid, using default\n", __func__);
+			default_spl_boot_list(spl_boot_list, length);
+		} else {
+			printf("%s: no valid element spl-boot-order list\n", __func__);
+		}
+	}
+}
diff --git a/arch/arm/mach-socfpga/u-boot-spl-soc64.lds b/arch/arm/mach-socfpga/u-boot-spl-soc64.lds
new file mode 100644
index 0000000000..8beef91d17
--- /dev/null
+++ b/arch/arm/mach-socfpga/u-boot-spl-soc64.lds
@@ -0,0 +1,93 @@
+/*
+ * (C) Copyright 2018
+ * Intel Corporation <www.intel.com>
+ *
+ * (C) Copyright 2013
+ * David Feng <fenghua at phytium.com.cn>
+ *
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <garyj at denx.de>
+ *
+ * (C) Copyright 2010
+ * Texas Instruments, <www.ti.com>
+ *	Aneesh V <aneesh at ti.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+MEMORY { .sram : ORIGIN = CONFIG_SPL_TEXT_BASE,
+		LENGTH = CONFIG_SPL_MAX_SIZE }
+MEMORY { .sdram : ORIGIN = CONFIG_SPL_BSS_START_ADDR,
+		LENGTH = CONFIG_SPL_BSS_MAX_SIZE }
+
+OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
+OUTPUT_ARCH(aarch64)
+ENTRY(_start)
+SECTIONS
+{
+	.text : {
+		. = ALIGN(8);
+		__image_copy_start = .;
+		CPUDIR/start.o (.text*)
+		*(.text*)
+	} >.sram
+
+	.rodata : {
+		. = ALIGN(8);
+		*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
+	} >.sram
+
+	.data : {
+		. = ALIGN(8);
+		/* Run time .data section starting at this location */
+		__data_start = .;
+		*(.data*)
+		/* Run time .data section ending at this location */
+		__data_end = .;
+	} >.sram
+
+	. = ALIGN(8);
+	/* Preserve original .data section starting at this location */
+	__preserve_data_start = .;
+	. = __preserve_data_start + (__data_end - __data_start);
+	/* Preserve original .data section ending at this location */
+	__preserve_data_end = .;
+
+	. = ALIGN(8);
+	__u_boot_list . : {
+		KEEP(*(SORT(__u_boot_list*)));
+	} >.sram
+
+	.image_copy_end : {
+		. = ALIGN(8);
+		*(.__image_copy_end)
+	} >.sram
+
+	.end : {
+		. = ALIGN(8);
+		*(.__end)
+	} >.sram
+
+	_image_binary_end = .;
+
+	.bss_start (NOLOAD) : {
+		. = ALIGN(8);
+		KEEP(*(.__bss_start));
+	} >.sdram
+
+	.bss (NOLOAD) : {
+		*(.bss*)
+		 . = ALIGN(8);
+	} >.sdram
+
+	.bss_end (NOLOAD) : {
+		KEEP(*(.__bss_end));
+	} >.sdram
+
+	/DISCARD/ : { *(.dynsym) }
+	/DISCARD/ : { *(.dynstr*) }
+	/DISCARD/ : { *(.dynamic*) }
+	/DISCARD/ : { *(.plt*) }
+	/DISCARD/ : { *(.interp*) }
+	/DISCARD/ : { *(.gnu*) }
+}
diff --git a/arch/arm/mach-socfpga/wrap_handoff_soc64.c b/arch/arm/mach-socfpga/wrap_handoff_soc64.c
index e7cb5ea89c..23434dbf6c 100644
--- a/arch/arm/mach-socfpga/wrap_handoff_soc64.c
+++ b/arch/arm/mach-socfpga/wrap_handoff_soc64.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Copyright (C) 2020-2021 Intel Corporation <www.intel.com>
+ * Copyright (C) 2020-2022 Intel Corporation <www.intel.com>
  *
  */
 
@@ -19,7 +19,12 @@ static enum endianness check_endianness(u32 handoff)
 	case SOC64_HANDOFF_MAGIC_FPGA:
 	case SOC64_HANDOFF_MAGIC_DELAY:
 	case SOC64_HANDOFF_MAGIC_CLOCK:
+#if IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX5)
+	case SOC64_HANDOFF_MAGIC_PERI:
+	case SOC64_HANDOFF_MAGIC_SDRAM:
+#else
 	case SOC64_HANDOFF_MAGIC_MISC:
+#endif
 		return BIG_ENDIAN;
 #if IS_ENABLED(CONFIG_TARGET_SOCFPGA_N5X)
 	case SOC64_HANDOFF_DDR_UMCTL2_MAGIC:
-- 
2.26.2



More information about the U-Boot mailing list