1 /*
2  * GE b1x5v2 - QMX6 SPL
3  *
4  * Copyright 2013, Adeneo Embedded <www.adeneo-embedded.com>
5  * Copyright 2018-2020 GE Inc.
6  * Copyright 2018-2020 Collabora Ltd.
7  *
8  * SPDX-License-Identifier:    GPL-2.0+
9  */
10 
11 #include <asm/arch/clock.h>
12 #include <asm/arch/crm_regs.h>
13 #include <asm/arch/imx-regs.h>
14 #include <asm/arch/iomux.h>
15 #include <asm/arch/mx6-pins.h>
16 #include <asm/arch/sys_proto.h>
17 #include <asm/gpio.h>
18 #include <init.h>
19 #include <spi.h>
20 #include <spi_flash.h>
21 #include <spl.h>
22 
23 #if defined(CONFIG_SPL_BUILD)
24 
25 #include <asm/arch/mx6-ddr.h>
26 
27 #define IMX6DQ_DRIVE_STRENGTH_40_OHM		0x30
28 #define IMX6DQ_DRIVE_STRENGTH_48_OHM		0x28
29 #define IMX6DQ_DRIVE_STRENGTH			IMX6DQ_DRIVE_STRENGTH_40_OHM
30 
31 #define QMX6_DDR_PKE_DISABLED			0x00000000
32 #define QMX6_DDR_ODT_60_OHM			(2 << 16)
33 #define QMX6_DDR_TYPE_DDR3			0x000c0000
34 
35 #define QMX6_DRAM_SDCKE_PULLUP_100K		0x00003000
36 #define QMX6_DRAM_SDBA2_PULLUP_NONE		0x00000000
37 
38 #define SPI_PAD_CTRL (PAD_CTL_HYS |				\
39 	PAD_CTL_SPEED_MED |		\
40 	PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST)
41 
42 #define UART_PAD_CTRL  (PAD_CTL_PUS_100K_UP |			\
43 	PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm |			\
44 	PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
45 
46 #define SPI1_CS0 IMX_GPIO_NR(3, 19)
47 #define POWEROFF IMX_GPIO_NR(4, 25)
48 
49 static iomux_v3_cfg_t const poweroff_pads[] = {
50 	IOMUX_PADS(PAD_DISP0_DAT4__GPIO4_IO25 | MUX_PAD_CTRL(NO_PAD_CTRL)),
51 };
52 
53 static iomux_v3_cfg_t const uart2_pads[] = {
54 	IOMUX_PADS(PAD_EIM_D26__UART2_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
55 	IOMUX_PADS(PAD_EIM_D27__UART2_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
56 };
57 
58 static iomux_v3_cfg_t const uart3_pads[] = {
59 	IOMUX_PADS(PAD_EIM_D24__UART3_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
60 	IOMUX_PADS(PAD_EIM_D25__UART3_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
61 };
62 
63 static iomux_v3_cfg_t const ecspi1_pads[] = {
64 	IOMUX_PADS(PAD_EIM_D16__ECSPI1_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL)),
65 	IOMUX_PADS(PAD_EIM_D17__ECSPI1_MISO | MUX_PAD_CTRL(SPI_PAD_CTRL)),
66 	IOMUX_PADS(PAD_EIM_D18__ECSPI1_MOSI | MUX_PAD_CTRL(SPI_PAD_CTRL)),
67 	IOMUX_PADS(PAD_EIM_D19__GPIO3_IO19 | MUX_PAD_CTRL(NO_PAD_CTRL)),
68 };
69 
70 static struct mx6dq_iomux_ddr_regs mx6q_ddr_ioregs = {
71 	.dram_sdclk_0 = IMX6DQ_DRIVE_STRENGTH,
72 	.dram_sdclk_1 = IMX6DQ_DRIVE_STRENGTH,
73 	.dram_cas = IMX6DQ_DRIVE_STRENGTH,
74 	.dram_ras = IMX6DQ_DRIVE_STRENGTH,
75 	.dram_reset = IMX6DQ_DRIVE_STRENGTH,
76 	.dram_sdcke0 = QMX6_DRAM_SDCKE_PULLUP_100K,
77 	.dram_sdcke1 = QMX6_DRAM_SDCKE_PULLUP_100K,
78 	.dram_sdba2 = QMX6_DRAM_SDBA2_PULLUP_NONE,
79 	.dram_sdodt0 = IMX6DQ_DRIVE_STRENGTH,
80 	.dram_sdodt1 = IMX6DQ_DRIVE_STRENGTH,
81 	.dram_sdqs0 = IMX6DQ_DRIVE_STRENGTH,
82 	.dram_sdqs1 = IMX6DQ_DRIVE_STRENGTH,
83 	.dram_sdqs2 = IMX6DQ_DRIVE_STRENGTH,
84 	.dram_sdqs3 = IMX6DQ_DRIVE_STRENGTH,
85 	.dram_sdqs4 = IMX6DQ_DRIVE_STRENGTH,
86 	.dram_sdqs5 = IMX6DQ_DRIVE_STRENGTH,
87 	.dram_sdqs6 = IMX6DQ_DRIVE_STRENGTH,
88 	.dram_sdqs7 = IMX6DQ_DRIVE_STRENGTH,
89 	.dram_dqm0 = IMX6DQ_DRIVE_STRENGTH,
90 	.dram_dqm1 = IMX6DQ_DRIVE_STRENGTH,
91 	.dram_dqm2 = IMX6DQ_DRIVE_STRENGTH,
92 	.dram_dqm3 = IMX6DQ_DRIVE_STRENGTH,
93 	.dram_dqm4 = IMX6DQ_DRIVE_STRENGTH,
94 	.dram_dqm5 = IMX6DQ_DRIVE_STRENGTH,
95 	.dram_dqm6 = IMX6DQ_DRIVE_STRENGTH,
96 	.dram_dqm7 = IMX6DQ_DRIVE_STRENGTH,
97 };
98 
99 static const struct mx6sdl_iomux_ddr_regs mx6dl_ddr_ioregs = {
100 	.dram_sdclk_0 = IMX6DQ_DRIVE_STRENGTH,
101 	.dram_sdclk_1 = IMX6DQ_DRIVE_STRENGTH,
102 	.dram_cas = IMX6DQ_DRIVE_STRENGTH,
103 	.dram_ras = IMX6DQ_DRIVE_STRENGTH,
104 	.dram_reset = IMX6DQ_DRIVE_STRENGTH,
105 	.dram_sdcke0 = QMX6_DRAM_SDCKE_PULLUP_100K,
106 	.dram_sdcke1 = QMX6_DRAM_SDCKE_PULLUP_100K,
107 	.dram_sdba2 = QMX6_DRAM_SDBA2_PULLUP_NONE,
108 	.dram_sdodt0 = IMX6DQ_DRIVE_STRENGTH,
109 	.dram_sdodt1 = IMX6DQ_DRIVE_STRENGTH,
110 	.dram_sdqs0 = IMX6DQ_DRIVE_STRENGTH,
111 	.dram_sdqs1 = IMX6DQ_DRIVE_STRENGTH,
112 	.dram_sdqs2 = IMX6DQ_DRIVE_STRENGTH,
113 	.dram_sdqs3 = IMX6DQ_DRIVE_STRENGTH,
114 	.dram_sdqs4 = IMX6DQ_DRIVE_STRENGTH,
115 	.dram_sdqs5 = IMX6DQ_DRIVE_STRENGTH,
116 	.dram_sdqs6 = IMX6DQ_DRIVE_STRENGTH,
117 	.dram_sdqs7 = IMX6DQ_DRIVE_STRENGTH,
118 	.dram_dqm0 = IMX6DQ_DRIVE_STRENGTH,
119 	.dram_dqm1 = IMX6DQ_DRIVE_STRENGTH,
120 	.dram_dqm2 = IMX6DQ_DRIVE_STRENGTH,
121 	.dram_dqm3 = IMX6DQ_DRIVE_STRENGTH,
122 	.dram_dqm4 = IMX6DQ_DRIVE_STRENGTH,
123 	.dram_dqm5 = IMX6DQ_DRIVE_STRENGTH,
124 	.dram_dqm6 = IMX6DQ_DRIVE_STRENGTH,
125 	.dram_dqm7 = IMX6DQ_DRIVE_STRENGTH,
126 };
127 
128 static struct mx6dq_iomux_grp_regs mx6q_grp_ioregs = {
129 	.grp_ddr_type = QMX6_DDR_TYPE_DDR3,
130 	.grp_ddrmode_ctl = QMX6_DDR_ODT_60_OHM,
131 	.grp_ddrpke = QMX6_DDR_PKE_DISABLED,
132 	.grp_addds = IMX6DQ_DRIVE_STRENGTH,
133 	.grp_ctlds = IMX6DQ_DRIVE_STRENGTH,
134 	.grp_ddrmode = QMX6_DDR_ODT_60_OHM,
135 	.grp_b0ds = IMX6DQ_DRIVE_STRENGTH,
136 	.grp_b1ds = IMX6DQ_DRIVE_STRENGTH,
137 	.grp_b2ds = IMX6DQ_DRIVE_STRENGTH,
138 	.grp_b3ds = IMX6DQ_DRIVE_STRENGTH,
139 	.grp_b4ds = IMX6DQ_DRIVE_STRENGTH,
140 	.grp_b5ds = IMX6DQ_DRIVE_STRENGTH,
141 	.grp_b6ds = IMX6DQ_DRIVE_STRENGTH,
142 	.grp_b7ds = IMX6DQ_DRIVE_STRENGTH,
143 };
144 
145 static const struct mx6sdl_iomux_grp_regs mx6sdl_grp_ioregs = {
146 	.grp_ddr_type = QMX6_DDR_TYPE_DDR3,
147 	.grp_ddrmode_ctl = QMX6_DDR_ODT_60_OHM,
148 	.grp_ddrpke = QMX6_DDR_PKE_DISABLED,
149 	.grp_addds = IMX6DQ_DRIVE_STRENGTH,
150 	.grp_ctlds = IMX6DQ_DRIVE_STRENGTH,
151 	.grp_ddrmode = QMX6_DDR_ODT_60_OHM,
152 	.grp_b0ds = IMX6DQ_DRIVE_STRENGTH,
153 	.grp_b1ds = IMX6DQ_DRIVE_STRENGTH,
154 	.grp_b2ds = IMX6DQ_DRIVE_STRENGTH,
155 	.grp_b3ds = IMX6DQ_DRIVE_STRENGTH,
156 	.grp_b4ds = IMX6DQ_DRIVE_STRENGTH,
157 	.grp_b5ds = IMX6DQ_DRIVE_STRENGTH,
158 	.grp_b6ds = IMX6DQ_DRIVE_STRENGTH,
159 	.grp_b7ds = IMX6DQ_DRIVE_STRENGTH,
160 };
161 
162 const struct mx6_mmdc_calibration mx6q_mmcd_calib = {
163 	.p0_mpwldectrl0 =  0x0016001A,
164 	.p0_mpwldectrl1 =  0x0023001C,
165 	.p1_mpwldectrl0 =  0x0028003A,
166 	.p1_mpwldectrl1 =  0x001F002C,
167 	.p0_mpdgctrl0 =  0x43440354,
168 	.p0_mpdgctrl1 =  0x033C033C,
169 	.p1_mpdgctrl0 =  0x43300368,
170 	.p1_mpdgctrl1 =  0x03500330,
171 	.p0_mprddlctl =  0x3228242E,
172 	.p1_mprddlctl =  0x2C2C2636,
173 	.p0_mpwrdlctl =  0x36323A38,
174 	.p1_mpwrdlctl =  0x42324440,
175 };
176 
177 const struct mx6_mmdc_calibration mx6q_2g_mmcd_calib = {
178 	.p0_mpwldectrl0 =  0x00080016,
179 	.p0_mpwldectrl1 =  0x001D0016,
180 	.p1_mpwldectrl0 =  0x0018002C,
181 	.p1_mpwldectrl1 =  0x000D001D,
182 	.p0_mpdgctrl0 =    0x43200334,
183 	.p0_mpdgctrl1 =    0x0320031C,
184 	.p1_mpdgctrl0 =    0x0344034C,
185 	.p1_mpdgctrl1 =    0x03380314,
186 	.p0_mprddlctl =    0x3E36383A,
187 	.p1_mprddlctl =    0x38363240,
188 	.p0_mpwrdlctl =	   0x36364238,
189 	.p1_mpwrdlctl =    0x4230423E,
190 };
191 
192 const struct mx6_mmdc_calibration mx6q_4g_mmcd_calib = {
193 	.p0_mpwldectrl0 =  0x00180018,
194 	.p0_mpwldectrl1 =  0x00220018,
195 	.p1_mpwldectrl0 =  0x00330046,
196 	.p1_mpwldectrl1 =  0x002B003D,
197 	.p0_mpdgctrl0 =    0x4344034C,
198 	.p0_mpdgctrl1 =    0x033C033C,
199 	.p1_mpdgctrl0 =    0x03700374,
200 	.p1_mpdgctrl1 =    0x03600338,
201 	.p0_mprddlctl =    0x443E3E40,
202 	.p1_mprddlctl =    0x423E3E48,
203 	.p0_mpwrdlctl =	   0x3C3C4442,
204 	.p1_mpwrdlctl =    0x46384C46,
205 };
206 
207 static const struct mx6_mmdc_calibration mx6s_mmcd_calib = {
208 	.p0_mpwldectrl0 =  0x00480049,
209 	.p0_mpwldectrl1 =  0x00410044,
210 	.p0_mpdgctrl0 =    0x42480248,
211 	.p0_mpdgctrl1 =    0x023C023C,
212 	.p0_mprddlctl =    0x40424644,
213 	.p0_mpwrdlctl =    0x34323034,
214 };
215 
216 static const struct mx6_mmdc_calibration mx6s_2g_mmcd_calib = {
217 	.p0_mpwldectrl0 =  0x00450048,
218 	.p0_mpwldectrl1 =  0x003B003F,
219 	.p0_mpdgctrl0 =    0x424C0248,
220 	.p0_mpdgctrl1 =    0x0234023C,
221 	.p0_mprddlctl =    0x40444848,
222 	.p0_mpwrdlctl =    0x38363232,
223 };
224 
225 static const struct mx6_mmdc_calibration mx6dl_mmcd_calib = {
226 	.p0_mpwldectrl0 =  0x0043004B,
227 	.p0_mpwldectrl1 =  0x003A003E,
228 	.p1_mpwldectrl0 =  0x0047004F,
229 	.p1_mpwldectrl1 =  0x004E0061,
230 	.p0_mpdgctrl0 =    0x42500250,
231 	.p0_mpdgctrl1 =	   0x0238023C,
232 	.p1_mpdgctrl0 =    0x42640264,
233 	.p1_mpdgctrl1 =    0x02500258,
234 	.p0_mprddlctl =    0x40424846,
235 	.p1_mprddlctl =    0x46484842,
236 	.p0_mpwrdlctl =    0x38382C30,
237 	.p1_mpwrdlctl =    0x34343430,
238 };
239 
240 static const struct mx6_mmdc_calibration mx6dl_2g_mmcd_calib = {
241 	.p0_mpwldectrl0 =  0x00450045,
242 	.p0_mpwldectrl1 =  0x00390043,
243 	.p1_mpwldectrl0 =  0x0049004D,
244 	.p1_mpwldectrl1 =  0x004E0061,
245 	.p0_mpdgctrl0 =    0x4240023C,
246 	.p0_mpdgctrl1 =	   0x0228022C,
247 	.p1_mpdgctrl0 =    0x02400244,
248 	.p1_mpdgctrl1 =    0x02340238,
249 	.p0_mprddlctl =    0x42464648,
250 	.p1_mprddlctl =    0x4446463C,
251 	.p0_mpwrdlctl =    0x3C38323A,
252 	.p1_mpwrdlctl =    0x34323430,
253 };
254 
255 static struct mx6_ddr3_cfg mem_ddr_2g = {
256 	.mem_speed = 1600,
257 	.density = 2,
258 	.width = 16,
259 	.banks = 8,
260 	.rowaddr = 14,
261 	.coladdr = 10,
262 	.pagesz = 2,
263 	.trcd = 1310,
264 	.trcmin = 4875,
265 	.trasmin = 3500,
266 };
267 
268 static struct mx6_ddr3_cfg mem_ddr_4g = {
269 	.mem_speed = 1600,
270 	.density = 4,
271 	.width = 16,
272 	.banks = 8,
273 	.rowaddr = 15,
274 	.coladdr = 10,
275 	.pagesz = 2,
276 	.trcd = 1310,
277 	.trcmin = 4875,
278 	.trasmin = 3500,
279 };
280 
281 static struct mx6_ddr3_cfg mem_ddr_8g = {
282 	.mem_speed = 1600,
283 	.density = 8,
284 	.width = 16,
285 	.banks = 8,
286 	.rowaddr = 16,
287 	.coladdr = 10,
288 	.pagesz = 2,
289 	.trcd = 1310,
290 	.trcmin = 4875,
291 	.trasmin = 3500,
292 };
293 
spl_dram_init(u8 width,u32 memsize)294 static void spl_dram_init(u8 width, u32 memsize) {
295 	struct mx6_ddr_sysinfo sysinfo = {
296 		 /* width of data bus: 0=16, 1=32, 2=64 */
297 		.dsize		= width / 32,
298 		/* config for full 4GB range so that get_mem_size() works */
299 		.cs_density	= 32,	/* 32Gb per CS */
300 
301 		.ncs = 1,
302 		.cs1_mirror = 0,
303 		.rtt_wr = 2,
304 		.rtt_nom = 2,
305 		.walat = 0,
306 		.ralat = 5,
307 		.mif3_mode = 3,
308 		.bi_on = 1,
309 		.sde_to_rst = 0x0d,
310 		.rst_to_cke = 0x20,
311 	};
312 
313 	if (is_cpu_type(MXC_CPU_MX6SOLO)) {
314 		sysinfo.walat = 1;
315 		mx6sdl_dram_iocfg(width, &mx6dl_ddr_ioregs, &mx6sdl_grp_ioregs);
316 
317 		switch(memsize) {
318 		case 512:
319 			mx6_dram_cfg(&sysinfo, &mx6s_2g_mmcd_calib, &mem_ddr_2g);
320 			break;
321 		default:
322 			mx6_dram_cfg(&sysinfo, &mx6s_mmcd_calib, &mem_ddr_4g);
323 			break;
324 		}
325 	} else if (is_cpu_type(MXC_CPU_MX6DL)) {
326 		sysinfo.walat = 1;
327 		mx6sdl_dram_iocfg(width, &mx6dl_ddr_ioregs, &mx6sdl_grp_ioregs);
328 
329 		switch(memsize) {
330 		case 2048:
331 			mx6_dram_cfg(&sysinfo, &mx6dl_2g_mmcd_calib, &mem_ddr_4g);
332 			break;
333 		default:
334 			mx6_dram_cfg(&sysinfo, &mx6dl_mmcd_calib, &mem_ddr_2g);
335 			break;
336 		}
337 	} else if (is_cpu_type(MXC_CPU_MX6Q)) {
338 		mx6dq_dram_iocfg(width, &mx6q_ddr_ioregs, &mx6q_grp_ioregs);
339 
340 		switch(memsize) {
341 		case 4096:
342 			sysinfo.cs_density = 16;
343 			sysinfo.ncs = 2;
344 			mx6_dram_cfg(&sysinfo, &mx6q_4g_mmcd_calib, &mem_ddr_8g);
345 			break;
346 		case 2048:
347 			mx6_dram_cfg(&sysinfo, &mx6q_2g_mmcd_calib, &mem_ddr_4g);
348 			break;
349 		default:
350 			mx6_dram_cfg(&sysinfo, &mx6q_mmcd_calib, &mem_ddr_2g);
351 			break;
352 		}
353 	}
354 }
355 
356 /* Define a minimal structure so that the part number can be read via SPL */
357 #define CFG_MFG_ADDR_OFFSET	(spi->size - SZ_16K)
358 struct mfgdata {
359 	unsigned char tsize;
360 	/* size of checksummed part in bytes */
361 	unsigned char ckcnt;
362 	/* checksum corrected byte */
363 	unsigned char cksum;
364 	/* decimal serial number, packed BCD */
365 	unsigned char serial[6];
366 	 /* part number, right justified, ASCII */
367 	unsigned char pn[16];
368 };
369 
conv_ascii(unsigned char * dst,unsigned char * src,int len)370 static void conv_ascii(unsigned char *dst, unsigned char *src, int len)
371 {
372 	int remain = len;
373 	unsigned char *sptr = src;
374 	unsigned char *dptr = dst;
375 
376 	while (remain) {
377 		if (*sptr) {
378 			*dptr = *sptr;
379 			dptr++;
380 		}
381 		sptr++;
382 		remain--;
383 	}
384 	*dptr = 0x0;
385 }
386 
387 /*
388  * Returns the total size of the memory [in MB] the board is equipped with
389  *
390  * This is determined via the partnumber which is stored in the
391  * congatec manufacturing area
392  */
get_boardmem_size(struct spi_flash * spi)393 static int get_boardmem_size(struct spi_flash *spi)
394 {
395 	int ret;
396 	int i;
397 	int arraysize;
398 	char buf[sizeof(struct mfgdata)];
399 	struct mfgdata *data = (struct mfgdata *)buf;
400 	unsigned char outbuf[32];
401 	char partnumbers_2g[4][7] = { "016104", "016105", "016304", "016305" };
402 	char partnumbers_4g[2][7] = { "016308", "016318" };
403 	char partnumbers_512m[2][7] = { "016203", "616300" };
404 
405 	ret = spi_flash_read(spi, CFG_MFG_ADDR_OFFSET, sizeof(struct mfgdata),
406 			     buf);
407 	if (ret)
408 		return 1024; /* default to 1GByte in case of error */
409 
410 	conv_ascii(outbuf, data->pn, sizeof(data->pn));
411 
412 	printf("Detected Congatec QMX6 SOM: %s\n", outbuf);
413 
414 	/* congatec PN 016104, 016105, 016304, 016305 have 2GiB of RAM */
415 	arraysize = sizeof(partnumbers_2g) / sizeof(partnumbers_2g[0]);
416 	for (i=0; i < arraysize; i++) {
417 		if (!memcmp(outbuf,partnumbers_2g[i],6))
418 			return 2048;
419 	}
420 
421 	/* congatec PN 016308, 016318 have 4GiB of RAM */
422 	arraysize = sizeof(partnumbers_4g) / sizeof(partnumbers_4g[0]);
423 	for (i=0; i < arraysize; i++) {
424 		if (!memcmp(outbuf,partnumbers_4g[i],6))
425 			return 4096;
426 	}
427 
428 	/* congatec PN 016203, 616300 has 512MiB of RAM */
429 	arraysize = sizeof(partnumbers_512m) / sizeof(partnumbers_512m[0]);
430 	for (i=0; i < arraysize; i++) {
431 		if (!memcmp(outbuf,partnumbers_512m[i],6))
432 			return 512;
433 	}
434 
435 	/* default to 1GByte */
436 	return 1024;
437 }
438 
reset_cpu(void)439 void reset_cpu(void)
440 {
441 }
442 
board_spi_cs_gpio(unsigned bus,unsigned cs)443 int board_spi_cs_gpio(unsigned bus, unsigned cs)
444 {
445 	if (bus == 0 && cs == 0)
446 		return (SPI1_CS0);
447 	else
448 		return -1;
449 }
450 
memory_init(void)451 static void memory_init(void) {
452 	struct spi_flash *spi;
453 	u8 width;
454 	u32 size;
455 
456 	SETUP_IOMUX_PADS(ecspi1_pads);
457 	gpio_direction_output(SPI1_CS0, 0);
458 
459 	spi = spi_flash_probe(CONFIG_ENV_SPI_BUS,
460 			      CONFIG_ENV_SPI_CS,
461 			      CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE);
462 	if (!spi)
463 		panic("Cannot identify board type: SPI-NOR flash module not detected\n");
464 
465 	/* lock manufacturer area */
466 	spi_flash_protect(spi, CFG_MFG_ADDR_OFFSET, SZ_16K, true);
467 
468 	width = is_cpu_type(MXC_CPU_MX6SOLO) ? 32 : 64;
469 	size = get_boardmem_size(spi);
470 	printf("Detected Memory Size: %u\n", size);
471 
472 	spl_dram_init(width, size);
473 }
474 
ccgr_init(void)475 static void ccgr_init(void)
476 {
477 	struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
478 
479 	static const uint32_t ccgr0 =
480 		MXC_CCM_CCGR0_AIPS_TZ1_MASK |
481 		MXC_CCM_CCGR0_AIPS_TZ2_MASK |
482 		MXC_CCM_CCGR0_APBHDMA_MASK |
483 		MXC_CCM_CCGR0_CAAM_SECURE_MEM_MASK |
484 		MXC_CCM_CCGR0_CAAM_WRAPPER_ACLK_MASK |
485 		MXC_CCM_CCGR0_CAAM_WRAPPER_IPG_MASK |
486 		MXC_CCM_CCGR0_CHEETAH_DBG_CLK_MASK;
487 
488 	static const uint32_t ccgr1 =
489 		MXC_CCM_CCGR1_ECSPI1S_MASK |
490 		MXC_CCM_CCGR1_ENET_MASK |
491 		MXC_CCM_CCGR1_EPIT1S_MASK |
492 		MXC_CCM_CCGR1_EPIT2S_MASK |
493 		MXC_CCM_CCGR1_GPT_BUS_MASK;
494 
495 	static const uint32_t ccgr2 =
496 		MXC_CCM_CCGR2_IOMUX_IPT_CLK_IO_MASK |
497 		MXC_CCM_CCGR2_IPMUX1_MASK |
498 		MXC_CCM_CCGR2_IPMUX2_MASK |
499 		MXC_CCM_CCGR2_IPMUX3_MASK |
500 		MXC_CCM_CCGR2_IPSYNC_IP2APB_TZASC1_IPGS_MASK |
501 		MXC_CCM_CCGR2_IPSYNC_IP2APB_TZASC2_IPG_MASK |
502 		MXC_CCM_CCGR2_IPSYNC_VDOA_IPG_MASTER_CLK_MASK;
503 
504 	static const uint32_t ccgr3 =
505 		MXC_CCM_CCGR3_MMDC_CORE_ACLK_FAST_CORE_P0_MASK |
506 		MXC_CCM_CCGR3_MMDC_CORE_ACLK_FAST_CORE_P1_MASK |
507 		MXC_CCM_CCGR3_MMDC_CORE_IPG_CLK_P0_MASK |
508 		MXC_CCM_CCGR3_MMDC_CORE_IPG_CLK_P1_MASK |
509 		MXC_CCM_CCGR3_OCRAM_MASK;
510 
511 	static const uint32_t ccgr4 =
512 		MXC_CCM_CCGR4_PL301_MX6QFAST1_S133_MASK |
513 		MXC_CCM_CCGR4_PL301_MX6QPER1_BCH_MASK |
514 		MXC_CCM_CCGR4_PL301_MX6QPER2_MAINCLK_ENABLE_MASK |
515 		MXC_CCM_CCGR4_PWM1_MASK |
516 		MXC_CCM_CCGR4_PWM2_MASK |
517 		MXC_CCM_CCGR4_PWM3_MASK |
518 		MXC_CCM_CCGR4_PWM4_MASK;
519 
520 	static const uint32_t ccgr5 =
521 		MXC_CCM_CCGR5_ROM_MASK |
522 		MXC_CCM_CCGR5_SDMA_MASK |
523 		MXC_CCM_CCGR5_UART_MASK |
524 		MXC_CCM_CCGR5_UART_SERIAL_MASK;
525 
526 	static const uint32_t ccgr6 =
527 		MXC_CCM_CCGR6_USBOH3_MASK |
528 		MXC_CCM_CCGR6_USDHC1_MASK |
529 		MXC_CCM_CCGR6_USDHC2_MASK |
530 		MXC_CCM_CCGR6_SIM1_CLK_MASK |
531 		MXC_CCM_CCGR6_SIM2_CLK_MASK;
532 
533 	writel(ccgr0, &ccm->CCGR0);
534 	writel(ccgr1, &ccm->CCGR1);
535 	writel(ccgr2, &ccm->CCGR2);
536 	writel(ccgr3, &ccm->CCGR3);
537 	writel(ccgr4, &ccm->CCGR4);
538 	writel(ccgr5, &ccm->CCGR5);
539 	writel(ccgr6, &ccm->CCGR6);
540 }
541 
board_init_f(ulong dummy)542 void board_init_f(ulong dummy)
543 {
544 	/* setup clock gating */
545 	ccgr_init();
546 
547 	/* setup AIPS and disable watchdog */
548 	arch_cpu_init();
549 
550 	/* setup AXI */
551 	gpr_init();
552 
553 	/*
554 	 * setup poweroff GPIO. This controls system power regulator. Once
555 	 * the power button is released this must be enabled to keep system
556 	 * running. Not enabling it (or disabling it later) will turn off
557 	 * the main system regulator and instantly poweroff the system. We
558 	 * do this very early, to reduce the time users have to press the
559 	 * power button.
560 	 */
561 	SETUP_IOMUX_PADS(poweroff_pads);
562 	gpio_direction_output(POWEROFF, 1);
563 
564 	/* setup GP timer */
565 	timer_init();
566 
567 	/* iomux */
568 	if (CONFIG_MXC_UART_BASE == UART2_BASE)
569 		SETUP_IOMUX_PADS(uart2_pads);
570 	else if (CONFIG_MXC_UART_BASE == UART3_BASE)
571 		SETUP_IOMUX_PADS(uart3_pads);
572 
573 	/* UART clocks enabled and gd valid - init serial console */
574 	preloader_console_init();
575 
576 	/* Needed for malloc() [used by SPI] to work in SPL prior to board_init_r() */
577 	spl_init();
578 
579 	/* DDR initialization */
580 	memory_init();
581 }
582 
spl_board_prepare_for_boot(void)583 void spl_board_prepare_for_boot(void)
584 {
585 	printf("Load normal U-Boot...\n");
586 }
587 #endif
588