blob: d115b25a5b6c04398b8970117dc2da83b108ee4a [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Peng Faneae4de22018-01-10 13:20:37 +08002/*
Gaurav Jain81113a02022-03-24 11:50:27 +05303 * Copyright 2017-2019, 2021 NXP
Peng Faneae4de22018-01-10 13:20:37 +08004 *
5 * Peng Fan <peng.fan@nxp.com>
Peng Faneae4de22018-01-10 13:20:37 +08006 */
7
8#include <common.h>
Simon Glass1d91ba72019-11-14 12:57:37 -07009#include <cpu_func.h>
Simon Glassfc557362022-03-04 08:43:05 -070010#include <event.h>
Simon Glass97589732020-05-10 11:40:02 -060011#include <init.h>
Simon Glass0f2af882020-05-10 11:40:05 -060012#include <log.h>
Peng Faneae4de22018-01-10 13:20:37 +080013#include <asm/arch/imx-regs.h>
Simon Glass3ba929a2020-10-30 21:38:53 -060014#include <asm/global_data.h>
Peng Faneae4de22018-01-10 13:20:37 +080015#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>
Peng Fana35215d2020-07-09 13:39:26 +080021#include <asm/ptrace.h>
Peng Faneae4de22018-01-10 13:20:37 +080022#include <asm/armv8/mmu.h>
Peng Fanc98e0322019-08-27 06:25:58 +000023#include <dm/uclass.h>
Gaurav Jain81113a02022-03-24 11:50:27 +053024#include <dm/device.h>
Peng Fana35215d2020-07-09 13:39:26 +080025#include <efi_loader.h>
Ye Li0513f362019-07-15 01:16:46 -070026#include <env.h>
27#include <env_internal.h>
Peng Faneae4de22018-01-10 13:20:37 +080028#include <errno.h>
29#include <fdt_support.h>
30#include <fsl_wdog.h>
31#include <imx_sip.h>
Simon Glass4dcacfc2020-05-10 11:40:13 -060032#include <linux/bitops.h>
Peng Faneae4de22018-01-10 13:20:37 +080033
34DECLARE_GLOBAL_DATA_PTR;
35
Stefano Babicf8b509b2019-09-20 08:47:53 +020036#if defined(CONFIG_IMX_HAB)
Peng Faneae4de22018-01-10 13:20:37 +080037struct 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);
Andrey Zhizhikin7c2d23a2022-01-24 21:48:09 +010070
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 */
Peng Fanda7a16c2022-04-29 16:18:49 +080075 setbits_le32(&gpr->gpr[10], GPR_TZASC_ID_SWAP_BYPASS);
Andrey Zhizhikin7c2d23a2022-01-24 21:48:09 +010076
77 /*
78 * imx8mn and imx8mp implements the lock bit for
79 * TZASC_ID_SWAP_BYPASS, enable it to lock settings
80 */
Peng Fanda7a16c2022-04-29 16:18:49 +080081 setbits_le32(&gpr->gpr[10], GPR_TZASC_ID_SWAP_BYPASS_LOCK);
Andrey Zhizhikin7c2d23a2022-01-24 21:48:09 +010082
Ye Li4c97c462019-08-27 06:25:34 +000083 /*
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);
Peng Faneae4de22018-01-10 13:20:37 +080089}
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
111 }, {
Gary Bisson5c72a452018-11-14 17:55:28 +0100112 /* 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
119 }, {
Marek Vasutb1738e02021-02-25 21:52:26 +0100120 /* OCRAM_S */
121 .virt = 0x180000UL,
122 .phys = 0x180000UL,
123 .size = 0x8000UL,
124 .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
125 PTE_BLOCK_OUTER_SHARE
126 }, {
Gary Bisson5c72a452018-11-14 17:55:28 +0100127 /* 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
134 }, {
Peng Faneae4de22018-01-10 13:20:37 +0800135 /* 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,
Peng Fanb749b5e2019-08-27 06:25:27 +0000153 .size = PHYS_SDRAM_SIZE,
Peng Faneae4de22018-01-10 13:20:37 +0800154 .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
155 PTE_BLOCK_OUTER_SHARE
Peng Fanb749b5e2019-08-27 06:25:27 +0000156#ifdef PHYS_SDRAM_2_SIZE
Peng Faneae4de22018-01-10 13:20:37 +0800157 }, {
158 /* DRAM2 */
159 .virt = 0x100000000UL,
160 .phys = 0x100000000UL,
Peng Fanb749b5e2019-08-27 06:25:27 +0000161 .size = PHYS_SDRAM_2_SIZE,
Peng Faneae4de22018-01-10 13:20:37 +0800162 .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
163 PTE_BLOCK_OUTER_SHARE
Peng Fanb749b5e2019-08-27 06:25:27 +0000164#endif
Peng Faneae4de22018-01-10 13:20:37 +0800165 }, {
Peng Fanfa35c3d2020-07-09 15:26:06 +0800166 /* empty entrie to split table entry 5 if needed when TEEs are used */
167 0,
168 }, {
Peng Faneae4de22018-01-10 13:20:37 +0800169 /* List terminator */
170 0,
171 }
172};
173
174struct mm_region *mem_map = imx8m_mem_map;
175
Marek Vasute48aac02021-02-27 14:59:00 +0100176static 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
Peng Fanb749b5e2019-08-27 06:25:27 +0000187void enable_caches(void)
188{
Ye Li453bfcb2022-04-07 15:55:56 +0800189 /* 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;
Peng Fanfa35c3d2020-07-09 15:26:06 +0800200
Ye Li453bfcb2022-04-07 15:55:56 +0800201 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++;
Peng Fanfa35c3d2020-07-09 15:26:06 +0800212 }
Peng Fanb749b5e2019-08-27 06:25:27 +0000213
214 icache_enable();
215 dcache_enable();
216}
217
Peng Fanfa35c3d2020-07-09 15:26:06 +0800218__weak int board_phys_sdram_size(phys_size_t *size)
219{
220 if (!size)
221 return -EINVAL;
222
223 *size = PHYS_SDRAM_SIZE;
Ye Li453bfcb2022-04-07 15:55:56 +0800224
225#ifdef PHYS_SDRAM_2_SIZE
226 *size += PHYS_SDRAM_2_SIZE;
227#endif
Peng Fanfa35c3d2020-07-09 15:26:06 +0800228 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
Peng Fanfa35c3d2020-07-09 15:26:06 +0800246 return 0;
247}
248
249int dram_init_banksize(void)
250{
251 int bank = 0;
252 int ret;
253 phys_size_t sdram_size;
Ye Li453bfcb2022-04-07 15:55:56 +0800254 phys_size_t sdram_b1_size, sdram_b2_size;
Peng Fanfa35c3d2020-07-09 15:26:06 +0800255
256 ret = board_phys_sdram_size(&sdram_size);
257 if (ret)
258 return ret;
259
Ye Li453bfcb2022-04-07 15:55:56 +0800260 /* 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
Peng Fanfa35c3d2020-07-09 15:26:06 +0800269 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;
Ye Li453bfcb2022-04-07 15:55:56 +0800275 if ((optee_start + optee_size) < (PHYS_SDRAM + sdram_b1_size)) {
Peng Fanfa35c3d2020-07-09 15:26:06 +0800276 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 +
Ye Li453bfcb2022-04-07 15:55:56 +0800283 sdram_b1_size - gd->bd->bi_dram[bank].start;
Peng Fanfa35c3d2020-07-09 15:26:06 +0800284 }
285 } else {
Ye Li453bfcb2022-04-07 15:55:56 +0800286 gd->bd->bi_dram[bank].size = sdram_b1_size;
Peng Fanfa35c3d2020-07-09 15:26:06 +0800287 }
288
Ye Li453bfcb2022-04-07 15:55:56 +0800289 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;
Peng Fanfa35c3d2020-07-09 15:26:06 +0800296 }
Peng Fanfa35c3d2020-07-09 15:26:06 +0800297
298 return 0;
299}
300
301phys_size_t get_effective_memsize(void)
302{
Ye Li453bfcb2022-04-07 15:55:56 +0800303 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 }
Peng Fanfa35c3d2020-07-09 15:26:06 +0800314
Ye Li453bfcb2022-04-07 15:55:56 +0800315 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 }
Peng Fanfa35c3d2020-07-09 15:26:06 +0800328}
329
Frieder Schrempf159879e2021-06-07 14:36:44 +0200330ulong board_get_usable_ram_top(ulong total_size)
331{
Marek Vasutdcbbf782022-04-14 15:51:46 +0200332 ulong top_addr;
Ying-Chun Liu (PaulLiu)ed55caf2021-08-23 10:43:06 +0800333
Frieder Schrempf159879e2021-06-07 14:36:44 +0200334 /*
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 */
Marek Vasutdcbbf782022-04-14 15:51:46 +0200340 top_addr = clamp_val((u64)PHYS_SDRAM + gd->ram_size, 0, 0xffffffff);
Ying-Chun Liu (PaulLiu)ed55caf2021-08-23 10:43:06 +0800341
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];
Frieder Schrempf159879e2021-06-07 14:36:44 +0200349
Ying-Chun Liu (PaulLiu)ed55caf2021-08-23 10:43:06 +0800350 return top_addr;
Frieder Schrempf159879e2021-06-07 14:36:44 +0200351}
352
Peng Fan1caffdf2019-08-27 06:25:17 +0000353static 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
Peng Fan67815082020-02-05 17:34:54 +0800362 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) {
Peng Fan1caffdf2019-08-27 06:25:17 +0000369 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 }
Peng Fan1a07d912020-02-05 17:39:27 +0800385 } else if (type == MXC_CPU_IMX8MN) {
386 switch (value & 0x3) {
387 case 2:
Ye Li715180e2021-03-19 15:57:11 +0800388 if (value & 0x1000000) {
389 if (value & 0x10000000) /* MIPI DSI */
390 return MXC_CPU_IMX8MNUD;
391 else
392 return MXC_CPU_IMX8MNDL;
393 } else {
Peng Fan1a07d912020-02-05 17:39:27 +0800394 return MXC_CPU_IMX8MND;
Ye Li715180e2021-03-19 15:57:11 +0800395 }
Peng Fan1a07d912020-02-05 17:39:27 +0800396 case 3:
Ye Li715180e2021-03-19 15:57:11 +0800397 if (value & 0x1000000) {
398 if (value & 0x10000000) /* MIPI DSI */
399 return MXC_CPU_IMX8MNUS;
400 else
401 return MXC_CPU_IMX8MNSL;
402 } else {
Peng Fan1a07d912020-02-05 17:39:27 +0800403 return MXC_CPU_IMX8MNS;
Ye Li715180e2021-03-19 15:57:11 +0800404 }
Peng Fan1a07d912020-02-05 17:39:27 +0800405 default:
Ye Li715180e2021-03-19 15:57:11 +0800406 if (value & 0x1000000) {
407 if (value & 0x10000000) /* MIPI DSI */
408 return MXC_CPU_IMX8MNUQ;
409 else
410 return MXC_CPU_IMX8MNL;
411 }
Peng Fan1a07d912020-02-05 17:39:27 +0800412 break;
413 }
Ye Lid2d754f2020-04-20 20:12:54 -0700414 } 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)
Peng Fan0386e7f2022-04-07 15:55:52 +0800427 flag |= BIT(1);
Ye Lid2d754f2020-04-20 20:12:54 -0700428
429 /* isp disabled */
430 if ((value & 0x3) == 0x3)
Peng Fan0386e7f2022-04-07 15:55:52 +0800431 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);
Ye Lid2d754f2020-04-20 20:12:54 -0700444
445 switch (flag) {
Peng Fan0386e7f2022-04-07 15:55:52 +0800446 case 0x3f:
447 return MXC_CPU_IMX8MPUL;
Ye Lid2d754f2020-04-20 20:12:54 -0700448 case 7:
449 return MXC_CPU_IMX8MPL;
Ye Lid2d754f2020-04-20 20:12:54 -0700450 case 2:
451 return MXC_CPU_IMX8MP6;
Ye Lid2d754f2020-04-20 20:12:54 -0700452 default:
453 break;
454 }
455
Peng Fan1caffdf2019-08-27 06:25:17 +0000456 }
457
458 return type;
459}
460
Peng Faneae4de22018-01-10 13:20:37 +0800461u32 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;
Peng Fan1caffdf2019-08-27 06:25:17 +0000466 u32 major_low = (reg >> 8) & 0xff;
Peng Faneae4de22018-01-10 13:20:37 +0800467 u32 rom_version;
468
469 reg &= 0xff;
470
Peng Fan69cec072019-12-27 10:14:02 +0800471 /* iMX8MP */
472 if (major_low == 0x43) {
Ye Lid2d754f2020-04-20 20:12:54 -0700473 type = get_cpu_variant_type(MXC_CPU_IMX8MP);
Peng Fan69cec072019-12-27 10:14:02 +0800474 } else if (major_low == 0x42) {
475 /* iMX8MN */
Peng Fan1a07d912020-02-05 17:39:27 +0800476 type = get_cpu_variant_type(MXC_CPU_IMX8MN);
Peng Fan5d2f2062019-06-27 17:23:49 +0800477 } else if (major_low == 0x41) {
Peng Fan1caffdf2019-08-27 06:25:17 +0000478 type = get_cpu_variant_type(MXC_CPU_IMX8MM);
479 } else {
480 if (reg == CHIP_REV_1_0) {
481 /*
Peng Fanc23fbdd2019-10-16 10:24:17 +0000482 * 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.
Peng Fan1caffdf2019-08-27 06:25:17 +0000486 */
Peng Fanc23fbdd2019-10-16 10:24:17 +0000487 if (readl((void __iomem *)(OCOTP_BASE_ADDR + 0x40)) == 0xff0055aa) {
Ye Lic963ed12021-03-19 15:57:16 +0800488 /*
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;
Peng Fanc23fbdd2019-10-16 10:24:17 +0000498 } 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);
Patrick Wildtd4a78b92019-11-19 09:42:06 +0100503 rom_version &= 0xff;
Peng Fanc23fbdd2019-10-16 10:24:17 +0000504 if (rom_version == CHIP_REV_2_0)
505 reg = CHIP_REV_2_0;
506 }
Peng Fan1caffdf2019-08-27 06:25:17 +0000507 }
Peng Faneae4de22018-01-10 13:20:37 +0800508 }
Peng Fan67815082020-02-05 17:34:54 +0800509
510 type = get_cpu_variant_type(type);
Peng Faneae4de22018-01-10 13:20:37 +0800511 }
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
Simon Glassfc557362022-03-04 08:43:05 -0700528static int imx8m_check_clock(void *ctx, struct event *event)
Peng Fanc98e0322019-08-27 06:25:58 +0000529{
530 struct udevice *dev;
531 int ret;
532
Peng Fan3c073342019-10-16 03:01:51 +0000533 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 }
Peng Fanc98e0322019-08-27 06:25:58 +0000541 }
542
543 return 0;
544}
Simon Glassfc557362022-03-04 08:43:05 -0700545EVENT_SPY(EVT_DM_POST_INIT, imx8m_check_clock);
Peng Fanc98e0322019-08-27 06:25:58 +0000546
Peng Faneae4de22018-01-10 13:20:37 +0800547int arch_cpu_init(void)
548{
Peng Fanc0b30d72019-04-17 09:41:16 +0000549 struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
Marek Vasut3ea500a2022-04-13 00:41:52 +0200550
551#if !CONFIG_IS_ENABLED(SYS_ICACHE_OFF)
552 icache_enable();
553#endif
554
Peng Faneae4de22018-01-10 13:20:37 +0800555 /*
Peng Fand0ca2892019-08-27 06:25:37 +0000556 * 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);
561 /*
Peng Faneae4de22018-01-10 13:20:37 +0800562 * 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);
Peng Fan9cf2aa32020-07-09 13:52:41 +0800570
571 if (is_imx8md() || is_imx8mmd() || is_imx8mmdl() || is_imx8mms() ||
572 is_imx8mmsl() || is_imx8mnd() || is_imx8mndl() || is_imx8mns() ||
Ye Li715180e2021-03-19 15:57:11 +0800573 is_imx8mnsl() || is_imx8mpd() || is_imx8mnud() || is_imx8mnus()) {
Peng Fan9cf2aa32020-07-09 13:52:41 +0800574 /* 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);
Ye Li715180e2021-03-19 15:57:11 +0800582 if (is_imx8mms() || is_imx8mmsl() || is_imx8mns() || is_imx8mnsl() || is_imx8mnus()) {
Peng Fan9cf2aa32020-07-09 13:52:41 +0800583 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 }
Peng Faneae4de22018-01-10 13:20:37 +0800589 }
590
Peng Fanc0b30d72019-04-17 09:41:16 +0000591 if (is_imx8mq()) {
592 clock_enable(CCGR_OCOTP, 1);
593 if (readl(&ocotp->ctrl) & 0x200)
594 writel(0x200, &ocotp->ctrl_clr);
595 }
596
Peng Faneae4de22018-01-10 13:20:37 +0800597 return 0;
598}
599
Peng Fanc9823b02019-09-16 03:09:36 +0000600#if defined(CONFIG_IMX8MN) || defined(CONFIG_IMX8MP)
601struct rom_api *g_rom_api = (struct rom_api *)0x980;
Peng Fanc9823b02019-09-16 03:09:36 +0000602#endif
603
Marek Vasut520ded02021-07-03 04:55:33 +0200604#if defined(CONFIG_IMX8M)
605#include <spl.h>
606int spl_mmc_emmc_boot_partition(struct mmc *mmc)
607{
608 u32 *rom_log_addr = (u32 *)0x9e0;
609 u32 *rom_log;
610 u8 event_id;
611 int i, part;
612
613 part = default_spl_mmc_emmc_boot_partition(mmc);
614
615 /* If the ROM event log pointer is not valid. */
616 if (*rom_log_addr < 0x900000 || *rom_log_addr >= 0xb00000 ||
617 *rom_log_addr & 0x3)
618 return part;
619
620 /* Parse the ROM event ID version 2 log */
621 rom_log = (u32 *)(uintptr_t)(*rom_log_addr);
622 for (i = 0; i < 128; i++) {
623 event_id = rom_log[i] >> 24;
624 switch (event_id) {
625 case 0x00: /* End of list */
626 return part;
627 /* Log entries with 1 parameter, skip 1 */
628 case 0x80: /* Start to perform the device initialization */
629 case 0x81: /* The boot device initialization completes */
630 case 0x8f: /* The boot device initialization fails */
631 case 0x90: /* Start to read data from boot device */
632 case 0x91: /* Reading data from boot device completes */
633 case 0x9f: /* Reading data from boot device fails */
634 i += 1;
635 continue;
636 /* Log entries with 2 parameters, skip 2 */
637 case 0xa0: /* Image authentication result */
638 case 0xc0: /* Jump to the boot image soon */
639 i += 2;
640 continue;
641 /* Boot from the secondary boot image */
642 case 0x51:
643 /*
644 * Swap the eMMC boot partitions in case there was a
645 * fallback event (i.e. primary image was corrupted
646 * and that corruption was recognized by the BootROM),
647 * so the SPL loads the rest of the U-Boot from the
648 * correct eMMC boot partition, since the BootROM
649 * leaves the boot partition set to the corrupted one.
650 */
651 if (part == 1)
652 part = 2;
653 else if (part == 2)
654 part = 1;
655 continue;
656 default:
657 continue;
658 }
659 }
660
661 return part;
662}
663#endif
664
Peng Faneae4de22018-01-10 13:20:37 +0800665bool is_usb_boot(void)
666{
667 return get_boot_device() == USB_BOOT;
668}
669
670#ifdef CONFIG_OF_SYSTEM_SETUP
Peng Fan435dc122020-07-09 14:06:49 +0800671bool check_fdt_new_path(void *blob)
672{
673 const char *soc_path = "/soc@0";
674 int nodeoff;
675
676 nodeoff = fdt_path_offset(blob, soc_path);
677 if (nodeoff < 0)
678 return false;
679
680 return true;
681}
682
683static int disable_fdt_nodes(void *blob, const char *const nodes_path[], int size_array)
684{
685 int i = 0;
686 int rc;
687 int nodeoff;
688 const char *status = "disabled";
689
690 for (i = 0; i < size_array; i++) {
691 nodeoff = fdt_path_offset(blob, nodes_path[i]);
692 if (nodeoff < 0)
693 continue; /* Not found, skip it */
694
695 printf("Found %s node\n", nodes_path[i]);
696
697add_status:
698 rc = fdt_setprop(blob, nodeoff, "status", status, strlen(status) + 1);
699 if (rc) {
700 if (rc == -FDT_ERR_NOSPACE) {
701 rc = fdt_increase_size(blob, 512);
702 if (!rc)
703 goto add_status;
704 }
705 printf("Unable to update property %s:%s, err=%s\n",
706 nodes_path[i], "status", fdt_strerror(rc));
707 } else {
708 printf("Modify %s:%s disabled\n",
709 nodes_path[i], "status");
710 }
711 }
712
713 return 0;
714}
715
716#ifdef CONFIG_IMX8MQ
717bool check_dcss_fused(void)
718{
719 struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
720 struct fuse_bank *bank = &ocotp->bank[1];
721 struct fuse_bank1_regs *fuse =
722 (struct fuse_bank1_regs *)bank->fuse_regs;
723 u32 value = readl(&fuse->tester4);
724
725 if (value & 0x4000000)
726 return true;
727
728 return false;
729}
730
731static int disable_mipi_dsi_nodes(void *blob)
732{
733 static const char * const nodes_path[] = {
734 "/mipi_dsi@30A00000",
735 "/mipi_dsi_bridge@30A00000",
736 "/dsi_phy@30A00300",
737 "/soc@0/bus@30800000/mipi_dsi@30a00000",
Peng Fan7d4195c2021-03-19 15:57:13 +0800738 "/soc@0/bus@30800000/dphy@30a00300",
739 "/soc@0/bus@30800000/mipi-dsi@30a00000",
Peng Fan435dc122020-07-09 14:06:49 +0800740 };
741
742 return disable_fdt_nodes(blob, nodes_path, ARRAY_SIZE(nodes_path));
743}
744
745static int disable_dcss_nodes(void *blob)
746{
747 static const char * const nodes_path[] = {
748 "/dcss@0x32e00000",
749 "/dcss@32e00000",
750 "/hdmi@32c00000",
751 "/hdmi_cec@32c33800",
752 "/hdmi_drm@32c00000",
753 "/display-subsystem",
754 "/sound-hdmi",
755 "/sound-hdmi-arc",
756 "/soc@0/bus@32c00000/display-controller@32e00000",
757 "/soc@0/bus@32c00000/hdmi@32c00000",
758 };
759
760 return disable_fdt_nodes(blob, nodes_path, ARRAY_SIZE(nodes_path));
761}
762
763static int check_mipi_dsi_nodes(void *blob)
764{
765 static const char * const lcdif_path[] = {
766 "/lcdif@30320000",
Peng Fan7d4195c2021-03-19 15:57:13 +0800767 "/soc@0/bus@30000000/lcdif@30320000",
768 "/soc@0/bus@30000000/lcd-controller@30320000"
Peng Fan435dc122020-07-09 14:06:49 +0800769 };
770 static const char * const mipi_dsi_path[] = {
771 "/mipi_dsi@30A00000",
772 "/soc@0/bus@30800000/mipi_dsi@30a00000"
773 };
774 static const char * const lcdif_ep_path[] = {
775 "/lcdif@30320000/port@0/mipi-dsi-endpoint",
Peng Fan7d4195c2021-03-19 15:57:13 +0800776 "/soc@0/bus@30000000/lcdif@30320000/port@0/endpoint",
777 "/soc@0/bus@30000000/lcd-controller@30320000/port@0/endpoint"
Peng Fan435dc122020-07-09 14:06:49 +0800778 };
779 static const char * const mipi_dsi_ep_path[] = {
780 "/mipi_dsi@30A00000/port@1/endpoint",
Peng Fan7d4195c2021-03-19 15:57:13 +0800781 "/soc@0/bus@30800000/mipi_dsi@30a00000/ports/port@0/endpoint",
782 "/soc@0/bus@30800000/mipi-dsi@30a00000/ports/port@0/endpoint@0"
Peng Fan435dc122020-07-09 14:06:49 +0800783 };
784
785 int lookup_node;
786 int nodeoff;
787 bool new_path = check_fdt_new_path(blob);
788 int i = new_path ? 1 : 0;
789
790 nodeoff = fdt_path_offset(blob, lcdif_path[i]);
791 if (nodeoff < 0 || !fdtdec_get_is_enabled(blob, nodeoff)) {
792 /*
793 * If can't find lcdif node or lcdif node is disabled,
794 * then disable all mipi dsi, since they only can input
795 * from DCSS
796 */
797 return disable_mipi_dsi_nodes(blob);
798 }
799
800 nodeoff = fdt_path_offset(blob, mipi_dsi_path[i]);
801 if (nodeoff < 0 || !fdtdec_get_is_enabled(blob, nodeoff))
802 return 0;
803
804 nodeoff = fdt_path_offset(blob, lcdif_ep_path[i]);
805 if (nodeoff < 0) {
806 /*
807 * If can't find lcdif endpoint, then disable all mipi dsi,
808 * since they only can input from DCSS
809 */
810 return disable_mipi_dsi_nodes(blob);
811 }
812
813 lookup_node = fdtdec_lookup_phandle(blob, nodeoff, "remote-endpoint");
814 nodeoff = fdt_path_offset(blob, mipi_dsi_ep_path[i]);
815
816 if (nodeoff > 0 && nodeoff == lookup_node)
817 return 0;
818
819 return disable_mipi_dsi_nodes(blob);
820}
821#endif
822
823int disable_vpu_nodes(void *blob)
824{
825 static const char * const nodes_path_8mq[] = {
826 "/vpu@38300000",
827 "/soc@0/vpu@38300000"
828 };
829
830 static const char * const nodes_path_8mm[] = {
831 "/vpu_g1@38300000",
832 "/vpu_g2@38310000",
833 "/vpu_h1@38320000"
834 };
835
836 static const char * const nodes_path_8mp[] = {
837 "/vpu_g1@38300000",
838 "/vpu_g2@38310000",
839 "/vpu_vc8000e@38320000"
840 };
841
842 if (is_imx8mq())
843 return disable_fdt_nodes(blob, nodes_path_8mq, ARRAY_SIZE(nodes_path_8mq));
844 else if (is_imx8mm())
845 return disable_fdt_nodes(blob, nodes_path_8mm, ARRAY_SIZE(nodes_path_8mm));
846 else if (is_imx8mp())
847 return disable_fdt_nodes(blob, nodes_path_8mp, ARRAY_SIZE(nodes_path_8mp));
848 else
849 return -EPERM;
850}
851
Ye Liee337ce2021-03-19 15:57:09 +0800852#ifdef CONFIG_IMX8MN_LOW_DRIVE_MODE
853static int low_drive_gpu_freq(void *blob)
854{
855 static const char *nodes_path_8mn[] = {
856 "/gpu@38000000",
857 "/soc@0/gpu@38000000"
858 };
859
860 int nodeoff, cnt, i;
861 u32 assignedclks[7];
862
863 nodeoff = fdt_path_offset(blob, nodes_path_8mn[0]);
864 if (nodeoff < 0)
865 return nodeoff;
866
867 cnt = fdtdec_get_int_array_count(blob, nodeoff, "assigned-clock-rates", assignedclks, 7);
868 if (cnt < 0)
869 return cnt;
870
871 if (cnt != 7)
872 printf("Warning: %s, assigned-clock-rates count %d\n", nodes_path_8mn[0], cnt);
873
874 assignedclks[cnt - 1] = 200000000;
875 assignedclks[cnt - 2] = 200000000;
876
877 for (i = 0; i < cnt; i++) {
878 debug("<%u>, ", assignedclks[i]);
879 assignedclks[i] = cpu_to_fdt32(assignedclks[i]);
880 }
881 debug("\n");
882
883 return fdt_setprop(blob, nodeoff, "assigned-clock-rates", &assignedclks, sizeof(assignedclks));
884}
885#endif
886
Peng Fanf5f9b8e2022-04-07 15:55:53 +0800887static bool check_remote_endpoint(void *blob, const char *ep1, const char *ep2)
888{
889 int lookup_node;
890 int nodeoff;
891
892 nodeoff = fdt_path_offset(blob, ep1);
893 if (nodeoff) {
894 lookup_node = fdtdec_lookup_phandle(blob, nodeoff, "remote-endpoint");
895 nodeoff = fdt_path_offset(blob, ep2);
896
897 if (nodeoff > 0 && nodeoff == lookup_node)
898 return true;
899 }
900
901 return false;
902}
903
904int disable_dsi_lcdif_nodes(void *blob)
905{
906 int ret;
907
908 static const char * const dsi_path_8mp[] = {
909 "/soc@0/bus@32c00000/mipi_dsi@32e60000"
910 };
911
912 static const char * const lcdif_path_8mp[] = {
913 "/soc@0/bus@32c00000/lcd-controller@32e80000"
914 };
915
916 static const char * const lcdif_ep_path_8mp[] = {
917 "/soc@0/bus@32c00000/lcd-controller@32e80000/port@0/endpoint"
918 };
919 static const char * const dsi_ep_path_8mp[] = {
920 "/soc@0/bus@32c00000/mipi_dsi@32e60000/port@0/endpoint"
921 };
922
923 ret = disable_fdt_nodes(blob, dsi_path_8mp, ARRAY_SIZE(dsi_path_8mp));
924 if (ret)
925 return ret;
926
927 if (check_remote_endpoint(blob, dsi_ep_path_8mp[0], lcdif_ep_path_8mp[0])) {
928 /* Disable lcdif node */
929 return disable_fdt_nodes(blob, lcdif_path_8mp, ARRAY_SIZE(lcdif_path_8mp));
930 }
931
932 return 0;
933}
934
935int disable_lvds_lcdif_nodes(void *blob)
936{
937 int ret, i;
938
939 static const char * const ldb_path_8mp[] = {
940 "/soc@0/bus@32c00000/ldb@32ec005c",
941 "/soc@0/bus@32c00000/phy@32ec0128"
942 };
943
944 static const char * const lcdif_path_8mp[] = {
945 "/soc@0/bus@32c00000/lcd-controller@32e90000"
946 };
947
948 static const char * const lcdif_ep_path_8mp[] = {
949 "/soc@0/bus@32c00000/lcd-controller@32e90000/port@0/endpoint@0",
950 "/soc@0/bus@32c00000/lcd-controller@32e90000/port@0/endpoint@1"
951 };
952 static const char * const ldb_ep_path_8mp[] = {
953 "/soc@0/bus@32c00000/ldb@32ec005c/lvds-channel@0/port@0/endpoint",
954 "/soc@0/bus@32c00000/ldb@32ec005c/lvds-channel@1/port@0/endpoint"
955 };
956
957 ret = disable_fdt_nodes(blob, ldb_path_8mp, ARRAY_SIZE(ldb_path_8mp));
958 if (ret)
959 return ret;
960
961 for (i = 0; i < ARRAY_SIZE(ldb_ep_path_8mp); i++) {
962 if (check_remote_endpoint(blob, ldb_ep_path_8mp[i], lcdif_ep_path_8mp[i])) {
963 /* Disable lcdif node */
964 return disable_fdt_nodes(blob, lcdif_path_8mp, ARRAY_SIZE(lcdif_path_8mp));
965 }
966 }
967
968 return 0;
969}
970
Peng Fan435dc122020-07-09 14:06:49 +0800971int disable_gpu_nodes(void *blob)
972{
973 static const char * const nodes_path_8mn[] = {
Peng Fan7d4195c2021-03-19 15:57:13 +0800974 "/gpu@38000000",
975 "/soc@/gpu@38000000"
Peng Fan435dc122020-07-09 14:06:49 +0800976 };
977
Peng Fanf5f9b8e2022-04-07 15:55:53 +0800978 static const char * const nodes_path_8mp[] = {
979 "/gpu3d@38000000",
980 "/gpu2d@38008000"
981 };
982
983 if (is_imx8mp())
984 return disable_fdt_nodes(blob, nodes_path_8mp, ARRAY_SIZE(nodes_path_8mp));
985 else
986 return disable_fdt_nodes(blob, nodes_path_8mn, ARRAY_SIZE(nodes_path_8mn));
Peng Fan435dc122020-07-09 14:06:49 +0800987}
988
989int disable_npu_nodes(void *blob)
990{
991 static const char * const nodes_path_8mp[] = {
992 "/vipsi@38500000"
993 };
994
995 return disable_fdt_nodes(blob, nodes_path_8mp, ARRAY_SIZE(nodes_path_8mp));
996}
997
998int disable_isp_nodes(void *blob)
999{
1000 static const char * const nodes_path_8mp[] = {
1001 "/soc@0/bus@32c00000/camera/isp@32e10000",
1002 "/soc@0/bus@32c00000/camera/isp@32e20000"
1003 };
1004
1005 return disable_fdt_nodes(blob, nodes_path_8mp, ARRAY_SIZE(nodes_path_8mp));
1006}
1007
1008int disable_dsp_nodes(void *blob)
1009{
1010 static const char * const nodes_path_8mp[] = {
1011 "/dsp@3b6e8000"
1012 };
1013
1014 return disable_fdt_nodes(blob, nodes_path_8mp, ARRAY_SIZE(nodes_path_8mp));
1015}
1016
Ye Li26517af2021-03-19 15:57:12 +08001017static void disable_thermal_cpu_nodes(void *blob, u32 disabled_cores)
1018{
1019 static const char * const thermal_path[] = {
1020 "/thermal-zones/cpu-thermal/cooling-maps/map0"
1021 };
1022
1023 int nodeoff, cnt, i, ret, j;
1024 u32 cooling_dev[12];
1025
1026 for (i = 0; i < ARRAY_SIZE(thermal_path); i++) {
1027 nodeoff = fdt_path_offset(blob, thermal_path[i]);
1028 if (nodeoff < 0)
1029 continue; /* Not found, skip it */
1030
1031 cnt = fdtdec_get_int_array_count(blob, nodeoff, "cooling-device", cooling_dev, 12);
1032 if (cnt < 0)
1033 continue;
1034
1035 if (cnt != 12)
1036 printf("Warning: %s, cooling-device count %d\n", thermal_path[i], cnt);
1037
1038 for (j = 0; j < cnt; j++)
1039 cooling_dev[j] = cpu_to_fdt32(cooling_dev[j]);
1040
1041 ret = fdt_setprop(blob, nodeoff, "cooling-device", &cooling_dev,
1042 sizeof(u32) * (12 - disabled_cores * 3));
1043 if (ret < 0) {
1044 printf("Warning: %s, cooling-device setprop failed %d\n",
1045 thermal_path[i], ret);
1046 continue;
1047 }
1048
1049 printf("Update node %s, cooling-device prop\n", thermal_path[i]);
1050 }
1051}
1052
1053static void disable_pmu_cpu_nodes(void *blob, u32 disabled_cores)
1054{
1055 static const char * const pmu_path[] = {
1056 "/pmu"
1057 };
1058
1059 int nodeoff, cnt, i, ret, j;
1060 u32 irq_affinity[4];
1061
1062 for (i = 0; i < ARRAY_SIZE(pmu_path); i++) {
1063 nodeoff = fdt_path_offset(blob, pmu_path[i]);
1064 if (nodeoff < 0)
1065 continue; /* Not found, skip it */
1066
1067 cnt = fdtdec_get_int_array_count(blob, nodeoff, "interrupt-affinity",
1068 irq_affinity, 4);
1069 if (cnt < 0)
1070 continue;
1071
1072 if (cnt != 4)
1073 printf("Warning: %s, interrupt-affinity count %d\n", pmu_path[i], cnt);
1074
1075 for (j = 0; j < cnt; j++)
1076 irq_affinity[j] = cpu_to_fdt32(irq_affinity[j]);
1077
1078 ret = fdt_setprop(blob, nodeoff, "interrupt-affinity", &irq_affinity,
1079 sizeof(u32) * (4 - disabled_cores));
1080 if (ret < 0) {
1081 printf("Warning: %s, interrupt-affinity setprop failed %d\n",
1082 pmu_path[i], ret);
1083 continue;
1084 }
1085
1086 printf("Update node %s, interrupt-affinity prop\n", pmu_path[i]);
1087 }
1088}
1089
Peng Fan435dc122020-07-09 14:06:49 +08001090static int disable_cpu_nodes(void *blob, u32 disabled_cores)
1091{
1092 static const char * const nodes_path[] = {
1093 "/cpus/cpu@1",
1094 "/cpus/cpu@2",
1095 "/cpus/cpu@3",
1096 };
1097 u32 i = 0;
1098 int rc;
1099 int nodeoff;
1100
1101 if (disabled_cores > 3)
1102 return -EINVAL;
1103
1104 i = 3 - disabled_cores;
1105
1106 for (; i < 3; i++) {
1107 nodeoff = fdt_path_offset(blob, nodes_path[i]);
1108 if (nodeoff < 0)
1109 continue; /* Not found, skip it */
1110
1111 debug("Found %s node\n", nodes_path[i]);
1112
1113 rc = fdt_del_node(blob, nodeoff);
1114 if (rc < 0) {
1115 printf("Unable to delete node %s, err=%s\n",
1116 nodes_path[i], fdt_strerror(rc));
1117 } else {
1118 printf("Delete node %s\n", nodes_path[i]);
1119 }
1120 }
1121
Ye Li26517af2021-03-19 15:57:12 +08001122 disable_thermal_cpu_nodes(blob, disabled_cores);
1123 disable_pmu_cpu_nodes(blob, disabled_cores);
1124
Peng Fan435dc122020-07-09 14:06:49 +08001125 return 0;
1126}
1127
Peng Fana08bc872022-04-07 15:55:54 +08001128static int cleanup_nodes_for_efi(void *blob)
1129{
Peng Fan1585b202022-04-07 15:55:55 +08001130 static const char * const path[][2] = {
1131 { "/soc@0/bus@32c00000/usb@32e40000", "extcon" },
1132 { "/soc@0/bus@32c00000/usb@32e50000", "extcon" },
1133 { "/soc@0/bus@30800000/ethernet@30be0000", "phy-reset-gpios" },
1134 { "/soc@0/bus@30800000/ethernet@30bf0000", "phy-reset-gpios" }
1135 };
Peng Fana08bc872022-04-07 15:55:54 +08001136 int nodeoff, i, rc;
1137
Peng Fan1585b202022-04-07 15:55:55 +08001138 for (i = 0; i < ARRAY_SIZE(path); i++) {
1139 nodeoff = fdt_path_offset(blob, path[i][0]);
Peng Fana08bc872022-04-07 15:55:54 +08001140 if (nodeoff < 0)
1141 continue; /* Not found, skip it */
Peng Fan1585b202022-04-07 15:55:55 +08001142 debug("Found %s node\n", path[i][0]);
Peng Fana08bc872022-04-07 15:55:54 +08001143
Peng Fan1585b202022-04-07 15:55:55 +08001144 rc = fdt_delprop(blob, nodeoff, path[i][1]);
Peng Fana08bc872022-04-07 15:55:54 +08001145 if (rc == -FDT_ERR_NOTFOUND)
1146 continue;
1147 if (rc) {
1148 printf("Unable to update property %s:%s, err=%s\n",
Peng Fan1585b202022-04-07 15:55:55 +08001149 path[i][0], path[i][1], fdt_strerror(rc));
Peng Fana08bc872022-04-07 15:55:54 +08001150 return rc;
1151 }
1152
Peng Fan1585b202022-04-07 15:55:55 +08001153 printf("Remove %s:%s\n", path[i][0], path[i][1]);
Peng Fana08bc872022-04-07 15:55:54 +08001154 }
1155
1156 return 0;
1157}
Peng Fana08bc872022-04-07 15:55:54 +08001158
Andrejs Cainikovs2f3491c2022-05-27 15:20:42 +02001159static int fixup_thermal_trips(void *blob, const char *name)
1160{
1161 int minc, maxc;
1162 int node, trip;
1163
1164 node = fdt_path_offset(blob, "/thermal-zones");
1165 if (node < 0)
1166 return node;
1167
1168 node = fdt_subnode_offset(blob, node, name);
1169 if (node < 0)
1170 return node;
1171
1172 node = fdt_subnode_offset(blob, node, "trips");
1173 if (node < 0)
1174 return node;
1175
1176 get_cpu_temp_grade(&minc, &maxc);
1177
1178 fdt_for_each_subnode(trip, blob, node) {
1179 const char *type;
1180 int temp, ret;
1181
1182 type = fdt_getprop(blob, trip, "type", NULL);
1183 if (!type)
1184 continue;
1185
1186 temp = 0;
1187 if (!strcmp(type, "critical"))
1188 temp = 1000 * maxc;
1189 else if (!strcmp(type, "passive"))
1190 temp = 1000 * (maxc - 10);
1191 if (temp) {
1192 ret = fdt_setprop_u32(blob, trip, "temperature", temp);
1193 if (ret)
1194 return ret;
1195 }
1196 }
1197
1198 return 0;
1199}
1200
Masahiro Yamadaf7ed78b2020-06-26 15:13:33 +09001201int ft_system_setup(void *blob, struct bd_info *bd)
Peng Faneae4de22018-01-10 13:20:37 +08001202{
Peng Fan435dc122020-07-09 14:06:49 +08001203#ifdef CONFIG_IMX8MQ
Peng Faneae4de22018-01-10 13:20:37 +08001204 int i = 0;
1205 int rc;
1206 int nodeoff;
1207
Peng Fan435dc122020-07-09 14:06:49 +08001208 if (get_boot_device() == USB_BOOT) {
1209 disable_dcss_nodes(blob);
1210
1211 bool new_path = check_fdt_new_path(blob);
1212 int v = new_path ? 1 : 0;
1213 static const char * const usb_dwc3_path[] = {
1214 "/usb@38100000/dwc3",
1215 "/soc@0/usb@38100000"
1216 };
1217
1218 nodeoff = fdt_path_offset(blob, usb_dwc3_path[v]);
1219 if (nodeoff >= 0) {
1220 const char *speed = "high-speed";
1221
1222 printf("Found %s node\n", usb_dwc3_path[v]);
1223
1224usb_modify_speed:
1225
1226 rc = fdt_setprop(blob, nodeoff, "maximum-speed", speed, strlen(speed) + 1);
1227 if (rc) {
1228 if (rc == -FDT_ERR_NOSPACE) {
1229 rc = fdt_increase_size(blob, 512);
1230 if (!rc)
1231 goto usb_modify_speed;
1232 }
1233 printf("Unable to set property %s:%s, err=%s\n",
1234 usb_dwc3_path[v], "maximum-speed", fdt_strerror(rc));
1235 } else {
1236 printf("Modify %s:%s = %s\n",
1237 usb_dwc3_path[v], "maximum-speed", speed);
1238 }
1239 } else {
1240 printf("Can't found %s node\n", usb_dwc3_path[v]);
1241 }
1242 }
1243
Peng Faneae4de22018-01-10 13:20:37 +08001244 /* Disable the CPU idle for A0 chip since the HW does not support it */
1245 if (is_soc_rev(CHIP_REV_1_0)) {
1246 static const char * const nodes_path[] = {
1247 "/cpus/cpu@0",
1248 "/cpus/cpu@1",
1249 "/cpus/cpu@2",
1250 "/cpus/cpu@3",
1251 };
1252
1253 for (i = 0; i < ARRAY_SIZE(nodes_path); i++) {
1254 nodeoff = fdt_path_offset(blob, nodes_path[i]);
1255 if (nodeoff < 0)
1256 continue; /* Not found, skip it */
1257
Marek Vasute2e7a772020-04-24 21:37:33 +02001258 debug("Found %s node\n", nodes_path[i]);
Peng Faneae4de22018-01-10 13:20:37 +08001259
1260 rc = fdt_delprop(blob, nodeoff, "cpu-idle-states");
Marek Vasute2e7a772020-04-24 21:37:33 +02001261 if (rc == -FDT_ERR_NOTFOUND)
1262 continue;
Peng Faneae4de22018-01-10 13:20:37 +08001263 if (rc) {
1264 printf("Unable to update property %s:%s, err=%s\n",
1265 nodes_path[i], "status", fdt_strerror(rc));
1266 return rc;
1267 }
1268
Marek Vasute2e7a772020-04-24 21:37:33 +02001269 debug("Remove %s:%s\n", nodes_path[i],
Peng Faneae4de22018-01-10 13:20:37 +08001270 "cpu-idle-states");
1271 }
1272 }
1273
Peng Fan435dc122020-07-09 14:06:49 +08001274 if (is_imx8mql()) {
1275 disable_vpu_nodes(blob);
1276 if (check_dcss_fused()) {
1277 printf("DCSS is fused\n");
1278 disable_dcss_nodes(blob);
1279 check_mipi_dsi_nodes(blob);
1280 }
1281 }
1282
1283 if (is_imx8md())
1284 disable_cpu_nodes(blob, 2);
1285
1286#elif defined(CONFIG_IMX8MM)
1287 if (is_imx8mml() || is_imx8mmdl() || is_imx8mmsl())
1288 disable_vpu_nodes(blob);
1289
1290 if (is_imx8mmd() || is_imx8mmdl())
1291 disable_cpu_nodes(blob, 2);
1292 else if (is_imx8mms() || is_imx8mmsl())
1293 disable_cpu_nodes(blob, 3);
1294
1295#elif defined(CONFIG_IMX8MN)
1296 if (is_imx8mnl() || is_imx8mndl() || is_imx8mnsl())
1297 disable_gpu_nodes(blob);
Ye Liee337ce2021-03-19 15:57:09 +08001298#ifdef CONFIG_IMX8MN_LOW_DRIVE_MODE
1299 else {
1300 int ldm_gpu = low_drive_gpu_freq(blob);
1301
1302 if (ldm_gpu < 0)
1303 printf("Update GPU node assigned-clock-rates failed\n");
1304 else
1305 printf("Update GPU node assigned-clock-rates ok\n");
1306 }
1307#endif
Peng Fan435dc122020-07-09 14:06:49 +08001308
Ye Li715180e2021-03-19 15:57:11 +08001309 if (is_imx8mnd() || is_imx8mndl() || is_imx8mnud())
Peng Fan435dc122020-07-09 14:06:49 +08001310 disable_cpu_nodes(blob, 2);
Ye Li715180e2021-03-19 15:57:11 +08001311 else if (is_imx8mns() || is_imx8mnsl() || is_imx8mnus())
Peng Fan435dc122020-07-09 14:06:49 +08001312 disable_cpu_nodes(blob, 3);
1313
1314#elif defined(CONFIG_IMX8MP)
Peng Fanf5f9b8e2022-04-07 15:55:53 +08001315 if (is_imx8mpul()) {
1316 /* Disable GPU */
1317 disable_gpu_nodes(blob);
1318
1319 /* Disable DSI */
1320 disable_dsi_lcdif_nodes(blob);
1321
1322 /* Disable LVDS */
1323 disable_lvds_lcdif_nodes(blob);
1324 }
1325
1326 if (is_imx8mpul() || is_imx8mpl())
Peng Fan435dc122020-07-09 14:06:49 +08001327 disable_vpu_nodes(blob);
1328
Peng Fanf5f9b8e2022-04-07 15:55:53 +08001329 if (is_imx8mpul() || is_imx8mpl() || is_imx8mp6())
Peng Fan435dc122020-07-09 14:06:49 +08001330 disable_npu_nodes(blob);
1331
Peng Fanf5f9b8e2022-04-07 15:55:53 +08001332 if (is_imx8mpul() || is_imx8mpl())
Peng Fan435dc122020-07-09 14:06:49 +08001333 disable_isp_nodes(blob);
1334
Peng Fanf5f9b8e2022-04-07 15:55:53 +08001335 if (is_imx8mpul() || is_imx8mpl() || is_imx8mp6())
Peng Fan435dc122020-07-09 14:06:49 +08001336 disable_dsp_nodes(blob);
1337
1338 if (is_imx8mpd())
1339 disable_cpu_nodes(blob, 2);
1340#endif
1341
Peng Fan1585b202022-04-07 15:55:55 +08001342 cleanup_nodes_for_efi(blob);
Andrejs Cainikovs2f3491c2022-05-27 15:20:42 +02001343
1344 if (fixup_thermal_trips(blob, "cpu-thermal"))
1345 printf("Failed to update cpu-thermal trip(s)");
1346 if (IS_ENABLED(CONFIG_IMX8MP) &&
1347 fixup_thermal_trips(blob, "soc-thermal"))
1348 printf("Failed to update soc-thermal trip(s)");
1349
Peng Faneae4de22018-01-10 13:20:37 +08001350 return 0;
1351}
1352#endif
1353
Peng Fanf5f9b8e2022-04-07 15:55:53 +08001354#ifdef CONFIG_OF_BOARD_FIXUP
1355#ifndef CONFIG_SPL_BUILD
1356int board_fix_fdt(void *fdt)
1357{
1358 if (is_imx8mpul()) {
1359 int i = 0;
1360 int nodeoff, ret;
1361 const char *status = "disabled";
1362 static const char * const dsi_nodes[] = {
1363 "/soc@0/bus@32c00000/mipi_dsi@32e60000",
1364 "/soc@0/bus@32c00000/lcd-controller@32e80000",
1365 "/dsi-host"
1366 };
1367
1368 for (i = 0; i < ARRAY_SIZE(dsi_nodes); i++) {
1369 nodeoff = fdt_path_offset(fdt, dsi_nodes[i]);
1370 if (nodeoff > 0) {
1371set_status:
1372 ret = fdt_setprop(fdt, nodeoff, "status", status,
1373 strlen(status) + 1);
1374 if (ret == -FDT_ERR_NOSPACE) {
1375 ret = fdt_increase_size(fdt, 512);
1376 if (!ret)
1377 goto set_status;
1378 }
1379 }
1380 }
1381 }
1382
1383 return 0;
1384}
1385#endif
1386#endif
1387
Marek Vasut64dc4de2020-04-29 15:04:21 +02001388#if !CONFIG_IS_ENABLED(SYSRESET)
Harald Seiler6f14d5f2020-12-15 16:47:52 +01001389void reset_cpu(void)
Peng Faneae4de22018-01-10 13:20:37 +08001390{
Claudius Heinee73f3942020-04-29 15:04:23 +02001391 struct watchdog_regs *wdog = (struct watchdog_regs *)WDOG1_BASE_ADDR;
Peng Faneae4de22018-01-10 13:20:37 +08001392
Ye Li54a915a2019-12-09 00:47:18 -08001393 /* Clear WDA to trigger WDOG_B immediately */
1394 writew((SET_WCR_WT(1) | WCR_WDT | WCR_WDE | WCR_SRS), &wdog->wcr);
Peng Fan24290d92019-08-27 06:25:41 +00001395
Ye Li54a915a2019-12-09 00:47:18 -08001396 while (1) {
1397 /*
Harald Seilerec0c4472020-04-29 15:04:22 +02001398 * spin for .5 seconds before reset
Ye Li54a915a2019-12-09 00:47:18 -08001399 */
1400 }
Peng Faneae4de22018-01-10 13:20:37 +08001401}
Peng Fan24290d92019-08-27 06:25:41 +00001402#endif
Peng Fan5760d8d2020-04-22 10:51:13 +08001403
1404#if defined(CONFIG_ARCH_MISC_INIT)
Peng Fan5760d8d2020-04-22 10:51:13 +08001405int arch_misc_init(void)
1406{
Gaurav Jain81113a02022-03-24 11:50:27 +05301407 if (IS_ENABLED(CONFIG_FSL_CAAM)) {
1408 struct udevice *dev;
1409 int ret;
1410
1411 ret = uclass_get_device_by_driver(UCLASS_MISC, DM_DRIVER_GET(caam_jr), &dev);
1412 if (ret)
Ye Liec346892022-05-11 13:56:20 +05301413 printf("Failed to initialize caam_jr: %d\n", ret);
Gaurav Jain81113a02022-03-24 11:50:27 +05301414 }
Peng Fan5760d8d2020-04-22 10:51:13 +08001415
1416 return 0;
1417}
1418#endif
Ye Li325cd012020-05-03 22:19:52 +08001419
1420void imx_tmu_arch_init(void *reg_base)
1421{
Ye Lia00f2f02020-05-03 22:19:53 +08001422 if (is_imx8mm() || is_imx8mn()) {
Ye Li325cd012020-05-03 22:19:52 +08001423 /* Load TCALIV and TASR from fuses */
1424 struct ocotp_regs *ocotp =
1425 (struct ocotp_regs *)OCOTP_BASE_ADDR;
1426 struct fuse_bank *bank = &ocotp->bank[3];
1427 struct fuse_bank3_regs *fuse =
1428 (struct fuse_bank3_regs *)bank->fuse_regs;
1429
1430 u32 tca_rt, tca_hr, tca_en;
1431 u32 buf_vref, buf_slope;
1432
1433 tca_rt = fuse->ana0 & 0xFF;
1434 tca_hr = (fuse->ana0 & 0xFF00) >> 8;
1435 tca_en = (fuse->ana0 & 0x2000000) >> 25;
1436
1437 buf_vref = (fuse->ana0 & 0x1F00000) >> 20;
1438 buf_slope = (fuse->ana0 & 0xF0000) >> 16;
1439
1440 writel(buf_vref | (buf_slope << 16), (ulong)reg_base + 0x28);
1441 writel((tca_en << 31) | (tca_hr << 16) | tca_rt,
1442 (ulong)reg_base + 0x30);
1443 }
Ye Li41a20252020-05-03 22:19:54 +08001444#ifdef CONFIG_IMX8MP
1445 /* Load TCALIV0/1/m40 and TRIM from fuses */
1446 struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
1447 struct fuse_bank *bank = &ocotp->bank[38];
1448 struct fuse_bank38_regs *fuse =
1449 (struct fuse_bank38_regs *)bank->fuse_regs;
1450 struct fuse_bank *bank2 = &ocotp->bank[39];
1451 struct fuse_bank39_regs *fuse2 =
1452 (struct fuse_bank39_regs *)bank2->fuse_regs;
1453 u32 buf_vref, buf_slope, bjt_cur, vlsb, bgr;
1454 u32 reg;
1455 u32 tca40[2], tca25[2], tca105[2];
1456
1457 /* For blank sample */
1458 if (!fuse->ana_trim2 && !fuse->ana_trim3 &&
1459 !fuse->ana_trim4 && !fuse2->ana_trim5) {
1460 /* Use a default 25C binary codes */
1461 tca25[0] = 1596;
Ye Lid756ca02020-05-03 22:19:55 +08001462 tca25[1] = 1596;
Ye Li41a20252020-05-03 22:19:54 +08001463 writel(tca25[0], (ulong)reg_base + 0x30);
Ye Lid756ca02020-05-03 22:19:55 +08001464 writel(tca25[1], (ulong)reg_base + 0x34);
Ye Li41a20252020-05-03 22:19:54 +08001465 return;
1466 }
1467
1468 buf_vref = (fuse->ana_trim2 & 0xc0) >> 6;
1469 buf_slope = (fuse->ana_trim2 & 0xF00) >> 8;
1470 bjt_cur = (fuse->ana_trim2 & 0xF000) >> 12;
1471 bgr = (fuse->ana_trim2 & 0xF0000) >> 16;
1472 vlsb = (fuse->ana_trim2 & 0xF00000) >> 20;
1473 writel(buf_vref | (buf_slope << 16), (ulong)reg_base + 0x28);
1474
1475 reg = (bgr << 28) | (bjt_cur << 20) | (vlsb << 12) | (1 << 7);
1476 writel(reg, (ulong)reg_base + 0x3c);
1477
1478 tca40[0] = (fuse->ana_trim3 & 0xFFF0000) >> 16;
1479 tca25[0] = (fuse->ana_trim3 & 0xF0000000) >> 28;
1480 tca25[0] |= ((fuse->ana_trim4 & 0xFF) << 4);
1481 tca105[0] = (fuse->ana_trim4 & 0xFFF00) >> 8;
1482 tca40[1] = (fuse->ana_trim4 & 0xFFF00000) >> 20;
1483 tca25[1] = fuse2->ana_trim5 & 0xFFF;
1484 tca105[1] = (fuse2->ana_trim5 & 0xFFF000) >> 12;
1485
1486 /* use 25c for 1p calibration */
1487 writel(tca25[0] | (tca105[0] << 16), (ulong)reg_base + 0x30);
1488 writel(tca25[1] | (tca105[1] << 16), (ulong)reg_base + 0x34);
1489 writel(tca40[0] | (tca40[1] << 16), (ulong)reg_base + 0x38);
1490#endif
Ye Li325cd012020-05-03 22:19:52 +08001491}
Peng Fana35215d2020-07-09 13:39:26 +08001492
1493#if defined(CONFIG_SPL_BUILD)
1494#if defined(CONFIG_IMX8MQ) || defined(CONFIG_IMX8MM) || defined(CONFIG_IMX8MN)
1495bool serror_need_skip = true;
1496
Sean Anderson2d755492022-03-22 17:17:35 -04001497void do_error(struct pt_regs *pt_regs)
Peng Fana35215d2020-07-09 13:39:26 +08001498{
1499 /*
1500 * If stack is still in ROM reserved OCRAM not switch to SPL,
1501 * it is the ROM SError
1502 */
1503 ulong sp;
1504
1505 asm volatile("mov %0, sp" : "=r"(sp) : );
1506
1507 if (serror_need_skip && sp < 0x910000 && sp >= 0x900000) {
1508 /* Check for ERR050342, imx8mq HDCP enabled parts */
1509 if (is_imx8mq() && !(readl(OCOTP_BASE_ADDR + 0x450) & 0x08000000)) {
1510 serror_need_skip = false;
1511 return; /* Do nothing skip the SError in ROM */
1512 }
1513
1514 /* Check for ERR050350, field return mode for imx8mq, mm and mn */
1515 if (readl(OCOTP_BASE_ADDR + 0x630) & 0x1) {
1516 serror_need_skip = false;
1517 return; /* Do nothing skip the SError in ROM */
1518 }
1519 }
1520
1521 efi_restore_gd();
Sean Anderson2d755492022-03-22 17:17:35 -04001522 printf("\"Error\" handler, esr 0x%08lx\n", pt_regs->esr);
Peng Fana35215d2020-07-09 13:39:26 +08001523 show_regs(pt_regs);
1524 panic("Resetting CPU ...\n");
1525}
1526#endif
1527#endif
Ye Li0513f362019-07-15 01:16:46 -07001528
1529#if defined(CONFIG_IMX8MN) || defined(CONFIG_IMX8MP)
Marek Vasut765b5802022-04-06 02:21:34 +02001530enum env_location arch_env_get_location(enum env_operation op, int prio)
Ye Li0513f362019-07-15 01:16:46 -07001531{
1532 enum boot_device dev = get_boot_device();
Ye Li0513f362019-07-15 01:16:46 -07001533
1534 if (prio)
Ricardo Salveti1daf63f2021-10-20 16:16:26 -03001535 return ENVL_UNKNOWN;
Ye Li0513f362019-07-15 01:16:46 -07001536
1537 switch (dev) {
Fabio Estevam9be6daf2022-04-21 15:05:23 -03001538 case USB_BOOT:
1539 if (IS_ENABLED(CONFIG_ENV_IS_IN_SPI_FLASH))
1540 return ENVL_SPI_FLASH;
1541 if (IS_ENABLED(CONFIG_ENV_IS_IN_NAND))
1542 return ENVL_NAND;
1543 if (IS_ENABLED(CONFIG_ENV_IS_IN_MMC))
1544 return ENVL_MMC;
1545 if (IS_ENABLED(CONFIG_ENV_IS_NOWHERE))
1546 return ENVL_NOWHERE;
1547 return ENVL_UNKNOWN;
Ye Li0513f362019-07-15 01:16:46 -07001548 case QSPI_BOOT:
Marek Vasut31b3bc42022-03-25 18:59:28 +01001549 case SPI_NOR_BOOT:
Ricardo Salveti1daf63f2021-10-20 16:16:26 -03001550 if (IS_ENABLED(CONFIG_ENV_IS_IN_SPI_FLASH))
1551 return ENVL_SPI_FLASH;
1552 return ENVL_NOWHERE;
Ye Li0513f362019-07-15 01:16:46 -07001553 case NAND_BOOT:
Ricardo Salveti1daf63f2021-10-20 16:16:26 -03001554 if (IS_ENABLED(CONFIG_ENV_IS_IN_NAND))
1555 return ENVL_NAND;
1556 return ENVL_NOWHERE;
Ye Li0513f362019-07-15 01:16:46 -07001557 case SD1_BOOT:
1558 case SD2_BOOT:
1559 case SD3_BOOT:
1560 case MMC1_BOOT:
1561 case MMC2_BOOT:
1562 case MMC3_BOOT:
Ricardo Salveti1daf63f2021-10-20 16:16:26 -03001563 if (IS_ENABLED(CONFIG_ENV_IS_IN_MMC))
1564 return ENVL_MMC;
1565 else if (IS_ENABLED(CONFIG_ENV_IS_IN_EXT4))
1566 return ENVL_EXT4;
1567 else if (IS_ENABLED(CONFIG_ENV_IS_IN_FAT))
1568 return ENVL_FAT;
1569 return ENVL_NOWHERE;
Ye Li0513f362019-07-15 01:16:46 -07001570 default:
Ricardo Salveti1daf63f2021-10-20 16:16:26 -03001571 return ENVL_NOWHERE;
Ye Li0513f362019-07-15 01:16:46 -07001572 }
Ye Li0513f362019-07-15 01:16:46 -07001573}
1574
Ye Li0513f362019-07-15 01:16:46 -07001575#endif
Peng Fanf19e0e52022-04-29 16:03:14 +08001576
1577#ifdef CONFIG_IMX_BOOTAUX
1578const struct rproc_att hostmap[] = {
1579 /* aux core , host core, size */
1580 { 0x00000000, 0x007e0000, 0x00020000 },
1581 /* OCRAM_S */
1582 { 0x00180000, 0x00180000, 0x00008000 },
1583 /* OCRAM */
1584 { 0x00900000, 0x00900000, 0x00020000 },
1585 /* OCRAM */
1586 { 0x00920000, 0x00920000, 0x00020000 },
1587 /* QSPI Code - alias */
1588 { 0x08000000, 0x08000000, 0x08000000 },
1589 /* DDR (Code) - alias */
1590 { 0x10000000, 0x80000000, 0x0FFE0000 },
1591 /* TCML */
1592 { 0x1FFE0000, 0x007E0000, 0x00040000 },
1593 /* OCRAM_S */
1594 { 0x20180000, 0x00180000, 0x00008000 },
1595 /* OCRAM */
1596 { 0x20200000, 0x00900000, 0x00040000 },
1597 /* DDR (Data) */
1598 { 0x40000000, 0x40000000, 0x80000000 },
1599 { /* sentinel */ }
1600};
1601#endif