1 /*
2 * Copyright 2018-2021, 2025 NXP
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #include <assert.h>
9
10 #include <arch.h>
11 #include <bl31/interrupt_mgmt.h>
12 #include <caam.h>
13 #include <cassert.h>
14 #include <ccn.h>
15 #include <common/debug.h>
16 #include <dcfg.h>
17 #ifdef I2C_INIT
18 #include <i2c.h>
19 #endif
20 #include <lib/mmio.h>
21 #include <lib/xlat_tables/xlat_tables_v2.h>
22 #include <ls_interconnect.h>
23 #ifdef POLICY_FUSE_PROVISION
24 #include <nxp_gpio.h>
25 #endif
26 #include <nxp_smmu.h>
27 #include <nxp_timer.h>
28 #include <plat_console.h>
29 #include <plat_gic.h>
30 #include <plat_tzc400.h>
31 #include <pmu.h>
32 #if defined(NXP_SFP_ENABLED)
33 #include <sfp.h>
34 #endif
35 #if TRUSTED_BOARD_BOOT
36 #include <snvs.h>
37 #endif
38
39 #include <errata.h>
40 #include <ls_interrupt_mgmt.h>
41 #ifdef CONFIG_OCRAM_ECC_EN
42 #include <ocram.h>
43 #endif
44 #include "plat_common.h"
45 #ifdef NXP_NV_SW_MAINT_LAST_EXEC_DATA
46 #include <plat_nv_storage.h>
47 #endif
48 #ifdef NXP_WARM_BOOT
49 #include <plat_warm_rst.h>
50 #endif
51 #include "platform_def.h"
52 #include "soc.h"
53
54 static struct soc_type soc_list[] = {
55 /* SoC LX2160A */
56 SOC_ENTRY(LX2160A, LX2160A, 8, 2),
57 SOC_ENTRY(LX2160E, LX2160E, 8, 2),
58 SOC_ENTRY(LX2160C, LX2160C, 8, 2),
59 SOC_ENTRY(LX2160N, LX2160N, 8, 2),
60 SOC_ENTRY(LX2080A, LX2080A, 8, 1),
61 SOC_ENTRY(LX2080E, LX2080E, 8, 1),
62 SOC_ENTRY(LX2080C, LX2080C, 8, 1),
63 SOC_ENTRY(LX2080N, LX2080N, 8, 1),
64 SOC_ENTRY(LX2120A, LX2120A, 6, 2),
65 SOC_ENTRY(LX2120E, LX2120E, 6, 2),
66 SOC_ENTRY(LX2120C, LX2120C, 6, 2),
67 SOC_ENTRY(LX2120N, LX2120N, 6, 2),
68 /* SoC LX2162A */
69 SOC_ENTRY(LX2162A, LX2162A, 8, 2),
70 SOC_ENTRY(LX2162E, LX2162E, 8, 2),
71 SOC_ENTRY(LX2162C, LX2162C, 8, 2),
72 SOC_ENTRY(LX2162N, LX2162N, 8, 2),
73 SOC_ENTRY(LX2082A, LX2082A, 8, 1),
74 SOC_ENTRY(LX2082E, LX2082E, 8, 1),
75 SOC_ENTRY(LX2082C, LX2082C, 8, 1),
76 SOC_ENTRY(LX2082N, LX2082N, 8, 1),
77 SOC_ENTRY(LX2122A, LX2122A, 6, 2),
78 SOC_ENTRY(LX2122E, LX2122E, 6, 2),
79 SOC_ENTRY(LX2122C, LX2122C, 6, 2),
80 SOC_ENTRY(LX2122N, LX2122N, 6, 2),
81 };
82
83 static dcfg_init_info_t dcfg_init_data = {
84 .g_nxp_dcfg_addr = NXP_DCFG_ADDR,
85 .nxp_sysclk_freq = NXP_SYSCLK_FREQ,
86 .nxp_ddrclk_freq = NXP_DDRCLK_FREQ,
87 .nxp_plat_clk_divider = NXP_PLATFORM_CLK_DIVIDER,
88 };
89 static const unsigned char master_to_6rn_id_map[] = {
90 PLAT_6CLUSTER_TO_CCN_ID_MAP
91 };
92
93 static const unsigned char master_to_rn_id_map[] = {
94 PLAT_CLUSTER_TO_CCN_ID_MAP
95 };
96
97 CASSERT(ARRAY_SIZE(master_to_rn_id_map) == NUMBER_OF_CLUSTERS,
98 assert_invalid_cluster_count_for_ccn_variant);
99
100 static const ccn_desc_t plat_six_cluster_ccn_desc = {
101 .periphbase = NXP_CCN_ADDR,
102 .num_masters = ARRAY_SIZE(master_to_6rn_id_map),
103 .master_to_rn_id_map = master_to_6rn_id_map
104 };
105
106 static const ccn_desc_t plat_ccn_desc = {
107 .periphbase = NXP_CCN_ADDR,
108 .num_masters = ARRAY_SIZE(master_to_rn_id_map),
109 .master_to_rn_id_map = master_to_rn_id_map
110 };
111
112 /******************************************************************************
113 * Function returns the base counter frequency
114 * after reading the first entry at CNTFID0 (0x20 offset).
115 *
116 * Function is used by:
117 * 1. ARM common code for PSCI management.
118 * 2. ARM Generic Timer init.
119 *
120 *****************************************************************************/
plat_get_syscnt_freq2(void)121 unsigned int plat_get_syscnt_freq2(void)
122 {
123 unsigned int counter_base_frequency;
124 /*
125 * Below register specifies the base frequency of the system counter.
126 * As per NXP Board Manuals:
127 * The system counter always works with SYS_REF_CLK/4 frequency clock.
128 *
129 *
130 */
131 counter_base_frequency = mmio_read_32(NXP_TIMER_ADDR + CNTFID_OFF);
132
133 return counter_base_frequency;
134 }
135
136 #ifdef IMAGE_BL2
137
138 #ifdef POLICY_FUSE_PROVISION
139 static gpio_init_info_t gpio_init_data = {
140 .gpio1_base_addr = NXP_GPIO1_ADDR,
141 .gpio2_base_addr = NXP_GPIO2_ADDR,
142 .gpio3_base_addr = NXP_GPIO3_ADDR,
143 .gpio4_base_addr = NXP_GPIO4_ADDR,
144 };
145 #endif
146
soc_interconnect_config(void)147 static void soc_interconnect_config(void)
148 {
149 unsigned long long val = 0x0U;
150 uint8_t num_clusters, cores_per_cluster;
151
152 get_cluster_info(soc_list, ARRAY_SIZE(soc_list),
153 &num_clusters, &cores_per_cluster);
154
155 if (num_clusters == 6U) {
156 ccn_init(&plat_six_cluster_ccn_desc);
157 } else {
158 ccn_init(&plat_ccn_desc);
159 }
160
161 /*
162 * Enable Interconnect coherency for the primary CPU's cluster.
163 */
164 plat_ls_interconnect_enter_coherency(num_clusters);
165
166 val = ccn_read_node_reg(NODE_TYPE_HNI, 13, PCIeRC_RN_I_NODE_ID_OFFSET);
167 val |= (1 << 17);
168 ccn_write_node_reg(NODE_TYPE_HNI, 13, PCIeRC_RN_I_NODE_ID_OFFSET, val);
169
170 /* PCIe is Connected to RN-I 17 which is connected to HN-I 13. */
171 val = ccn_read_node_reg(NODE_TYPE_HNI, 30, PCIeRC_RN_I_NODE_ID_OFFSET);
172 val |= (1 << 17);
173 ccn_write_node_reg(NODE_TYPE_HNI, 30, PCIeRC_RN_I_NODE_ID_OFFSET, val);
174
175 val = ccn_read_node_reg(NODE_TYPE_HNI, 13, SA_AUX_CTRL_REG_OFFSET);
176 val |= SERIALIZE_DEV_nGnRnE_WRITES;
177 ccn_write_node_reg(NODE_TYPE_HNI, 13, SA_AUX_CTRL_REG_OFFSET, val);
178
179 val = ccn_read_node_reg(NODE_TYPE_HNI, 30, SA_AUX_CTRL_REG_OFFSET);
180 val &= ~(ENABLE_RESERVE_BIT53);
181 val |= SERIALIZE_DEV_nGnRnE_WRITES;
182 ccn_write_node_reg(NODE_TYPE_HNI, 30, SA_AUX_CTRL_REG_OFFSET, val);
183
184 val = ccn_read_node_reg(NODE_TYPE_HNI, 13, PoS_CONTROL_REG_OFFSET);
185 val &= ~(HNI_POS_EN);
186 ccn_write_node_reg(NODE_TYPE_HNI, 13, PoS_CONTROL_REG_OFFSET, val);
187
188 val = ccn_read_node_reg(NODE_TYPE_HNI, 30, PoS_CONTROL_REG_OFFSET);
189 val &= ~(HNI_POS_EN);
190 ccn_write_node_reg(NODE_TYPE_HNI, 30, PoS_CONTROL_REG_OFFSET, val);
191
192 val = ccn_read_node_reg(NODE_TYPE_HNI, 13, SA_AUX_CTRL_REG_OFFSET);
193 val &= ~(POS_EARLY_WR_COMP_EN);
194 ccn_write_node_reg(NODE_TYPE_HNI, 13, SA_AUX_CTRL_REG_OFFSET, val);
195
196 val = ccn_read_node_reg(NODE_TYPE_HNI, 30, SA_AUX_CTRL_REG_OFFSET);
197 val &= ~(POS_EARLY_WR_COMP_EN);
198 ccn_write_node_reg(NODE_TYPE_HNI, 30, SA_AUX_CTRL_REG_OFFSET, val);
199
200 #if POLICY_PERF_WRIOP
201 uint16_t wriop_rni = 0U;
202
203 if (POLICY_PERF_WRIOP == 1) {
204 wriop_rni = 7U;
205 } else if (POLICY_PERF_WRIOP == 2) {
206 wriop_rni = 23U;
207 } else {
208 ERROR("Incorrect WRIOP selected.\n");
209 panic();
210 }
211
212 val = ccn_read_node_reg(NODE_TYPE_RNI, wriop_rni,
213 SA_AUX_CTRL_REG_OFFSET);
214 val |= ENABLE_WUO;
215 ccn_write_node_reg(NODE_TYPE_HNI, wriop_rni, SA_AUX_CTRL_REG_OFFSET,
216 val);
217 #else
218 val = ccn_read_node_reg(NODE_TYPE_RNI, 17, SA_AUX_CTRL_REG_OFFSET);
219 val |= ENABLE_WUO;
220 ccn_write_node_reg(NODE_TYPE_RNI, 17, SA_AUX_CTRL_REG_OFFSET, val);
221 #endif
222 }
223
224
soc_preload_setup(void)225 void soc_preload_setup(void)
226 {
227 dram_regions_info_t *info_dram_regions = get_dram_regions_info();
228 #if defined(NXP_WARM_BOOT)
229 bool warm_reset = is_warm_boot();
230 #endif
231 info_dram_regions->total_dram_size =
232 #if defined(NXP_WARM_BOOT)
233 init_ddr(warm_reset);
234 #else
235 init_ddr();
236 #endif
237 }
238
239 /*******************************************************************************
240 * This function implements soc specific erratas
241 * This is called before DDR is initialized or MMU is enabled
242 ******************************************************************************/
soc_early_init(void)243 void soc_early_init(void)
244 {
245 #if TRUSTED_BOARD_BOOT
246 snvs_init(NXP_SNVS_ADDR);
247 #endif
248
249 #ifdef CONFIG_OCRAM_ECC_EN
250 ocram_init(NXP_OCRAM_ADDR, NXP_OCRAM_SIZE);
251 #endif
252 dcfg_init(&dcfg_init_data);
253 #ifdef POLICY_FUSE_PROVISION
254 gpio_init(&gpio_init_data);
255 sec_init(NXP_CAAM_ADDR);
256 #endif
257 #if LOG_LEVEL > 0
258 /* Initialize the console to provide early debug support */
259 plat_console_init(NXP_CONSOLE_ADDR,
260 NXP_UART_CLK_DIVIDER, NXP_CONSOLE_BAUDRATE);
261 #endif
262
263 enable_timer_base_to_cluster(NXP_PMU_ADDR);
264 soc_interconnect_config();
265
266 enum boot_device dev = get_boot_dev();
267 /* Mark the buffer for SD in OCRAM as non secure.
268 * The buffer is assumed to be at end of OCRAM for
269 * the logic below to calculate TZPC programming
270 */
271 if (dev == BOOT_DEVICE_EMMC || dev == BOOT_DEVICE_SDHC2_EMMC) {
272 /* Calculate the region in OCRAM which is secure
273 * The buffer for SD needs to be marked non-secure
274 * to allow SD to do DMA operations on it
275 */
276 uint32_t secure_region = (NXP_OCRAM_SIZE
277 - NXP_SD_BLOCK_BUF_SIZE);
278 uint32_t mask = secure_region/TZPC_BLOCK_SIZE;
279
280 mmio_write_32(NXP_OCRAM_TZPC_ADDR, mask);
281
282 /* Add the entry for buffer in MMU Table */
283 mmap_add_region(NXP_SD_BLOCK_BUF_ADDR, NXP_SD_BLOCK_BUF_ADDR,
284 NXP_SD_BLOCK_BUF_SIZE,
285 MT_DEVICE | MT_RW | MT_NS);
286 }
287
288 soc_errata();
289
290 #if (TRUSTED_BOARD_BOOT) || defined(POLICY_FUSE_PROVISION)
291 sfp_init(NXP_SFP_ADDR);
292 #endif
293
294 /*
295 * Unlock write access for SMMU SMMU_CBn_ACTLR in all Non-secure contexts.
296 */
297 smmu_cache_unlock(NXP_SMMU_ADDR);
298 INFO("SMMU Cache Unlocking is Configured.\n");
299
300 #if TRUSTED_BOARD_BOOT
301 uint32_t mode;
302
303 /* For secure boot disable SMMU.
304 * Later when platform security policy comes in picture,
305 * this might get modified based on the policy
306 */
307 if (check_boot_mode_secure(&mode) == true) {
308 bypass_smmu(NXP_SMMU_ADDR);
309 }
310
311 /* For Mbedtls currently crypto is not supported via CAAM
312 * enable it when that support is there. In tbbr.mk
313 * the CAAM_INTEG is set as 0.
314 */
315
316 #ifndef MBEDTLS_X509
317 /* Initialize the crypto accelerator if enabled */
318 if (is_sec_enabled() == false)
319 INFO("SEC is disabled.\n");
320 else
321 sec_init(NXP_CAAM_ADDR);
322 #endif
323 #endif
324
325 /*
326 * Initialize system level generic timer for Layerscape Socs.
327 */
328 delay_timer_init(NXP_TIMER_ADDR);
329 i2c_init(NXP_I2C_ADDR);
330 }
331
soc_bl2_prepare_exit(void)332 void soc_bl2_prepare_exit(void)
333 {
334 #if defined(NXP_SFP_ENABLED) && defined(DISABLE_FUSE_WRITE)
335 set_sfp_wr_disable();
336 #endif
337 }
338
339 /*****************************************************************************
340 * This function returns the boot device based on RCW_SRC
341 ****************************************************************************/
get_boot_dev(void)342 enum boot_device get_boot_dev(void)
343 {
344 enum boot_device src = BOOT_DEVICE_NONE;
345 uint32_t porsr1;
346 uint32_t rcw_src;
347
348 porsr1 = read_reg_porsr1();
349
350 rcw_src = (porsr1 & PORSR1_RCW_MASK) >> PORSR1_RCW_SHIFT;
351
352 switch (rcw_src) {
353 case FLEXSPI_NOR:
354 src = BOOT_DEVICE_FLEXSPI_NOR;
355 INFO("RCW BOOT SRC is FLEXSPI NOR\n");
356 break;
357 case FLEXSPI_NAND2K_VAL:
358 case FLEXSPI_NAND4K_VAL:
359 INFO("RCW BOOT SRC is FLEXSPI NAND\n");
360 src = BOOT_DEVICE_FLEXSPI_NAND;
361 break;
362 case SDHC1_VAL:
363 src = BOOT_DEVICE_EMMC;
364 INFO("RCW BOOT SRC is SD\n");
365 break;
366 case SDHC2_VAL:
367 src = BOOT_DEVICE_SDHC2_EMMC;
368 INFO("RCW BOOT SRC is EMMC\n");
369 break;
370 default:
371 break;
372 }
373
374 return src;
375 }
376
377
soc_mem_access(void)378 void soc_mem_access(void)
379 {
380 const devdisr5_info_t *devdisr5_info = get_devdisr5_info();
381 dram_regions_info_t *info_dram_regions = get_dram_regions_info();
382 struct tzc400_reg tzc400_reg_list[MAX_NUM_TZC_REGION];
383 int dram_idx, index = 0U;
384
385 for (dram_idx = 0U; dram_idx < info_dram_regions->num_dram_regions;
386 dram_idx++) {
387 if (info_dram_regions->region[dram_idx].size == 0) {
388 ERROR("DDR init failure, or");
389 ERROR("DRAM regions not populated correctly.\n");
390 break;
391 }
392
393 index = populate_tzc400_reg_list(tzc400_reg_list,
394 dram_idx, index,
395 info_dram_regions->region[dram_idx].addr,
396 info_dram_regions->region[dram_idx].size,
397 NXP_SECURE_DRAM_SIZE, NXP_SP_SHRD_DRAM_SIZE);
398 }
399
400 if (devdisr5_info->ddrc1_present != 0) {
401 INFO("DDR Controller 1.\n");
402 mem_access_setup(NXP_TZC_ADDR, index,
403 tzc400_reg_list);
404 mem_access_setup(NXP_TZC3_ADDR, index,
405 tzc400_reg_list);
406 }
407 if (devdisr5_info->ddrc2_present != 0) {
408 INFO("DDR Controller 2.\n");
409 mem_access_setup(NXP_TZC2_ADDR, index,
410 tzc400_reg_list);
411 mem_access_setup(NXP_TZC4_ADDR, index,
412 tzc400_reg_list);
413 }
414 }
415
416 #else
417 const unsigned char _power_domain_tree_desc[] = {1, 8, 2, 2, 2, 2, 2, 2, 2, 2};
418
419 CASSERT(NUMBER_OF_CLUSTERS && NUMBER_OF_CLUSTERS <= 256,
420 assert_invalid_lx2160a_cluster_count);
421
422 /******************************************************************************
423 * This function returns the SoC topology
424 ****************************************************************************/
425
plat_get_power_domain_tree_desc(void)426 const unsigned char *plat_get_power_domain_tree_desc(void)
427 {
428
429 return _power_domain_tree_desc;
430 }
431
432 /*******************************************************************************
433 * This function returns the core count within the cluster corresponding to
434 * `mpidr`.
435 ******************************************************************************/
plat_ls_get_cluster_core_count(u_register_t mpidr)436 unsigned int plat_ls_get_cluster_core_count(u_register_t mpidr)
437 {
438 return CORES_PER_CLUSTER;
439 }
440
441
soc_early_platform_setup2(void)442 void soc_early_platform_setup2(void)
443 {
444 dcfg_init(&dcfg_init_data);
445 /*
446 * Initialize system level generic timer for Socs
447 */
448 delay_timer_init(NXP_TIMER_ADDR);
449
450 #if LOG_LEVEL > 0
451 /* Initialize the console to provide early debug support */
452 plat_console_init(NXP_CONSOLE_ADDR,
453 NXP_UART_CLK_DIVIDER, NXP_CONSOLE_BAUDRATE);
454 #endif
455 }
456
soc_platform_setup(void)457 void soc_platform_setup(void)
458 {
459 /* Initialize the GIC driver, cpu and distributor interfaces */
460 static uintptr_t target_mask_array[PLATFORM_CORE_COUNT];
461 static interrupt_prop_t ls_interrupt_props[] = {
462 PLAT_LS_G1S_IRQ_PROPS(INTR_GROUP1S),
463 PLAT_LS_G0_IRQ_PROPS(INTR_GROUP0)
464 };
465
466 plat_ls_gic_driver_init(NXP_GICD_ADDR, NXP_GICR_ADDR,
467 PLATFORM_CORE_COUNT,
468 ls_interrupt_props,
469 ARRAY_SIZE(ls_interrupt_props),
470 target_mask_array,
471 plat_core_pos);
472
473 plat_ls_gic_init();
474 enable_init_timer();
475 #ifdef LS_SYS_TIMCTL_BASE
476 ls_configure_sys_timer(LS_SYS_TIMCTL_BASE,
477 LS_CONFIG_CNTACR,
478 PLAT_LS_NSTIMER_FRAME_ID);
479 #endif
480 }
481
482 /*******************************************************************************
483 * This function initializes the soc from the BL31 module
484 ******************************************************************************/
soc_init(void)485 void soc_init(void)
486 {
487 uint8_t num_clusters, cores_per_cluster;
488
489 get_cluster_info(soc_list, ARRAY_SIZE(soc_list),
490 &num_clusters, &cores_per_cluster);
491
492 /* low-level init of the soc */
493 soc_init_start();
494 _init_global_data();
495 soc_init_percpu();
496 _initialize_psci();
497
498 if (ccn_get_part0_id(NXP_CCN_ADDR) != CCN_508_PART0_ID) {
499 ERROR("Unrecognized CCN variant detected.");
500 ERROR("Only CCN-508 is supported\n");
501 panic();
502 }
503
504 if (num_clusters == 6U) {
505 ccn_init(&plat_six_cluster_ccn_desc);
506 } else {
507 ccn_init(&plat_ccn_desc);
508 }
509
510 plat_ls_interconnect_enter_coherency(num_clusters);
511
512 /* Set platform security policies */
513 _set_platform_security();
514
515 /* make sure any parallel init tasks are finished */
516 soc_init_finish();
517
518 /* Initialize the crypto accelerator if enabled */
519 if (is_sec_enabled() == false) {
520 INFO("SEC is disabled.\n");
521 } else {
522 sec_init(NXP_CAAM_ADDR);
523 }
524
525 }
526
527 #ifdef NXP_WDOG_RESTART
wdog_interrupt_handler(uint32_t id,uint32_t flags,void * handle,void * cookie)528 static uint64_t wdog_interrupt_handler(uint32_t id, uint32_t flags,
529 void *handle, void *cookie)
530 {
531 uint8_t data = WDOG_RESET_FLAG;
532
533 wr_nv_app_data(WDT_RESET_FLAG_OFFSET,
534 (uint8_t *)&data, sizeof(data));
535
536 mmio_write_32(NXP_RST_ADDR + RSTCNTL_OFFSET, SW_RST_REQ_INIT);
537
538 return 0;
539 }
540 #endif
541
soc_runtime_setup(void)542 void soc_runtime_setup(void)
543 {
544
545 #ifdef NXP_WDOG_RESTART
546 request_intr_type_el3(BL31_NS_WDOG_WS1, wdog_interrupt_handler);
547 #endif
548 }
549 #endif
550