Blame view

arch/arm/mach-imx/imx8m/soc.c 33 KB
83d290c56   Tom Rini   SPDX: Convert all...
1
  // SPDX-License-Identifier: GPL-2.0+
fcdbde7ce   Peng Fan   imx: mx8m: add so...
2
  /*
d99e05082   Ye Li   MLK-20784-2 imx8m...
3
   * Copyright 2017-2019 NXP
fcdbde7ce   Peng Fan   imx: mx8m: add so...
4
5
   *
   * Peng Fan <peng.fan@nxp.com>
fcdbde7ce   Peng Fan   imx: mx8m: add so...
6
7
8
   */
  
  #include <common.h>
9edefc277   Simon Glass   common: Move some...
9
  #include <cpu_func.h>
fcdbde7ce   Peng Fan   imx: mx8m: add so...
10
11
12
13
14
15
  #include <asm/arch/imx-regs.h>
  #include <asm/io.h>
  #include <asm/arch/clock.h>
  #include <asm/arch/sys_proto.h>
  #include <asm/mach-imx/hab.h>
  #include <asm/mach-imx/boot_mode.h>
07be6f855   Silvano di Ninno   TEE-502 imx: refa...
16
  #include <asm/mach-imx/optee.h>
fcdbde7ce   Peng Fan   imx: mx8m: add so...
17
18
  #include <asm/mach-imx/syscounter.h>
  #include <asm/armv8/mmu.h>
e663c703b   Peng Fan   imx8m: soc: probe...
19
  #include <dm/uclass.h>
fcdbde7ce   Peng Fan   imx: mx8m: add so...
20
21
  #include <errno.h>
  #include <fdt_support.h>
e4926d415   Ye Li   MLK-19526-2 imx8m...
22
  #include <fdtdec.h>
fcdbde7ce   Peng Fan   imx: mx8m: add so...
23
24
  #include <fsl_wdog.h>
  #include <imx_sip.h>
4d4de2adc   Peng Fan   MLK-17050 imx8m: ...
25
  #include <generated/version_autogenerated.h>
9f99e9de1   Ye Li   MLK-18591-3 andro...
26
  #include <asm/setup.h>
ce78751b8   Ye Li   MLK-22749 imx8mq:...
27
  #include <asm/bootm.h>
6427f23dc   Aymen Sghaier   MLK-18703: crypto...
28
29
30
  #ifdef CONFIG_IMX_SEC_INIT
  #include <fsl_caam.h>
  #endif
c4ac5e2be   Ye Li   MLK-22279-3 imx8m...
31
32
  #include <env.h>
  #include <env_internal.h>
31400529b   Ye Li   MLK-22622 imx8m: ...
33
  #include <efi_loader.h>
fcdbde7ce   Peng Fan   imx: mx8m: add so...
34
35
  
  DECLARE_GLOBAL_DATA_PTR;
6bdc7d05c   Ji Luo   MA-15019-1 Suppor...
36
  #if defined(CONFIG_IMX_HAB) || defined(CONFIG_AVB_ATX) || defined(CONFIG_IMX_TRUSTY_OS)
fcdbde7ce   Peng Fan   imx: mx8m: add so...
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
  struct imx_sec_config_fuse_t const imx_sec_config_fuse = {
  	.bank = 1,
  	.word = 3,
  };
  #endif
  
  int timer_init(void)
  {
  #ifdef CONFIG_SPL_BUILD
  	struct sctr_regs *sctr = (struct sctr_regs *)SYSCNT_CTRL_BASE_ADDR;
  	unsigned long freq = readl(&sctr->cntfid0);
  
  	/* Update with accurate clock frequency */
  	asm volatile("msr cntfrq_el0, %0" : : "r" (freq) : "memory");
  
  	clrsetbits_le32(&sctr->cntcr, SC_CNTCR_FREQ0 | SC_CNTCR_FREQ1,
  			SC_CNTCR_FREQ0 | SC_CNTCR_ENABLE | SC_CNTCR_HDBG);
  #endif
  
  	gd->arch.tbl = 0;
  	gd->arch.tbu = 0;
  
  	return 0;
  }
  
  void enable_tzc380(void)
  {
  	struct iomuxc_gpr_base_regs *gpr =
  		(struct iomuxc_gpr_base_regs *)IOMUXC_GPR_BASE_ADDR;
  
  	/* Enable TZASC and lock setting */
  	setbits_le32(&gpr->gpr[10], GPR_TZASC_EN);
  	setbits_le32(&gpr->gpr[10], GPR_TZASC_EN_LOCK);
a07c71812   Peng Fan   imx8mp: set BYPAS...
70
  	if (is_imx8mm() || is_imx8mn() || is_imx8mp())
dbb2b7e50   Peng Fan   imx8m: set BYPASS...
71
  		setbits_le32(&gpr->gpr[10], BIT(1));
b3cf0a8f0   Ye Li   imx8m: Configure ...
72
73
74
75
76
77
  	/*
  	 * set Region 0 attribute to allow secure and non-secure
  	 * read/write permission. Found some masters like usb dwc3
  	 * controllers can't work with secure memory.
  	 */
  	writel(0xf0000000, TZASC_BASE_ADDR + 0x108);
fcdbde7ce   Peng Fan   imx: mx8m: add so...
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
  }
  
  void set_wdog_reset(struct wdog_regs *wdog)
  {
  	/*
  	 * Output WDOG_B signal to reset external pmic or POR_B decided by
  	 * the board design. Without external reset, the peripherals/DDR/
  	 * PMIC are not reset, that may cause system working abnormal.
  	 * WDZST bit is write-once only bit. Align this bit in kernel,
  	 * otherwise kernel code will have no chance to set this bit.
  	 */
  	setbits_le16(&wdog->wcr, WDOG_WDT_MASK | WDOG_WDZST_MASK);
  }
  
  static struct mm_region imx8m_mem_map[] = {
  	{
  		/* ROM */
  		.virt = 0x0UL,
  		.phys = 0x0UL,
  		.size = 0x100000UL,
  		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
  			 PTE_BLOCK_OUTER_SHARE
  	}, {
cb15885b4   Gary Bisson   imx: mx8m: add me...
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
  		/* CAAM */
  		.virt = 0x100000UL,
  		.phys = 0x100000UL,
  		.size = 0x8000UL,
  		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
  			 PTE_BLOCK_NON_SHARE |
  			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
  	}, {
  		/* TCM */
  		.virt = 0x7C0000UL,
  		.phys = 0x7C0000UL,
  		.size = 0x80000UL,
  		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
  			 PTE_BLOCK_NON_SHARE |
  			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
  	}, {
fcdbde7ce   Peng Fan   imx: mx8m: add so...
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
  		/* OCRAM */
  		.virt = 0x900000UL,
  		.phys = 0x900000UL,
  		.size = 0x200000UL,
  		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
  			 PTE_BLOCK_OUTER_SHARE
  	}, {
  		/* AIPS */
  		.virt = 0xB00000UL,
  		.phys = 0xB00000UL,
  		.size = 0x3f500000UL,
  		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
  			 PTE_BLOCK_NON_SHARE |
  			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
  	}, {
  		/* DRAM1 */
  		.virt = 0x40000000UL,
  		.phys = 0x40000000UL,
59efa6b52   Peng Fan   imx8m: Fix MMU ta...
135
  		.size = PHYS_SDRAM_SIZE,
fcdbde7ce   Peng Fan   imx: mx8m: add so...
136
  		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
d5046e6f0   Ye Li   MLK-18591-6 andro...
137
138
139
  #ifdef CONFIG_IMX_TRUSTY_OS
  			 PTE_BLOCK_INNER_SHARE
  #else
fcdbde7ce   Peng Fan   imx: mx8m: add so...
140
  			 PTE_BLOCK_OUTER_SHARE
d5046e6f0   Ye Li   MLK-18591-6 andro...
141
  #endif
59efa6b52   Peng Fan   imx8m: Fix MMU ta...
142
  #ifdef PHYS_SDRAM_2_SIZE
fcdbde7ce   Peng Fan   imx: mx8m: add so...
143
144
145
146
  	}, {
  		/* DRAM2 */
  		.virt = 0x100000000UL,
  		.phys = 0x100000000UL,
59efa6b52   Peng Fan   imx8m: Fix MMU ta...
147
  		.size = PHYS_SDRAM_2_SIZE,
fcdbde7ce   Peng Fan   imx: mx8m: add so...
148
  		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
d5046e6f0   Ye Li   MLK-18591-6 andro...
149
150
151
  #ifdef CONFIG_IMX_TRUSTY_OS
  			 PTE_BLOCK_INNER_SHARE
  #else
fcdbde7ce   Peng Fan   imx: mx8m: add so...
152
  			 PTE_BLOCK_OUTER_SHARE
59efa6b52   Peng Fan   imx8m: Fix MMU ta...
153
  #endif
d5046e6f0   Ye Li   MLK-18591-6 andro...
154
  #endif
fcdbde7ce   Peng Fan   imx: mx8m: add so...
155
  	}, {
69dc01864   Ye Li   TEE-502 imx8m: Re...
156
157
158
159
160
  		/* empty entrie to split table entry 5
  		* if needed when TEEs are used
  		*/
  		0,
  	}, {
fcdbde7ce   Peng Fan   imx: mx8m: add so...
161
162
163
164
165
166
  		/* List terminator */
  		0,
  	}
  };
  
  struct mm_region *mem_map = imx8m_mem_map;
