diff options
Diffstat (limited to 'arch/arm/mach-socfpga')
-rw-r--r-- | arch/arm/mach-socfpga/Kconfig | 5 | ||||
-rw-r--r-- | arch/arm/mach-socfpga/Makefile | 8 | ||||
-rw-r--r-- | arch/arm/mach-socfpga/altera-sysmgr.c | 113 | ||||
-rw-r--r-- | arch/arm/mach-socfpga/board.c | 33 | ||||
-rw-r--r-- | arch/arm/mach-socfpga/ccu_ncore3.c | 64 | ||||
-rw-r--r-- | arch/arm/mach-socfpga/include/mach/altera-sysmgr.h | 16 | ||||
-rw-r--r-- | arch/arm/mach-socfpga/include/mach/board.h | 11 | ||||
-rw-r--r-- | arch/arm/mach-socfpga/include/mach/firewall.h | 17 | ||||
-rw-r--r-- | arch/arm/mach-socfpga/include/mach/handoff_soc64.h | 5 | ||||
-rw-r--r-- | arch/arm/mach-socfpga/include/mach/misc.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-socfpga/include/mach/reset_manager_soc64.h | 9 | ||||
-rw-r--r-- | arch/arm/mach-socfpga/include/mach/system_manager_soc64.h | 128 | ||||
-rw-r--r-- | arch/arm/mach-socfpga/misc.c | 71 | ||||
-rw-r--r-- | arch/arm/mach-socfpga/misc_soc64.c | 32 | ||||
-rw-r--r-- | arch/arm/mach-socfpga/smc_api.c | 12 | ||||
-rw-r--r-- | arch/arm/mach-socfpga/spl_agilex5.c | 110 | ||||
-rw-r--r-- | arch/arm/mach-socfpga/spl_soc64.c | 119 | ||||
-rw-r--r-- | arch/arm/mach-socfpga/wrap_handoff_soc64.c | 9 |
18 files changed, 672 insertions, 92 deletions
diff --git a/arch/arm/mach-socfpga/Kconfig b/arch/arm/mach-socfpga/Kconfig index 6b6a162f568..a76a9fb2a39 100644 --- a/arch/arm/mach-socfpga/Kconfig +++ b/arch/arm/mach-socfpga/Kconfig @@ -55,6 +55,7 @@ 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 @@ -64,7 +65,6 @@ config TARGET_SOCFPGA_AGILEX5 select BINMAN if SPL_ATF select CLK select FPGA_INTEL_SDM_MAILBOX - select GICV3 select SPL_CLK if SPL select TARGET_SOCFPGA_SOC64 @@ -74,6 +74,7 @@ config TARGET_SOCFPGA_ARRIA5 config TARGET_SOCFPGA_ARRIA10 bool + select GICV2 select SPL_ALTERA_SDRAM select SPL_BOARD_INIT if SPL select SPL_CACHE if SPL @@ -118,6 +119,7 @@ config TARGET_SOCFPGA_N5X select ARMV8_SET_SMPEN select BINMAN if SPL_ATF select CLK + select GICV2 select FPGA_INTEL_SDM_MAILBOX select NCORE_CACHE select SPL_ALTERA_SDRAM @@ -137,6 +139,7 @@ config TARGET_SOCFPGA_STRATIX10 select ARMV8_SET_SMPEN select BINMAN if SPL_ATF select FPGA_INTEL_SDM_MAILBOX + select GICV2 select TARGET_SOCFPGA_SOC64 choice diff --git a/arch/arm/mach-socfpga/Makefile b/arch/arm/mach-socfpga/Makefile index 5fc61b4a5c6..22d48dfae1c 100644 --- a/arch/arm/mach-socfpga/Makefile +++ b/arch/arm/mach-socfpga/Makefile @@ -3,7 +3,7 @@ # (C) Copyright 2000-2003 # Wolfgang Denk, DENX Software Engineering, wd@denx.de. # -# Copyright (C) 2012-2017 Altera Corporation <www.altera.com> +# Copyright (C) 2012-2025 Altera Corporation <www.altera.com> # Copyright (C) 2017-2024 Intel Corporation <www.intel.com> obj-y += board.o @@ -62,7 +62,12 @@ obj-y += mailbox_s10.o obj-y += misc_soc64.o obj-y += mmu-arm64_s10.o obj-y += reset_manager_s10.o +obj-y += wrap_handoff_soc64.o obj-y += wrap_pll_config_soc64.o +obj-y += altera-sysmgr.o +obj-y += ccu_ncore3.o +obj-y += system_manager_soc64.o +obj-y += timer_s10.o endif ifdef CONFIG_TARGET_SOCFPGA_N5X @@ -106,6 +111,7 @@ obj-y += spl_n5x.o endif ifdef CONFIG_TARGET_SOCFPGA_AGILEX5 obj-y += spl_soc64.o +obj-y += spl_agilex5.o endif else obj-$(CONFIG_SPL_ATF) += secure_reg_helper.o diff --git a/arch/arm/mach-socfpga/altera-sysmgr.c b/arch/arm/mach-socfpga/altera-sysmgr.c new file mode 100644 index 00000000000..ca3f5ca7dd5 --- /dev/null +++ b/arch/arm/mach-socfpga/altera-sysmgr.c @@ -0,0 +1,113 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2025 Altera Corporation <www.altera.com> + */ + +/* + * This driver supports the SOCFPGA System Manager Register block which + * aggregates different peripheral function into one area. + * On 64 bit ARM parts, the system manager only can be accessed during + * EL3 mode. At lower exception level a SMC call is required to perform + * the read and write operation. + */ + +#define LOG_CATEGORY UCLASS_NOP + +#include <dm.h> +#include <log.h> +#include <misc.h> +#include <asm/io.h> +#include <asm/system.h> +#include <asm/arch/altera-sysmgr.h> +#include <asm/arch/smc_api.h> +#include <linux/delay.h> +#include <linux/err.h> +#include <linux/intel-smc.h> + +static int altr_sysmgr_read_generic(struct udevice *dev, u32 *addr, u32 *value) +{ + u64 args[1]; + u64 ret_arg; + int ret = 0; + + debug("%s: %s(dev=%p, addr=0x%lx):\n", __func__, + dev->name, dev, (uintptr_t)addr); + + if (current_el() == 3) { + ret_arg = readl((uintptr_t)addr); + } else { + if (!(IS_ENABLED(CONFIG_SPL_BUILD)) && IS_ENABLED(CONFIG_SPL_ATF)) { + args[0] = (u64)(uintptr_t)addr; + ret = invoke_smc(INTEL_SIP_SMC_REG_READ, args, 1, &ret_arg, 1); + } else { + pr_err("%s Failed to read system manager at lower privilege and without BL31\n", + dev->name); + return -EPROTONOSUPPORT; + } + } + + *value = (u32)ret_arg; + return ret; +} + +static int altr_sysmgr_write_generic(struct udevice *dev, u32 *addr, u32 value) +{ + u64 args[2]; + int ret = 0; + + debug("%s: %s(dev=%p, addr=0x%lx, val=0x%x):\n", __func__, + dev->name, dev, (uintptr_t)addr, value); + + if (current_el() == 3) { + writel(value, (uintptr_t)addr); + } else { + if (!(IS_ENABLED(CONFIG_SPL_BUILD)) && IS_ENABLED(CONFIG_SPL_ATF)) { + args[0] = (u64)(uintptr_t)(addr); + args[1] = value; + ret = invoke_smc(INTEL_SIP_SMC_REG_WRITE, args, 2, NULL, 0); + } else { + pr_err("%s Failed to write to system manager at lower privilege and without BL31\n", + dev->name); + return -EPROTONOSUPPORT; + } + } + + return ret; +} + +static int altr_sysmgr_probe(struct udevice *dev) +{ + fdt_addr_t addr; + struct altr_sysmgr_priv *altr_priv = dev_get_priv(dev); + + debug("%s: %s(dev=%p):\n", __func__, dev->name, dev); + addr = dev_read_addr(dev); + if (addr == FDT_ADDR_T_NONE) { + pr_err("%s dev_read_addr() failed\n", dev->name); + return -ENODEV; + } + + altr_priv->regs = (void __iomem *)addr; + return 0; +} + +static const struct altr_sysmgr_ops sysmgr_ops = { + .read = altr_sysmgr_read_generic, + .write = altr_sysmgr_write_generic, +}; + +static const struct udevice_id altr_sysmgr_ids[] = { + { .compatible = "altr,sys-mgr-s10" }, + { .compatible = "altr,sys-mgr" }, + { }, +}; + +U_BOOT_DRIVER(altr_sysmgr) = { + .name = "altr_sysmgr", + .id = UCLASS_NOP, + .of_match = altr_sysmgr_ids, + .probe = altr_sysmgr_probe, + .ops = &sysmgr_ops, + .priv_auto = sizeof(struct altr_sysmgr_priv), + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/arch/arm/mach-socfpga/board.c b/arch/arm/mach-socfpga/board.c index 24a15f7903f..27072e53135 100644 --- a/arch/arm/mach-socfpga/board.c +++ b/arch/arm/mach-socfpga/board.c @@ -6,22 +6,24 @@ */ #include <config.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> #include <fdtdec.h> +#include <log.h> +#include <init.h> #include <hang.h> +#include <handoff.h> #include <image.h> -#include <init.h> -#include <log.h> #include <usb.h> #include <usb/dwc2_udc.h> +#include <asm/global_data.h> +#include <asm/io.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 <bloblist.h> DECLARE_GLOBAL_DATA_PTR; @@ -57,7 +59,18 @@ int board_init(void) int dram_init_banksize(void) { +#if CONFIG_IS_ENABLED(HANDOFF) && IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX5) +#ifndef CONFIG_SPL_BUILD + struct spl_handoff *ho; + + ho = bloblist_find(BLOBLISTT_U_BOOT_SPL_HANDOFF, sizeof(*ho)); + if (!ho) + return log_msg_ret("Missing SPL hand-off info", -ENOENT); + handoff_load_dram_banks(ho); +#endif +#else fdtdec_setup_memory_banksize(); +#endif /* HANDOFF && CONFIG_TARGET_SOCFPGA_AGILEX5 */ return 0; } diff --git a/arch/arm/mach-socfpga/ccu_ncore3.c b/arch/arm/mach-socfpga/ccu_ncore3.c new file mode 100644 index 00000000000..a399aedcd10 --- /dev/null +++ b/arch/arm/mach-socfpga/ccu_ncore3.c @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2025 Altera Corporation <www.altera.com> + * + */ +#include <wait_bit.h> +#include <asm/arch/base_addr_soc64.h> +#include <linux/bitfield.h> + +#define CCU_DMI0_DMIUSMCTCR SOCFPGA_CCU_ADDRESS + 0x7300 +#define CCU_DMI0_DMIUSMCMCR SOCFPGA_CCU_ADDRESS + 0x7340 +#define CCU_DMI0_DMIUSMCMAR SOCFPGA_CCU_ADDRESS + 0x7344 +#define CCU_DMI0_DMIUSMCMCR_MNTOP GENMASK(3, 0) +#define MAX_DISTRIBUTED_MEM_INTERFACE 2 +#define FLUSH_ALL_ENTRIES 0x4 +#define CCU_DMI0_DMIUSMCMCR_ARRAY_ID GENMASK(21, 16) +#define ARRAY_ID_TAG 0x0 +#define ARRAY_ID_DATA 0x1 +#define CACHE_OPERATION_DONE BIT(0) +#define TIMEOUT_200MS 200 + +int __asm_flush_l3_dcache(void) +{ + int i; + int ret = 0; + + /* Flushing all entries in CCU system memory cache */ + for (i = 0; i < MAX_DISTRIBUTED_MEM_INTERFACE; i++) { + /* + * Skipping if the system memory cache is not enabled for + * particular DMI + */ + if (!readl((uintptr_t)(CCU_DMI0_DMIUSMCTCR + (i * 0x1000)))) + continue; + + writel(FIELD_PREP(CCU_DMI0_DMIUSMCMCR_MNTOP, FLUSH_ALL_ENTRIES) | + FIELD_PREP(CCU_DMI0_DMIUSMCMCR_ARRAY_ID, ARRAY_ID_TAG), + (uintptr_t)(CCU_DMI0_DMIUSMCMCR + (i * 0x1000))); + + /* Wait for cache maintenance operation done */ + ret = wait_for_bit_le32((const void *)(uintptr_t)(CCU_DMI0_DMIUSMCMAR + + (i * 0x1000)), CACHE_OPERATION_DONE, false, TIMEOUT_200MS, + false); + if (ret) { + debug("%s: Timeout while waiting for flushing tag in DMI%d done\n", + __func__, i); + return ret; + } + + writel(FIELD_PREP(CCU_DMI0_DMIUSMCMCR_MNTOP, FLUSH_ALL_ENTRIES) | + FIELD_PREP(CCU_DMI0_DMIUSMCMCR_ARRAY_ID, ARRAY_ID_DATA), + (uintptr_t)(CCU_DMI0_DMIUSMCMCR + (i * 0x1000))); + + /* Wait for cache maintenance operation done */ + ret = wait_for_bit_le32((const void *)(uintptr_t)(CCU_DMI0_DMIUSMCMAR + + (i * 0x1000)), CACHE_OPERATION_DONE, false, TIMEOUT_200MS, + false); + if (ret) + debug("%s: Timeout waiting for flushing data in DMI%d done\n", + __func__, i); + } + + return ret; +} diff --git a/arch/arm/mach-socfpga/include/mach/altera-sysmgr.h b/arch/arm/mach-socfpga/include/mach/altera-sysmgr.h new file mode 100644 index 00000000000..8516617efe5 --- /dev/null +++ b/arch/arm/mach-socfpga/include/mach/altera-sysmgr.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2025 Altera Corporation <www.altera.com> + */ + +struct altr_sysmgr_ops { + int (*read)(struct udevice *dev, u32 *addr, u32 *value); + int (*write)(struct udevice *dev, u32 *addr, u32 value); +}; + +struct altr_sysmgr_priv { + void __iomem *regs; +}; + +#define altr_sysmgr_get_ops(dev) ((struct altr_sysmgr_ops *)(dev)->driver->ops) +#define altr_sysmgr_get_priv(dev) ((struct altr_sysmgr_priv *)(dev_get_priv(dev))) diff --git a/arch/arm/mach-socfpga/include/mach/board.h b/arch/arm/mach-socfpga/include/mach/board.h new file mode 100644 index 00000000000..2c3127e629f --- /dev/null +++ b/arch/arm/mach-socfpga/include/mach/board.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2025 Altera Corporation <www.altera.com> + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +u8 socfpga_get_board_id(void); + +#endif /* _BOARD_H_ */ diff --git a/arch/arm/mach-socfpga/include/mach/firewall.h b/arch/arm/mach-socfpga/include/mach/firewall.h index 5cb7f23f8f0..2b436b64816 100644 --- a/arch/arm/mach-socfpga/include/mach/firewall.h +++ b/arch/arm/mach-socfpga/include/mach/firewall.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 * * Copyright (C) 2017-2019 Intel Corporation <www.intel.com> + * Copyright (C) 2025 Altera Corporation <www.altera.com> * */ @@ -126,11 +127,27 @@ struct socfpga_firwall_l4_sys { #define FW_MPU_DDR_SCR_NONMPUREGION0ADDR_LIMITEXT 0x9c #define FW_MPU_DDR_SCR_NONMPUREGION0ADDR_LIMITEXT_FIELD 0xff +/* Firewall F2SDRAM DDR SCR registers */ +#define FW_F2SDRAM_DDR_SCR_EN 0x00 +#define FW_F2SDRAM_DDR_SCR_EN_SET 0x04 +#define FW_F2SDRAM_DDR_SCR_REGION0ADDR_BASE 0x10 +#define FW_F2SDRAM_DDR_SCR_REGION0ADDR_BASEEXT 0x14 +#define FW_F2SDRAM_DDR_SCR_REGION0ADDR_LIMIT 0x18 +#define FW_F2SDRAM_DDR_SCR_REGION0ADDR_LIMITEXT 0x1c + #define MPUREGION0_ENABLE BIT(0) #define NONMPUREGION0_ENABLE BIT(8) +#if IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX5) +#define FW_MPU_DDR_SCR_WRITEL(data, reg) \ + writel(data, SOCFPGA_FW_DDR_CCU_DMI0_ADDRESS + (reg)); \ + writel(data, SOCFPGA_FW_DDR_CCU_DMI1_ADDRESS + (reg)) +#define FW_F2SDRAM_DDR_SCR_WRITEL(data, reg) \ + writel(data, SOCFPGA_FW_TBU2NOC_ADDRESS + (reg)) +#else #define FW_MPU_DDR_SCR_WRITEL(data, reg) \ writel(data, SOCFPGA_FW_MPU_DDR_SCR_ADDRESS + (reg)) +#endif void firewall_setup(void); diff --git a/arch/arm/mach-socfpga/include/mach/handoff_soc64.h b/arch/arm/mach-socfpga/include/mach/handoff_soc64.h index d839f288411..763b077d8c1 100644 --- a/arch/arm/mach-socfpga/include/mach/handoff_soc64.h +++ b/arch/arm/mach-socfpga/include/mach/handoff_soc64.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 * * Copyright (C) 2016-2024 Intel Corporation <www.intel.com> + * Copyright (C) 2025 Altera Corporation <www.altera.com> * */ @@ -17,9 +18,9 @@ #define SOC64_HANDOFF_MAGIC_FPGA 0x46504741 #define SOC64_HANDOFF_MAGIC_DELAY 0x444C4159 #define SOC64_HANDOFF_MAGIC_CLOCK 0x434C4B53 +#define SOC64_HANDOFF_MAGIC_SDRAM 0x5344524d #if IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX5) #define SOC64_HANDOFF_MAGIC_PERI 0x50455249 -#define SOC64_HANDOFF_MAGIC_SDRAM 0x5344524d #else #define SOC64_HANDOFF_MAGIC_MISC 0x4D495343 #endif @@ -68,7 +69,7 @@ #if IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX5) #define SOC64_HANDOFF_PERI (SOC64_HANDOFF_BASE + 0x620) #define SOC64_HANDOFF_SDRAM (SOC64_HANDOFF_BASE + 0x634) -#define SOC64_HANDOFF_SDRAM_LEN 1 +#define SOC64_HANDOFF_SDRAM_LEN 5 #endif #if IS_ENABLED(CONFIG_TARGET_SOCFPGA_STRATIX10) diff --git a/arch/arm/mach-socfpga/include/mach/misc.h b/arch/arm/mach-socfpga/include/mach/misc.h index 8460acb00d9..ab46415168f 100644 --- a/arch/arm/mach-socfpga/include/mach/misc.h +++ b/arch/arm/mach-socfpga/include/mach/misc.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 2016-2021 Intel Corporation + * Copyright (C) 2025 Altera Corporation <www.altera.com> */ #ifndef _SOCFPGA_MISC_H_ @@ -51,6 +52,7 @@ bool is_periph_program_force(void); void set_regular_boot(unsigned int status); void socfpga_pl310_clear(void); void socfpga_get_managers_addr(void); +void socfpga_get_sys_mgr_addr(const char *compat); int qspi_flash_software_reset(void); #endif /* _SOCFPGA_MISC_H_ */ diff --git a/arch/arm/mach-socfpga/include/mach/reset_manager_soc64.h b/arch/arm/mach-socfpga/include/mach/reset_manager_soc64.h index c8bb727aa2b..058fdd6e548 100644 --- a/arch/arm/mach-socfpga/include/mach/reset_manager_soc64.h +++ b/arch/arm/mach-socfpga/include/mach/reset_manager_soc64.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 2016-2019 Intel Corporation <www.intel.com> + * Copyright (C) 2025 Altera Corporation <www.altera.com> */ #ifndef _RESET_MANAGER_SOC64_H_ @@ -23,14 +24,20 @@ void socfpga_bridges_reset(int enable); #define RSTMGR_BRGMODRST_FPGA2SOC_MASK 0x00000004 /* SDM, Watchdogs and MPU warm reset mask */ -#define RSTMGR_STAT_SDMWARMRST BIT(1) +#define RSTMGR_STAT_SDMWARMRST 0x2 #define RSTMGR_STAT_MPU0RST_BITPOS 8 #define RSTMGR_STAT_L4WD0RST_BITPOS 16 +#if IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX5) +#define RSTMGR_STAT_L4WD0RST_BIT 0x1F0000 +#define RSTMGR_L4WD_MPU_WARMRESET_MASK (RSTMGR_STAT_SDMWARMRST | \ + RSTMGR_STAT_L4WD0RST_BIT) +#else #define RSTMGR_L4WD_MPU_WARMRESET_MASK (RSTMGR_STAT_SDMWARMRST | \ GENMASK(RSTMGR_STAT_MPU0RST_BITPOS + 3, \ RSTMGR_STAT_MPU0RST_BITPOS) | \ GENMASK(RSTMGR_STAT_L4WD0RST_BITPOS + 3, \ RSTMGR_STAT_L4WD0RST_BITPOS)) +#endif /* * SocFPGA Stratix10 reset IDs, bank mapping is as follows: diff --git a/arch/arm/mach-socfpga/include/mach/system_manager_soc64.h b/arch/arm/mach-socfpga/include/mach/system_manager_soc64.h index 78eff247978..c2ca0a50e35 100644 --- a/arch/arm/mach-socfpga/include/mach/system_manager_soc64.h +++ b/arch/arm/mach-socfpga/include/mach/system_manager_soc64.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 2019-2021 Intel Corporation <www.intel.com> + * Copyright (C) 2025 Altera Corporation <www.altera.com> */ #ifndef _SYSTEM_MANAGER_SOC64_H_ @@ -11,22 +12,43 @@ void sysmgr_pinmux_init(void); void populate_sysmgr_fpgaintf_module(void); void populate_sysmgr_pinmux(void); -#define SYSMGR_SOC64_WDDBG 0x08 -#define SYSMGR_SOC64_DMA 0x20 -#define SYSMGR_SOC64_DMA_PERIPH 0x24 -#define SYSMGR_SOC64_SDMMC 0x28 -#define SYSMGR_SOC64_SDMMC_L3MASTER 0x2c -#define SYSMGR_SOC64_EMAC_GLOBAL 0x40 -#define SYSMGR_SOC64_EMAC0 0x44 -#define SYSMGR_SOC64_EMAC1 0x48 -#define SYSMGR_SOC64_EMAC2 0x4c -#define SYSMGR_SOC64_EMAC0_ACE 0x50 -#define SYSMGR_SOC64_EMAC1_ACE 0x54 -#define SYSMGR_SOC64_EMAC2_ACE 0x58 +#if IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX5) +#define SYSMGR_SOC64_SILICONID_1 0x00 +#define SYSMGR_SOC64_SILICONID_2 0x04 +#define SYSMGR_SOC64_MPU_STATUS 0x10 +#define SYSMGR_SOC64_COMBOPHY_DFISEL 0xfc +#define SYSMGR_SOC64_COMBOPHY_DFISEL_SDMMC 0x1 +#define SYSMGR_SOC64_NANDGRP_L3MASTER 0x34 +#define SYSMGR_SOC64_USB0_L3MASTER 0x38 +#define SYSMGR_SOC64_USB1_L3MASTER 0x3c +#define SYSMGR_SOC64_DMAC0_L3_MASTER 0x74 +#define SYSMGR_SOC64_ETR_L3_MASTER 0x78 +#define SYSMGR_SOC64_DMAC1_L3_MASTER 0x7C +#define SYSMGR_SOC64_SEC_CTRL_SLT 0x80 +#define SYSMGR_SOC64_OSC_TRIM 0x84 +#define SYSMGR_SOC64_DMAC0_CTRL_STATUS_REG 0x88 +#define SYSMGR_SOC64_DMAC1_CTRL_STATUS_REG 0x8C +#define SYSMGR_SOC64_ECC_INTMASK_VALUE 0x90 +#define SYSMGR_SOC64_ECC_INTMASK_SET 0x94 +#define SYSMGR_SOC64_ECC_INTMASK_CLR 0x98 +#define SYSMGR_SOC64_ECC_INTMASK_SERR 0x9C +#define SYSMGR_SOC64_ECC_INTMASK_DERR 0xA0 +#define SYSMGR_SOC64_MPFE_CONFIG 0x228 +#define SYSMGR_SOC64_BOOT_SCRATCH_POR0 0x258 +#define SYSMGR_SOC64_BOOT_SCRATCH_POR1 0x25C +#define SYSMGR_SCRATCH_REG_0_QSPI_REFCLK_MASK GENMASK(31, 0) +#define ALT_SYSMGR_SCRATCH_REG_3_DDR_RESET_TYPE_MASK GENMASK(31, 29) +#define ALT_SYSMGR_SCRATCH_REG_3_DDR_RESET_TYPE_SHIFT 29 +#define ALT_SYSMGR_SCRATCH_REG_3_DDR_PORT_INFO_MASK BIT(27) +#define ALT_SYSMGR_SCRATCH_REG_3_DDR_EMIF_INFO_MASK BIT(28) +#define ALT_SYSMGR_SCRATCH_REG_3_DDR_PORT_EMIF_INFO_MASK GENMASK(28, 27) +#define ALT_SYSMGR_SCRATCH_REG_3_DDR_DBE_MASK BIT(1) +#define ALT_SYSMGR_SCRATCH_REG_3_OCRAM_DBE_MASK BIT(0) +#define ALT_SYSMGR_SCRATCH_REG_POR_0_DDR_PROGRESS_MASK BIT(0) +#define ALT_SYSMGR_SCRATCH_REG_POR_1_REVA_WORKAROUND_USER_MODE_MASK BIT(0) +#define ALT_SYSMGR_SCRATCH_REG_POR_1_REVA_WORKAROUND_MASK BIT(1) +#else #define SYSMGR_SOC64_NAND_AXUSER 0x5c -#define SYSMGR_SOC64_FPGAINTF_EN1 0x68 -#define SYSMGR_SOC64_FPGAINTF_EN2 0x6c -#define SYSMGR_SOC64_FPGAINTF_EN3 0x70 #define SYSMGR_SOC64_DMA_L3MASTER 0x74 #if IS_ENABLED(CONFIG_TARGET_SOCFPGA_N5X) #define SYSMGR_SOC64_DDR_MODE 0xb8 @@ -34,39 +56,56 @@ void populate_sysmgr_pinmux(void); #define SYSMGR_SOC64_HMC_CLK 0xb4 #define SYSMGR_SOC64_IO_PA_CTRL 0xb8 #endif -#define SYSMGR_SOC64_NOC_TIMEOUT 0xc0 -#define SYSMGR_SOC64_NOC_IDLEREQ_SET 0xc4 -#define SYSMGR_SOC64_NOC_IDLEREQ_CLR 0xc8 -#define SYSMGR_SOC64_NOC_IDLEREQ_VAL 0xcc -#define SYSMGR_SOC64_NOC_IDLEACK 0xd0 -#define SYSMGR_SOC64_NOC_IDLESTATUS 0xd4 -#define SYSMGR_SOC64_FPGA2SOC_CTRL 0xd8 -#define SYSMGR_SOC64_FPGA_CONFIG 0xdc #define SYSMGR_SOC64_IOCSRCLK_GATE 0xe0 #define SYSMGR_SOC64_GPO 0xe4 #define SYSMGR_SOC64_GPI 0xe8 #define SYSMGR_SOC64_MPU 0xf0 -/* - * Bits[31:28] reserved for N5X DDR retention, bits[27:0] reserved for SOC 64-bit - * storing qspi ref clock (kHz) - */ -#define SYSMGR_SOC64_BOOT_SCRATCH_COLD0 0x200 -/* store osc1 clock freq */ -#define SYSMGR_SOC64_BOOT_SCRATCH_COLD1 0x204 -/* store fpga clock freq */ -#define SYSMGR_SOC64_BOOT_SCRATCH_COLD2 0x208 -/* reserved for customer use */ -#define SYSMGR_SOC64_BOOT_SCRATCH_COLD3 0x20c -/* store PSCI_CPU_ON value */ -#define SYSMGR_SOC64_BOOT_SCRATCH_COLD4 0x210 -/* store PSCI_CPU_ON value */ -#define SYSMGR_SOC64_BOOT_SCRATCH_COLD5 0x214 -/* store VBAR_EL3 value */ -#define SYSMGR_SOC64_BOOT_SCRATCH_COLD6 0x218 -/* store VBAR_EL3 value */ -#define SYSMGR_SOC64_BOOT_SCRATCH_COLD7 0x21c -#define SYSMGR_SOC64_BOOT_SCRATCH_COLD8 0x220 -#define SYSMGR_SOC64_BOOT_SCRATCH_COLD9 0x224 +#define SYSMGR_SCRATCH_REG_0_QSPI_REFCLK_MASK GENMASK(27, 0) +#endif /*CONFIG_TARGET_SOCFPGA_AGILEX5*/ + +#define SYSMGR_SOC64_DMA 0x20 +#define SYSMGR_SOC64_DMA_PERIPH 0x24 +#define SYSMGR_SOC64_WDDBG 0x08 +#define SYSMGR_SOC64_SDMMC 0x28 +#define SYSMGR_SOC64_SDMMC_L3MASTER 0x2C +#define SYSMGR_SOC64_FPGAINTF_EN1 0x68 +#define SYSMGR_SOC64_FPGAINTF_EN2 0x6C +#define SYSMGR_SOC64_FPGAINTF_EN3 0x70 +#define SYSMGR_SOC64_NOC_TIMEOUT 0xC0 +#define SYSMGR_SOC64_NOC_IDLEREQ_SET 0xC4 +#define SYSMGR_SOC64_NOC_IDLEREQ_CLR 0xC8 +#define SYSMGR_SOC64_NOC_IDLEREQ_VAL 0xCC +#define SYSMGR_SOC64_NOC_IDLEACK 0xd0 +#define SYSMGR_SOC64_NOC_IDLESTATUS 0xD4 +#define SYSMGR_SOC64_FPGA2SOC_CTRL 0xD8 +#define SYSMGR_SOC64_FPGA_CONFIG 0xDC + +#define SYSMGR_SOC64_TSN_GLOBAL 0x40 +#define SYSMGR_SOC64_TSN_0 0x44 +#define SYSMGR_SOC64_TSN_1 0x48 +#define SYSMGR_SOC64_TSN_2 0x4C +#define SYSMGR_SOC64_TSN_0_ACE 0x50 +#define SYSMGR_SOC64_TSN_1_ACE 0x54 +#define SYSMGR_SOC64_TSN_2_ACE 0x58 +#define SYSMGR_SOC64_EMAC_GLOBAL SYSMGR_SOC64_TSN_GLOBAL +#define SYSMGR_SOC64_EMAC0 SYSMGR_SOC64_TSN_0 +#define SYSMGR_SOC64_EMAC1 SYSMGR_SOC64_TSN_1 +#define SYSMGR_SOC64_EMAC2 SYSMGR_SOC64_TSN_2 +#define SYSMGR_SOC64_EMAC0_ACE SYSMGR_SOC64_TSN_0_ACE +#define SYSMGR_SOC64_EMAC1_ACE SYSMGR_SOC64_TSN_1_ACE +#define SYSMGR_SOC64_EMAC2_ACE SYSMGR_SOC64_TSN_2_ACE + +#define SYSMGR_SOC64_BOOT_SCRATCH_COLD0 0x200 +#define SYSMGR_SOC64_BOOT_SCRATCH_COLD1 0x204 +#define SYSMGR_SOC64_BOOT_SCRATCH_COLD2 0x208 +#define SYSMGR_SOC64_BOOT_SCRATCH_COLD3 0x20C +#define SYSMGR_SOC64_BOOT_SCRATCH_COLD4 0x210 +#define SYSMGR_SOC64_BOOT_SCRATCH_COLD5 0x214 +#define SYSMGR_SOC64_BOOT_SCRATCH_COLD6 0x218 +#define SYSMGR_SOC64_BOOT_SCRATCH_COLD7 0x21C +#define SYSMGR_SOC64_BOOT_SCRATCH_COLD8 0x220 +#define SYSMGR_SOC64_BOOT_SCRATCH_COLD9 0x224 + #define SYSMGR_SOC64_PINSEL0 0x1000 #define SYSMGR_SOC64_IOCTRL0 0x1130 #define SYSMGR_SOC64_EMAC0_USEFPGA 0x1300 @@ -97,7 +136,6 @@ void populate_sysmgr_pinmux(void); * Bits[31:28] reserved for DM DDR retention, bits[27:0] reserved for SOC 64-bit * storing qspi ref clock (kHz) */ -#define SYSMGR_SCRATCH_REG_0_QSPI_REFCLK_MASK GENMASK(27, 0) #define ALT_SYSMGR_SCRATCH_REG_0_DDR_RETENTION_MASK BIT(31) #define ALT_SYSMGR_SCRATCH_REG_0_DDR_SHA_MASK BIT(30) #define ALT_SYSMGR_SCRATCH_REG_0_DDR_RESET_TYPE_MASK (BIT(29) | BIT(28)) diff --git a/arch/arm/mach-socfpga/misc.c b/arch/arm/mach-socfpga/misc.c index 46f9c82bbb2..97e01140513 100644 --- a/arch/arm/mach-socfpga/misc.c +++ b/arch/arm/mach-socfpga/misc.c @@ -1,31 +1,33 @@ // SPDX-License-Identifier: GPL-2.0+ /* - * Copyright (C) 2012-2017 Altera Corporation <www.altera.com> + * Copyright (C) 2012-2025 Altera Corporation <www.altera.com> */ #include <config.h> #include <command.h> -#include <cpu_func.h> -#include <hang.h> -#include <asm/cache.h> -#include <init.h> -#include <asm/global_data.h> -#include <asm/io.h> #include <errno.h> +#include <init.h> +#include <handoff.h> +#include <hang.h> +#include <watchdog.h> #include <fdtdec.h> #include <linux/libfdt.h> -#include <altera.h> +#include <linux/printk.h> #include <miiphy.h> #include <netdev.h> -#include <watchdog.h> +#include <asm/global_data.h> +#include <asm/io.h> +#include <asm/cache.h> +#include <asm/pl310.h> #include <asm/arch/misc.h> +#include <asm/arch/nic301.h> #include <asm/arch/reset_manager.h> #include <asm/arch/scan_manager.h> -#include <asm/arch/system_manager.h> -#include <asm/arch/nic301.h> #include <asm/arch/scu.h> -#include <asm/pl310.h> -#include <linux/printk.h> +#include <asm/arch/system_manager.h> +#include <altera.h> +#include <bloblist.h> +#include <cpu_func.h> DECLARE_GLOBAL_DATA_PTR; @@ -51,8 +53,18 @@ struct bsel bsel_str[] = { int dram_init(void) { +#if CONFIG_IS_ENABLED(HANDOFF) && IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX5) + struct spl_handoff *ho; + + ho = bloblist_find(BLOBLISTT_U_BOOT_SPL_HANDOFF, sizeof(*ho)); + if (!ho) + return log_msg_ret("Missing SPL hand-off info", -ENOENT); + gd->ram_size = ho->ram_bank[0].size; + gd->ram_base = ho->ram_bank[0].start; +#else if (fdtdec_setup_mem_size_base() != 0) return -EINVAL; +#endif /* HANDOFF && CONFIG_TARGET_SOCFPGA_AGILEX5 */ return 0; } @@ -248,21 +260,32 @@ void socfpga_get_managers_addr(void) if (ret) hang(); - ret = socfpga_get_base_addr("altr,sys-mgr", &socfpga_sysmgr_base); + if (IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX)) + ret = socfpga_get_base_addr("intel,agilex-clkmgr", + &socfpga_clkmgr_base); + else if (IS_ENABLED(CONFIG_TARGET_SOCFPGA_N5X)) + ret = socfpga_get_base_addr("intel,n5x-clkmgr", + &socfpga_clkmgr_base); + else if (!IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX5)) + ret = socfpga_get_base_addr("altr,clk-mgr", + &socfpga_clkmgr_base); + if (ret) hang(); +} -#ifdef CONFIG_TARGET_SOCFPGA_AGILEX - ret = socfpga_get_base_addr("intel,agilex-clkmgr", - &socfpga_clkmgr_base); -#elif IS_ENABLED(CONFIG_TARGET_SOCFPGA_N5X) - ret = socfpga_get_base_addr("intel,n5x-clkmgr", - &socfpga_clkmgr_base); -#else - ret = socfpga_get_base_addr("altr,clk-mgr", &socfpga_clkmgr_base); -#endif - if (ret) +void socfpga_get_sys_mgr_addr(const char *compat) +{ + int ret; + struct udevice *sysmgr_dev; + + ret = uclass_get_device_by_name(UCLASS_NOP, compat, &sysmgr_dev); + if (ret) { + printf("Altera system manager init failed: %d\n", ret); hang(); + } else { + socfpga_sysmgr_base = (phys_addr_t)dev_read_addr(sysmgr_dev); + } } phys_addr_t socfpga_get_rstmgr_addr(void) diff --git a/arch/arm/mach-socfpga/misc_soc64.c b/arch/arm/mach-socfpga/misc_soc64.c index a6cc78454da..e0b2b4237e1 100644 --- a/arch/arm/mach-socfpga/misc_soc64.c +++ b/arch/arm/mach-socfpga/misc_soc64.c @@ -1,20 +1,23 @@ // SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2016-2018 Intel Corporation <www.intel.com> + * Copyright (C) 2025 Altera Corporation <www.altera.com> * */ #include <altera.h> +#include <env.h> +#include <errno.h> +#include <init.h> +#include <log.h> +#include <asm/arch/board.h> #include <asm/arch/mailbox_s10.h> #include <asm/arch/misc.h> #include <asm/arch/reset_manager.h> #include <asm/arch/system_manager.h> #include <asm/io.h> +#include <asm/system.h> #include <asm/global_data.h> -#include <env.h> -#include <errno.h> -#include <init.h> -#include <log.h> #include <mach/clock_manager.h> DECLARE_GLOBAL_DATA_PTR; @@ -40,12 +43,26 @@ static Altera_desc altera_fpga[] = { }; /* + * The Agilex5 platform has enabled the bloblist feature, and the bloblist + * address and size are initialized based on the defconfig settings. + * During the SPL phase, this function is used to prevent the bloblist + * from initializing its address and size with the saved boot parameters, + * which may have been incorrectly set. + */ +void save_boot_params(unsigned long r0, unsigned long r1, unsigned long r2, + unsigned long r3) +{ + save_boot_params_ret(); +} + +/* * Print CPU information */ #if defined(CONFIG_DISPLAY_CPUINFO) int print_cpuinfo(void) { - puts("CPU: Intel FPGA SoCFPGA Platform (ARMv8 64bit Cortex-A53)\n"); + printf("CPU: Intel FPGA SoCFPGA Platform (ARMv8 64bit Cortex-%s)\n", + IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX5) ? "A55/A76" : "A53"); return 0; } @@ -55,10 +72,15 @@ int print_cpuinfo(void) int arch_misc_init(void) { char qspi_string[13]; + unsigned long id; sprintf(qspi_string, "<0x%08x>", cm_get_qspi_controller_clk_hz()); env_set("qspi_clock", qspi_string); + /* Export board_id as environment variable */ + id = socfpga_get_board_id(); + env_set_ulong("board_id", id); + return 0; } #endif diff --git a/arch/arm/mach-socfpga/smc_api.c b/arch/arm/mach-socfpga/smc_api.c index ebaa0b8fa17..b212a94b321 100644 --- a/arch/arm/mach-socfpga/smc_api.c +++ b/arch/arm/mach-socfpga/smc_api.c @@ -1,9 +1,11 @@ // SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2020 Intel Corporation <www.intel.com> + * Copyright (C) 2025 Altera Corporation <www.altera.com> * */ +#include <cpu_func.h> #include <asm/ptrace.h> #include <asm/system.h> #include <linux/errno.h> @@ -40,10 +42,16 @@ int smc_send_mailbox(u32 cmd, u32 len, u32 *arg, u8 urgent, u32 *resp_buf_len, args[2] = len; args[3] = urgent; args[4] = (u64)resp_buf; - if (resp_buf_len) + + if (arg && len > 0) + flush_dcache_range((uintptr_t)arg, (uintptr_t)arg + len); + + if (resp_buf && resp_buf_len && *resp_buf_len > 0) { args[5] = *resp_buf_len; - else + flush_dcache_range((uintptr_t)resp_buf, (uintptr_t)resp_buf + *resp_buf_len); + } else { args[5] = 0; + } ret = invoke_smc(INTEL_SIP_SMC_MBOX_SEND_CMD, args, ARRAY_SIZE(args), resp, ARRAY_SIZE(resp)); diff --git a/arch/arm/mach-socfpga/spl_agilex5.c b/arch/arm/mach-socfpga/spl_agilex5.c new file mode 100644 index 00000000000..3451611082d --- /dev/null +++ b/arch/arm/mach-socfpga/spl_agilex5.c @@ -0,0 +1,110 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2024 Intel Corporation <www.intel.com> + * Copyright (C) 2025 Altera Corporation <www.altera.com> + * + */ + +#include <init.h> +#include <asm/global_data.h> +#include <asm/io.h> +#include <hang.h> +#include <spl.h> +#include <asm/arch/base_addr_soc64.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/system_manager.h> +#include <wdt.h> +#include <dm/uclass.h> + +DECLARE_GLOBAL_DATA_PTR; + +u32 reset_flag(void) +{ + /* Check rstmgr.stat for warm reset status */ + u32 status = readl(SOCFPGA_RSTMGR_ADDRESS); + + /* Check whether any L4 watchdogs or SDM had triggered warm reset */ + u32 warm_reset_mask = RSTMGR_L4WD_MPU_WARMRESET_MASK; + + if (status & warm_reset_mask) + return 0; + + return 1; +} + +void board_init_f(ulong dummy) +{ + int ret; + struct udevice *dev; + + /* Enable Async */ + asm volatile("msr daifclr, #4"); + +#ifdef CONFIG_SPL_BUILD + spl_save_restore_data(); +#endif + + ret = spl_early_init(); + if (ret) + hang(); + + socfpga_get_sys_mgr_addr("sysmgr@10d12000"); + socfpga_get_managers_addr(); + + sysmgr_pinmux_init(); + + /* 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(); + } + + /* + * 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-ccu-config", &dev); + if (ret) { + printf("HPS CCU settings init failed: %d\n", ret); + hang(); + } + + ret = uclass_get_device_by_name(UCLASS_NOP, "socfpga-firewall-config", &dev); + if (ret) { + printf("HPS firewall settings init failed: %d\n", ret); + hang(); + } + + if (IS_ENABLED(CONFIG_SPL_ALTERA_SDRAM)) { + ret = uclass_get_device(UCLASS_RAM, 0, &dev); + if (ret) { + debug("DRAM init failed: %d\n", ret); + hang(); + } + } + + mbox_init(); + + if (IS_ENABLED(CONFIG_CADENCE_QSPI)) + mbox_qspi_open(); + + /* Enable non secure access to ocram */ + clrbits_le32(SOCFPGA_OCRAM_FIREWALL_ADDRESS + 0x18, BIT(0)); +} diff --git a/arch/arm/mach-socfpga/spl_soc64.c b/arch/arm/mach-socfpga/spl_soc64.c index 4fe67ea0811..651d9fc9cb8 100644 --- a/arch/arm/mach-socfpga/spl_soc64.c +++ b/arch/arm/mach-socfpga/spl_soc64.c @@ -1,10 +1,13 @@ // SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2020 Intel Corporation. All rights reserved + * Copyright (C) 2025 Altera Corporation <www.altera.com> * */ +#include <hang.h> #include <spl.h> +#include <dm/uclass.h> DECLARE_GLOBAL_DATA_PTR; @@ -13,6 +16,109 @@ u32 spl_boot_device(void) return BOOT_DEVICE_MMC1; } +/* 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 -ENODEV; +} + +static void default_spl_boot_list(u32 *spl_boot_list, int length) +{ + spl_boot_list[0] = spl_boot_device(); + + 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__); + } + } +} + #if IS_ENABLED(CONFIG_SPL_MMC) u32 spl_boot_mode(const u32 boot_device) { @@ -22,3 +128,16 @@ u32 spl_boot_mode(const u32 boot_device) return MMCSD_MODE_RAW; } #endif + +/* board specific function prior loading SSBL / U-Boot */ +void spl_perform_fixups(struct spl_image_info *spl_image) +{ + int ret; + struct udevice *dev; + + ret = uclass_get_device_by_name(UCLASS_NOP, "socfpga-smmu-secure-config", &dev); + if (ret) { + printf("HPS SMMU secure settings init failed: %d\n", ret); + hang(); + } +} diff --git a/arch/arm/mach-socfpga/wrap_handoff_soc64.c b/arch/arm/mach-socfpga/wrap_handoff_soc64.c index 92051d19b73..7105cdc4905 100644 --- a/arch/arm/mach-socfpga/wrap_handoff_soc64.c +++ b/arch/arm/mach-socfpga/wrap_handoff_soc64.c @@ -1,15 +1,17 @@ // SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2020-2021 Intel Corporation <www.intel.com> + * Copyright (C) 2025 Altera Corporation <www.altera.com> * */ +#include <errno.h> #include <asm/arch/handoff_soc64.h> #include <asm/io.h> -#include <errno.h> #include "log.h" #ifndef __ASSEMBLY__ +#include <asm/types.h> enum endianness { LITTLE_ENDIAN = 0, BIG_ENDIAN, @@ -26,7 +28,12 @@ static enum endianness check_endianness(u32 handoff) case SOC64_HANDOFF_MAGIC_FPGA: case SOC64_HANDOFF_MAGIC_DELAY: case SOC64_HANDOFF_MAGIC_CLOCK: + case SOC64_HANDOFF_MAGIC_SDRAM: +#if IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX5) + case SOC64_HANDOFF_MAGIC_PERI: +#else case SOC64_HANDOFF_MAGIC_MISC: +#endif return BIG_ENDIAN; #if IS_ENABLED(CONFIG_TARGET_SOCFPGA_N5X) case SOC64_HANDOFF_DDR_UMCTL2_MAGIC: |