xref: /rk3399_rockchip-uboot/board/engicam/icorem6/icorem6.c (revision 671f458aae4b6f14826c19fde56648fe7f6e2e2c)
1 /*
2  * Copyright (C) 2016 Amarula Solutions B.V.
3  * Copyright (C) 2016 Engicam S.r.l.
4  * Author: Jagan Teki <jagan@amarulasolutions.com>
5  *
6  * SPDX-License-Identifier:	GPL-2.0+
7  */
8 
9 #include <common.h>
10 #include <mmc.h>
11 
12 #include <asm/io.h>
13 #include <asm/gpio.h>
14 #include <linux/sizes.h>
15 
16 #include <asm/arch/clock.h>
17 #include <asm/arch/crm_regs.h>
18 #include <asm/arch/iomux.h>
19 #include <asm/arch/mx6-pins.h>
20 #include <asm/arch/sys_proto.h>
21 #include <asm/imx-common/iomux-v3.h>
22 #include <asm/imx-common/video.h>
23 
24 DECLARE_GLOBAL_DATA_PTR;
25 
26 #ifdef CONFIG_NAND_MXS
27 
28 #define GPMI_PAD_CTRL0	(PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_100K_UP)
29 #define GPMI_PAD_CTRL1	(PAD_CTL_DSE_40ohm | PAD_CTL_SPEED_MED | \
30 			PAD_CTL_SRE_FAST)
31 #define GPMI_PAD_CTRL2	(GPMI_PAD_CTRL0 | GPMI_PAD_CTRL1)
32 
33 iomux_v3_cfg_t gpmi_pads[] = {
34 	IOMUX_PADS(PAD_NANDF_CLE__NAND_CLE	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
35 	IOMUX_PADS(PAD_NANDF_ALE__NAND_ALE	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
36 	IOMUX_PADS(PAD_NANDF_WP_B__NAND_WP_B	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
37 	IOMUX_PADS(PAD_NANDF_RB0__NAND_READY_B	| MUX_PAD_CTRL(GPMI_PAD_CTRL0)),
38 	IOMUX_PADS(PAD_NANDF_CS0__NAND_CE0_B	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
39 	IOMUX_PADS(PAD_SD4_CMD__NAND_RE_B	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
40 	IOMUX_PADS(PAD_SD4_CLK__NAND_WE_B	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
41 	IOMUX_PADS(PAD_NANDF_D0__NAND_DATA00	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
42 	IOMUX_PADS(PAD_NANDF_D1__NAND_DATA01	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
43 	IOMUX_PADS(PAD_NANDF_D2__NAND_DATA02	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
44 	IOMUX_PADS(PAD_NANDF_D3__NAND_DATA03	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
45 	IOMUX_PADS(PAD_NANDF_D4__NAND_DATA04	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
46 	IOMUX_PADS(PAD_NANDF_D5__NAND_DATA05	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
47 	IOMUX_PADS(PAD_NANDF_D6__NAND_DATA06	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
48 	IOMUX_PADS(PAD_NANDF_D7__NAND_DATA07	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
49 };
50 
51 static void setup_gpmi_nand(void)
52 {
53 	struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
54 
55 	/* config gpmi nand iomux */
56 	SETUP_IOMUX_PADS(gpmi_pads);
57 
58 	/* gate ENFC_CLK_ROOT clock first,before clk source switch */
59 	clrbits_le32(&mxc_ccm->CCGR2, MXC_CCM_CCGR2_IOMUX_IPT_CLK_IO_MASK);
60 
61 	/* config gpmi and bch clock to 100 MHz */
62 	clrsetbits_le32(&mxc_ccm->cs2cdr,
63 			MXC_CCM_CS2CDR_ENFC_CLK_PODF_MASK |
64 			MXC_CCM_CS2CDR_ENFC_CLK_PRED_MASK |
65 			MXC_CCM_CS2CDR_ENFC_CLK_SEL_MASK,
66 			MXC_CCM_CS2CDR_ENFC_CLK_PODF(0) |
67 			MXC_CCM_CS2CDR_ENFC_CLK_PRED(3) |
68 			MXC_CCM_CS2CDR_ENFC_CLK_SEL(3));
69 
70 	/* enable ENFC_CLK_ROOT clock */
71 	setbits_le32(&mxc_ccm->CCGR2, MXC_CCM_CCGR2_IOMUX_IPT_CLK_IO_MASK);
72 
73 	/* enable gpmi and bch clock gating */
74 	setbits_le32(&mxc_ccm->CCGR4,
75 		     MXC_CCM_CCGR4_RAWNAND_U_BCH_INPUT_APB_MASK |
76 		     MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_BCH_MASK |
77 		     MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_MASK |
78 		     MXC_CCM_CCGR4_RAWNAND_U_GPMI_INPUT_APB_MASK |
79 		     MXC_CCM_CCGR4_PL301_MX6QPER1_BCH_OFFSET);
80 
81 	/* enable apbh clock gating */
82 	setbits_le32(&mxc_ccm->CCGR0, MXC_CCM_CCGR0_APBHDMA_MASK);
83 }
84 #endif
85 
86 #if defined(CONFIG_VIDEO_IPUV3)
87 static iomux_v3_cfg_t const rgb_pads[] = {
88 	IOMUX_PADS(PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK),
89 	IOMUX_PADS(PAD_DI0_PIN15__IPU1_DI0_PIN15),
90 	IOMUX_PADS(PAD_DI0_PIN2__IPU1_DI0_PIN02),
91 	IOMUX_PADS(PAD_DI0_PIN3__IPU1_DI0_PIN03),
92 	IOMUX_PADS(PAD_DISP0_DAT0__IPU1_DISP0_DATA00),
93 	IOMUX_PADS(PAD_DISP0_DAT1__IPU1_DISP0_DATA01),
94 	IOMUX_PADS(PAD_DISP0_DAT2__IPU1_DISP0_DATA02),
95 	IOMUX_PADS(PAD_DISP0_DAT3__IPU1_DISP0_DATA03),
96 	IOMUX_PADS(PAD_DISP0_DAT4__IPU1_DISP0_DATA04),
97 	IOMUX_PADS(PAD_DISP0_DAT5__IPU1_DISP0_DATA05),
98 	IOMUX_PADS(PAD_DISP0_DAT6__IPU1_DISP0_DATA06),
99 	IOMUX_PADS(PAD_DISP0_DAT7__IPU1_DISP0_DATA07),
100 	IOMUX_PADS(PAD_DISP0_DAT8__IPU1_DISP0_DATA08),
101 	IOMUX_PADS(PAD_DISP0_DAT9__IPU1_DISP0_DATA09),
102 	IOMUX_PADS(PAD_DISP0_DAT10__IPU1_DISP0_DATA10),
103 	IOMUX_PADS(PAD_DISP0_DAT11__IPU1_DISP0_DATA11),
104 	IOMUX_PADS(PAD_DISP0_DAT12__IPU1_DISP0_DATA12),
105 	IOMUX_PADS(PAD_DISP0_DAT13__IPU1_DISP0_DATA13),
106 	IOMUX_PADS(PAD_DISP0_DAT14__IPU1_DISP0_DATA14),
107 	IOMUX_PADS(PAD_DISP0_DAT15__IPU1_DISP0_DATA15),
108 	IOMUX_PADS(PAD_DISP0_DAT16__IPU1_DISP0_DATA16),
109 	IOMUX_PADS(PAD_DISP0_DAT17__IPU1_DISP0_DATA17),
110 };
111 
112 static void enable_rgb(struct display_info_t const *dev)
113 {
114 	SETUP_IOMUX_PADS(rgb_pads);
115 }
116 
117 struct display_info_t const displays[] = {
118 	{
119 		.bus	= -1,
120 		.addr	= 0,
121 		.pixfmt	= IPU_PIX_FMT_RGB666,
122 		.detect	= NULL,
123 		.enable	= enable_rgb,
124 		.mode	= {
125 			.name           = "Amp-WD",
126 			.refresh        = 60,
127 			.xres           = 800,
128 			.yres           = 480,
129 			.pixclock       = 30000,
130 			.left_margin    = 30,
131 			.right_margin   = 30,
132 			.upper_margin   = 5,
133 			.lower_margin   = 5,
134 			.hsync_len      = 64,
135 			.vsync_len      = 20,
136 			.sync           = FB_SYNC_EXT,
137 			.vmode          = FB_VMODE_NONINTERLACED
138 		}
139 	},
140 };
141 
142 size_t display_count = ARRAY_SIZE(displays);
143 
144 static void setup_display(void)
145 {
146 	struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
147 	struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
148 	int reg;
149 
150 	enable_ipu_clock();
151 
152 	/* Turn on LDB0,IPU,IPU DI0 clocks */
153 	reg = __raw_readl(&mxc_ccm->CCGR3);
154 	reg |=  (MXC_CCM_CCGR3_LDB_DI0_MASK | 0xffff);
155 	writel(reg, &mxc_ccm->CCGR3);
156 
157 	/* set LDB0, LDB1 clk select to 011/011 */
158 	reg = readl(&mxc_ccm->cs2cdr);
159 	reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK |
160 		MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK);
161 	reg |= (3 << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET) |
162 		(3 << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET);
163 	writel(reg, &mxc_ccm->cs2cdr);
164 
165 	reg = readl(&mxc_ccm->cscmr2);
166 	reg |= MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV;
167 	writel(reg, &mxc_ccm->cscmr2);
168 
169 	reg = readl(&mxc_ccm->chsccdr);
170 	reg |= (CHSCCDR_CLK_SEL_LDB_DI0 <<
171 		MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET);
172 	writel(reg, &mxc_ccm->chsccdr);
173 
174 	reg = IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES |
175 		IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_HIGH |
176 		IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_LOW |
177 		IOMUXC_GPR2_BIT_MAPPING_CH1_SPWG |
178 		IOMUXC_GPR2_DATA_WIDTH_CH1_18BIT |
179 		IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG |
180 		IOMUXC_GPR2_DATA_WIDTH_CH0_18BIT |
181 		IOMUXC_GPR2_LVDS_CH1_MODE_DISABLED |
182 		IOMUXC_GPR2_LVDS_CH0_MODE_ENABLED_DI0;
183 	writel(reg, &iomux->gpr[2]);
184 
185 	reg = readl(&iomux->gpr[3]);
186 	reg = (reg & ~IOMUXC_GPR3_LVDS0_MUX_CTL_MASK) |
187 		(IOMUXC_GPR3_MUX_SRC_IPU1_DI0 <<
188 		IOMUXC_GPR3_LVDS0_MUX_CTL_OFFSET);
189 	writel(reg, &iomux->gpr[3]);
190 }
191 #endif /* CONFIG_VIDEO_IPUV3 */
192 
193 #ifdef CONFIG_ENV_IS_IN_MMC
194 static void mmc_late_init(void)
195 {
196 	char cmd[32];
197 	char mmcblk[32];
198 	u32 dev_no = mmc_get_env_dev();
199 
200 	setenv_ulong("mmcdev", dev_no);
201 
202 	/* Set mmcblk env */
203 	sprintf(mmcblk, "/dev/mmcblk%dp2 rootwait rw", dev_no);
204 	setenv("mmcroot", mmcblk);
205 
206 	sprintf(cmd, "mmc dev %d", dev_no);
207 	run_command(cmd, 0);
208 }
209 #endif
210 
211 int board_late_init(void)
212 {
213 	switch ((imx6_src_get_boot_mode() & IMX6_BMODE_MASK) >>
214 			IMX6_BMODE_SHIFT) {
215 	case IMX6_BMODE_SD:
216 	case IMX6_BMODE_ESD:
217 #ifdef CONFIG_ENV_IS_IN_MMC
218 		mmc_late_init();
219 #endif
220 		setenv("modeboot", "mmcboot");
221 		break;
222 	case IMX6_BMODE_NAND:
223 		setenv("modeboot", "nandboot");
224 		break;
225 	default:
226 		setenv("modeboot", "");
227 		break;
228 	}
229 
230 	if (is_mx6dq())
231 		setenv("fdt_file", "imx6q-icore.dtb");
232 	else if(is_mx6dl() || is_mx6solo())
233 		setenv("fdt_file", "imx6dl-icore.dtb");
234 
235 	return 0;
236 }
237 
238 int board_init(void)
239 {
240 	/* Address of boot parameters */
241 	gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
242 
243 #ifdef CONFIG_NAND_MXS
244 	setup_gpmi_nand();
245 #endif
246 
247 #ifdef CONFIG_VIDEO_IPUV3
248 	setup_display();
249 #endif
250 
251 	return 0;
252 }
253 
254 int dram_init(void)
255 {
256 	gd->ram_size = imx_ddr_size();
257 
258 	return 0;
259 }
260 
261 #ifdef CONFIG_SPL_BUILD
262 #include <libfdt.h>
263 #include <spl.h>
264 
265 #include <asm/arch/crm_regs.h>
266 #include <asm/arch/mx6-ddr.h>
267 
268 #define UART_PAD_CTRL  (PAD_CTL_PKE | PAD_CTL_PUE |		\
269 	PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED |		\
270 	PAD_CTL_DSE_40ohm   | PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
271 
272 static iomux_v3_cfg_t const uart4_pads[] = {
273 	IOMUX_PADS(PAD_KEY_COL0__UART4_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
274 	IOMUX_PADS(PAD_KEY_ROW0__UART4_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
275 };
276 
277 /* MMC board initialization is needed till adding DM support in SPL */
278 #if defined(CONFIG_FSL_ESDHC) && !defined(CONFIG_DM_MMC)
279 #include <mmc.h>
280 #include <fsl_esdhc.h>
281 
282 #define USDHC_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE |             \
283 	PAD_CTL_PUS_22K_UP  | PAD_CTL_SPEED_LOW |               \
284 	PAD_CTL_DSE_80ohm   | PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
285 
286 static iomux_v3_cfg_t const usdhc1_pads[] = {
287 	IOMUX_PADS(PAD_SD1_CLK__SD1_CLK	| MUX_PAD_CTRL(USDHC_PAD_CTRL)),
288 	IOMUX_PADS(PAD_SD1_CMD__SD1_CMD	| MUX_PAD_CTRL(USDHC_PAD_CTRL)),
289 	IOMUX_PADS(PAD_SD1_DAT0__SD1_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
290 	IOMUX_PADS(PAD_SD1_DAT1__SD1_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
291 	IOMUX_PADS(PAD_SD1_DAT2__SD1_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
292 	IOMUX_PADS(PAD_SD1_DAT3__SD1_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
293 	IOMUX_PADS(PAD_GPIO_1__GPIO1_IO01 | MUX_PAD_CTRL(NO_PAD_CTRL)),/* CD */
294 };
295 
296 #define USDHC1_CD_GPIO	IMX_GPIO_NR(1, 1)
297 
298 struct fsl_esdhc_cfg usdhc_cfg[1] = {
299 	{USDHC1_BASE_ADDR, 0, 4},
300 };
301 
302 int board_mmc_getcd(struct mmc *mmc)
303 {
304 	struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
305 	int ret = 0;
306 
307 	switch (cfg->esdhc_base) {
308 	case USDHC1_BASE_ADDR:
309 		ret = !gpio_get_value(USDHC1_CD_GPIO);
310 		break;
311 	}
312 
313 	return ret;
314 }
315 
316 int board_mmc_init(bd_t *bis)
317 {
318 	int i, ret;
319 
320 	/*
321 	* According to the board_mmc_init() the following map is done:
322 	* (U-boot device node)    (Physical Port)
323 	* mmc0				USDHC1
324 	*/
325 	for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) {
326 		switch (i) {
327 		case 0:
328 			SETUP_IOMUX_PADS(usdhc1_pads);
329 			gpio_direction_input(USDHC1_CD_GPIO);
330 			usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
331 			break;
332 		default:
333 			printf("Warning - USDHC%d controller not supporting\n",
334 			       i + 1);
335 			return 0;
336 		}
337 
338 		ret = fsl_esdhc_initialize(bis, &usdhc_cfg[i]);
339 		if (ret) {
340 			printf("Warning: failed to initialize mmc dev %d\n", i);
341 			return ret;
342 		}
343 	}
344 
345 	return 0;
346 }
347 #endif
348 
349 #ifdef CONFIG_SPL_LOAD_FIT
350 int board_fit_config_name_match(const char *name)
351 {
352 	if (is_mx6dq() && !strcmp(name, "imx6q-icore"))
353 		return 0;
354 	else if ((is_mx6dl() || is_mx6solo()) && !strcmp(name, "imx6dl-icore"))
355 		return 0;
356 	else
357 		return -1;
358 }
359 #endif
360 
361 /*
362  * Driving strength:
363  *   0x30 == 40 Ohm
364  *   0x28 == 48 Ohm
365  */
366 
367 #define IMX6DQ_DRIVE_STRENGTH		0x30
368 #define IMX6SDL_DRIVE_STRENGTH		0x28
369 
370 /* configure MX6Q/DUAL mmdc DDR io registers */
371 static struct mx6dq_iomux_ddr_regs mx6dq_ddr_ioregs = {
372 	.dram_sdqs0 = IMX6DQ_DRIVE_STRENGTH,
373 	.dram_sdqs1 = IMX6DQ_DRIVE_STRENGTH,
374 	.dram_sdqs2 = IMX6DQ_DRIVE_STRENGTH,
375 	.dram_sdqs3 = IMX6DQ_DRIVE_STRENGTH,
376 	.dram_sdqs4 = IMX6DQ_DRIVE_STRENGTH,
377 	.dram_sdqs5 = IMX6DQ_DRIVE_STRENGTH,
378 	.dram_sdqs6 = IMX6DQ_DRIVE_STRENGTH,
379 	.dram_sdqs7 = IMX6DQ_DRIVE_STRENGTH,
380 	.dram_dqm0 = IMX6DQ_DRIVE_STRENGTH,
381 	.dram_dqm1 = IMX6DQ_DRIVE_STRENGTH,
382 	.dram_dqm2 = IMX6DQ_DRIVE_STRENGTH,
383 	.dram_dqm3 = IMX6DQ_DRIVE_STRENGTH,
384 	.dram_dqm4 = IMX6DQ_DRIVE_STRENGTH,
385 	.dram_dqm5 = IMX6DQ_DRIVE_STRENGTH,
386 	.dram_dqm6 = IMX6DQ_DRIVE_STRENGTH,
387 	.dram_dqm7 = IMX6DQ_DRIVE_STRENGTH,
388 	.dram_cas = IMX6DQ_DRIVE_STRENGTH,
389 	.dram_ras = IMX6DQ_DRIVE_STRENGTH,
390 	.dram_sdclk_0 = IMX6DQ_DRIVE_STRENGTH,
391 	.dram_sdclk_1 = IMX6DQ_DRIVE_STRENGTH,
392 	.dram_reset = IMX6DQ_DRIVE_STRENGTH,
393 	.dram_sdcke0 = IMX6DQ_DRIVE_STRENGTH,
394 	.dram_sdcke1 = IMX6DQ_DRIVE_STRENGTH,
395 	.dram_sdba2 = 0x00000000,
396 	.dram_sdodt0 = IMX6DQ_DRIVE_STRENGTH,
397 	.dram_sdodt1 = IMX6DQ_DRIVE_STRENGTH,
398 };
399 
400 /* configure MX6Q/DUAL mmdc GRP io registers */
401 static struct mx6dq_iomux_grp_regs mx6dq_grp_ioregs = {
402 	.grp_b0ds = IMX6DQ_DRIVE_STRENGTH,
403 	.grp_b1ds = IMX6DQ_DRIVE_STRENGTH,
404 	.grp_b2ds = IMX6DQ_DRIVE_STRENGTH,
405 	.grp_b3ds = IMX6DQ_DRIVE_STRENGTH,
406 	.grp_b4ds = IMX6DQ_DRIVE_STRENGTH,
407 	.grp_b5ds = IMX6DQ_DRIVE_STRENGTH,
408 	.grp_b6ds = IMX6DQ_DRIVE_STRENGTH,
409 	.grp_b7ds = IMX6DQ_DRIVE_STRENGTH,
410 	.grp_addds = IMX6DQ_DRIVE_STRENGTH,
411 	.grp_ddrmode_ctl = 0x00020000,
412 	.grp_ddrpke = 0x00000000,
413 	.grp_ddrmode = 0x00020000,
414 	.grp_ctlds = IMX6DQ_DRIVE_STRENGTH,
415 	.grp_ddr_type = 0x000c0000,
416 };
417 
418 /* configure MX6SOLO/DUALLITE mmdc DDR io registers */
419 struct mx6sdl_iomux_ddr_regs mx6sdl_ddr_ioregs = {
420 	.dram_sdclk_0 = IMX6SDL_DRIVE_STRENGTH,
421 	.dram_sdclk_1 = IMX6SDL_DRIVE_STRENGTH,
422 	.dram_cas = IMX6SDL_DRIVE_STRENGTH,
423 	.dram_ras = IMX6SDL_DRIVE_STRENGTH,
424 	.dram_reset = IMX6SDL_DRIVE_STRENGTH,
425 	.dram_sdcke0 = IMX6SDL_DRIVE_STRENGTH,
426 	.dram_sdcke1 = IMX6SDL_DRIVE_STRENGTH,
427 	.dram_sdba2 = 0x00000000,
428 	.dram_sdodt0 = IMX6SDL_DRIVE_STRENGTH,
429 	.dram_sdodt1 = IMX6SDL_DRIVE_STRENGTH,
430 	.dram_sdqs0 = IMX6SDL_DRIVE_STRENGTH,
431 	.dram_sdqs1 = IMX6SDL_DRIVE_STRENGTH,
432 	.dram_sdqs2 = IMX6SDL_DRIVE_STRENGTH,
433 	.dram_sdqs3 = IMX6SDL_DRIVE_STRENGTH,
434 	.dram_sdqs4 = IMX6SDL_DRIVE_STRENGTH,
435 	.dram_sdqs5 = IMX6SDL_DRIVE_STRENGTH,
436 	.dram_sdqs6 = IMX6SDL_DRIVE_STRENGTH,
437 	.dram_sdqs7 = IMX6SDL_DRIVE_STRENGTH,
438 	.dram_dqm0 = IMX6SDL_DRIVE_STRENGTH,
439 	.dram_dqm1 = IMX6SDL_DRIVE_STRENGTH,
440 	.dram_dqm2 = IMX6SDL_DRIVE_STRENGTH,
441 	.dram_dqm3 = IMX6SDL_DRIVE_STRENGTH,
442 	.dram_dqm4 = IMX6SDL_DRIVE_STRENGTH,
443 	.dram_dqm5 = IMX6SDL_DRIVE_STRENGTH,
444 	.dram_dqm6 = IMX6SDL_DRIVE_STRENGTH,
445 	.dram_dqm7 = IMX6SDL_DRIVE_STRENGTH,
446 };
447 
448 /* configure MX6SOLO/DUALLITE mmdc GRP io registers */
449 struct mx6sdl_iomux_grp_regs mx6sdl_grp_ioregs = {
450 	.grp_ddr_type = 0x000c0000,
451 	.grp_ddrmode_ctl = 0x00020000,
452 	.grp_ddrpke = 0x00000000,
453 	.grp_addds = IMX6SDL_DRIVE_STRENGTH,
454 	.grp_ctlds = IMX6SDL_DRIVE_STRENGTH,
455 	.grp_ddrmode = 0x00020000,
456 	.grp_b0ds = IMX6SDL_DRIVE_STRENGTH,
457 	.grp_b1ds = IMX6SDL_DRIVE_STRENGTH,
458 	.grp_b2ds = IMX6SDL_DRIVE_STRENGTH,
459 	.grp_b3ds = IMX6SDL_DRIVE_STRENGTH,
460 	.grp_b4ds = IMX6SDL_DRIVE_STRENGTH,
461 	.grp_b5ds = IMX6SDL_DRIVE_STRENGTH,
462 	.grp_b6ds = IMX6SDL_DRIVE_STRENGTH,
463 	.grp_b7ds = IMX6SDL_DRIVE_STRENGTH,
464 };
465 
466 /* mt41j256 */
467 static struct mx6_ddr3_cfg mt41j256 = {
468 	.mem_speed = 1066,
469 	.density = 2,
470 	.width = 16,
471 	.banks = 8,
472 	.rowaddr = 13,
473 	.coladdr = 10,
474 	.pagesz = 2,
475 	.trcd = 1375,
476 	.trcmin = 4875,
477 	.trasmin = 3500,
478 	.SRT = 0,
479 };
480 
481 static struct mx6_mmdc_calibration mx6dq_mmdc_calib = {
482 	.p0_mpwldectrl0 = 0x000E0009,
483 	.p0_mpwldectrl1 = 0x0018000E,
484 	.p1_mpwldectrl0 = 0x00000007,
485 	.p1_mpwldectrl1 = 0x00000000,
486 	.p0_mpdgctrl0 = 0x43280334,
487 	.p0_mpdgctrl1 = 0x031C0314,
488 	.p1_mpdgctrl0 = 0x4318031C,
489 	.p1_mpdgctrl1 = 0x030C0258,
490 	.p0_mprddlctl = 0x3E343A40,
491 	.p1_mprddlctl = 0x383C3844,
492 	.p0_mpwrdlctl = 0x40404440,
493 	.p1_mpwrdlctl = 0x4C3E4446,
494 };
495 
496 /* DDR 64bit */
497 static struct mx6_ddr_sysinfo mem_q = {
498 	.ddr_type	= DDR_TYPE_DDR3,
499 	.dsize		= 2,
500 	.cs1_mirror	= 0,
501 	/* config for full 4GB range so that get_mem_size() works */
502 	.cs_density	= 32,
503 	.ncs		= 1,
504 	.bi_on		= 1,
505 	.rtt_nom	= 2,
506 	.rtt_wr		= 2,
507 	.ralat		= 5,
508 	.walat		= 0,
509 	.mif3_mode	= 3,
510 	.rst_to_cke	= 0x23,
511 	.sde_to_rst	= 0x10,
512 };
513 
514 static struct mx6_mmdc_calibration mx6dl_mmdc_calib = {
515 	.p0_mpwldectrl0 = 0x001F0024,
516 	.p0_mpwldectrl1 = 0x00110018,
517 	.p1_mpwldectrl0 = 0x001F0024,
518 	.p1_mpwldectrl1 = 0x00110018,
519 	.p0_mpdgctrl0 = 0x4230022C,
520 	.p0_mpdgctrl1 = 0x02180220,
521 	.p1_mpdgctrl0 = 0x42440248,
522 	.p1_mpdgctrl1 = 0x02300238,
523 	.p0_mprddlctl = 0x44444A48,
524 	.p1_mprddlctl = 0x46484A42,
525 	.p0_mpwrdlctl = 0x38383234,
526 	.p1_mpwrdlctl = 0x3C34362E,
527 };
528 
529 /* DDR 64bit 1GB */
530 static struct mx6_ddr_sysinfo mem_dl = {
531 	.dsize		= 2,
532 	.cs1_mirror	= 0,
533 	/* config for full 4GB range so that get_mem_size() works */
534 	.cs_density	= 32,
535 	.ncs		= 1,
536 	.bi_on		= 1,
537 	.rtt_nom	= 1,
538 	.rtt_wr		= 1,
539 	.ralat		= 5,
540 	.walat		= 0,
541 	.mif3_mode	= 3,
542 	.rst_to_cke	= 0x23,
543 	.sde_to_rst	= 0x10,
544 };
545 
546 /* DDR 32bit 512MB */
547 static struct mx6_ddr_sysinfo mem_s = {
548 	.dsize		= 1,
549 	.cs1_mirror	= 0,
550 	/* config for full 4GB range so that get_mem_size() works */
551 	.cs_density	= 32,
552 	.ncs		= 1,
553 	.bi_on		= 1,
554 	.rtt_nom	= 1,
555 	.rtt_wr		= 1,
556 	.ralat		= 5,
557 	.walat		= 0,
558 	.mif3_mode	= 3,
559 	.rst_to_cke	= 0x23,
560 	.sde_to_rst	= 0x10,
561 };
562 
563 static void ccgr_init(void)
564 {
565 	struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
566 
567 	writel(0x00003F3F, &ccm->CCGR0);
568 	writel(0x0030FC00, &ccm->CCGR1);
569 	writel(0x000FC000, &ccm->CCGR2);
570 	writel(0x3F300000, &ccm->CCGR3);
571 	writel(0xFF00F300, &ccm->CCGR4);
572 	writel(0x0F0000C3, &ccm->CCGR5);
573 	writel(0x000003CC, &ccm->CCGR6);
574 }
575 
576 static void gpr_init(void)
577 {
578 	struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
579 
580 	/* enable AXI cache for VDOA/VPU/IPU */
581 	writel(0xF00000CF, &iomux->gpr[4]);
582 	/* set IPU AXI-id0 Qos=0xf(bypass) AXI-id1 Qos=0x7 */
583 	writel(0x007F007F, &iomux->gpr[6]);
584 	writel(0x007F007F, &iomux->gpr[7]);
585 }
586 
587 static void spl_dram_init(void)
588 {
589 	if (is_mx6solo()) {
590 		mx6sdl_dram_iocfg(32, &mx6sdl_ddr_ioregs, &mx6sdl_grp_ioregs);
591 		mx6_dram_cfg(&mem_s, &mx6dl_mmdc_calib, &mt41j256);
592 	} else if (is_mx6dl()) {
593 		mx6sdl_dram_iocfg(64, &mx6sdl_ddr_ioregs, &mx6sdl_grp_ioregs);
594 		mx6_dram_cfg(&mem_dl, &mx6dl_mmdc_calib, &mt41j256);
595 	} else if (is_mx6dq()) {
596 		mx6dq_dram_iocfg(64, &mx6dq_ddr_ioregs, &mx6dq_grp_ioregs);
597 		mx6_dram_cfg(&mem_q, &mx6dq_mmdc_calib, &mt41j256);
598 	}
599 
600 	udelay(100);
601 }
602 
603 void board_init_f(ulong dummy)
604 {
605 	ccgr_init();
606 
607 	/* setup AIPS and disable watchdog */
608 	arch_cpu_init();
609 
610 	gpr_init();
611 
612 	/* iomux */
613 	SETUP_IOMUX_PADS(uart4_pads);
614 
615 	/* setup GP timer */
616 	timer_init();
617 
618 	/* UART clocks enabled and gd valid - init serial console */
619 	preloader_console_init();
620 
621 	/* DDR initialization */
622 	spl_dram_init();
623 
624 	/* Clear the BSS. */
625 	memset(__bss_start, 0, __bss_end - __bss_start);
626 
627 	/* load/boot image from boot device */
628 	board_init_r(NULL, 0);
629 }
630 #endif
631