1 /*
2  * Copyright (C) 2010-2011 Freescale Semiconductor, Inc.
3  * Based on mx6qsabrelite.c file
4  * Copyright (C) 2013, Adeneo Embedded <www.adeneo-embedded.com>
5  * Leo Sartre, <lsartre@adeneo-embedded.com>
6  *
7  * SPDX-License-Identifier:	GPL-2.0+
8  */
9 
10 #include <common.h>
11 #include <asm/io.h>
12 #include <asm/arch/clock.h>
13 #include <asm/arch/imx-regs.h>
14 #include <asm/arch/iomux.h>
15 #include <asm/arch/mx6-pins.h>
16 #include <asm/gpio.h>
17 #include <asm/imx-common/iomux-v3.h>
18 #include <asm/imx-common/sata.h>
19 #include <asm/imx-common/boot_mode.h>
20 #include <asm/imx-common/mxc_i2c.h>
21 #include <asm/arch/mxc_hdmi.h>
22 #include <asm/arch/crm_regs.h>
23 #include <mmc.h>
24 #include <fsl_esdhc.h>
25 #include <i2c.h>
26 #include <power/pmic.h>
27 #include <power/pfuze100_pmic.h>
28 #include <linux/fb.h>
29 #include <ipu_pixfmt.h>
30 #include <malloc.h>
31 #include <miiphy.h>
32 #include <netdev.h>
33 #include <micrel.h>
34 
35 DECLARE_GLOBAL_DATA_PTR;
36 
37 #define UART_PAD_CTRL  (PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED |\
38 	PAD_CTL_DSE_40ohm   | PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
39 
40 #define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP  | PAD_CTL_SPEED_LOW |\
41 	PAD_CTL_DSE_80ohm   | PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
42 
43 #define I2C_PAD_CTRL	(PAD_CTL_PKE | PAD_CTL_PUE |		\
44 	PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED |		\
45 	PAD_CTL_DSE_40ohm | PAD_CTL_HYS |			\
46 	PAD_CTL_ODE | PAD_CTL_SRE_FAST)
47 
48 #define MX6Q_QMX6_PFUZE_MUX		IMX_GPIO_NR(6, 9)
49 
50 
51 #define ENET_PAD_CTRL  (PAD_CTL_PKE | PAD_CTL_PUE |		\
52 	PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED   |		\
53 	PAD_CTL_DSE_40ohm   | PAD_CTL_HYS)
54 
55 int dram_init(void)
56 {
57 	gd->ram_size = get_ram_size((void *)PHYS_SDRAM, PHYS_SDRAM_SIZE);
58 
59 	return 0;
60 }
61 
62 static iomux_v3_cfg_t const uart2_pads[] = {
63 	MX6_PAD_EIM_D26__UART2_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
64 	MX6_PAD_EIM_D27__UART2_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
65 };
66 
67 static iomux_v3_cfg_t const usdhc2_pads[] = {
68 	MX6_PAD_SD2_CLK__SD2_CLK   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
69 	MX6_PAD_SD2_CMD__SD2_CMD   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
70 	MX6_PAD_SD2_DAT0__SD2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
71 	MX6_PAD_SD2_DAT1__SD2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
72 	MX6_PAD_SD2_DAT2__SD2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
73 	MX6_PAD_SD2_DAT3__SD2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
74 	MX6_PAD_GPIO_4__GPIO1_IO04      | MUX_PAD_CTRL(USDHC_PAD_CTRL),
75 };
76 
77 static iomux_v3_cfg_t const usdhc3_pads[] = {
78 	MX6_PAD_SD3_CLK__SD3_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
79 	MX6_PAD_SD3_CMD__SD3_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
80 	MX6_PAD_SD3_DAT0__SD3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
81 	MX6_PAD_SD3_DAT1__SD3_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
82 	MX6_PAD_SD3_DAT2__SD3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
83 	MX6_PAD_SD3_DAT3__SD3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
84 	MX6_PAD_SD3_DAT4__SD3_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
85 	MX6_PAD_SD3_DAT5__SD3_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
86 	MX6_PAD_SD3_DAT6__SD3_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
87 	MX6_PAD_SD3_DAT7__SD3_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
88 	MX6_PAD_SD3_RST__SD3_RESET | MUX_PAD_CTRL(USDHC_PAD_CTRL),
89 };
90 
91 static iomux_v3_cfg_t const usdhc4_pads[] = {
92 	MX6_PAD_SD4_CLK__SD4_CLK   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
93 	MX6_PAD_SD4_CMD__SD4_CMD   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
94 	MX6_PAD_SD4_DAT0__SD4_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
95 	MX6_PAD_SD4_DAT1__SD4_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
96 	MX6_PAD_SD4_DAT2__SD4_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
97 	MX6_PAD_SD4_DAT3__SD4_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
98 	MX6_PAD_SD4_DAT4__SD4_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
99 	MX6_PAD_SD4_DAT5__SD4_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
100 	MX6_PAD_SD4_DAT6__SD4_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
101 	MX6_PAD_SD4_DAT7__SD4_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
102 	MX6_PAD_NANDF_D6__GPIO2_IO06    | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */
103 };
104 
105 static iomux_v3_cfg_t const usb_otg_pads[] = {
106 	MX6_PAD_EIM_D22__USB_OTG_PWR | MUX_PAD_CTRL(NO_PAD_CTRL),
107 	MX6_PAD_GPIO_1__USB_OTG_ID | MUX_PAD_CTRL(NO_PAD_CTRL),
108 };
109 
110 static iomux_v3_cfg_t enet_pads_ksz9031[] = {
111 	MX6_PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL),
112 	MX6_PAD_ENET_MDC__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL),
113 	MX6_PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
114 	MX6_PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
115 	MX6_PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
116 	MX6_PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
117 	MX6_PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
118 	MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
119 	MX6_PAD_ENET_REF_CLK__ENET_TX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL),
120 	MX6_PAD_RGMII_RXC__GPIO6_IO30 | MUX_PAD_CTRL(NO_PAD_CTRL),
121 	MX6_PAD_RGMII_RD0__GPIO6_IO25 | MUX_PAD_CTRL(NO_PAD_CTRL),
122 	MX6_PAD_RGMII_RD1__GPIO6_IO27 | MUX_PAD_CTRL(NO_PAD_CTRL),
123 	MX6_PAD_RGMII_RD2__GPIO6_IO28 | MUX_PAD_CTRL(NO_PAD_CTRL),
124 	MX6_PAD_RGMII_RD3__GPIO6_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL),
125 	MX6_PAD_RGMII_RX_CTL__GPIO6_IO24 | MUX_PAD_CTRL(NO_PAD_CTRL),
126 };
127 
128 static iomux_v3_cfg_t enet_pads_final_ksz9031[] = {
129 	MX6_PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
130 	MX6_PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
131 	MX6_PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
132 	MX6_PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
133 	MX6_PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
134 	MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
135 };
136 
137 static iomux_v3_cfg_t enet_pads_ar8035[] = {
138 	MX6_PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL),
139 	MX6_PAD_ENET_MDC__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL),
140 	MX6_PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
141 	MX6_PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
142 	MX6_PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
143 	MX6_PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
144 	MX6_PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
145 	MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
146 	MX6_PAD_ENET_REF_CLK__ENET_TX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL),
147 	MX6_PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
148 	MX6_PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
149 	MX6_PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
150 	MX6_PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
151 	MX6_PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
152 	MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
153 };
154 
155 #define PC MUX_PAD_CTRL(I2C_PAD_CTRL)
156 struct i2c_pads_info i2c_pad_info1 = {
157 	.scl = {
158 		.i2c_mode = MX6_PAD_KEY_COL3__I2C2_SCL | PC,
159 		.gpio_mode = MX6_PAD_KEY_COL3__GPIO4_IO12 | PC,
160 		.gp = IMX_GPIO_NR(4, 12)
161 	},
162 	.sda = {
163 		.i2c_mode = MX6_PAD_KEY_ROW3__I2C2_SDA | PC,
164 		.gpio_mode = MX6_PAD_KEY_ROW3__GPIO4_IO13 | PC,
165 		.gp = IMX_GPIO_NR(4, 13)
166 	}
167 };
168 
169 #define I2C_PMIC	1	/* I2C2 port is used to connect to the PMIC */
170 
171 struct interface_level {
172 	char *name;
173 	uchar value;
174 };
175 
176 static struct interface_level mipi_levels[] = {
177 	{"0V0", 0x00},
178 	{"2V5", 0x17},
179 };
180 
181 /* setup board specific PMIC */
182 int power_init_board(void)
183 {
184 	struct pmic *p;
185 	u32 id1, id2, i;
186 	int ret;
187 	char const *lv_mipi;
188 
189 	/* configure I2C multiplexer */
190 	gpio_direction_output(MX6Q_QMX6_PFUZE_MUX, 1);
191 
192 	power_pfuze100_init(I2C_PMIC);
193 	p = pmic_get("PFUZE100");
194 	if (!p)
195 		return -EINVAL;
196 
197 	ret = pmic_probe(p);
198 	if (ret)
199 		return ret;
200 
201 	pmic_reg_read(p, PFUZE100_DEVICEID, &id1);
202 	pmic_reg_read(p, PFUZE100_REVID, &id2);
203 	printf("PFUZE100 Rev. [%02x/%02x] detected\n", id1, id2);
204 
205 	if (id2 >= 0x20)
206 		return 0;
207 
208 	/* set level of MIPI if specified */
209 	lv_mipi = getenv("lv_mipi");
210 	if (lv_mipi)
211 		return 0;
212 
213 	for (i = 0; i < ARRAY_SIZE(mipi_levels); i++) {
214 		if (!strcmp(mipi_levels[i].name, lv_mipi)) {
215 			printf("set MIPI level %s\n",
216 			       mipi_levels[i].name);
217 			ret = pmic_reg_write(p, PFUZE100_VGEN4VOL,
218 					     mipi_levels[i].value);
219 			if (ret)
220 				return ret;
221 		}
222 	}
223 
224 	return 0;
225 }
226 
227 int board_eth_init(bd_t *bis)
228 {
229 	struct phy_device *phydev;
230 	struct mii_dev *bus;
231 	unsigned short id1, id2;
232 	int ret;
233 
234 	iomux_v3_cfg_t enet_reset = MX6_PAD_EIM_D23__GPIO3_IO23 |
235 				    MUX_PAD_CTRL(NO_PAD_CTRL);
236 
237 	/* check whether KSZ9031 or AR8035 has to be configured */
238 	imx_iomux_v3_setup_multiple_pads(enet_pads_ar8035,
239 					 ARRAY_SIZE(enet_pads_ar8035));
240 	imx_iomux_v3_setup_pad(enet_reset);
241 
242 	/* phy reset */
243 	gpio_direction_output(IMX_GPIO_NR(3, 23), 0);
244 	udelay(2000);
245 	gpio_set_value(IMX_GPIO_NR(3, 23), 1);
246 	udelay(500);
247 
248 	bus = fec_get_miibus(IMX_FEC_BASE, -1);
249 	if (!bus)
250 		return -EINVAL;
251 	phydev = phy_find_by_mask(bus, (0xf << 4), PHY_INTERFACE_MODE_RGMII);
252 	if (!phydev) {
253 		printf("Error: phy device not found.\n");
254 		ret = -ENODEV;
255 		goto free_bus;
256 	}
257 
258 	/* get the PHY id */
259 	id1 = phy_read(phydev, MDIO_DEVAD_NONE, 2);
260 	id2 = phy_read(phydev, MDIO_DEVAD_NONE, 3);
261 
262 	if ((id1 == 0x22) && ((id2 & 0xFFF0) == 0x1620)) {
263 		/* re-configure for Micrel KSZ9031 */
264 		printf("configure Micrel KSZ9031 Ethernet Phy at address %d\n",
265 		       phydev->addr);
266 
267 		/* phy reset: gpio3-23 */
268 		gpio_set_value(IMX_GPIO_NR(3, 23), 0);
269 		gpio_set_value(IMX_GPIO_NR(6, 30), (phydev->addr >> 2));
270 		gpio_set_value(IMX_GPIO_NR(6, 25), 1);
271 		gpio_set_value(IMX_GPIO_NR(6, 27), 1);
272 		gpio_set_value(IMX_GPIO_NR(6, 28), 1);
273 		gpio_set_value(IMX_GPIO_NR(6, 29), 1);
274 		imx_iomux_v3_setup_multiple_pads(enet_pads_ksz9031,
275 						 ARRAY_SIZE(enet_pads_ksz9031));
276 		gpio_set_value(IMX_GPIO_NR(6, 24), 1);
277 		udelay(500);
278 		gpio_set_value(IMX_GPIO_NR(3, 23), 1);
279 		imx_iomux_v3_setup_multiple_pads(enet_pads_final_ksz9031,
280 						 ARRAY_SIZE(enet_pads_final_ksz9031));
281 	} else if ((id1 == 0x004d) && (id2 == 0xd072)) {
282 		/* configure Atheros AR8035 - actually nothing to do */
283 		printf("configure Atheros AR8035 Ethernet Phy at address %d\n",
284 		       phydev->addr);
285 	} else {
286 		printf("Unknown Ethernet-Phy: 0x%04x 0x%04x\n", id1, id2);
287 		ret = -EINVAL;
288 		goto free_phydev;
289 	}
290 
291 	ret = fec_probe(bis, -1, IMX_FEC_BASE, bus, phydev);
292 	if (ret)
293 		goto free_phydev;
294 
295 	return 0;
296 
297 free_phydev:
298 	free(phydev);
299 free_bus:
300 	free(bus);
301 	return ret;
302 }
303 
304 int mx6_rgmii_rework(struct phy_device *phydev)
305 {
306 	unsigned short id1, id2;
307 	unsigned short val;
308 
309 	/* check whether KSZ9031 or AR8035 has to be configured */
310 	id1 = phy_read(phydev, MDIO_DEVAD_NONE, 2);
311 	id2 = phy_read(phydev, MDIO_DEVAD_NONE, 3);
312 
313 	if ((id1 == 0x22) && ((id2 & 0xFFF0) == 0x1620)) {
314 		/* finalize phy configuration for Micrel KSZ9031 */
315 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, 2);
316 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 4);
317 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, MII_KSZ9031_MOD_DATA_POST_INC_W | 0x2);
318 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 0x0000);
319 
320 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, 2);
321 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 5);
322 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, MII_KSZ9031_MOD_DATA_POST_INC_W | 0x2);
323 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, MII_KSZ9031_MOD_REG);
324 
325 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, 2);
326 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 6);
327 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, MII_KSZ9031_MOD_DATA_POST_INC_W | 0x2);
328 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 0xFFFF);
329 
330 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, 2);
331 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 8);
332 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, MII_KSZ9031_MOD_DATA_POST_INC_W | 0x2);
333 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 0x3FFF);
334 
335 		/* fix KSZ9031 link up issue */
336 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, 0x0);
337 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 0x4);
338 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, MII_KSZ9031_MOD_DATA_NO_POST_INC);
339 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 0x6);
340 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, MII_KSZ9031_MOD_REG);
341 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 0x3);
342 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, MII_KSZ9031_MOD_DATA_NO_POST_INC);
343 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 0x1A80);
344 	}
345 
346 	if ((id1 == 0x004d) && (id2 == 0xd072)) {
347 		/* enable AR8035 ouput a 125MHz clk from CLK_25M */
348 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, 0x7);
349 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, MII_KSZ9031_MOD_DATA_POST_INC_RW | 0x16);
350 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, MII_KSZ9031_MOD_DATA_NO_POST_INC | 0x7);
351 		val = phy_read(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA);
352 		val &= 0xfe63;
353 		val |= 0x18;
354 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, val);
355 
356 		/* introduce tx clock delay */
357 		phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x5);
358 		val = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e);
359 		val |= 0x0100;
360 		phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, val);
361 
362 		/* disable hibernation */
363 		phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0xb);
364 		val = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e);
365 		phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x3c40);
366 	}
367 	return 0;
368 }
369 
370 int board_phy_config(struct phy_device *phydev)
371 {
372 	mx6_rgmii_rework(phydev);
373 
374 	if (phydev->drv->config)
375 		phydev->drv->config(phydev);
376 
377 	return 0;
378 }
379 
380 static void setup_iomux_uart(void)
381 {
382 	imx_iomux_v3_setup_multiple_pads(uart2_pads, ARRAY_SIZE(uart2_pads));
383 }
384 
385 #ifdef CONFIG_FSL_ESDHC
386 static struct fsl_esdhc_cfg usdhc_cfg[] = {
387 	{USDHC2_BASE_ADDR},
388 	{USDHC3_BASE_ADDR},
389 	{USDHC4_BASE_ADDR},
390 };
391 
392 int board_mmc_getcd(struct mmc *mmc)
393 {
394 	struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
395 	int ret = 0;
396 
397 	switch (cfg->esdhc_base) {
398 	case USDHC2_BASE_ADDR:
399 		gpio_direction_input(IMX_GPIO_NR(1, 4));
400 		ret = !gpio_get_value(IMX_GPIO_NR(1, 4));
401 		break;
402 	case USDHC3_BASE_ADDR:
403 		ret = 1;	/* eMMC is always present */
404 		break;
405 	case USDHC4_BASE_ADDR:
406 		gpio_direction_input(IMX_GPIO_NR(2, 6));
407 		ret = !gpio_get_value(IMX_GPIO_NR(2, 6));
408 		break;
409 	default:
410 		printf("Bad USDHC interface\n");
411 	}
412 
413 	return ret;
414 }
415 
416 int board_mmc_init(bd_t *bis)
417 {
418 	s32 status = 0;
419 	int i;
420 
421 	usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
422 	usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
423 	usdhc_cfg[2].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
424 
425 	imx_iomux_v3_setup_multiple_pads(usdhc2_pads, ARRAY_SIZE(usdhc2_pads));
426 	imx_iomux_v3_setup_multiple_pads(usdhc3_pads, ARRAY_SIZE(usdhc3_pads));
427 	imx_iomux_v3_setup_multiple_pads(usdhc4_pads, ARRAY_SIZE(usdhc4_pads));
428 
429 	for (i = 0; i < ARRAY_SIZE(usdhc_cfg); i++) {
430 		status = fsl_esdhc_initialize(bis, &usdhc_cfg[i]);
431 		if (status)
432 			return status;
433 	}
434 
435 	return 0;
436 }
437 #endif
438 
439 int board_ehci_hcd_init(int port)
440 {
441 	switch (port) {
442 	case 0:
443 		imx_iomux_v3_setup_multiple_pads(usb_otg_pads,
444 						 ARRAY_SIZE(usb_otg_pads));
445 		/*
446 		 * set daisy chain for otg_pin_id on 6q.
447 		 * for 6dl, this bit is reserved
448 		 */
449 		imx_iomux_set_gpr_register(1, 13, 1, 1);
450 		break;
451 	case 1:
452 		/* nothing to do */
453 		break;
454 	default:
455 		printf("Invalid USB port: %d\n", port);
456 		return -EINVAL;
457 	}
458 
459 	return 0;
460 }
461 
462 int board_ehci_power(int port, int on)
463 {
464 	switch (port) {
465 	case 0:
466 		break;
467 	case 1:
468 		gpio_direction_output(IMX_GPIO_NR(5, 5), on);
469 		break;
470 	default:
471 		printf("Invalid USB port: %d\n", port);
472 		return -EINVAL;
473 	}
474 
475 	return 0;
476 }
477 
478 struct display_info_t {
479 	int bus;
480 	int addr;
481 	int pixfmt;
482 	int (*detect)(struct display_info_t const *dev);
483 	void (*enable)(struct display_info_t const *dev);
484 	struct fb_videomode mode;
485 };
486 
487 static void disable_lvds(struct display_info_t const *dev)
488 {
489 	struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
490 
491 	clrbits_le32(&iomux->gpr[2], IOMUXC_GPR2_LVDS_CH0_MODE_MASK |
492 		     IOMUXC_GPR2_LVDS_CH1_MODE_MASK);
493 }
494 
495 static void do_enable_hdmi(struct display_info_t const *dev)
496 {
497 	disable_lvds(dev);
498 	imx_enable_hdmi_phy();
499 }
500 
501 static struct display_info_t const displays[] = {
502 {
503 	.bus = -1,
504 	.addr = 0,
505 	.pixfmt = IPU_PIX_FMT_RGB666,
506 	.detect = NULL,
507 	.enable = NULL,
508 	.mode = {
509 		.name =
510 		"Hannstar-XGA",
511 		.refresh = 60,
512 		.xres = 1024,
513 		.yres = 768,
514 		.pixclock = 15385,
515 		.left_margin = 220,
516 		.right_margin = 40,
517 		.upper_margin = 21,
518 		.lower_margin = 7,
519 		.hsync_len = 60,
520 		.vsync_len = 10,
521 		.sync = FB_SYNC_EXT,
522 		.vmode = FB_VMODE_NONINTERLACED } },
523 {
524 	.bus = -1,
525 	.addr = 0,
526 	.pixfmt = IPU_PIX_FMT_RGB24,
527 	.detect = NULL,
528 	.enable = do_enable_hdmi,
529 	.mode = {
530 		.name = "HDMI",
531 		.refresh = 60,
532 		.xres = 1024,
533 		.yres = 768,
534 		.pixclock = 15385,
535 		.left_margin = 220,
536 		.right_margin = 40,
537 		.upper_margin = 21,
538 		.lower_margin = 7,
539 		.hsync_len = 60,
540 		.vsync_len = 10,
541 		.sync = FB_SYNC_EXT,
542 		.vmode = FB_VMODE_NONINTERLACED } }
543 };
544 
545 int board_video_skip(void)
546 {
547 	int i;
548 	int ret;
549 	char const *panel = getenv("panel");
550 	if (!panel) {
551 		for (i = 0; i < ARRAY_SIZE(displays); i++) {
552 			struct display_info_t const *dev = displays + i;
553 			if (dev->detect && dev->detect(dev)) {
554 				panel = dev->mode.name;
555 				printf("auto-detected panel %s\n", panel);
556 				break;
557 			}
558 		}
559 		if (!panel) {
560 			panel = displays[0].mode.name;
561 			printf("No panel detected: default to %s\n", panel);
562 			i = 0;
563 		}
564 	} else {
565 		for (i = 0; i < ARRAY_SIZE(displays); i++) {
566 			if (!strcmp(panel, displays[i].mode.name))
567 				break;
568 		}
569 	}
570 	if (i < ARRAY_SIZE(displays)) {
571 		ret = ipuv3_fb_init(&displays[i].mode, 0, displays[i].pixfmt);
572 		if (!ret) {
573 			if (displays[i].enable)
574 				displays[i].enable(displays + i);
575 			printf("Display: %s (%ux%u)\n",
576 			       displays[i].mode.name, displays[i].mode.xres,
577 			       displays[i].mode.yres);
578 		} else
579 			printf("LCD %s cannot be configured: %d\n",
580 			       displays[i].mode.name, ret);
581 	} else {
582 		printf("unsupported panel %s\n", panel);
583 		return -EINVAL;
584 	}
585 
586 	return 0;
587 }
588 
589 static void setup_display(void)
590 {
591 	struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
592 	struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
593 	int reg;
594 
595 	enable_ipu_clock();
596 	imx_setup_hdmi();
597 
598 	/* Turn on LDB0, LDB1, IPU,IPU DI0 clocks */
599 	setbits_le32(&mxc_ccm->CCGR3, MXC_CCM_CCGR3_LDB_DI0_MASK |
600 		     MXC_CCM_CCGR3_LDB_DI1_MASK);
601 
602 	/* set LDB0, LDB1 clk select to 011/011 */
603 	reg = readl(&mxc_ccm->cs2cdr);
604 	reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK |
605 		 MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK);
606 	reg |= (3 << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET) |
607 		(3 << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET);
608 	writel(reg, &mxc_ccm->cs2cdr);
609 
610 	setbits_le32(&mxc_ccm->cscmr2, MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV |
611 		     MXC_CCM_CSCMR2_LDB_DI1_IPU_DIV);
612 
613 	setbits_le32(&mxc_ccm->chsccdr, CHSCCDR_CLK_SEL_LDB_DI0 <<
614 		     MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET |
615 		     CHSCCDR_CLK_SEL_LDB_DI0 <<
616 		     MXC_CCM_CHSCCDR_IPU1_DI1_CLK_SEL_OFFSET);
617 
618 	reg = IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES
619 		| IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_LOW
620 		| IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_LOW
621 		| IOMUXC_GPR2_BIT_MAPPING_CH1_SPWG
622 		| IOMUXC_GPR2_DATA_WIDTH_CH1_18BIT
623 		| IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG
624 		| IOMUXC_GPR2_DATA_WIDTH_CH0_18BIT
625 		| IOMUXC_GPR2_LVDS_CH0_MODE_DISABLED
626 		| IOMUXC_GPR2_LVDS_CH1_MODE_ENABLED_DI0;
627 	writel(reg, &iomux->gpr[2]);
628 
629 	reg = readl(&iomux->gpr[3]);
630 	reg = (reg & ~(IOMUXC_GPR3_LVDS1_MUX_CTL_MASK |
631 		       IOMUXC_GPR3_HDMI_MUX_CTL_MASK)) |
632 		(IOMUXC_GPR3_MUX_SRC_IPU1_DI0 <<
633 		 IOMUXC_GPR3_LVDS1_MUX_CTL_OFFSET);
634 	writel(reg, &iomux->gpr[3]);
635 }
636 
637 /*
638  * Do not overwrite the console
639  * Use always serial for U-Boot console
640  */
641 int overwrite_console(void)
642 {
643 	return 1;
644 }
645 
646 int board_early_init_f(void)
647 {
648 	setup_iomux_uart();
649 	setup_display();
650 
651 	return 0;
652 }
653 
654 int board_init(void)
655 {
656 	/* address of boot parameters */
657 	gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
658 
659 	setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1);
660 
661 #ifdef CONFIG_CMD_SATA
662 	setup_sata();
663 #endif
664 
665 	return 0;
666 }
667 
668 int checkboard(void)
669 {
670 	puts("Board: Conga-QEVAL QMX6 Quad\n");
671 
672 	return 0;
673 }
674 
675 #ifdef CONFIG_CMD_BMODE
676 static const struct boot_mode board_boot_modes[] = {
677 	/* 4 bit bus width */
678 	{"mmc0",	MAKE_CFGVAL(0x50, 0x20, 0x00, 0x00)},
679 	{"mmc1",	MAKE_CFGVAL(0x50, 0x38, 0x00, 0x00)},
680 	{NULL,		0},
681 };
682 #endif
683 
684 int misc_init_r(void)
685 {
686 #ifdef CONFIG_CMD_BMODE
687 	add_board_boot_modes(board_boot_modes);
688 #endif
689 	return 0;
690 }
691