1 /*
2  * Copyright 2015 Toradex, Inc.
3  *
4  * Based on vf610twr.c:
5  * Copyright 2013 Freescale Semiconductor, Inc.
6  *
7  * SPDX-License-Identifier:	GPL-2.0+
8  */
9 
10 #include <common.h>
11 #include <asm/io.h>
12 #include <asm/arch/imx-regs.h>
13 #include <asm/arch/iomux-vf610.h>
14 #include <asm/arch/ddrmc-vf610.h>
15 #include <asm/arch/crm_regs.h>
16 #include <asm/arch/clock.h>
17 #include <mmc.h>
18 #include <fsl_esdhc.h>
19 #include <miiphy.h>
20 #include <netdev.h>
21 #include <i2c.h>
22 #include <g_dnl.h>
23 
24 DECLARE_GLOBAL_DATA_PTR;
25 
26 #define UART_PAD_CTRL	(PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
27 			PAD_CTL_DSE_25ohm | PAD_CTL_OBE_IBE_ENABLE)
28 
29 #define ESDHC_PAD_CTRL	(PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_HIGH | \
30 			PAD_CTL_DSE_20ohm | PAD_CTL_OBE_IBE_ENABLE)
31 
32 #define ENET_PAD_CTRL	(PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_HIGH | \
33 			PAD_CTL_DSE_50ohm | PAD_CTL_OBE_IBE_ENABLE)
34 
35 int dram_init(void)
36 {
37 	static const struct ddr3_jedec_timings timings = {
38 		.tinit           = 5,
39 		.trst_pwron      = 80000,
40 		.cke_inactive    = 200000,
41 		.wrlat           = 5,
42 		.caslat_lin      = 12,
43 		.trc             = 21,
44 		.trrd            = 4,
45 		.tccd            = 4,
46 		.tfaw            = 20,
47 		.trp             = 6,
48 		.twtr            = 4,
49 		.tras_min        = 15,
50 		.tmrd            = 4,
51 		.trtp            = 4,
52 		.tras_max        = 28080,
53 		.tmod            = 12,
54 		.tckesr          = 4,
55 		.tcke            = 3,
56 		.trcd_int        = 6,
57 		.tdal            = 12,
58 		.tdll            = 512,
59 		.trp_ab          = 6,
60 		.tref            = 3120,
61 		.trfc            = 64,
62 		.tpdex           = 3,
63 		.txpdll          = 10,
64 		.txsnr           = 48,
65 		.txsr            = 468,
66 		.cksrx           = 5,
67 		.cksre           = 5,
68 		.zqcl            = 256,
69 		.zqinit          = 512,
70 		.zqcs            = 64,
71 		.ref_per_zq      = 64,
72 		.aprebit         = 10,
73 		.wlmrd           = 40,
74 		.wldqsen         = 25,
75 	};
76 
77 	ddrmc_setup_iomux();
78 
79 	ddrmc_ctrl_init_ddr3(&timings, NULL, 1, 2);
80 	gd->ram_size = get_ram_size((void *)PHYS_SDRAM, PHYS_SDRAM_SIZE);
81 
82 	return 0;
83 }
84 
85 static void setup_iomux_uart(void)
86 {
87 	static const iomux_v3_cfg_t uart_pads[] = {
88 		NEW_PAD_CTRL(VF610_PAD_PTB4__UART1_TX, UART_PAD_CTRL),
89 		NEW_PAD_CTRL(VF610_PAD_PTB5__UART1_RX, UART_PAD_CTRL),
90 		NEW_PAD_CTRL(VF610_PAD_PTB10__UART0_TX, UART_PAD_CTRL),
91 		NEW_PAD_CTRL(VF610_PAD_PTB11__UART0_RX, UART_PAD_CTRL),
92 	};
93 
94 	imx_iomux_v3_setup_multiple_pads(uart_pads, ARRAY_SIZE(uart_pads));
95 }
96 
97 static void setup_iomux_enet(void)
98 {
99 	static const iomux_v3_cfg_t enet0_pads[] = {
100 		NEW_PAD_CTRL(VF610_PAD_PTA6__RMII0_CLKOUT, ENET_PAD_CTRL),
101 		NEW_PAD_CTRL(VF610_PAD_PTC10__RMII1_MDIO, ENET_PAD_CTRL),
102 		NEW_PAD_CTRL(VF610_PAD_PTC9__RMII1_MDC, ENET_PAD_CTRL),
103 		NEW_PAD_CTRL(VF610_PAD_PTC11__RMII1_CRS_DV, ENET_PAD_CTRL),
104 		NEW_PAD_CTRL(VF610_PAD_PTC12__RMII1_RD1, ENET_PAD_CTRL),
105 		NEW_PAD_CTRL(VF610_PAD_PTC13__RMII1_RD0, ENET_PAD_CTRL),
106 		NEW_PAD_CTRL(VF610_PAD_PTC14__RMII1_RXER, ENET_PAD_CTRL),
107 		NEW_PAD_CTRL(VF610_PAD_PTC15__RMII1_TD1, ENET_PAD_CTRL),
108 		NEW_PAD_CTRL(VF610_PAD_PTC16__RMII1_TD0, ENET_PAD_CTRL),
109 		NEW_PAD_CTRL(VF610_PAD_PTC17__RMII1_TXEN, ENET_PAD_CTRL),
110 	};
111 
112 	imx_iomux_v3_setup_multiple_pads(enet0_pads, ARRAY_SIZE(enet0_pads));
113 }
114 
115 static void setup_iomux_i2c(void)
116 {
117 	static const iomux_v3_cfg_t i2c0_pads[] = {
118 		VF610_PAD_PTB14__I2C0_SCL,
119 		VF610_PAD_PTB15__I2C0_SDA,
120 	};
121 
122 	imx_iomux_v3_setup_multiple_pads(i2c0_pads, ARRAY_SIZE(i2c0_pads));
123 }
124 
125 #ifdef CONFIG_NAND_VF610_NFC
126 static void setup_iomux_nfc(void)
127 {
128 	static const iomux_v3_cfg_t nfc_pads[] = {
129 		VF610_PAD_PTD23__NF_IO7,
130 		VF610_PAD_PTD22__NF_IO6,
131 		VF610_PAD_PTD21__NF_IO5,
132 		VF610_PAD_PTD20__NF_IO4,
133 		VF610_PAD_PTD19__NF_IO3,
134 		VF610_PAD_PTD18__NF_IO2,
135 		VF610_PAD_PTD17__NF_IO1,
136 		VF610_PAD_PTD16__NF_IO0,
137 		VF610_PAD_PTB24__NF_WE_B,
138 		VF610_PAD_PTB25__NF_CE0_B,
139 		VF610_PAD_PTB27__NF_RE_B,
140 		VF610_PAD_PTC26__NF_RB_B,
141 		VF610_PAD_PTC27__NF_ALE,
142 		VF610_PAD_PTC28__NF_CLE
143 	};
144 
145 	imx_iomux_v3_setup_multiple_pads(nfc_pads, ARRAY_SIZE(nfc_pads));
146 }
147 #endif
148 
149 #ifdef CONFIG_FSL_ESDHC
150 struct fsl_esdhc_cfg esdhc_cfg[1] = {
151 	{ESDHC1_BASE_ADDR},
152 };
153 
154 int board_mmc_getcd(struct mmc *mmc)
155 {
156 	/* eSDHC1 is always present */
157 	return 1;
158 }
159 
160 int board_mmc_init(bd_t *bis)
161 {
162 	static const iomux_v3_cfg_t esdhc1_pads[] = {
163 		NEW_PAD_CTRL(VF610_PAD_PTA24__ESDHC1_CLK, ESDHC_PAD_CTRL),
164 		NEW_PAD_CTRL(VF610_PAD_PTA25__ESDHC1_CMD, ESDHC_PAD_CTRL),
165 		NEW_PAD_CTRL(VF610_PAD_PTA26__ESDHC1_DAT0, ESDHC_PAD_CTRL),
166 		NEW_PAD_CTRL(VF610_PAD_PTA27__ESDHC1_DAT1, ESDHC_PAD_CTRL),
167 		NEW_PAD_CTRL(VF610_PAD_PTA28__ESDHC1_DAT2, ESDHC_PAD_CTRL),
168 		NEW_PAD_CTRL(VF610_PAD_PTA29__ESDHC1_DAT3, ESDHC_PAD_CTRL),
169 	};
170 
171 	esdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
172 
173 	imx_iomux_v3_setup_multiple_pads(
174 		esdhc1_pads, ARRAY_SIZE(esdhc1_pads));
175 
176 	return fsl_esdhc_initialize(bis, &esdhc_cfg[0]);
177 }
178 #endif
179 
180 static inline int is_colibri_vf61(void)
181 {
182 	struct mscm *mscm = (struct mscm *)MSCM_BASE_ADDR;
183 
184 	/*
185 	 * Detect board type by Level 2 Cache: VF50 don't have any
186 	 * Level 2 Cache.
187 	 */
188 	return !!mscm->cpxcfg1;
189 }
190 
191 static void clock_init(void)
192 {
193 	struct ccm_reg *ccm = (struct ccm_reg *)CCM_BASE_ADDR;
194 	struct anadig_reg *anadig = (struct anadig_reg *)ANADIG_BASE_ADDR;
195 	u32 pfd_clk_sel, ddr_clk_sel;
196 
197 	clrsetbits_le32(&ccm->ccgr0, CCM_REG_CTRL_MASK,
198 			CCM_CCGR0_UART0_CTRL_MASK);
199 	clrsetbits_le32(&ccm->ccgr1, CCM_REG_CTRL_MASK,
200 			CCM_CCGR1_PIT_CTRL_MASK | CCM_CCGR1_WDOGA5_CTRL_MASK);
201 	clrsetbits_le32(&ccm->ccgr2, CCM_REG_CTRL_MASK,
202 			CCM_CCGR2_IOMUXC_CTRL_MASK | CCM_CCGR2_PORTA_CTRL_MASK |
203 			CCM_CCGR2_PORTB_CTRL_MASK | CCM_CCGR2_PORTC_CTRL_MASK |
204 			CCM_CCGR2_PORTD_CTRL_MASK | CCM_CCGR2_PORTE_CTRL_MASK);
205 	clrsetbits_le32(&ccm->ccgr3, CCM_REG_CTRL_MASK,
206 			CCM_CCGR3_ANADIG_CTRL_MASK | CCM_CCGR3_SCSC_CTRL_MASK);
207 	clrsetbits_le32(&ccm->ccgr4, CCM_REG_CTRL_MASK,
208 			CCM_CCGR4_WKUP_CTRL_MASK | CCM_CCGR4_CCM_CTRL_MASK |
209 			CCM_CCGR4_GPC_CTRL_MASK | CCM_CCGR4_I2C0_CTRL_MASK);
210 	clrsetbits_le32(&ccm->ccgr6, CCM_REG_CTRL_MASK,
211 			CCM_CCGR6_OCOTP_CTRL_MASK | CCM_CCGR6_DDRMC_CTRL_MASK);
212 	clrsetbits_le32(&ccm->ccgr7, CCM_REG_CTRL_MASK,
213 			CCM_CCGR7_SDHC1_CTRL_MASK);
214 	clrsetbits_le32(&ccm->ccgr9, CCM_REG_CTRL_MASK,
215 			CCM_CCGR9_FEC0_CTRL_MASK | CCM_CCGR9_FEC1_CTRL_MASK);
216 	clrsetbits_le32(&ccm->ccgr10, CCM_REG_CTRL_MASK,
217 			CCM_CCGR10_NFC_CTRL_MASK);
218 
219 #ifdef CONFIG_CI_UDC
220 	setbits_le32(&ccm->ccgr1, CCM_CCGR1_USBC0_CTRL_MASK);
221 #endif
222 
223 #ifdef CONFIG_USB_EHCI
224 	setbits_le32(&ccm->ccgr7, CCM_CCGR7_USBC1_CTRL_MASK);
225 #endif
226 
227 	clrsetbits_le32(&anadig->pll5_ctrl, ANADIG_PLL5_CTRL_BYPASS |
228 			ANADIG_PLL5_CTRL_POWERDOWN, ANADIG_PLL5_CTRL_ENABLE |
229 			ANADIG_PLL5_CTRL_DIV_SELECT);
230 
231 	if (is_colibri_vf61()) {
232 		clrsetbits_le32(&anadig->pll2_ctrl, ANADIG_PLL5_CTRL_BYPASS |
233 				ANADIG_PLL2_CTRL_POWERDOWN,
234 				ANADIG_PLL2_CTRL_ENABLE |
235 				ANADIG_PLL2_CTRL_DIV_SELECT);
236 	}
237 
238 	clrsetbits_le32(&anadig->pll1_ctrl, ANADIG_PLL1_CTRL_POWERDOWN,
239 			ANADIG_PLL1_CTRL_ENABLE | ANADIG_PLL1_CTRL_DIV_SELECT);
240 
241 	clrsetbits_le32(&ccm->ccr, CCM_CCR_OSCNT_MASK,
242 			CCM_CCR_FIRC_EN | CCM_CCR_OSCNT(5));
243 
244 	/* See "Typical PLL Configuration" */
245 	if (is_colibri_vf61()) {
246 		pfd_clk_sel = CCM_CCSR_PLL1_PFD_CLK_SEL(1);
247 		ddr_clk_sel = CCM_CCSR_DDRC_CLK_SEL(0);
248 	} else {
249 		pfd_clk_sel = CCM_CCSR_PLL1_PFD_CLK_SEL(3);
250 		ddr_clk_sel = CCM_CCSR_DDRC_CLK_SEL(1);
251 	}
252 
253 	clrsetbits_le32(&ccm->ccsr, CCM_REG_CTRL_MASK, pfd_clk_sel |
254 			CCM_CCSR_PLL2_PFD4_EN | CCM_CCSR_PLL2_PFD3_EN |
255 			CCM_CCSR_PLL2_PFD2_EN | CCM_CCSR_PLL2_PFD1_EN |
256 			CCM_CCSR_PLL1_PFD4_EN | CCM_CCSR_PLL1_PFD3_EN |
257 			CCM_CCSR_PLL1_PFD2_EN | CCM_CCSR_PLL1_PFD1_EN |
258 			ddr_clk_sel | CCM_CCSR_FAST_CLK_SEL(1) |
259 			CCM_CCSR_SYS_CLK_SEL(4));
260 
261 	clrsetbits_le32(&ccm->cacrr, CCM_REG_CTRL_MASK,
262 			CCM_CACRR_IPG_CLK_DIV(1) | CCM_CACRR_BUS_CLK_DIV(2) |
263 			CCM_CACRR_ARM_CLK_DIV(0));
264 	clrsetbits_le32(&ccm->cscmr1, CCM_REG_CTRL_MASK,
265 			CCM_CSCMR1_ESDHC1_CLK_SEL(3) |
266 			CCM_CSCMR1_NFC_CLK_SEL(0));
267 	clrsetbits_le32(&ccm->cscdr1, CCM_REG_CTRL_MASK,
268 			CCM_CSCDR1_RMII_CLK_EN);
269 	clrsetbits_le32(&ccm->cscdr2, CCM_REG_CTRL_MASK,
270 			CCM_CSCDR2_ESDHC1_EN | CCM_CSCDR2_ESDHC1_CLK_DIV(0) |
271 			CCM_CSCDR2_NFC_EN);
272 	clrsetbits_le32(&ccm->cscdr3, CCM_REG_CTRL_MASK,
273 			CCM_CSCDR3_NFC_PRE_DIV(5));
274 	clrsetbits_le32(&ccm->cscmr2, CCM_REG_CTRL_MASK,
275 			CCM_CSCMR2_RMII_CLK_SEL(2));
276 }
277 
278 static void mscm_init(void)
279 {
280 	struct mscm_ir *mscmir = (struct mscm_ir *)MSCM_IR_BASE_ADDR;
281 	int i;
282 
283 	for (i = 0; i < MSCM_IRSPRC_NUM; i++)
284 		writew(MSCM_IRSPRC_CP0_EN, &mscmir->irsprc[i]);
285 }
286 
287 int board_phy_config(struct phy_device *phydev)
288 {
289 	if (phydev->drv->config)
290 		phydev->drv->config(phydev);
291 
292 	return 0;
293 }
294 
295 int board_early_init_f(void)
296 {
297 	clock_init();
298 	mscm_init();
299 
300 	setup_iomux_uart();
301 	setup_iomux_enet();
302 	setup_iomux_i2c();
303 #ifdef CONFIG_NAND_VF610_NFC
304 	setup_iomux_nfc();
305 #endif
306 
307 	return 0;
308 }
309 
310 #ifdef CONFIG_BOARD_LATE_INIT
311 int board_late_init(void)
312 {
313 	struct src *src = (struct src *)SRC_BASE_ADDR;
314 
315 	/* Default memory arguments */
316 	if (!getenv("memargs")) {
317 		switch (gd->ram_size) {
318 		case 0x08000000:
319 			/* 128 MB */
320 			setenv("memargs", "mem=128M");
321 			break;
322 		case 0x10000000:
323 			/* 256 MB */
324 			setenv("memargs", "mem=256M");
325 			break;
326 		default:
327 			printf("Failed detecting RAM size.\n");
328 		}
329 	}
330 
331 	if (((src->sbmr2 & SRC_SBMR2_BMOD_MASK) >> SRC_SBMR2_BMOD_SHIFT)
332 			== SRC_SBMR2_BMOD_SERIAL) {
333 		printf("Serial Downloader recovery mode, disable autoboot\n");
334 		setenv("bootdelay", "-1");
335 	}
336 
337 	return 0;
338 }
339 #endif /* CONFIG_BOARD_LATE_INIT */
340 
341 int board_init(void)
342 {
343 	struct scsc_reg *scsc = (struct scsc_reg *)SCSC_BASE_ADDR;
344 
345 	/* address of boot parameters */
346 	gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
347 
348 	/*
349 	 * Enable external 32K Oscillator
350 	 *
351 	 * The internal clock experiences significant drift
352 	 * so we must use the external oscillator in order
353 	 * to maintain correct time in the hwclock
354 	 */
355 
356 	setbits_le32(&scsc->sosc_ctr, SCSC_SOSC_CTR_SOSC_EN);
357 
358 	return 0;
359 }
360 
361 int checkboard(void)
362 {
363 	if (is_colibri_vf61())
364 		puts("Board: Colibri VF61\n");
365 	else
366 		puts("Board: Colibri VF50\n");
367 
368 	return 0;
369 }
370 
371 int g_dnl_bind_fixup(struct usb_device_descriptor *dev, const char *name)
372 {
373 	unsigned short usb_pid;
374 
375 	put_unaligned(CONFIG_TRDX_VID, &dev->idVendor);
376 
377 	if (is_colibri_vf61())
378 		usb_pid = CONFIG_TRDX_PID_COLIBRI_VF61IT;
379 	else
380 		usb_pid = CONFIG_TRDX_PID_COLIBRI_VF50IT;
381 
382 	put_unaligned(usb_pid, &dev->idProduct);
383 
384 	return 0;
385 }
386