59efa6b52   Peng Fan   imx8m: Fix MMU ta...
167
168
  void enable_caches(void)
  {
69dc01864   Ye Li   TEE-502 imx8m: Re...
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
  	/* If OPTEE runs, remove OPTEE memory from MMU table to avoid speculative prefetch */
  	if (rom_pointer[1]) {
  
  		/* TEE are loaded, So the ddr bank structures
  		* have been modified update mmu table accordingly
  		*/
  		int i = 0;
  		/* please make sure that entry initial value matches
  		* imx8m_mem_map for DRAM1
  		*/
  		int entry = 5;
  		u64 attrs = imx8m_mem_map[entry].attrs;
  		while (i < CONFIG_NR_DRAM_BANKS && entry < 8) {
  			if (gd->bd->bi_dram[i].start == 0)
  				break;
  			imx8m_mem_map[entry].phys = gd->bd->bi_dram[i].start;
  			imx8m_mem_map[entry].virt = gd->bd->bi_dram[i].start;
  			imx8m_mem_map[entry].size = gd->bd->bi_dram[i].size;
  			imx8m_mem_map[entry].attrs = attrs;
  			debug("Added memory mapping (%d): %llx %llx
  ", entry,
  				imx8m_mem_map[entry].phys, imx8m_mem_map[entry].size);
  			i++;entry++;
  		}
  	}
59efa6b52   Peng Fan   imx8m: Fix MMU ta...
194
195
196
197
  
  	icache_enable();
  	dcache_enable();
  }
