feat(intel): platform enablement for Agilex5 SoC FPGA
This patch is used to enable platform enablement for
Agilex5 SoC FPGA.
New feature:
1. Added ATF->Zephyr boot option
2. Added xlat_v2 for MMU
3. Added ATF->Linux boot option
4. Added SMP support
5. Added HPS bridges support
6. Added EMULATOR support
7. Added DDR support
8. Added GICv3 Redistirbution init
9. Added SDMMC/NAND/Combo Phy support
10. Updated GIC as secure access
11. Added CCU driver support
12. Updated product name -> Agilex5
13. Updated register address based on y22ww52.2 RTL
14. Updated system counter freq to 400MHz
Signed-off-by: Jit Loon Lim <jit.loon.lim@intel.com>
Change-Id: Ice82f3e4535527cfd01500d4d528402985f72009
diff --git a/plat/intel/soc/agilex/include/socfpga_plat_def.h b/plat/intel/soc/agilex/include/socfpga_plat_def.h
index 85dfeab..a744d09 100644
--- a/plat/intel/soc/agilex/include/socfpga_plat_def.h
+++ b/plat/intel/soc/agilex/include/socfpga_plat_def.h
@@ -87,6 +87,18 @@
#define PLAT_SYS_COUNTER_FREQ_IN_TICKS (400000000)
#define PLAT_HZ_CONVERT_TO_MHZ (1000000)
+/*******************************************************************************
+ * SDMMC related pointer function
+ ******************************************************************************/
+#define SDMMC_READ_BLOCKS mmc_read_blocks
+#define SDMMC_WRITE_BLOCKS mmc_write_blocks
+
+/*******************************************************************************
+ * sysmgr.boot_scratch_cold6 & 7 (64bit) are used to indicate L2 reset
+ * is done and HPS should trigger warm reset via RMR_EL3.
+ ******************************************************************************/
+#define L2_RESET_DONE_REG 0xFFD12218
+
/* Platform specific system counter */
#define PLAT_SYS_COUNTER_FREQ_IN_MHZ get_cpu_clk()
diff --git a/plat/intel/soc/agilex5/bl2_plat_setup.c b/plat/intel/soc/agilex5/bl2_plat_setup.c
new file mode 100644
index 0000000..88f9880
--- /dev/null
+++ b/plat/intel/soc/agilex5/bl2_plat_setup.c
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2019-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <arch.h>
+#include <arch_helpers.h>
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <common/desc_image_load.h>
+#include <drivers/cadence/cdns_sdmmc.h>
+#include <drivers/generic_delay_timer.h>
+#include <drivers/synopsys/dw_mmc.h>
+#include <drivers/ti/uart/uart_16550.h>
+#include <lib/mmio.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+
+#include "agilex5_clock_manager.h"
+#include "agilex5_memory_controller.h"
+#include "agilex5_mmc.h"
+#include "agilex5_pinmux.h"
+#include "agilex5_system_manager.h"
+#include "ccu/ncore_ccu.h"
+#include "combophy/combophy.h"
+#include "nand/nand.h"
+#include "qspi/cadence_qspi.h"
+#include "sdmmc/sdmmc.h"
+#include "socfpga_emac.h"
+#include "socfpga_f2sdram_manager.h"
+#include "socfpga_handoff.h"
+#include "socfpga_mailbox.h"
+#include "socfpga_private.h"
+#include "socfpga_reset_manager.h"
+#include "wdt/watchdog.h"
+
+
+/* Declare mmc_info */
+static struct mmc_device_info mmc_info;
+
+/* Declare cadence idmac descriptor */
+extern struct cdns_idmac_desc cdns_desc[8] __aligned(32);
+
+const mmap_region_t agilex_plat_mmap[] = {
+ MAP_REGION_FLAT(DRAM_BASE, DRAM_SIZE,
+ MT_MEMORY | MT_RW | MT_NS),
+ MAP_REGION_FLAT(PSS_BASE, PSS_SIZE,
+ MT_DEVICE | MT_RW | MT_NS),
+ MAP_REGION_FLAT(MPFE_BASE, MPFE_SIZE,
+ MT_DEVICE | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(OCRAM_BASE, OCRAM_SIZE,
+ MT_NON_CACHEABLE | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(CCU_BASE, CCU_SIZE,
+ MT_DEVICE | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(MEM64_BASE, MEM64_SIZE,
+ MT_DEVICE | MT_RW | MT_NS),
+ MAP_REGION_FLAT(GIC_BASE, GIC_SIZE,
+ MT_DEVICE | MT_RW | MT_SECURE),
+ {0},
+};
+
+boot_source_type boot_source = BOOT_SOURCE;
+
+void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1,
+ u_register_t x2, u_register_t x4)
+{
+ static console_t console;
+
+ handoff reverse_handoff_ptr;
+
+ generic_delay_timer_init();
+ config_clkmgr_handoff(&reverse_handoff_ptr);
+ mailbox_init();
+ enable_nonsecure_access();
+
+ deassert_peripheral_reset();
+ if (combo_phy_init(&reverse_handoff_ptr) != 0) {
+ ERROR("Combo Phy initialization failed\n");
+ }
+
+ console_16550_register(PLAT_INTEL_UART_BASE, PLAT_UART_CLOCK,
+ PLAT_BAUDRATE, &console);
+
+ /* Store magic number */
+ mmio_write_32(L2_RESET_DONE_REG, PLAT_L2_RESET_REQ);
+}
+
+void bl2_el3_plat_arch_setup(void)
+{
+ handoff reverse_handoff_ptr;
+
+ struct cdns_sdmmc_params params = EMMC_INIT_PARAMS((uintptr_t) &cdns_desc, get_mmc_clk());
+
+ mmc_info.mmc_dev_type = MMC_DEVICE_TYPE;
+ mmc_info.ocr_voltage = OCR_3_3_3_4 | OCR_3_2_3_3;
+
+ /* Request ownership and direct access to QSPI */
+ mailbox_hps_qspi_enable();
+
+ switch (boot_source) {
+ case BOOT_SOURCE_SDMMC:
+ NOTICE("SDMMC boot\n");
+ sdmmc_init(&reverse_handoff_ptr, ¶ms, &mmc_info);
+ socfpga_io_setup(boot_source);
+ break;
+
+ case BOOT_SOURCE_QSPI:
+ NOTICE("QSPI boot\n");
+ cad_qspi_init(0, QSPI_CONFIG_CPHA, QSPI_CONFIG_CPOL,
+ QSPI_CONFIG_CSDA, QSPI_CONFIG_CSDADS,
+ QSPI_CONFIG_CSEOT, QSPI_CONFIG_CSSOT, 0);
+ socfpga_io_setup(boot_source);
+ break;
+
+ case BOOT_SOURCE_NAND:
+ NOTICE("NAND boot\n");
+ nand_init(&reverse_handoff_ptr);
+ socfpga_io_setup(boot_source);
+ break;
+
+ default:
+ ERROR("Unsupported boot source\n");
+ panic();
+ break;
+ }
+}
+
+uint32_t get_spsr_for_bl33_entry(void)
+{
+ unsigned long el_status;
+ unsigned int mode;
+ uint32_t spsr;
+
+ /* Figure out what mode we enter the non-secure world in */
+ el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT;
+ el_status &= ID_AA64PFR0_ELX_MASK;
+
+ mode = (el_status) ? MODE_EL2 : MODE_EL1;
+
+ /*
+ * TODO: Consider the possibility of specifying the SPSR in
+ * the FIP ToC and allowing the platform to have a say as
+ * well.
+ */
+ spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
+ return spsr;
+}
+
+int bl2_plat_handle_post_image_load(unsigned int image_id)
+{
+ bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id);
+
+ assert(bl_mem_params);
+
+ switch (image_id) {
+ case BL33_IMAGE_ID:
+ bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr();
+ bl_mem_params->ep_info.spsr = get_spsr_for_bl33_entry();
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+/*******************************************************************************
+ * Perform any BL3-1 platform setup code
+ ******************************************************************************/
+void bl2_platform_setup(void)
+{
+}
diff --git a/plat/intel/soc/agilex5/bl31_plat_setup.c b/plat/intel/soc/agilex5/bl31_plat_setup.c
new file mode 100644
index 0000000..5ae4bf7
--- /dev/null
+++ b/plat/intel/soc/agilex5/bl31_plat_setup.c
@@ -0,0 +1,284 @@
+/*
+ * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <arch.h>
+#include <arch_helpers.h>
+#include <common/bl_common.h>
+#include <drivers/arm/gic_common.h>
+#include <drivers/arm/gicv3.h>
+#include <drivers/ti/uart/uart_16550.h>
+#include <lib/mmio.h>
+#include <lib/xlat_tables/xlat_mmu_helpers.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <plat/common/platform.h>
+
+#include "agilex5_power_manager.h"
+#include "ccu/ncore_ccu.h"
+#include "socfpga_mailbox.h"
+#include "socfpga_private.h"
+#include "socfpga_reset_manager.h"
+
+/* Get non-secure SPSR for BL33. Zephyr and Linux */
+uint32_t arm_get_spsr_for_bl33_entry(void);
+
+static entry_point_info_t bl32_image_ep_info;
+static entry_point_info_t bl33_image_ep_info;
+
+/* The GICv3 driver only needs to be initialized in EL3 */
+static uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT];
+
+#define SMMU_SDMMC
+
+entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
+{
+ entry_point_info_t *next_image_info;
+
+ next_image_info = (type == NON_SECURE) ?
+ &bl33_image_ep_info : &bl32_image_ep_info;
+
+ /* None of the images on this platform can have 0x0 as the entrypoint */
+ if (next_image_info->pc)
+ return next_image_info;
+ else
+ return NULL;
+}
+
+void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+ u_register_t arg2, u_register_t arg3)
+{
+ static console_t console;
+
+ mmio_write_64(PLAT_SEC_ENTRY, PLAT_SEC_WARM_ENTRY);
+
+ console_16550_register(PLAT_INTEL_UART_BASE, PLAT_UART_CLOCK,
+ PLAT_BAUDRATE, &console);
+
+ init_ncore_ccu();
+ setup_smmu_stream_id();
+
+ /*
+ * Check params passed from BL31 should not be NULL,
+ */
+ void *from_bl2 = (void *) arg0;
+
+#if RESET_TO_BL31
+ /* There are no parameters from BL2 if BL31 is a reset vector */
+ assert(from_bl2 == NULL);
+ void *plat_params_from_bl2 = (void *) arg3;
+
+ assert(plat_params_from_bl2 == NULL);
+
+ /* Populate entry point information for BL33 */
+ SET_PARAM_HEAD(&bl33_image_ep_info,
+ PARAM_EP,
+ VERSION_1,
+ 0);
+
+# if ARM_LINUX_KERNEL_AS_BL33
+ /*
+ * According to the file ``Documentation/arm64/booting.txt`` of the
+ * Linux kernel tree, Linux expects the physical address of the device
+ * tree blob (DTB) in x0, while x1-x3 are reserved for future use and
+ * must be 0.
+ */
+ bl33_image_ep_info.args.arg0 = (u_register_t)ARM_PRELOADED_DTB_BASE;
+ bl33_image_ep_info.args.arg1 = 0U;
+ bl33_image_ep_info.args.arg2 = 0U;
+ bl33_image_ep_info.args.arg3 = 0U;
+# endif
+
+#else /* RESET_TO_BL31 */
+ bl_params_t *params_from_bl2 = (bl_params_t *)from_bl2;
+
+ assert(params_from_bl2 != NULL);
+
+ /*
+ * Copy BL32 (if populated by BL31) and BL33 entry point information.
+ * They are stored in Secure RAM, in BL31's address space.
+ */
+
+ if (params_from_bl2->h.type == PARAM_BL_PARAMS &&
+ params_from_bl2->h.version >= VERSION_2) {
+
+ bl_params_node_t *bl_params = params_from_bl2->head;
+
+ while (bl_params) {
+ if (bl_params->image_id == BL33_IMAGE_ID) {
+ bl33_image_ep_info = *bl_params->ep_info;
+ }
+ bl_params = bl_params->next_params_info;
+ }
+ } else {
+ struct socfpga_bl31_params *arg_from_bl2 =
+ (struct socfpga_bl31_params *) from_bl2;
+
+ assert(arg_from_bl2->h.type == PARAM_BL31);
+ assert(arg_from_bl2->h.version >= VERSION_1);
+
+ bl32_image_ep_info = *arg_from_bl2->bl32_ep_info;
+ bl33_image_ep_info = *arg_from_bl2->bl33_ep_info;
+ }
+
+ bl33_image_ep_info.args.arg0 = (u_register_t)ARM_PRELOADED_DTB_BASE;
+ bl33_image_ep_info.args.arg1 = 0U;
+ bl33_image_ep_info.args.arg2 = 0U;
+ bl33_image_ep_info.args.arg3 = 0U;
+#endif
+
+ /*
+ * Tell BL31 where the non-trusted software image
+ * is located and the entry state information
+ */
+ bl33_image_ep_info.pc = plat_get_ns_image_entrypoint();
+ bl33_image_ep_info.spsr = arm_get_spsr_for_bl33_entry();
+
+ SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
+}
+
+static const interrupt_prop_t agx5_interrupt_props[] = {
+ PLAT_INTEL_SOCFPGA_G1S_IRQ_PROPS(INTR_GROUP1S),
+ PLAT_INTEL_SOCFPGA_G0_IRQ_PROPS(INTR_GROUP0)
+};
+
+static const gicv3_driver_data_t plat_gicv3_gic_data = {
+ .gicd_base = PLAT_INTEL_SOCFPGA_GICD_BASE,
+ .gicr_base = PLAT_INTEL_SOCFPGA_GICR_BASE,
+ .interrupt_props = agx5_interrupt_props,
+ .interrupt_props_num = ARRAY_SIZE(agx5_interrupt_props),
+ .rdistif_num = PLATFORM_CORE_COUNT,
+ .rdistif_base_addrs = rdistif_base_addrs,
+};
+
+/*******************************************************************************
+ * Perform any BL3-1 platform setup code
+ ******************************************************************************/
+void bl31_platform_setup(void)
+{
+ socfpga_delay_timer_init();
+
+ /* Initialize the gic cpu and distributor interfaces */
+ gicv3_driver_init(&plat_gicv3_gic_data);
+ gicv3_distif_init();
+ gicv3_rdistif_init(plat_my_core_pos());
+ gicv3_cpuif_enable(plat_my_core_pos());
+ mailbox_hps_stage_notify(HPS_EXECUTION_STATE_SSBL);
+#if !defined(SIMICS_RUN)
+ ncore_enable_ocram_firewall();
+#endif
+
+}
+
+const mmap_region_t plat_agilex_mmap[] = {
+ MAP_REGION_FLAT(DRAM_BASE, DRAM_SIZE, MT_MEMORY | MT_RW | MT_NS),
+ MAP_REGION_FLAT(PSS_BASE, PSS_SIZE, MT_DEVICE | MT_RW | MT_NS),
+ MAP_REGION_FLAT(MPFE_BASE, MPFE_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(OCRAM_BASE, OCRAM_SIZE, MT_NON_CACHEABLE | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(CCU_BASE, CCU_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(MEM64_BASE, MEM64_SIZE, MT_DEVICE | MT_RW | MT_NS),
+ MAP_REGION_FLAT(GIC_BASE, GIC_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
+ {0}
+};
+
+/*******************************************************************************
+ * Perform the very early platform specific architectural setup here. At the
+ * moment this is only intializes the mmu in a quick and dirty way.
+ ******************************************************************************/
+void bl31_plat_arch_setup(void)
+{
+ uint32_t boot_core = 0x00;
+ uint32_t cpuid = 0x00;
+
+ cpuid = read_mpidr();
+ boot_core = (mmio_read_32(AGX5_PWRMGR(MPU_BOOTCONFIG)) & 0xC00);
+ NOTICE("BL31: Boot Core = %x\n", boot_core);
+ NOTICE("BL31: CPU ID = %x\n", cpuid);
+
+}
+
+/* Get non-secure image entrypoint for BL33. Zephyr and Linux */
+uintptr_t plat_get_ns_image_entrypoint(void)
+{
+#ifdef PRELOADED_BL33_BASE
+ return PRELOADED_BL33_BASE;
+#else
+ return PLAT_NS_IMAGE_OFFSET;
+#endif
+}
+
+/* Get non-secure SPSR for BL33. Zephyr and Linux */
+uint32_t arm_get_spsr_for_bl33_entry(void)
+{
+ unsigned int mode;
+ uint32_t spsr;
+
+ /* Figure out what mode we enter the non-secure world in */
+ mode = (el_implemented(2) != EL_IMPL_NONE) ? MODE_EL2 : MODE_EL1;
+
+ /*
+ * TODO: Consider the possibility of specifying the SPSR in
+ * the FIP ToC and allowing the platform to have a say as
+ * well.
+ */
+ spsr = SPSR_64((uint64_t)mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
+ return spsr;
+}
+
+/* SMP: Secondary cores BL31 setup reset vector */
+void bl31_plat_set_secondary_cpu_entrypoint(unsigned int cpu_id)
+{
+ unsigned int pch_cpu = 0x00;
+ unsigned int pchctlr_old = 0x00;
+ unsigned int pchctlr_new = 0x00;
+ uint32_t boot_core = 0x00;
+
+ boot_core = (mmio_read_32(AGX5_PWRMGR(MPU_BOOTCONFIG)) & 0xC00);
+ /* Update the p-channel based on cpu id */
+ pch_cpu = 1 << cpu_id;
+
+ if (boot_core == 0x00) {
+ /* Update reset vector to 0x00 */
+ mmio_write_64(RSTMGR_CPUxRESETBASELOW_CPU2,
+(uint64_t) plat_secondary_cpus_bl31_entry >> 2);
+ } else {
+ /* Update reset vector to 0x00 */
+ mmio_write_64(RSTMGR_CPUxRESETBASELOW_CPU0,
+(uint64_t) plat_secondary_cpus_bl31_entry >> 2);
+ }
+
+ /* Update reset vector to 0x00 */
+ mmio_write_64(RSTMGR_CPUxRESETBASELOW_CPU1, (uint64_t) plat_secondary_cpus_bl31_entry >> 2);
+ mmio_write_64(RSTMGR_CPUxRESETBASELOW_CPU3, (uint64_t) plat_secondary_cpus_bl31_entry >> 2);
+
+ /* On all cores - temporary */
+ pchctlr_old = mmio_read_32(AGX5_PWRMGR(MPU_PCHCTLR));
+ pchctlr_new = pchctlr_old | (pch_cpu<<1);
+ mmio_write_32(AGX5_PWRMGR(MPU_PCHCTLR), pchctlr_new);
+
+ /* We will only release the target secondary CPUs */
+ /* Bit mask for each CPU BIT0-3 */
+ mmio_write_32(RSTMGR_CPUSTRELEASE_CPUx, pch_cpu);
+}
+
+void bl31_plat_set_secondary_cpu_off(void)
+{
+ unsigned int pch_cpu = 0x00;
+ unsigned int pch_cpu_off = 0x00;
+ unsigned int cpu_id = plat_my_core_pos();
+
+ pch_cpu_off = 1 << cpu_id;
+
+ pch_cpu = mmio_read_32(AGX5_PWRMGR(MPU_PCHCTLR));
+ pch_cpu = pch_cpu & ~(pch_cpu_off << 1);
+
+ mmio_write_32(AGX5_PWRMGR(MPU_PCHCTLR), pch_cpu);
+}
+
+void bl31_plat_enable_mmu(uint32_t flags)
+{
+ /* TODO: Enable mmu when needed */
+}
diff --git a/plat/intel/soc/agilex5/include/socfpga_plat_def.h b/plat/intel/soc/agilex5/include/socfpga_plat_def.h
new file mode 100644
index 0000000..8a49d61
--- /dev/null
+++ b/plat/intel/soc/agilex5/include/socfpga_plat_def.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_SOCFPGA_DEF_H
+#define PLAT_SOCFPGA_DEF_H
+
+#include "agilex5_memory_controller.h"
+#include "agilex5_system_manager.h"
+#include <platform_def.h>
+
+/* Platform Setting */
+#define PLATFORM_MODEL PLAT_SOCFPGA_AGILEX5
+#define BOOT_SOURCE BOOT_SOURCE_SDMMC
+#define MMC_DEVICE_TYPE 1 /* MMC = 0, SD = 1 */
+#define XLAT_TABLES_V2 U(1)
+#define PLAT_PRIMARY_CPU_A55 0x000
+#define PLAT_PRIMARY_CPU_A76 0x200
+#define PLAT_CLUSTER_ID_MPIDR_AFF_SHIFT MPIDR_AFF2_SHIFT
+#define PLAT_CPU_ID_MPIDR_AFF_SHIFT MPIDR_AFF1_SHIFT
+#define PLAT_L2_RESET_REQ 0xB007C0DE
+
+/* System Counter */ /* TODO: Update back to 400MHz */
+#define PLAT_SYS_COUNTER_FREQ_IN_TICKS (80000000)
+#define PLAT_SYS_COUNTER_FREQ_IN_MHZ (80)
+
+/* FPGA config helpers */
+#define INTEL_SIP_SMC_FPGA_CONFIG_ADDR 0x400000
+#define INTEL_SIP_SMC_FPGA_CONFIG_SIZE 0x2000000
+
+/* QSPI Setting */
+#define CAD_QSPIDATA_OFST 0x10900000
+#define CAD_QSPI_OFFSET 0x108d2000
+
+/* Register Mapping */
+#define SOCFPGA_CCU_NOC_REG_BASE 0x1c000000
+#define SOCFPGA_F2SDRAMMGR_REG_BASE 0x18001000
+
+#define SOCFPGA_MMC_REG_BASE 0x10808000
+#define SOCFPGA_MEMCTRL_REG_BASE 0x108CC000
+#define SOCFPGA_RSTMGR_REG_BASE 0x10d11000
+#define SOCFPGA_SYSMGR_REG_BASE 0x10d12000
+#define SOCFPGA_PINMUX_REG_BASE 0x10d13000
+#define SOCFPGA_NAND_REG_BASE 0x10B80000
+
+#define SOCFPGA_L4_PER_SCR_REG_BASE 0x10d21000
+#define SOCFPGA_L4_SYS_SCR_REG_BASE 0x10d21100
+#define SOCFPGA_SOC2FPGA_SCR_REG_BASE 0x10d21200
+#define SOCFPGA_LWSOC2FPGA_SCR_REG_BASE 0x10d21300
+
+/* Define maximum page size for NAND flash devices */
+#define PLATFORM_MTD_MAX_PAGE_SIZE U(0x1000)
+
+/*******************************************************************************
+ * Platform memory map related constants
+ ******************************************************************************/
+#define DRAM_BASE (0x80000000)
+#define DRAM_SIZE (0x80000000)
+
+#define OCRAM_BASE (0x00000000)
+#define OCRAM_SIZE (0x00080000)
+
+#define MEM64_BASE (0x0080000000)
+#define MEM64_SIZE (0x0080000000)
+
+//128MB PSS
+#define PSS_BASE (0x10000000)
+#define PSS_SIZE (0x08000000)
+
+//64MB MPFE
+#define MPFE_BASE (0x18000000)
+#define MPFE_SIZE (0x04000000)
+
+//16MB CCU
+#define CCU_BASE (0x1C000000)
+#define CCU_SIZE (0x01000000)
+
+//1MB GIC
+#define GIC_BASE (0x1D000000)
+#define GIC_SIZE (0x00100000)
+
+#define BL2_BASE (0x00000000)
+#define BL2_LIMIT (0x0001b000)
+
+#define BL31_BASE (0x80000000)
+#define BL31_LIMIT (0x82000000)
+
+/*******************************************************************************
+ * UART related constants
+ ******************************************************************************/
+#define PLAT_UART0_BASE (0x10C02000)
+#define PLAT_UART1_BASE (0x10C02100)
+
+/*******************************************************************************
+ * GIC related constants
+ ******************************************************************************/
+#define PLAT_GIC_BASE (0x1D000000)
+#define PLAT_GICC_BASE (PLAT_GIC_BASE + 0x20000)
+#define PLAT_GICD_BASE (PLAT_GIC_BASE + 0x00000)
+#define PLAT_GICR_BASE (PLAT_GIC_BASE + 0x60000)
+
+#define PLAT_INTEL_SOCFPGA_GICR_BASE PLAT_GICR_BASE
+
+/*******************************************************************************
+ * SDMMC related pointer function
+ ******************************************************************************/
+#define SDMMC_READ_BLOCKS sdmmc_read_blocks
+#define SDMMC_WRITE_BLOCKS sdmmc_write_blocks
+
+/*******************************************************************************
+ * sysmgr.boot_scratch_cold6 & 7 (64bit) are used to indicate L2 reset
+ * is done and HPS should trigger warm reset via RMR_EL3.
+ ******************************************************************************/
+#define L2_RESET_DONE_REG 0x10D12218
+
+#endif /* PLAT_SOCFPGA_DEF_H */
diff --git a/plat/intel/soc/agilex5/platform.mk b/plat/intel/soc/agilex5/platform.mk
new file mode 100644
index 0000000..779c629
--- /dev/null
+++ b/plat/intel/soc/agilex5/platform.mk
@@ -0,0 +1,107 @@
+#
+# Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+include lib/xlat_tables_v2/xlat_tables.mk
+PLAT_INCLUDES := \
+ -Iplat/intel/soc/agilex5/include/ \
+ -Iplat/intel/soc/common/drivers/ \
+ -Iplat/intel/soc/common/include/
+
+# GIC-600 configuration
+GICV3_SUPPORT_GIC600 := 1
+# Include GICv3 driver files
+include drivers/arm/gic/v3/gicv3.mk
+AGX5_GICv3_SOURCES := \
+ ${GICV3_SOURCES} \
+ plat/common/plat_gicv3.c
+
+PLAT_BL_COMMON_SOURCES := \
+ ${AGX5_GICv3_SOURCES} \
+ drivers/cadence/combo_phy/cdns_combo_phy.c \
+ drivers/cadence/emmc/cdns_sdmmc.c \
+ drivers/cadence/nand/cdns_nand.c \
+ drivers/delay_timer/delay_timer.c \
+ drivers/delay_timer/generic_delay_timer.c \
+ drivers/ti/uart/aarch64/16550_console.S \
+ plat/intel/soc/common/aarch64/platform_common.c \
+ plat/intel/soc/common/aarch64/plat_helpers.S \
+ plat/intel/soc/common/drivers/ccu/ncore_ccu.c \
+ plat/intel/soc/common/drivers/combophy/combophy.c \
+ plat/intel/soc/common/drivers/sdmmc/sdmmc.c \
+ plat/intel/soc/common/drivers/ddr/ddr.c \
+ plat/intel/soc/common/drivers/nand/nand.c \
+ plat/intel/soc/common/socfpga_delay_timer.c
+
+BL2_SOURCES += \
+ common/desc_image_load.c \
+ lib/xlat_tables_v2/aarch64/enable_mmu.S \
+ lib/xlat_tables_v2/xlat_tables_context.c \
+ lib/xlat_tables_v2/xlat_tables_core.c \
+ lib/xlat_tables_v2/aarch64/xlat_tables_arch.c \
+ lib/xlat_tables_v2/xlat_tables_utils.c \
+ drivers/mmc/mmc.c \
+ drivers/intel/soc/stratix10/io/s10_memmap_qspi.c \
+ drivers/io/io_storage.c \
+ drivers/io/io_block.c \
+ drivers/io/io_fip.c \
+ drivers/io/io_mtd.c \
+ drivers/partition/partition.c \
+ drivers/partition/gpt.c \
+ drivers/synopsys/emmc/dw_mmc.c \
+ lib/cpus/aarch64/cortex_a55.S \
+ lib/cpus/aarch64/cortex_a76.S \
+ plat/intel/soc/agilex5/soc/agilex5_clock_manager.c \
+ plat/intel/soc/agilex5/soc/agilex5_memory_controller.c \
+ plat/intel/soc/agilex5/soc/agilex5_mmc.c \
+ plat/intel/soc/agilex5/soc/agilex5_pinmux.c \
+ plat/intel/soc/agilex5/soc/agilex5_power_manager.c \
+ plat/intel/soc/common/bl2_plat_mem_params_desc.c \
+ plat/intel/soc/common/socfpga_image_load.c \
+ plat/intel/soc/common/socfpga_storage.c \
+ plat/intel/soc/common/socfpga_vab.c \
+ plat/intel/soc/common/soc/socfpga_emac.c \
+ plat/intel/soc/common/soc/socfpga_firewall.c \
+ plat/intel/soc/common/soc/socfpga_handoff.c \
+ plat/intel/soc/common/soc/socfpga_mailbox.c \
+ plat/intel/soc/common/soc/socfpga_reset_manager.c \
+ plat/intel/soc/common/drivers/qspi/cadence_qspi.c \
+ plat/intel/soc/agilex5/bl2_plat_setup.c \
+ plat/intel/soc/common/drivers/wdt/watchdog.c
+
+include lib/zlib/zlib.mk
+PLAT_INCLUDES += -Ilib/zlib
+BL2_SOURCES += $(ZLIB_SOURCES)
+
+BL31_SOURCES += \
+ drivers/arm/cci/cci.c \
+ ${XLAT_TABLES_LIB_SRCS} \
+ lib/cpus/aarch64/aem_generic.S \
+ lib/cpus/aarch64/cortex_a55.S \
+ lib/cpus/aarch64/cortex_a76.S \
+ plat/common/plat_psci_common.c \
+ plat/intel/soc/agilex5/bl31_plat_setup.c \
+ plat/intel/soc/agilex5/soc/agilex5_power_manager.c \
+ plat/intel/soc/common/socfpga_psci.c \
+ plat/intel/soc/common/socfpga_sip_svc.c \
+ plat/intel/soc/common/socfpga_sip_svc_v2.c \
+ plat/intel/soc/common/socfpga_topology.c \
+ plat/intel/soc/common/sip/socfpga_sip_ecc.c \
+ plat/intel/soc/common/sip/socfpga_sip_fcs.c \
+ plat/intel/soc/common/soc/socfpga_mailbox.c \
+ plat/intel/soc/common/soc/socfpga_reset_manager.c
+
+# Configs for A76 and A55
+HW_ASSISTED_COHERENCY := 1
+USE_COHERENT_MEM := 0
+CTX_INCLUDE_AARCH32_REGS := 0
+ERRATA_A55_1530923 := 1
+
+$(eval $(call add_define,ARM_PRELOADED_DTB_BASE))
+
+PROGRAMMABLE_RESET_ADDRESS := 0
+RESET_TO_BL2 := 1
+BL2_INV_DCACHE := 0
+MULTI_CONSOLE_API := 1
diff --git a/plat/intel/soc/common/aarch64/plat_helpers.S b/plat/intel/soc/common/aarch64/plat_helpers.S
index 6bf2d82..cbd0121 100644
--- a/plat/intel/soc/common/aarch64/plat_helpers.S
+++ b/plat/intel/soc/common/aarch64/plat_helpers.S
@@ -34,6 +34,11 @@
func plat_secondary_cold_boot_setup
/* Wait until the it gets reset signal from rstmgr gets populated */
poll_mailbox:
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+ mov_imm x0, PLAT_SEC_ENTRY
+ cbz x0, poll_mailbox
+ br x0
+#else
wfi
mov_imm x0, PLAT_SEC_ENTRY
ldr x1, [x0]
@@ -44,8 +49,13 @@
cmp x3, x4
b.ne poll_mailbox
br x1
+#endif
endfunc plat_secondary_cold_boot_setup
+#if ((PLATFORM_MODEL == PLAT_SOCFPGA_STRATIX10) || \
+ (PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX) || \
+ (PLATFORM_MODEL == PLAT_SOCFPGA_N5X))
+
func platform_is_primary_cpu
and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
cmp x0, #PLAT_PRIMARY_CPU
@@ -53,6 +63,21 @@
ret
endfunc platform_is_primary_cpu
+#else
+
+func platform_is_primary_cpu
+ and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
+ cmp x0, #(PLAT_PRIMARY_CPU_A76)
+ b.eq primary_cpu
+ cmp x0, #(PLAT_PRIMARY_CPU_A55)
+ b.eq primary_cpu
+primary_cpu:
+ cset x0, eq
+ ret
+endfunc platform_is_primary_cpu
+
+#endif
+
func plat_is_my_cpu_primary
mrs x0, mpidr_el1
b platform_is_primary_cpu
@@ -62,11 +87,27 @@
mrs x0, mpidr_el1
and x1, x0, #MPIDR_CPU_MASK
and x0, x0, #MPIDR_CLUSTER_MASK
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+ add x0, x1, x0, LSR #8
+#else
add x0, x1, x0, LSR #6
+#endif
ret
endfunc plat_my_core_pos
func warm_reset_req
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+ bl plat_is_my_cpu_primary
+ cbnz x0, warm_reset
+warm_reset:
+ mov_imm x1, PLAT_SEC_ENTRY
+ str xzr, [x1]
+ mrs x1, rmr_el3
+ orr x1, x1, #0x02
+ msr rmr_el3, x1
+ isb
+ dsb sy
+#else
str xzr, [x4]
bl plat_is_my_cpu_primary
cbz x0, cpu_in_wfi
@@ -80,11 +121,28 @@
cpu_in_wfi:
wfi
b cpu_in_wfi
+#endif
endfunc warm_reset_req
+/* TODO: Zephyr warm reset test */
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
func plat_get_my_entrypoint
ldr x4, =L2_RESET_DONE_REG
ldr x5, [x4]
+ ldr x1, =PLAT_L2_RESET_REQ
+ cmp x1, x5
+ b.eq zephyr_reset_req
+ mov_imm x1, PLAT_SEC_ENTRY
+ ldr x0, [x1]
+ ret
+zephyr_reset_req:
+ ldr x0, =0x00
+ ret
+endfunc plat_get_my_entrypoint
+#else
+func plat_get_my_entrypoint
+ ldr x4, =L2_RESET_DONE_REG
+ ldr x5, [x4]
ldr x1, =L2_RESET_DONE_STATUS
cmp x1, x5
b.eq warm_reset_req
@@ -92,7 +150,7 @@
ldr x0, [x1]
ret
endfunc plat_get_my_entrypoint
-
+#endif
/* ---------------------------------------------
* int plat_crash_console_init(void)
@@ -138,6 +196,13 @@
ret
endfunc platform_mem_init
+ /* --------------------------------------------------------
+ * macro plat_secondary_cpus_bl31_entry;
+ *
+ * el3_entrypoint_common init param configuration.
+ * Called very early in the secondary cores boot process.
+ * --------------------------------------------------------
+ */
func plat_secondary_cpus_bl31_entry
el3_entrypoint_common \
_init_sctlr=0 \
diff --git a/plat/intel/soc/common/include/platform_def.h b/plat/intel/soc/common/include/platform_def.h
index 78deebc..49fc567 100644
--- a/plat/intel/soc/common/include/platform_def.h
+++ b/plat/intel/soc/common/include/platform_def.h
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -25,12 +25,6 @@
/* sysmgr.boot_scratch_cold4 & 5 used for CPU release address for SPL */
#define PLAT_CPU_RELEASE_ADDR 0xffd12210
-/*
- * sysmgr.boot_scratch_cold6 & 7 (64bit) are used to indicate L2 reset
- * is done and HPS should trigger warm reset via RMR_EL3.
- */
-#define L2_RESET_DONE_REG 0xFFD12218
-
/* Magic word to indicate L2 reset is completed */
#define L2_RESET_DONE_STATUS 0x1228E5E7
diff --git a/plat/intel/soc/common/include/socfpga_noc.h b/plat/intel/soc/common/include/socfpga_noc.h
index e3c0f73..3fc3f81 100644
--- a/plat/intel/soc/common/include/socfpga_noc.h
+++ b/plat/intel/soc/common/include/socfpga_noc.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2022, Intel Corporation. All rights reserved.
+ * Copyright (c) 2020-2023, Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -74,6 +74,10 @@
#define SOCFPGA_NOC_FW_L4_SYS_SCR_WATCHDOG2 0x0070
#define SOCFPGA_NOC_FW_L4_SYS_SCR_WATCHDOG3 0x0074
#define SOCFPGA_NOC_FW_L4_SYS_SCR_DAP 0x0078
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_WATCHDOG4 0x007c
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_PWRMGR 0x0080
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_USB1_RXECC 0x0084
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_USB1_TXECC 0x0088
#define SOCFPGA_NOC_FW_L4_SYS_SCR_L4_NOC_PROBES 0x0090
#define SOCFPGA_NOC_FW_L4_SYS_SCR_L4_NOC_QOS 0x0094
diff --git a/plat/intel/soc/common/soc/socfpga_firewall.c b/plat/intel/soc/common/soc/socfpga_firewall.c
index fc3889c..6247df3 100644
--- a/plat/intel/soc/common/soc/socfpga_firewall.c
+++ b/plat/intel/soc/common/soc/socfpga_firewall.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -20,7 +20,11 @@
void enable_ns_peripheral_access(void)
{
mmio_write_32(SOCFPGA_L4_PER_SCR(NAND_REGISTER), DISABLE_L4_FIREWALL);
+#if ((PLATFORM_MODEL == PLAT_SOCFPGA_STRATIX10) || \
+ (PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX) || \
+ (PLATFORM_MODEL == PLAT_SOCFPGA_N5X))
mmio_write_32(SOCFPGA_L4_PER_SCR(NAND_DATA), DISABLE_L4_FIREWALL);
+#endif
mmio_write_32(SOCFPGA_L4_SYS_SCR(NAND_ECC), DISABLE_L4_FIREWALL);
mmio_write_32(SOCFPGA_L4_SYS_SCR(NAND_READ_ECC), DISABLE_L4_FIREWALL);
@@ -87,9 +91,19 @@
mmio_write_32(SOCFPGA_L4_SYS_SCR(WATCHDOG1), DISABLE_L4_FIREWALL);
mmio_write_32(SOCFPGA_L4_SYS_SCR(WATCHDOG2), DISABLE_L4_FIREWALL);
mmio_write_32(SOCFPGA_L4_SYS_SCR(WATCHDOG3), DISABLE_L4_FIREWALL);
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+ mmio_write_32(SOCFPGA_L4_SYS_SCR(WATCHDOG4), DISABLE_L4_FIREWALL);
+#endif
mmio_write_32(SOCFPGA_L4_SYS_SCR(DAP), DISABLE_L4_FIREWALL);
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+ mmio_write_32(SOCFPGA_L4_SYS_SCR(PWRMGR), DISABLE_L4_FIREWALL);
+
+ mmio_write_32(SOCFPGA_L4_SYS_SCR(USB1_RXECC), DISABLE_L4_FIREWALL);
+ mmio_write_32(SOCFPGA_L4_SYS_SCR(USB1_TXECC), DISABLE_L4_FIREWALL);
+#endif
+
mmio_write_32(SOCFPGA_L4_SYS_SCR(L4_NOC_PROBES), DISABLE_L4_FIREWALL);
mmio_write_32(SOCFPGA_L4_SYS_SCR(L4_NOC_QOS), DISABLE_L4_FIREWALL);
diff --git a/plat/intel/soc/n5x/include/socfpga_plat_def.h b/plat/intel/soc/n5x/include/socfpga_plat_def.h
index 197bbca..a06bbc4 100644
--- a/plat/intel/soc/n5x/include/socfpga_plat_def.h
+++ b/plat/intel/soc/n5x/include/socfpga_plat_def.h
@@ -88,6 +88,18 @@
#define PLAT_SYS_COUNTER_FREQ_IN_TICKS (400000000)
#define PLAT_HZ_CONVERT_TO_MHZ (1000000)
+/*******************************************************************************
+ * SDMMC related pointer function
+ ******************************************************************************/
+#define SDMMC_READ_BLOCKS mmc_read_blocks
+#define SDMMC_WRITE_BLOCKS mmc_write_blocks
+
+/*******************************************************************************
+ * sysmgr.boot_scratch_cold6 & 7 (64bit) are used to indicate L2 reset
+ * is done and HPS should trigger warm reset via RMR_EL3.
+ ******************************************************************************/
+#define L2_RESET_DONE_REG 0xFFD12218
+
/* Platform specific system counter */
#define PLAT_SYS_COUNTER_FREQ_IN_MHZ get_cpu_clk()
diff --git a/plat/intel/soc/stratix10/include/socfpga_plat_def.h b/plat/intel/soc/stratix10/include/socfpga_plat_def.h
index 8a5d4a4..7c9f15a 100644
--- a/plat/intel/soc/stratix10/include/socfpga_plat_def.h
+++ b/plat/intel/soc/stratix10/include/socfpga_plat_def.h
@@ -86,6 +86,18 @@
#define PLAT_SYS_COUNTER_FREQ_IN_TICKS (400000000)
#define PLAT_HZ_CONVERT_TO_MHZ (1000000)
+/*******************************************************************************
+ * SDMMC related pointer function
+ ******************************************************************************/
+#define SDMMC_READ_BLOCKS mmc_read_blocks
+#define SDMMC_WRITE_BLOCKS mmc_write_blocks
+
+/*******************************************************************************
+ * sysmgr.boot_scratch_cold6 & 7 (64bit) are used to indicate L2 reset
+ * is done and HPS should trigger warm reset via RMR_EL3.
+ ******************************************************************************/
+#define L2_RESET_DONE_REG 0xFFD12218
+
/* Platform specific system counter */
#define PLAT_SYS_COUNTER_FREQ_IN_MHZ get_cpu_clk()