xref: /rk3399_rockchip-uboot/board/engicam/icorem6/icorem6.c (revision e920f607793a0846b3837924e8ea5e95f2adc29b)
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 
11 #include <asm/io.h>
12 #include <asm/gpio.h>
13 #include <linux/sizes.h>
14 
15 #include <asm/arch/clock.h>
16 #include <asm/arch/crm_regs.h>
17 #include <asm/arch/iomux.h>
18 #include <asm/arch/mx6-pins.h>
19 #include <asm/arch/sys_proto.h>
20 #include <asm/imx-common/iomux-v3.h>
21 
22 DECLARE_GLOBAL_DATA_PTR;
23 
24 #define UART_PAD_CTRL  (PAD_CTL_PKE | PAD_CTL_PUE |		\
25 	PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED |		\
26 	PAD_CTL_DSE_40ohm   | PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
27 
28 static iomux_v3_cfg_t const uart4_pads[] = {
29 	IOMUX_PADS(PAD_KEY_COL0__UART4_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
30 	IOMUX_PADS(PAD_KEY_ROW0__UART4_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
31 };
32 
33 #ifdef CONFIG_NAND_MXS
34 
35 #define GPMI_PAD_CTRL0	(PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_100K_UP)
36 #define GPMI_PAD_CTRL1	(PAD_CTL_DSE_40ohm | PAD_CTL_SPEED_MED | \
37 			PAD_CTL_SRE_FAST)
38 #define GPMI_PAD_CTRL2	(GPMI_PAD_CTRL0 | GPMI_PAD_CTRL1)
39 
40 iomux_v3_cfg_t gpmi_pads[] = {
41 	IOMUX_PADS(PAD_NANDF_CLE__NAND_CLE	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
42 	IOMUX_PADS(PAD_NANDF_ALE__NAND_ALE	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
43 	IOMUX_PADS(PAD_NANDF_WP_B__NAND_WP_B	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
44 	IOMUX_PADS(PAD_NANDF_RB0__NAND_READY_B	| MUX_PAD_CTRL(GPMI_PAD_CTRL0)),
45 	IOMUX_PADS(PAD_NANDF_CS0__NAND_CE0_B	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
46 	IOMUX_PADS(PAD_SD4_CMD__NAND_RE_B	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
47 	IOMUX_PADS(PAD_SD4_CLK__NAND_WE_B	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
48 	IOMUX_PADS(PAD_NANDF_D0__NAND_DATA00	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
49 	IOMUX_PADS(PAD_NANDF_D1__NAND_DATA01	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
50 	IOMUX_PADS(PAD_NANDF_D2__NAND_DATA02	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
51 	IOMUX_PADS(PAD_NANDF_D3__NAND_DATA03	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
52 	IOMUX_PADS(PAD_NANDF_D4__NAND_DATA04	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
53 	IOMUX_PADS(PAD_NANDF_D5__NAND_DATA05	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
54 	IOMUX_PADS(PAD_NANDF_D6__NAND_DATA06	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
55 	IOMUX_PADS(PAD_NANDF_D7__NAND_DATA07	| MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
56 };
57 
58 static void setup_gpmi_nand(void)
59 {
60 	struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
61 
62 	/* config gpmi nand iomux */
63 	SETUP_IOMUX_PADS(gpmi_pads);
64 
65 	/* gate ENFC_CLK_ROOT clock first,before clk source switch */
66 	clrbits_le32(&mxc_ccm->CCGR2, MXC_CCM_CCGR2_IOMUX_IPT_CLK_IO_MASK);
67 
68 	/* config gpmi and bch clock to 100 MHz */
69 	clrsetbits_le32(&mxc_ccm->cs2cdr,
70 			MXC_CCM_CS2CDR_ENFC_CLK_PODF_MASK |
71 			MXC_CCM_CS2CDR_ENFC_CLK_PRED_MASK |
72 			MXC_CCM_CS2CDR_ENFC_CLK_SEL_MASK,
73 			MXC_CCM_CS2CDR_ENFC_CLK_PODF(0) |
74 			MXC_CCM_CS2CDR_ENFC_CLK_PRED(3) |
75 			MXC_CCM_CS2CDR_ENFC_CLK_SEL(3));
76 
77 	/* enable ENFC_CLK_ROOT clock */
78 	setbits_le32(&mxc_ccm->CCGR2, MXC_CCM_CCGR2_IOMUX_IPT_CLK_IO_MASK);
79 
80 	/* enable gpmi and bch clock gating */
81 	setbits_le32(&mxc_ccm->CCGR4,
82 		     MXC_CCM_CCGR4_RAWNAND_U_BCH_INPUT_APB_MASK |
83 		     MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_BCH_MASK |
84 		     MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_MASK |
85 		     MXC_CCM_CCGR4_RAWNAND_U_GPMI_INPUT_APB_MASK |
86 		     MXC_CCM_CCGR4_PL301_MX6QPER1_BCH_OFFSET);
87 
88 	/* enable apbh clock gating */
89 	setbits_le32(&mxc_ccm->CCGR0, MXC_CCM_CCGR0_APBHDMA_MASK);
90 }
91 #endif
92 
93 int board_early_init_f(void)
94 {
95 	SETUP_IOMUX_PADS(uart4_pads);
96 
97 	return 0;
98 }
99 
100 int board_init(void)
101 {
102 	/* Address of boot parameters */
103 	gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
104 
105 #ifdef CONFIG_NAND_MXS
106 	setup_gpmi_nand();
107 #endif
108 	return 0;
109 }
110 
111 int dram_init(void)
112 {
113 	gd->ram_size = imx_ddr_size();
114 
115 	return 0;
116 }
117 
118 #ifdef CONFIG_SPL_BUILD
119 #include <libfdt.h>
120 #include <spl.h>
121 
122 #include <asm/arch/crm_regs.h>
123 #include <asm/arch/mx6-ddr.h>
124 
125 /* MMC board initialization is needed till adding DM support in SPL */
126 #if defined(CONFIG_FSL_ESDHC) && !defined(CONFIG_DM_MMC)
127 #include <mmc.h>
128 #include <fsl_esdhc.h>
129 
130 #define USDHC_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE |             \
131 	PAD_CTL_PUS_22K_UP  | PAD_CTL_SPEED_LOW |               \
132 	PAD_CTL_DSE_80ohm   | PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
133 
134 static iomux_v3_cfg_t const usdhc1_pads[] = {
135 	IOMUX_PADS(PAD_SD1_CLK__SD1_CLK	| MUX_PAD_CTRL(USDHC_PAD_CTRL)),
136 	IOMUX_PADS(PAD_SD1_CMD__SD1_CMD	| MUX_PAD_CTRL(USDHC_PAD_CTRL)),
137 	IOMUX_PADS(PAD_SD1_DAT0__SD1_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
138 	IOMUX_PADS(PAD_SD1_DAT1__SD1_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
139 	IOMUX_PADS(PAD_SD1_DAT2__SD1_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
140 	IOMUX_PADS(PAD_SD1_DAT3__SD1_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
141 	IOMUX_PADS(PAD_GPIO_1__GPIO1_IO01 | MUX_PAD_CTRL(NO_PAD_CTRL)),/* CD */
142 };
143 
144 #define USDHC1_CD_GPIO	IMX_GPIO_NR(1, 1)
145 
146 struct fsl_esdhc_cfg usdhc_cfg[1] = {
147 	{USDHC1_BASE_ADDR, 0, 4},
148 };
149 
150 int board_mmc_getcd(struct mmc *mmc)
151 {
152 	struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
153 	int ret = 0;
154 
155 	switch (cfg->esdhc_base) {
156 	case USDHC1_BASE_ADDR:
157 		ret = !gpio_get_value(USDHC1_CD_GPIO);
158 		break;
159 	}
160 
161 	return ret;
162 }
163 
164 int board_mmc_init(bd_t *bis)
165 {
166 	int i, ret;
167 
168 	/*
169 	* According to the board_mmc_init() the following map is done:
170 	* (U-boot device node)    (Physical Port)
171 	* mmc0				USDHC1
172 	*/
173 	for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) {
174 		switch (i) {
175 		case 0:
176 			SETUP_IOMUX_PADS(usdhc1_pads);
177 			gpio_direction_input(USDHC1_CD_GPIO);
178 			usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
179 			break;
180 		default:
181 			printf("Warning - USDHC%d controller not supporting\n",
182 			       i + 1);
183 			return 0;
184 		}
185 
186 		ret = fsl_esdhc_initialize(bis, &usdhc_cfg[i]);
187 		if (ret) {
188 			printf("Warning: failed to initialize mmc dev %d\n", i);
189 			return ret;
190 		}
191 	}
192 
193 	return 0;
194 }
195 #endif
196 
197 /*
198  * Driving strength:
199  *   0x30 == 40 Ohm
200  *   0x28 == 48 Ohm
201  */
202 
203 #define IMX6DQ_DRIVE_STRENGTH		0x30
204 #define IMX6SDL_DRIVE_STRENGTH		0x28
205 
206 /* configure MX6Q/DUAL mmdc DDR io registers */
207 static struct mx6dq_iomux_ddr_regs mx6dq_ddr_ioregs = {
208 	.dram_sdqs0 = 0x28,
209 	.dram_sdqs1 = 0x28,
210 	.dram_sdqs2 = 0x28,
211 	.dram_sdqs3 = 0x28,
212 	.dram_sdqs4 = 0x28,
213 	.dram_sdqs5 = 0x28,
214 	.dram_sdqs6 = 0x28,
215 	.dram_sdqs7 = 0x28,
216 	.dram_dqm0 = 0x28,
217 	.dram_dqm1 = 0x28,
218 	.dram_dqm2 = 0x28,
219 	.dram_dqm3 = 0x28,
220 	.dram_dqm4 = 0x28,
221 	.dram_dqm5 = 0x28,
222 	.dram_dqm6 = 0x28,
223 	.dram_dqm7 = 0x28,
224 	.dram_cas = 0x30,
225 	.dram_ras = 0x30,
226 	.dram_sdclk_0 = 0x30,
227 	.dram_sdclk_1 = 0x30,
228 	.dram_reset = 0x30,
229 	.dram_sdcke0 = 0x3000,
230 	.dram_sdcke1 = 0x3000,
231 	.dram_sdba2 = 0x00000000,
232 	.dram_sdodt0 = 0x30,
233 	.dram_sdodt1 = 0x30,
234 };
235 
236 /* configure MX6Q/DUAL mmdc GRP io registers */
237 static struct mx6dq_iomux_grp_regs mx6dq_grp_ioregs = {
238 	.grp_b0ds = 0x30,
239 	.grp_b1ds = 0x30,
240 	.grp_b2ds = 0x30,
241 	.grp_b3ds = 0x30,
242 	.grp_b4ds = 0x30,
243 	.grp_b5ds = 0x30,
244 	.grp_b6ds = 0x30,
245 	.grp_b7ds = 0x30,
246 	.grp_addds = 0x30,
247 	.grp_ddrmode_ctl = 0x00020000,
248 	.grp_ddrpke = 0x00000000,
249 	.grp_ddrmode = 0x00020000,
250 	.grp_ctlds = 0x30,
251 	.grp_ddr_type = 0x000c0000,
252 };
253 
254 /* configure MX6SOLO/DUALLITE mmdc DDR io registers */
255 struct mx6sdl_iomux_ddr_regs mx6sdl_ddr_ioregs = {
256 	.dram_sdclk_0 = 0x30,
257 	.dram_sdclk_1 = 0x30,
258 	.dram_cas = 0x30,
259 	.dram_ras = 0x30,
260 	.dram_reset = 0x30,
261 	.dram_sdcke0 = 0x30,
262 	.dram_sdcke1 = 0x30,
263 	.dram_sdba2 = 0x00000000,
264 	.dram_sdodt0 = 0x30,
265 	.dram_sdodt1 = 0x30,
266 	.dram_sdqs0 = 0x28,
267 	.dram_sdqs1 = 0x28,
268 	.dram_sdqs2 = 0x28,
269 	.dram_sdqs3 = 0x28,
270 	.dram_sdqs4 = 0x28,
271 	.dram_sdqs5 = 0x28,
272 	.dram_sdqs6 = 0x28,
273 	.dram_sdqs7 = 0x28,
274 	.dram_dqm0 = 0x28,
275 	.dram_dqm1 = 0x28,
276 	.dram_dqm2 = 0x28,
277 	.dram_dqm3 = 0x28,
278 	.dram_dqm4 = 0x28,
279 	.dram_dqm5 = 0x28,
280 	.dram_dqm6 = 0x28,
281 	.dram_dqm7 = 0x28,
282 };
283 
284 /* configure MX6SOLO/DUALLITE mmdc GRP io registers */
285 struct mx6sdl_iomux_grp_regs mx6sdl_grp_ioregs = {
286 	.grp_ddr_type = 0x000c0000,
287 	.grp_ddrmode_ctl = 0x00020000,
288 	.grp_ddrpke = 0x00000000,
289 	.grp_addds = 0x30,
290 	.grp_ctlds = 0x30,
291 	.grp_ddrmode = 0x00020000,
292 	.grp_b0ds = 0x28,
293 	.grp_b1ds = 0x28,
294 	.grp_b2ds = 0x28,
295 	.grp_b3ds = 0x28,
296 	.grp_b4ds = 0x28,
297 	.grp_b5ds = 0x28,
298 	.grp_b6ds = 0x28,
299 	.grp_b7ds = 0x28,
300 };
301 
302 /* mt41j256 */
303 static struct mx6_ddr3_cfg mt41j256 = {
304 	.mem_speed = 1066,
305 	.density = 2,
306 	.width = 16,
307 	.banks = 8,
308 	.rowaddr = 13,
309 	.coladdr = 10,
310 	.pagesz = 2,
311 	.trcd = 1375,
312 	.trcmin = 4875,
313 	.trasmin = 3500,
314 	.SRT = 0,
315 };
316 
317 static struct mx6_mmdc_calibration mx6dq_mmdc_calib = {
318 	.p0_mpwldectrl0 = 0x000E0009,
319 	.p0_mpwldectrl1 = 0x0018000E,
320 	.p1_mpwldectrl0 = 0x00000007,
321 	.p1_mpwldectrl1 = 0x00000000,
322 	.p0_mpdgctrl0 = 0x43280334,
323 	.p0_mpdgctrl1 = 0x031C0314,
324 	.p1_mpdgctrl0 = 0x4318031C,
325 	.p1_mpdgctrl1 = 0x030C0258,
326 	.p0_mprddlctl = 0x3E343A40,
327 	.p1_mprddlctl = 0x383C3844,
328 	.p0_mpwrdlctl = 0x40404440,
329 	.p1_mpwrdlctl = 0x4C3E4446,
330 };
331 
332 /* DDR 64bit */
333 static struct mx6_ddr_sysinfo mem_q = {
334 	.ddr_type	= DDR_TYPE_DDR3,
335 	.dsize		= 2,
336 	.cs1_mirror	= 0,
337 	/* config for full 4GB range so that get_mem_size() works */
338 	.cs_density	= 32,
339 	.ncs		= 1,
340 	.bi_on		= 1,
341 	.rtt_nom	= 2,
342 	.rtt_wr		= 2,
343 	.ralat		= 5,
344 	.walat		= 0,
345 	.mif3_mode	= 3,
346 	.rst_to_cke	= 0x23,
347 	.sde_to_rst	= 0x10,
348 };
349 
350 static struct mx6_mmdc_calibration mx6dl_mmdc_calib = {
351 	.p0_mpwldectrl0 = 0x001F0024,
352 	.p0_mpwldectrl1 = 0x00110018,
353 	.p1_mpwldectrl0 = 0x001F0024,
354 	.p1_mpwldectrl1 = 0x00110018,
355 	.p0_mpdgctrl0 = 0x4230022C,
356 	.p0_mpdgctrl1 = 0x02180220,
357 	.p1_mpdgctrl0 = 0x42440248,
358 	.p1_mpdgctrl1 = 0x02300238,
359 	.p0_mprddlctl = 0x44444A48,
360 	.p1_mprddlctl = 0x46484A42,
361 	.p0_mpwrdlctl = 0x38383234,
362 	.p1_mpwrdlctl = 0x3C34362E,
363 };
364 
365 /* DDR 64bit 1GB */
366 static struct mx6_ddr_sysinfo mem_dl = {
367 	.dsize		= 2,
368 	.cs1_mirror	= 0,
369 	/* config for full 4GB range so that get_mem_size() works */
370 	.cs_density	= 32,
371 	.ncs		= 1,
372 	.bi_on		= 1,
373 	.rtt_nom	= 1,
374 	.rtt_wr		= 1,
375 	.ralat		= 5,
376 	.walat		= 0,
377 	.mif3_mode	= 3,
378 	.rst_to_cke	= 0x23,
379 	.sde_to_rst	= 0x10,
380 };
381 
382 /* DDR 32bit 512MB */
383 static struct mx6_ddr_sysinfo mem_s = {
384 	.dsize		= 1,
385 	.cs1_mirror	= 0,
386 	/* config for full 4GB range so that get_mem_size() works */
387 	.cs_density	= 32,
388 	.ncs		= 1,
389 	.bi_on		= 1,
390 	.rtt_nom	= 1,
391 	.rtt_wr		= 1,
392 	.ralat		= 5,
393 	.walat		= 0,
394 	.mif3_mode	= 3,
395 	.rst_to_cke	= 0x23,
396 	.sde_to_rst	= 0x10,
397 };
398 
399 static void ccgr_init(void)
400 {
401 	struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
402 
403 	writel(0x00003F3F, &ccm->CCGR0);
404 	writel(0x0030FC00, &ccm->CCGR1);
405 	writel(0x000FC000, &ccm->CCGR2);
406 	writel(0x3F300000, &ccm->CCGR3);
407 	writel(0xFF00F300, &ccm->CCGR4);
408 	writel(0x0F0000C3, &ccm->CCGR5);
409 	writel(0x000003CC, &ccm->CCGR6);
410 }
411 
412 static void gpr_init(void)
413 {
414 	struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
415 
416 	/* enable AXI cache for VDOA/VPU/IPU */
417 	writel(0xF00000CF, &iomux->gpr[4]);
418 	/* set IPU AXI-id0 Qos=0xf(bypass) AXI-id1 Qos=0x7 */
419 	writel(0x007F007F, &iomux->gpr[6]);
420 	writel(0x007F007F, &iomux->gpr[7]);
421 }
422 
423 static void spl_dram_init(void)
424 {
425 	if (is_mx6solo()) {
426 		mx6sdl_dram_iocfg(32, &mx6sdl_ddr_ioregs, &mx6sdl_grp_ioregs);
427 		mx6_dram_cfg(&mem_s, &mx6dl_mmdc_calib, &mt41j256);
428 	} else if (is_mx6dl()) {
429 		mx6sdl_dram_iocfg(64, &mx6sdl_ddr_ioregs, &mx6sdl_grp_ioregs);
430 		mx6_dram_cfg(&mem_dl, &mx6dl_mmdc_calib, &mt41j256);
431 	} else if (is_mx6dq()) {
432 		mx6dq_dram_iocfg(64, &mx6dq_ddr_ioregs, &mx6dq_grp_ioregs);
433 		mx6_dram_cfg(&mem_q, &mx6dq_mmdc_calib, &mt41j256);
434 	}
435 
436 	udelay(100);
437 }
438 
439 void board_init_f(ulong dummy)
440 {
441 	ccgr_init();
442 
443 	/* setup AIPS and disable watchdog */
444 	arch_cpu_init();
445 
446 	gpr_init();
447 
448 	/* iomux */
449 	board_early_init_f();
450 
451 	/* setup GP timer */
452 	timer_init();
453 
454 	/* UART clocks enabled and gd valid - init serial console */
455 	preloader_console_init();
456 
457 	/* DDR initialization */
458 	spl_dram_init();
459 
460 	/* Clear the BSS. */
461 	memset(__bss_start, 0, __bss_end - __bss_start);
462 
463 	/* load/boot image from boot device */
464 	board_init_r(NULL, 0);
465 }
466 #endif
467