69dc01864   Ye Li   TEE-502 imx8m: Re...
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
  __weak int board_phys_sdram_size(phys_size_t *size)
  {
  	if (!size)
  		return -EINVAL;
  
  	*size = PHYS_SDRAM_SIZE;
  	return 0;
  }
  
  int dram_init(void)
  {
  	phys_size_t sdram_size;
  	int ret;
  
  	ret = board_phys_sdram_size(&sdram_size);
  	if (ret)
  		return ret;
  
  	/* rom_pointer[1] contains the size of TEE occupies */
  	if (rom_pointer[1])
  		gd->ram_size = sdram_size - rom_pointer[1];
  	else
  		gd->ram_size = sdram_size;
  
  #ifdef PHYS_SDRAM_2_SIZE
  	gd->ram_size += PHYS_SDRAM_2_SIZE;
  #endif
  
  	return 0;
  }
  
  int dram_init_banksize(void)
  {
  	int bank = 0;
  	int ret;
  	phys_size_t sdram_size;
  
  	ret = board_phys_sdram_size(&sdram_size);
  	if (ret)
  		return ret;
  
  	gd->bd->bi_dram[bank].start = PHYS_SDRAM;
  	if (rom_pointer[1]) {
  		phys_addr_t optee_start = (phys_addr_t)rom_pointer[0];
  		phys_size_t optee_size = (size_t)rom_pointer[1];
  
  		gd->bd->bi_dram[bank].size = optee_start -gd->bd->bi_dram[bank].start;
  		if ((optee_start + optee_size) < (PHYS_SDRAM + sdram_size)) {
  			if ( ++bank >= CONFIG_NR_DRAM_BANKS) {
  				puts("CONFIG_NR_DRAM_BANKS is not enough
  ");
  				return -1;
  			}
  
  			gd->bd->bi_dram[bank].start = optee_start + optee_size;
  			gd->bd->bi_dram[bank].size = PHYS_SDRAM +
  				sdram_size - gd->bd->bi_dram[bank].start;
  		}
  	} else {
  		gd->bd->bi_dram[bank].size = sdram_size;
  	}
  
  #ifdef PHYS_SDRAM_2_SIZE
  	if ( ++bank >= CONFIG_NR_DRAM_BANKS) {
  		puts("CONFIG_NR_DRAM_BANKS is not enough for SDRAM_2
  ");
  		return -1;
  	}
  	gd->bd->bi_dram[bank].start = PHYS_SDRAM_2;
  	gd->bd->bi_dram[bank].size = PHYS_SDRAM_2_SIZE;
  #endif
  
  	return 0;
  }
  
  phys_size_t get_effective_memsize(void)
  {
  	/* return the first bank as effective memory */
  	if (rom_pointer[1])
  		return ((phys_addr_t)rom_pointer[0] - PHYS_SDRAM);
  
  #ifdef PHYS_SDRAM_2_SIZE
  	return gd->ram_size - PHYS_SDRAM_2_SIZE;
  #else
  	return gd->ram_size;
  #endif
  }
78db9a546   Peng Fan   imx: add get_cpu_...
285
286
287
288
289
290
291
292
  static u32 get_cpu_variant_type(u32 type)
  {
  	struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
  	struct fuse_bank *bank = &ocotp->bank[1];
  	struct fuse_bank1_regs *fuse =
  		(struct fuse_bank1_regs *)bank->fuse_regs;
  
  	u32 value = readl(&fuse->tester4);
f8787814c   Ye Li   MLK-19526-1 imx8m...
293
294
295
296
297
298
299
  	if (type == MXC_CPU_IMX8MQ) {
  		if ((value & 0x3) == 0x2)
  			return MXC_CPU_IMX8MD;
  		else if (value & 0x200000)
  			return MXC_CPU_IMX8MQL;
  
  	} else if (type == MXC_CPU_IMX8MM) {
78db9a546   Peng Fan   imx: add get_cpu_...
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
  		switch (value & 0x3) {
  		case 2:
  			if (value & 0x1c0000)
  				return MXC_CPU_IMX8MMDL;
  			else
  				return MXC_CPU_IMX8MMD;
  		case 3:
  			if (value & 0x1c0000)
  				return MXC_CPU_IMX8MMSL;
  			else
  				return MXC_CPU_IMX8MMS;
  		default:
  			if (value & 0x1c0000)
  				return MXC_CPU_IMX8MML;
  			break;
  		}
062c8597d   Ye Li   MLK-22192 imx8mn:...
316
317
318
  	} else if (type == MXC_CPU_IMX8MN) {
  		switch (value & 0x3) {
  		case 2:
dce6de018   Ye Li   MLK-25003-1 iMX8M...
319
320
321
322
323
324
  			if (value & 0x1000000) {
  				if (value & 0x10000000)	 /* MIPI DSI */
  					return MXC_CPU_IMX8MNUD;
  				else
  					return MXC_CPU_IMX8MNDL;
  			} else {
062c8597d   Ye Li   MLK-22192 imx8mn:...
325
  				return MXC_CPU_IMX8MND;
dce6de018   Ye Li   MLK-25003-1 iMX8M...
326
  			}
062c8597d   Ye Li   MLK-22192 imx8mn:...
327
  		case 3:
dce6de018   Ye Li   MLK-25003-1 iMX8M...
328
329
330
331
332
333
  			if (value & 0x1000000) {
  				if (value & 0x10000000)	 /* MIPI DSI */
  					return MXC_CPU_IMX8MNUS;
  				else
  					return MXC_CPU_IMX8MNSL;
  			} else {
062c8597d   Ye Li   MLK-22192 imx8mn:...
334
  				return MXC_CPU_IMX8MNS;
dce6de018   Ye Li   MLK-25003-1 iMX8M...
335
  			}
062c8597d   Ye Li   MLK-22192 imx8mn:...
336
  		default:
dce6de018   Ye Li   MLK-25003-1 iMX8M...
337
338
339
340
341
342
  			if (value & 0x1000000) {
  				if (value & 0x10000000)	 /* MIPI DSI */
  					return MXC_CPU_IMX8MNUQ;
  				else
  					return MXC_CPU_IMX8MNL;
  			}
062c8597d   Ye Li   MLK-22192 imx8mn:...
343
344
  			break;
  		}
05d235a99   Ye Li   MLK-23811 imx8mp:...
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
  	} else if (type == MXC_CPU_IMX8MP) {
  		u32 value0 = readl(&fuse->tester3);
  		u32 flag = 0;
  
  		if ((value0 & 0xc0000) == 0x80000) {
  			return MXC_CPU_IMX8MPD;
  		} else {
  			/* vpu disabled */
  			if ((value0 & 0x43000000) == 0x43000000)
  				flag = 1;
  
  			/* npu disabled*/
  			if ((value & 0x8) == 0x8)
  				flag |= (1 << 1);
  
  			/* isp disabled */
  			if ((value & 0x3) == 0x3)
  				flag |= (1 << 2);
  
  			switch (flag) {
  			case 7:
  				return MXC_CPU_IMX8MPL;
05d235a99   Ye Li   MLK-23811 imx8mp:...
367
368
  			case 2:
  				return MXC_CPU_IMX8MP6;
05d235a99   Ye Li   MLK-23811 imx8mp:...
369
370
371
372
  			default:
  				break;
  			}
  		}
78db9a546   Peng Fan   imx: add get_cpu_...
373
374
375
376
  	}
  
  	return type;
  }
fcdbde7ce   Peng Fan   imx: mx8m: add so...
377
378
379
380
381
  u32 get_cpu_rev(void)
  {
  	struct anamix_pll *ana_pll = (struct anamix_pll *)ANATOP_BASE_ADDR;
  	u32 reg = readl(&ana_pll->digprog);
  	u32 type = (reg >> 16) & 0xff;
78db9a546   Peng Fan   imx: add get_cpu_...
382
  	u32 major_low = (reg >> 8) & 0xff;
fcdbde7ce   Peng Fan   imx: mx8m: add so...
383
384
385
  	u32 rom_version;
  
  	reg &= 0xff;
625b03d81   Peng Fan   imx: get cpu id/t...
386
387
  	/* iMX8MP */
  	if (major_low == 0x43) {
05d235a99   Ye Li   MLK-23811 imx8mp:...
388
  		type = get_cpu_variant_type(MXC_CPU_IMX8MP);
625b03d81   Peng Fan   imx: get cpu id/t...
389
390
  	} else if (major_low == 0x42) {
  		/* iMX8MN */
062c8597d   Ye Li   MLK-22192 imx8mn:...
391
  		type = get_cpu_variant_type(MXC_CPU_IMX8MN);
2434131a7   Peng Fan   imx8mn: support g...
392
  	} else if (major_low == 0x41) {
78db9a546   Peng Fan   imx: add get_cpu_...
393
394
395
396
  		type = get_cpu_variant_type(MXC_CPU_IMX8MM);
  	} else {
  		if (reg == CHIP_REV_1_0) {
  			/*
9e0944554   Peng Fan   imx8m: imx8mq: ge...
397
398
399
400
  			 * For B0 chip, the DIGPROG is not updated,
  			 * it is still TO1.0. we have to check ROM
  			 * version or OCOTP_READ_FUSE_DATA.
  			 * 0xff0055aa is magic number for B1.
78db9a546   Peng Fan   imx: add get_cpu_...
401
  			 */
9e0944554   Peng Fan   imx8m: imx8mq: ge...
402
  			if (readl((void __iomem *)(OCOTP_BASE_ADDR + 0x40)) == 0xff0055aa) {
ec1f64b42   Ye Li   MLK-25291-1 iMX8M...
403
404
405
406
407
408
409
410
411
412
  				/*
  				 * B2 uses same DIGPROG and OCOTP_READ_FUSE_DATA value with B1,
  				 * so have to check ROM to distinguish them
  				 */
  				rom_version = readl((void __iomem *)ROM_VERSION_B0);
  				rom_version &= 0xff;
  				if (rom_version == CHIP_REV_2_2)
  					reg = CHIP_REV_2_2;
  				else
  					reg = CHIP_REV_2_1;
9e0944554   Peng Fan   imx8m: imx8mq: ge...
413
414
415
416
417
  			} else {
  				rom_version =
  					readl((void __iomem *)ROM_VERSION_A0);
  				if (rom_version != CHIP_REV_1_0) {
  					rom_version = readl((void __iomem *)ROM_VERSION_B0);
6a4b07e08   Patrick Wildt   imx8m: fix rom ve...
418
  					rom_version &= 0xff;
9e0944554   Peng Fan   imx8m: imx8mq: ge...
419
420
421
  					if (rom_version == CHIP_REV_2_0)
  						reg = CHIP_REV_2_0;
  				}
78db9a546   Peng Fan   imx: add get_cpu_...
422
  			}
fcdbde7ce   Peng Fan   imx: mx8m: add so...
423
  		}
f8787814c   Ye Li   MLK-19526-1 imx8m...
424
425
  
  		type = get_cpu_variant_type(type);
fcdbde7ce   Peng Fan   imx: mx8m: add so...
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
  	}
  
  	return (type << 12) | reg;
  }
  
  static void imx_set_wdog_powerdown(bool enable)
  {
  	struct wdog_regs *wdog1 = (struct wdog_regs *)WDOG1_BASE_ADDR;
  	struct wdog_regs *wdog2 = (struct wdog_regs *)WDOG2_BASE_ADDR;
  	struct wdog_regs *wdog3 = (struct wdog_regs *)WDOG3_BASE_ADDR;
  
  	/* Write to the PDE (Power Down Enable) bit */
  	writew(enable, &wdog1->wmcr);
  	writew(enable, &wdog2->wmcr);
  	writew(enable, &wdog3->wmcr);
  }
e663c703b   Peng Fan   imx8m: soc: probe...
442
443
444
445
  int arch_cpu_init_dm(void)
  {
  	struct udevice *dev;
  	int ret;
cd7c806f4   Peng Fan   imx: imx8m: fix b...
446
447
448
449
450
451
452
453
454
  	if (CONFIG_IS_ENABLED(CLK)) {
  		ret = uclass_get_device_by_name(UCLASS_CLK,
  						"clock-controller@30380000",
  						&dev);
  		if (ret < 0) {
  			printf("Failed to find clock node. Check device tree
  ");
  			return ret;
  		}
e663c703b   Peng Fan   imx8m: soc: probe...
455
456
457
458
  	}
  
  	return 0;
  }
ce78751b8   Ye Li   MLK-22749 imx8mq:...
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
  #if defined(CONFIG_IMX_HAB) && defined(CONFIG_IMX8MQ)
  static bool is_hdmi_fused(void) {
  	struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
  	struct fuse_bank *bank = &ocotp->bank[1];
  	struct fuse_bank1_regs *fuse =
  		(struct fuse_bank1_regs *)bank->fuse_regs;
  
  	u32 value = readl(&fuse->tester4);
  
  	if (is_imx8mq()) {
  		if (value & 0x02000000)
  			return true;
  	}
  
  	return false;
  }
  
  bool is_uid_matched(u64 uid) {
  	struct tag_serialnr nr;
  	get_board_serial(&nr);
  
  	if (lower_32_bits(uid) == nr.low &&
  		upper_32_bits(uid) == nr.high)
  		return true;
  
  	return false;
  }
  
  static void secure_lockup(void)
  {
  	if (is_imx8mq() && is_soc_rev(CHIP_REV_2_1) &&
  		imx_hab_is_enabled() && !is_hdmi_fused()) {
  #ifdef CONFIG_SECURE_STICKY_BITS_LOCKUP
  		struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
  
  		clock_enable(CCGR_OCOTP, 1);
  		setbits_le32(&ocotp->sw_sticky, 0x6); /* Lock up field return and SRK revoke */
  		writel(0x80000000, &ocotp->scs_set); /* Lock up SCS */
ce78751b8   Ye Li   MLK-22749 imx8mq:...
497
498
499
500
501
502
503
504
  #else
  		/* Check the Unique ID, if it is matched with UID config, then allow to leave sticky bits unlocked */
  		if (!is_uid_matched(CONFIG_IMX_UNIQUE_ID))
  			hang();
  #endif
  	}
  }
  #endif
fcdbde7ce   Peng Fan   imx: mx8m: add so...
505
506
  int arch_cpu_init(void)
  {
702339bdf   Peng Fan   imx: i.MX8MQ: cle...
507
  	struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
fcdbde7ce   Peng Fan   imx: mx8m: add so...
508
  	/*
0528ba0e1   Peng Fan   imx8m: soc: enabl...
509
510
511
512
513
514
  	 * ROM might disable clock for SCTR,
  	 * enable the clock before timer_init.
  	 */
  	if (IS_ENABLED(CONFIG_SPL_BUILD))
  		clock_enable(CCGR_SCTR, 1);
  	/*
fcdbde7ce   Peng Fan   imx: mx8m: add so...
515
516
517
518
519
520
521
522
  	 * Init timer at very early state, because sscg pll setting
  	 * will use it
  	 */
  	timer_init();
  
  	if (IS_ENABLED(CONFIG_SPL_BUILD)) {
  		clock_init();
  		imx_set_wdog_powerdown(false);
96f627a6d   Ye Li   MLK-19526-5 imx8m...
523

ce78751b8   Ye Li   MLK-22749 imx8mq:...
524
525
526
  #if defined(CONFIG_IMX_HAB) && defined(CONFIG_IMX8MQ)
  		secure_lockup();
  #endif
062c8597d   Ye Li   MLK-22192 imx8mn:...
527
  		if (is_imx8md() || is_imx8mmd() || is_imx8mmdl() || is_imx8mms() || is_imx8mmsl() ||
dce6de018   Ye Li   MLK-25003-1 iMX8M...
528
529
  			is_imx8mnd() || is_imx8mndl() || is_imx8mns() || is_imx8mnsl() || is_imx8mpd() ||
  			is_imx8mnud() || is_imx8mnus()) {
f05bc5f9e   Ye Li   MLK-19960-3 imx8m...
530
531
  			/* Power down cpu core 1, 2 and 3 for iMX8M Dual core or Single core */
  			struct pgc_reg *pgc_core1 = (struct pgc_reg *)(GPC_BASE_ADDR + 0x840);
96f627a6d   Ye Li   MLK-19526-5 imx8m...
532
533
534
535
536
537
  			struct pgc_reg *pgc_core2 = (struct pgc_reg *)(GPC_BASE_ADDR + 0x880);
  			struct pgc_reg *pgc_core3 = (struct pgc_reg *)(GPC_BASE_ADDR + 0x8C0);
  			struct gpc_reg *gpc = (struct gpc_reg *)GPC_BASE_ADDR;
  
  			writel(0x1, &pgc_core2->pgcr);
  			writel(0x1, &pgc_core3->pgcr);
dce6de018   Ye Li   MLK-25003-1 iMX8M...
538
  			if (is_imx8mms() || is_imx8mmsl() || is_imx8mns() || is_imx8mnsl() || is_imx8mnus()) {
f05bc5f9e   Ye Li   MLK-19960-3 imx8m...
539
540
541
542
543
  				writel(0x1, &pgc_core1->pgcr);
  				writel(0xE, &gpc->cpu_pgc_dn_trg);
  			} else {
  				writel(0xC, &gpc->cpu_pgc_dn_trg);
  			}
96f627a6d   Ye Li   MLK-19526-5 imx8m...
544
  		}
fcdbde7ce   Peng Fan   imx: mx8m: add so...
545
  	}
6427f23dc   Aymen Sghaier   MLK-18703: crypto...
546
547
548
549
  #ifdef CONFIG_IMX_SEC_INIT
  	/* Secure init function such RNG */
  	imx_sec_init();
  #endif
9f99e9de1   Ye Li   MLK-18591-3 andro...
550
551
552
553
  #if defined(CONFIG_ANDROID_SUPPORT)
  	/* Enable RTC */
  	writel(0x21, 0x30370038);
  #endif
6427f23dc   Aymen Sghaier   MLK-18703: crypto...
554

702339bdf   Peng Fan   imx: i.MX8MQ: cle...
555
556
557
558
559
  	if (is_imx8mq()) {
  		clock_enable(CCGR_OCOTP, 1);
  		if (readl(&ocotp->ctrl) & 0x200)
  			writel(0x200, &ocotp->ctrl_clr);
  	}
fcdbde7ce   Peng Fan   imx: mx8m: add so...
560
561
  	return 0;
  }
b1821376e   Peng Fan   imx8mn: add get_b...
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
  #if defined(CONFIG_IMX8MN) || defined(CONFIG_IMX8MP)
  struct rom_api *g_rom_api = (struct rom_api *)0x980;
  
  enum boot_device get_boot_device(void)
  {
  	volatile gd_t *pgd = gd;
  	int ret;
  	u32 boot;
  	u16 boot_type;
  	u8 boot_instance;
  	enum boot_device boot_dev = SD1_BOOT;
  
  	ret = g_rom_api->query_boot_infor(QUERY_BT_DEV, &boot,
  					  ((uintptr_t)&boot) ^ QUERY_BT_DEV);
  	gd = pgd;
  
  	if (ret != ROM_API_OKAY) {
  		puts("ROMAPI: failure at query_boot_info
  ");
  		return -1;
  	}
  
  	boot_type = boot >> 16;
  	boot_instance = (boot >> 8) & 0xff;
  
  	switch (boot_type) {
  	case BT_DEV_TYPE_SD:
  		boot_dev = boot_instance + SD1_BOOT;
  		break;
  	case BT_DEV_TYPE_MMC:
  		boot_dev = boot_instance + MMC1_BOOT;
  		break;
  	case BT_DEV_TYPE_NAND:
  		boot_dev = NAND_BOOT;
  		break;
  	case BT_DEV_TYPE_FLEXSPINOR:
  		boot_dev = QSPI_BOOT;
  		break;
  	case BT_DEV_TYPE_USB:
  		boot_dev = USB_BOOT;
  		break;
  	default:
  		break;
  	}
  
  	return boot_dev;
  }
  #endif
fcdbde7ce   Peng Fan   imx: mx8m: add so...
610
611
612
613
  bool is_usb_boot(void)
  {
  	return get_boot_device() == USB_BOOT;
  }
9f99e9de1   Ye Li   MLK-18591-3 andro...
614
615
616
617
618
619
620
621
622
623
624
625
  #ifdef CONFIG_SERIAL_TAG
  void get_board_serial(struct tag_serialnr *serialnr)
  {
  	struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
  	struct fuse_bank *bank = &ocotp->bank[0];
  	struct fuse_bank0_regs *fuse =
  		(struct fuse_bank0_regs *)bank->fuse_regs;
  
  	serialnr->low = fuse->uid_low;
  	serialnr->high = fuse->uid_high;
  }
  #endif
fcdbde7ce   Peng Fan   imx: mx8m: add so...
626
627
  
  #ifdef CONFIG_OF_SYSTEM_SETUP
9b1033f34   Ye Li   MLK-23524 imx8m: ...
628
629
630
631
632
633
634
635
636
637
638
639
  bool check_fdt_new_path(void *blob)
  {
  	const char *soc_path = "/soc@0";
  	int nodeoff;
  
  	nodeoff = fdt_path_offset(blob, soc_path);
  	if (nodeoff < 0) {
  		return false;
  	}
  
  	return true;
  }
e4926d415   Ye Li   MLK-19526-2 imx8m...
640
  static int disable_fdt_nodes(void *blob, const char *nodes_path[], int size_array)
fcdbde7ce   Peng Fan   imx: mx8m: add so...
641
642
643
644
  {
  	int i = 0;
  	int rc;
  	int nodeoff;
e4926d415   Ye Li   MLK-19526-2 imx8m...
645
  	const char *status = "disabled";
fcdbde7ce   Peng Fan   imx: mx8m: add so...
646

e4926d415   Ye Li   MLK-19526-2 imx8m...
647
648
649
650
  	for (i = 0; i < size_array; i++) {
  		nodeoff = fdt_path_offset(blob, nodes_path[i]);
  		if (nodeoff < 0)
  			continue; /* Not found, skip it */
e18f601c5   Ye Li   MLK-16246 imx8mq_...
651

e4926d415   Ye Li   MLK-19526-2 imx8m...
652
653
  		printf("Found %s node
  ", nodes_path[i]);
e18f601c5   Ye Li   MLK-16246 imx8mq_...
654
655
  
  add_status:
e4926d415   Ye Li   MLK-19526-2 imx8m...
656
657
658
659
660
661
  		rc = fdt_setprop(blob, nodeoff, "status", status, strlen(status) + 1);
  		if (rc) {
  			if (rc == -FDT_ERR_NOSPACE) {
  				rc = fdt_increase_size(blob, 512);
  				if (!rc)
  					goto add_status;
e18f601c5   Ye Li   MLK-16246 imx8mq_...
662
  			}
e4926d415   Ye Li   MLK-19526-2 imx8m...
663
664
665
666
667
668
669
670
671
672
673
674
  			printf("Unable to update property %s:%s, err=%s
  ",
  				nodes_path[i], "status", fdt_strerror(rc));
  		} else {
  			printf("Modify %s:%s disabled
  ",
  				nodes_path[i], "status");
  		}
  	}
  
  	return 0;
  }
dcdb0c9a1   Ye Li   MLK-19960-2 imx8m...
675
  #ifdef CONFIG_IMX8MQ
e4926d415   Ye Li   MLK-19526-2 imx8m...
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
  bool check_dcss_fused(void)
  {
  	struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
  	struct fuse_bank *bank = &ocotp->bank[1];
  	struct fuse_bank1_regs *fuse =
  		(struct fuse_bank1_regs *)bank->fuse_regs;
  
  	u32 value = readl(&fuse->tester4);
  	if (value & 0x4000000)
  		return true;
  
  	return false;
  }
  
  static int disable_mipi_dsi_nodes(void *blob)
  {
  	const char *nodes_path[] = {
  		"/mipi_dsi@30A00000",
  		"/mipi_dsi_bridge@30A00000",
9b1033f34   Ye Li   MLK-23524 imx8m: ...
695
696
697
  		"/dsi_phy@30A00300",
  		"/soc@0/bus@30800000/mipi_dsi@30a00000",
  		"/soc@0/bus@30800000/dphy@30a00300"
602b90354   Peng Fan   MLK-24968 imx8m: ...
698
  		"/soc@0/bus@30800000/mipi-dsi@30a00000",
e4926d415   Ye Li   MLK-19526-2 imx8m...
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
  	};
  
  	return disable_fdt_nodes(blob, nodes_path, ARRAY_SIZE(nodes_path));
  }
  
  static int disable_dcss_nodes(void *blob)
  {
  	const char *nodes_path[] = {
  		"/dcss@0x32e00000",
  		"/dcss@32e00000",
  		"/hdmi@32c00000",
  		"/hdmi_cec@32c33800",
  		"/hdmi_drm@32c00000",
  		"/display-subsystem",
  		"/sound-hdmi",
9b1033f34   Ye Li   MLK-23524 imx8m: ...
714
715
716
  		"/sound-hdmi-arc",
  		"/soc@0/bus@32c00000/display-controller@32e00000",
  		"/soc@0/bus@32c00000/hdmi@32c00000",
e4926d415   Ye Li   MLK-19526-2 imx8m...
717
718
719
720
  	};
  
  	return disable_fdt_nodes(blob, nodes_path, ARRAY_SIZE(nodes_path));
  }
e4926d415   Ye Li   MLK-19526-2 imx8m...
721
722
  static int check_mipi_dsi_nodes(void *blob)
  {
9b1033f34   Ye Li   MLK-23524 imx8m: ...
723
724
  	const char *lcdif_path[] = {
  		"/lcdif@30320000",
602b90354   Peng Fan   MLK-24968 imx8m: ...
725
726
  		"/soc@0/bus@30000000/lcdif@30320000",
  		"/soc@0/bus@30000000/lcd-controller@30320000"
9b1033f34   Ye Li   MLK-23524 imx8m: ...
727
728
729
730
731
732
733
  	};
  	const char *mipi_dsi_path[] = {
  		"/mipi_dsi@30A00000",
  		"/soc@0/bus@30800000/mipi_dsi@30a00000"
  	};
  	const char *lcdif_ep_path[] = {
  		"/lcdif@30320000/port@0/mipi-dsi-endpoint",
602b90354   Peng Fan   MLK-24968 imx8m: ...
734
735
  		"/soc@0/bus@30000000/lcdif@30320000/port@0/endpoint",
  		"/soc@0/bus@30000000/lcd-controller@30320000/port@0/endpoint"
9b1033f34   Ye Li   MLK-23524 imx8m: ...
736
737
738
  	};
  	const char *mipi_dsi_ep_path[] = {
  		"/mipi_dsi@30A00000/port@1/endpoint",
602b90354   Peng Fan   MLK-24968 imx8m: ...
739
740
  		"/soc@0/bus@30800000/mipi_dsi@30a00000/ports/port@0/endpoint",
  		"/soc@0/bus@30800000/mipi-dsi@30a00000/ports/port@0/endpoint@0"
9b1033f34   Ye Li   MLK-23524 imx8m: ...
741
  	};
e4926d415   Ye Li   MLK-19526-2 imx8m...
742
743
  
  	int nodeoff;
9b1033f34   Ye Li   MLK-23524 imx8m: ...
744
745
746
747
  	bool new_path = check_fdt_new_path(blob);
  	int i = new_path? 1 : 0;
  
  	nodeoff = fdt_path_offset(blob, lcdif_path[i]);
e4926d415   Ye Li   MLK-19526-2 imx8m...
748
749
750
751
752
  	if (nodeoff < 0 || !fdtdec_get_is_enabled(blob, nodeoff)) {
  		/* If can't find lcdif node or lcdif node is disabled, then disable all mipi dsi,
  		    since they only can input from DCSS */
  		return disable_mipi_dsi_nodes(blob);
  	}
9b1033f34   Ye Li   MLK-23524 imx8m: ...
753
  	nodeoff = fdt_path_offset(blob, mipi_dsi_path[i]);
e4926d415   Ye Li   MLK-19526-2 imx8m...
754
755
  	if (nodeoff < 0 || !fdtdec_get_is_enabled(blob, nodeoff))
  		return 0;
9b1033f34   Ye Li   MLK-23524 imx8m: ...
756
  	nodeoff = fdt_path_offset(blob, lcdif_ep_path[i]);
e4926d415   Ye Li   MLK-19526-2 imx8m...
757
758
759
760
761
762
763
  	if (nodeoff < 0) {
  		/* If can't find lcdif endpoint, then disable all mipi dsi,
  		    since they only can input from DCSS */
  		return disable_mipi_dsi_nodes(blob);
  	} else {
  		int lookup_node;
  		lookup_node = fdtdec_lookup_phandle(blob, nodeoff, "remote-endpoint");
9b1033f34   Ye Li   MLK-23524 imx8m: ...
764
  		nodeoff = fdt_path_offset(blob, mipi_dsi_ep_path[i]);
e4926d415   Ye Li   MLK-19526-2 imx8m...
765
766
767
768
769
770
771
772
  
  		if (nodeoff >0 && nodeoff == lookup_node)
  			return 0;
  
  		return disable_mipi_dsi_nodes(blob);
  	}
  
  }
27cb9ee66   Ye Li   MLK-24079 imx8mp:...
773
  #endif
c08b3c762   Li Jun   MLK-19995 imx8mq:...
774
775
776
777
778
779
780
781
  
  void board_quiesce_devices(void)
  {
  #ifdef CONFIG_USB_DWC3
  	if (is_usb_boot())
  		disconnect_from_pc();
  #endif
  }
e4926d415   Ye Li   MLK-19526-2 imx8m...
782

dcdb0c9a1   Ye Li   MLK-19960-2 imx8m...
783
784
785
  int disable_vpu_nodes(void *blob)
  {
  	const char *nodes_path_8mq[] = {
9b1033f34   Ye Li   MLK-23524 imx8m: ...
786
787
  		"/vpu@38300000",
  		"/soc@0/vpu@38300000"
dcdb0c9a1   Ye Li   MLK-19960-2 imx8m...
788
789
790
791
792
793
794
  	};
  
  	const char *nodes_path_8mm[] = {
  		"/vpu_g1@38300000",
  		"/vpu_g2@38310000",
  		"/vpu_h1@38320000"
  	};
05d235a99   Ye Li   MLK-23811 imx8mp:...
795
796
797
798
799
  	const char *nodes_path_8mp[] = {
  		"/vpu_g1@38300000",
  		"/vpu_g2@38310000",
  		"/vpu_vc8000e@38320000"
  	};
dcdb0c9a1   Ye Li   MLK-19960-2 imx8m...
800
801
802
803
  	if (is_imx8mq())
  		return disable_fdt_nodes(blob, nodes_path_8mq, ARRAY_SIZE(nodes_path_8mq));
  	else if (is_imx8mm())
  		return disable_fdt_nodes(blob, nodes_path_8mm, ARRAY_SIZE(nodes_path_8mm));
05d235a99   Ye Li   MLK-23811 imx8mp:...
804
805
  	else if (is_imx8mp())
  		return disable_fdt_nodes(blob, nodes_path_8mp, ARRAY_SIZE(nodes_path_8mp));
dcdb0c9a1   Ye Li   MLK-19960-2 imx8m...
806
807
808
809
  	else
  		return -EPERM;
  
  }
1220640b4   Ye Li   MLK-24434 imx8mn:...
810
811
812
813
  #ifdef CONFIG_IMX8MN_LOW_DRIVE_MODE
  static int low_drive_gpu_freq(void *blob)
  {
  	const char *nodes_path_8mn[] = {
602b90354   Peng Fan   MLK-24968 imx8m: ...
814
815
  		"/gpu@38000000",
  		"/soc@0/gpu@38000000"
1220640b4   Ye Li   MLK-24434 imx8mn:...
816
  	};
968b42dd7   Ye Li   MLK-25010 iMX8MN:...
817
  	int nodeoff, cnt, i, j;
1220640b4   Ye Li   MLK-24434 imx8mn:...
818
  	u32 assignedclks[7];
968b42dd7   Ye Li   MLK-25010 iMX8MN:...
819
820
821
822
823
824
825
826
  	for (i = 0; i < ARRAY_SIZE(nodes_path_8mn); i++) {
  		nodeoff = fdt_path_offset(blob, nodes_path_8mn[i]);
  		if (nodeoff < 0)
  			continue;
  
  		cnt = fdtdec_get_int_array_count(blob, nodeoff, "assigned-clock-rates", assignedclks, 7);
  		if (cnt < 0)
  			return cnt;
1220640b4   Ye Li   MLK-24434 imx8mn:...
827

968b42dd7   Ye Li   MLK-25010 iMX8MN:...
828
829
830
  		if (cnt != 7)
  			printf("Warning: %s, assigned-clock-rates count %d
  ", nodes_path_8mn[i], cnt);
1220640b4   Ye Li   MLK-24434 imx8mn:...
831

968b42dd7   Ye Li   MLK-25010 iMX8MN:...
832
833
  		assignedclks[cnt - 1] = 200000000;
  		assignedclks[cnt - 2] = 200000000;
1220640b4   Ye Li   MLK-24434 imx8mn:...
834

968b42dd7   Ye Li   MLK-25010 iMX8MN:...
835
836
837
838
839
840
  		for (j = 0; j < cnt; j++) {
  			debug("<%u>, ", assignedclks[j]);
  			assignedclks[j] = cpu_to_fdt32(assignedclks[j]);
  		}
  		debug("
  ");
1220640b4   Ye Li   MLK-24434 imx8mn:...
841

968b42dd7   Ye Li   MLK-25010 iMX8MN:...
842
  		return fdt_setprop(blob, nodeoff, "assigned-clock-rates", &assignedclks, sizeof(assignedclks));
1220640b4   Ye Li   MLK-24434 imx8mn:...
843
  	}
1220640b4   Ye Li   MLK-24434 imx8mn:...
844

968b42dd7   Ye Li   MLK-25010 iMX8MN:...
845
  	return -ENOENT;
1220640b4   Ye Li   MLK-24434 imx8mn:...
846
847
  }
  #endif
062c8597d   Ye Li   MLK-22192 imx8mn:...
848
849
850
  int disable_gpu_nodes(void *blob)
  {
  	const char *nodes_path_8mn[] = {
602b90354   Peng Fan   MLK-24968 imx8m: ...
851
852
  		"/gpu@38000000",
  		"/soc@/gpu@38000000"
062c8597d   Ye Li   MLK-22192 imx8mn:...
853
854
855
856
  	};
  
  	return disable_fdt_nodes(blob, nodes_path_8mn, ARRAY_SIZE(nodes_path_8mn));
  }
05d235a99   Ye Li   MLK-23811 imx8mp:...
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
  int disable_npu_nodes(void *blob)
  {
  	const char *nodes_path_8mp[] = {
  		"/vipsi@38500000"
  	};
  
  	return disable_fdt_nodes(blob, nodes_path_8mp, ARRAY_SIZE(nodes_path_8mp));
  }
  
  int disable_isp_nodes(void *blob)
  {
  	const char *nodes_path_8mp[] = {
  		"/soc@0/bus@32c00000/camera/isp@32e10000",
  		"/soc@0/bus@32c00000/camera/isp@32e20000"
  	};
  
  	return disable_fdt_nodes(blob, nodes_path_8mp, ARRAY_SIZE(nodes_path_8mp));
  }
  
  int disable_dsp_nodes(void *blob)
  {
  	const char *nodes_path_8mp[] = {
  		"/dsp@3b6e8000"
  	};
  
  	return disable_fdt_nodes(blob, nodes_path_8mp, ARRAY_SIZE(nodes_path_8mp));
  }
8f02b26d5   Ye Li   MLK-25003-2 iMX8M...
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
  static void disable_thermal_cpu_nodes(void *blob, u32 disabled_cores)
  {
  	const char *thermal_path[] = {
  		"/thermal-zones/cpu-thermal/cooling-maps/map0"
  	};
  
  	int nodeoff, cnt, i, ret, j;
  	u32 cooling_dev[12];
  
  	for (i = 0; i < ARRAY_SIZE(thermal_path); i++) {
  		nodeoff = fdt_path_offset(blob, thermal_path[i]);
  		if (nodeoff < 0)
  			continue; /* Not found, skip it */
  
  		cnt = fdtdec_get_int_array_count(blob, nodeoff, "cooling-device", cooling_dev, 12);
  		if (cnt < 0)
  			continue;
  
  		if (cnt != 12)
  			printf("Warning: %s, cooling-device count %d
  ", thermal_path[i], cnt);
  
  		for (j = 0; j < cnt; j++) {
  			cooling_dev[j] = cpu_to_fdt32(cooling_dev[j]);
  		}
  
  		ret= fdt_setprop(blob, nodeoff, "cooling-device", &cooling_dev, sizeof(u32) * (12 - disabled_cores * 3));
  		if (ret < 0) {
  			printf("Warning: %s, cooling-device setprop failed %d
  ", thermal_path[i], ret);
  			continue;
  		}
  
  		printf("Update node %s, cooling-device prop
  ", thermal_path[i]);
  	}
  }
  
  static void disable_pmu_cpu_nodes(void *blob, u32 disabled_cores)
  {
  	const char *pmu_path[] = {
  		"/pmu"
  	};
  
  	int nodeoff, cnt, i, ret, j;
  	u32 irq_affinity[4];
  
  	for (i = 0; i < ARRAY_SIZE(pmu_path); i++) {
  		nodeoff = fdt_path_offset(blob, pmu_path[i]);
  		if (nodeoff < 0)
  			continue; /* Not found, skip it */
  
  		cnt = fdtdec_get_int_array_count(blob, nodeoff, "interrupt-affinity", irq_affinity, 4);
  		if (cnt < 0)
  			continue;
  
  		if (cnt != 4)
  			printf("Warning: %s, interrupt-affinity count %d
  ", pmu_path[i], cnt);
  
  		for (j = 0; j < cnt; j++) {
  			irq_affinity[j] = cpu_to_fdt32(irq_affinity[j]);
  		}
  
  		ret= fdt_setprop(blob, nodeoff, "interrupt-affinity", &irq_affinity, sizeof(u32) * (4 - disabled_cores));
  		if (ret < 0) {
  			printf("Warning: %s, interrupt-affinity setprop failed %d
  ", pmu_path[i], ret);
  			continue;
  		}
  
  		printf("Update node %s, interrupt-affinity prop
  ", pmu_path[i]);
  	}
  }
dcdb0c9a1   Ye Li   MLK-19960-2 imx8m...
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
  static int disable_cpu_nodes(void *blob, u32 disabled_cores)
  {
  	const char *nodes_path[] = {
  			"/cpus/cpu@1",
  			"/cpus/cpu@2",
  			"/cpus/cpu@3",
  	};
  
  	u32 i = 0;
  	int rc;
  	int nodeoff;
  
  	if (disabled_cores > 3)
  		return -EINVAL;
  
  	i = 3 - disabled_cores;
  
  	for (; i < 3; i++) {
  		nodeoff = fdt_path_offset(blob, nodes_path[i]);
  		if (nodeoff < 0)
  			continue; /* Not found, skip it */
  
  		printf("Found %s node
  ", nodes_path[i]);
  
  		rc = fdt_del_node(blob, nodeoff);
  		if (rc < 0) {
  			printf("Unable to delete node %s, err=%s
  ",
  				nodes_path[i], fdt_strerror(rc));
  		} else {
  			printf("Delete node %s
  ", nodes_path[i]);
  		}
  	}
8f02b26d5   Ye Li   MLK-25003-2 iMX8M...
994
995
  	disable_thermal_cpu_nodes(blob, disabled_cores);
  	disable_pmu_cpu_nodes(blob, disabled_cores);
dcdb0c9a1   Ye Li   MLK-19960-2 imx8m...
996
997
  	return 0;
  }
e4926d415   Ye Li   MLK-19526-2 imx8m...
998
999
1000
1001
1002
1003
1004
1005
1006
1007
  int ft_system_setup(void *blob, bd_t *bd)
  {
  #ifdef CONFIG_IMX8MQ
  	int i = 0;
  	int rc;
  	int nodeoff;
  
  	if (get_boot_device() == USB_BOOT) {
  
  		disable_dcss_nodes(blob);
e18f601c5   Ye Li   MLK-16246 imx8mq_...
1008

9b1033f34   Ye Li   MLK-23524 imx8m: ...
1009
1010
1011
1012
1013
1014
1015
1016
  		bool new_path = check_fdt_new_path(blob);
  		int v = new_path? 1 : 0;
  		const char *usb_dwc3_path[] = {
  			"/usb@38100000/dwc3",
  			"/soc@0/usb@38100000"
  		};
  
  		nodeoff = fdt_path_offset(blob, usb_dwc3_path[v]);
32943c7d8   Ye Li   MLK-16974 imx8m: ...
1017
1018
  		if (nodeoff >= 0) {
  			const char *speed = "high-speed";
9b1033f34   Ye Li   MLK-23524 imx8m: ...
1019
1020
  			printf("Found %s node
  ", usb_dwc3_path[v]);
32943c7d8   Ye Li   MLK-16974 imx8m: ...
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
  
  usb_modify_speed:
  
  			rc = fdt_setprop(blob, nodeoff, "maximum-speed", speed, strlen(speed) + 1);
  			if (rc) {
  				if (rc == -FDT_ERR_NOSPACE) {
  					rc = fdt_increase_size(blob, 512);
  					if (!rc)
  						goto usb_modify_speed;
  				}
  				printf("Unable to set property %s:%s, err=%s
  ",
9b1033f34   Ye Li   MLK-23524 imx8m: ...
1033
  					usb_dwc3_path[v], "maximum-speed", fdt_strerror(rc));
32943c7d8   Ye Li   MLK-16974 imx8m: ...
1034
1035
1036
  			} else {
  				printf("Modify %s:%s = %s
  ",
9b1033f34   Ye Li   MLK-23524 imx8m: ...
1037
  					usb_dwc3_path[v], "maximum-speed", speed);
32943c7d8   Ye Li   MLK-16974 imx8m: ...
1038
1039
  			}
  		}else {
9b1033f34   Ye Li   MLK-23524 imx8m: ...
1040
1041
  			printf("Can't found %s node
  ", usb_dwc3_path[v]);
32943c7d8   Ye Li   MLK-16974 imx8m: ...
1042
1043
  		}
  	}
fcdbde7ce   Peng Fan   imx: mx8m: add so...
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
  	/* Disable the CPU idle for A0 chip since the HW does not support it */
  	if (is_soc_rev(CHIP_REV_1_0)) {
  		static const char * const nodes_path[] = {
  			"/cpus/cpu@0",
  			"/cpus/cpu@1",
  			"/cpus/cpu@2",
  			"/cpus/cpu@3",
  		};
  
  		for (i = 0; i < ARRAY_SIZE(nodes_path); i++) {
  			nodeoff = fdt_path_offset(blob, nodes_path[i]);
  			if (nodeoff < 0)
  				continue; /* Not found, skip it */
  
  			printf("Found %s node
  ", nodes_path[i]);
  
  			rc = fdt_delprop(blob, nodeoff, "cpu-idle-states");
  			if (rc) {
  				printf("Unable to update property %s:%s, err=%s
  ",
  				       nodes_path[i], "status", fdt_strerror(rc));
  				return rc;
  			}
  
  			printf("Remove %s:%s
  ", nodes_path[i],
  			       "cpu-idle-states");
  		}
  	}
e4926d415   Ye Li   MLK-19526-2 imx8m...
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
  	if (is_imx8mql()) {
  		disable_vpu_nodes(blob);
  		if (check_dcss_fused()) {
  			printf("DCSS is fused
  ");
  			disable_dcss_nodes(blob);
  			check_mipi_dsi_nodes(blob);
  		}
  	}
  
  	if (is_imx8md())
dcdb0c9a1   Ye Li   MLK-19960-2 imx8m...
1085
1086
1087
1088
1089
  		disable_cpu_nodes(blob, 2);
  
  #elif defined(CONFIG_IMX8MM)
  	if (is_imx8mml() || is_imx8mmdl() ||  is_imx8mmsl())
  		disable_vpu_nodes(blob);
e4926d415   Ye Li   MLK-19526-2 imx8m...
1090

dcdb0c9a1   Ye Li   MLK-19960-2 imx8m...
1091
1092
1093
1094
  	if (is_imx8mmd() || is_imx8mmdl())
  		disable_cpu_nodes(blob, 2);
  	else if (is_imx8mms() || is_imx8mmsl())
  		disable_cpu_nodes(blob, 3);
062c8597d   Ye Li   MLK-22192 imx8mn:...
1095
1096
1097
1098
  
  #elif defined(CONFIG_IMX8MN)
  	if (is_imx8mnl() || is_imx8mndl() ||  is_imx8mnsl())
  		disable_gpu_nodes(blob);
1220640b4   Ye Li   MLK-24434 imx8mn:...
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
  #ifdef CONFIG_IMX8MN_LOW_DRIVE_MODE
  	else {
  		int ldm_gpu = low_drive_gpu_freq(blob);
  		if (ldm_gpu < 0)
  			printf("Update GPU node assigned-clock-rates failed
  ");
  		else
  			printf("Update GPU node assigned-clock-rates ok
  ");
  	}
  #endif
062c8597d   Ye Li   MLK-22192 imx8mn:...
1110

dce6de018   Ye Li   MLK-25003-1 iMX8M...
1111
  	if (is_imx8mnd() || is_imx8mndl() || is_imx8mnud())
062c8597d   Ye Li   MLK-22192 imx8mn:...
1112
  		disable_cpu_nodes(blob, 2);
dce6de018   Ye Li   MLK-25003-1 iMX8M...
1113
  	else if (is_imx8mns() || is_imx8mnsl() || is_imx8mnus())
062c8597d   Ye Li   MLK-22192 imx8mn:...
1114
  		disable_cpu_nodes(blob, 3);
05d235a99   Ye Li   MLK-23811 imx8mp:...
1115
  #elif defined(CONFIG_IMX8MP)
ac0a4645b   Ye Li   MLK-24451 imx8mp:...
1116
  	if (is_imx8mpl())
05d235a99   Ye Li   MLK-23811 imx8mp:...
1117
  		disable_vpu_nodes(blob);
ac0a4645b   Ye Li   MLK-24451 imx8mp:...
1118
  	if (is_imx8mpl() || is_imx8mp6())
05d235a99   Ye Li   MLK-23811 imx8mp:...
1119
  		disable_npu_nodes(blob);
ac0a4645b   Ye Li   MLK-24451 imx8mp:...
1120
  	if (is_imx8mpl())
05d235a99   Ye Li   MLK-23811 imx8mp:...
1121
  		disable_isp_nodes(blob);
ac0a4645b   Ye Li   MLK-24451 imx8mp:...
1122
  	if (is_imx8mpl() || is_imx8mp6())
05d235a99   Ye Li   MLK-23811 imx8mp:...
1123
1124
1125
1126
  		disable_dsp_nodes(blob);
  
  	if (is_imx8mpd())
  		disable_cpu_nodes(blob, 2);
e4926d415   Ye Li   MLK-19526-2 imx8m...
1127
  #endif
dbdf9dd3b   Peng Fan   MLK-16753-1 imx8m...
1128
  	return ft_add_optee_node(blob, bd);
fcdbde7ce   Peng Fan   imx: mx8m: add so...
1129
1130
  }
  #endif
d2041725e   Peng Fan   imx8m: restrict r...
1131
  #if defined(CONFIG_SPL_BUILD) || !defined(CONFIG_SYSRESET)
fcdbde7ce   Peng Fan   imx: mx8m: add so...
1132
1133
  void reset_cpu(ulong addr)
  {
fb59c65b5   Ye Li   MLK-23093 imx8m: ...
1134
  	struct watchdog_regs *wdog = (struct watchdog_regs *)addr;
fcdbde7ce   Peng Fan   imx: mx8m: add so...
1135

fb59c65b5   Ye Li   MLK-23093 imx8m: ...
1136
1137
  	if (!addr)
  		wdog = (struct watchdog_regs *)WDOG1_BASE_ADDR;
fcdbde7ce   Peng Fan   imx: mx8m: add so...
1138

fb59c65b5   Ye Li   MLK-23093 imx8m: ...
1139
1140
  	/* Clear WDA to trigger WDOG_B immediately */
  	writew((SET_WCR_WT(1) | WCR_WDT | WCR_WDE | WCR_SRS), &wdog->wcr);
d2041725e   Peng Fan   imx8m: restrict r...
1141

fb59c65b5   Ye Li   MLK-23093 imx8m: ...
1142
1143
1144
1145
1146
  	while (1) {
  		/*
  		 * spin for 1 second before timeout reset
  		 */
  	}
fcdbde7ce   Peng Fan   imx: mx8m: add so...
1147
  }
d2041725e   Peng Fan   imx8m: restrict r...
1148
  #endif
4d4de2adc   Peng Fan   MLK-17050 imx8m: ...
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
  
  #if defined(CONFIG_ARCH_MISC_INIT)
  #define FSL_SIP_BUILDINFO			0xC2000003
  #define FSL_SIP_BUILDINFO_GET_COMMITHASH	0x00
  static void acquire_buildinfo(void)
  {
  	uint64_t atf_commit = 0;
  
  	/* Get ARM Trusted Firmware commit id */
  	atf_commit = call_imx_sip(FSL_SIP_BUILDINFO,
  				  FSL_SIP_BUILDINFO_GET_COMMITHASH, 0, 0, 0);
  	if (atf_commit == 0xffffffff) {
  		debug("ATF does not support build info
  ");
  		atf_commit = 0x30; /* Display 0, 0 ascii is 0x30 */
  	}
  
  	printf("
   BuildInfo:
    - ATF %s
    - %s
  
  ", (char *)&atf_commit,
  	       U_BOOT_VERSION);
  }
  
  int arch_misc_init(void)
  {
  	acquire_buildinfo();
  
  	return 0;
  }
  #endif
fdae2f235   Ye Li   MLK-17210 usb: im...
1182

fdae2f235   Ye Li   MLK-17210 usb: im...
1183
1184
  #define FSL_SIP_GPC			0xC2000000
  #define FSL_SIP_CONFIG_GPC_PM_DOMAIN	0x03
830584d72   Frank Li   MLK-19181-2: i.MX...
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
  
  #ifdef CONFIG_SPL_BUILD
  static uint32_t gpc_pu_m_core_offset[11] = {
  	0xc00, 0xc40, 0xc80, 0xcc0,
  	0xdc0, 0xe00, 0xe40, 0xe80,
  	0xec0, 0xf00, 0xf40,
  };
  
  #define PGC_PCR				0
  
  void imx_gpc_set_m_core_pgc(unsigned int offset, bool pdn)
fdae2f235   Ye Li   MLK-17210 usb: im...
1196
  {
830584d72   Frank Li   MLK-19181-2: i.MX...
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
  	uint32_t val;
  	uintptr_t reg = GPC_BASE_ADDR + offset;
  
  	val = readl(reg);
  	val &= ~(0x1 << PGC_PCR);
  
  	if(pdn)
  		val |= 0x1 << PGC_PCR;
  	writel(val, reg);
  }
  
  void imx8m_usb_power_domain(uint32_t domain_id, bool on)
  {
  	uint32_t val;
  	uintptr_t reg;
  
  	imx_gpc_set_m_core_pgc(gpc_pu_m_core_offset[domain_id], true);
  
  	reg = GPC_BASE_ADDR + (on ? 0xf8 : 0x104);
  	val = 1 << (domain_id > 3 ? (domain_id + 3) : domain_id);
  	writel(val, reg);
  	while (readl(reg) & val)
  		;
  	imx_gpc_set_m_core_pgc(gpc_pu_m_core_offset[domain_id], false);
  }
  #endif
fdae2f235   Ye Li   MLK-17210 usb: im...
1223

830584d72   Frank Li   MLK-19181-2: i.MX...
1224
1225
  int imx8m_usb_power(int usb_id, bool on)
  {
fdae2f235   Ye Li   MLK-17210 usb: im...
1226
1227
  	if (usb_id > 1)
  		return -EINVAL;
830584d72   Frank Li   MLK-19181-2: i.MX...
1228
1229
1230
1231
  #ifdef CONFIG_SPL_BUILD
  	imx8m_usb_power_domain(2 + usb_id, on);
  #else
  	unsigned long ret;
fdae2f235   Ye Li   MLK-17210 usb: im...
1232
1233
1234
1235
  	ret = call_imx_sip(FSL_SIP_GPC,
  			FSL_SIP_CONFIG_GPC_PM_DOMAIN, 2 + usb_id, on, 0);
  	if (ret)
  		return -EPERM;
830584d72   Frank Li   MLK-19181-2: i.MX...
1236
  #endif
fdae2f235   Ye Li   MLK-17210 usb: im...
1237
1238
1239
  
  	return 0;
  }
d99e05082   Ye Li   MLK-20784-2 imx8m...
1240
1241
1242
  
  void nxp_tmu_arch_init(void *reg_base)
  {
b6765ef4a   Ye Li   MLK-22425 TMU: iM...
1243
  	if (is_imx8mm() || is_imx8mn()) {
d99e05082   Ye Li   MLK-20784-2 imx8m...
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
  		/* Load TCALIV and TASR from fuses */
  		struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
  		struct fuse_bank *bank = &ocotp->bank[3];
  		struct fuse_bank3_regs *fuse =
  			(struct fuse_bank3_regs *)bank->fuse_regs;
  
  		u32 tca_rt, tca_hr, tca_en;
  		u32 buf_vref, buf_slope;
  
  		tca_rt = fuse->ana0 & 0xFF;
  		tca_hr = (fuse->ana0 & 0xFF00) >> 8;
  		tca_en = (fuse->ana0 & 0x2000000) >> 25;
  
  		buf_vref = (fuse->ana0 & 0x1F00000) >> 20;
  		buf_slope = (fuse->ana0 & 0xF0000) >> 16;
  
  		writel(buf_vref | (buf_slope << 16), (ulong)reg_base + 0x28);
  		writel((tca_en << 31) |(tca_hr <<16) | tca_rt,  (ulong)reg_base + 0x30);
  	}
28d626d48   Ye Li   MLK-23165-22 nxp_...
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
  #ifdef CONFIG_IMX8MP
  	/* Load TCALIV0/1/m40 and TRIM from fuses */
  	struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
  	struct fuse_bank *bank = &ocotp->bank[38];
  	struct fuse_bank38_regs *fuse =
  		(struct fuse_bank38_regs *)bank->fuse_regs;
  
  	struct fuse_bank *bank2 = &ocotp->bank[39];
  	struct fuse_bank39_regs *fuse2 =
  		(struct fuse_bank39_regs *)bank2->fuse_regs;
  
  	u32 buf_vref, buf_slope, bjt_cur, vlsb, bgr;
  	u32 reg;
  	u32 tca40[2], tca25[2], tca105[2];
  
  	/* For blank sample */
  	if (!fuse->ana_trim2 && !fuse->ana_trim3 &&
  		!fuse->ana_trim4 && !fuse2->ana_trim5) {
  		/* Use a default 25C binary codes */
  		tca25[0] = 1596;
ef139ba67   Ye Li   MLK-23197 imx8mp:...
1283
  		tca25[1] = 1596;
28d626d48   Ye Li   MLK-23165-22 nxp_...
1284
  		writel(tca25[0], (ulong)reg_base + 0x30);
ef139ba67   Ye Li   MLK-23197 imx8mp:...
1285
  		writel(tca25[1], (ulong)reg_base + 0x34);
28d626d48   Ye Li   MLK-23165-22 nxp_...
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
  		return;
  	}
  
  	buf_vref = (fuse->ana_trim2 & 0xc0) >> 6;
  	buf_slope = (fuse->ana_trim2 & 0xF00) >> 8;
  	bjt_cur = (fuse->ana_trim2 & 0xF000) >> 12;
  	bgr = (fuse->ana_trim2 & 0xF0000) >> 16;
  	vlsb = (fuse->ana_trim2 & 0xF00000) >> 20;
  	writel(buf_vref | (buf_slope << 16), (ulong)reg_base + 0x28);
  
  	reg = (bgr << 28) | (bjt_cur << 20) | (vlsb << 12) | ( 1 << 7);
  	writel(reg, (ulong)reg_base + 0x3c);
  
  	tca40[0] = (fuse->ana_trim3 & 0xFFF0000) >> 16;
  	tca25[0] = (fuse->ana_trim3 & 0xF0000000) >> 28;
  	tca25[0] |= ((fuse->ana_trim4 & 0xFF) << 4);
  	tca105[0] = (fuse->ana_trim4 & 0xFFF00) >> 8;
  	tca40[1] = (fuse->ana_trim4 & 0xFFF00000) >> 20;
  	tca25[1] = fuse2->ana_trim5 & 0xFFF;
  	tca105[1] = (fuse2->ana_trim5 & 0xFFF000) >> 12;
  
  	/* use 25c for 1p calibration */
  	writel(tca25[0] | (tca105[0] << 16), (ulong)reg_base + 0x30);
  	writel(tca25[1] | (tca105[1] << 16), (ulong)reg_base + 0x34);
  	writel(tca40[0] | (tca40[1] << 16), (ulong)reg_base + 0x38);
  #endif
d99e05082   Ye Li   MLK-20784-2 imx8m...
1312
  }
c4ac5e2be   Ye Li   MLK-22279-3 imx8m...
1313

31400529b   Ye Li   MLK-22622 imx8m: ...
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
  #if defined(CONFIG_SPL_BUILD)
  #if defined(CONFIG_IMX8MQ) || defined(CONFIG_IMX8MM) || defined(CONFIG_IMX8MN)
  bool serror_need_skip = true;
  void do_error(struct pt_regs *pt_regs, unsigned int esr)
  {
  	/* If stack is still in ROM reserved OCRAM not switch to SPL, it is the ROM SError */
  	ulong sp;
  	asm volatile("mov %0, sp" : "=r"(sp) : );
  
  	if (serror_need_skip &&
  		sp < 0x910000 && sp >= 0x900000) {
  
  		/* Check for ERR050342, imx8mq HDCP enabled parts */
  		if (is_imx8mq() && !(readl(OCOTP_BASE_ADDR + 0x450) & 0x08000000)) {
  			serror_need_skip = false;
  			return; /* Do nothing skip the SError in ROM */
  		}
  
  		/* Check for ERR050350, field return mode for imx8mq, mm and mn */
  		if (readl(OCOTP_BASE_ADDR + 0x630) & 0x1) {
  			serror_need_skip = false;
  			return; /* Do nothing skip the SError in ROM */
  		}
  	}
  
  	efi_restore_gd();
  	printf("\"Error\" handler, esr 0x%08x
  ", esr);
  	show_regs(pt_regs);
  	panic("Resetting CPU ...
  ");
  
  }
  #endif
  #endif
c4ac5e2be   Ye Li   MLK-22279-3 imx8m...
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
  #if defined(CONFIG_IMX8MN) || defined(CONFIG_IMX8MP)
  enum env_location env_get_location(enum env_operation op, int prio)
  {
  	enum boot_device dev = get_boot_device();
  	enum env_location env_loc = ENVL_UNKNOWN;
  
  	if (prio)
  		return env_loc;
  
  	switch (dev) {
  #ifdef CONFIG_ENV_IS_IN_SPI_FLASH
  	case QSPI_BOOT:
  		env_loc = ENVL_SPI_FLASH;
  		break;
  #endif
  #ifdef CONFIG_ENV_IS_IN_NAND
  	case NAND_BOOT:
  		env_loc = ENVL_NAND;
  		break;
  #endif
  #ifdef CONFIG_ENV_IS_IN_MMC
  	case SD1_BOOT:
  	case SD2_BOOT:
  	case SD3_BOOT:
  	case MMC1_BOOT:
  	case MMC2_BOOT:
  	case MMC3_BOOT:
  		env_loc =  ENVL_MMC;
  		break;
  #endif
  	default:
  #if defined(CONFIG_ENV_IS_NOWHERE)
  		env_loc = ENVL_NOWHERE;
  #endif
  		break;
  	}
  
  	return env_loc;
  }
  
  #ifndef ENV_IS_EMBEDDED
  long long env_get_offset(long long defautl_offset)
  {
  	enum boot_device dev = get_boot_device();
  
  	switch (dev) {
  	case NAND_BOOT:
  		return (60 << 20);  /* 60MB offset for NAND */
  	default:
  		break;
  	}
  
  	return defautl_offset;
  }
  #endif
  #endif
f869ee6da   Ye Li   MLK-23964-13 imx8...
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
  
  #ifdef CONFIG_IMX8MQ
  int imx8m_dcss_power_init(void)
  {
  	/* Enable the display CCGR before power on */
  	clock_enable(CCGR_DISPLAY, 1);
  
  	writel(0x0000ffff, 0x303A00EC); /*PGC_CPU_MAPPING */
  	setbits_le32(0x303A00F8, 0x1 << 10); /*PU_PGC_SW_PUP_REQ : disp was 10 */
  
  	return 0;
  }
  #endif