]> git.ipfire.org Git - thirdparty/u-boot.git/blame - arch/arm/mach-imx/imx8m/soc.c
caam: Fix crash in case caam_jr_probe failed
[thirdparty/u-boot.git] / arch / arm / mach-imx / imx8m / soc.c
CommitLineData
83d290c5 1// SPDX-License-Identifier: GPL-2.0+
fcdbde7c 2/*
2cddfcbc 3 * Copyright 2017-2019, 2021 NXP
fcdbde7c
PF
4 *
5 * Peng Fan <peng.fan@nxp.com>
fcdbde7c
PF
6 */
7
8#include <common.h>
9edefc27 9#include <cpu_func.h>
7fe32b34 10#include <event.h>
691d719d 11#include <init.h>
f7ae49fc 12#include <log.h>
fcdbde7c 13#include <asm/arch/imx-regs.h>
401d1c4f 14#include <asm/global_data.h>
fcdbde7c
PF
15#include <asm/io.h>
16#include <asm/arch/clock.h>
17#include <asm/arch/sys_proto.h>
18#include <asm/mach-imx/hab.h>
19#include <asm/mach-imx/boot_mode.h>
20#include <asm/mach-imx/syscounter.h>
2f3c9206 21#include <asm/ptrace.h>
fcdbde7c 22#include <asm/armv8/mmu.h>
e663c703 23#include <dm/uclass.h>
2cddfcbc 24#include <dm/device.h>
2f3c9206 25#include <efi_loader.h>
2707faf0
YL
26#include <env.h>
27#include <env_internal.h>
fcdbde7c
PF
28#include <errno.h>
29#include <fdt_support.h>
30#include <fsl_wdog.h>
31#include <imx_sip.h>
cd93d625 32#include <linux/bitops.h>
fcdbde7c
PF
33
34DECLARE_GLOBAL_DATA_PTR;
35
d714a75f 36#if defined(CONFIG_IMX_HAB)
fcdbde7c
PF
37struct imx_sec_config_fuse_t const imx_sec_config_fuse = {
38 .bank = 1,
39 .word = 3,
40};
41#endif
42
43int timer_init(void)
44{
45#ifdef CONFIG_SPL_BUILD
46 struct sctr_regs *sctr = (struct sctr_regs *)SYSCNT_CTRL_BASE_ADDR;
47 unsigned long freq = readl(&sctr->cntfid0);
48
49 /* Update with accurate clock frequency */
50 asm volatile("msr cntfrq_el0, %0" : : "r" (freq) : "memory");
51
52 clrsetbits_le32(&sctr->cntcr, SC_CNTCR_FREQ0 | SC_CNTCR_FREQ1,
53 SC_CNTCR_FREQ0 | SC_CNTCR_ENABLE | SC_CNTCR_HDBG);
54#endif
55
56 gd->arch.tbl = 0;
57 gd->arch.tbu = 0;
58
59 return 0;
60}
61
62void enable_tzc380(void)
63{
64 struct iomuxc_gpr_base_regs *gpr =
65 (struct iomuxc_gpr_base_regs *)IOMUXC_GPR_BASE_ADDR;
66
67 /* Enable TZASC and lock setting */
68 setbits_le32(&gpr->gpr[10], GPR_TZASC_EN);
69 setbits_le32(&gpr->gpr[10], GPR_TZASC_EN_LOCK);
1289ff7b
AZ
70
71 /*
72 * According to TRM, TZASC_ID_SWAP_BYPASS should be set in
73 * order to avoid AXI Bus errors when GPU is in use
74 */
a1d675ac 75 setbits_le32(&gpr->gpr[10], GPR_TZASC_ID_SWAP_BYPASS);
1289ff7b
AZ
76
77 /*
78 * imx8mn and imx8mp implements the lock bit for
79 * TZASC_ID_SWAP_BYPASS, enable it to lock settings
80 */
a1d675ac 81 setbits_le32(&gpr->gpr[10], GPR_TZASC_ID_SWAP_BYPASS_LOCK);
1289ff7b 82
b3cf0a8f
YL
83 /*
84 * set Region 0 attribute to allow secure and non-secure
85 * read/write permission. Found some masters like usb dwc3
86 * controllers can't work with secure memory.
87 */
88 writel(0xf0000000, TZASC_BASE_ADDR + 0x108);
fcdbde7c
PF
89}
90
91void set_wdog_reset(struct wdog_regs *wdog)
92{
93 /*
94 * Output WDOG_B signal to reset external pmic or POR_B decided by
95 * the board design. Without external reset, the peripherals/DDR/
96 * PMIC are not reset, that may cause system working abnormal.
97 * WDZST bit is write-once only bit. Align this bit in kernel,
98 * otherwise kernel code will have no chance to set this bit.
99 */
100 setbits_le16(&wdog->wcr, WDOG_WDT_MASK | WDOG_WDZST_MASK);
101}
102
103static struct mm_region imx8m_mem_map[] = {
104 {
105 /* ROM */
106 .virt = 0x0UL,
107 .phys = 0x0UL,
108 .size = 0x100000UL,
109 .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
110 PTE_BLOCK_OUTER_SHARE
cb15885b
GB
111 }, {
112 /* CAAM */
113 .virt = 0x100000UL,
114 .phys = 0x100000UL,
115 .size = 0x8000UL,
116 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
117 PTE_BLOCK_NON_SHARE |
118 PTE_BLOCK_PXN | PTE_BLOCK_UXN
09d86eab
MV
119 }, {
120 /* OCRAM_S */
121 .virt = 0x180000UL,
122 .phys = 0x180000UL,
123 .size = 0x8000UL,
124 .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
125 PTE_BLOCK_OUTER_SHARE
cb15885b
GB
126 }, {
127 /* TCM */
128 .virt = 0x7C0000UL,
129 .phys = 0x7C0000UL,
130 .size = 0x80000UL,
131 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
132 PTE_BLOCK_NON_SHARE |
133 PTE_BLOCK_PXN | PTE_BLOCK_UXN
fcdbde7c
PF
134 }, {
135 /* OCRAM */
136 .virt = 0x900000UL,
137 .phys = 0x900000UL,
138 .size = 0x200000UL,
139 .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
140 PTE_BLOCK_OUTER_SHARE
141 }, {
142 /* AIPS */
143 .virt = 0xB00000UL,
144 .phys = 0xB00000UL,
145 .size = 0x3f500000UL,
146 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
147 PTE_BLOCK_NON_SHARE |
148 PTE_BLOCK_PXN | PTE_BLOCK_UXN
149 }, {
150 /* DRAM1 */
151 .virt = 0x40000000UL,
152 .phys = 0x40000000UL,
59efa6b5 153 .size = PHYS_SDRAM_SIZE,
fcdbde7c
PF
154 .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
155 PTE_BLOCK_OUTER_SHARE
59efa6b5 156#ifdef PHYS_SDRAM_2_SIZE
fcdbde7c
PF
157 }, {
158 /* DRAM2 */
159 .virt = 0x100000000UL,
160 .phys = 0x100000000UL,
59efa6b5 161 .size = PHYS_SDRAM_2_SIZE,
fcdbde7c
PF
162 .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
163 PTE_BLOCK_OUTER_SHARE
59efa6b5 164#endif
3c41728d
PF
165 }, {
166 /* empty entrie to split table entry 5 if needed when TEEs are used */
167 0,
fcdbde7c
PF
168 }, {
169 /* List terminator */
170 0,
171 }
172};
173
174struct mm_region *mem_map = imx8m_mem_map;
175
076dc92a
MV
176static unsigned int imx8m_find_dram_entry_in_mem_map(void)
177{
178 int i;
179
180 for (i = 0; i < ARRAY_SIZE(imx8m_mem_map); i++)
181 if (imx8m_mem_map[i].phys == CONFIG_SYS_SDRAM_BASE)
182 return i;
183
184 hang(); /* Entry not found, this must never happen. */
185}
186
59efa6b5
PF
187void enable_caches(void)
188{
1c9bc0ff
YL
189 /* If OPTEE runs, remove OPTEE memory from MMU table to avoid speculative prefetch
190 * If OPTEE does not run, still update the MMU table according to dram banks structure
191 * to set correct dram size from board_phys_sdram_size
192 */
193 int i = 0;
194 /*
195 * please make sure that entry initial value matches
196 * imx8m_mem_map for DRAM1
197 */
198 int entry = imx8m_find_dram_entry_in_mem_map();
199 u64 attrs = imx8m_mem_map[entry].attrs;
200
201 while (i < CONFIG_NR_DRAM_BANKS &&
202 entry < ARRAY_SIZE(imx8m_mem_map)) {
203 if (gd->bd->bi_dram[i].start == 0)
204 break;
205 imx8m_mem_map[entry].phys = gd->bd->bi_dram[i].start;
206 imx8m_mem_map[entry].virt = gd->bd->bi_dram[i].start;
207 imx8m_mem_map[entry].size = gd->bd->bi_dram[i].size;
208 imx8m_mem_map[entry].attrs = attrs;
209 debug("Added memory mapping (%d): %llx %llx\n", entry,
210 imx8m_mem_map[entry].phys, imx8m_mem_map[entry].size);
211 i++; entry++;
3c41728d 212 }
59efa6b5
PF
213
214 icache_enable();
215 dcache_enable();
216}
217
3c41728d
PF
218__weak int board_phys_sdram_size(phys_size_t *size)
219{
220 if (!size)
221 return -EINVAL;
222
223 *size = PHYS_SDRAM_SIZE;
1c9bc0ff
YL
224
225#ifdef PHYS_SDRAM_2_SIZE
226 *size += PHYS_SDRAM_2_SIZE;
227#endif
3c41728d
PF
228 return 0;
229}
230
231int dram_init(void)
232{
233 phys_size_t sdram_size;
234 int ret;
235
236 ret = board_phys_sdram_size(&sdram_size);
237 if (ret)
238 return ret;
239
240 /* rom_pointer[1] contains the size of TEE occupies */
241 if (rom_pointer[1])
242 gd->ram_size = sdram_size - rom_pointer[1];
243 else
244 gd->ram_size = sdram_size;
245
3c41728d
PF
246 return 0;
247}
248
249int dram_init_banksize(void)
250{
251 int bank = 0;
252 int ret;
253 phys_size_t sdram_size;
1c9bc0ff 254 phys_size_t sdram_b1_size, sdram_b2_size;
3c41728d
PF
255
256 ret = board_phys_sdram_size(&sdram_size);
257 if (ret)
258 return ret;
259
1c9bc0ff
YL
260 /* Bank 1 can't cross over 4GB space */
261 if (sdram_size > 0xc0000000) {
262 sdram_b1_size = 0xc0000000;
263 sdram_b2_size = sdram_size - 0xc0000000;
264 } else {
265 sdram_b1_size = sdram_size;
266 sdram_b2_size = 0;
267 }
268
3c41728d
PF
269 gd->bd->bi_dram[bank].start = PHYS_SDRAM;
270 if (rom_pointer[1]) {
271 phys_addr_t optee_start = (phys_addr_t)rom_pointer[0];
272 phys_size_t optee_size = (size_t)rom_pointer[1];
273
274 gd->bd->bi_dram[bank].size = optee_start - gd->bd->bi_dram[bank].start;
1c9bc0ff 275 if ((optee_start + optee_size) < (PHYS_SDRAM + sdram_b1_size)) {
3c41728d
PF
276 if (++bank >= CONFIG_NR_DRAM_BANKS) {
277 puts("CONFIG_NR_DRAM_BANKS is not enough\n");
278 return -1;
279 }
280
281 gd->bd->bi_dram[bank].start = optee_start + optee_size;
282 gd->bd->bi_dram[bank].size = PHYS_SDRAM +
1c9bc0ff 283 sdram_b1_size - gd->bd->bi_dram[bank].start;
3c41728d
PF
284 }
285 } else {
1c9bc0ff 286 gd->bd->bi_dram[bank].size = sdram_b1_size;
3c41728d
PF
287 }
288
1c9bc0ff
YL
289 if (sdram_b2_size) {
290 if (++bank >= CONFIG_NR_DRAM_BANKS) {
291 puts("CONFIG_NR_DRAM_BANKS is not enough for SDRAM_2\n");
292 return -1;
293 }
294 gd->bd->bi_dram[bank].start = 0x100000000UL;
295 gd->bd->bi_dram[bank].size = sdram_b2_size;
3c41728d 296 }
3c41728d
PF
297
298 return 0;
299}
300
301phys_size_t get_effective_memsize(void)
302{
1c9bc0ff
YL
303 int ret;
304 phys_size_t sdram_size;
305 phys_size_t sdram_b1_size;
306 ret = board_phys_sdram_size(&sdram_size);
307 if (!ret) {
308 /* Bank 1 can't cross over 4GB space */
309 if (sdram_size > 0xc0000000) {
310 sdram_b1_size = 0xc0000000;
311 } else {
312 sdram_b1_size = sdram_size;
313 }
3c41728d 314
1c9bc0ff
YL
315 if (rom_pointer[1]) {
316 /* We will relocate u-boot to Top of dram1. Tee position has two cases:
317 * 1. At the top of dram1, Then return the size removed optee size.
318 * 2. In the middle of dram1, return the size of dram1.
319 */
320 if ((rom_pointer[0] + rom_pointer[1]) == (PHYS_SDRAM + sdram_b1_size))
321 return ((phys_addr_t)rom_pointer[0] - PHYS_SDRAM);
322 }
323
324 return sdram_b1_size;
325 } else {
326 return PHYS_SDRAM_SIZE;
327 }
3c41728d
PF
328}
329
e27bddff
FS
330ulong board_get_usable_ram_top(ulong total_size)
331{
74f88b72 332 ulong top_addr;
5a6af8c1 333
e27bddff
FS
334 /*
335 * Some IPs have their accessible address space restricted by
336 * the interconnect. Let's make sure U-Boot only ever uses the
337 * space below the 4G address boundary (which is 3GiB big),
338 * even when the effective available memory is bigger.
339 */
74f88b72 340 top_addr = clamp_val((u64)PHYS_SDRAM + gd->ram_size, 0, 0xffffffff);
5a6af8c1
YCLP
341
342 /*
343 * rom_pointer[0] stores the TEE memory start address.
344 * rom_pointer[1] stores the size TEE uses.
345 * We need to reserve the memory region for TEE.
346 */
347 if (rom_pointer[0] && rom_pointer[1] && top_addr > rom_pointer[0])
348 top_addr = rom_pointer[0];
e27bddff 349
5a6af8c1 350 return top_addr;
e27bddff
FS
351}
352
78db9a54
PF
353static u32 get_cpu_variant_type(u32 type)
354{
355 struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
356 struct fuse_bank *bank = &ocotp->bank[1];
357 struct fuse_bank1_regs *fuse =
358 (struct fuse_bank1_regs *)bank->fuse_regs;
359
360 u32 value = readl(&fuse->tester4);
361
cb1a1de6
PF
362 if (type == MXC_CPU_IMX8MQ) {
363 if ((value & 0x3) == 0x2)
364 return MXC_CPU_IMX8MD;
365 else if (value & 0x200000)
366 return MXC_CPU_IMX8MQL;
367
368 } else if (type == MXC_CPU_IMX8MM) {
78db9a54
PF
369 switch (value & 0x3) {
370 case 2:
371 if (value & 0x1c0000)
372 return MXC_CPU_IMX8MMDL;
373 else
374 return MXC_CPU_IMX8MMD;
375 case 3:
376 if (value & 0x1c0000)
377 return MXC_CPU_IMX8MMSL;
378 else
379 return MXC_CPU_IMX8MMS;
380 default:
381 if (value & 0x1c0000)
382 return MXC_CPU_IMX8MML;
383 break;
384 }
c9154032
PF
385 } else if (type == MXC_CPU_IMX8MN) {
386 switch (value & 0x3) {
387 case 2:
c4f78cbf
YL
388 if (value & 0x1000000) {
389 if (value & 0x10000000) /* MIPI DSI */
390 return MXC_CPU_IMX8MNUD;
391 else
392 return MXC_CPU_IMX8MNDL;
393 } else {
c9154032 394 return MXC_CPU_IMX8MND;
c4f78cbf 395 }
c9154032 396 case 3:
c4f78cbf
YL
397 if (value & 0x1000000) {
398 if (value & 0x10000000) /* MIPI DSI */
399 return MXC_CPU_IMX8MNUS;
400 else
401 return MXC_CPU_IMX8MNSL;
402 } else {
c9154032 403 return MXC_CPU_IMX8MNS;
c4f78cbf 404 }
c9154032 405 default:
c4f78cbf
YL
406 if (value & 0x1000000) {
407 if (value & 0x10000000) /* MIPI DSI */
408 return MXC_CPU_IMX8MNUQ;
409 else
410 return MXC_CPU_IMX8MNL;
411 }
c9154032
PF
412 break;
413 }
d1eee7ee
YL
414 } else if (type == MXC_CPU_IMX8MP) {
415 u32 value0 = readl(&fuse->tester3);
416 u32 flag = 0;
417
418 if ((value0 & 0xc0000) == 0x80000)
419 return MXC_CPU_IMX8MPD;
420
421 /* vpu disabled */
422 if ((value0 & 0x43000000) == 0x43000000)
423 flag = 1;
424
425 /* npu disabled*/
426 if ((value & 0x8) == 0x8)
36bfd71c 427 flag |= BIT(1);
d1eee7ee
YL
428
429 /* isp disabled */
430 if ((value & 0x3) == 0x3)
36bfd71c
PF
431 flag |= BIT(2);
432
433 /* gpu disabled */
434 if ((value & 0xc0) == 0xc0)
435 flag |= BIT(3);
436
437 /* lvds disabled */
438 if ((value & 0x180000) == 0x180000)
439 flag |= BIT(4);
440
441 /* mipi dsi disabled */
442 if ((value & 0x60000) == 0x60000)
443 flag |= BIT(5);
d1eee7ee
YL
444
445 switch (flag) {
36bfd71c
PF
446 case 0x3f:
447 return MXC_CPU_IMX8MPUL;
d1eee7ee
YL
448 case 7:
449 return MXC_CPU_IMX8MPL;
d1eee7ee
YL
450 case 2:
451 return MXC_CPU_IMX8MP6;
d1eee7ee
YL
452 default:
453 break;
454 }
455
78db9a54
PF
456 }
457
458 return type;
459}
460
fcdbde7c
PF
461u32 get_cpu_rev(void)
462{
463 struct anamix_pll *ana_pll = (struct anamix_pll *)ANATOP_BASE_ADDR;
464 u32 reg = readl(&ana_pll->digprog);
465 u32 type = (reg >> 16) & 0xff;
78db9a54 466 u32 major_low = (reg >> 8) & 0xff;
fcdbde7c
PF
467 u32 rom_version;
468
469 reg &= 0xff;
470
625b03d8
PF
471 /* iMX8MP */
472 if (major_low == 0x43) {
d1eee7ee 473 type = get_cpu_variant_type(MXC_CPU_IMX8MP);
625b03d8
PF
474 } else if (major_low == 0x42) {
475 /* iMX8MN */
c9154032 476 type = get_cpu_variant_type(MXC_CPU_IMX8MN);
2434131a 477 } else if (major_low == 0x41) {
78db9a54
PF
478 type = get_cpu_variant_type(MXC_CPU_IMX8MM);
479 } else {
480 if (reg == CHIP_REV_1_0) {
481 /*
9e094455
PF
482 * For B0 chip, the DIGPROG is not updated,
483 * it is still TO1.0. we have to check ROM
484 * version or OCOTP_READ_FUSE_DATA.
485 * 0xff0055aa is magic number for B1.
78db9a54 486 */
9e094455 487 if (readl((void __iomem *)(OCOTP_BASE_ADDR + 0x40)) == 0xff0055aa) {
ea2b26fb
YL
488 /*
489 * B2 uses same DIGPROG and OCOTP_READ_FUSE_DATA value with B1,
490 * so have to check ROM to distinguish them
491 */
492 rom_version = readl((void __iomem *)ROM_VERSION_B0);
493 rom_version &= 0xff;
494 if (rom_version == CHIP_REV_2_2)
495 reg = CHIP_REV_2_2;
496 else
497 reg = CHIP_REV_2_1;
9e094455
PF
498 } else {
499 rom_version =
500 readl((void __iomem *)ROM_VERSION_A0);
501 if (rom_version != CHIP_REV_1_0) {
502 rom_version = readl((void __iomem *)ROM_VERSION_B0);
6a4b07e0 503 rom_version &= 0xff;
9e094455
PF
504 if (rom_version == CHIP_REV_2_0)
505 reg = CHIP_REV_2_0;
506 }
78db9a54 507 }
fcdbde7c 508 }
cb1a1de6
PF
509
510 type = get_cpu_variant_type(type);
fcdbde7c
PF
511 }
512
513 return (type << 12) | reg;
514}
515
516static void imx_set_wdog_powerdown(bool enable)
517{
518 struct wdog_regs *wdog1 = (struct wdog_regs *)WDOG1_BASE_ADDR;
519 struct wdog_regs *wdog2 = (struct wdog_regs *)WDOG2_BASE_ADDR;
520 struct wdog_regs *wdog3 = (struct wdog_regs *)WDOG3_BASE_ADDR;
521
522 /* Write to the PDE (Power Down Enable) bit */
523 writew(enable, &wdog1->wmcr);
524 writew(enable, &wdog2->wmcr);
525 writew(enable, &wdog3->wmcr);
526}
527
7fe32b34 528static int imx8m_check_clock(void *ctx, struct event *event)
e663c703
PF
529{
530 struct udevice *dev;
531 int ret;
532
cd7c806f
PF
533 if (CONFIG_IS_ENABLED(CLK)) {
534 ret = uclass_get_device_by_name(UCLASS_CLK,
535 "clock-controller@30380000",
536 &dev);
537 if (ret < 0) {
538 printf("Failed to find clock node. Check device tree\n");
539 return ret;
540 }
e663c703
PF
541 }
542
543 return 0;
544}
7fe32b34 545EVENT_SPY(EVT_DM_POST_INIT, imx8m_check_clock);
e663c703 546
fcdbde7c
PF
547int arch_cpu_init(void)
548{
702339bd 549 struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
2fa763ba
MV
550
551#if !CONFIG_IS_ENABLED(SYS_ICACHE_OFF)
552 icache_enable();
553#endif
554
0528ba0e
PF
555 /*
556 * ROM might disable clock for SCTR,
557 * enable the clock before timer_init.
558 */
559 if (IS_ENABLED(CONFIG_SPL_BUILD))
560 clock_enable(CCGR_SCTR, 1);
fcdbde7c
PF
561 /*
562 * Init timer at very early state, because sscg pll setting
563 * will use it
564 */
565 timer_init();
566
567 if (IS_ENABLED(CONFIG_SPL_BUILD)) {
568 clock_init();
569 imx_set_wdog_powerdown(false);
7a42bf04
PF
570
571 if (is_imx8md() || is_imx8mmd() || is_imx8mmdl() || is_imx8mms() ||
572 is_imx8mmsl() || is_imx8mnd() || is_imx8mndl() || is_imx8mns() ||
c4f78cbf 573 is_imx8mnsl() || is_imx8mpd() || is_imx8mnud() || is_imx8mnus()) {
7a42bf04
PF
574 /* Power down cpu core 1, 2 and 3 for iMX8M Dual core or Single core */
575 struct pgc_reg *pgc_core1 = (struct pgc_reg *)(GPC_BASE_ADDR + 0x840);
576 struct pgc_reg *pgc_core2 = (struct pgc_reg *)(GPC_BASE_ADDR + 0x880);
577 struct pgc_reg *pgc_core3 = (struct pgc_reg *)(GPC_BASE_ADDR + 0x8C0);
578 struct gpc_reg *gpc = (struct gpc_reg *)GPC_BASE_ADDR;
579
580 writel(0x1, &pgc_core2->pgcr);
581 writel(0x1, &pgc_core3->pgcr);
c4f78cbf 582 if (is_imx8mms() || is_imx8mmsl() || is_imx8mns() || is_imx8mnsl() || is_imx8mnus()) {
7a42bf04
PF
583 writel(0x1, &pgc_core1->pgcr);
584 writel(0xE, &gpc->cpu_pgc_dn_trg);
585 } else {
586 writel(0xC, &gpc->cpu_pgc_dn_trg);
587 }
588 }
fcdbde7c
PF
589 }
590
702339bd
PF
591 if (is_imx8mq()) {
592 clock_enable(CCGR_OCOTP, 1);
593 if (readl(&ocotp->ctrl) & 0x200)
594 writel(0x200, &ocotp->ctrl_clr);
595 }
596
fcdbde7c
PF
597 return 0;
598}
599
b1821376
PF
600#if defined(CONFIG_IMX8MN) || defined(CONFIG_IMX8MP)
601struct rom_api *g_rom_api = (struct rom_api *)0x980;
602
603enum boot_device get_boot_device(void)
604{
605 volatile gd_t *pgd = gd;
606 int ret;
607 u32 boot;
608 u16 boot_type;
609 u8 boot_instance;
610 enum boot_device boot_dev = SD1_BOOT;
611
612 ret = g_rom_api->query_boot_infor(QUERY_BT_DEV, &boot,
613 ((uintptr_t)&boot) ^ QUERY_BT_DEV);
86c5e210 614 set_gd(pgd);
b1821376
PF
615
616 if (ret != ROM_API_OKAY) {
617 puts("ROMAPI: failure at query_boot_info\n");
618 return -1;
619 }
620
621 boot_type = boot >> 16;
622 boot_instance = (boot >> 8) & 0xff;
623
624 switch (boot_type) {
625 case BT_DEV_TYPE_SD:
626 boot_dev = boot_instance + SD1_BOOT;
627 break;
628 case BT_DEV_TYPE_MMC:
629 boot_dev = boot_instance + MMC1_BOOT;
630 break;
631 case BT_DEV_TYPE_NAND:
632 boot_dev = NAND_BOOT;
633 break;
634 case BT_DEV_TYPE_FLEXSPINOR:
635 boot_dev = QSPI_BOOT;
636 break;
e26d0152
MV
637 case BT_DEV_TYPE_SPI_NOR:
638 boot_dev = SPI_NOR_BOOT;
639 break;
b1821376
PF
640 case BT_DEV_TYPE_USB:
641 boot_dev = USB_BOOT;
642 break;
643 default:
644 break;
645 }
646
647 return boot_dev;
648}
a5ee05cf
MV
649#endif
650
651#if defined(CONFIG_IMX8M)
652#include <spl.h>
653int spl_mmc_emmc_boot_partition(struct mmc *mmc)
654{
655 u32 *rom_log_addr = (u32 *)0x9e0;
656 u32 *rom_log;
657 u8 event_id;
658 int i, part;
659
660 part = default_spl_mmc_emmc_boot_partition(mmc);
661
662 /* If the ROM event log pointer is not valid. */
663 if (*rom_log_addr < 0x900000 || *rom_log_addr >= 0xb00000 ||
664 *rom_log_addr & 0x3)
665 return part;
666
667 /* Parse the ROM event ID version 2 log */
668 rom_log = (u32 *)(uintptr_t)(*rom_log_addr);
669 for (i = 0; i < 128; i++) {
670 event_id = rom_log[i] >> 24;
671 switch (event_id) {
672 case 0x00: /* End of list */
673 return part;
674 /* Log entries with 1 parameter, skip 1 */
675 case 0x80: /* Start to perform the device initialization */
676 case 0x81: /* The boot device initialization completes */
677 case 0x8f: /* The boot device initialization fails */
678 case 0x90: /* Start to read data from boot device */
679 case 0x91: /* Reading data from boot device completes */
680 case 0x9f: /* Reading data from boot device fails */
681 i += 1;
682 continue;
683 /* Log entries with 2 parameters, skip 2 */
684 case 0xa0: /* Image authentication result */
685 case 0xc0: /* Jump to the boot image soon */
686 i += 2;
687 continue;
688 /* Boot from the secondary boot image */
689 case 0x51:
690 /*
691 * Swap the eMMC boot partitions in case there was a
692 * fallback event (i.e. primary image was corrupted
693 * and that corruption was recognized by the BootROM),
694 * so the SPL loads the rest of the U-Boot from the
695 * correct eMMC boot partition, since the BootROM
696 * leaves the boot partition set to the corrupted one.
697 */
698 if (part == 1)
699 part = 2;
700 else if (part == 2)
701 part = 1;
702 continue;
703 default:
704 continue;
705 }
706 }
707
708 return part;
709}
b1821376
PF
710#endif
711
fcdbde7c
PF
712bool is_usb_boot(void)
713{
714 return get_boot_device() == USB_BOOT;
715}
716
717#ifdef CONFIG_OF_SYSTEM_SETUP
6036dba1
PF
718bool check_fdt_new_path(void *blob)
719{
720 const char *soc_path = "/soc@0";
721 int nodeoff;
722
723 nodeoff = fdt_path_offset(blob, soc_path);
724 if (nodeoff < 0)
725 return false;
726
727 return true;
728}
729
730static int disable_fdt_nodes(void *blob, const char *const nodes_path[], int size_array)
731{
732 int i = 0;
733 int rc;
734 int nodeoff;
735 const char *status = "disabled";
736
737 for (i = 0; i < size_array; i++) {
738 nodeoff = fdt_path_offset(blob, nodes_path[i]);
739 if (nodeoff < 0)
740 continue; /* Not found, skip it */
741
742 printf("Found %s node\n", nodes_path[i]);
743
744add_status:
745 rc = fdt_setprop(blob, nodeoff, "status", status, strlen(status) + 1);
746 if (rc) {
747 if (rc == -FDT_ERR_NOSPACE) {
748 rc = fdt_increase_size(blob, 512);
749 if (!rc)
750 goto add_status;
751 }
752 printf("Unable to update property %s:%s, err=%s\n",
753 nodes_path[i], "status", fdt_strerror(rc));
754 } else {
755 printf("Modify %s:%s disabled\n",
756 nodes_path[i], "status");
757 }
758 }
759
760 return 0;
761}
762
763#ifdef CONFIG_IMX8MQ
764bool check_dcss_fused(void)
765{
766 struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
767 struct fuse_bank *bank = &ocotp->bank[1];
768 struct fuse_bank1_regs *fuse =
769 (struct fuse_bank1_regs *)bank->fuse_regs;
770 u32 value = readl(&fuse->tester4);
771
772 if (value & 0x4000000)
773 return true;
774
775 return false;
776}
777
778static int disable_mipi_dsi_nodes(void *blob)
779{
780 static const char * const nodes_path[] = {
781 "/mipi_dsi@30A00000",
782 "/mipi_dsi_bridge@30A00000",
783 "/dsi_phy@30A00300",
784 "/soc@0/bus@30800000/mipi_dsi@30a00000",
c0e2f76b
PF
785 "/soc@0/bus@30800000/dphy@30a00300",
786 "/soc@0/bus@30800000/mipi-dsi@30a00000",
6036dba1
PF
787 };
788
789 return disable_fdt_nodes(blob, nodes_path, ARRAY_SIZE(nodes_path));
790}
791
792static int disable_dcss_nodes(void *blob)
793{
794 static const char * const nodes_path[] = {
795 "/dcss@0x32e00000",
796 "/dcss@32e00000",
797 "/hdmi@32c00000",
798 "/hdmi_cec@32c33800",
799 "/hdmi_drm@32c00000",
800 "/display-subsystem",
801 "/sound-hdmi",
802 "/sound-hdmi-arc",
803 "/soc@0/bus@32c00000/display-controller@32e00000",
804 "/soc@0/bus@32c00000/hdmi@32c00000",
805 };
806
807 return disable_fdt_nodes(blob, nodes_path, ARRAY_SIZE(nodes_path));
808}
809
810static int check_mipi_dsi_nodes(void *blob)
811{
812 static const char * const lcdif_path[] = {
813 "/lcdif@30320000",
c0e2f76b
PF
814 "/soc@0/bus@30000000/lcdif@30320000",
815 "/soc@0/bus@30000000/lcd-controller@30320000"
6036dba1
PF
816 };
817 static const char * const mipi_dsi_path[] = {
818 "/mipi_dsi@30A00000",
819 "/soc@0/bus@30800000/mipi_dsi@30a00000"
820 };
821 static const char * const lcdif_ep_path[] = {
822 "/lcdif@30320000/port@0/mipi-dsi-endpoint",
c0e2f76b
PF
823 "/soc@0/bus@30000000/lcdif@30320000/port@0/endpoint",
824 "/soc@0/bus@30000000/lcd-controller@30320000/port@0/endpoint"
6036dba1
PF
825 };
826 static const char * const mipi_dsi_ep_path[] = {
827 "/mipi_dsi@30A00000/port@1/endpoint",
c0e2f76b
PF
828 "/soc@0/bus@30800000/mipi_dsi@30a00000/ports/port@0/endpoint",
829 "/soc@0/bus@30800000/mipi-dsi@30a00000/ports/port@0/endpoint@0"
6036dba1
PF
830 };
831
832 int lookup_node;
833 int nodeoff;
834 bool new_path = check_fdt_new_path(blob);
835 int i = new_path ? 1 : 0;
836
837 nodeoff = fdt_path_offset(blob, lcdif_path[i]);
838 if (nodeoff < 0 || !fdtdec_get_is_enabled(blob, nodeoff)) {
839 /*
840 * If can't find lcdif node or lcdif node is disabled,
841 * then disable all mipi dsi, since they only can input
842 * from DCSS
843 */
844 return disable_mipi_dsi_nodes(blob);
845 }
846
847 nodeoff = fdt_path_offset(blob, mipi_dsi_path[i]);
848 if (nodeoff < 0 || !fdtdec_get_is_enabled(blob, nodeoff))
849 return 0;
850
851 nodeoff = fdt_path_offset(blob, lcdif_ep_path[i]);
852 if (nodeoff < 0) {
853 /*
854 * If can't find lcdif endpoint, then disable all mipi dsi,
855 * since they only can input from DCSS
856 */
857 return disable_mipi_dsi_nodes(blob);
858 }
859
860 lookup_node = fdtdec_lookup_phandle(blob, nodeoff, "remote-endpoint");
861 nodeoff = fdt_path_offset(blob, mipi_dsi_ep_path[i]);
862
863 if (nodeoff > 0 && nodeoff == lookup_node)
864 return 0;
865
866 return disable_mipi_dsi_nodes(blob);
867}
868#endif
869
870int disable_vpu_nodes(void *blob)
871{
872 static const char * const nodes_path_8mq[] = {
873 "/vpu@38300000",
874 "/soc@0/vpu@38300000"
875 };
876
877 static const char * const nodes_path_8mm[] = {
878 "/vpu_g1@38300000",
879 "/vpu_g2@38310000",
880 "/vpu_h1@38320000"
881 };
882
883 static const char * const nodes_path_8mp[] = {
884 "/vpu_g1@38300000",
885 "/vpu_g2@38310000",
886 "/vpu_vc8000e@38320000"
887 };
888
889 if (is_imx8mq())
890 return disable_fdt_nodes(blob, nodes_path_8mq, ARRAY_SIZE(nodes_path_8mq));
891 else if (is_imx8mm())
892 return disable_fdt_nodes(blob, nodes_path_8mm, ARRAY_SIZE(nodes_path_8mm));
893 else if (is_imx8mp())
894 return disable_fdt_nodes(blob, nodes_path_8mp, ARRAY_SIZE(nodes_path_8mp));
895 else
896 return -EPERM;
897}
898
98bcdf16
YL
899#ifdef CONFIG_IMX8MN_LOW_DRIVE_MODE
900static int low_drive_gpu_freq(void *blob)
901{
902 static const char *nodes_path_8mn[] = {
903 "/gpu@38000000",
904 "/soc@0/gpu@38000000"
905 };
906
907 int nodeoff, cnt, i;
908 u32 assignedclks[7];
909
910 nodeoff = fdt_path_offset(blob, nodes_path_8mn[0]);
911 if (nodeoff < 0)
912 return nodeoff;
913
914 cnt = fdtdec_get_int_array_count(blob, nodeoff, "assigned-clock-rates", assignedclks, 7);
915 if (cnt < 0)
916 return cnt;
917
918 if (cnt != 7)
919 printf("Warning: %s, assigned-clock-rates count %d\n", nodes_path_8mn[0], cnt);
920
921 assignedclks[cnt - 1] = 200000000;
922 assignedclks[cnt - 2] = 200000000;
923
924 for (i = 0; i < cnt; i++) {
925 debug("<%u>, ", assignedclks[i]);
926 assignedclks[i] = cpu_to_fdt32(assignedclks[i]);
927 }
928 debug("\n");
929
930 return fdt_setprop(blob, nodeoff, "assigned-clock-rates", &assignedclks, sizeof(assignedclks));
931}
932#endif
933
35bb6078
PF
934static bool check_remote_endpoint(void *blob, const char *ep1, const char *ep2)
935{
936 int lookup_node;
937 int nodeoff;
938
939 nodeoff = fdt_path_offset(blob, ep1);
940 if (nodeoff) {
941 lookup_node = fdtdec_lookup_phandle(blob, nodeoff, "remote-endpoint");
942 nodeoff = fdt_path_offset(blob, ep2);
943
944 if (nodeoff > 0 && nodeoff == lookup_node)
945 return true;
946 }
947
948 return false;
949}
950
951int disable_dsi_lcdif_nodes(void *blob)
952{
953 int ret;
954
955 static const char * const dsi_path_8mp[] = {
956 "/soc@0/bus@32c00000/mipi_dsi@32e60000"
957 };
958
959 static const char * const lcdif_path_8mp[] = {
960 "/soc@0/bus@32c00000/lcd-controller@32e80000"
961 };
962
963 static const char * const lcdif_ep_path_8mp[] = {
964 "/soc@0/bus@32c00000/lcd-controller@32e80000/port@0/endpoint"
965 };
966 static const char * const dsi_ep_path_8mp[] = {
967 "/soc@0/bus@32c00000/mipi_dsi@32e60000/port@0/endpoint"
968 };
969
970 ret = disable_fdt_nodes(blob, dsi_path_8mp, ARRAY_SIZE(dsi_path_8mp));
971 if (ret)
972 return ret;
973
974 if (check_remote_endpoint(blob, dsi_ep_path_8mp[0], lcdif_ep_path_8mp[0])) {
975 /* Disable lcdif node */
976 return disable_fdt_nodes(blob, lcdif_path_8mp, ARRAY_SIZE(lcdif_path_8mp));
977 }
978
979 return 0;
980}
981
982int disable_lvds_lcdif_nodes(void *blob)
983{
984 int ret, i;
985
986 static const char * const ldb_path_8mp[] = {
987 "/soc@0/bus@32c00000/ldb@32ec005c",
988 "/soc@0/bus@32c00000/phy@32ec0128"
989 };
990
991 static const char * const lcdif_path_8mp[] = {
992 "/soc@0/bus@32c00000/lcd-controller@32e90000"
993 };
994
995 static const char * const lcdif_ep_path_8mp[] = {
996 "/soc@0/bus@32c00000/lcd-controller@32e90000/port@0/endpoint@0",
997 "/soc@0/bus@32c00000/lcd-controller@32e90000/port@0/endpoint@1"
998 };
999 static const char * const ldb_ep_path_8mp[] = {
1000 "/soc@0/bus@32c00000/ldb@32ec005c/lvds-channel@0/port@0/endpoint",
1001 "/soc@0/bus@32c00000/ldb@32ec005c/lvds-channel@1/port@0/endpoint"
1002 };
1003
1004 ret = disable_fdt_nodes(blob, ldb_path_8mp, ARRAY_SIZE(ldb_path_8mp));
1005 if (ret)
1006 return ret;
1007
1008 for (i = 0; i < ARRAY_SIZE(ldb_ep_path_8mp); i++) {
1009 if (check_remote_endpoint(blob, ldb_ep_path_8mp[i], lcdif_ep_path_8mp[i])) {
1010 /* Disable lcdif node */
1011 return disable_fdt_nodes(blob, lcdif_path_8mp, ARRAY_SIZE(lcdif_path_8mp));
1012 }
1013 }
1014
1015 return 0;
1016}
1017
6036dba1
PF
1018int disable_gpu_nodes(void *blob)
1019{
1020 static const char * const nodes_path_8mn[] = {
c0e2f76b
PF
1021 "/gpu@38000000",
1022 "/soc@/gpu@38000000"
6036dba1
PF
1023 };
1024
35bb6078
PF
1025 static const char * const nodes_path_8mp[] = {
1026 "/gpu3d@38000000",
1027 "/gpu2d@38008000"
1028 };
1029
1030 if (is_imx8mp())
1031 return disable_fdt_nodes(blob, nodes_path_8mp, ARRAY_SIZE(nodes_path_8mp));
1032 else
1033 return disable_fdt_nodes(blob, nodes_path_8mn, ARRAY_SIZE(nodes_path_8mn));
6036dba1
PF
1034}
1035
1036int disable_npu_nodes(void *blob)
1037{
1038 static const char * const nodes_path_8mp[] = {
1039 "/vipsi@38500000"
1040 };
1041
1042 return disable_fdt_nodes(blob, nodes_path_8mp, ARRAY_SIZE(nodes_path_8mp));
1043}
1044
1045int disable_isp_nodes(void *blob)
1046{
1047 static const char * const nodes_path_8mp[] = {
1048 "/soc@0/bus@32c00000/camera/isp@32e10000",
1049 "/soc@0/bus@32c00000/camera/isp@32e20000"
1050 };
1051
1052 return disable_fdt_nodes(blob, nodes_path_8mp, ARRAY_SIZE(nodes_path_8mp));
1053}
1054
1055int disable_dsp_nodes(void *blob)
1056{
1057 static const char * const nodes_path_8mp[] = {
1058 "/dsp@3b6e8000"
1059 };
1060
1061 return disable_fdt_nodes(blob, nodes_path_8mp, ARRAY_SIZE(nodes_path_8mp));
1062}
1063
4e83c057
YL
1064static void disable_thermal_cpu_nodes(void *blob, u32 disabled_cores)
1065{
1066 static const char * const thermal_path[] = {
1067 "/thermal-zones/cpu-thermal/cooling-maps/map0"
1068 };
1069
1070 int nodeoff, cnt, i, ret, j;
1071 u32 cooling_dev[12];
1072
1073 for (i = 0; i < ARRAY_SIZE(thermal_path); i++) {
1074 nodeoff = fdt_path_offset(blob, thermal_path[i]);
1075 if (nodeoff < 0)
1076 continue; /* Not found, skip it */
1077
1078 cnt = fdtdec_get_int_array_count(blob, nodeoff, "cooling-device", cooling_dev, 12);
1079 if (cnt < 0)
1080 continue;
1081
1082 if (cnt != 12)
1083 printf("Warning: %s, cooling-device count %d\n", thermal_path[i], cnt);
1084
1085 for (j = 0; j < cnt; j++)
1086 cooling_dev[j] = cpu_to_fdt32(cooling_dev[j]);
1087
1088 ret = fdt_setprop(blob, nodeoff, "cooling-device", &cooling_dev,
1089 sizeof(u32) * (12 - disabled_cores * 3));
1090 if (ret < 0) {
1091 printf("Warning: %s, cooling-device setprop failed %d\n",
1092 thermal_path[i], ret);
1093 continue;
1094 }
1095
1096 printf("Update node %s, cooling-device prop\n", thermal_path[i]);
1097 }
1098}
1099
1100static void disable_pmu_cpu_nodes(void *blob, u32 disabled_cores)
1101{
1102 static const char * const pmu_path[] = {
1103 "/pmu"
1104 };
1105
1106 int nodeoff, cnt, i, ret, j;
1107 u32 irq_affinity[4];
1108
1109 for (i = 0; i < ARRAY_SIZE(pmu_path); i++) {
1110 nodeoff = fdt_path_offset(blob, pmu_path[i]);
1111 if (nodeoff < 0)
1112 continue; /* Not found, skip it */
1113
1114 cnt = fdtdec_get_int_array_count(blob, nodeoff, "interrupt-affinity",
1115 irq_affinity, 4);
1116 if (cnt < 0)
1117 continue;
1118
1119 if (cnt != 4)
1120 printf("Warning: %s, interrupt-affinity count %d\n", pmu_path[i], cnt);
1121
1122 for (j = 0; j < cnt; j++)
1123 irq_affinity[j] = cpu_to_fdt32(irq_affinity[j]);
1124
1125 ret = fdt_setprop(blob, nodeoff, "interrupt-affinity", &irq_affinity,
1126 sizeof(u32) * (4 - disabled_cores));
1127 if (ret < 0) {
1128 printf("Warning: %s, interrupt-affinity setprop failed %d\n",
1129 pmu_path[i], ret);
1130 continue;
1131 }
1132
1133 printf("Update node %s, interrupt-affinity prop\n", pmu_path[i]);
1134 }
1135}
1136
6036dba1
PF
1137static int disable_cpu_nodes(void *blob, u32 disabled_cores)
1138{
1139 static const char * const nodes_path[] = {
1140 "/cpus/cpu@1",
1141 "/cpus/cpu@2",
1142 "/cpus/cpu@3",
1143 };
1144 u32 i = 0;
1145 int rc;
1146 int nodeoff;
1147
1148 if (disabled_cores > 3)
1149 return -EINVAL;
1150
1151 i = 3 - disabled_cores;
1152
1153 for (; i < 3; i++) {
1154 nodeoff = fdt_path_offset(blob, nodes_path[i]);
1155 if (nodeoff < 0)
1156 continue; /* Not found, skip it */
1157
1158 debug("Found %s node\n", nodes_path[i]);
1159
1160 rc = fdt_del_node(blob, nodeoff);
1161 if (rc < 0) {
1162 printf("Unable to delete node %s, err=%s\n",
1163 nodes_path[i], fdt_strerror(rc));
1164 } else {
1165 printf("Delete node %s\n", nodes_path[i]);
1166 }
1167 }
1168
4e83c057
YL
1169 disable_thermal_cpu_nodes(blob, disabled_cores);
1170 disable_pmu_cpu_nodes(blob, disabled_cores);
1171
6036dba1
PF
1172 return 0;
1173}
1174
8325ef3d
PF
1175static int cleanup_nodes_for_efi(void *blob)
1176{
1166bd43
PF
1177 static const char * const path[][2] = {
1178 { "/soc@0/bus@32c00000/usb@32e40000", "extcon" },
1179 { "/soc@0/bus@32c00000/usb@32e50000", "extcon" },
1180 { "/soc@0/bus@30800000/ethernet@30be0000", "phy-reset-gpios" },
1181 { "/soc@0/bus@30800000/ethernet@30bf0000", "phy-reset-gpios" }
1182 };
8325ef3d
PF
1183 int nodeoff, i, rc;
1184
1166bd43
PF
1185 for (i = 0; i < ARRAY_SIZE(path); i++) {
1186 nodeoff = fdt_path_offset(blob, path[i][0]);
8325ef3d
PF
1187 if (nodeoff < 0)
1188 continue; /* Not found, skip it */
1166bd43 1189 debug("Found %s node\n", path[i][0]);
8325ef3d 1190
1166bd43 1191 rc = fdt_delprop(blob, nodeoff, path[i][1]);
8325ef3d
PF
1192 if (rc == -FDT_ERR_NOTFOUND)
1193 continue;
1194 if (rc) {
1195 printf("Unable to update property %s:%s, err=%s\n",
1166bd43 1196 path[i][0], path[i][1], fdt_strerror(rc));
8325ef3d
PF
1197 return rc;
1198 }
1199
1166bd43 1200 printf("Remove %s:%s\n", path[i][0], path[i][1]);
8325ef3d
PF
1201 }
1202
1203 return 0;
1204}
8325ef3d 1205
b75d8dc5 1206int ft_system_setup(void *blob, struct bd_info *bd)
fcdbde7c 1207{
6036dba1 1208#ifdef CONFIG_IMX8MQ
fcdbde7c
PF
1209 int i = 0;
1210 int rc;
1211 int nodeoff;
1212
6036dba1
PF
1213 if (get_boot_device() == USB_BOOT) {
1214 disable_dcss_nodes(blob);
1215
1216 bool new_path = check_fdt_new_path(blob);
1217 int v = new_path ? 1 : 0;
1218 static const char * const usb_dwc3_path[] = {
1219 "/usb@38100000/dwc3",
1220 "/soc@0/usb@38100000"
1221 };
1222
1223 nodeoff = fdt_path_offset(blob, usb_dwc3_path[v]);
1224 if (nodeoff >= 0) {
1225 const char *speed = "high-speed";
1226
1227 printf("Found %s node\n", usb_dwc3_path[v]);
1228
1229usb_modify_speed:
1230
1231 rc = fdt_setprop(blob, nodeoff, "maximum-speed", speed, strlen(speed) + 1);
1232 if (rc) {
1233 if (rc == -FDT_ERR_NOSPACE) {
1234 rc = fdt_increase_size(blob, 512);
1235 if (!rc)
1236 goto usb_modify_speed;
1237 }
1238 printf("Unable to set property %s:%s, err=%s\n",
1239 usb_dwc3_path[v], "maximum-speed", fdt_strerror(rc));
1240 } else {
1241 printf("Modify %s:%s = %s\n",
1242 usb_dwc3_path[v], "maximum-speed", speed);
1243 }
1244 } else {
1245 printf("Can't found %s node\n", usb_dwc3_path[v]);
1246 }
1247 }
1248
fcdbde7c
PF
1249 /* Disable the CPU idle for A0 chip since the HW does not support it */
1250 if (is_soc_rev(CHIP_REV_1_0)) {
1251 static const char * const nodes_path[] = {
1252 "/cpus/cpu@0",
1253 "/cpus/cpu@1",
1254 "/cpus/cpu@2",
1255 "/cpus/cpu@3",
1256 };
1257
1258 for (i = 0; i < ARRAY_SIZE(nodes_path); i++) {
1259 nodeoff = fdt_path_offset(blob, nodes_path[i]);
1260 if (nodeoff < 0)
1261 continue; /* Not found, skip it */
1262
dabaabd3 1263 debug("Found %s node\n", nodes_path[i]);
fcdbde7c
PF
1264
1265 rc = fdt_delprop(blob, nodeoff, "cpu-idle-states");
dabaabd3
MV
1266 if (rc == -FDT_ERR_NOTFOUND)
1267 continue;
fcdbde7c
PF
1268 if (rc) {
1269 printf("Unable to update property %s:%s, err=%s\n",
1270 nodes_path[i], "status", fdt_strerror(rc));
1271 return rc;
1272 }
1273
dabaabd3 1274 debug("Remove %s:%s\n", nodes_path[i],
fcdbde7c
PF
1275 "cpu-idle-states");
1276 }
1277 }
1278
6036dba1
PF
1279 if (is_imx8mql()) {
1280 disable_vpu_nodes(blob);
1281 if (check_dcss_fused()) {
1282 printf("DCSS is fused\n");
1283 disable_dcss_nodes(blob);
1284 check_mipi_dsi_nodes(blob);
1285 }
1286 }
1287
1288 if (is_imx8md())
1289 disable_cpu_nodes(blob, 2);
1290
1291#elif defined(CONFIG_IMX8MM)
1292 if (is_imx8mml() || is_imx8mmdl() || is_imx8mmsl())
1293 disable_vpu_nodes(blob);
1294
1295 if (is_imx8mmd() || is_imx8mmdl())
1296 disable_cpu_nodes(blob, 2);
1297 else if (is_imx8mms() || is_imx8mmsl())
1298 disable_cpu_nodes(blob, 3);
1299
1300#elif defined(CONFIG_IMX8MN)
1301 if (is_imx8mnl() || is_imx8mndl() || is_imx8mnsl())
1302 disable_gpu_nodes(blob);
98bcdf16
YL
1303#ifdef CONFIG_IMX8MN_LOW_DRIVE_MODE
1304 else {
1305 int ldm_gpu = low_drive_gpu_freq(blob);
1306
1307 if (ldm_gpu < 0)
1308 printf("Update GPU node assigned-clock-rates failed\n");
1309 else
1310 printf("Update GPU node assigned-clock-rates ok\n");
1311 }
1312#endif
6036dba1 1313
c4f78cbf 1314 if (is_imx8mnd() || is_imx8mndl() || is_imx8mnud())
6036dba1 1315 disable_cpu_nodes(blob, 2);
c4f78cbf 1316 else if (is_imx8mns() || is_imx8mnsl() || is_imx8mnus())
6036dba1
PF
1317 disable_cpu_nodes(blob, 3);
1318
1319#elif defined(CONFIG_IMX8MP)
35bb6078
PF
1320 if (is_imx8mpul()) {
1321 /* Disable GPU */
1322 disable_gpu_nodes(blob);
1323
1324 /* Disable DSI */
1325 disable_dsi_lcdif_nodes(blob);
1326
1327 /* Disable LVDS */
1328 disable_lvds_lcdif_nodes(blob);
1329 }
1330
1331 if (is_imx8mpul() || is_imx8mpl())
6036dba1
PF
1332 disable_vpu_nodes(blob);
1333
35bb6078 1334 if (is_imx8mpul() || is_imx8mpl() || is_imx8mp6())
6036dba1
PF
1335 disable_npu_nodes(blob);
1336
35bb6078 1337 if (is_imx8mpul() || is_imx8mpl())
6036dba1
PF
1338 disable_isp_nodes(blob);
1339
35bb6078 1340 if (is_imx8mpul() || is_imx8mpl() || is_imx8mp6())
6036dba1
PF
1341 disable_dsp_nodes(blob);
1342
1343 if (is_imx8mpd())
1344 disable_cpu_nodes(blob, 2);
1345#endif
1346
1166bd43 1347 cleanup_nodes_for_efi(blob);
fcdbde7c
PF
1348 return 0;
1349}
1350#endif
1351
35bb6078
PF
1352#ifdef CONFIG_OF_BOARD_FIXUP
1353#ifndef CONFIG_SPL_BUILD
1354int board_fix_fdt(void *fdt)
1355{
1356 if (is_imx8mpul()) {
1357 int i = 0;
1358 int nodeoff, ret;
1359 const char *status = "disabled";
1360 static const char * const dsi_nodes[] = {
1361 "/soc@0/bus@32c00000/mipi_dsi@32e60000",
1362 "/soc@0/bus@32c00000/lcd-controller@32e80000",
1363 "/dsi-host"
1364 };
1365
1366 for (i = 0; i < ARRAY_SIZE(dsi_nodes); i++) {
1367 nodeoff = fdt_path_offset(fdt, dsi_nodes[i]);
1368 if (nodeoff > 0) {
1369set_status:
1370 ret = fdt_setprop(fdt, nodeoff, "status", status,
1371 strlen(status) + 1);
1372 if (ret == -FDT_ERR_NOSPACE) {
1373 ret = fdt_increase_size(fdt, 512);
1374 if (!ret)
1375 goto set_status;
1376 }
1377 }
1378 }
1379 }
1380
1381 return 0;
1382}
1383#endif
1384#endif
1385
efa1a62a 1386#if !CONFIG_IS_ENABLED(SYSRESET)
35b65dd8 1387void reset_cpu(void)
fcdbde7c 1388{
c5635a03 1389 struct watchdog_regs *wdog = (struct watchdog_regs *)WDOG1_BASE_ADDR;
fcdbde7c 1390
72479746
YL
1391 /* Clear WDA to trigger WDOG_B immediately */
1392 writew((SET_WCR_WT(1) | WCR_WDT | WCR_WDE | WCR_SRS), &wdog->wcr);
d2041725 1393
72479746
YL
1394 while (1) {
1395 /*
568af926 1396 * spin for .5 seconds before reset
72479746
YL
1397 */
1398 }
fcdbde7c 1399}
d2041725 1400#endif
a07bcec4
PF
1401
1402#if defined(CONFIG_ARCH_MISC_INIT)
a07bcec4
PF
1403int arch_misc_init(void)
1404{
2cddfcbc
GJ
1405 if (IS_ENABLED(CONFIG_FSL_CAAM)) {
1406 struct udevice *dev;
1407 int ret;
1408
1409 ret = uclass_get_device_by_driver(UCLASS_MISC, DM_DRIVER_GET(caam_jr), &dev);
1410 if (ret)
cda8f873 1411 printf("Failed to initialize caam_jr: %d\n", ret);
2cddfcbc 1412 }
a07bcec4
PF
1413
1414 return 0;
1415}
1416#endif
70487ff3
YL
1417
1418void imx_tmu_arch_init(void *reg_base)
1419{
94c693d7 1420 if (is_imx8mm() || is_imx8mn()) {
70487ff3
YL
1421 /* Load TCALIV and TASR from fuses */
1422 struct ocotp_regs *ocotp =
1423 (struct ocotp_regs *)OCOTP_BASE_ADDR;
1424 struct fuse_bank *bank = &ocotp->bank[3];
1425 struct fuse_bank3_regs *fuse =
1426 (struct fuse_bank3_regs *)bank->fuse_regs;
1427
1428 u32 tca_rt, tca_hr, tca_en;
1429 u32 buf_vref, buf_slope;
1430
1431 tca_rt = fuse->ana0 & 0xFF;
1432 tca_hr = (fuse->ana0 & 0xFF00) >> 8;
1433 tca_en = (fuse->ana0 & 0x2000000) >> 25;
1434
1435 buf_vref = (fuse->ana0 & 0x1F00000) >> 20;
1436 buf_slope = (fuse->ana0 & 0xF0000) >> 16;
1437
1438 writel(buf_vref | (buf_slope << 16), (ulong)reg_base + 0x28);
1439 writel((tca_en << 31) | (tca_hr << 16) | tca_rt,
1440 (ulong)reg_base + 0x30);
1441 }
ebb9aab3
YL
1442#ifdef CONFIG_IMX8MP
1443 /* Load TCALIV0/1/m40 and TRIM from fuses */
1444 struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
1445 struct fuse_bank *bank = &ocotp->bank[38];
1446 struct fuse_bank38_regs *fuse =
1447 (struct fuse_bank38_regs *)bank->fuse_regs;
1448 struct fuse_bank *bank2 = &ocotp->bank[39];
1449 struct fuse_bank39_regs *fuse2 =
1450 (struct fuse_bank39_regs *)bank2->fuse_regs;
1451 u32 buf_vref, buf_slope, bjt_cur, vlsb, bgr;
1452 u32 reg;
1453 u32 tca40[2], tca25[2], tca105[2];
1454
1455 /* For blank sample */
1456 if (!fuse->ana_trim2 && !fuse->ana_trim3 &&
1457 !fuse->ana_trim4 && !fuse2->ana_trim5) {
1458 /* Use a default 25C binary codes */
1459 tca25[0] = 1596;
3462b55d 1460 tca25[1] = 1596;
ebb9aab3 1461 writel(tca25[0], (ulong)reg_base + 0x30);
3462b55d 1462 writel(tca25[1], (ulong)reg_base + 0x34);
ebb9aab3
YL
1463 return;
1464 }
1465
1466 buf_vref = (fuse->ana_trim2 & 0xc0) >> 6;
1467 buf_slope = (fuse->ana_trim2 & 0xF00) >> 8;
1468 bjt_cur = (fuse->ana_trim2 & 0xF000) >> 12;
1469 bgr = (fuse->ana_trim2 & 0xF0000) >> 16;
1470 vlsb = (fuse->ana_trim2 & 0xF00000) >> 20;
1471 writel(buf_vref | (buf_slope << 16), (ulong)reg_base + 0x28);
1472
1473 reg = (bgr << 28) | (bjt_cur << 20) | (vlsb << 12) | (1 << 7);
1474 writel(reg, (ulong)reg_base + 0x3c);
1475
1476 tca40[0] = (fuse->ana_trim3 & 0xFFF0000) >> 16;
1477 tca25[0] = (fuse->ana_trim3 & 0xF0000000) >> 28;
1478 tca25[0] |= ((fuse->ana_trim4 & 0xFF) << 4);
1479 tca105[0] = (fuse->ana_trim4 & 0xFFF00) >> 8;
1480 tca40[1] = (fuse->ana_trim4 & 0xFFF00000) >> 20;
1481 tca25[1] = fuse2->ana_trim5 & 0xFFF;
1482 tca105[1] = (fuse2->ana_trim5 & 0xFFF000) >> 12;
1483
1484 /* use 25c for 1p calibration */
1485 writel(tca25[0] | (tca105[0] << 16), (ulong)reg_base + 0x30);
1486 writel(tca25[1] | (tca105[1] << 16), (ulong)reg_base + 0x34);
1487 writel(tca40[0] | (tca40[1] << 16), (ulong)reg_base + 0x38);
1488#endif
70487ff3 1489}
2f3c9206
PF
1490
1491#if defined(CONFIG_SPL_BUILD)
1492#if defined(CONFIG_IMX8MQ) || defined(CONFIG_IMX8MM) || defined(CONFIG_IMX8MN)
1493bool serror_need_skip = true;
1494
e97ac478 1495void do_error(struct pt_regs *pt_regs)
2f3c9206
PF
1496{
1497 /*
1498 * If stack is still in ROM reserved OCRAM not switch to SPL,
1499 * it is the ROM SError
1500 */
1501 ulong sp;
1502
1503 asm volatile("mov %0, sp" : "=r"(sp) : );
1504
1505 if (serror_need_skip && sp < 0x910000 && sp >= 0x900000) {
1506 /* Check for ERR050342, imx8mq HDCP enabled parts */
1507 if (is_imx8mq() && !(readl(OCOTP_BASE_ADDR + 0x450) & 0x08000000)) {
1508 serror_need_skip = false;
1509 return; /* Do nothing skip the SError in ROM */
1510 }
1511
1512 /* Check for ERR050350, field return mode for imx8mq, mm and mn */
1513 if (readl(OCOTP_BASE_ADDR + 0x630) & 0x1) {
1514 serror_need_skip = false;
1515 return; /* Do nothing skip the SError in ROM */
1516 }
1517 }
1518
1519 efi_restore_gd();
e97ac478 1520 printf("\"Error\" handler, esr 0x%08lx\n", pt_regs->esr);
2f3c9206
PF
1521 show_regs(pt_regs);
1522 panic("Resetting CPU ...\n");
1523}
1524#endif
1525#endif
2707faf0
YL
1526
1527#if defined(CONFIG_IMX8MN) || defined(CONFIG_IMX8MP)
e4dc2d06 1528enum env_location arch_env_get_location(enum env_operation op, int prio)
2707faf0
YL
1529{
1530 enum boot_device dev = get_boot_device();
2707faf0
YL
1531
1532 if (prio)
89ca5a7e 1533 return ENVL_UNKNOWN;
2707faf0
YL
1534
1535 switch (dev) {
d175982c
FE
1536 case USB_BOOT:
1537 if (IS_ENABLED(CONFIG_ENV_IS_IN_SPI_FLASH))
1538 return ENVL_SPI_FLASH;
1539 if (IS_ENABLED(CONFIG_ENV_IS_IN_NAND))
1540 return ENVL_NAND;
1541 if (IS_ENABLED(CONFIG_ENV_IS_IN_MMC))
1542 return ENVL_MMC;
1543 if (IS_ENABLED(CONFIG_ENV_IS_NOWHERE))
1544 return ENVL_NOWHERE;
1545 return ENVL_UNKNOWN;
2707faf0 1546 case QSPI_BOOT:
e26d0152 1547 case SPI_NOR_BOOT:
89ca5a7e
RS
1548 if (IS_ENABLED(CONFIG_ENV_IS_IN_SPI_FLASH))
1549 return ENVL_SPI_FLASH;
1550 return ENVL_NOWHERE;
2707faf0 1551 case NAND_BOOT:
89ca5a7e
RS
1552 if (IS_ENABLED(CONFIG_ENV_IS_IN_NAND))
1553 return ENVL_NAND;
1554 return ENVL_NOWHERE;
2707faf0
YL
1555 case SD1_BOOT:
1556 case SD2_BOOT:
1557 case SD3_BOOT:
1558 case MMC1_BOOT:
1559 case MMC2_BOOT:
1560 case MMC3_BOOT:
89ca5a7e
RS
1561 if (IS_ENABLED(CONFIG_ENV_IS_IN_MMC))
1562 return ENVL_MMC;
1563 else if (IS_ENABLED(CONFIG_ENV_IS_IN_EXT4))
1564 return ENVL_EXT4;
1565 else if (IS_ENABLED(CONFIG_ENV_IS_IN_FAT))
1566 return ENVL_FAT;
1567 return ENVL_NOWHERE;
2707faf0 1568 default:
89ca5a7e 1569 return ENVL_NOWHERE;
2707faf0 1570 }
2707faf0
YL
1571}
1572
2707faf0 1573#endif
5dd9db8f
PF
1574
1575#ifdef CONFIG_IMX_BOOTAUX
1576const struct rproc_att hostmap[] = {
1577 /* aux core , host core, size */
1578 { 0x00000000, 0x007e0000, 0x00020000 },
1579 /* OCRAM_S */
1580 { 0x00180000, 0x00180000, 0x00008000 },
1581 /* OCRAM */
1582 { 0x00900000, 0x00900000, 0x00020000 },
1583 /* OCRAM */
1584 { 0x00920000, 0x00920000, 0x00020000 },
1585 /* QSPI Code - alias */
1586 { 0x08000000, 0x08000000, 0x08000000 },
1587 /* DDR (Code) - alias */
1588 { 0x10000000, 0x80000000, 0x0FFE0000 },
1589 /* TCML */
1590 { 0x1FFE0000, 0x007E0000, 0x00040000 },
1591 /* OCRAM_S */
1592 { 0x20180000, 0x00180000, 0x00008000 },
1593 /* OCRAM */
1594 { 0x20200000, 0x00900000, 0x00040000 },
1595 /* DDR (Data) */
1596 { 0x40000000, 0x40000000, 0x80000000 },
1597 { /* sentinel */ }
1598};
1599#endif