blob: 8171631db10a420b34183b351d57a1c6b3b23c72 [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 Fandbe5d682022-04-10 12:18:27 +080075 if (is_imx8mq() || is_imx8mm() || is_imx8mn() || is_imx8mp())
Andrey Zhizhikin7c2d23a2022-01-24 21:48:09 +010076 setbits_le32(&gpr->gpr[10], GPR_TZASC_ID_SWAP_BYPASS);
77
78 /*
79 * imx8mn and imx8mp implements the lock bit for
80 * TZASC_ID_SWAP_BYPASS, enable it to lock settings
81 */
82 if (is_imx8mn() || is_imx8mp())
83 setbits_le32(&gpr->gpr[10], GPR_TZASC_ID_SWAP_BYPASS_LOCK);
84
Ye Li4c97c462019-08-27 06:25:34 +000085 /*
86 * set Region 0 attribute to allow secure and non-secure
87 * read/write permission. Found some masters like usb dwc3
88 * controllers can't work with secure memory.
89 */
90 writel(0xf0000000, TZASC_BASE_ADDR + 0x108);
Peng Faneae4de22018-01-10 13:20:37 +080091}
92
93void set_wdog_reset(struct wdog_regs *wdog)
94{
95 /*
96 * Output WDOG_B signal to reset external pmic or POR_B decided by
97 * the board design. Without external reset, the peripherals/DDR/
98 * PMIC are not reset, that may cause system working abnormal.
99 * WDZST bit is write-once only bit. Align this bit in kernel,
100 * otherwise kernel code will have no chance to set this bit.
101 */
102 setbits_le16(&wdog->wcr, WDOG_WDT_MASK | WDOG_WDZST_MASK);
103}
104
105static struct mm_region imx8m_mem_map[] = {
106 {
107 /* ROM */
108 .virt = 0x0UL,
109 .phys = 0x0UL,
110 .size = 0x100000UL,
111 .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
112 PTE_BLOCK_OUTER_SHARE
113 }, {
Gary Bisson5c72a452018-11-14 17:55:28 +0100114 /* CAAM */
115 .virt = 0x100000UL,
116 .phys = 0x100000UL,
117 .size = 0x8000UL,
118 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
119 PTE_BLOCK_NON_SHARE |
120 PTE_BLOCK_PXN | PTE_BLOCK_UXN
121 }, {
Marek Vasutb1738e02021-02-25 21:52:26 +0100122 /* OCRAM_S */
123 .virt = 0x180000UL,
124 .phys = 0x180000UL,
125 .size = 0x8000UL,
126 .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
127 PTE_BLOCK_OUTER_SHARE
128 }, {
Gary Bisson5c72a452018-11-14 17:55:28 +0100129 /* TCM */
130 .virt = 0x7C0000UL,
131 .phys = 0x7C0000UL,
132 .size = 0x80000UL,
133 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
134 PTE_BLOCK_NON_SHARE |
135 PTE_BLOCK_PXN | PTE_BLOCK_UXN
136 }, {
Peng Faneae4de22018-01-10 13:20:37 +0800137 /* OCRAM */
138 .virt = 0x900000UL,
139 .phys = 0x900000UL,
140 .size = 0x200000UL,
141 .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
142 PTE_BLOCK_OUTER_SHARE
143 }, {
144 /* AIPS */
145 .virt = 0xB00000UL,
146 .phys = 0xB00000UL,
147 .size = 0x3f500000UL,
148 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
149 PTE_BLOCK_NON_SHARE |
150 PTE_BLOCK_PXN | PTE_BLOCK_UXN
151 }, {
152 /* DRAM1 */
153 .virt = 0x40000000UL,
154 .phys = 0x40000000UL,
Peng Fanb749b5e2019-08-27 06:25:27 +0000155 .size = PHYS_SDRAM_SIZE,
Peng Faneae4de22018-01-10 13:20:37 +0800156 .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
157 PTE_BLOCK_OUTER_SHARE
Peng Fanb749b5e2019-08-27 06:25:27 +0000158#ifdef PHYS_SDRAM_2_SIZE
Peng Faneae4de22018-01-10 13:20:37 +0800159 }, {
160 /* DRAM2 */
161 .virt = 0x100000000UL,
162 .phys = 0x100000000UL,
Peng Fanb749b5e2019-08-27 06:25:27 +0000163 .size = PHYS_SDRAM_2_SIZE,
Peng Faneae4de22018-01-10 13:20:37 +0800164 .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
165 PTE_BLOCK_OUTER_SHARE
Peng Fanb749b5e2019-08-27 06:25:27 +0000166#endif
Peng Faneae4de22018-01-10 13:20:37 +0800167 }, {
Peng Fanfa35c3d2020-07-09 15:26:06 +0800168 /* empty entrie to split table entry 5 if needed when TEEs are used */
169 0,
170 }, {
Peng Faneae4de22018-01-10 13:20:37 +0800171 /* List terminator */
172 0,
173 }
174};
175
176struct mm_region *mem_map = imx8m_mem_map;
177
Marek Vasute48aac02021-02-27 14:59:00 +0100178static unsigned int imx8m_find_dram_entry_in_mem_map(void)
179{
180 int i;
181
182 for (i = 0; i < ARRAY_SIZE(imx8m_mem_map); i++)
183 if (imx8m_mem_map[i].phys == CONFIG_SYS_SDRAM_BASE)
184 return i;
185
186 hang(); /* Entry not found, this must never happen. */
187}
188
Peng Fanb749b5e2019-08-27 06:25:27 +0000189void enable_caches(void)
190{
Ye Li453bfcb2022-04-07 15:55:56 +0800191 /* If OPTEE runs, remove OPTEE memory from MMU table to avoid speculative prefetch
192 * If OPTEE does not run, still update the MMU table according to dram banks structure
193 * to set correct dram size from board_phys_sdram_size
194 */
195 int i = 0;
196 /*
197 * please make sure that entry initial value matches
198 * imx8m_mem_map for DRAM1
199 */
200 int entry = imx8m_find_dram_entry_in_mem_map();
201 u64 attrs = imx8m_mem_map[entry].attrs;
Peng Fanfa35c3d2020-07-09 15:26:06 +0800202
Ye Li453bfcb2022-04-07 15:55:56 +0800203 while (i < CONFIG_NR_DRAM_BANKS &&
204 entry < ARRAY_SIZE(imx8m_mem_map)) {
205 if (gd->bd->bi_dram[i].start == 0)
206 break;
207 imx8m_mem_map[entry].phys = gd->bd->bi_dram[i].start;
208 imx8m_mem_map[entry].virt = gd->bd->bi_dram[i].start;
209 imx8m_mem_map[entry].size = gd->bd->bi_dram[i].size;
210 imx8m_mem_map[entry].attrs = attrs;
211 debug("Added memory mapping (%d): %llx %llx\n", entry,
212 imx8m_mem_map[entry].phys, imx8m_mem_map[entry].size);
213 i++; entry++;
Peng Fanfa35c3d2020-07-09 15:26:06 +0800214 }
Peng Fanb749b5e2019-08-27 06:25:27 +0000215
216 icache_enable();
217 dcache_enable();
218}
219
Peng Fanfa35c3d2020-07-09 15:26:06 +0800220__weak int board_phys_sdram_size(phys_size_t *size)
221{
222 if (!size)
223 return -EINVAL;
224
225 *size = PHYS_SDRAM_SIZE;
Ye Li453bfcb2022-04-07 15:55:56 +0800226
227#ifdef PHYS_SDRAM_2_SIZE
228 *size += PHYS_SDRAM_2_SIZE;
229#endif
Peng Fanfa35c3d2020-07-09 15:26:06 +0800230 return 0;
231}
232
233int dram_init(void)
234{
235 phys_size_t sdram_size;
236 int ret;
237
238 ret = board_phys_sdram_size(&sdram_size);
239 if (ret)
240 return ret;
241
242 /* rom_pointer[1] contains the size of TEE occupies */
243 if (rom_pointer[1])
244 gd->ram_size = sdram_size - rom_pointer[1];
245 else
246 gd->ram_size = sdram_size;
247
Peng Fanfa35c3d2020-07-09 15:26:06 +0800248 return 0;
249}
250
251int dram_init_banksize(void)
252{
253 int bank = 0;
254 int ret;
255 phys_size_t sdram_size;
Ye Li453bfcb2022-04-07 15:55:56 +0800256 phys_size_t sdram_b1_size, sdram_b2_size;
Peng Fanfa35c3d2020-07-09 15:26:06 +0800257
258 ret = board_phys_sdram_size(&sdram_size);
259 if (ret)
260 return ret;
261
Ye Li453bfcb2022-04-07 15:55:56 +0800262 /* Bank 1 can't cross over 4GB space */
263 if (sdram_size > 0xc0000000) {
264 sdram_b1_size = 0xc0000000;
265 sdram_b2_size = sdram_size - 0xc0000000;
266 } else {
267 sdram_b1_size = sdram_size;
268 sdram_b2_size = 0;
269 }
270
Peng Fanfa35c3d2020-07-09 15:26:06 +0800271 gd->bd->bi_dram[bank].start = PHYS_SDRAM;
272 if (rom_pointer[1]) {
273 phys_addr_t optee_start = (phys_addr_t)rom_pointer[0];
274 phys_size_t optee_size = (size_t)rom_pointer[1];
275
276 gd->bd->bi_dram[bank].size = optee_start - gd->bd->bi_dram[bank].start;
Ye Li453bfcb2022-04-07 15:55:56 +0800277 if ((optee_start + optee_size) < (PHYS_SDRAM + sdram_b1_size)) {
Peng Fanfa35c3d2020-07-09 15:26:06 +0800278 if (++bank >= CONFIG_NR_DRAM_BANKS) {
279 puts("CONFIG_NR_DRAM_BANKS is not enough\n");
280 return -1;
281 }
282
283 gd->bd->bi_dram[bank].start = optee_start + optee_size;
284 gd->bd->bi_dram[bank].size = PHYS_SDRAM +
Ye Li453bfcb2022-04-07 15:55:56 +0800285 sdram_b1_size - gd->bd->bi_dram[bank].start;
Peng Fanfa35c3d2020-07-09 15:26:06 +0800286 }
287 } else {
Ye Li453bfcb2022-04-07 15:55:56 +0800288 gd->bd->bi_dram[bank].size = sdram_b1_size;
Peng Fanfa35c3d2020-07-09 15:26:06 +0800289 }
290
Ye Li453bfcb2022-04-07 15:55:56 +0800291 if (sdram_b2_size) {
292 if (++bank >= CONFIG_NR_DRAM_BANKS) {
293 puts("CONFIG_NR_DRAM_BANKS is not enough for SDRAM_2\n");
294 return -1;
295 }
296 gd->bd->bi_dram[bank].start = 0x100000000UL;
297 gd->bd->bi_dram[bank].size = sdram_b2_size;
Peng Fanfa35c3d2020-07-09 15:26:06 +0800298 }
Peng Fanfa35c3d2020-07-09 15:26:06 +0800299
300 return 0;
301}
302
303phys_size_t get_effective_memsize(void)
304{
Ye Li453bfcb2022-04-07 15:55:56 +0800305 int ret;
306 phys_size_t sdram_size;
307 phys_size_t sdram_b1_size;
308 ret = board_phys_sdram_size(&sdram_size);
309 if (!ret) {
310 /* Bank 1 can't cross over 4GB space */
311 if (sdram_size > 0xc0000000) {
312 sdram_b1_size = 0xc0000000;
313 } else {
314 sdram_b1_size = sdram_size;
315 }
Peng Fanfa35c3d2020-07-09 15:26:06 +0800316
Ye Li453bfcb2022-04-07 15:55:56 +0800317 if (rom_pointer[1]) {
318 /* We will relocate u-boot to Top of dram1. Tee position has two cases:
319 * 1. At the top of dram1, Then return the size removed optee size.
320 * 2. In the middle of dram1, return the size of dram1.
321 */
322 if ((rom_pointer[0] + rom_pointer[1]) == (PHYS_SDRAM + sdram_b1_size))
323 return ((phys_addr_t)rom_pointer[0] - PHYS_SDRAM);
324 }
325
326 return sdram_b1_size;
327 } else {
328 return PHYS_SDRAM_SIZE;
329 }
Peng Fanfa35c3d2020-07-09 15:26:06 +0800330}
331
Frieder Schrempf159879e2021-06-07 14:36:44 +0200332ulong board_get_usable_ram_top(ulong total_size)
333{
Ying-Chun Liu (PaulLiu)ed55caf2021-08-23 10:43:06 +0800334 ulong top_addr = PHYS_SDRAM + gd->ram_size;
335
Frieder Schrempf159879e2021-06-07 14:36:44 +0200336 /*
337 * Some IPs have their accessible address space restricted by
338 * the interconnect. Let's make sure U-Boot only ever uses the
339 * space below the 4G address boundary (which is 3GiB big),
340 * even when the effective available memory is bigger.
341 */
Ying-Chun Liu (PaulLiu)ed55caf2021-08-23 10:43:06 +0800342 if (top_addr > 0x80000000)
343 top_addr = 0x80000000;
344
345 /*
346 * rom_pointer[0] stores the TEE memory start address.
347 * rom_pointer[1] stores the size TEE uses.
348 * We need to reserve the memory region for TEE.
349 */
350 if (rom_pointer[0] && rom_pointer[1] && top_addr > rom_pointer[0])
351 top_addr = rom_pointer[0];
Frieder Schrempf159879e2021-06-07 14:36:44 +0200352
Ying-Chun Liu (PaulLiu)ed55caf2021-08-23 10:43:06 +0800353 return top_addr;
Frieder Schrempf159879e2021-06-07 14:36:44 +0200354}
355
Peng Fan1caffdf2019-08-27 06:25:17 +0000356static u32 get_cpu_variant_type(u32 type)
357{
358 struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
359 struct fuse_bank *bank = &ocotp->bank[1];
360 struct fuse_bank1_regs *fuse =
361 (struct fuse_bank1_regs *)bank->fuse_regs;
362
363 u32 value = readl(&fuse->tester4);
364
Peng Fan67815082020-02-05 17:34:54 +0800365 if (type == MXC_CPU_IMX8MQ) {
366 if ((value & 0x3) == 0x2)
367 return MXC_CPU_IMX8MD;
368 else if (value & 0x200000)
369 return MXC_CPU_IMX8MQL;
370
371 } else if (type == MXC_CPU_IMX8MM) {
Peng Fan1caffdf2019-08-27 06:25:17 +0000372 switch (value & 0x3) {
373 case 2:
374 if (value & 0x1c0000)
375 return MXC_CPU_IMX8MMDL;
376 else
377 return MXC_CPU_IMX8MMD;
378 case 3:
379 if (value & 0x1c0000)
380 return MXC_CPU_IMX8MMSL;
381 else
382 return MXC_CPU_IMX8MMS;
383 default:
384 if (value & 0x1c0000)
385 return MXC_CPU_IMX8MML;
386 break;
387 }
Peng Fan1a07d912020-02-05 17:39:27 +0800388 } else if (type == MXC_CPU_IMX8MN) {
389 switch (value & 0x3) {
390 case 2:
Ye Li715180e2021-03-19 15:57:11 +0800391 if (value & 0x1000000) {
392 if (value & 0x10000000) /* MIPI DSI */
393 return MXC_CPU_IMX8MNUD;
394 else
395 return MXC_CPU_IMX8MNDL;
396 } else {
Peng Fan1a07d912020-02-05 17:39:27 +0800397 return MXC_CPU_IMX8MND;
Ye Li715180e2021-03-19 15:57:11 +0800398 }
Peng Fan1a07d912020-02-05 17:39:27 +0800399 case 3:
Ye Li715180e2021-03-19 15:57:11 +0800400 if (value & 0x1000000) {
401 if (value & 0x10000000) /* MIPI DSI */
402 return MXC_CPU_IMX8MNUS;
403 else
404 return MXC_CPU_IMX8MNSL;
405 } else {
Peng Fan1a07d912020-02-05 17:39:27 +0800406 return MXC_CPU_IMX8MNS;
Ye Li715180e2021-03-19 15:57:11 +0800407 }
Peng Fan1a07d912020-02-05 17:39:27 +0800408 default:
Ye Li715180e2021-03-19 15:57:11 +0800409 if (value & 0x1000000) {
410 if (value & 0x10000000) /* MIPI DSI */
411 return MXC_CPU_IMX8MNUQ;
412 else
413 return MXC_CPU_IMX8MNL;
414 }
Peng Fan1a07d912020-02-05 17:39:27 +0800415 break;
416 }
Ye Lid2d754f2020-04-20 20:12:54 -0700417 } else if (type == MXC_CPU_IMX8MP) {
418 u32 value0 = readl(&fuse->tester3);
419 u32 flag = 0;
420
421 if ((value0 & 0xc0000) == 0x80000)
422 return MXC_CPU_IMX8MPD;
423
424 /* vpu disabled */
425 if ((value0 & 0x43000000) == 0x43000000)
426 flag = 1;
427
428 /* npu disabled*/
429 if ((value & 0x8) == 0x8)
Peng Fan0386e7f2022-04-07 15:55:52 +0800430 flag |= BIT(1);
Ye Lid2d754f2020-04-20 20:12:54 -0700431
432 /* isp disabled */
433 if ((value & 0x3) == 0x3)
Peng Fan0386e7f2022-04-07 15:55:52 +0800434 flag |= BIT(2);
435
436 /* gpu disabled */
437 if ((value & 0xc0) == 0xc0)
438 flag |= BIT(3);
439
440 /* lvds disabled */
441 if ((value & 0x180000) == 0x180000)
442 flag |= BIT(4);
443
444 /* mipi dsi disabled */
445 if ((value & 0x60000) == 0x60000)
446 flag |= BIT(5);
Ye Lid2d754f2020-04-20 20:12:54 -0700447
448 switch (flag) {
Peng Fan0386e7f2022-04-07 15:55:52 +0800449 case 0x3f:
450 return MXC_CPU_IMX8MPUL;
Ye Lid2d754f2020-04-20 20:12:54 -0700451 case 7:
452 return MXC_CPU_IMX8MPL;
Ye Lid2d754f2020-04-20 20:12:54 -0700453 case 2:
454 return MXC_CPU_IMX8MP6;
Ye Lid2d754f2020-04-20 20:12:54 -0700455 default:
456 break;
457 }
458
Peng Fan1caffdf2019-08-27 06:25:17 +0000459 }
460
461 return type;
462}
463
Peng Faneae4de22018-01-10 13:20:37 +0800464u32 get_cpu_rev(void)
465{
466 struct anamix_pll *ana_pll = (struct anamix_pll *)ANATOP_BASE_ADDR;
467 u32 reg = readl(&ana_pll->digprog);
468 u32 type = (reg >> 16) & 0xff;
Peng Fan1caffdf2019-08-27 06:25:17 +0000469 u32 major_low = (reg >> 8) & 0xff;
Peng Faneae4de22018-01-10 13:20:37 +0800470 u32 rom_version;
471
472 reg &= 0xff;
473
Peng Fan69cec072019-12-27 10:14:02 +0800474 /* iMX8MP */
475 if (major_low == 0x43) {
Ye Lid2d754f2020-04-20 20:12:54 -0700476 type = get_cpu_variant_type(MXC_CPU_IMX8MP);
Peng Fan69cec072019-12-27 10:14:02 +0800477 } else if (major_low == 0x42) {
478 /* iMX8MN */
Peng Fan1a07d912020-02-05 17:39:27 +0800479 type = get_cpu_variant_type(MXC_CPU_IMX8MN);
Peng Fan5d2f2062019-06-27 17:23:49 +0800480 } else if (major_low == 0x41) {
Peng Fan1caffdf2019-08-27 06:25:17 +0000481 type = get_cpu_variant_type(MXC_CPU_IMX8MM);
482 } else {
483 if (reg == CHIP_REV_1_0) {
484 /*
Peng Fanc23fbdd2019-10-16 10:24:17 +0000485 * For B0 chip, the DIGPROG is not updated,
486 * it is still TO1.0. we have to check ROM
487 * version or OCOTP_READ_FUSE_DATA.
488 * 0xff0055aa is magic number for B1.
Peng Fan1caffdf2019-08-27 06:25:17 +0000489 */
Peng Fanc23fbdd2019-10-16 10:24:17 +0000490 if (readl((void __iomem *)(OCOTP_BASE_ADDR + 0x40)) == 0xff0055aa) {
Ye Lic963ed12021-03-19 15:57:16 +0800491 /*
492 * B2 uses same DIGPROG and OCOTP_READ_FUSE_DATA value with B1,
493 * so have to check ROM to distinguish them
494 */
495 rom_version = readl((void __iomem *)ROM_VERSION_B0);
496 rom_version &= 0xff;
497 if (rom_version == CHIP_REV_2_2)
498 reg = CHIP_REV_2_2;
499 else
500 reg = CHIP_REV_2_1;
Peng Fanc23fbdd2019-10-16 10:24:17 +0000501 } else {
502 rom_version =
503 readl((void __iomem *)ROM_VERSION_A0);
504 if (rom_version != CHIP_REV_1_0) {
505 rom_version = readl((void __iomem *)ROM_VERSION_B0);
Patrick Wildtd4a78b92019-11-19 09:42:06 +0100506 rom_version &= 0xff;
Peng Fanc23fbdd2019-10-16 10:24:17 +0000507 if (rom_version == CHIP_REV_2_0)
508 reg = CHIP_REV_2_0;
509 }
Peng Fan1caffdf2019-08-27 06:25:17 +0000510 }
Peng Faneae4de22018-01-10 13:20:37 +0800511 }
Peng Fan67815082020-02-05 17:34:54 +0800512
513 type = get_cpu_variant_type(type);
Peng Faneae4de22018-01-10 13:20:37 +0800514 }
515
516 return (type << 12) | reg;
517}
518
519static void imx_set_wdog_powerdown(bool enable)
520{
521 struct wdog_regs *wdog1 = (struct wdog_regs *)WDOG1_BASE_ADDR;
522 struct wdog_regs *wdog2 = (struct wdog_regs *)WDOG2_BASE_ADDR;
523 struct wdog_regs *wdog3 = (struct wdog_regs *)WDOG3_BASE_ADDR;
524
525 /* Write to the PDE (Power Down Enable) bit */
526 writew(enable, &wdog1->wmcr);
527 writew(enable, &wdog2->wmcr);
528 writew(enable, &wdog3->wmcr);
529}
530
Simon Glassfc557362022-03-04 08:43:05 -0700531static int imx8m_check_clock(void *ctx, struct event *event)
Peng Fanc98e0322019-08-27 06:25:58 +0000532{
533 struct udevice *dev;
534 int ret;
535
Peng Fan3c073342019-10-16 03:01:51 +0000536 if (CONFIG_IS_ENABLED(CLK)) {
537 ret = uclass_get_device_by_name(UCLASS_CLK,
538 "clock-controller@30380000",
539 &dev);
540 if (ret < 0) {
541 printf("Failed to find clock node. Check device tree\n");
542 return ret;
543 }
Peng Fanc98e0322019-08-27 06:25:58 +0000544 }
545
546 return 0;
547}
Simon Glassfc557362022-03-04 08:43:05 -0700548EVENT_SPY(EVT_DM_POST_INIT, imx8m_check_clock);
Peng Fanc98e0322019-08-27 06:25:58 +0000549
Peng Faneae4de22018-01-10 13:20:37 +0800550int arch_cpu_init(void)
551{
Peng Fanc0b30d72019-04-17 09:41:16 +0000552 struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
Marek Vasut3ea500a2022-04-13 00:41:52 +0200553
554#if !CONFIG_IS_ENABLED(SYS_ICACHE_OFF)
555 icache_enable();
556#endif
557
Peng Faneae4de22018-01-10 13:20:37 +0800558 /*
Peng Fand0ca2892019-08-27 06:25:37 +0000559 * ROM might disable clock for SCTR,
560 * enable the clock before timer_init.
561 */
562 if (IS_ENABLED(CONFIG_SPL_BUILD))
563 clock_enable(CCGR_SCTR, 1);
564 /*
Peng Faneae4de22018-01-10 13:20:37 +0800565 * Init timer at very early state, because sscg pll setting
566 * will use it
567 */
568 timer_init();
569
570 if (IS_ENABLED(CONFIG_SPL_BUILD)) {
571 clock_init();
572 imx_set_wdog_powerdown(false);
Peng Fan9cf2aa32020-07-09 13:52:41 +0800573
574 if (is_imx8md() || is_imx8mmd() || is_imx8mmdl() || is_imx8mms() ||
575 is_imx8mmsl() || is_imx8mnd() || is_imx8mndl() || is_imx8mns() ||
Ye Li715180e2021-03-19 15:57:11 +0800576 is_imx8mnsl() || is_imx8mpd() || is_imx8mnud() || is_imx8mnus()) {
Peng Fan9cf2aa32020-07-09 13:52:41 +0800577 /* Power down cpu core 1, 2 and 3 for iMX8M Dual core or Single core */
578 struct pgc_reg *pgc_core1 = (struct pgc_reg *)(GPC_BASE_ADDR + 0x840);
579 struct pgc_reg *pgc_core2 = (struct pgc_reg *)(GPC_BASE_ADDR + 0x880);
580 struct pgc_reg *pgc_core3 = (struct pgc_reg *)(GPC_BASE_ADDR + 0x8C0);
581 struct gpc_reg *gpc = (struct gpc_reg *)GPC_BASE_ADDR;
582
583 writel(0x1, &pgc_core2->pgcr);
584 writel(0x1, &pgc_core3->pgcr);
Ye Li715180e2021-03-19 15:57:11 +0800585 if (is_imx8mms() || is_imx8mmsl() || is_imx8mns() || is_imx8mnsl() || is_imx8mnus()) {
Peng Fan9cf2aa32020-07-09 13:52:41 +0800586 writel(0x1, &pgc_core1->pgcr);
587 writel(0xE, &gpc->cpu_pgc_dn_trg);
588 } else {
589 writel(0xC, &gpc->cpu_pgc_dn_trg);
590 }
591 }
Peng Faneae4de22018-01-10 13:20:37 +0800592 }
593
Peng Fanc0b30d72019-04-17 09:41:16 +0000594 if (is_imx8mq()) {
595 clock_enable(CCGR_OCOTP, 1);
596 if (readl(&ocotp->ctrl) & 0x200)
597 writel(0x200, &ocotp->ctrl_clr);
598 }
599
Peng Faneae4de22018-01-10 13:20:37 +0800600 return 0;
601}
602
Peng Fanc9823b02019-09-16 03:09:36 +0000603#if defined(CONFIG_IMX8MN) || defined(CONFIG_IMX8MP)
604struct rom_api *g_rom_api = (struct rom_api *)0x980;
605
606enum boot_device get_boot_device(void)
607{
608 volatile gd_t *pgd = gd;
609 int ret;
610 u32 boot;
611 u16 boot_type;
612 u8 boot_instance;
613 enum boot_device boot_dev = SD1_BOOT;
614
615 ret = g_rom_api->query_boot_infor(QUERY_BT_DEV, &boot,
616 ((uintptr_t)&boot) ^ QUERY_BT_DEV);
Marek Behúna8cf1552021-05-20 13:24:10 +0200617 set_gd(pgd);
Peng Fanc9823b02019-09-16 03:09:36 +0000618
619 if (ret != ROM_API_OKAY) {
620 puts("ROMAPI: failure at query_boot_info\n");
621 return -1;
622 }
623
624 boot_type = boot >> 16;
625 boot_instance = (boot >> 8) & 0xff;
626
627 switch (boot_type) {
628 case BT_DEV_TYPE_SD:
629 boot_dev = boot_instance + SD1_BOOT;
630 break;
631 case BT_DEV_TYPE_MMC:
632 boot_dev = boot_instance + MMC1_BOOT;
633 break;
634 case BT_DEV_TYPE_NAND:
635 boot_dev = NAND_BOOT;
636 break;
637 case BT_DEV_TYPE_FLEXSPINOR:
638 boot_dev = QSPI_BOOT;
639 break;
Marek Vasut31b3bc42022-03-25 18:59:28 +0100640 case BT_DEV_TYPE_SPI_NOR:
641 boot_dev = SPI_NOR_BOOT;
642 break;
Peng Fanc9823b02019-09-16 03:09:36 +0000643 case BT_DEV_TYPE_USB:
644 boot_dev = USB_BOOT;
645 break;
646 default:
647 break;
648 }
649
650 return boot_dev;
651}
652#endif
653
Marek Vasut520ded02021-07-03 04:55:33 +0200654#if defined(CONFIG_IMX8M)
655#include <spl.h>
656int spl_mmc_emmc_boot_partition(struct mmc *mmc)
657{
658 u32 *rom_log_addr = (u32 *)0x9e0;
659 u32 *rom_log;
660 u8 event_id;
661 int i, part;
662
663 part = default_spl_mmc_emmc_boot_partition(mmc);
664
665 /* If the ROM event log pointer is not valid. */
666 if (*rom_log_addr < 0x900000 || *rom_log_addr >= 0xb00000 ||
667 *rom_log_addr & 0x3)
668 return part;
669
670 /* Parse the ROM event ID version 2 log */
671 rom_log = (u32 *)(uintptr_t)(*rom_log_addr);
672 for (i = 0; i < 128; i++) {
673 event_id = rom_log[i] >> 24;
674 switch (event_id) {
675 case 0x00: /* End of list */
676 return part;
677 /* Log entries with 1 parameter, skip 1 */
678 case 0x80: /* Start to perform the device initialization */
679 case 0x81: /* The boot device initialization completes */
680 case 0x8f: /* The boot device initialization fails */
681 case 0x90: /* Start to read data from boot device */
682 case 0x91: /* Reading data from boot device completes */
683 case 0x9f: /* Reading data from boot device fails */
684 i += 1;
685 continue;
686 /* Log entries with 2 parameters, skip 2 */
687 case 0xa0: /* Image authentication result */
688 case 0xc0: /* Jump to the boot image soon */
689 i += 2;
690 continue;
691 /* Boot from the secondary boot image */
692 case 0x51:
693 /*
694 * Swap the eMMC boot partitions in case there was a
695 * fallback event (i.e. primary image was corrupted
696 * and that corruption was recognized by the BootROM),
697 * so the SPL loads the rest of the U-Boot from the
698 * correct eMMC boot partition, since the BootROM
699 * leaves the boot partition set to the corrupted one.
700 */
701 if (part == 1)
702 part = 2;
703 else if (part == 2)
704 part = 1;
705 continue;
706 default:
707 continue;
708 }
709 }
710
711 return part;
712}
713#endif
714
Peng Faneae4de22018-01-10 13:20:37 +0800715bool is_usb_boot(void)
716{
717 return get_boot_device() == USB_BOOT;
718}
719
720#ifdef CONFIG_OF_SYSTEM_SETUP
Peng Fan435dc122020-07-09 14:06:49 +0800721bool check_fdt_new_path(void *blob)
722{
723 const char *soc_path = "/soc@0";
724 int nodeoff;
725
726 nodeoff = fdt_path_offset(blob, soc_path);
727 if (nodeoff < 0)
728 return false;
729
730 return true;
731}
732
733static int disable_fdt_nodes(void *blob, const char *const nodes_path[], int size_array)
734{
735 int i = 0;
736 int rc;
737 int nodeoff;
738 const char *status = "disabled";
739
740 for (i = 0; i < size_array; i++) {
741 nodeoff = fdt_path_offset(blob, nodes_path[i]);
742 if (nodeoff < 0)
743 continue; /* Not found, skip it */
744
745 printf("Found %s node\n", nodes_path[i]);
746
747add_status:
748 rc = fdt_setprop(blob, nodeoff, "status", status, strlen(status) + 1);
749 if (rc) {
750 if (rc == -FDT_ERR_NOSPACE) {
751 rc = fdt_increase_size(blob, 512);
752 if (!rc)
753 goto add_status;
754 }
755 printf("Unable to update property %s:%s, err=%s\n",
756 nodes_path[i], "status", fdt_strerror(rc));
757 } else {
758 printf("Modify %s:%s disabled\n",
759 nodes_path[i], "status");
760 }
761 }
762
763 return 0;
764}
765
766#ifdef CONFIG_IMX8MQ
767bool check_dcss_fused(void)
768{
769 struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
770 struct fuse_bank *bank = &ocotp->bank[1];
771 struct fuse_bank1_regs *fuse =
772 (struct fuse_bank1_regs *)bank->fuse_regs;
773 u32 value = readl(&fuse->tester4);
774
775 if (value & 0x4000000)
776 return true;
777
778 return false;
779}
780
781static int disable_mipi_dsi_nodes(void *blob)
782{
783 static const char * const nodes_path[] = {
784 "/mipi_dsi@30A00000",
785 "/mipi_dsi_bridge@30A00000",
786 "/dsi_phy@30A00300",
787 "/soc@0/bus@30800000/mipi_dsi@30a00000",
Peng Fan7d4195c2021-03-19 15:57:13 +0800788 "/soc@0/bus@30800000/dphy@30a00300",
789 "/soc@0/bus@30800000/mipi-dsi@30a00000",
Peng Fan435dc122020-07-09 14:06:49 +0800790 };
791
792 return disable_fdt_nodes(blob, nodes_path, ARRAY_SIZE(nodes_path));
793}
794
795static int disable_dcss_nodes(void *blob)
796{
797 static const char * const nodes_path[] = {
798 "/dcss@0x32e00000",
799 "/dcss@32e00000",
800 "/hdmi@32c00000",
801 "/hdmi_cec@32c33800",
802 "/hdmi_drm@32c00000",
803 "/display-subsystem",
804 "/sound-hdmi",
805 "/sound-hdmi-arc",
806 "/soc@0/bus@32c00000/display-controller@32e00000",
807 "/soc@0/bus@32c00000/hdmi@32c00000",
808 };
809
810 return disable_fdt_nodes(blob, nodes_path, ARRAY_SIZE(nodes_path));
811}
812
813static int check_mipi_dsi_nodes(void *blob)
814{
815 static const char * const lcdif_path[] = {
816 "/lcdif@30320000",
Peng Fan7d4195c2021-03-19 15:57:13 +0800817 "/soc@0/bus@30000000/lcdif@30320000",
818 "/soc@0/bus@30000000/lcd-controller@30320000"
Peng Fan435dc122020-07-09 14:06:49 +0800819 };
820 static const char * const mipi_dsi_path[] = {
821 "/mipi_dsi@30A00000",
822 "/soc@0/bus@30800000/mipi_dsi@30a00000"
823 };
824 static const char * const lcdif_ep_path[] = {
825 "/lcdif@30320000/port@0/mipi-dsi-endpoint",
Peng Fan7d4195c2021-03-19 15:57:13 +0800826 "/soc@0/bus@30000000/lcdif@30320000/port@0/endpoint",
827 "/soc@0/bus@30000000/lcd-controller@30320000/port@0/endpoint"
Peng Fan435dc122020-07-09 14:06:49 +0800828 };
829 static const char * const mipi_dsi_ep_path[] = {
830 "/mipi_dsi@30A00000/port@1/endpoint",
Peng Fan7d4195c2021-03-19 15:57:13 +0800831 "/soc@0/bus@30800000/mipi_dsi@30a00000/ports/port@0/endpoint",
832 "/soc@0/bus@30800000/mipi-dsi@30a00000/ports/port@0/endpoint@0"
Peng Fan435dc122020-07-09 14:06:49 +0800833 };
834
835 int lookup_node;
836 int nodeoff;
837 bool new_path = check_fdt_new_path(blob);
838 int i = new_path ? 1 : 0;
839
840 nodeoff = fdt_path_offset(blob, lcdif_path[i]);
841 if (nodeoff < 0 || !fdtdec_get_is_enabled(blob, nodeoff)) {
842 /*
843 * If can't find lcdif node or lcdif node is disabled,
844 * then disable all mipi dsi, since they only can input
845 * from DCSS
846 */
847 return disable_mipi_dsi_nodes(blob);
848 }
849
850 nodeoff = fdt_path_offset(blob, mipi_dsi_path[i]);
851 if (nodeoff < 0 || !fdtdec_get_is_enabled(blob, nodeoff))
852 return 0;
853
854 nodeoff = fdt_path_offset(blob, lcdif_ep_path[i]);
855 if (nodeoff < 0) {
856 /*
857 * If can't find lcdif endpoint, then disable all mipi dsi,
858 * since they only can input from DCSS
859 */
860 return disable_mipi_dsi_nodes(blob);
861 }
862
863 lookup_node = fdtdec_lookup_phandle(blob, nodeoff, "remote-endpoint");
864 nodeoff = fdt_path_offset(blob, mipi_dsi_ep_path[i]);
865
866 if (nodeoff > 0 && nodeoff == lookup_node)
867 return 0;
868
869 return disable_mipi_dsi_nodes(blob);
870}
871#endif
872
873int disable_vpu_nodes(void *blob)
874{
875 static const char * const nodes_path_8mq[] = {
876 "/vpu@38300000",
877 "/soc@0/vpu@38300000"
878 };
879
880 static const char * const nodes_path_8mm[] = {
881 "/vpu_g1@38300000",
882 "/vpu_g2@38310000",
883 "/vpu_h1@38320000"
884 };
885
886 static const char * const nodes_path_8mp[] = {
887 "/vpu_g1@38300000",
888 "/vpu_g2@38310000",
889 "/vpu_vc8000e@38320000"
890 };
891
892 if (is_imx8mq())
893 return disable_fdt_nodes(blob, nodes_path_8mq, ARRAY_SIZE(nodes_path_8mq));
894 else if (is_imx8mm())
895 return disable_fdt_nodes(blob, nodes_path_8mm, ARRAY_SIZE(nodes_path_8mm));
896 else if (is_imx8mp())
897 return disable_fdt_nodes(blob, nodes_path_8mp, ARRAY_SIZE(nodes_path_8mp));
898 else
899 return -EPERM;
900}
901
Ye Liee337ce2021-03-19 15:57:09 +0800902#ifdef CONFIG_IMX8MN_LOW_DRIVE_MODE
903static int low_drive_gpu_freq(void *blob)
904{
905 static const char *nodes_path_8mn[] = {
906 "/gpu@38000000",
907 "/soc@0/gpu@38000000"
908 };
909
910 int nodeoff, cnt, i;
911 u32 assignedclks[7];
912
913 nodeoff = fdt_path_offset(blob, nodes_path_8mn[0]);
914 if (nodeoff < 0)
915 return nodeoff;
916
917 cnt = fdtdec_get_int_array_count(blob, nodeoff, "assigned-clock-rates", assignedclks, 7);
918 if (cnt < 0)
919 return cnt;
920
921 if (cnt != 7)
922 printf("Warning: %s, assigned-clock-rates count %d\n", nodes_path_8mn[0], cnt);
923
924 assignedclks[cnt - 1] = 200000000;
925 assignedclks[cnt - 2] = 200000000;
926
927 for (i = 0; i < cnt; i++) {
928 debug("<%u>, ", assignedclks[i]);
929 assignedclks[i] = cpu_to_fdt32(assignedclks[i]);
930 }
931 debug("\n");
932
933 return fdt_setprop(blob, nodeoff, "assigned-clock-rates", &assignedclks, sizeof(assignedclks));
934}
935#endif
936
Peng Fanf5f9b8e2022-04-07 15:55:53 +0800937static bool check_remote_endpoint(void *blob, const char *ep1, const char *ep2)
938{
939 int lookup_node;
940 int nodeoff;
941
942 nodeoff = fdt_path_offset(blob, ep1);
943 if (nodeoff) {
944 lookup_node = fdtdec_lookup_phandle(blob, nodeoff, "remote-endpoint");
945 nodeoff = fdt_path_offset(blob, ep2);
946
947 if (nodeoff > 0 && nodeoff == lookup_node)
948 return true;
949 }
950
951 return false;
952}
953
954int disable_dsi_lcdif_nodes(void *blob)
955{
956 int ret;
957
958 static const char * const dsi_path_8mp[] = {
959 "/soc@0/bus@32c00000/mipi_dsi@32e60000"
960 };
961
962 static const char * const lcdif_path_8mp[] = {
963 "/soc@0/bus@32c00000/lcd-controller@32e80000"
964 };
965
966 static const char * const lcdif_ep_path_8mp[] = {
967 "/soc@0/bus@32c00000/lcd-controller@32e80000/port@0/endpoint"
968 };
969 static const char * const dsi_ep_path_8mp[] = {
970 "/soc@0/bus@32c00000/mipi_dsi@32e60000/port@0/endpoint"
971 };
972
973 ret = disable_fdt_nodes(blob, dsi_path_8mp, ARRAY_SIZE(dsi_path_8mp));
974 if (ret)
975 return ret;
976
977 if (check_remote_endpoint(blob, dsi_ep_path_8mp[0], lcdif_ep_path_8mp[0])) {
978 /* Disable lcdif node */
979 return disable_fdt_nodes(blob, lcdif_path_8mp, ARRAY_SIZE(lcdif_path_8mp));
980 }
981
982 return 0;
983}
984
985int disable_lvds_lcdif_nodes(void *blob)
986{
987 int ret, i;
988
989 static const char * const ldb_path_8mp[] = {
990 "/soc@0/bus@32c00000/ldb@32ec005c",
991 "/soc@0/bus@32c00000/phy@32ec0128"
992 };
993
994 static const char * const lcdif_path_8mp[] = {
995 "/soc@0/bus@32c00000/lcd-controller@32e90000"
996 };
997
998 static const char * const lcdif_ep_path_8mp[] = {
999 "/soc@0/bus@32c00000/lcd-controller@32e90000/port@0/endpoint@0",
1000 "/soc@0/bus@32c00000/lcd-controller@32e90000/port@0/endpoint@1"
1001 };
1002 static const char * const ldb_ep_path_8mp[] = {
1003 "/soc@0/bus@32c00000/ldb@32ec005c/lvds-channel@0/port@0/endpoint",
1004 "/soc@0/bus@32c00000/ldb@32ec005c/lvds-channel@1/port@0/endpoint"
1005 };
1006
1007 ret = disable_fdt_nodes(blob, ldb_path_8mp, ARRAY_SIZE(ldb_path_8mp));
1008 if (ret)
1009 return ret;
1010
1011 for (i = 0; i < ARRAY_SIZE(ldb_ep_path_8mp); i++) {
1012 if (check_remote_endpoint(blob, ldb_ep_path_8mp[i], lcdif_ep_path_8mp[i])) {
1013 /* Disable lcdif node */
1014 return disable_fdt_nodes(blob, lcdif_path_8mp, ARRAY_SIZE(lcdif_path_8mp));
1015 }
1016 }
1017
1018 return 0;
1019}
1020
Peng Fan435dc122020-07-09 14:06:49 +08001021int disable_gpu_nodes(void *blob)
1022{
1023 static const char * const nodes_path_8mn[] = {
Peng Fan7d4195c2021-03-19 15:57:13 +08001024 "/gpu@38000000",
1025 "/soc@/gpu@38000000"
Peng Fan435dc122020-07-09 14:06:49 +08001026 };
1027
Peng Fanf5f9b8e2022-04-07 15:55:53 +08001028 static const char * const nodes_path_8mp[] = {
1029 "/gpu3d@38000000",
1030 "/gpu2d@38008000"
1031 };
1032
1033 if (is_imx8mp())
1034 return disable_fdt_nodes(blob, nodes_path_8mp, ARRAY_SIZE(nodes_path_8mp));
1035 else
1036 return disable_fdt_nodes(blob, nodes_path_8mn, ARRAY_SIZE(nodes_path_8mn));
Peng Fan435dc122020-07-09 14:06:49 +08001037}
1038
1039int disable_npu_nodes(void *blob)
1040{
1041 static const char * const nodes_path_8mp[] = {
1042 "/vipsi@38500000"
1043 };
1044
1045 return disable_fdt_nodes(blob, nodes_path_8mp, ARRAY_SIZE(nodes_path_8mp));
1046}
1047
1048int disable_isp_nodes(void *blob)
1049{
1050 static const char * const nodes_path_8mp[] = {
1051 "/soc@0/bus@32c00000/camera/isp@32e10000",
1052 "/soc@0/bus@32c00000/camera/isp@32e20000"
1053 };
1054
1055 return disable_fdt_nodes(blob, nodes_path_8mp, ARRAY_SIZE(nodes_path_8mp));
1056}
1057
1058int disable_dsp_nodes(void *blob)
1059{
1060 static const char * const nodes_path_8mp[] = {
1061 "/dsp@3b6e8000"
1062 };
1063
1064 return disable_fdt_nodes(blob, nodes_path_8mp, ARRAY_SIZE(nodes_path_8mp));
1065}
1066
Ye Li26517af2021-03-19 15:57:12 +08001067static void disable_thermal_cpu_nodes(void *blob, u32 disabled_cores)
1068{
1069 static const char * const thermal_path[] = {
1070 "/thermal-zones/cpu-thermal/cooling-maps/map0"
1071 };
1072
1073 int nodeoff, cnt, i, ret, j;
1074 u32 cooling_dev[12];
1075
1076 for (i = 0; i < ARRAY_SIZE(thermal_path); i++) {
1077 nodeoff = fdt_path_offset(blob, thermal_path[i]);
1078 if (nodeoff < 0)
1079 continue; /* Not found, skip it */
1080
1081 cnt = fdtdec_get_int_array_count(blob, nodeoff, "cooling-device", cooling_dev, 12);
1082 if (cnt < 0)
1083 continue;
1084
1085 if (cnt != 12)
1086 printf("Warning: %s, cooling-device count %d\n", thermal_path[i], cnt);
1087
1088 for (j = 0; j < cnt; j++)
1089 cooling_dev[j] = cpu_to_fdt32(cooling_dev[j]);
1090
1091 ret = fdt_setprop(blob, nodeoff, "cooling-device", &cooling_dev,
1092 sizeof(u32) * (12 - disabled_cores * 3));
1093 if (ret < 0) {
1094 printf("Warning: %s, cooling-device setprop failed %d\n",
1095 thermal_path[i], ret);
1096 continue;
1097 }
1098
1099 printf("Update node %s, cooling-device prop\n", thermal_path[i]);
1100 }
1101}
1102
1103static void disable_pmu_cpu_nodes(void *blob, u32 disabled_cores)
1104{
1105 static const char * const pmu_path[] = {
1106 "/pmu"
1107 };
1108
1109 int nodeoff, cnt, i, ret, j;
1110 u32 irq_affinity[4];
1111
1112 for (i = 0; i < ARRAY_SIZE(pmu_path); i++) {
1113 nodeoff = fdt_path_offset(blob, pmu_path[i]);
1114 if (nodeoff < 0)
1115 continue; /* Not found, skip it */
1116
1117 cnt = fdtdec_get_int_array_count(blob, nodeoff, "interrupt-affinity",
1118 irq_affinity, 4);
1119 if (cnt < 0)
1120 continue;
1121
1122 if (cnt != 4)
1123 printf("Warning: %s, interrupt-affinity count %d\n", pmu_path[i], cnt);
1124
1125 for (j = 0; j < cnt; j++)
1126 irq_affinity[j] = cpu_to_fdt32(irq_affinity[j]);
1127
1128 ret = fdt_setprop(blob, nodeoff, "interrupt-affinity", &irq_affinity,
1129 sizeof(u32) * (4 - disabled_cores));
1130 if (ret < 0) {
1131 printf("Warning: %s, interrupt-affinity setprop failed %d\n",
1132 pmu_path[i], ret);
1133 continue;
1134 }
1135
1136 printf("Update node %s, interrupt-affinity prop\n", pmu_path[i]);
1137 }
1138}
1139
Peng Fan435dc122020-07-09 14:06:49 +08001140static int disable_cpu_nodes(void *blob, u32 disabled_cores)
1141{
1142 static const char * const nodes_path[] = {
1143 "/cpus/cpu@1",
1144 "/cpus/cpu@2",
1145 "/cpus/cpu@3",
1146 };
1147 u32 i = 0;
1148 int rc;
1149 int nodeoff;
1150
1151 if (disabled_cores > 3)
1152 return -EINVAL;
1153
1154 i = 3 - disabled_cores;
1155
1156 for (; i < 3; i++) {
1157 nodeoff = fdt_path_offset(blob, nodes_path[i]);
1158 if (nodeoff < 0)
1159 continue; /* Not found, skip it */
1160
1161 debug("Found %s node\n", nodes_path[i]);
1162
1163 rc = fdt_del_node(blob, nodeoff);
1164 if (rc < 0) {
1165 printf("Unable to delete node %s, err=%s\n",
1166 nodes_path[i], fdt_strerror(rc));
1167 } else {
1168 printf("Delete node %s\n", nodes_path[i]);
1169 }
1170 }
1171
Ye Li26517af2021-03-19 15:57:12 +08001172 disable_thermal_cpu_nodes(blob, disabled_cores);
1173 disable_pmu_cpu_nodes(blob, disabled_cores);
1174
Peng Fan435dc122020-07-09 14:06:49 +08001175 return 0;
1176}
1177
Peng Fana08bc872022-04-07 15:55:54 +08001178static int cleanup_nodes_for_efi(void *blob)
1179{
Peng Fan1585b202022-04-07 15:55:55 +08001180 static const char * const path[][2] = {
1181 { "/soc@0/bus@32c00000/usb@32e40000", "extcon" },
1182 { "/soc@0/bus@32c00000/usb@32e50000", "extcon" },
1183 { "/soc@0/bus@30800000/ethernet@30be0000", "phy-reset-gpios" },
1184 { "/soc@0/bus@30800000/ethernet@30bf0000", "phy-reset-gpios" }
1185 };
Peng Fana08bc872022-04-07 15:55:54 +08001186 int nodeoff, i, rc;
1187
Peng Fan1585b202022-04-07 15:55:55 +08001188 for (i = 0; i < ARRAY_SIZE(path); i++) {
1189 nodeoff = fdt_path_offset(blob, path[i][0]);
Peng Fana08bc872022-04-07 15:55:54 +08001190 if (nodeoff < 0)
1191 continue; /* Not found, skip it */
Peng Fan1585b202022-04-07 15:55:55 +08001192 debug("Found %s node\n", path[i][0]);
Peng Fana08bc872022-04-07 15:55:54 +08001193
Peng Fan1585b202022-04-07 15:55:55 +08001194 rc = fdt_delprop(blob, nodeoff, path[i][1]);
Peng Fana08bc872022-04-07 15:55:54 +08001195 if (rc == -FDT_ERR_NOTFOUND)
1196 continue;
1197 if (rc) {
1198 printf("Unable to update property %s:%s, err=%s\n",
Peng Fan1585b202022-04-07 15:55:55 +08001199 path[i][0], path[i][1], fdt_strerror(rc));
Peng Fana08bc872022-04-07 15:55:54 +08001200 return rc;
1201 }
1202
Peng Fan1585b202022-04-07 15:55:55 +08001203 printf("Remove %s:%s\n", path[i][0], path[i][1]);
Peng Fana08bc872022-04-07 15:55:54 +08001204 }
1205
1206 return 0;
1207}
Peng Fana08bc872022-04-07 15:55:54 +08001208
Masahiro Yamadaf7ed78b2020-06-26 15:13:33 +09001209int ft_system_setup(void *blob, struct bd_info *bd)
Peng Faneae4de22018-01-10 13:20:37 +08001210{
Peng Fan435dc122020-07-09 14:06:49 +08001211#ifdef CONFIG_IMX8MQ
Peng Faneae4de22018-01-10 13:20:37 +08001212 int i = 0;
1213 int rc;
1214 int nodeoff;
1215
Peng Fan435dc122020-07-09 14:06:49 +08001216 if (get_boot_device() == USB_BOOT) {
1217 disable_dcss_nodes(blob);
1218
1219 bool new_path = check_fdt_new_path(blob);
1220 int v = new_path ? 1 : 0;
1221 static const char * const usb_dwc3_path[] = {
1222 "/usb@38100000/dwc3",
1223 "/soc@0/usb@38100000"
1224 };
1225
1226 nodeoff = fdt_path_offset(blob, usb_dwc3_path[v]);
1227 if (nodeoff >= 0) {
1228 const char *speed = "high-speed";
1229
1230 printf("Found %s node\n", usb_dwc3_path[v]);
1231
1232usb_modify_speed:
1233
1234 rc = fdt_setprop(blob, nodeoff, "maximum-speed", speed, strlen(speed) + 1);
1235 if (rc) {
1236 if (rc == -FDT_ERR_NOSPACE) {
1237 rc = fdt_increase_size(blob, 512);
1238 if (!rc)
1239 goto usb_modify_speed;
1240 }
1241 printf("Unable to set property %s:%s, err=%s\n",
1242 usb_dwc3_path[v], "maximum-speed", fdt_strerror(rc));
1243 } else {
1244 printf("Modify %s:%s = %s\n",
1245 usb_dwc3_path[v], "maximum-speed", speed);
1246 }
1247 } else {
1248 printf("Can't found %s node\n", usb_dwc3_path[v]);
1249 }
1250 }
1251
Peng Faneae4de22018-01-10 13:20:37 +08001252 /* Disable the CPU idle for A0 chip since the HW does not support it */
1253 if (is_soc_rev(CHIP_REV_1_0)) {
1254 static const char * const nodes_path[] = {
1255 "/cpus/cpu@0",
1256 "/cpus/cpu@1",
1257 "/cpus/cpu@2",
1258 "/cpus/cpu@3",
1259 };
1260
1261 for (i = 0; i < ARRAY_SIZE(nodes_path); i++) {
1262 nodeoff = fdt_path_offset(blob, nodes_path[i]);
1263 if (nodeoff < 0)
1264 continue; /* Not found, skip it */
1265
Marek Vasute2e7a772020-04-24 21:37:33 +02001266 debug("Found %s node\n", nodes_path[i]);
Peng Faneae4de22018-01-10 13:20:37 +08001267
1268 rc = fdt_delprop(blob, nodeoff, "cpu-idle-states");
Marek Vasute2e7a772020-04-24 21:37:33 +02001269 if (rc == -FDT_ERR_NOTFOUND)
1270 continue;
Peng Faneae4de22018-01-10 13:20:37 +08001271 if (rc) {
1272 printf("Unable to update property %s:%s, err=%s\n",
1273 nodes_path[i], "status", fdt_strerror(rc));
1274 return rc;
1275 }
1276
Marek Vasute2e7a772020-04-24 21:37:33 +02001277 debug("Remove %s:%s\n", nodes_path[i],
Peng Faneae4de22018-01-10 13:20:37 +08001278 "cpu-idle-states");
1279 }
1280 }
1281
Peng Fan435dc122020-07-09 14:06:49 +08001282 if (is_imx8mql()) {
1283 disable_vpu_nodes(blob);
1284 if (check_dcss_fused()) {
1285 printf("DCSS is fused\n");
1286 disable_dcss_nodes(blob);
1287 check_mipi_dsi_nodes(blob);
1288 }
1289 }
1290
1291 if (is_imx8md())
1292 disable_cpu_nodes(blob, 2);
1293
1294#elif defined(CONFIG_IMX8MM)
1295 if (is_imx8mml() || is_imx8mmdl() || is_imx8mmsl())
1296 disable_vpu_nodes(blob);
1297
1298 if (is_imx8mmd() || is_imx8mmdl())
1299 disable_cpu_nodes(blob, 2);
1300 else if (is_imx8mms() || is_imx8mmsl())
1301 disable_cpu_nodes(blob, 3);
1302
1303#elif defined(CONFIG_IMX8MN)
1304 if (is_imx8mnl() || is_imx8mndl() || is_imx8mnsl())
1305 disable_gpu_nodes(blob);
Ye Liee337ce2021-03-19 15:57:09 +08001306#ifdef CONFIG_IMX8MN_LOW_DRIVE_MODE
1307 else {
1308 int ldm_gpu = low_drive_gpu_freq(blob);
1309
1310 if (ldm_gpu < 0)
1311 printf("Update GPU node assigned-clock-rates failed\n");
1312 else
1313 printf("Update GPU node assigned-clock-rates ok\n");
1314 }
1315#endif
Peng Fan435dc122020-07-09 14:06:49 +08001316
Ye Li715180e2021-03-19 15:57:11 +08001317 if (is_imx8mnd() || is_imx8mndl() || is_imx8mnud())
Peng Fan435dc122020-07-09 14:06:49 +08001318 disable_cpu_nodes(blob, 2);
Ye Li715180e2021-03-19 15:57:11 +08001319 else if (is_imx8mns() || is_imx8mnsl() || is_imx8mnus())
Peng Fan435dc122020-07-09 14:06:49 +08001320 disable_cpu_nodes(blob, 3);
1321
1322#elif defined(CONFIG_IMX8MP)
Peng Fanf5f9b8e2022-04-07 15:55:53 +08001323 if (is_imx8mpul()) {
1324 /* Disable GPU */
1325 disable_gpu_nodes(blob);
1326
1327 /* Disable DSI */
1328 disable_dsi_lcdif_nodes(blob);
1329
1330 /* Disable LVDS */
1331 disable_lvds_lcdif_nodes(blob);
1332 }
1333
1334 if (is_imx8mpul() || is_imx8mpl())
Peng Fan435dc122020-07-09 14:06:49 +08001335 disable_vpu_nodes(blob);
1336
Peng Fanf5f9b8e2022-04-07 15:55:53 +08001337 if (is_imx8mpul() || is_imx8mpl() || is_imx8mp6())
Peng Fan435dc122020-07-09 14:06:49 +08001338 disable_npu_nodes(blob);
1339
Peng Fanf5f9b8e2022-04-07 15:55:53 +08001340 if (is_imx8mpul() || is_imx8mpl())
Peng Fan435dc122020-07-09 14:06:49 +08001341 disable_isp_nodes(blob);
1342
Peng Fanf5f9b8e2022-04-07 15:55:53 +08001343 if (is_imx8mpul() || is_imx8mpl() || is_imx8mp6())
Peng Fan435dc122020-07-09 14:06:49 +08001344 disable_dsp_nodes(blob);
1345
1346 if (is_imx8mpd())
1347 disable_cpu_nodes(blob, 2);
1348#endif
1349
Peng Fan1585b202022-04-07 15:55:55 +08001350 cleanup_nodes_for_efi(blob);
Peng Faneae4de22018-01-10 13:20:37 +08001351 return 0;
1352}
1353#endif
1354
Peng Fanf5f9b8e2022-04-07 15:55:53 +08001355#ifdef CONFIG_OF_BOARD_FIXUP
1356#ifndef CONFIG_SPL_BUILD
1357int board_fix_fdt(void *fdt)
1358{
1359 if (is_imx8mpul()) {
1360 int i = 0;
1361 int nodeoff, ret;
1362 const char *status = "disabled";
1363 static const char * const dsi_nodes[] = {
1364 "/soc@0/bus@32c00000/mipi_dsi@32e60000",
1365 "/soc@0/bus@32c00000/lcd-controller@32e80000",
1366 "/dsi-host"
1367 };
1368
1369 for (i = 0; i < ARRAY_SIZE(dsi_nodes); i++) {
1370 nodeoff = fdt_path_offset(fdt, dsi_nodes[i]);
1371 if (nodeoff > 0) {
1372set_status:
1373 ret = fdt_setprop(fdt, nodeoff, "status", status,
1374 strlen(status) + 1);
1375 if (ret == -FDT_ERR_NOSPACE) {
1376 ret = fdt_increase_size(fdt, 512);
1377 if (!ret)
1378 goto set_status;
1379 }
1380 }
1381 }
1382 }
1383
1384 return 0;
1385}
1386#endif
1387#endif
1388
Marek Vasut64dc4de2020-04-29 15:04:21 +02001389#if !CONFIG_IS_ENABLED(SYSRESET)
Harald Seiler6f14d5f2020-12-15 16:47:52 +01001390void reset_cpu(void)
Peng Faneae4de22018-01-10 13:20:37 +08001391{
Claudius Heinee73f3942020-04-29 15:04:23 +02001392 struct watchdog_regs *wdog = (struct watchdog_regs *)WDOG1_BASE_ADDR;
Peng Faneae4de22018-01-10 13:20:37 +08001393
Ye Li54a915a2019-12-09 00:47:18 -08001394 /* Clear WDA to trigger WDOG_B immediately */
1395 writew((SET_WCR_WT(1) | WCR_WDT | WCR_WDE | WCR_SRS), &wdog->wcr);
Peng Fan24290d92019-08-27 06:25:41 +00001396
Ye Li54a915a2019-12-09 00:47:18 -08001397 while (1) {
1398 /*
Harald Seilerec0c4472020-04-29 15:04:22 +02001399 * spin for .5 seconds before reset
Ye Li54a915a2019-12-09 00:47:18 -08001400 */
1401 }
Peng Faneae4de22018-01-10 13:20:37 +08001402}
Peng Fan24290d92019-08-27 06:25:41 +00001403#endif
Peng Fan5760d8d2020-04-22 10:51:13 +08001404
1405#if defined(CONFIG_ARCH_MISC_INIT)
Peng Fan5760d8d2020-04-22 10:51:13 +08001406int arch_misc_init(void)
1407{
Gaurav Jain81113a02022-03-24 11:50:27 +05301408 if (IS_ENABLED(CONFIG_FSL_CAAM)) {
1409 struct udevice *dev;
1410 int ret;
1411
1412 ret = uclass_get_device_by_driver(UCLASS_MISC, DM_DRIVER_GET(caam_jr), &dev);
1413 if (ret)
1414 printf("Failed to initialize %s: %d\n", dev->name, ret);
1415 }
Peng Fan5760d8d2020-04-22 10:51:13 +08001416
1417 return 0;
1418}
1419#endif
Ye Li325cd012020-05-03 22:19:52 +08001420
1421void imx_tmu_arch_init(void *reg_base)
1422{
Ye Lia00f2f02020-05-03 22:19:53 +08001423 if (is_imx8mm() || is_imx8mn()) {
Ye Li325cd012020-05-03 22:19:52 +08001424 /* Load TCALIV and TASR from fuses */
1425 struct ocotp_regs *ocotp =
1426 (struct ocotp_regs *)OCOTP_BASE_ADDR;
1427 struct fuse_bank *bank = &ocotp->bank[3];
1428 struct fuse_bank3_regs *fuse =
1429 (struct fuse_bank3_regs *)bank->fuse_regs;
1430
1431 u32 tca_rt, tca_hr, tca_en;
1432 u32 buf_vref, buf_slope;
1433
1434 tca_rt = fuse->ana0 & 0xFF;
1435 tca_hr = (fuse->ana0 & 0xFF00) >> 8;
1436 tca_en = (fuse->ana0 & 0x2000000) >> 25;
1437
1438 buf_vref = (fuse->ana0 & 0x1F00000) >> 20;
1439 buf_slope = (fuse->ana0 & 0xF0000) >> 16;
1440
1441 writel(buf_vref | (buf_slope << 16), (ulong)reg_base + 0x28);
1442 writel((tca_en << 31) | (tca_hr << 16) | tca_rt,
1443 (ulong)reg_base + 0x30);
1444 }
Ye Li41a20252020-05-03 22:19:54 +08001445#ifdef CONFIG_IMX8MP
1446 /* Load TCALIV0/1/m40 and TRIM from fuses */
1447 struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
1448 struct fuse_bank *bank = &ocotp->bank[38];
1449 struct fuse_bank38_regs *fuse =
1450 (struct fuse_bank38_regs *)bank->fuse_regs;
1451 struct fuse_bank *bank2 = &ocotp->bank[39];
1452 struct fuse_bank39_regs *fuse2 =
1453 (struct fuse_bank39_regs *)bank2->fuse_regs;
1454 u32 buf_vref, buf_slope, bjt_cur, vlsb, bgr;
1455 u32 reg;
1456 u32 tca40[2], tca25[2], tca105[2];
1457
1458 /* For blank sample */
1459 if (!fuse->ana_trim2 && !fuse->ana_trim3 &&
1460 !fuse->ana_trim4 && !fuse2->ana_trim5) {
1461 /* Use a default 25C binary codes */
1462 tca25[0] = 1596;
Ye Lid756ca02020-05-03 22:19:55 +08001463 tca25[1] = 1596;
Ye Li41a20252020-05-03 22:19:54 +08001464 writel(tca25[0], (ulong)reg_base + 0x30);
Ye Lid756ca02020-05-03 22:19:55 +08001465 writel(tca25[1], (ulong)reg_base + 0x34);
Ye Li41a20252020-05-03 22:19:54 +08001466 return;
1467 }
1468
1469 buf_vref = (fuse->ana_trim2 & 0xc0) >> 6;
1470 buf_slope = (fuse->ana_trim2 & 0xF00) >> 8;
1471 bjt_cur = (fuse->ana_trim2 & 0xF000) >> 12;
1472 bgr = (fuse->ana_trim2 & 0xF0000) >> 16;
1473 vlsb = (fuse->ana_trim2 & 0xF00000) >> 20;
1474 writel(buf_vref | (buf_slope << 16), (ulong)reg_base + 0x28);
1475
1476 reg = (bgr << 28) | (bjt_cur << 20) | (vlsb << 12) | (1 << 7);
1477 writel(reg, (ulong)reg_base + 0x3c);
1478
1479 tca40[0] = (fuse->ana_trim3 & 0xFFF0000) >> 16;
1480 tca25[0] = (fuse->ana_trim3 & 0xF0000000) >> 28;
1481 tca25[0] |= ((fuse->ana_trim4 & 0xFF) << 4);
1482 tca105[0] = (fuse->ana_trim4 & 0xFFF00) >> 8;
1483 tca40[1] = (fuse->ana_trim4 & 0xFFF00000) >> 20;
1484 tca25[1] = fuse2->ana_trim5 & 0xFFF;
1485 tca105[1] = (fuse2->ana_trim5 & 0xFFF000) >> 12;
1486
1487 /* use 25c for 1p calibration */
1488 writel(tca25[0] | (tca105[0] << 16), (ulong)reg_base + 0x30);
1489 writel(tca25[1] | (tca105[1] << 16), (ulong)reg_base + 0x34);
1490 writel(tca40[0] | (tca40[1] << 16), (ulong)reg_base + 0x38);
1491#endif
Ye Li325cd012020-05-03 22:19:52 +08001492}
Peng Fana35215d2020-07-09 13:39:26 +08001493
1494#if defined(CONFIG_SPL_BUILD)
1495#if defined(CONFIG_IMX8MQ) || defined(CONFIG_IMX8MM) || defined(CONFIG_IMX8MN)
1496bool serror_need_skip = true;
1497
Sean Anderson2d755492022-03-22 17:17:35 -04001498void do_error(struct pt_regs *pt_regs)
Peng Fana35215d2020-07-09 13:39:26 +08001499{
1500 /*
1501 * If stack is still in ROM reserved OCRAM not switch to SPL,
1502 * it is the ROM SError
1503 */
1504 ulong sp;
1505
1506 asm volatile("mov %0, sp" : "=r"(sp) : );
1507
1508 if (serror_need_skip && sp < 0x910000 && sp >= 0x900000) {
1509 /* Check for ERR050342, imx8mq HDCP enabled parts */
1510 if (is_imx8mq() && !(readl(OCOTP_BASE_ADDR + 0x450) & 0x08000000)) {
1511 serror_need_skip = false;
1512 return; /* Do nothing skip the SError in ROM */
1513 }
1514
1515 /* Check for ERR050350, field return mode for imx8mq, mm and mn */
1516 if (readl(OCOTP_BASE_ADDR + 0x630) & 0x1) {
1517 serror_need_skip = false;
1518 return; /* Do nothing skip the SError in ROM */
1519 }
1520 }
1521
1522 efi_restore_gd();
Sean Anderson2d755492022-03-22 17:17:35 -04001523 printf("\"Error\" handler, esr 0x%08lx\n", pt_regs->esr);
Peng Fana35215d2020-07-09 13:39:26 +08001524 show_regs(pt_regs);
1525 panic("Resetting CPU ...\n");
1526}
1527#endif
1528#endif
Ye Li0513f362019-07-15 01:16:46 -07001529
1530#if defined(CONFIG_IMX8MN) || defined(CONFIG_IMX8MP)
1531enum env_location env_get_location(enum env_operation op, int prio)
1532{
1533 enum boot_device dev = get_boot_device();
Ye Li0513f362019-07-15 01:16:46 -07001534
1535 if (prio)
Ricardo Salveti1daf63f2021-10-20 16:16:26 -03001536 return ENVL_UNKNOWN;
Ye Li0513f362019-07-15 01:16:46 -07001537
1538 switch (dev) {
Ye Li0513f362019-07-15 01:16:46 -07001539 case QSPI_BOOT:
Marek Vasut31b3bc42022-03-25 18:59:28 +01001540 case SPI_NOR_BOOT:
Ricardo Salveti1daf63f2021-10-20 16:16:26 -03001541 if (IS_ENABLED(CONFIG_ENV_IS_IN_SPI_FLASH))
1542 return ENVL_SPI_FLASH;
1543 return ENVL_NOWHERE;
Ye Li0513f362019-07-15 01:16:46 -07001544 case NAND_BOOT:
Ricardo Salveti1daf63f2021-10-20 16:16:26 -03001545 if (IS_ENABLED(CONFIG_ENV_IS_IN_NAND))
1546 return ENVL_NAND;
1547 return ENVL_NOWHERE;
Ye Li0513f362019-07-15 01:16:46 -07001548 case SD1_BOOT:
1549 case SD2_BOOT:
1550 case SD3_BOOT:
1551 case MMC1_BOOT:
1552 case MMC2_BOOT:
1553 case MMC3_BOOT:
Ricardo Salveti1daf63f2021-10-20 16:16:26 -03001554 if (IS_ENABLED(CONFIG_ENV_IS_IN_MMC))
1555 return ENVL_MMC;
1556 else if (IS_ENABLED(CONFIG_ENV_IS_IN_EXT4))
1557 return ENVL_EXT4;
1558 else if (IS_ENABLED(CONFIG_ENV_IS_IN_FAT))
1559 return ENVL_FAT;
1560 return ENVL_NOWHERE;
Ye Li0513f362019-07-15 01:16:46 -07001561 default:
Ricardo Salveti1daf63f2021-10-20 16:16:26 -03001562 return ENVL_NOWHERE;
Ye Li0513f362019-07-15 01:16:46 -07001563 }
Ye Li0513f362019-07-15 01:16:46 -07001564}
1565
Ye Li0513f362019-07-15 01:16:46 -07001566#endif