1 /* 2 * Copyright 2018-2021, 2025 NXP 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <endian.h> 8 9 #include <arch.h> 10 #include <caam.h> 11 #include <cassert.h> 12 #include <cci.h> 13 #include <common/debug.h> 14 #include <dcfg.h> 15 #include <i2c.h> 16 #include <lib/xlat_tables/xlat_tables_v2.h> 17 #include <ls_interconnect.h> 18 #include <mmio.h> 19 #ifdef POLICY_FUSE_PROVISION 20 #include <nxp_gpio.h> 21 #endif 22 #include <nxp_smmu.h> 23 #include <nxp_timer.h> 24 #include <plat_console.h> 25 #include <plat_gic.h> 26 #include <plat_tzc400.h> 27 #include <pmu.h> 28 #include <scfg.h> 29 #if defined(NXP_SFP_ENABLED) 30 #include <sfp.h> 31 #endif 32 #if TRUSTED_BOARD_BOOT 33 #include <snvs.h> 34 #endif 35 36 #include <errata.h> 37 #ifdef CONFIG_OCRAM_ECC_EN 38 #include <ocram.h> 39 #endif 40 #include "plat_common.h" 41 #include "platform_def.h" 42 #include "soc.h" 43 44 static dcfg_init_info_t dcfg_init_data = { 45 .g_nxp_dcfg_addr = NXP_DCFG_ADDR, 46 .nxp_sysclk_freq = NXP_SYSCLK_FREQ, 47 .nxp_ddrclk_freq = NXP_DDRCLK_FREQ, 48 .nxp_plat_clk_divider = NXP_PLATFORM_CLK_DIVIDER, 49 }; 50 51 static struct soc_type soc_list[] = { 52 SOC_ENTRY(LS1017AN, LS1017AN, 1, 1), 53 SOC_ENTRY(LS1017AE, LS1017AE, 1, 1), 54 SOC_ENTRY(LS1018AN, LS1018AN, 1, 1), 55 SOC_ENTRY(LS1018AE, LS1018AE, 1, 1), 56 SOC_ENTRY(LS1027AN, LS1027AN, 1, 2), 57 SOC_ENTRY(LS1027AE, LS1027AE, 1, 2), 58 SOC_ENTRY(LS1028AN, LS1028AN, 1, 2), 59 SOC_ENTRY(LS1028AE, LS1028AE, 1, 2), 60 }; 61 62 CASSERT(NUMBER_OF_CLUSTERS && NUMBER_OF_CLUSTERS <= 256, 63 assert_invalid_ls1028a_cluster_count); 64 65 /* 66 * Function returns the base counter frequency 67 * after reading the first entry at CNTFID0 (0x20 offset). 68 * 69 * Function is used by: 70 * 1. ARM common code for PSCI management. 71 * 2. ARM Generic Timer init. 72 * 73 */ 74 unsigned int plat_get_syscnt_freq2(void) 75 { 76 unsigned int counter_base_frequency; 77 /* 78 * Below register specifies the base frequency of the system counter. 79 * As per NXP Board Manuals: 80 * The system counter always works with SYS_REF_CLK/4 frequency clock. 81 */ 82 counter_base_frequency = mmio_read_32(NXP_TIMER_ADDR + CNTFID_OFF); 83 84 return counter_base_frequency; 85 } 86 87 #ifdef IMAGE_BL2 88 89 #ifdef POLICY_FUSE_PROVISION 90 static gpio_init_info_t gpio_init_data = { 91 .gpio1_base_addr = NXP_GPIO1_ADDR, 92 .gpio2_base_addr = NXP_GPIO2_ADDR, 93 .gpio3_base_addr = NXP_GPIO3_ADDR, 94 }; 95 #endif 96 97 void soc_preload_setup(void) 98 { 99 } 100 101 void soc_early_init(void) 102 { 103 uint8_t num_clusters, cores_per_cluster; 104 105 #if TRUSTED_BOARD_BOOT 106 snvs_init(NXP_SNVS_ADDR); 107 #endif 108 109 #ifdef CONFIG_OCRAM_ECC_EN 110 ocram_init(NXP_OCRAM_ADDR, NXP_OCRAM_SIZE); 111 #endif 112 dcfg_init(&dcfg_init_data); 113 enable_timer_base_to_cluster(NXP_PMU_ADDR); 114 enable_core_tb(NXP_PMU_ADDR); 115 dram_regions_info_t *dram_regions_info = get_dram_regions_info(); 116 117 #ifdef POLICY_FUSE_PROVISION 118 gpio_init(&gpio_init_data); 119 sec_init(NXP_CAAM_ADDR); 120 #endif 121 122 #if LOG_LEVEL > 0 123 /* Initialize the console to provide early debug support */ 124 plat_console_init(NXP_CONSOLE_ADDR, 125 NXP_UART_CLK_DIVIDER, NXP_CONSOLE_BAUDRATE); 126 #endif 127 enum boot_device dev = get_boot_dev(); 128 /* 129 * Mark the buffer for SD in OCRAM as non secure. 130 * The buffer is assumed to be at end of OCRAM for 131 * the logic below to calculate TZPC programming 132 */ 133 if (dev == BOOT_DEVICE_EMMC || dev == BOOT_DEVICE_SDHC2_EMMC) { 134 /* 135 * Calculate the region in OCRAM which is secure 136 * The buffer for SD needs to be marked non-secure 137 * to allow SD to do DMA operations on it 138 */ 139 uint32_t secure_region = (NXP_OCRAM_SIZE - NXP_SD_BLOCK_BUF_SIZE); 140 uint32_t mask = secure_region/TZPC_BLOCK_SIZE; 141 142 mmio_write_32(NXP_OCRAM_TZPC_ADDR, mask); 143 144 /* Add the entry for buffer in MMU Table */ 145 mmap_add_region(NXP_SD_BLOCK_BUF_ADDR, NXP_SD_BLOCK_BUF_ADDR, 146 NXP_SD_BLOCK_BUF_SIZE, MT_DEVICE | MT_RW | MT_NS); 147 } 148 149 /* 150 * Unlock write access for SMMU SMMU_CBn_ACTLR in all Non-secure contexts. 151 */ 152 smmu_cache_unlock(NXP_SMMU_ADDR); 153 INFO("SMMU Cache Unlocking is Configured.\n"); 154 155 #if TRUSTED_BOARD_BOOT 156 uint32_t mode; 157 158 sfp_init(NXP_SFP_ADDR); 159 160 /* 161 * For secure boot disable SMMU. 162 * Later when platform security policy comes in picture, 163 * this might get modified based on the policy 164 */ 165 if (check_boot_mode_secure(&mode) == true) { 166 bypass_smmu(NXP_SMMU_ADDR); 167 } 168 169 /* 170 * For Mbedtls currently crypto is not supported via CAAM 171 * enable it when that support is there. In tbbr.mk 172 * the CAAM_INTEG is set as 0. 173 */ 174 #ifndef MBEDTLS_X509 175 /* Initialize the crypto accelerator if enabled */ 176 if (is_sec_enabled()) { 177 sec_init(NXP_CAAM_ADDR); 178 } else { 179 INFO("SEC is disabled.\n"); 180 } 181 #endif 182 #endif 183 184 /* Set eDDRTQ for DDR performance */ 185 scfg_setbits32((void *)(NXP_SCFG_ADDR + 0x210), 0x1f1f1f1f); 186 187 soc_errata(); 188 189 /* 190 * Initialize Interconnect for this cluster during cold boot. 191 * No need for locks as no other CPU is active. 192 */ 193 cci_init(NXP_CCI_ADDR, cci_map, ARRAY_SIZE(cci_map)); 194 195 /* 196 * Enable Interconnect coherency for the primary CPU's cluster. 197 */ 198 get_cluster_info(soc_list, ARRAY_SIZE(soc_list), &num_clusters, &cores_per_cluster); 199 plat_ls_interconnect_enter_coherency(num_clusters); 200 201 delay_timer_init(NXP_TIMER_ADDR); 202 i2c_init(NXP_I2C_ADDR); 203 dram_regions_info->total_dram_size = init_ddr(); 204 } 205 206 void soc_bl2_prepare_exit(void) 207 { 208 #if defined(NXP_SFP_ENABLED) && defined(DISABLE_FUSE_WRITE) 209 set_sfp_wr_disable(); 210 #endif 211 } 212 213 /* 214 * This function returns the boot device based on RCW_SRC 215 */ 216 enum boot_device get_boot_dev(void) 217 { 218 enum boot_device src = BOOT_DEVICE_NONE; 219 uint32_t porsr1; 220 uint32_t rcw_src; 221 222 porsr1 = read_reg_porsr1(); 223 224 rcw_src = (porsr1 & PORSR1_RCW_MASK) >> PORSR1_RCW_SHIFT; 225 switch (rcw_src) { 226 case FLEXSPI_NOR: 227 src = BOOT_DEVICE_FLEXSPI_NOR; 228 INFO("RCW BOOT SRC is FLEXSPI NOR\n"); 229 break; 230 case FLEXSPI_NAND2K_VAL: 231 case FLEXSPI_NAND4K_VAL: 232 INFO("RCW BOOT SRC is FLEXSPI NAND\n"); 233 src = BOOT_DEVICE_FLEXSPI_NAND; 234 break; 235 case SDHC1_VAL: 236 src = BOOT_DEVICE_EMMC; 237 INFO("RCW BOOT SRC is SD\n"); 238 break; 239 case SDHC2_VAL: 240 src = BOOT_DEVICE_SDHC2_EMMC; 241 INFO("RCW BOOT SRC is EMMC\n"); 242 break; 243 default: 244 break; 245 } 246 247 return src; 248 } 249 250 /* 251 * This function sets up access permissions on memory regions 252 ****************************************************************************/ 253 void soc_mem_access(void) 254 { 255 dram_regions_info_t *info_dram_regions = get_dram_regions_info(); 256 struct tzc400_reg tzc400_reg_list[MAX_NUM_TZC_REGION]; 257 int dram_idx = 0; 258 /* index 0 is reserved for region-0 */ 259 int index = 1; 260 261 for (dram_idx = 0; dram_idx < info_dram_regions->num_dram_regions; 262 dram_idx++) { 263 if (info_dram_regions->region[dram_idx].size == 0) { 264 ERROR("DDR init failure, or"); 265 ERROR("DRAM regions not populated correctly.\n"); 266 break; 267 } 268 269 index = populate_tzc400_reg_list(tzc400_reg_list, 270 dram_idx, index, 271 info_dram_regions->region[dram_idx].addr, 272 info_dram_regions->region[dram_idx].size, 273 NXP_SECURE_DRAM_SIZE, NXP_SP_SHRD_DRAM_SIZE); 274 } 275 276 mem_access_setup(NXP_TZC_ADDR, index, tzc400_reg_list); 277 } 278 279 #else 280 281 static unsigned char _power_domain_tree_desc[NUMBER_OF_CLUSTERS + 2]; 282 /* 283 * This function dynamically constructs the topology according to 284 * SoC Flavor and returns it. 285 */ 286 const unsigned char *plat_get_power_domain_tree_desc(void) 287 { 288 uint8_t num_clusters, cores_per_cluster; 289 unsigned int i; 290 291 get_cluster_info(soc_list, ARRAY_SIZE(soc_list), &num_clusters, &cores_per_cluster); 292 /* 293 * The highest level is the system level. The next level is constituted 294 * by clusters and then cores in clusters. 295 */ 296 _power_domain_tree_desc[0] = 1; 297 _power_domain_tree_desc[1] = num_clusters; 298 299 for (i = 0; i < _power_domain_tree_desc[1]; i++) 300 _power_domain_tree_desc[i + 2] = cores_per_cluster; 301 302 return _power_domain_tree_desc; 303 } 304 305 /* 306 * This function returns the core count within the cluster corresponding to 307 * `mpidr`. 308 */ 309 unsigned int plat_ls_get_cluster_core_count(u_register_t mpidr) 310 { 311 uint8_t num_clusters, cores_per_cluster; 312 313 get_cluster_info(soc_list, ARRAY_SIZE(soc_list), &num_clusters, &cores_per_cluster); 314 return num_clusters; 315 } 316 317 void soc_early_platform_setup2(void) 318 { 319 dcfg_init(&dcfg_init_data); 320 /* Initialize system level generic timer for Socs */ 321 delay_timer_init(NXP_TIMER_ADDR); 322 323 #if LOG_LEVEL > 0 324 /* Initialize the console to provide early debug support */ 325 plat_console_init(NXP_CONSOLE_ADDR, 326 NXP_UART_CLK_DIVIDER, NXP_CONSOLE_BAUDRATE); 327 #endif 328 } 329 330 void soc_platform_setup(void) 331 { 332 /* Initialize the GIC driver, cpu and distributor interfaces */ 333 static uintptr_t target_mask_array[PLATFORM_CORE_COUNT]; 334 static interrupt_prop_t ls_interrupt_props[] = { 335 PLAT_LS_G1S_IRQ_PROPS(INTR_GROUP1S), 336 PLAT_LS_G0_IRQ_PROPS(INTR_GROUP0) 337 }; 338 339 plat_ls_gic_driver_init(NXP_GICD_ADDR, NXP_GICR_ADDR, 340 PLATFORM_CORE_COUNT, 341 ls_interrupt_props, 342 ARRAY_SIZE(ls_interrupt_props), 343 target_mask_array, 344 plat_core_pos); 345 346 plat_ls_gic_init(); 347 enable_init_timer(); 348 } 349 350 /* This function initializes the soc from the BL31 module */ 351 void soc_init(void) 352 { 353 uint8_t num_clusters, cores_per_cluster; 354 355 get_cluster_info(soc_list, ARRAY_SIZE(soc_list), &num_clusters, &cores_per_cluster); 356 357 /* Low-level init of the soc */ 358 soc_init_lowlevel(); 359 _init_global_data(); 360 soc_init_percpu(); 361 _initialize_psci(); 362 363 /* 364 * Initialize Interconnect for this cluster during cold boot. 365 * No need for locks as no other CPU is active. 366 */ 367 cci_init(NXP_CCI_ADDR, cci_map, ARRAY_SIZE(cci_map)); 368 369 /* Enable Interconnect coherency for the primary CPU's cluster. */ 370 plat_ls_interconnect_enter_coherency(num_clusters); 371 372 /* Set platform security policies */ 373 _set_platform_security(); 374 375 /* Init SEC Engine which will be used by SiP */ 376 if (is_sec_enabled()) { 377 sec_init(NXP_CAAM_ADDR); 378 } else { 379 INFO("SEC is disabled.\n"); 380 } 381 } 382 383 #ifdef NXP_WDOG_RESTART 384 static uint64_t wdog_interrupt_handler(uint32_t id, uint32_t flags, 385 void *handle, void *cookie) 386 { 387 uint8_t data = WDOG_RESET_FLAG; 388 389 wr_nv_app_data(WDT_RESET_FLAG_OFFSET, 390 (uint8_t *)&data, sizeof(data)); 391 392 mmio_write_32(NXP_RST_ADDR + RSTCNTL_OFFSET, SW_RST_REQ_INIT); 393 394 return 0; 395 } 396 #endif 397 398 void soc_runtime_setup(void) 399 { 400 #ifdef NXP_WDOG_RESTART 401 request_intr_type_el3(BL31_NS_WDOG_WS1, wdog_interrupt_handler); 402 #endif 403 } 404 405 /* This function returns the total number of cores in the SoC. */ 406 unsigned int get_tot_num_cores(void) 407 { 408 uint8_t num_clusters, cores_per_cluster; 409 410 get_cluster_info(soc_list, ARRAY_SIZE(soc_list), &num_clusters, &cores_per_cluster); 411 return (num_clusters * cores_per_cluster); 412 } 413 414 /* This function returns the PMU IDLE Cluster mask. */ 415 unsigned int get_pmu_idle_cluster_mask(void) 416 { 417 uint8_t num_clusters, cores_per_cluster; 418 419 get_cluster_info(soc_list, ARRAY_SIZE(soc_list), &num_clusters, &cores_per_cluster); 420 return ((1 << num_clusters) - 2); 421 } 422 423 /* This function returns the PMU Flush Cluster mask. */ 424 unsigned int get_pmu_flush_cluster_mask(void) 425 { 426 uint8_t num_clusters, cores_per_cluster; 427 428 get_cluster_info(soc_list, ARRAY_SIZE(soc_list), &num_clusters, &cores_per_cluster); 429 return ((1 << num_clusters) - 2); 430 } 431 432 /* This function returns the PMU idle core mask. */ 433 unsigned int get_pmu_idle_core_mask(void) 434 { 435 return ((1 << get_tot_num_cores()) - 2); 436 } 437 438 /* Function to return the SoC SYS CLK */ 439 unsigned int get_sys_clk(void) 440 { 441 return NXP_SYSCLK_FREQ; 442 } 443 #endif 444