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