1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2015 Freescale Semiconductor, Inc.
4  *
5  * Author: Fabio Estevam <fabio.estevam@freescale.com>
6  *
7  * Copyright (C) 2013 Jon Nettleton <jon.nettleton@gmail.com>
8  *
9  * Based on SPL code from Solidrun tree, which is:
10  * Author: Tungyi Lin <tungyilin1127@gmail.com>
11  *
12  * Derived from EDM_CF_IMX6 code by TechNexion,Inc
13  * Ported to SolidRun microSOM by Rabeeh Khoury <rabeeh@solid-run.com>
14  */
15 
16 #include <common.h>
17 #include <image.h>
18 #include <init.h>
19 #include <log.h>
20 #include <asm/arch/clock.h>
21 #include <asm/arch/imx-regs.h>
22 #include <asm/arch/iomux.h>
23 #include <asm/arch/mx6-pins.h>
24 #include <asm/arch/mxc_hdmi.h>
25 #include <env.h>
26 #include <asm/global_data.h>
27 #include <linux/delay.h>
28 #include <linux/errno.h>
29 #include <asm/gpio.h>
30 #include <asm/mach-imx/iomux-v3.h>
31 #include <asm/mach-imx/sata.h>
32 #include <asm/mach-imx/video.h>
33 #include <mmc.h>
34 #include <fsl_esdhc_imx.h>
35 #include <malloc.h>
36 #include <asm/arch/crm_regs.h>
37 #include <asm/io.h>
38 #include <asm/arch/sys_proto.h>
39 #include <spl.h>
40 #include <usb.h>
41 #include <usb/ehci-ci.h>
42 
43 DECLARE_GLOBAL_DATA_PTR;
44 
45 #define UART_PAD_CTRL  (PAD_CTL_PUS_100K_UP |			\
46 	PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm |			\
47 	PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
48 
49 #define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP |			\
50 	PAD_CTL_SPEED_LOW | PAD_CTL_DSE_80ohm |			\
51 	PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
52 
53 #define USB_H1_VBUS	IMX_GPIO_NR(1, 0)
54 
55 enum board_type {
56 	CUBOXI          = 0x00,
57 	HUMMINGBOARD    = 0x01,
58 	HUMMINGBOARD2   = 0x02,
59 	UNKNOWN         = 0x03,
60 };
61 
62 static struct gpio_desc board_detect_desc[5];
63 
64 #define MEM_STRIDE 0x4000000
get_ram_size_stride_test(u32 * base,u32 maxsize)65 static u32 get_ram_size_stride_test(u32 *base, u32 maxsize)
66 {
67         volatile u32 *addr;
68         u32          save[64];
69         u32          cnt;
70         u32          size;
71         int          i = 0;
72 
73         /* First save the data */
74         for (cnt = 0; cnt < maxsize; cnt += MEM_STRIDE) {
75                 addr = (volatile u32 *)((u32)base + cnt);       /* pointer arith! */
76                 sync ();
77                 save[i++] = *addr;
78                 sync ();
79         }
80 
81         /* First write a signature */
82         * (volatile u32 *)base = 0x12345678;
83         for (size = MEM_STRIDE; size < maxsize; size += MEM_STRIDE) {
84                 * (volatile u32 *)((u32)base + size) = size;
85                 sync ();
86                 if (* (volatile u32 *)((u32)base) == size) {	/* We reached the overlapping address */
87                         break;
88                 }
89         }
90 
91         /* Restore the data */
92         for (cnt = (maxsize - MEM_STRIDE); i > 0; cnt -= MEM_STRIDE) {
93                 addr = (volatile u32 *)((u32)base + cnt);       /* pointer arith! */
94                 sync ();
95                 *addr = save[i--];
96                 sync ();
97         }
98 
99         return (size);
100 }
101 
dram_init(void)102 int dram_init(void)
103 {
104 	u32 max_size = imx_ddr_size();
105 
106 	gd->ram_size = get_ram_size_stride_test((u32 *) CONFIG_SYS_SDRAM_BASE,
107 						(u32)max_size);
108 
109 	return 0;
110 }
111 
112 static iomux_v3_cfg_t const uart1_pads[] = {
113 	IOMUX_PADS(PAD_CSI0_DAT10__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
114 	IOMUX_PADS(PAD_CSI0_DAT11__UART1_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
115 };
116 
117 static iomux_v3_cfg_t const usdhc2_pads[] = {
118 	IOMUX_PADS(PAD_SD2_CLK__SD2_CLK	| MUX_PAD_CTRL(USDHC_PAD_CTRL)),
119 	IOMUX_PADS(PAD_SD2_CMD__SD2_CMD	| MUX_PAD_CTRL(USDHC_PAD_CTRL)),
120 	IOMUX_PADS(PAD_SD2_DAT0__SD2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
121 	IOMUX_PADS(PAD_SD2_DAT1__SD2_DATA1	| MUX_PAD_CTRL(USDHC_PAD_CTRL)),
122 	IOMUX_PADS(PAD_SD2_DAT2__SD2_DATA2	| MUX_PAD_CTRL(USDHC_PAD_CTRL)),
123 	IOMUX_PADS(PAD_SD2_DAT3__SD2_DATA3	| MUX_PAD_CTRL(USDHC_PAD_CTRL)),
124 };
125 
126 static iomux_v3_cfg_t const usdhc3_pads[] = {
127 	IOMUX_PADS(PAD_SD3_CLK__SD3_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
128 	IOMUX_PADS(PAD_SD3_CMD__SD3_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
129 	IOMUX_PADS(PAD_SD3_DAT0__SD3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
130 	IOMUX_PADS(PAD_SD3_DAT1__SD3_DATA1      | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
131 	IOMUX_PADS(PAD_SD3_DAT2__SD3_DATA2      | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
132 	IOMUX_PADS(PAD_SD3_DAT3__SD3_DATA3      | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
133 	IOMUX_PADS(PAD_SD3_DAT4__SD3_DATA4      | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
134 	IOMUX_PADS(PAD_SD3_DAT5__SD3_DATA5      | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
135 	IOMUX_PADS(PAD_SD3_DAT6__SD3_DATA6      | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
136 	IOMUX_PADS(PAD_SD3_DAT7__SD3_DATA7      | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
137 	IOMUX_PADS(PAD_SD3_RST__SD3_RESET       | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
138 };
139 
140 static iomux_v3_cfg_t const board_detect[] = {
141 	/* These pins are for sensing if it is a CuBox-i or a HummingBoard */
142 	IOMUX_PADS(PAD_KEY_ROW1__GPIO4_IO09  | MUX_PAD_CTRL(UART_PAD_CTRL)),
143 	IOMUX_PADS(PAD_EIM_DA4__GPIO3_IO04   | MUX_PAD_CTRL(UART_PAD_CTRL)),
144 	IOMUX_PADS(PAD_SD4_DAT0__GPIO2_IO08  | MUX_PAD_CTRL(UART_PAD_CTRL)),
145 };
146 
147 static iomux_v3_cfg_t const som_rev_detect[] = {
148 	/* These pins are for sensing if it is a CuBox-i or a HummingBoard */
149 	IOMUX_PADS(PAD_CSI0_DAT14__GPIO6_IO00  | MUX_PAD_CTRL(UART_PAD_CTRL)),
150 	IOMUX_PADS(PAD_CSI0_DAT18__GPIO6_IO04  | MUX_PAD_CTRL(UART_PAD_CTRL)),
151 };
152 
setup_iomux_uart(void)153 static void setup_iomux_uart(void)
154 {
155 	SETUP_IOMUX_PADS(uart1_pads);
156 }
157 
board_mmc_get_env_dev(int devno)158 int board_mmc_get_env_dev(int devno)
159 {
160 	return devno;
161 }
162 
163 #ifdef CONFIG_VIDEO_IPUV3
do_enable_hdmi(struct display_info_t const * dev)164 static void do_enable_hdmi(struct display_info_t const *dev)
165 {
166 	imx_enable_hdmi_phy();
167 }
168 
169 struct display_info_t const displays[] = {
170 	{
171 		.bus	= -1,
172 		.addr	= 0,
173 		.pixfmt	= IPU_PIX_FMT_RGB24,
174 		.detect	= detect_hdmi,
175 		.enable	= do_enable_hdmi,
176 		.mode	= {
177 			.name           = "HDMI",
178 			/* 1024x768@60Hz (VESA)*/
179 			.refresh        = 60,
180 			.xres           = 1024,
181 			.yres           = 768,
182 			.pixclock       = 15384,
183 			.left_margin    = 160,
184 			.right_margin   = 24,
185 			.upper_margin   = 29,
186 			.lower_margin   = 3,
187 			.hsync_len      = 136,
188 			.vsync_len      = 6,
189 			.sync           = FB_SYNC_EXT,
190 			.vmode          = FB_VMODE_NONINTERLACED
191 		}
192 	}
193 };
194 
195 size_t display_count = ARRAY_SIZE(displays);
196 
setup_display(void)197 static int setup_display(void)
198 {
199 	struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
200 	int reg;
201 	int timeout = 100000;
202 
203 	enable_ipu_clock();
204 	imx_setup_hdmi();
205 
206 	/* set video pll to 455MHz (24MHz * (37+11/12) / 2) */
207 	setbits_le32(&ccm->analog_pll_video, BM_ANADIG_PLL_VIDEO_POWERDOWN);
208 
209 	reg = readl(&ccm->analog_pll_video);
210 	reg &= ~BM_ANADIG_PLL_VIDEO_DIV_SELECT;
211 	reg |= BF_ANADIG_PLL_VIDEO_DIV_SELECT(37);
212 	reg &= ~BM_ANADIG_PLL_VIDEO_POST_DIV_SELECT;
213 	reg |= BF_ANADIG_PLL_VIDEO_POST_DIV_SELECT(1);
214 	writel(reg, &ccm->analog_pll_video);
215 
216 	writel(BF_ANADIG_PLL_VIDEO_NUM_A(11), &ccm->analog_pll_video_num);
217 	writel(BF_ANADIG_PLL_VIDEO_DENOM_B(12), &ccm->analog_pll_video_denom);
218 
219 	reg &= ~BM_ANADIG_PLL_VIDEO_POWERDOWN;
220 	writel(reg, &ccm->analog_pll_video);
221 
222 	while (timeout--)
223 		if (readl(&ccm->analog_pll_video) & BM_ANADIG_PLL_VIDEO_LOCK)
224 			break;
225 	if (timeout < 0) {
226 		printf("Warning: video pll lock timeout!\n");
227 		return -ETIMEDOUT;
228 	}
229 
230 	reg = readl(&ccm->analog_pll_video);
231 	reg |= BM_ANADIG_PLL_VIDEO_ENABLE;
232 	reg &= ~BM_ANADIG_PLL_VIDEO_BYPASS;
233 	writel(reg, &ccm->analog_pll_video);
234 
235 	/* gate ipu1_di0_clk */
236 	clrbits_le32(&ccm->CCGR3, MXC_CCM_CCGR3_LDB_DI0_MASK);
237 
238 	/* select video_pll clock / 7  for ipu1_di0_clk -> 65MHz pixclock */
239 	reg = readl(&ccm->chsccdr);
240 	reg &= ~(MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_MASK |
241 		 MXC_CCM_CHSCCDR_IPU1_DI0_PODF_MASK |
242 		 MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_MASK);
243 	reg |= (2 << MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_OFFSET) |
244 	       (6 << MXC_CCM_CHSCCDR_IPU1_DI0_PODF_OFFSET) |
245 	       (0 << MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET);
246 	writel(reg, &ccm->chsccdr);
247 
248 	/* enable ipu1_di0_clk */
249 	setbits_le32(&ccm->CCGR3, MXC_CCM_CCGR3_LDB_DI0_MASK);
250 
251 	return 0;
252 }
253 #endif /* CONFIG_VIDEO_IPUV3 */
254 
setup_fec(void)255 static int setup_fec(void)
256 {
257 	struct iomuxc *const iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
258 	int ret;
259 
260 	ret = enable_fec_anatop_clock(0, ENET_25MHZ);
261 	if (ret)
262 		return ret;
263 
264 	/* set gpr1[ENET_CLK_SEL] */
265 	setbits_le32(&iomuxc_regs->gpr[1], IOMUXC_GPR1_ENET_CLK_SEL_MASK);
266 
267 	return 0;
268 }
269 
board_early_init_f(void)270 int board_early_init_f(void)
271 {
272 	setup_iomux_uart();
273 
274 #ifdef CONFIG_CMD_SATA
275 	setup_sata();
276 #endif
277 	setup_fec();
278 
279 	return 0;
280 }
281 
board_init(void)282 int board_init(void)
283 {
284 	int ret = 0;
285 
286 	/* address of boot parameters */
287 	gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
288 
289 #ifdef CONFIG_VIDEO_IPUV3
290 	ret = setup_display();
291 #endif
292 
293 	return ret;
294 }
295 
request_detect_gpios(void)296 static int request_detect_gpios(void)
297 {
298 	int node;
299 	int ret;
300 
301 	node = fdt_node_offset_by_compatible(gd->fdt_blob, 0,
302 		"solidrun,hummingboard-detect");
303 	if (node < 0)
304 		return -ENODEV;
305 
306 	ret = gpio_request_list_by_name_nodev(offset_to_ofnode(node),
307 		"detect-gpios", board_detect_desc,
308 		ARRAY_SIZE(board_detect_desc), GPIOD_IS_IN);
309 
310 	return ret;
311 }
312 
free_detect_gpios(void)313 static int free_detect_gpios(void)
314 {
315 	return gpio_free_list_nodev(board_detect_desc,
316 		ARRAY_SIZE(board_detect_desc));
317 }
318 
board_type(void)319 static enum board_type board_type(void)
320 {
321 	int val1, val2, val3;
322 
323 	SETUP_IOMUX_PADS(board_detect);
324 
325 	/*
326 	 * Machine selection -
327 	 * Machine      val1, val2, val3
328 	 * ----------------------------
329 	 * HB2            x     x    0
330 	 * HB rev 3.x     x     0    x
331 	 * CBi            0     1    x
332 	 * HB             1     1    x
333 	 */
334 
335 	gpio_direction_input(IMX_GPIO_NR(2, 8));
336 	val3 = gpio_get_value(IMX_GPIO_NR(2, 8));
337 
338 	if (val3 == 0)
339 		return HUMMINGBOARD2;
340 
341 	gpio_direction_input(IMX_GPIO_NR(3, 4));
342 	val2 = gpio_get_value(IMX_GPIO_NR(3, 4));
343 
344 	if (val2 == 0)
345 		return HUMMINGBOARD;
346 
347 	gpio_direction_input(IMX_GPIO_NR(4, 9));
348 	val1 = gpio_get_value(IMX_GPIO_NR(4, 9));
349 
350 	if (val1 == 0) {
351 		return CUBOXI;
352 	} else {
353 		return HUMMINGBOARD;
354 	}
355 }
356 
is_rev_15_som(void)357 static bool is_rev_15_som(void)
358 {
359 	int val1, val2;
360 	SETUP_IOMUX_PADS(som_rev_detect);
361 
362 	val1 = gpio_get_value(IMX_GPIO_NR(6, 0));
363 	val2 = gpio_get_value(IMX_GPIO_NR(6, 4));
364 
365 	if (val1 == 1 && val2 == 0)
366 		return true;
367 
368 	return false;
369 }
370 
has_emmc(void)371 static bool has_emmc(void)
372 {
373 	struct mmc *mmc;
374 	mmc = find_mmc_device(2);
375 	if (!mmc)
376 		return 0;
377 	return (mmc_get_op_cond(mmc) < 0) ? 0 : 1;
378 }
379 
checkboard(void)380 int checkboard(void)
381 {
382 	request_detect_gpios();
383 
384 	switch (board_type()) {
385 	case CUBOXI:
386 		puts("Board: MX6 Cubox-i");
387 		break;
388 	case HUMMINGBOARD:
389 		puts("Board: MX6 HummingBoard");
390 		break;
391 	case HUMMINGBOARD2:
392 		puts("Board: MX6 HummingBoard2");
393 		break;
394 	case UNKNOWN:
395 	default:
396 		puts("Board: Unknown\n");
397 		goto out;
398 	}
399 
400 	if (is_rev_15_som())
401 		puts(" (som rev 1.5)\n");
402 	else
403 		puts("\n");
404 
405 	free_detect_gpios();
406 out:
407 	return 0;
408 }
409 
410 /* Override the default implementation, DT model is not accurate */
show_board_info(void)411 int show_board_info(void)
412 {
413 	return checkboard();
414 }
415 
board_late_init(void)416 int board_late_init(void)
417 {
418 #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
419 	request_detect_gpios();
420 
421 	switch (board_type()) {
422 	case CUBOXI:
423 		env_set("board_name", "CUBOXI");
424 		break;
425 	case HUMMINGBOARD:
426 		env_set("board_name", "HUMMINGBOARD");
427 		break;
428 	case HUMMINGBOARD2:
429 		env_set("board_name", "HUMMINGBOARD2");
430 		break;
431 	case UNKNOWN:
432 	default:
433 		env_set("board_name", "CUBOXI");
434 	}
435 
436 	if (is_mx6dq())
437 		env_set("board_rev", "MX6Q");
438 	else
439 		env_set("board_rev", "MX6DL");
440 
441 	if (is_rev_15_som())
442 		env_set("som_rev", "V15");
443 
444 	if (has_emmc())
445 		env_set("has_emmc", "yes");
446 
447 	free_detect_gpios();
448 #endif
449 
450 	return 0;
451 }
452 
453 /*
454  * This is not a perfect match. Avoid dependency on the DM GPIO driver needed
455  * for accurate board detection. Hummingboard2 DT is good enough for U-Boot on
456  * all Hummingboard/Cubox-i platforms.
457  */
board_fit_config_name_match(const char * name)458 int board_fit_config_name_match(const char *name)
459 {
460 	char tmp_name[36];
461 
462 	snprintf(tmp_name, sizeof(tmp_name), "%s-hummingboard2-emmc-som-v15",
463 			is_mx6dq() ? "imx6q" : "imx6dl");
464 
465 	return strcmp(name, tmp_name);
466 }
467 
board_boot_order(u32 * spl_boot_list)468 void board_boot_order(u32 *spl_boot_list)
469 {
470 	struct src *psrc = (struct src *)SRC_BASE_ADDR;
471 	unsigned int reg = readl(&psrc->sbmr1) >> 11;
472 	u32 boot_mode = imx6_src_get_boot_mode() & IMX6_BMODE_MASK;
473 	unsigned int bmode = readl(&src_base->sbmr2);
474 
475 	/* If bmode is serial or USB phy is active, return serial */
476 	if (((bmode >> 24) & 0x03) == 0x01 || is_usbotg_phy_active()) {
477 		spl_boot_list[0] = BOOT_DEVICE_BOARD;
478 		return;
479 	}
480 
481 	switch (boot_mode >> IMX6_BMODE_SHIFT) {
482 	case IMX6_BMODE_SD:
483 	case IMX6_BMODE_ESD:
484 	case IMX6_BMODE_MMC:
485 	case IMX6_BMODE_EMMC:
486 		/*
487 		 * Upon reading BOOT_CFG register the following map is done:
488 		 * Bit 11 and 12 of BOOT_CFG register can determine the current
489 		 * mmc port
490 		 * 0x1                  SD2
491 		 * 0x2                  SD3
492 		 */
493 
494 		reg &= 0x3; /* Only care about bottom 2 bits */
495 		switch (reg) {
496 		case 1:
497 			SETUP_IOMUX_PADS(usdhc2_pads);
498 			spl_boot_list[0] = BOOT_DEVICE_MMC1;
499 			break;
500 		case 2:
501 			SETUP_IOMUX_PADS(usdhc3_pads);
502 			spl_boot_list[0] = BOOT_DEVICE_MMC2;
503 			break;
504 		}
505 		break;
506 	default:
507 		/* By default use USB downloader */
508 		spl_boot_list[0] = BOOT_DEVICE_BOARD;
509 		break;
510 	}
511 
512 	/* As a last resort, use serial downloader */
513 	spl_boot_list[1] = BOOT_DEVICE_BOARD;
514 }
515 
516 #ifdef CONFIG_SPL_BUILD
517 #include <asm/arch/mx6-ddr.h>
518 static const struct mx6dq_iomux_ddr_regs mx6q_ddr_ioregs = {
519 	.dram_sdclk_0 =  0x00020030,
520 	.dram_sdclk_1 =  0x00020030,
521 	.dram_cas =  0x00020030,
522 	.dram_ras =  0x00020030,
523 	.dram_reset =  0x000c0030,
524 	.dram_sdcke0 =  0x00003000,
525 	.dram_sdcke1 =  0x00003000,
526 	.dram_sdba2 =  0x00000000,
527 	.dram_sdodt0 =  0x00003030,
528 	.dram_sdodt1 =  0x00003030,
529 	.dram_sdqs0 =  0x00000030,
530 	.dram_sdqs1 =  0x00000030,
531 	.dram_sdqs2 =  0x00000030,
532 	.dram_sdqs3 =  0x00000030,
533 	.dram_sdqs4 =  0x00000030,
534 	.dram_sdqs5 =  0x00000030,
535 	.dram_sdqs6 =  0x00000030,
536 	.dram_sdqs7 =  0x00000030,
537 	.dram_dqm0 =  0x00020030,
538 	.dram_dqm1 =  0x00020030,
539 	.dram_dqm2 =  0x00020030,
540 	.dram_dqm3 =  0x00020030,
541 	.dram_dqm4 =  0x00020030,
542 	.dram_dqm5 =  0x00020030,
543 	.dram_dqm6 =  0x00020030,
544 	.dram_dqm7 =  0x00020030,
545 };
546 
547 static const struct mx6sdl_iomux_ddr_regs mx6dl_ddr_ioregs = {
548 	.dram_sdclk_0 = 0x00000028,
549 	.dram_sdclk_1 = 0x00000028,
550 	.dram_cas =	0x00000028,
551 	.dram_ras =	0x00000028,
552 	.dram_reset =	0x000c0028,
553 	.dram_sdcke0 =	0x00003000,
554 	.dram_sdcke1 =	0x00003000,
555 	.dram_sdba2 =	0x00000000,
556 	.dram_sdodt0 =	0x00003030,
557 	.dram_sdodt1 =	0x00003030,
558 	.dram_sdqs0 =	0x00000028,
559 	.dram_sdqs1 =	0x00000028,
560 	.dram_sdqs2 =	0x00000028,
561 	.dram_sdqs3 =	0x00000028,
562 	.dram_sdqs4 =	0x00000028,
563 	.dram_sdqs5 =	0x00000028,
564 	.dram_sdqs6 =	0x00000028,
565 	.dram_sdqs7 =	0x00000028,
566 	.dram_dqm0 =	0x00000028,
567 	.dram_dqm1 =	0x00000028,
568 	.dram_dqm2 =	0x00000028,
569 	.dram_dqm3 =	0x00000028,
570 	.dram_dqm4 =	0x00000028,
571 	.dram_dqm5 =	0x00000028,
572 	.dram_dqm6 =	0x00000028,
573 	.dram_dqm7 =	0x00000028,
574 };
575 
576 static const struct mx6dq_iomux_grp_regs mx6q_grp_ioregs = {
577 	.grp_ddr_type =  0x000C0000,
578 	.grp_ddrmode_ctl =  0x00020000,
579 	.grp_ddrpke =  0x00000000,
580 	.grp_addds =  0x00000030,
581 	.grp_ctlds =  0x00000030,
582 	.grp_ddrmode =  0x00020000,
583 	.grp_b0ds =  0x00000030,
584 	.grp_b1ds =  0x00000030,
585 	.grp_b2ds =  0x00000030,
586 	.grp_b3ds =  0x00000030,
587 	.grp_b4ds =  0x00000030,
588 	.grp_b5ds =  0x00000030,
589 	.grp_b6ds =  0x00000030,
590 	.grp_b7ds =  0x00000030,
591 };
592 
593 static const struct mx6sdl_iomux_grp_regs mx6sdl_grp_ioregs = {
594 	.grp_ddr_type = 0x000c0000,
595 	.grp_ddrmode_ctl = 0x00020000,
596 	.grp_ddrpke = 0x00000000,
597 	.grp_addds = 0x00000028,
598 	.grp_ctlds = 0x00000028,
599 	.grp_ddrmode = 0x00020000,
600 	.grp_b0ds = 0x00000028,
601 	.grp_b1ds = 0x00000028,
602 	.grp_b2ds = 0x00000028,
603 	.grp_b3ds = 0x00000028,
604 	.grp_b4ds = 0x00000028,
605 	.grp_b5ds = 0x00000028,
606 	.grp_b6ds = 0x00000028,
607 	.grp_b7ds = 0x00000028,
608 };
609 
610 /* microSOM with Dual processor and 1GB memory */
611 static const struct mx6_mmdc_calibration mx6q_1g_mmcd_calib = {
612 	.p0_mpwldectrl0 =  0x00000000,
613 	.p0_mpwldectrl1 =  0x00000000,
614 	.p1_mpwldectrl0 =  0x00000000,
615 	.p1_mpwldectrl1 =  0x00000000,
616 	.p0_mpdgctrl0 =    0x0314031c,
617 	.p0_mpdgctrl1 =    0x023e0304,
618 	.p1_mpdgctrl0 =    0x03240330,
619 	.p1_mpdgctrl1 =    0x03180260,
620 	.p0_mprddlctl =    0x3630323c,
621 	.p1_mprddlctl =    0x3436283a,
622 	.p0_mpwrdlctl =    0x36344038,
623 	.p1_mpwrdlctl =    0x422a423c,
624 };
625 
626 /* microSOM with Quad processor and 2GB memory */
627 static const struct mx6_mmdc_calibration mx6q_2g_mmcd_calib = {
628 	.p0_mpwldectrl0 =  0x00000000,
629 	.p0_mpwldectrl1 =  0x00000000,
630 	.p1_mpwldectrl0 =  0x00000000,
631 	.p1_mpwldectrl1 =  0x00000000,
632 	.p0_mpdgctrl0 =    0x0314031c,
633 	.p0_mpdgctrl1 =    0x023e0304,
634 	.p1_mpdgctrl0 =    0x03240330,
635 	.p1_mpdgctrl1 =    0x03180260,
636 	.p0_mprddlctl =    0x3630323c,
637 	.p1_mprddlctl =    0x3436283a,
638 	.p0_mpwrdlctl =    0x36344038,
639 	.p1_mpwrdlctl =    0x422a423c,
640 };
641 
642 /* microSOM with Solo processor and 512MB memory */
643 static const struct mx6_mmdc_calibration mx6dl_512m_mmcd_calib = {
644 	.p0_mpwldectrl0 = 0x0045004D,
645 	.p0_mpwldectrl1 = 0x003A0047,
646 	.p0_mpdgctrl0 =   0x023C0224,
647 	.p0_mpdgctrl1 =   0x02000220,
648 	.p0_mprddlctl =   0x44444846,
649 	.p0_mpwrdlctl =   0x32343032,
650 };
651 
652 /* microSOM with Dual lite processor and 1GB memory */
653 static const struct mx6_mmdc_calibration mx6dl_1g_mmcd_calib = {
654 	.p0_mpwldectrl0 =  0x0045004D,
655 	.p0_mpwldectrl1 =  0x003A0047,
656 	.p1_mpwldectrl0 =  0x001F001F,
657 	.p1_mpwldectrl1 =  0x00210035,
658 	.p0_mpdgctrl0 =    0x023C0224,
659 	.p0_mpdgctrl1 =    0x02000220,
660 	.p1_mpdgctrl0 =    0x02200220,
661 	.p1_mpdgctrl1 =    0x02040208,
662 	.p0_mprddlctl =    0x44444846,
663 	.p1_mprddlctl =    0x4042463C,
664 	.p0_mpwrdlctl =    0x32343032,
665 	.p1_mpwrdlctl =    0x36363430,
666 };
667 
668 static struct mx6_ddr3_cfg mem_ddr_2g = {
669 	.mem_speed = 1600,
670 	.density   = 2,
671 	.width     = 16,
672 	.banks     = 8,
673 	.rowaddr   = 14,
674 	.coladdr   = 10,
675 	.pagesz    = 2,
676 	.trcd      = 1375,
677 	.trcmin    = 4875,
678 	.trasmin   = 3500,
679 };
680 
681 static struct mx6_ddr3_cfg mem_ddr_4g = {
682 	.mem_speed = 1600,
683 	.density = 4,
684 	.width = 16,
685 	.banks = 8,
686 	.rowaddr = 16,
687 	.coladdr = 10,
688 	.pagesz = 2,
689 	.trcd = 1375,
690 	.trcmin = 4875,
691 	.trasmin = 3500,
692 };
693 
ccgr_init(void)694 static void ccgr_init(void)
695 {
696 	struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
697 
698 	writel(0x00C03F3F, &ccm->CCGR0);
699 	writel(0x0030FC03, &ccm->CCGR1);
700 	writel(0x0FFFC000, &ccm->CCGR2);
701 	writel(0x3FF00000, &ccm->CCGR3);
702 	writel(0x00FFF300, &ccm->CCGR4);
703 	writel(0x0F0000C3, &ccm->CCGR5);
704 	writel(0x000003FF, &ccm->CCGR6);
705 }
706 
spl_dram_init(int width)707 static void spl_dram_init(int width)
708 {
709 	struct mx6_ddr_sysinfo sysinfo = {
710 		/* width of data bus: 0=16, 1=32, 2=64 */
711 		.dsize = width / 32,
712 		/* config for full 4GB range so that get_mem_size() works */
713 		.cs_density = 32,	/* 32Gb per CS */
714 		.ncs = 1,		/* single chip select */
715 		.cs1_mirror = 0,
716 		.rtt_wr = 1 /*DDR3_RTT_60_OHM*/,	/* RTT_Wr = RZQ/4 */
717 		.rtt_nom = 1 /*DDR3_RTT_60_OHM*/,	/* RTT_Nom = RZQ/4 */
718 		.walat = 1,	/* Write additional latency */
719 		.ralat = 5,	/* Read additional latency */
720 		.mif3_mode = 3,	/* Command prediction working mode */
721 		.bi_on = 1,	/* Bank interleaving enabled */
722 		.sde_to_rst = 0x10,	/* 14 cycles, 200us (JEDEC default) */
723 		.rst_to_cke = 0x23,	/* 33 cycles, 500us (JEDEC default) */
724 		.ddr_type = DDR_TYPE_DDR3,
725 		.refsel = 1,	/* Refresh cycles at 32KHz */
726 		.refr = 7,	/* 8 refresh commands per refresh cycle */
727 	};
728 
729 	if (is_mx6dq())
730 		mx6dq_dram_iocfg(width, &mx6q_ddr_ioregs, &mx6q_grp_ioregs);
731 	else
732 		mx6sdl_dram_iocfg(width, &mx6dl_ddr_ioregs, &mx6sdl_grp_ioregs);
733 
734 	if (is_cpu_type(MXC_CPU_MX6D))
735 		mx6_dram_cfg(&sysinfo, &mx6q_1g_mmcd_calib, &mem_ddr_2g);
736 	else if (is_cpu_type(MXC_CPU_MX6Q))
737 		mx6_dram_cfg(&sysinfo, &mx6q_2g_mmcd_calib, &mem_ddr_4g);
738 	else if (is_cpu_type(MXC_CPU_MX6DL))
739 		mx6_dram_cfg(&sysinfo, &mx6dl_1g_mmcd_calib, &mem_ddr_2g);
740 	else if (is_cpu_type(MXC_CPU_MX6SOLO))
741 		mx6_dram_cfg(&sysinfo, &mx6dl_512m_mmcd_calib, &mem_ddr_2g);
742 }
743 
board_init_f(ulong dummy)744 void board_init_f(ulong dummy)
745 {
746 	/* setup AIPS and disable watchdog */
747 	arch_cpu_init();
748 
749 	ccgr_init();
750 	gpr_init();
751 
752 	/* iomux and setup of i2c */
753 	board_early_init_f();
754 
755 	/* setup GP timer */
756 	timer_init();
757 
758 	/* UART clocks enabled and gd valid - init serial console */
759 	preloader_console_init();
760 
761 	/* DDR initialization */
762 	if (is_cpu_type(MXC_CPU_MX6SOLO))
763 		spl_dram_init(32);
764 	else
765 		spl_dram_init(64);
766 
767 	/* Clear the BSS. */
768 	memset(__bss_start, 0, __bss_end - __bss_start);
769 
770 	/* load/boot image from boot device */
771 	board_init_r(NULL, 0);
772 }
773 #endif
774