[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