17931d332SJit Loon Lim /*
2998da640SHarrison Mutai * Copyright (c) 2019-2024, ARM Limited and Contributors. All rights reserved.
37931d332SJit Loon Lim * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
429d1e29dSJit Loon Lim * Copyright (c) 2024-2025, Altera Corporation. All rights reserved.
57931d332SJit Loon Lim *
67931d332SJit Loon Lim * SPDX-License-Identifier: BSD-3-Clause
77931d332SJit Loon Lim */
87931d332SJit Loon Lim
97931d332SJit Loon Lim #include <assert.h>
107931d332SJit Loon Lim #include <arch.h>
117931d332SJit Loon Lim #include <arch_helpers.h>
127931d332SJit Loon Lim #include <common/bl_common.h>
137931d332SJit Loon Lim #include <drivers/arm/gic_common.h>
147931d332SJit Loon Lim #include <drivers/arm/gicv3.h>
157931d332SJit Loon Lim #include <drivers/ti/uart/uart_16550.h>
167931d332SJit Loon Lim #include <lib/mmio.h>
177931d332SJit Loon Lim #include <lib/xlat_tables/xlat_mmu_helpers.h>
187931d332SJit Loon Lim #include <lib/xlat_tables/xlat_tables_v2.h>
197931d332SJit Loon Lim #include <plat/common/platform.h>
207931d332SJit Loon Lim
213c640c12STanmay Kathpalia #include "agilex5_cache.h"
227931d332SJit Loon Lim #include "agilex5_power_manager.h"
237931d332SJit Loon Lim #include "ccu/ncore_ccu.h"
2429d1e29dSJit Loon Lim #include "socfpga_dt.h"
257931d332SJit Loon Lim #include "socfpga_mailbox.h"
267931d332SJit Loon Lim #include "socfpga_private.h"
277931d332SJit Loon Lim #include "socfpga_reset_manager.h"
287931d332SJit Loon Lim
297931d332SJit Loon Lim /* Get non-secure SPSR for BL33. Zephyr and Linux */
307931d332SJit Loon Lim uint32_t arm_get_spsr_for_bl33_entry(void);
317931d332SJit Loon Lim
327931d332SJit Loon Lim static entry_point_info_t bl32_image_ep_info;
337931d332SJit Loon Lim static entry_point_info_t bl33_image_ep_info;
347931d332SJit Loon Lim
357931d332SJit Loon Lim /* The GICv3 driver only needs to be initialized in EL3 */
367931d332SJit Loon Lim static uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT];
377931d332SJit Loon Lim
387931d332SJit Loon Lim #define SMMU_SDMMC
397931d332SJit Loon Lim
bl31_plat_get_next_image_ep_info(uint32_t type)407931d332SJit Loon Lim entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
417931d332SJit Loon Lim {
427931d332SJit Loon Lim entry_point_info_t *next_image_info;
437931d332SJit Loon Lim
447931d332SJit Loon Lim next_image_info = (type == NON_SECURE) ?
457931d332SJit Loon Lim &bl33_image_ep_info : &bl32_image_ep_info;
467931d332SJit Loon Lim
477931d332SJit Loon Lim /* None of the images on this platform can have 0x0 as the entrypoint */
487931d332SJit Loon Lim if (next_image_info->pc)
497931d332SJit Loon Lim return next_image_info;
507931d332SJit Loon Lim else
517931d332SJit Loon Lim return NULL;
527931d332SJit Loon Lim }
537931d332SJit Loon Lim
bl31_early_platform_setup2(u_register_t arg0,u_register_t arg1,u_register_t arg2,u_register_t arg3)547931d332SJit Loon Lim void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
557931d332SJit Loon Lim u_register_t arg2, u_register_t arg3)
567931d332SJit Loon Lim {
577931d332SJit Loon Lim static console_t console;
587931d332SJit Loon Lim
597931d332SJit Loon Lim mmio_write_64(PLAT_SEC_ENTRY, PLAT_SEC_WARM_ENTRY);
607931d332SJit Loon Lim
617931d332SJit Loon Lim console_16550_register(PLAT_INTEL_UART_BASE, PLAT_UART_CLOCK,
627931d332SJit Loon Lim PLAT_BAUDRATE, &console);
637931d332SJit Loon Lim
64458b40dfSJit Loon Lim /* Enable TF-A BL31 logs when running from non-secure world also. */
65458b40dfSJit Loon Lim console_set_scope(&console,
66458b40dfSJit Loon Lim (CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH));
67458b40dfSJit Loon Lim
687931d332SJit Loon Lim setup_smmu_stream_id();
697931d332SJit Loon Lim
707931d332SJit Loon Lim /*
717931d332SJit Loon Lim * Check params passed from BL31 should not be NULL,
727931d332SJit Loon Lim */
737931d332SJit Loon Lim void *from_bl2 = (void *) arg0;
747931d332SJit Loon Lim
757931d332SJit Loon Lim #if RESET_TO_BL31
767931d332SJit Loon Lim /* There are no parameters from BL2 if BL31 is a reset vector */
777931d332SJit Loon Lim assert(from_bl2 == NULL);
787931d332SJit Loon Lim void *plat_params_from_bl2 = (void *) arg3;
797931d332SJit Loon Lim
807931d332SJit Loon Lim assert(plat_params_from_bl2 == NULL);
817931d332SJit Loon Lim
827931d332SJit Loon Lim /* Populate entry point information for BL33 */
837931d332SJit Loon Lim SET_PARAM_HEAD(&bl33_image_ep_info,
847931d332SJit Loon Lim PARAM_EP,
857931d332SJit Loon Lim VERSION_1,
867931d332SJit Loon Lim 0);
877931d332SJit Loon Lim
887931d332SJit Loon Lim # if ARM_LINUX_KERNEL_AS_BL33
897931d332SJit Loon Lim /*
907931d332SJit Loon Lim * According to the file ``Documentation/arm64/booting.txt`` of the
917931d332SJit Loon Lim * Linux kernel tree, Linux expects the physical address of the device
927931d332SJit Loon Lim * tree blob (DTB) in x0, while x1-x3 are reserved for future use and
937931d332SJit Loon Lim * must be 0.
947931d332SJit Loon Lim */
957931d332SJit Loon Lim bl33_image_ep_info.args.arg0 = (u_register_t)ARM_PRELOADED_DTB_BASE;
967931d332SJit Loon Lim bl33_image_ep_info.args.arg1 = 0U;
977931d332SJit Loon Lim bl33_image_ep_info.args.arg2 = 0U;
987931d332SJit Loon Lim bl33_image_ep_info.args.arg3 = 0U;
997931d332SJit Loon Lim # endif
1007931d332SJit Loon Lim
1017931d332SJit Loon Lim #else /* RESET_TO_BL31 */
1027931d332SJit Loon Lim bl_params_t *params_from_bl2 = (bl_params_t *)from_bl2;
1037931d332SJit Loon Lim
1047931d332SJit Loon Lim assert(params_from_bl2 != NULL);
1057931d332SJit Loon Lim
1067931d332SJit Loon Lim /*
1077931d332SJit Loon Lim * Copy BL32 (if populated by BL31) and BL33 entry point information.
1087931d332SJit Loon Lim * They are stored in Secure RAM, in BL31's address space.
1097931d332SJit Loon Lim */
1107931d332SJit Loon Lim
1117931d332SJit Loon Lim if (params_from_bl2->h.type == PARAM_BL_PARAMS &&
1127931d332SJit Loon Lim params_from_bl2->h.version >= VERSION_2) {
1137931d332SJit Loon Lim
1147931d332SJit Loon Lim bl_params_node_t *bl_params = params_from_bl2->head;
1157931d332SJit Loon Lim
1167931d332SJit Loon Lim while (bl_params) {
1177931d332SJit Loon Lim if (bl_params->image_id == BL33_IMAGE_ID) {
1187931d332SJit Loon Lim bl33_image_ep_info = *bl_params->ep_info;
1197931d332SJit Loon Lim }
1207931d332SJit Loon Lim bl_params = bl_params->next_params_info;
1217931d332SJit Loon Lim }
1227931d332SJit Loon Lim } else {
1237931d332SJit Loon Lim struct socfpga_bl31_params *arg_from_bl2 =
1247931d332SJit Loon Lim (struct socfpga_bl31_params *) from_bl2;
1257931d332SJit Loon Lim
1267931d332SJit Loon Lim assert(arg_from_bl2->h.type == PARAM_BL31);
1277931d332SJit Loon Lim assert(arg_from_bl2->h.version >= VERSION_1);
1287931d332SJit Loon Lim
1297931d332SJit Loon Lim bl32_image_ep_info = *arg_from_bl2->bl32_ep_info;
1307931d332SJit Loon Lim bl33_image_ep_info = *arg_from_bl2->bl33_ep_info;
1317931d332SJit Loon Lim }
1327931d332SJit Loon Lim
1337931d332SJit Loon Lim bl33_image_ep_info.args.arg0 = (u_register_t)ARM_PRELOADED_DTB_BASE;
1347931d332SJit Loon Lim bl33_image_ep_info.args.arg1 = 0U;
1357931d332SJit Loon Lim bl33_image_ep_info.args.arg2 = 0U;
1367931d332SJit Loon Lim bl33_image_ep_info.args.arg3 = 0U;
1377931d332SJit Loon Lim #endif
1387931d332SJit Loon Lim
1397931d332SJit Loon Lim /*
1407931d332SJit Loon Lim * Tell BL31 where the non-trusted software image
1417931d332SJit Loon Lim * is located and the entry state information
1427931d332SJit Loon Lim */
1437931d332SJit Loon Lim bl33_image_ep_info.pc = plat_get_ns_image_entrypoint();
1447931d332SJit Loon Lim bl33_image_ep_info.spsr = arm_get_spsr_for_bl33_entry();
1457931d332SJit Loon Lim
1467931d332SJit Loon Lim SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
1477931d332SJit Loon Lim }
1487931d332SJit Loon Lim
1497931d332SJit Loon Lim static const interrupt_prop_t agx5_interrupt_props[] = {
1507931d332SJit Loon Lim PLAT_INTEL_SOCFPGA_G1S_IRQ_PROPS(INTR_GROUP1S),
1517931d332SJit Loon Lim PLAT_INTEL_SOCFPGA_G0_IRQ_PROPS(INTR_GROUP0)
1527931d332SJit Loon Lim };
1537931d332SJit Loon Lim
15429d1e29dSJit Loon Lim gicv3_driver_data_t plat_gicv3_gic_data = {
1557931d332SJit Loon Lim .gicd_base = PLAT_INTEL_SOCFPGA_GICD_BASE,
1567931d332SJit Loon Lim .gicr_base = PLAT_INTEL_SOCFPGA_GICR_BASE,
1577931d332SJit Loon Lim .interrupt_props = agx5_interrupt_props,
1587931d332SJit Loon Lim .interrupt_props_num = ARRAY_SIZE(agx5_interrupt_props),
1597931d332SJit Loon Lim .rdistif_num = PLATFORM_CORE_COUNT,
1607931d332SJit Loon Lim .rdistif_base_addrs = rdistif_base_addrs,
1617931d332SJit Loon Lim };
1627931d332SJit Loon Lim
1637931d332SJit Loon Lim /*******************************************************************************
1647931d332SJit Loon Lim * Perform any BL3-1 platform setup code
1657931d332SJit Loon Lim ******************************************************************************/
bl31_platform_setup(void)1667931d332SJit Loon Lim void bl31_platform_setup(void)
1677931d332SJit Loon Lim {
1687931d332SJit Loon Lim socfpga_delay_timer_init();
1697931d332SJit Loon Lim
17029d1e29dSJit Loon Lim /* TODO: DTB not available */
17129d1e29dSJit Loon Lim // socfpga_dt_populate_gicv3_config(SOCFPGA_DTB_BASE, &plat_gicv3_gic_data);
17229d1e29dSJit Loon Lim // NOTICE("SOCFPGA: GIC GICD base address 0x%lx\n", plat_gicv3_gic_data.gicd_base);
17329d1e29dSJit Loon Lim // NOTICE("SOCFPGA: GIC GICR base address 0x%lx\n", plat_gicv3_gic_data.gicr_base);
17429d1e29dSJit Loon Lim
1757931d332SJit Loon Lim /* Initialize the gic cpu and distributor interfaces */
1767931d332SJit Loon Lim gicv3_driver_init(&plat_gicv3_gic_data);
1777931d332SJit Loon Lim gicv3_distif_init();
1787931d332SJit Loon Lim gicv3_rdistif_init(plat_my_core_pos());
1797931d332SJit Loon Lim gicv3_cpuif_enable(plat_my_core_pos());
180204d5e67SSieu Mun Tang
181204d5e67SSieu Mun Tang #if SIP_SVC_V3
182204d5e67SSieu Mun Tang /*
183204d5e67SSieu Mun Tang * Re-initialize the mailbox to include V3 specific routines.
184204d5e67SSieu Mun Tang * In V3, this re-initialize is required because prior to BL31, U-Boot
185204d5e67SSieu Mun Tang * SPL has its own mailbox settings and this initialization will
186204d5e67SSieu Mun Tang * override to those settings as required by the V3 framework.
187204d5e67SSieu Mun Tang */
188204d5e67SSieu Mun Tang mailbox_init();
189204d5e67SSieu Mun Tang #endif
190204d5e67SSieu Mun Tang
1917931d332SJit Loon Lim mailbox_hps_stage_notify(HPS_EXECUTION_STATE_SSBL);
1927931d332SJit Loon Lim }
1937931d332SJit Loon Lim
1947931d332SJit Loon Lim const mmap_region_t plat_agilex_mmap[] = {
1957931d332SJit Loon Lim MAP_REGION_FLAT(DRAM_BASE, DRAM_SIZE, MT_MEMORY | MT_RW | MT_NS),
1967931d332SJit Loon Lim MAP_REGION_FLAT(PSS_BASE, PSS_SIZE, MT_DEVICE | MT_RW | MT_NS),
1977931d332SJit Loon Lim MAP_REGION_FLAT(MPFE_BASE, MPFE_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
1987931d332SJit Loon Lim MAP_REGION_FLAT(OCRAM_BASE, OCRAM_SIZE, MT_NON_CACHEABLE | MT_RW | MT_SECURE),
1997931d332SJit Loon Lim MAP_REGION_FLAT(CCU_BASE, CCU_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
2007931d332SJit Loon Lim MAP_REGION_FLAT(MEM64_BASE, MEM64_SIZE, MT_DEVICE | MT_RW | MT_NS),
2017931d332SJit Loon Lim MAP_REGION_FLAT(GIC_BASE, GIC_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
2027931d332SJit Loon Lim {0}
2037931d332SJit Loon Lim };
2047931d332SJit Loon Lim
2057931d332SJit Loon Lim /*******************************************************************************
2067931d332SJit Loon Lim * Perform the very early platform specific architectural setup here. At the
207998da640SHarrison Mutai * moment this is only initializes the mmu in a quick and dirty way.
2087931d332SJit Loon Lim ******************************************************************************/
bl31_plat_arch_setup(void)2097931d332SJit Loon Lim void bl31_plat_arch_setup(void)
2107931d332SJit Loon Lim {
2117931d332SJit Loon Lim uint32_t boot_core = 0x00;
2127931d332SJit Loon Lim uint32_t cpuid = 0x00;
2137931d332SJit Loon Lim
214b3d28508SSieu Mun Tang cpuid = MPIDR_AFFLVL1_VAL(read_mpidr());
215b3d28508SSieu Mun Tang boot_core = ((mmio_read_32(AGX5_PWRMGR(MPU_BOOTCONFIG)) & 0xC00) >> 10);
21629d1e29dSJit Loon Lim NOTICE("SOCFPGA: Boot Core = %x\n", boot_core);
21729d1e29dSJit Loon Lim NOTICE("SOCFPGA: CPU ID = %x\n", cpuid);
21829d1e29dSJit Loon Lim INFO("SOCFPGA: Invalidate Data cache\n");
2193c640c12STanmay Kathpalia invalidate_dcache_all();
220bf3877e0SSieu Mun Tang /* Invalidate for NS EL2 and EL1 */
221bf3877e0SSieu Mun Tang invalidate_cache_low_el();
222bb9e34f9SJit Loon Lim
223bb9e34f9SJit Loon Lim NOTICE("SOCFPGA: Setting CLUSTERECTRL_EL1\n");
224bb9e34f9SJit Loon Lim setup_clusterectlr_el1();
2257931d332SJit Loon Lim }
2267931d332SJit Loon Lim
2277931d332SJit Loon Lim /* Get non-secure image entrypoint for BL33. Zephyr and Linux */
plat_get_ns_image_entrypoint(void)2287931d332SJit Loon Lim uintptr_t plat_get_ns_image_entrypoint(void)
2297931d332SJit Loon Lim {
2307931d332SJit Loon Lim #ifdef PRELOADED_BL33_BASE
2317931d332SJit Loon Lim return PRELOADED_BL33_BASE;
2327931d332SJit Loon Lim #else
2337931d332SJit Loon Lim return PLAT_NS_IMAGE_OFFSET;
2347931d332SJit Loon Lim #endif
2357931d332SJit Loon Lim }
2367931d332SJit Loon Lim
2377931d332SJit Loon Lim /* Get non-secure SPSR for BL33. Zephyr and Linux */
arm_get_spsr_for_bl33_entry(void)2387931d332SJit Loon Lim uint32_t arm_get_spsr_for_bl33_entry(void)
2397931d332SJit Loon Lim {
2407931d332SJit Loon Lim unsigned int mode;
2417931d332SJit Loon Lim uint32_t spsr;
2427931d332SJit Loon Lim
2437931d332SJit Loon Lim /* Figure out what mode we enter the non-secure world in */
2447931d332SJit Loon Lim mode = (el_implemented(2) != EL_IMPL_NONE) ? MODE_EL2 : MODE_EL1;
2457931d332SJit Loon Lim
2467931d332SJit Loon Lim /*
2477931d332SJit Loon Lim * TODO: Consider the possibility of specifying the SPSR in
2487931d332SJit Loon Lim * the FIP ToC and allowing the platform to have a say as
2497931d332SJit Loon Lim * well.
2507931d332SJit Loon Lim */
2517931d332SJit Loon Lim spsr = SPSR_64((uint64_t)mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
2527931d332SJit Loon Lim return spsr;
2537931d332SJit Loon Lim }
2547931d332SJit Loon Lim
2557931d332SJit Loon Lim /* SMP: Secondary cores BL31 setup reset vector */
bl31_plat_set_secondary_cpu_entrypoint(unsigned int cpu_id)2567931d332SJit Loon Lim void bl31_plat_set_secondary_cpu_entrypoint(unsigned int cpu_id)
2577931d332SJit Loon Lim {
2587931d332SJit Loon Lim unsigned int pch_cpu = 0x00;
2597931d332SJit Loon Lim unsigned int pchctlr_old = 0x00;
2607931d332SJit Loon Lim unsigned int pchctlr_new = 0x00;
2617931d332SJit Loon Lim uint32_t boot_core = 0x00;
2627931d332SJit Loon Lim
263646a9a16SJit Loon Lim /* Set bit for SMP secondary cores boot */
264646a9a16SJit Loon Lim mmio_clrsetbits_32(L2_RESET_DONE_REG, BS_REG_MAGIC_KEYS_MASK,
265646a9a16SJit Loon Lim SMP_SEC_CORE_BOOT_REQ);
2667931d332SJit Loon Lim boot_core = (mmio_read_32(AGX5_PWRMGR(MPU_BOOTCONFIG)) & 0xC00);
2677931d332SJit Loon Lim /* Update the p-channel based on cpu id */
2687931d332SJit Loon Lim pch_cpu = 1 << cpu_id;
2697931d332SJit Loon Lim
2707931d332SJit Loon Lim if (boot_core == 0x00) {
2717931d332SJit Loon Lim /* Update reset vector to 0x00 */
2727931d332SJit Loon Lim mmio_write_64(RSTMGR_CPUxRESETBASELOW_CPU2,
2737931d332SJit Loon Lim (uint64_t) plat_secondary_cpus_bl31_entry >> 2);
2747931d332SJit Loon Lim } else {
2757931d332SJit Loon Lim /* Update reset vector to 0x00 */
2767931d332SJit Loon Lim mmio_write_64(RSTMGR_CPUxRESETBASELOW_CPU0,
2777931d332SJit Loon Lim (uint64_t) plat_secondary_cpus_bl31_entry >> 2);
2787931d332SJit Loon Lim }
2797931d332SJit Loon Lim
2807931d332SJit Loon Lim /* Update reset vector to 0x00 */
2817931d332SJit Loon Lim mmio_write_64(RSTMGR_CPUxRESETBASELOW_CPU1, (uint64_t) plat_secondary_cpus_bl31_entry >> 2);
2827931d332SJit Loon Lim mmio_write_64(RSTMGR_CPUxRESETBASELOW_CPU3, (uint64_t) plat_secondary_cpus_bl31_entry >> 2);
2837931d332SJit Loon Lim
2847931d332SJit Loon Lim /* On all cores - temporary */
2857931d332SJit Loon Lim pchctlr_old = mmio_read_32(AGX5_PWRMGR(MPU_PCHCTLR));
2867931d332SJit Loon Lim pchctlr_new = pchctlr_old | (pch_cpu<<1);
2877931d332SJit Loon Lim mmio_write_32(AGX5_PWRMGR(MPU_PCHCTLR), pchctlr_new);
2887931d332SJit Loon Lim
2897931d332SJit Loon Lim /* We will only release the target secondary CPUs */
2907931d332SJit Loon Lim /* Bit mask for each CPU BIT0-3 */
2917931d332SJit Loon Lim mmio_write_32(RSTMGR_CPUSTRELEASE_CPUx, pch_cpu);
2927931d332SJit Loon Lim }
2937931d332SJit Loon Lim
bl31_plat_reset_secondary_cpu(unsigned int cpu_id)294*8f7575efSBoon Khai Ng void bl31_plat_reset_secondary_cpu(unsigned int cpu_id)
295*8f7575efSBoon Khai Ng {
296*8f7575efSBoon Khai Ng uint32_t mask = 0x1;
297*8f7575efSBoon Khai Ng uint32_t value = 0;
298*8f7575efSBoon Khai Ng uint32_t pwrctlr_addr = 0;
299*8f7575efSBoon Khai Ng uint32_t pwrstat_addr = 0;
300*8f7575efSBoon Khai Ng uint32_t ret = 0;
301*8f7575efSBoon Khai Ng
302*8f7575efSBoon Khai Ng mask <<= cpu_id;
303*8f7575efSBoon Khai Ng
304*8f7575efSBoon Khai Ng switch (cpu_id) {
305*8f7575efSBoon Khai Ng case 0:
306*8f7575efSBoon Khai Ng pwrctlr_addr = AGX5_PWRMGR(CPU_PWRCTLR0);
307*8f7575efSBoon Khai Ng pwrstat_addr = AGX5_PWRMGR(CPU_PWRSTAT0);
308*8f7575efSBoon Khai Ng break;
309*8f7575efSBoon Khai Ng case 1:
310*8f7575efSBoon Khai Ng pwrctlr_addr = AGX5_PWRMGR(CPU_PWRCTLR1);
311*8f7575efSBoon Khai Ng pwrstat_addr = AGX5_PWRMGR(CPU_PWRSTAT1);
312*8f7575efSBoon Khai Ng break;
313*8f7575efSBoon Khai Ng case 2:
314*8f7575efSBoon Khai Ng pwrctlr_addr = AGX5_PWRMGR(CPU_PWRCTLR2);
315*8f7575efSBoon Khai Ng pwrstat_addr = AGX5_PWRMGR(CPU_PWRSTAT2);
316*8f7575efSBoon Khai Ng break;
317*8f7575efSBoon Khai Ng case 3:
318*8f7575efSBoon Khai Ng pwrctlr_addr = AGX5_PWRMGR(CPU_PWRCTLR3);
319*8f7575efSBoon Khai Ng pwrstat_addr = AGX5_PWRMGR(CPU_PWRSTAT3);
320*8f7575efSBoon Khai Ng break;
321*8f7575efSBoon Khai Ng default:
322*8f7575efSBoon Khai Ng ERROR("BL31: %s: Invalid CPU ID\n", __func__);
323*8f7575efSBoon Khai Ng break;
324*8f7575efSBoon Khai Ng }
325*8f7575efSBoon Khai Ng
326*8f7575efSBoon Khai Ng /* PSTATE = 0, RUN_PCH = 1 */
327*8f7575efSBoon Khai Ng mmio_write_32(pwrctlr_addr, AGX5_PWRMGR_CPU_RUN_PCH(1));
328*8f7575efSBoon Khai Ng
329*8f7575efSBoon Khai Ng /* Poll for CPU OFF */
330*8f7575efSBoon Khai Ng SOCFPGA_POLL(!((AGX5_PWRMGR_CPU_RUN_PCH(
331*8f7575efSBoon Khai Ng mmio_read_32(pwrstat_addr)) == 0) ||
332*8f7575efSBoon Khai Ng (AGX5_PWRMGR_CPU_SINGLE_FSM_STATE(
333*8f7575efSBoon Khai Ng mmio_read_32(pwrstat_addr)) != 0)),
334*8f7575efSBoon Khai Ng AGX5_PWRMGR_CPU_POLL_COUNT,
335*8f7575efSBoon Khai Ng AGX5_PWRMGR_CPU_DELAY_10_US, udelay, ret);
336*8f7575efSBoon Khai Ng
337*8f7575efSBoon Khai Ng if (ret != 0)
338*8f7575efSBoon Khai Ng ERROR("BL31: %s: Timeout when polling for CPU OFF\n", __func__);
339*8f7575efSBoon Khai Ng
340*8f7575efSBoon Khai Ng /* Performs the warm reset CPUx */
341*8f7575efSBoon Khai Ng value = mmio_read_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_WARM_9));
342*8f7575efSBoon Khai Ng mmio_write_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_WARM_9), value | mask);
343*8f7575efSBoon Khai Ng udelay(1);
344*8f7575efSBoon Khai Ng mmio_write_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_WARM_9), value & ~mask);
345*8f7575efSBoon Khai Ng udelay(1);
346*8f7575efSBoon Khai Ng
347*8f7575efSBoon Khai Ng /* Power up sequence */
348*8f7575efSBoon Khai Ng mmio_write_32(pwrctlr_addr, AGX5_PWRMGR_CPU_PROG_CPU_ON_STATE |
349*8f7575efSBoon Khai Ng AGX5_PWRMGR_CPU_RUN_PCH(1));
350*8f7575efSBoon Khai Ng
351*8f7575efSBoon Khai Ng /* Poll for CPU ON */
352*8f7575efSBoon Khai Ng SOCFPGA_POLL(!((AGX5_PWRMGR_CPU_RUN_PCH(
353*8f7575efSBoon Khai Ng mmio_read_32(pwrstat_addr)) == 0) ||
354*8f7575efSBoon Khai Ng AGX5_PWRMGR_CPU_SINGLE_FSM_STATE(
355*8f7575efSBoon Khai Ng mmio_read_32(pwrstat_addr)) == 0),
356*8f7575efSBoon Khai Ng AGX5_PWRMGR_CPU_POLL_COUNT,
357*8f7575efSBoon Khai Ng AGX5_PWRMGR_CPU_DELAY_10_US, udelay, ret);
358*8f7575efSBoon Khai Ng if (ret !=0 )
359*8f7575efSBoon Khai Ng ERROR("BL31: %s: Timeout when polling for CPU ON\n", __func__);
360*8f7575efSBoon Khai Ng }
361*8f7575efSBoon Khai Ng
bl31_plat_set_secondary_cpu_off(void)3627931d332SJit Loon Lim void bl31_plat_set_secondary_cpu_off(void)
3637931d332SJit Loon Lim {
3647931d332SJit Loon Lim unsigned int pch_cpu = 0x00;
3657931d332SJit Loon Lim unsigned int pch_cpu_off = 0x00;
3667931d332SJit Loon Lim unsigned int cpu_id = plat_my_core_pos();
3677931d332SJit Loon Lim
3687931d332SJit Loon Lim pch_cpu_off = 1 << cpu_id;
3697931d332SJit Loon Lim
3707931d332SJit Loon Lim pch_cpu = mmio_read_32(AGX5_PWRMGR(MPU_PCHCTLR));
3717931d332SJit Loon Lim pch_cpu = pch_cpu & ~(pch_cpu_off << 1);
3727931d332SJit Loon Lim
3737931d332SJit Loon Lim mmio_write_32(AGX5_PWRMGR(MPU_PCHCTLR), pch_cpu);
3747931d332SJit Loon Lim }
3757931d332SJit Loon Lim
setup_clusterectlr_el1(void)376bb9e34f9SJit Loon Lim void setup_clusterectlr_el1(void)
377bb9e34f9SJit Loon Lim {
378bb9e34f9SJit Loon Lim uint64_t value = 0;
379bb9e34f9SJit Loon Lim
380bb9e34f9SJit Loon Lim /* Read CLUSTERECTLR_EL1 */
381bb9e34f9SJit Loon Lim asm volatile("mrs %0, S3_0_C15_C3_4" : "=r"(value));
382bb9e34f9SJit Loon Lim
383bb9e34f9SJit Loon Lim /* Disable broadcasting atomics */
384bb9e34f9SJit Loon Lim value |= 0x80; /* set bit 7 */
385bb9e34f9SJit Loon Lim /* Disable sending data with clean evicts */
386bb9e34f9SJit Loon Lim value &= 0xFFFFBFFF; /* Mask out bit 14 */
387bb9e34f9SJit Loon Lim
388bb9e34f9SJit Loon Lim /* Write CLUSTERECTLR_EL1 */
389bb9e34f9SJit Loon Lim asm volatile("msr S3_0_C15_C3_4, %0" :: "r"(value));
390bb9e34f9SJit Loon Lim }
391bb9e34f9SJit Loon Lim
bl31_plat_runtime_setup(void)39229d1e29dSJit Loon Lim void bl31_plat_runtime_setup(void)
39329d1e29dSJit Loon Lim {
394458b40dfSJit Loon Lim /* Dummy override function. */
39529d1e29dSJit Loon Lim }
39629d1e29dSJit Loon Lim
bl31_plat_enable_mmu(uint32_t flags)3977931d332SJit Loon Lim void bl31_plat_enable_mmu(uint32_t flags)
3987931d332SJit Loon Lim {
3997931d332SJit Loon Lim /* TODO: Enable mmu when needed */
4007931d332SJit Loon Lim }
401