1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2007
4  * Sascha Hauer, Pengutronix
5  *
6  * (C) Copyright 2009 Freescale Semiconductor, Inc.
7  */
8 
9 #include <common.h>
10 #include <env.h>
11 #include <init.h>
12 #include <linux/delay.h>
13 #include <linux/errno.h>
14 #include <asm/io.h>
15 #include <asm/arch/imx-regs.h>
16 #include <asm/arch/clock.h>
17 #include <asm/arch/sys_proto.h>
18 #include <asm/bootm.h>
19 #include <asm/mach-imx/boot_mode.h>
20 #include <asm/mach-imx/dma.h>
21 #include <asm/mach-imx/hab.h>
22 #include <stdbool.h>
23 #include <asm/arch/mxc_hdmi.h>
24 #include <asm/arch/crm_regs.h>
25 #include <dm.h>
26 #include <fsl_sec.h>
27 #include <imx_thermal.h>
28 #include <mmc.h>
29 
30 #define has_err007805() \
31 	(is_mx6sl() || is_mx6dl() || is_mx6solo() || is_mx6ull())
32 
33 struct scu_regs {
34 	u32	ctrl;
35 	u32	config;
36 	u32	status;
37 	u32	invalidate;
38 	u32	fpga_rev;
39 };
40 
41 #if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_IMX_THERMAL)
42 static const struct imx_thermal_plat imx6_thermal_plat = {
43 	.regs = (void *)ANATOP_BASE_ADDR,
44 	.fuse_bank = 1,
45 	.fuse_word = 6,
46 };
47 
48 U_BOOT_DRVINFO(imx6_thermal) = {
49 	.name = "imx_thermal",
50 	.plat = &imx6_thermal_plat,
51 };
52 #endif
53 
54 #if defined(CONFIG_IMX_HAB)
55 struct imx_sec_config_fuse_t const imx_sec_config_fuse = {
56 	.bank = 0,
57 	.word = 6,
58 };
59 #endif
60 
get_nr_cpus(void)61 u32 get_nr_cpus(void)
62 {
63 	struct scu_regs *scu = (struct scu_regs *)SCU_BASE_ADDR;
64 	return readl(&scu->config) & 3;
65 }
66 
get_cpu_rev(void)67 u32 get_cpu_rev(void)
68 {
69 	struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
70 	u32 reg = readl(&anatop->digprog_sololite);
71 	u32 type = ((reg >> 16) & 0xff);
72 	u32 major, cfg = 0;
73 
74 	if (type != MXC_CPU_MX6SL) {
75 		reg = readl(&anatop->digprog);
76 		struct scu_regs *scu = (struct scu_regs *)SCU_BASE_ADDR;
77 		cfg = readl(&scu->config) & 3;
78 		type = ((reg >> 16) & 0xff);
79 		if (type == MXC_CPU_MX6DL) {
80 			if (!cfg)
81 				type = MXC_CPU_MX6SOLO;
82 		}
83 
84 		if (type == MXC_CPU_MX6Q) {
85 			if (cfg == 1)
86 				type = MXC_CPU_MX6D;
87 		}
88 
89 		if (type == MXC_CPU_MX6ULL) {
90 			if (readl(SRC_BASE_ADDR + 0x1c) & (1 << 6))
91 				type = MXC_CPU_MX6ULZ;
92 		}
93 	}
94 	major = ((reg >> 8) & 0xff);
95 	if ((major >= 1) &&
96 	    ((type == MXC_CPU_MX6Q) || (type == MXC_CPU_MX6D))) {
97 		major--;
98 		type = MXC_CPU_MX6QP;
99 		if (cfg == 1)
100 			type = MXC_CPU_MX6DP;
101 	}
102 	reg &= 0xff;		/* mx6 silicon revision */
103 
104 	/* For 6DQ, the value 0x00630005 is Silicon revision 1.3*/
105 	if (((type == MXC_CPU_MX6Q) || (type == MXC_CPU_MX6D)) && (reg == 0x5))
106 		reg = 0x3;
107 
108 	return (type << 12) | (reg + (0x10 * (major + 1)));
109 }
110 
111 /*
112  * OCOTP_CFG3[17:16] (see Fusemap Description Table offset 0x440)
113  * defines a 2-bit SPEED_GRADING
114  */
115 #define OCOTP_CFG3_SPEED_SHIFT	16
116 #define OCOTP_CFG3_SPEED_800MHZ	0
117 #define OCOTP_CFG3_SPEED_850MHZ	1
118 #define OCOTP_CFG3_SPEED_1GHZ	2
119 #define OCOTP_CFG3_SPEED_1P2GHZ	3
120 
121 /*
122  * For i.MX6UL
123  */
124 #define OCOTP_CFG3_SPEED_528MHZ 1
125 #define OCOTP_CFG3_SPEED_696MHZ 2
126 
127 /*
128  * For i.MX6ULL
129  */
130 #define OCOTP_CFG3_SPEED_792MHZ 2
131 #define OCOTP_CFG3_SPEED_900MHZ 3
132 
get_cpu_speed_grade_hz(void)133 u32 get_cpu_speed_grade_hz(void)
134 {
135 	struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
136 	struct fuse_bank *bank = &ocotp->bank[0];
137 	struct fuse_bank0_regs *fuse =
138 		(struct fuse_bank0_regs *)bank->fuse_regs;
139 	uint32_t val;
140 
141 	val = readl(&fuse->cfg3);
142 	val >>= OCOTP_CFG3_SPEED_SHIFT;
143 	val &= 0x3;
144 
145 	if (is_mx6ul()) {
146 		if (val == OCOTP_CFG3_SPEED_528MHZ)
147 			return 528000000;
148 		else if (val == OCOTP_CFG3_SPEED_696MHZ)
149 			return 696000000;
150 		else
151 			return 0;
152 	}
153 
154 	if (is_mx6ull()) {
155 		if (val == OCOTP_CFG3_SPEED_528MHZ)
156 			return 528000000;
157 		else if (val == OCOTP_CFG3_SPEED_792MHZ)
158 			return 792000000;
159 		else if (val == OCOTP_CFG3_SPEED_900MHZ)
160 			return 900000000;
161 		else
162 			return 0;
163 	}
164 
165 	switch (val) {
166 	/* Valid for IMX6DQ */
167 	case OCOTP_CFG3_SPEED_1P2GHZ:
168 		if (is_mx6dq() || is_mx6dqp())
169 			return 1200000000;
170 	/* Valid for IMX6SX/IMX6SDL/IMX6DQ */
171 	case OCOTP_CFG3_SPEED_1GHZ:
172 		return 996000000;
173 	/* Valid for IMX6DQ */
174 	case OCOTP_CFG3_SPEED_850MHZ:
175 		if (is_mx6dq() || is_mx6dqp())
176 			return 852000000;
177 	/* Valid for IMX6SX/IMX6SDL/IMX6DQ */
178 	case OCOTP_CFG3_SPEED_800MHZ:
179 		return 792000000;
180 	}
181 	return 0;
182 }
183 
184 /*
185  * OCOTP_MEM0[7:6] (see Fusemap Description Table offset 0x480)
186  * defines a 2-bit Temperature Grade
187  *
188  * return temperature grade and min/max temperature in Celsius
189  */
190 #define OCOTP_MEM0_TEMP_SHIFT          6
191 
get_cpu_temp_grade(int * minc,int * maxc)192 u32 get_cpu_temp_grade(int *minc, int *maxc)
193 {
194 	struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
195 	struct fuse_bank *bank = &ocotp->bank[1];
196 	struct fuse_bank1_regs *fuse =
197 		(struct fuse_bank1_regs *)bank->fuse_regs;
198 	uint32_t val;
199 
200 	val = readl(&fuse->mem0);
201 	val >>= OCOTP_MEM0_TEMP_SHIFT;
202 	val &= 0x3;
203 
204 	if (minc && maxc) {
205 		if (val == TEMP_AUTOMOTIVE) {
206 			*minc = -40;
207 			*maxc = 125;
208 		} else if (val == TEMP_INDUSTRIAL) {
209 			*minc = -40;
210 			*maxc = 105;
211 		} else if (val == TEMP_EXTCOMMERCIAL) {
212 			*minc = -20;
213 			*maxc = 105;
214 		} else {
215 			*minc = 0;
216 			*maxc = 95;
217 		}
218 	}
219 	return val;
220 }
221 
222 #ifdef CONFIG_REVISION_TAG
get_board_rev(void)223 u32 __weak get_board_rev(void)
224 {
225 	u32 cpurev = get_cpu_rev();
226 	u32 type = ((cpurev >> 12) & 0xff);
227 	if (type == MXC_CPU_MX6SOLO)
228 		cpurev = (MXC_CPU_MX6DL) << 12 | (cpurev & 0xFFF);
229 
230 	if (type == MXC_CPU_MX6D)
231 		cpurev = (MXC_CPU_MX6Q) << 12 | (cpurev & 0xFFF);
232 
233 	return cpurev;
234 }
235 #endif
236 
clear_ldo_ramp(void)237 static void clear_ldo_ramp(void)
238 {
239 	struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
240 	int reg;
241 
242 	/* ROM may modify LDO ramp up time according to fuse setting, so in
243 	 * order to be in the safe side we neeed to reset these settings to
244 	 * match the reset value: 0'b00
245 	 */
246 	reg = readl(&anatop->ana_misc2);
247 	reg &= ~(0x3f << 24);
248 	writel(reg, &anatop->ana_misc2);
249 }
250 
251 /*
252  * Set the PMU_REG_CORE register
253  *
254  * Set LDO_SOC/PU/ARM regulators to the specified millivolt level.
255  * Possible values are from 0.725V to 1.450V in steps of
256  * 0.025V (25mV).
257  */
set_ldo_voltage(enum ldo_reg ldo,u32 mv)258 int set_ldo_voltage(enum ldo_reg ldo, u32 mv)
259 {
260 	struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
261 	u32 val, step, old, reg = readl(&anatop->reg_core);
262 	u8 shift;
263 
264 	/* No LDO_SOC/PU/ARM */
265 	if (is_mx6sll())
266 		return 0;
267 
268 	if (mv < 725)
269 		val = 0x00;	/* Power gated off */
270 	else if (mv > 1450)
271 		val = 0x1F;	/* Power FET switched full on. No regulation */
272 	else
273 		val = (mv - 700) / 25;
274 
275 	clear_ldo_ramp();
276 
277 	switch (ldo) {
278 	case LDO_SOC:
279 		shift = 18;
280 		break;
281 	case LDO_PU:
282 		shift = 9;
283 		break;
284 	case LDO_ARM:
285 		shift = 0;
286 		break;
287 	default:
288 		return -EINVAL;
289 	}
290 
291 	old = (reg & (0x1F << shift)) >> shift;
292 	step = abs(val - old);
293 	if (step == 0)
294 		return 0;
295 
296 	reg = (reg & ~(0x1F << shift)) | (val << shift);
297 	writel(reg, &anatop->reg_core);
298 
299 	/*
300 	 * The LDO ramp-up is based on 64 clock cycles of 24 MHz = 2.6 us per
301 	 * step
302 	 */
303 	udelay(3 * step);
304 
305 	return 0;
306 }
307 
set_ahb_rate(u32 val)308 static void set_ahb_rate(u32 val)
309 {
310 	struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
311 	u32 reg, div;
312 
313 	div = get_periph_clk() / val - 1;
314 	reg = readl(&mxc_ccm->cbcdr);
315 
316 	writel((reg & (~MXC_CCM_CBCDR_AHB_PODF_MASK)) |
317 		(div << MXC_CCM_CBCDR_AHB_PODF_OFFSET), &mxc_ccm->cbcdr);
318 }
319 
clear_mmdc_ch_mask(void)320 static void clear_mmdc_ch_mask(void)
321 {
322 	struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
323 	u32 reg;
324 	reg = readl(&mxc_ccm->ccdr);
325 
326 	/* Clear MMDC channel mask */
327 	if (is_mx6sx() || is_mx6ul() || is_mx6ull() || is_mx6sl() || is_mx6sll())
328 		reg &= ~(MXC_CCM_CCDR_MMDC_CH1_HS_MASK);
329 	else
330 		reg &= ~(MXC_CCM_CCDR_MMDC_CH1_HS_MASK | MXC_CCM_CCDR_MMDC_CH0_HS_MASK);
331 	writel(reg, &mxc_ccm->ccdr);
332 }
333 
334 #define OCOTP_MEM0_REFTOP_TRIM_SHIFT          8
335 
init_bandgap(void)336 static void init_bandgap(void)
337 {
338 	struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
339 	struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
340 	struct fuse_bank *bank = &ocotp->bank[1];
341 	struct fuse_bank1_regs *fuse =
342 		(struct fuse_bank1_regs *)bank->fuse_regs;
343 	uint32_t val;
344 
345 	/*
346 	 * Ensure the bandgap has stabilized.
347 	 */
348 	while (!(readl(&anatop->ana_misc0) & 0x80))
349 		;
350 	/*
351 	 * For best noise performance of the analog blocks using the
352 	 * outputs of the bandgap, the reftop_selfbiasoff bit should
353 	 * be set.
354 	 */
355 	writel(BM_ANADIG_ANA_MISC0_REFTOP_SELBIASOFF, &anatop->ana_misc0_set);
356 	/*
357 	 * On i.MX6ULL,we need to set VBGADJ bits according to the
358 	 * REFTOP_TRIM[3:0] in fuse table
359 	 *	000 - set REFTOP_VBGADJ[2:0] to 3b'110,
360 	 *	110 - set REFTOP_VBGADJ[2:0] to 3b'000,
361 	 *	001 - set REFTOP_VBGADJ[2:0] to 3b'001,
362 	 *	010 - set REFTOP_VBGADJ[2:0] to 3b'010,
363 	 *	011 - set REFTOP_VBGADJ[2:0] to 3b'011,
364 	 *	100 - set REFTOP_VBGADJ[2:0] to 3b'100,
365 	 *	101 - set REFTOP_VBGADJ[2:0] to 3b'101,
366 	 *	111 - set REFTOP_VBGADJ[2:0] to 3b'111,
367 	 */
368 	if (is_mx6ull()) {
369 		val = readl(&fuse->mem0);
370 		val >>= OCOTP_MEM0_REFTOP_TRIM_SHIFT;
371 		val &= 0x7;
372 
373 		writel(val << BM_ANADIG_ANA_MISC0_REFTOP_VBGADJ_SHIFT,
374 		       &anatop->ana_misc0_set);
375 	}
376 }
377 
378 #if defined(CONFIG_MX6Q) || defined(CONFIG_MX6QDL)
noc_setup(void)379 static void noc_setup(void)
380 {
381 	enable_ipu_clock();
382 
383 	writel(0x80000201, 0xbb0608);
384 	/* Bypass IPU1 QoS generator */
385 	writel(0x00000002, 0x00bb048c);
386 	/* Bypass IPU2 QoS generator */
387 	writel(0x00000002, 0x00bb050c);
388 	/* Bandwidth THR for of PRE0 */
389 	writel(0x00000200, 0x00bb0690);
390 	/* Bandwidth THR for of PRE1 */
391 	writel(0x00000200, 0x00bb0710);
392 	/* Bandwidth THR for of PRE2 */
393 	writel(0x00000200, 0x00bb0790);
394 	/* Bandwidth THR for of PRE3 */
395 	writel(0x00000200, 0x00bb0810);
396 	/* Saturation THR for of PRE0 */
397 	writel(0x00000010, 0x00bb0694);
398 	/* Saturation THR for of PRE1 */
399 	writel(0x00000010, 0x00bb0714);
400 	/* Saturation THR for of PRE2 */
401 	writel(0x00000010, 0x00bb0794);
402 	/* Saturation THR for of PRE */
403 	writel(0x00000010, 0x00bb0814);
404 
405 	disable_ipu_clock();
406 }
407 #endif
408 
arch_cpu_init(void)409 int arch_cpu_init(void)
410 {
411 	struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
412 
413 	init_aips();
414 
415 	/* Need to clear MMDC_CHx_MASK to make warm reset work. */
416 	clear_mmdc_ch_mask();
417 
418 	/*
419 	 * Disable self-bias circuit in the analog bandap.
420 	 * The self-bias circuit is used by the bandgap during startup.
421 	 * This bit should be set after the bandgap has initialized.
422 	 */
423 	init_bandgap();
424 
425 	if (!is_mx6ul() && !is_mx6ull()) {
426 		/*
427 		 * When low freq boot is enabled, ROM will not set AHB
428 		 * freq, so we need to ensure AHB freq is 132MHz in such
429 		 * scenario.
430 		 *
431 		 * To i.MX6UL, when power up, default ARM core and
432 		 * AHB rate is 396M and 132M.
433 		 */
434 		if (mxc_get_clock(MXC_ARM_CLK) == 396000000)
435 			set_ahb_rate(132000000);
436 	}
437 
438 	if (is_mx6ul()) {
439 		if (is_soc_rev(CHIP_REV_1_0) == 0) {
440 			/*
441 			 * According to the design team's requirement on
442 			 * i.MX6UL,the PMIC_STBY_REQ PAD should be configured
443 			 * as open drain 100K (0x0000b8a0).
444 			 * Only exists on TO1.0
445 			 */
446 			writel(0x0000b8a0, IOMUXC_BASE_ADDR + 0x29c);
447 		} else {
448 			/*
449 			 * From TO1.1, SNVS adds internal pull up control
450 			 * for POR_B, the register filed is GPBIT[1:0],
451 			 * after system boot up, it can be set to 2b'01
452 			 * to disable internal pull up.It can save about
453 			 * 30uA power in SNVS mode.
454 			 */
455 			writel((readl(MX6UL_SNVS_LP_BASE_ADDR + 0x10) &
456 			       (~0x1400)) | 0x400,
457 			       MX6UL_SNVS_LP_BASE_ADDR + 0x10);
458 		}
459 	}
460 
461 	if (is_mx6ull()) {
462 		/*
463 		 * GPBIT[1:0] is suggested to set to 2'b11:
464 		 * 2'b00 : always PUP100K
465 		 * 2'b01 : PUP100K when PMIC_ON_REQ or SOC_NOT_FAIL
466 		 * 2'b10 : always disable PUP100K
467 		 * 2'b11 : PDN100K when SOC_FAIL, PUP100K when SOC_NOT_FAIL
468 		 * register offset is different from i.MX6UL, since
469 		 * i.MX6UL is fixed by ECO.
470 		 */
471 		writel(readl(MX6UL_SNVS_LP_BASE_ADDR) |
472 			0x3, MX6UL_SNVS_LP_BASE_ADDR);
473 	}
474 
475 	/* Set perclk to source from OSC 24MHz */
476 	if (has_err007805())
477 		setbits_le32(&ccm->cscmr1, MXC_CCM_CSCMR1_PER_CLK_SEL_MASK);
478 
479 	imx_wdog_disable_powerdown(); /* Disable PDE bit of WMCR register */
480 
481 	if (is_mx6sx())
482 		setbits_le32(&ccm->cscdr1, MXC_CCM_CSCDR1_UART_CLK_SEL);
483 
484 	init_src();
485 
486 #if defined(CONFIG_MX6Q) || defined(CONFIG_MX6QDL)
487 	if (is_mx6dqp())
488 		noc_setup();
489 #endif
490 	return 0;
491 }
492 
493 #ifdef CONFIG_ENV_IS_IN_MMC
board_mmc_get_env_dev(int devno)494 __weak int board_mmc_get_env_dev(int devno)
495 {
496 	return CONFIG_SYS_MMC_ENV_DEV;
497 }
498 
mmc_get_boot_dev(void)499 static int mmc_get_boot_dev(void)
500 {
501 	struct src *src_regs = (struct src *)SRC_BASE_ADDR;
502 	u32 soc_sbmr = readl(&src_regs->sbmr1);
503 	u32 bootsel;
504 	int devno;
505 
506 	/*
507 	 * Refer to
508 	 * "i.MX 6Dual/6Quad Applications Processor Reference Manual"
509 	 * Chapter "8.5.3.1 Expansion Device eFUSE Configuration"
510 	 * i.MX6SL/SX/UL has same layout.
511 	 */
512 	bootsel = (soc_sbmr & 0x000000FF) >> 6;
513 
514 	/* No boot from sd/mmc */
515 	if (bootsel != 1)
516 		return -1;
517 
518 	/* BOOT_CFG2[3] and BOOT_CFG2[4] */
519 	devno = (soc_sbmr & 0x00001800) >> 11;
520 
521 	return devno;
522 }
523 
mmc_get_env_dev(void)524 int mmc_get_env_dev(void)
525 {
526 	int devno = mmc_get_boot_dev();
527 
528 	/* If not boot from sd/mmc, use default value */
529 	if (devno < 0)
530 		return CONFIG_SYS_MMC_ENV_DEV;
531 
532 	return board_mmc_get_env_dev(devno);
533 }
534 
535 #ifdef CONFIG_SYS_MMC_ENV_PART
board_mmc_get_env_part(int devno)536 __weak int board_mmc_get_env_part(int devno)
537 {
538 	return CONFIG_SYS_MMC_ENV_PART;
539 }
540 
mmc_get_env_part(struct mmc * mmc)541 uint mmc_get_env_part(struct mmc *mmc)
542 {
543 	int devno = mmc_get_boot_dev();
544 
545 	/* If not boot from sd/mmc, use default value */
546 	if (devno < 0)
547 		return CONFIG_SYS_MMC_ENV_PART;
548 
549 	return board_mmc_get_env_part(devno);
550 }
551 #endif
552 #endif
553 
board_postclk_init(void)554 int board_postclk_init(void)
555 {
556 	/* NO LDO SOC on i.MX6SLL */
557 	if (is_mx6sll())
558 		return 0;
559 
560 	set_ldo_voltage(LDO_SOC, 1175);	/* Set VDDSOC to 1.175V */
561 
562 	return 0;
563 }
564 
565 #ifndef CONFIG_SPL_BUILD
566 /*
567  * cfg_val will be used for
568  * Boot_cfg4[7:0]:Boot_cfg3[7:0]:Boot_cfg2[7:0]:Boot_cfg1[7:0]
569  * After reset, if GPR10[28] is 1, ROM will use GPR9[25:0]
570  * instead of SBMR1 to determine the boot device.
571  */
572 const struct boot_mode soc_boot_modes[] = {
573 	{"normal",	MAKE_CFGVAL(0x00, 0x00, 0x00, 0x00)},
574 	/* reserved value should start rom usb */
575 #if defined(CONFIG_MX6UL) || defined(CONFIG_MX6ULL)
576 	{"usb",		MAKE_CFGVAL(0x20, 0x00, 0x00, 0x00)},
577 #else
578 	{"usb",		MAKE_CFGVAL(0x10, 0x00, 0x00, 0x00)},
579 #endif
580 	{"sata",	MAKE_CFGVAL(0x20, 0x00, 0x00, 0x00)},
581 	{"ecspi1:0",	MAKE_CFGVAL(0x30, 0x00, 0x00, 0x08)},
582 	{"ecspi1:1",	MAKE_CFGVAL(0x30, 0x00, 0x00, 0x18)},
583 	{"ecspi1:2",	MAKE_CFGVAL(0x30, 0x00, 0x00, 0x28)},
584 	{"ecspi1:3",	MAKE_CFGVAL(0x30, 0x00, 0x00, 0x38)},
585 	/* 4 bit bus width */
586 	{"esdhc1",	MAKE_CFGVAL(0x40, 0x20, 0x00, 0x00)},
587 	{"esdhc2",	MAKE_CFGVAL(0x40, 0x28, 0x00, 0x00)},
588 	{"esdhc3",	MAKE_CFGVAL(0x40, 0x30, 0x00, 0x00)},
589 	{"esdhc4",	MAKE_CFGVAL(0x40, 0x38, 0x00, 0x00)},
590 	{NULL,		0},
591 };
592 #endif
593 
reset_misc(void)594 void reset_misc(void)
595 {
596 #ifndef CONFIG_SPL_BUILD
597 #if defined(CONFIG_VIDEO_MXS) && !defined(CONFIG_DM_VIDEO)
598 	lcdif_power_down();
599 #endif
600 #endif
601 }
602 
s_init(void)603 void s_init(void)
604 {
605 	struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
606 	struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
607 	u32 mask480;
608 	u32 mask528;
609 	u32 reg, periph1, periph2;
610 
611 	if (is_mx6sx() || is_mx6ul() || is_mx6ull() || is_mx6sll())
612 		return;
613 
614 	/* Due to hardware limitation, on MX6Q we need to gate/ungate all PFDs
615 	 * to make sure PFD is working right, otherwise, PFDs may
616 	 * not output clock after reset, MX6DL and MX6SL have added 396M pfd
617 	 * workaround in ROM code, as bus clock need it
618 	 */
619 
620 	mask480 = ANATOP_PFD_CLKGATE_MASK(0) |
621 		ANATOP_PFD_CLKGATE_MASK(1) |
622 		ANATOP_PFD_CLKGATE_MASK(2) |
623 		ANATOP_PFD_CLKGATE_MASK(3);
624 	mask528 = ANATOP_PFD_CLKGATE_MASK(1) |
625 		ANATOP_PFD_CLKGATE_MASK(3);
626 
627 	reg = readl(&ccm->cbcmr);
628 	periph2 = ((reg & MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_MASK)
629 		>> MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_OFFSET);
630 	periph1 = ((reg & MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK)
631 		>> MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_OFFSET);
632 
633 	/* Checking if PLL2 PFD0 or PLL2 PFD2 is using for periph clock */
634 	if ((periph2 != 0x2) && (periph1 != 0x2))
635 		mask528 |= ANATOP_PFD_CLKGATE_MASK(0);
636 
637 	if ((periph2 != 0x1) && (periph1 != 0x1) &&
638 		(periph2 != 0x3) && (periph1 != 0x3))
639 		mask528 |= ANATOP_PFD_CLKGATE_MASK(2);
640 
641 	writel(mask480, &anatop->pfd_480_set);
642 	writel(mask528, &anatop->pfd_528_set);
643 	writel(mask480, &anatop->pfd_480_clr);
644 	writel(mask528, &anatop->pfd_528_clr);
645 }
646 
647 #ifdef CONFIG_IMX_HDMI
imx_enable_hdmi_phy(void)648 void imx_enable_hdmi_phy(void)
649 {
650 	struct hdmi_regs *hdmi = (struct hdmi_regs *)HDMI_ARB_BASE_ADDR;
651 	u8 reg;
652 	reg = readb(&hdmi->phy_conf0);
653 	reg |= HDMI_PHY_CONF0_PDZ_MASK;
654 	writeb(reg, &hdmi->phy_conf0);
655 	udelay(3000);
656 	reg |= HDMI_PHY_CONF0_ENTMDS_MASK;
657 	writeb(reg, &hdmi->phy_conf0);
658 	udelay(3000);
659 	reg |= HDMI_PHY_CONF0_GEN2_TXPWRON_MASK;
660 	writeb(reg, &hdmi->phy_conf0);
661 	writeb(HDMI_MC_PHYRSTZ_ASSERT, &hdmi->mc_phyrstz);
662 }
663 
imx_setup_hdmi(void)664 void imx_setup_hdmi(void)
665 {
666 	struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
667 	struct hdmi_regs *hdmi  = (struct hdmi_regs *)HDMI_ARB_BASE_ADDR;
668 	int reg, count;
669 	u8 val;
670 
671 	/* Turn on HDMI PHY clock */
672 	reg = readl(&mxc_ccm->CCGR2);
673 	reg |=  MXC_CCM_CCGR2_HDMI_TX_IAHBCLK_MASK|
674 		 MXC_CCM_CCGR2_HDMI_TX_ISFRCLK_MASK;
675 	writel(reg, &mxc_ccm->CCGR2);
676 	writeb(HDMI_MC_PHYRSTZ_DEASSERT, &hdmi->mc_phyrstz);
677 	reg = readl(&mxc_ccm->chsccdr);
678 	reg &= ~(MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_MASK|
679 		 MXC_CCM_CHSCCDR_IPU1_DI0_PODF_MASK|
680 		 MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_MASK);
681 	reg |= (CHSCCDR_PODF_DIVIDE_BY_3
682 		 << MXC_CCM_CHSCCDR_IPU1_DI0_PODF_OFFSET)
683 		 |(CHSCCDR_IPU_PRE_CLK_540M_PFD
684 		 << MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_OFFSET);
685 	writel(reg, &mxc_ccm->chsccdr);
686 
687 	/* Clear the overflow condition */
688 	if (readb(&hdmi->ih_fc_stat2) & HDMI_IH_FC_STAT2_OVERFLOW_MASK) {
689 		/* TMDS software reset */
690 		writeb((u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ, &hdmi->mc_swrstz);
691 		val = readb(&hdmi->fc_invidconf);
692 		/* Need minimum 3 times to write to clear the register */
693 		for (count = 0 ; count < 5 ; count++)
694 			writeb(val, &hdmi->fc_invidconf);
695 	}
696 }
697 #endif
698 
699 #ifdef CONFIG_ARCH_MISC_INIT
700 /*
701  * UNIQUE_ID describes a unique ID based on silicon wafer
702  * and die X/Y position
703  *
704  * UNIQUE_ID offset 0x410
705  * 31:0 fuse 0
706  * FSL-wide unique, encoded LOT ID STD II/SJC CHALLENGE/ Unique ID
707  *
708  * UNIQUE_ID offset 0x420
709  * 31:24 fuse 1
710  * The X-coordinate of the die location on the wafer/SJC CHALLENGE/ Unique ID
711  * 23:16 fuse 1
712  * The Y-coordinate of the die location on the wafer/SJC CHALLENGE/ Unique ID
713  * 15:11 fuse 1
714  * The wafer number of the wafer on which the device was fabricated/SJC
715  * CHALLENGE/ Unique ID
716  * 10:0 fuse 1
717  * FSL-wide unique, encoded LOT ID STD II/SJC CHALLENGE/ Unique ID
718  */
setup_serial_number(void)719 static void setup_serial_number(void)
720 {
721 	char serial_string[17];
722 	struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
723 	struct fuse_bank *bank = &ocotp->bank[0];
724 	struct fuse_bank0_regs *fuse =
725 		(struct fuse_bank0_regs *)bank->fuse_regs;
726 
727 	if (env_get("serial#"))
728 		return;
729 
730 	snprintf(serial_string, sizeof(serial_string), "%08x%08x",
731 		 fuse->uid_low, fuse->uid_high);
732 	env_set("serial#", serial_string);
733 }
734 
arch_misc_init(void)735 int arch_misc_init(void)
736 {
737 #ifdef CONFIG_FSL_CAAM
738 	sec_init();
739 #endif
740 	setup_serial_number();
741 	return 0;
742 }
743 #endif
744 
745 /*
746  * gpr_init() function is common for boards using MX6S, MX6DL, MX6D,
747  * MX6Q and MX6QP processors
748  */
gpr_init(void)749 void gpr_init(void)
750 {
751 	struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
752 
753 	/*
754 	 * If this function is used in a common MX6 spl implementation
755 	 * we have to ensure that it is only called for suitable cpu types,
756 	 * otherwise it breaks hardware parts like enet1, can1, can2, etc.
757 	 */
758 	if (!is_mx6dqp() && !is_mx6dq() && !is_mx6sdl())
759 		return;
760 
761 	/* enable AXI cache for VDOA/VPU/IPU */
762 	writel(0xF00000CF, &iomux->gpr[4]);
763 	if (is_mx6dqp()) {
764 		/* set IPU AXI-id1 Qos=0x1 AXI-id0/2/3 Qos=0x7 */
765 		writel(0x77177717, &iomux->gpr[6]);
766 		writel(0x77177717, &iomux->gpr[7]);
767 	} else {
768 		/* set IPU AXI-id0 Qos=0xf(bypass) AXI-id1 Qos=0x7 */
769 		writel(0x007F007F, &iomux->gpr[6]);
770 		writel(0x007F007F, &iomux->gpr[7]);
771 	}
772 }
773