blob: eb540e3881f6c19f222f58340cb832b2f5f2d4f1 [file] [log] [blame]
Peng Fan5c2218a2021-08-07 16:00:31 +08001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright 2021 NXP
4 */
5
Peng Fan72530162021-08-07 16:00:33 +08006#include <asm/io.h>
7#include <asm/arch/clock.h>
8#include <asm/arch/imx-regs.h>
Peng Fan5c2218a2021-08-07 16:00:31 +08009#include <asm/arch/sys_proto.h>
Peng Fanb15705a2021-08-07 16:00:35 +080010#include <asm/armv8/mmu.h>
Peng Fan72530162021-08-07 16:00:33 +080011#include <asm/mach-imx/boot_mode.h>
Ye Li88044c72021-08-07 16:01:01 +080012#include <asm/global_data.h>
Ye Li6dd43022021-08-07 16:00:48 +080013#include <efi_loader.h>
Simon Glassfc557362022-03-04 08:43:05 -070014#include <event.h>
Ye Li6dd43022021-08-07 16:00:48 +080015#include <spl.h>
Peng Fan9c87e462021-08-07 16:00:59 +080016#include <asm/arch/rdc.h>
Ye Li853cc9d2021-08-07 16:00:55 +080017#include <asm/arch/s400_api.h>
18#include <asm/arch/mu_hal.h>
19#include <cpu_func.h>
20#include <asm/setup.h>
Ye Li7bea5b02021-08-07 16:01:00 +080021#include <dm.h>
22#include <dm/device-internal.h>
23#include <dm/lists.h>
24#include <dm/uclass.h>
25#include <dm/device.h>
26#include <dm/uclass-internal.h>
Ye Li72012622021-10-29 09:46:15 +080027#include <fuse.h>
Alice Guof2c4a392021-10-29 09:46:32 +080028#include <thermal.h>
Ye Li2e9f15c2022-04-06 14:30:08 +080029#include <linux/iopoll.h>
Peng Fan5c2218a2021-08-07 16:00:31 +080030
Peng Fanb15705a2021-08-07 16:00:35 +080031DECLARE_GLOBAL_DATA_PTR;
32
Ye Li7a71c612021-08-07 16:00:39 +080033struct rom_api *g_rom_api = (struct rom_api *)0x1980;
34
Ye Li88044c72021-08-07 16:01:01 +080035enum boot_device get_boot_device(void)
36{
37 volatile gd_t *pgd = gd;
38 int ret;
39 u32 boot;
40 u16 boot_type;
41 u8 boot_instance;
42 enum boot_device boot_dev = SD1_BOOT;
43
44 ret = g_rom_api->query_boot_infor(QUERY_BT_DEV, &boot,
45 ((uintptr_t)&boot) ^ QUERY_BT_DEV);
46 set_gd(pgd);
47
48 if (ret != ROM_API_OKAY) {
49 puts("ROMAPI: failure at query_boot_info\n");
50 return -1;
51 }
52
53 boot_type = boot >> 16;
54 boot_instance = (boot >> 8) & 0xff;
55
56 switch (boot_type) {
57 case BT_DEV_TYPE_SD:
58 boot_dev = boot_instance + SD1_BOOT;
59 break;
60 case BT_DEV_TYPE_MMC:
61 boot_dev = boot_instance + MMC1_BOOT;
62 break;
63 case BT_DEV_TYPE_NAND:
64 boot_dev = NAND_BOOT;
65 break;
66 case BT_DEV_TYPE_FLEXSPINOR:
67 boot_dev = QSPI_BOOT;
68 break;
69 case BT_DEV_TYPE_USB:
70 boot_dev = USB_BOOT;
71 break;
72 default:
73 break;
74 }
75
76 return boot_dev;
77}
78
79bool is_usb_boot(void)
80{
81 return get_boot_device() == USB_BOOT;
82}
83
84#ifdef CONFIG_ENV_IS_IN_MMC
85__weak int board_mmc_get_env_dev(int devno)
86{
87 return devno;
88}
89
90int mmc_get_env_dev(void)
91{
92 volatile gd_t *pgd = gd;
93 int ret;
94 u32 boot;
95 u16 boot_type;
96 u8 boot_instance;
97
98 ret = g_rom_api->query_boot_infor(QUERY_BT_DEV, &boot,
99 ((uintptr_t)&boot) ^ QUERY_BT_DEV);
100 set_gd(pgd);
101
102 if (ret != ROM_API_OKAY) {
103 puts("ROMAPI: failure at query_boot_info\n");
104 return CONFIG_SYS_MMC_ENV_DEV;
105 }
106
107 boot_type = boot >> 16;
108 boot_instance = (boot >> 8) & 0xff;
109
110 /* If not boot from sd/mmc, use default value */
111 if (boot_type != BOOT_TYPE_SD && boot_type != BOOT_TYPE_MMC)
112 return env_get_ulong("mmcdev", 10, CONFIG_SYS_MMC_ENV_DEV);
113
114 return board_mmc_get_env_dev(boot_instance);
115}
116#endif
117
Peng Fan5c2218a2021-08-07 16:00:31 +0800118u32 get_cpu_rev(void)
119{
120 return (MXC_CPU_IMX8ULP << 12) | CHIP_REV_1_0;
121}
Peng Fan72530162021-08-07 16:00:33 +0800122
123enum bt_mode get_boot_mode(void)
124{
125 u32 bt0_cfg = 0;
126
Ye Li0e358052021-08-07 16:01:07 +0800127 bt0_cfg = readl(SIM_SEC_BASE_ADDR + 0x24);
Peng Fan72530162021-08-07 16:00:33 +0800128 bt0_cfg &= (BT0CFG_LPBOOT_MASK | BT0CFG_DUALBOOT_MASK);
129
130 if (!(bt0_cfg & BT0CFG_LPBOOT_MASK)) {
131 /* No low power boot */
132 if (bt0_cfg & BT0CFG_DUALBOOT_MASK)
133 return DUAL_BOOT;
134 else
135 return SINGLE_BOOT;
136 }
137
138 return LOW_POWER_BOOT;
139}
140
Ye Li2e9f15c2022-04-06 14:30:08 +0800141bool m33_image_booted(void)
142{
143 u32 gp6;
144
145 /* DGO_GP6 */
146 gp6 = readl(SIM_SEC_BASE_ADDR + 0x28);
147 if (gp6 & BIT(5))
148 return true;
149
150 return false;
151}
152
153int m33_image_handshake(ulong timeout_ms)
154{
155 u32 fsr;
156 int ret;
157 ulong timeout_us = timeout_ms * 1000;
158
Ye Li2e9f15c2022-04-06 14:30:08 +0800159 /* Notify m33 that it's ready to do init srtm(enable mu receive interrupt and so on) */
160 setbits_le32(MU0_B_BASE_ADDR + 0x100, BIT(0)); /* set FCR F0 flag of MU0_MUB */
161
162 /*
163 * Wait m33 to set FCR F0 flag of MU0_MUA
164 * Clear FCR F0 flag of MU0_MUB after m33 has set FCR F0 flag of MU0_MUA
165 */
166 ret = readl_poll_sleep_timeout(MU0_B_BASE_ADDR + 0x104, fsr, fsr & BIT(0), 10, timeout_us);
167 if (!ret)
168 clrbits_le32(MU0_B_BASE_ADDR + 0x100, BIT(0));
169
170 return ret;
171}
172
Peng Fanaf4f3b32021-08-07 16:00:34 +0800173#define CMC_SRS_TAMPER BIT(31)
174#define CMC_SRS_SECURITY BIT(30)
175#define CMC_SRS_TZWDG BIT(29)
176#define CMC_SRS_JTAG_RST BIT(28)
177#define CMC_SRS_CORE1 BIT(16)
178#define CMC_SRS_LOCKUP BIT(15)
179#define CMC_SRS_SW BIT(14)
180#define CMC_SRS_WDG BIT(13)
181#define CMC_SRS_PIN_RESET BIT(8)
182#define CMC_SRS_WARM BIT(4)
183#define CMC_SRS_HVD BIT(3)
184#define CMC_SRS_LVD BIT(2)
185#define CMC_SRS_POR BIT(1)
186#define CMC_SRS_WUP BIT(0)
187
Peng Fanaf4f3b32021-08-07 16:00:34 +0800188static char *get_reset_cause(char *ret)
189{
190 u32 cause1, cause = 0, srs = 0;
Peng Fanb15705a2021-08-07 16:00:35 +0800191 void __iomem *reg_ssrs = (void __iomem *)(CMC1_BASE_ADDR + 0x88);
192 void __iomem *reg_srs = (void __iomem *)(CMC1_BASE_ADDR + 0x80);
Peng Fanaf4f3b32021-08-07 16:00:34 +0800193
194 if (!ret)
195 return "null";
196
197 srs = readl(reg_srs);
198 cause1 = readl(reg_ssrs);
199
Peng Fan0d720e22021-08-07 16:01:06 +0800200 cause = srs & (CMC_SRS_POR | CMC_SRS_WUP | CMC_SRS_WARM);
Peng Fanaf4f3b32021-08-07 16:00:34 +0800201
202 switch (cause) {
203 case CMC_SRS_POR:
204 sprintf(ret, "%s", "POR");
205 break;
206 case CMC_SRS_WUP:
207 sprintf(ret, "%s", "WUP");
208 break;
209 case CMC_SRS_WARM:
Peng Fan0d720e22021-08-07 16:01:06 +0800210 cause = srs & (CMC_SRS_WDG | CMC_SRS_SW |
Peng Fanaf4f3b32021-08-07 16:00:34 +0800211 CMC_SRS_JTAG_RST);
212 switch (cause) {
213 case CMC_SRS_WDG:
214 sprintf(ret, "%s", "WARM-WDG");
215 break;
216 case CMC_SRS_SW:
217 sprintf(ret, "%s", "WARM-SW");
218 break;
219 case CMC_SRS_JTAG_RST:
220 sprintf(ret, "%s", "WARM-JTAG");
221 break;
222 default:
223 sprintf(ret, "%s", "WARM-UNKN");
224 break;
225 }
226 break;
227 default:
Peng Fan0d720e22021-08-07 16:01:06 +0800228 sprintf(ret, "%s-%X", "UNKN", srs);
Peng Fanaf4f3b32021-08-07 16:00:34 +0800229 break;
230 }
231
232 debug("[%X] SRS[%X] %X - ", cause1, srs, srs ^ cause1);
233 return ret;
234}
235
Peng Fan72530162021-08-07 16:00:33 +0800236#if defined(CONFIG_DISPLAY_CPUINFO)
237const char *get_imx_type(u32 imxtype)
238{
239 return "8ULP";
240}
241
242int print_cpuinfo(void)
243{
244 u32 cpurev;
245 char cause[18];
246
247 cpurev = get_cpu_rev();
248
Ye Lif012ceb2021-10-29 09:46:24 +0800249 printf("CPU: i.MX%s rev%d.%d at %d MHz\n",
Peng Fan72530162021-08-07 16:00:33 +0800250 get_imx_type((cpurev & 0xFF000) >> 12),
251 (cpurev & 0x000F0) >> 4, (cpurev & 0x0000F) >> 0,
252 mxc_get_clock(MXC_ARM_CLK) / 1000000);
253
Alice Guof2c4a392021-10-29 09:46:32 +0800254#if defined(CONFIG_IMX_PMC_TEMPERATURE)
255 struct udevice *udev;
256 int ret, temp;
257
258 ret = uclass_get_device(UCLASS_THERMAL, 0, &udev);
259 if (!ret) {
260 ret = thermal_get_temp(udev, &temp);
261 if (!ret)
262 printf("CPU current temperature: %d\n", temp);
263 else
264 debug(" - failed to get CPU current temperature\n");
265 } else {
266 debug(" - failed to get CPU current temperature\n");
267 }
268#endif
269
Peng Fanaf4f3b32021-08-07 16:00:34 +0800270 printf("Reset cause: %s\n", get_reset_cause(cause));
271
Peng Fan72530162021-08-07 16:00:33 +0800272 printf("Boot mode: ");
273 switch (get_boot_mode()) {
274 case LOW_POWER_BOOT:
275 printf("Low power boot\n");
276 break;
277 case DUAL_BOOT:
278 printf("Dual boot\n");
279 break;
280 case SINGLE_BOOT:
281 default:
282 printf("Single boot\n");
283 break;
284 }
285
286 return 0;
287}
288#endif
Peng Fanb15705a2021-08-07 16:00:35 +0800289
Peng Fanc84bc102021-08-07 16:00:49 +0800290#define UNLOCK_WORD0 0xC520 /* 1st unlock word */
291#define UNLOCK_WORD1 0xD928 /* 2nd unlock word */
292#define REFRESH_WORD0 0xA602 /* 1st refresh word */
293#define REFRESH_WORD1 0xB480 /* 2nd refresh word */
294
295static void disable_wdog(void __iomem *wdog_base)
296{
297 u32 val_cs = readl(wdog_base + 0x00);
298
299 if (!(val_cs & 0x80))
300 return;
301
302 dmb();
303 __raw_writel(REFRESH_WORD0, (wdog_base + 0x04)); /* Refresh the CNT */
304 __raw_writel(REFRESH_WORD1, (wdog_base + 0x04));
305 dmb();
306
307 if (!(val_cs & 800)) {
308 dmb();
309 __raw_writel(UNLOCK_WORD0, (wdog_base + 0x04));
310 __raw_writel(UNLOCK_WORD1, (wdog_base + 0x04));
311 dmb();
312
313 while (!(readl(wdog_base + 0x00) & 0x800))
314 ;
315 }
316 writel(0x0, (wdog_base + 0x0C)); /* Set WIN to 0 */
317 writel(0x400, (wdog_base + 0x08)); /* Set timeout to default 0x400 */
318 writel(0x120, (wdog_base + 0x00)); /* Disable it and set update */
319
320 while (!(readl(wdog_base + 0x00) & 0x400))
321 ;
322}
323
Peng Fanb15705a2021-08-07 16:00:35 +0800324void init_wdog(void)
325{
Peng Fanc84bc102021-08-07 16:00:49 +0800326 disable_wdog((void __iomem *)WDG3_RBASE);
Peng Fanb15705a2021-08-07 16:00:35 +0800327}
328
329static struct mm_region imx8ulp_arm64_mem_map[] = {
330 {
331 /* ROM */
332 .virt = 0x0,
333 .phys = 0x0,
334 .size = 0x40000UL,
335 .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
336 PTE_BLOCK_OUTER_SHARE
337 },
338 {
339 /* FLEXSPI0 */
340 .virt = 0x04000000,
341 .phys = 0x04000000,
342 .size = 0x08000000UL,
343 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
344 PTE_BLOCK_NON_SHARE |
345 PTE_BLOCK_PXN | PTE_BLOCK_UXN
346 },
347 {
348 /* SSRAM (align with 2M) */
349 .virt = 0x1FE00000UL,
350 .phys = 0x1FE00000UL,
351 .size = 0x400000UL,
352 .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
353 PTE_BLOCK_OUTER_SHARE |
354 PTE_BLOCK_PXN | PTE_BLOCK_UXN
355 }, {
356 /* SRAM1 (align with 2M) */
357 .virt = 0x21000000UL,
358 .phys = 0x21000000UL,
359 .size = 0x200000UL,
360 .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
361 PTE_BLOCK_OUTER_SHARE |
362 PTE_BLOCK_PXN | PTE_BLOCK_UXN
363 }, {
364 /* SRAM0 (align with 2M) */
365 .virt = 0x22000000UL,
366 .phys = 0x22000000UL,
367 .size = 0x200000UL,
368 .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
369 PTE_BLOCK_OUTER_SHARE |
370 PTE_BLOCK_PXN | PTE_BLOCK_UXN
371 }, {
372 /* Peripherals */
373 .virt = 0x27000000UL,
374 .phys = 0x27000000UL,
375 .size = 0x3000000UL,
376 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
377 PTE_BLOCK_NON_SHARE |
378 PTE_BLOCK_PXN | PTE_BLOCK_UXN
379 }, {
380 /* Peripherals */
381 .virt = 0x2D000000UL,
382 .phys = 0x2D000000UL,
383 .size = 0x1600000UL,
384 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
385 PTE_BLOCK_NON_SHARE |
386 PTE_BLOCK_PXN | PTE_BLOCK_UXN
387 }, {
388 /* FLEXSPI1-2 */
389 .virt = 0x40000000UL,
390 .phys = 0x40000000UL,
391 .size = 0x40000000UL,
392 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
393 PTE_BLOCK_NON_SHARE |
394 PTE_BLOCK_PXN | PTE_BLOCK_UXN
395 }, {
396 /* DRAM1 */
397 .virt = 0x80000000UL,
398 .phys = 0x80000000UL,
399 .size = PHYS_SDRAM_SIZE,
400 .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
401 PTE_BLOCK_OUTER_SHARE
402 }, {
403 /*
404 * empty entrie to split table entry 5
405 * if needed when TEEs are used
406 */
407 0,
408 }, {
409 /* List terminator */
410 0,
411 }
412};
413
414struct mm_region *mem_map = imx8ulp_arm64_mem_map;
415
416/* simplify the page table size to enhance boot speed */
417#define MAX_PTE_ENTRIES 512
418#define MAX_MEM_MAP_REGIONS 16
419u64 get_page_table_size(void)
420{
421 u64 one_pt = MAX_PTE_ENTRIES * sizeof(u64);
422 u64 size = 0;
423
424 /*
425 * For each memory region, the max table size:
426 * 2 level 3 tables + 2 level 2 tables + 1 level 1 table
427 */
428 size = (2 + 2 + 1) * one_pt * MAX_MEM_MAP_REGIONS + one_pt;
429
430 /*
431 * We need to duplicate our page table once to have an emergency pt to
432 * resort to when splitting page tables later on
433 */
434 size *= 2;
435
436 /*
437 * We may need to split page tables later on if dcache settings change,
438 * so reserve up to 4 (random pick) page tables for that.
439 */
440 size += one_pt * 4;
441
442 return size;
443}
444
445void enable_caches(void)
446{
447 /* TODO: add TEE memmap region */
448
449 icache_enable();
450 dcache_enable();
451}
452
453int dram_init(void)
454{
455 gd->ram_size = PHYS_SDRAM_SIZE;
456
457 return 0;
458}
459
Tom Riniae21e7f2021-08-30 09:16:29 -0400460#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
Peng Fanb15705a2021-08-07 16:00:35 +0800461void get_board_serial(struct tag_serialnr *serialnr)
462{
Ye Li7bea5b02021-08-07 16:01:00 +0800463 u32 uid[4];
464 u32 res;
465 int ret;
466
467 ret = ahab_read_common_fuse(1, uid, 4, &res);
468 if (ret)
469 printf("ahab read fuse failed %d, 0x%x\n", ret, res);
470 else
471 printf("UID 0x%x,0x%x,0x%x,0x%x\n", uid[0], uid[1], uid[2], uid[3]);
472
473 serialnr->low = uid[0];
474 serialnr->high = uid[3];
Peng Fanb15705a2021-08-07 16:00:35 +0800475}
476#endif
477
Ye Li6ee435eb2021-08-07 16:00:50 +0800478static void set_core0_reset_vector(u32 entry)
Peng Fanb15705a2021-08-07 16:00:35 +0800479{
Ye Li6dd43022021-08-07 16:00:48 +0800480 /* Update SIM1 DGO8 for reset vector base */
Ye Li6ee435eb2021-08-07 16:00:50 +0800481 writel(entry, SIM1_BASE_ADDR + 0x5c);
Ye Li6dd43022021-08-07 16:00:48 +0800482
483 /* set update bit */
484 setbits_le32(SIM1_BASE_ADDR + 0x8, 0x1 << 24);
485
486 /* polling the ack */
487 while ((readl(SIM1_BASE_ADDR + 0x8) & (0x1 << 26)) == 0)
488 ;
489
490 /* clear the update */
491 clrbits_le32(SIM1_BASE_ADDR + 0x8, (0x1 << 24));
492
493 /* clear the ack by set 1 */
494 setbits_le32(SIM1_BASE_ADDR + 0x8, (0x1 << 26));
Ye Li6ee435eb2021-08-07 16:00:50 +0800495}
496
Peng Fan9c87e462021-08-07 16:00:59 +0800497static int trdc_set_access(void)
Peng Fanb5c41b12021-08-07 16:00:58 +0800498{
499 /*
Peng Fan9c87e462021-08-07 16:00:59 +0800500 * TRDC mgr + 4 MBC + 2 MRC.
501 * S400 should already configure when release RDC
502 * A35 only map non-secure region for pbridge0 and 1, set sec_access to false
Peng Fanb5c41b12021-08-07 16:00:58 +0800503 */
Peng Fan9c87e462021-08-07 16:00:59 +0800504 trdc_mbc_set_access(2, 7, 0, 49, false);
505 trdc_mbc_set_access(2, 7, 0, 50, false);
506 trdc_mbc_set_access(2, 7, 0, 51, false);
507 trdc_mbc_set_access(2, 7, 0, 52, false);
508 trdc_mbc_set_access(2, 7, 0, 53, false);
509 trdc_mbc_set_access(2, 7, 0, 54, false);
Peng Fanb5c41b12021-08-07 16:00:58 +0800510
Peng Fan9c87e462021-08-07 16:00:59 +0800511 /* CGC0: PBridge0 slot 47 */
512 trdc_mbc_set_access(2, 7, 0, 47, false);
Peng Fanb5c41b12021-08-07 16:00:58 +0800513
Peng Fan9c87e462021-08-07 16:00:59 +0800514 /* Iomuxc0: : PBridge1 slot 33 */
515 trdc_mbc_set_access(2, 7, 1, 33, false);
Peng Fanb5c41b12021-08-07 16:00:58 +0800516
Ye Lid325d372021-10-29 09:46:20 +0800517 /* flexspi0 */
518 trdc_mrc_region_set_access(0, 7, 0x04000000, 0x0c000000, false);
Ye Li27666ca2021-10-29 09:46:21 +0800519
520 /* tpm0: PBridge1 slot 21 */
521 trdc_mbc_set_access(2, 7, 1, 21, false);
522 /* lpi2c0: PBridge1 slot 24 */
523 trdc_mbc_set_access(2, 7, 1, 24, false);
Peng Fanb5c41b12021-08-07 16:00:58 +0800524 return 0;
525}
526
Ye Liec10a802022-04-06 14:30:17 +0800527void lpav_configure(bool lpav_to_m33)
Ye Li43819eb2021-10-29 09:46:16 +0800528{
Ye Liec10a802022-04-06 14:30:17 +0800529 if (!lpav_to_m33)
530 setbits_le32(SIM_SEC_BASE_ADDR + 0x44, BIT(7)); /* LPAV to APD */
Ye Li43819eb2021-10-29 09:46:16 +0800531
Peng Fanfa609b42021-10-29 09:46:17 +0800532 /* PXP/GPU 2D/3D/DCNANO/MIPI_DSI/EPDC/HIFI4 to APD */
533 setbits_le32(SIM_SEC_BASE_ADDR + 0x4c, 0x7F);
Ye Li43819eb2021-10-29 09:46:16 +0800534
535 /* LPAV slave/dma2 ch allocation and request allocation to APD */
536 writel(0x1f, SIM_SEC_BASE_ADDR + 0x50);
537 writel(0xffffffff, SIM_SEC_BASE_ADDR + 0x54);
538 writel(0x003fffff, SIM_SEC_BASE_ADDR + 0x58);
Ye Li715cfa02021-10-29 09:46:23 +0800539}
Ye Lia0311552021-10-29 09:46:22 +0800540
Ye Li133f8b82021-10-29 09:46:25 +0800541void load_lposc_fuse(void)
542{
543 int ret;
544 u32 val = 0, val2 = 0, reg;
545
546 ret = fuse_read(25, 0, &val);
547 if (ret)
548 return; /* failed */
549
550 ret = fuse_read(25, 1, &val2);
551 if (ret)
552 return; /* failed */
553
554 /* LPOSCCTRL */
555 reg = readl(0x2802f304);
556 reg &= ~0xff;
557 reg |= (val & 0xff);
558 writel(reg, 0x2802f304);
559}
560
Ye Li715cfa02021-10-29 09:46:23 +0800561void set_lpav_qos(void)
562{
Ye Lia0311552021-10-29 09:46:22 +0800563 /* Set read QoS of dcnano on LPAV NIC */
564 writel(0xf, 0x2e447100);
Ye Li43819eb2021-10-29 09:46:16 +0800565}
566
Ye Li6ee435eb2021-08-07 16:00:50 +0800567int arch_cpu_init(void)
568{
569 if (IS_ENABLED(CONFIG_SPL_BUILD)) {
Ye Li72012622021-10-29 09:46:15 +0800570 u32 val = 0;
571 int ret;
572 bool rdc_en = true; /* Default assume DBD_EN is set */
573
Ye Li853cc9d2021-08-07 16:00:55 +0800574 /* Disable wdog */
575 init_wdog();
576
Ye Li72012622021-10-29 09:46:15 +0800577 /* Read DBD_EN fuse */
578 ret = fuse_read(8, 1, &val);
579 if (!ret)
580 rdc_en = !!(val & 0x4000);
581
Peng Fanb5c41b12021-08-07 16:00:58 +0800582 if (get_boot_mode() == SINGLE_BOOT) {
Ye Li72012622021-10-29 09:46:15 +0800583 if (rdc_en)
584 release_rdc(RDC_TRDC);
585
Peng Fanb5c41b12021-08-07 16:00:58 +0800586 trdc_set_access();
Ye Liec10a802022-04-06 14:30:17 +0800587 lpav_configure(false);
588 } else {
589 lpav_configure(true);
Peng Fanb5c41b12021-08-07 16:00:58 +0800590 }
Peng Fanfa55b212021-08-07 16:00:57 +0800591
Ye Li72012622021-10-29 09:46:15 +0800592 /* Release xrdc, then allow A35 to write SRAM2 */
593 if (rdc_en)
594 release_rdc(RDC_XRDC);
595
Ye Li853cc9d2021-08-07 16:00:55 +0800596 xrdc_mrc_region_set_access(2, CONFIG_SPL_TEXT_BASE, 0xE00);
597
Peng Fan4cdb3a32022-04-06 14:30:12 +0800598 clock_init_early();
Ye Li6ee435eb2021-08-07 16:00:50 +0800599 } else {
600 /* reconfigure core0 reset vector to ROM */
601 set_core0_reset_vector(0x1000);
602 }
603
604 return 0;
605}
606
Simon Glassfc557362022-03-04 08:43:05 -0700607static int imx8ulp_check_mu(void *ctx, struct event *event)
Ye Li7bea5b02021-08-07 16:01:00 +0800608{
609 struct udevice *devp;
610 int node, ret;
611
612 node = fdt_node_offset_by_compatible(gd->fdt_blob, -1, "fsl,imx8ulp-mu");
613
614 ret = uclass_get_device_by_of_offset(UCLASS_MISC, node, &devp);
615 if (ret) {
616 printf("could not get S400 mu %d\n", ret);
617 return ret;
618 }
619
620 return 0;
621}
Simon Glassfc557362022-03-04 08:43:05 -0700622EVENT_SPY(EVT_DM_POST_INIT, imx8ulp_check_mu);
Ye Li7bea5b02021-08-07 16:01:00 +0800623
Ye Li6ee435eb2021-08-07 16:00:50 +0800624#if defined(CONFIG_SPL_BUILD)
625__weak void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
626{
627 debug("image entry point: 0x%lx\n", spl_image->entry_point);
628
629 set_core0_reset_vector((u32)spl_image->entry_point);
Ye Li6dd43022021-08-07 16:00:48 +0800630
631 /* Enable the 512KB cache */
632 setbits_le32(SIM1_BASE_ADDR + 0x30, (0x1 << 4));
633
634 /* reset core */
635 setbits_le32(SIM1_BASE_ADDR + 0x30, (0x1 << 16));
636
637 while (1)
638 ;
639}
640#endif
Peng Fanfa6ae052021-08-07 16:01:03 +0800641
642void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
643{
Ye Li992b0ae2021-10-29 09:46:28 +0800644 u32 val[2] = {};
645 int ret;
646
647 ret = fuse_read(5, 3, &val[0]);
648 if (ret)
649 goto err;
650
651 ret = fuse_read(5, 4, &val[1]);
652 if (ret)
653 goto err;
654
655 mac[0] = val[0];
656 mac[1] = val[0] >> 8;
657 mac[2] = val[0] >> 16;
658 mac[3] = val[0] >> 24;
659 mac[4] = val[1];
660 mac[5] = val[1] >> 8;
661
662 debug("%s: MAC%d: %02x.%02x.%02x.%02x.%02x.%02x\n",
663 __func__, dev_id, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
664 return;
665err:
Peng Fanfa6ae052021-08-07 16:01:03 +0800666 memset(mac, 0, 6);
Ye Li992b0ae2021-10-29 09:46:28 +0800667 printf("%s: fuse read err: %d\n", __func__, ret);
Peng Fanfa6ae052021-08-07 16:01:03 +0800668}
Ye Li479fd4a2021-08-07 16:01:08 +0800669
670int (*card_emmc_is_boot_part_en)(void) = (void *)0x67cc;
671u32 spl_arch_boot_image_offset(u32 image_offset, u32 rom_bt_dev)
672{
673 /* Hard code for eMMC image_offset on 8ULP ROM, need fix by ROM, temp workaround */
674 if (((rom_bt_dev >> 16) & 0xff) == BT_DEV_TYPE_MMC && card_emmc_is_boot_part_en())
675 image_offset = 0;
676
677 return image_offset;
678}