1 /*
2  * (C) Copyright 2015
3  * Heiko Schocher, DENX Software Engineering, hs@denx.de.
4  *
5  * Based on:
6  * Copyright (C) 2012 Freescale Semiconductor, Inc.
7  *
8  * Author: Fabio Estevam <fabio.estevam@freescale.com>
9  *
10  * SPDX-License-Identifier:	GPL-2.0+
11  */
12 
13 #include <asm/arch/clock.h>
14 #include <asm/arch/imx-regs.h>
15 #include <asm/arch/iomux.h>
16 #include <asm/arch/mx6-pins.h>
17 #include <asm/errno.h>
18 #include <asm/gpio.h>
19 #include <asm/imx-common/iomux-v3.h>
20 #include <asm/imx-common/boot_mode.h>
21 #include <asm/imx-common/mxc_i2c.h>
22 #include <asm/imx-common/video.h>
23 #include <mmc.h>
24 #include <fsl_esdhc.h>
25 #include <miiphy.h>
26 #include <netdev.h>
27 #include <asm/arch/mxc_hdmi.h>
28 #include <asm/arch/crm_regs.h>
29 #include <linux/fb.h>
30 #include <ipu_pixfmt.h>
31 #include <asm/io.h>
32 #include <asm/arch/sys_proto.h>
33 #include <pwm.h>
34 #include <micrel.h>
35 #include <spi.h>
36 #include <video.h>
37 #include <../drivers/video/ipu.h>
38 #if defined(CONFIG_VIDEO_BMP_LOGO)
39 	#include <bmp_logo.h>
40 #endif
41 
42 #define USDHC2_PAD_CTRL (PAD_CTL_SPEED_LOW |			\
43 	PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST)
44 
45 #define ECSPI1_CS0		IMX_GPIO_NR(4, 9)   /* 4.3 display controller */
46 #define ECSPI4_CS0		IMX_GPIO_NR(3, 29)
47 #define SOFT_RESET_GPIO		IMX_GPIO_NR(7, 13)
48 #define SD2_DRIVER_ENABLE	IMX_GPIO_NR(7, 8)
49 
50 struct i2c_pads_info i2c_pad_info3 = {
51 	.scl = {
52 		.i2c_mode = MX6_PAD_GPIO_5__I2C3_SCL | PC,
53 		.gpio_mode = MX6_PAD_GPIO_5__GPIO1_IO05 | PC,
54 		.gp = IMX_GPIO_NR(1, 5)
55 	},
56 	.sda = {
57 		.i2c_mode = MX6_PAD_GPIO_6__I2C3_SDA | PC,
58 		.gpio_mode = MX6_PAD_GPIO_6__GPIO1_IO06 | PC,
59 		.gp = IMX_GPIO_NR(1, 6)
60 	}
61 };
62 
63 struct i2c_pads_info i2c_pad_info4 = {
64 	.scl = {
65 		.i2c_mode = MX6_PAD_GPIO_7__I2C4_SCL | PC,
66 		.gpio_mode = MX6_PAD_GPIO_7__GPIO1_IO07 | PC,
67 		.gp = IMX_GPIO_NR(1, 7)
68 	},
69 	.sda = {
70 		.i2c_mode = MX6_PAD_GPIO_8__I2C4_SDA | PC,
71 		.gpio_mode = MX6_PAD_GPIO_8__GPIO1_IO08 | PC,
72 		.gp = IMX_GPIO_NR(1, 8)
73 	}
74 };
75 
76 iomux_v3_cfg_t const uart1_pads[] = {
77 	MX6_PAD_CSI0_DAT10__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
78 	MX6_PAD_CSI0_DAT11__UART1_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
79 	MX6_PAD_EIM_D19__UART1_CTS_B    | MUX_PAD_CTRL(UART_PAD_CTRL),
80 	MX6_PAD_EIM_D20__UART1_RTS_B    | MUX_PAD_CTRL(UART_PAD_CTRL),
81 };
82 
83 iomux_v3_cfg_t const uart2_pads[] = {
84 	MX6_PAD_EIM_D26__UART2_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
85 	MX6_PAD_EIM_D27__UART2_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
86 };
87 
88 iomux_v3_cfg_t const uart3_pads[] = {
89 	MX6_PAD_EIM_D24__UART3_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
90 	MX6_PAD_EIM_D25__UART3_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
91 	MX6_PAD_EIM_D31__UART3_RTS_B | MUX_PAD_CTRL(UART_PAD_CTRL),
92 	MX6_PAD_EIM_D23__UART3_CTS_B | MUX_PAD_CTRL(UART_PAD_CTRL),
93 };
94 
95 iomux_v3_cfg_t const uart4_pads[] = {
96 	MX6_PAD_KEY_COL0__UART4_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
97 	MX6_PAD_KEY_ROW0__UART4_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
98 };
99 
100 iomux_v3_cfg_t const gpio_pads[] = {
101 	/* LED enable*/
102 	MX6_PAD_ENET_CRS_DV__GPIO1_IO25 | MUX_PAD_CTRL(NO_PAD_CTRL),
103 	/* LED yellow */
104 	MX6_PAD_NANDF_CS3__GPIO6_IO16 | MUX_PAD_CTRL(NO_PAD_CTRL),
105 	/* LED red */
106 	MX6_PAD_EIM_EB0__GPIO2_IO28 | MUX_PAD_CTRL(NO_PAD_CTRL),
107 	/* LED green */
108 	MX6_PAD_EIM_A24__GPIO5_IO04 | MUX_PAD_CTRL(NO_PAD_CTRL),
109 	/* LED blue */
110 	MX6_PAD_EIM_EB1__GPIO2_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL),
111 	/* spi flash WP protect */
112 	MX6_PAD_SD4_DAT7__GPIO2_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL),
113 	/* spi CS 0 */
114 	MX6_PAD_EIM_D29__GPIO3_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL),
115 	/* spi bus #2 SS driver enable */
116 	MX6_PAD_EIM_A23__GPIO6_IO06 | MUX_PAD_CTRL(NO_PAD_CTRL),
117 	/* RST_LOC# PHY reset input (has pull-down!)*/
118 	MX6_PAD_GPIO_18__GPIO7_IO13 | MUX_PAD_CTRL(NO_PAD_CTRL),
119 	/* SD 2 level shifter output enable */
120 	MX6_PAD_SD3_RST__GPIO7_IO08 | MUX_PAD_CTRL(NO_PAD_CTRL),
121 	/* SD1 card detect input */
122 	MX6_PAD_ENET_RXD0__GPIO1_IO27 | MUX_PAD_CTRL(NO_PAD_CTRL),
123 	/* SD1 write protect input */
124 	MX6_PAD_DI0_PIN4__GPIO4_IO20 | MUX_PAD_CTRL(NO_PAD_CTRL),
125 	/* SD2 card detect input */
126 	MX6_PAD_GPIO_19__GPIO4_IO05 | MUX_PAD_CTRL(NO_PAD_CTRL),
127 	/* SD2 write protect input */
128 	MX6_PAD_SD4_DAT2__GPIO2_IO10 | MUX_PAD_CTRL(NO_PAD_CTRL),
129 	/* Touchscreen IRQ */
130 	MX6_PAD_SD4_DAT1__GPIO2_IO09 | MUX_PAD_CTRL(NO_PAD_CTRL),
131 };
132 
133 static iomux_v3_cfg_t const misc_pads[] = {
134 	/* USB_OTG_ID = GPIO1_24*/
135 	MX6_PAD_ENET_RX_ER__USB_OTG_ID		| MUX_PAD_CTRL(NO_PAD_CTRL),
136 	/* H1 Power enable = GPIO1_0*/
137 	MX6_PAD_GPIO_0__USB_H1_PWR		| MUX_PAD_CTRL(NO_PAD_CTRL),
138 	/* OTG Power enable = GPIO4_15*/
139 	MX6_PAD_KEY_ROW4__USB_OTG_PWR		| MUX_PAD_CTRL(NO_PAD_CTRL),
140 };
141 
142 iomux_v3_cfg_t const enet_pads[] = {
143 	MX6_PAD_ENET_MDIO__ENET_MDIO		| MUX_PAD_CTRL(ENET_PAD_CTRL),
144 	MX6_PAD_ENET_MDC__ENET_MDC		| MUX_PAD_CTRL(ENET_PAD_CTRL),
145 	MX6_PAD_RGMII_TXC__RGMII_TXC	| MUX_PAD_CTRL(ENET_PAD_CTRL),
146 	MX6_PAD_RGMII_TD0__RGMII_TD0	| MUX_PAD_CTRL(ENET_PAD_CTRL),
147 	MX6_PAD_RGMII_TD1__RGMII_TD1	| MUX_PAD_CTRL(ENET_PAD_CTRL),
148 	MX6_PAD_RGMII_TD2__RGMII_TD2	| MUX_PAD_CTRL(ENET_PAD_CTRL),
149 	MX6_PAD_RGMII_TD3__RGMII_TD3	| MUX_PAD_CTRL(ENET_PAD_CTRL),
150 	MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL	| MUX_PAD_CTRL(ENET_PAD_CTRL),
151 	MX6_PAD_ENET_REF_CLK__ENET_TX_CLK	| MUX_PAD_CTRL(ENET_PAD_CTRL),
152 	MX6_PAD_RGMII_RXC__RGMII_RXC	| MUX_PAD_CTRL(ENET_PAD_CTRL),
153 	MX6_PAD_RGMII_RD0__RGMII_RD0	| MUX_PAD_CTRL(ENET_PAD_CTRL),
154 	MX6_PAD_RGMII_RD1__RGMII_RD1	| MUX_PAD_CTRL(ENET_PAD_CTRL),
155 	MX6_PAD_RGMII_RD2__RGMII_RD2	| MUX_PAD_CTRL(ENET_PAD_CTRL),
156 	MX6_PAD_RGMII_RD3__RGMII_RD3	| MUX_PAD_CTRL(ENET_PAD_CTRL),
157 	MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL	| MUX_PAD_CTRL(ENET_PAD_CTRL),
158 };
159 
160 static iomux_v3_cfg_t const backlight_pads[] = {
161 	/* backlight PWM brightness control */
162 	MX6_PAD_GPIO_9__PWM1_OUT | MUX_PAD_CTRL(NO_PAD_CTRL),
163 	/* backlight enable */
164 	MX6_PAD_EIM_BCLK__GPIO6_IO31 | MUX_PAD_CTRL(NO_PAD_CTRL),
165 	/* LCD power enable */
166 	MX6_PAD_NANDF_CS2__GPIO6_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL),
167 };
168 
169 static iomux_v3_cfg_t const ecspi1_pads[] = {
170 	MX6_PAD_EIM_D16__ECSPI1_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL),
171 	MX6_PAD_EIM_D17__ECSPI1_MISO | MUX_PAD_CTRL(SPI_PAD_CTRL),
172 	MX6_PAD_EIM_D18__ECSPI1_MOSI | MUX_PAD_CTRL(SPI_PAD_CTRL),
173 	MX6_PAD_KEY_ROW1__GPIO4_IO09 | MUX_PAD_CTRL(SPI_PAD_CTRL),
174 };
175 
176 static void setup_iomux_enet(void)
177 {
178 	imx_iomux_v3_setup_multiple_pads(enet_pads, ARRAY_SIZE(enet_pads));
179 }
180 
181 iomux_v3_cfg_t const ecspi4_pads[] = {
182 	MX6_PAD_EIM_D21__ECSPI4_SCLK | MUX_PAD_CTRL(NO_PAD_CTRL),
183 	MX6_PAD_EIM_D22__ECSPI4_MISO | MUX_PAD_CTRL(NO_PAD_CTRL),
184 	MX6_PAD_EIM_D28__ECSPI4_MOSI | MUX_PAD_CTRL(NO_PAD_CTRL),
185 	MX6_PAD_EIM_A25__GPIO5_IO02  | MUX_PAD_CTRL(NO_PAD_CTRL),
186 	MX6_PAD_EIM_D29__GPIO3_IO29  | MUX_PAD_CTRL(NO_PAD_CTRL),
187 };
188 
189 static iomux_v3_cfg_t const display_pads[] = {
190 	MX6_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK | MUX_PAD_CTRL(DISP_PAD_CTRL),
191 	MX6_PAD_DI0_PIN15__IPU1_DI0_PIN15,
192 	MX6_PAD_DI0_PIN2__IPU1_DI0_PIN02,
193 	MX6_PAD_DI0_PIN3__IPU1_DI0_PIN03,
194 	MX6_PAD_DISP0_DAT0__IPU1_DISP0_DATA00,
195 	MX6_PAD_DISP0_DAT1__IPU1_DISP0_DATA01,
196 	MX6_PAD_DISP0_DAT2__IPU1_DISP0_DATA02,
197 	MX6_PAD_DISP0_DAT3__IPU1_DISP0_DATA03,
198 	MX6_PAD_DISP0_DAT4__IPU1_DISP0_DATA04,
199 	MX6_PAD_DISP0_DAT5__IPU1_DISP0_DATA05,
200 	MX6_PAD_DISP0_DAT6__IPU1_DISP0_DATA06,
201 	MX6_PAD_DISP0_DAT7__IPU1_DISP0_DATA07,
202 	MX6_PAD_DISP0_DAT8__IPU1_DISP0_DATA08,
203 	MX6_PAD_DISP0_DAT9__IPU1_DISP0_DATA09,
204 	MX6_PAD_DISP0_DAT10__IPU1_DISP0_DATA10,
205 	MX6_PAD_DISP0_DAT11__IPU1_DISP0_DATA11,
206 	MX6_PAD_DISP0_DAT12__IPU1_DISP0_DATA12,
207 	MX6_PAD_DISP0_DAT13__IPU1_DISP0_DATA13,
208 	MX6_PAD_DISP0_DAT14__IPU1_DISP0_DATA14,
209 	MX6_PAD_DISP0_DAT15__IPU1_DISP0_DATA15,
210 	MX6_PAD_DISP0_DAT16__IPU1_DISP0_DATA16,
211 	MX6_PAD_DISP0_DAT17__IPU1_DISP0_DATA17,
212 	MX6_PAD_DISP0_DAT18__IPU1_DISP0_DATA18,
213 	MX6_PAD_DISP0_DAT19__IPU1_DISP0_DATA19,
214 	MX6_PAD_DISP0_DAT20__IPU1_DISP0_DATA20,
215 	MX6_PAD_DISP0_DAT21__IPU1_DISP0_DATA21,
216 	MX6_PAD_DISP0_DAT22__IPU1_DISP0_DATA22,
217 	MX6_PAD_DISP0_DAT23__IPU1_DISP0_DATA23,
218 };
219 
220 int board_spi_cs_gpio(unsigned bus, unsigned cs)
221 {
222 	if (bus == CONFIG_SF_DEFAULT_BUS && cs == CONFIG_SF_DEFAULT_CS)
223 		return IMX_GPIO_NR(5, 2);
224 
225 	if (bus == 0 && cs == 0)
226 		return IMX_GPIO_NR(4, 9);
227 
228 	return -1;
229 }
230 
231 static void setup_spi(void)
232 {
233 	int i;
234 
235 	imx_iomux_v3_setup_multiple_pads(ecspi1_pads, ARRAY_SIZE(ecspi1_pads));
236 	imx_iomux_v3_setup_multiple_pads(ecspi4_pads, ARRAY_SIZE(ecspi4_pads));
237 	for (i = 0; i < 4; i++)
238 		enable_spi_clk(true, i);
239 
240 	gpio_direction_output(ECSPI1_CS0, 1);
241 	gpio_direction_output(ECSPI4_CS1, 0);
242 
243 	/* set cs0 to high (second device on spi bus #4) */
244 	gpio_direction_output(ECSPI4_CS0, 1);
245 }
246 
247 static void setup_iomux_uart(void)
248 {
249 	switch (CONFIG_MXC_UART_BASE) {
250 	case UART1_BASE:
251 		imx_iomux_v3_setup_multiple_pads(uart1_pads,
252 						 ARRAY_SIZE(uart1_pads));
253 		break;
254 	case UART2_BASE:
255 		imx_iomux_v3_setup_multiple_pads(uart2_pads,
256 						 ARRAY_SIZE(uart2_pads));
257 		break;
258 	case UART3_BASE:
259 		imx_iomux_v3_setup_multiple_pads(uart3_pads,
260 						 ARRAY_SIZE(uart3_pads));
261 		break;
262 	case UART4_BASE:
263 		imx_iomux_v3_setup_multiple_pads(uart4_pads,
264 						 ARRAY_SIZE(uart4_pads));
265 		break;
266 	}
267 }
268 
269 int board_phy_config(struct phy_device *phydev)
270 {
271 	/* control data pad skew - devaddr = 0x02, register = 0x04 */
272 	ksz9031_phy_extended_write(phydev, 0x02,
273 				   MII_KSZ9031_EXT_RGMII_CTRL_SIG_SKEW,
274 				   MII_KSZ9031_MOD_DATA_NO_POST_INC, 0x0000);
275 	/* rx data pad skew - devaddr = 0x02, register = 0x05 */
276 	ksz9031_phy_extended_write(phydev, 0x02,
277 				   MII_KSZ9031_EXT_RGMII_RX_DATA_SKEW,
278 				   MII_KSZ9031_MOD_DATA_NO_POST_INC, 0x0000);
279 	/* tx data pad skew - devaddr = 0x02, register = 0x06 */
280 	ksz9031_phy_extended_write(phydev, 0x02,
281 				   MII_KSZ9031_EXT_RGMII_TX_DATA_SKEW,
282 				   MII_KSZ9031_MOD_DATA_NO_POST_INC, 0x0000);
283 	/* gtx and rx clock pad skew - devaddr = 0x02, register = 0x08 */
284 	ksz9031_phy_extended_write(phydev, 0x02,
285 				   MII_KSZ9031_EXT_RGMII_CLOCK_SKEW,
286 				   MII_KSZ9031_MOD_DATA_NO_POST_INC, 0x03FF);
287 
288 	if (phydev->drv->config)
289 		phydev->drv->config(phydev);
290 
291 	return 0;
292 }
293 
294 int board_eth_init(bd_t *bis)
295 {
296 	setup_iomux_enet();
297 	return cpu_eth_init(bis);
298 }
299 
300 static int rotate_logo_one(unsigned char *out, unsigned char *in)
301 {
302 	int   i, j;
303 
304 	for (i = 0; i < BMP_LOGO_WIDTH; i++)
305 		for (j = 0; j < BMP_LOGO_HEIGHT; j++)
306 			out[j * BMP_LOGO_WIDTH + BMP_LOGO_HEIGHT - 1 - i] =
307 			in[i * BMP_LOGO_WIDTH + j];
308 	return 0;
309 }
310 
311 /*
312  * Rotate the BMP_LOGO (only)
313  * Will only work, if the logo is square, as
314  * BMP_LOGO_HEIGHT and BMP_LOGO_WIDTH are defines, not variables
315  */
316 void rotate_logo(int rotations)
317 {
318 	unsigned char out_logo[BMP_LOGO_WIDTH * BMP_LOGO_HEIGHT];
319 	unsigned char *in_logo;
320 	int   i, j;
321 
322 	if (BMP_LOGO_WIDTH != BMP_LOGO_HEIGHT)
323 		return;
324 
325 	in_logo = bmp_logo_bitmap;
326 
327 	/* one 90 degree rotation */
328 	if (rotations == 1  ||  rotations == 2  ||  rotations == 3)
329 		rotate_logo_one(out_logo, in_logo);
330 
331 	/* second 90 degree rotation */
332 	if (rotations == 2  ||  rotations == 3)
333 		rotate_logo_one(in_logo, out_logo);
334 
335 	/* third 90 degree rotation */
336 	if (rotations == 3)
337 		rotate_logo_one(out_logo, in_logo);
338 
339 	/* copy result back to original array */
340 	if (rotations == 1  ||  rotations == 3)
341 		for (i = 0; i < BMP_LOGO_WIDTH; i++)
342 			for (j = 0; j < BMP_LOGO_HEIGHT; j++)
343 				in_logo[i * BMP_LOGO_WIDTH + j] =
344 				out_logo[i * BMP_LOGO_WIDTH + j];
345 }
346 
347 static void enable_display_power(void)
348 {
349 	imx_iomux_v3_setup_multiple_pads(backlight_pads,
350 					 ARRAY_SIZE(backlight_pads));
351 
352 	/* backlight enable */
353 	gpio_direction_output(IMX_GPIO_NR(6, 31), 1);
354 	/* LCD power enable */
355 	gpio_direction_output(IMX_GPIO_NR(6, 15), 1);
356 
357 	/* enable backlight PWM 1 */
358 	if (pwm_init(0, 0, 0))
359 		goto error;
360 	/* duty cycle 500ns, period: 3000ns */
361 	if (pwm_config(0, 50000, 300000))
362 		goto error;
363 	if (pwm_enable(0))
364 		goto error;
365 	return;
366 
367 error:
368 	puts("error init pwm for backlight\n");
369 	return;
370 }
371 
372 static void enable_lvds(struct display_info_t const *dev)
373 {
374 	struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
375 	struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
376 	int reg;
377 	s32 timeout = 100000;
378 
379 	/* set PLL5 clock */
380 	reg = readl(&ccm->analog_pll_video);
381 	reg |= BM_ANADIG_PLL_VIDEO_POWERDOWN;
382 	writel(reg, &ccm->analog_pll_video);
383 
384 	/* set PLL5 to 232720000Hz */
385 	reg &= ~BM_ANADIG_PLL_VIDEO_DIV_SELECT;
386 	reg |= BF_ANADIG_PLL_VIDEO_DIV_SELECT(0x26);
387 	reg &= ~BM_ANADIG_PLL_VIDEO_POST_DIV_SELECT;
388 	reg |= BF_ANADIG_PLL_VIDEO_POST_DIV_SELECT(0);
389 	writel(reg, &ccm->analog_pll_video);
390 
391 	writel(BF_ANADIG_PLL_VIDEO_NUM_A(0xC0238),
392 	       &ccm->analog_pll_video_num);
393 	writel(BF_ANADIG_PLL_VIDEO_DENOM_B(0xF4240),
394 	       &ccm->analog_pll_video_denom);
395 
396 	reg &= ~BM_ANADIG_PLL_VIDEO_POWERDOWN;
397 	writel(reg, &ccm->analog_pll_video);
398 
399 	while (timeout--)
400 		if (readl(&ccm->analog_pll_video) & BM_ANADIG_PLL_VIDEO_LOCK)
401 			break;
402 	if (timeout < 0)
403 		printf("Warning: video pll lock timeout!\n");
404 
405 	reg = readl(&ccm->analog_pll_video);
406 	reg |= BM_ANADIG_PLL_VIDEO_ENABLE;
407 	reg &= ~BM_ANADIG_PLL_VIDEO_BYPASS;
408 	writel(reg, &ccm->analog_pll_video);
409 
410 	/* set LDB0, LDB1 clk select to 000/000 (PLL5 clock) */
411 	reg = readl(&ccm->cs2cdr);
412 	reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK
413 		 | MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK);
414 	reg |= (0 << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET)
415 		| (0 << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET);
416 	writel(reg, &ccm->cs2cdr);
417 
418 	reg = readl(&ccm->cscmr2);
419 	reg |= MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV;
420 	writel(reg, &ccm->cscmr2);
421 
422 	reg = readl(&ccm->chsccdr);
423 	reg |= (CHSCCDR_CLK_SEL_LDB_DI0
424 		<< MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET);
425 	writel(reg, &ccm->chsccdr);
426 
427 	reg = IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES
428 	      | IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_HIGH
429 	      | IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_HIGH
430 	      | IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG
431 	      | IOMUXC_GPR2_DATA_WIDTH_CH0_24BIT
432 	      | IOMUXC_GPR2_LVDS_CH1_MODE_DISABLED
433 	      | IOMUXC_GPR2_LVDS_CH0_MODE_ENABLED_DI0;
434 	writel(reg, &iomux->gpr[2]);
435 
436 	reg = readl(&iomux->gpr[3]);
437 	reg = (reg & ~IOMUXC_GPR3_LVDS0_MUX_CTL_MASK)
438 	       | (IOMUXC_GPR3_MUX_SRC_IPU1_DI0
439 		  << IOMUXC_GPR3_LVDS0_MUX_CTL_OFFSET);
440 	writel(reg, &iomux->gpr[3]);
441 
442 	return;
443 }
444 
445 static void enable_spi_display(struct display_info_t const *dev)
446 {
447 	struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
448 	struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
449 	int reg;
450 	s32 timeout = 100000;
451 
452 #if defined(CONFIG_VIDEO_BMP_LOGO)
453 	rotate_logo(3);  /* portrait display in landscape mode */
454 #endif
455 
456 	/*
457 	 * set ldb clock to 28341000 Hz calculated through the formula:
458 	 * (XRES + LEFT_M + RIGHT_M + HSYNC_LEN) *
459 	 * (YRES + UPPER_M + LOWER_M + VSYNC_LEN) * REFRESH)
460 	 * see:
461 	 * https://community.freescale.com/thread/308170
462 	 */
463 	ipu_set_ldb_clock(28341000);
464 
465 	reg = readl(&ccm->cs2cdr);
466 
467 	/* select pll 5 clock */
468 	reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK
469 		| MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK);
470 	writel(reg, &ccm->cs2cdr);
471 
472 	/* set PLL5 to 197994996Hz */
473 	reg &= ~BM_ANADIG_PLL_VIDEO_DIV_SELECT;
474 	reg |= BF_ANADIG_PLL_VIDEO_DIV_SELECT(0x21);
475 	reg &= ~BM_ANADIG_PLL_VIDEO_POST_DIV_SELECT;
476 	reg |= BF_ANADIG_PLL_VIDEO_POST_DIV_SELECT(0);
477 	writel(reg, &ccm->analog_pll_video);
478 
479 	writel(BF_ANADIG_PLL_VIDEO_NUM_A(0xfbf4),
480 	       &ccm->analog_pll_video_num);
481 	writel(BF_ANADIG_PLL_VIDEO_DENOM_B(0xf4240),
482 	       &ccm->analog_pll_video_denom);
483 
484 	reg &= ~BM_ANADIG_PLL_VIDEO_POWERDOWN;
485 	writel(reg, &ccm->analog_pll_video);
486 
487 	while (timeout--)
488 		if (readl(&ccm->analog_pll_video) & BM_ANADIG_PLL_VIDEO_LOCK)
489 			break;
490 	if (timeout < 0)
491 		printf("Warning: video pll lock timeout!\n");
492 
493 	reg = readl(&ccm->analog_pll_video);
494 	reg |= BM_ANADIG_PLL_VIDEO_ENABLE;
495 	reg &= ~BM_ANADIG_PLL_VIDEO_BYPASS;
496 	writel(reg, &ccm->analog_pll_video);
497 
498 	/* set LDB0, LDB1 clk select to 000/000 (PLL5 clock) */
499 	reg = readl(&ccm->cs2cdr);
500 	reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK
501 		 | MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK);
502 	reg |= (0 << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET)
503 		| (0 << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET);
504 	writel(reg, &ccm->cs2cdr);
505 
506 	reg = readl(&ccm->cscmr2);
507 	reg |= MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV;
508 	writel(reg, &ccm->cscmr2);
509 
510 	reg = readl(&ccm->chsccdr);
511 	reg |= (CHSCCDR_CLK_SEL_LDB_DI0
512 		<< MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET);
513 	reg &= ~MXC_CCM_CHSCCDR_IPU1_DI0_PODF_MASK;
514 	reg |= (2 << MXC_CCM_CHSCCDR_IPU1_DI0_PODF_OFFSET);
515 	reg &= ~MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_MASK;
516 	reg |= (2 << MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_OFFSET);
517 	writel(reg, &ccm->chsccdr);
518 
519 	reg = IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES
520 	      | IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_HIGH
521 	      | IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_HIGH
522 	      | IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG
523 	      | IOMUXC_GPR2_DATA_WIDTH_CH0_24BIT
524 	      | IOMUXC_GPR2_LVDS_CH1_MODE_DISABLED
525 	      | IOMUXC_GPR2_LVDS_CH0_MODE_ENABLED_DI0;
526 	writel(reg, &iomux->gpr[2]);
527 
528 	reg = readl(&iomux->gpr[3]);
529 	reg = (reg & ~IOMUXC_GPR3_LVDS0_MUX_CTL_MASK)
530 	       | (IOMUXC_GPR3_MUX_SRC_IPU1_DI0
531 		  << IOMUXC_GPR3_LVDS0_MUX_CTL_OFFSET);
532 	writel(reg, &iomux->gpr[3]);
533 
534 	imx_iomux_v3_setup_multiple_pads(
535 		display_pads,
536 		 ARRAY_SIZE(display_pads));
537 
538 	return;
539 }
540 static void setup_display(void)
541 {
542 	enable_ipu_clock();
543 	enable_display_power();
544 }
545 
546 static void setup_iomux_gpio(void)
547 {
548 	imx_iomux_v3_setup_multiple_pads(gpio_pads, ARRAY_SIZE(gpio_pads));
549 }
550 
551 int board_early_init_f(void)
552 {
553 	setup_iomux_uart();
554 	setup_iomux_gpio();
555 
556 	gpio_direction_output(SOFT_RESET_GPIO, 1);
557 	gpio_direction_output(SD2_DRIVER_ENABLE, 1);
558 	setup_display();
559 	return 0;
560 }
561 
562 static void setup_i2c4(void)
563 {
564 	setup_i2c(3, CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE,
565 		  &i2c_pad_info4);
566 }
567 
568 static void setup_board_gpio(void)
569 {
570 	/* enable all LEDs */
571 	gpio_request(IMX_GPIO_NR(2, 13), "LED ena"); /* 25 */
572 	gpio_direction_output(IMX_GPIO_NR(1, 25), 0);
573 
574 	/* switch off Status LEDs */
575 	gpio_request(IMX_GPIO_NR(6, 16), "LED yellow"); /* 176 */
576 	gpio_direction_output(IMX_GPIO_NR(6, 16), 1);
577 	gpio_request(IMX_GPIO_NR(2, 28), "LED red"); /* 60 */
578 	gpio_direction_output(IMX_GPIO_NR(2, 28), 1);
579 	gpio_request(IMX_GPIO_NR(5, 4), "LED green"); /* 132 */
580 	gpio_direction_output(IMX_GPIO_NR(5, 4), 1);
581 	gpio_request(IMX_GPIO_NR(2, 29), "LED blue"); /* 61 */
582 	gpio_direction_output(IMX_GPIO_NR(2, 29), 1);
583 }
584 
585 static void setup_board_spi(void)
586 {
587 	/* enable spi bus #2 SS drivers */
588 	gpio_direction_output(IMX_GPIO_NR(6, 6), 1);
589 }
590 
591 int board_late_init(void)
592 {
593 	char *my_bootdelay;
594 	char bootmode = 0;
595 	char const *panel = getenv("panel");
596 
597 	/*
598 	 * Check the boot-source. If booting from NOR Flash,
599 	 * disable bootdelay
600 	 */
601 	gpio_request(IMX_GPIO_NR(7, 6), "bootsel0");
602 	gpio_direction_input(IMX_GPIO_NR(7, 6));
603 	gpio_request(IMX_GPIO_NR(7, 7), "bootsel1");
604 	gpio_direction_input(IMX_GPIO_NR(7, 7));
605 	gpio_request(IMX_GPIO_NR(7, 1), "bootsel2");
606 	gpio_direction_input(IMX_GPIO_NR(7, 1));
607 	bootmode |= (gpio_get_value(IMX_GPIO_NR(7, 6)) ? 1 : 0) << 0;
608 	bootmode |= (gpio_get_value(IMX_GPIO_NR(7, 7)) ? 1 : 0) << 1;
609 	bootmode |= (gpio_get_value(IMX_GPIO_NR(7, 1)) ? 1 : 0) << 2;
610 
611 	if (bootmode == 7) {
612 		my_bootdelay = getenv("nor_bootdelay");
613 		if (my_bootdelay != NULL)
614 			setenv("bootdelay", my_bootdelay);
615 		else
616 			setenv("bootdelay", "-2");
617 	}
618 
619 	/* if we have the lg panel, we can initialze it now */
620 	if (panel)
621 		if (!strcmp(panel, displays[1].mode.name))
622 			lg4573_spi_startup(0, 0, 10000000, SPI_MODE_0);
623 
624 	return 0;
625 }
626 
627