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