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", mipi_levels[i].name);
216 			ret = pmic_reg_write(p, PFUZE100_VGEN4VOL,
217 					     mipi_levels[i].value);
218 			if (ret)
219 				return ret;
220 		}
221 	}
222 
223 	return 0;
224 }
225 
226 int board_eth_init(bd_t *bis)
227 {
228 	struct phy_device *phydev;
229 	struct mii_dev *bus;
230 	unsigned short id1, id2;
231 	int ret;
232 
233 	iomux_v3_cfg_t enet_reset = MX6_PAD_EIM_D23__GPIO3_IO23 |
234 				    MUX_PAD_CTRL(NO_PAD_CTRL);
235 
236 	/* check whether KSZ9031 or AR8035 has to be configured */
237 	imx_iomux_v3_setup_multiple_pads(enet_pads_ar8035,
238 					 ARRAY_SIZE(enet_pads_ar8035));
239 	imx_iomux_v3_setup_pad(enet_reset);
240 
241 	/* phy reset */
242 	gpio_direction_output(IMX_GPIO_NR(3, 23), 0);
243 	udelay(2000);
244 	gpio_set_value(IMX_GPIO_NR(3, 23), 1);
245 	udelay(500);
246 
247 	bus = fec_get_miibus(IMX_FEC_BASE, -1);
248 	if (!bus)
249 		return -EINVAL;
250 	phydev = phy_find_by_mask(bus, (0xf << 4), PHY_INTERFACE_MODE_RGMII);
251 	if (!phydev) {
252 		printf("Error: phy device not found.\n");
253 		ret = -ENODEV;
254 		goto free_bus;
255 	}
256 
257 	/* get the PHY id */
258 	id1 = phy_read(phydev, MDIO_DEVAD_NONE, 2);
259 	id2 = phy_read(phydev, MDIO_DEVAD_NONE, 3);
260 
261 	if ((id1 == 0x22) && ((id2 & 0xFFF0) == 0x1620)) {
262 		/* re-configure for Micrel KSZ9031 */
263 		printf("configure Micrel KSZ9031 Ethernet Phy at address %d\n",
264 		       phydev->addr);
265 
266 		/* phy reset: gpio3-23 */
267 		gpio_set_value(IMX_GPIO_NR(3, 23), 0);
268 		gpio_set_value(IMX_GPIO_NR(6, 30), (phydev->addr >> 2));
269 		gpio_set_value(IMX_GPIO_NR(6, 25), 1);
270 		gpio_set_value(IMX_GPIO_NR(6, 27), 1);
271 		gpio_set_value(IMX_GPIO_NR(6, 28), 1);
272 		gpio_set_value(IMX_GPIO_NR(6, 29), 1);
273 		imx_iomux_v3_setup_multiple_pads(enet_pads_ksz9031,
274 						 ARRAY_SIZE(enet_pads_ksz9031));
275 		gpio_set_value(IMX_GPIO_NR(6, 24), 1);
276 		udelay(500);
277 		gpio_set_value(IMX_GPIO_NR(3, 23), 1);
278 		imx_iomux_v3_setup_multiple_pads(enet_pads_final_ksz9031,
279 						 ARRAY_SIZE(enet_pads_final_ksz9031));
280 	} else if ((id1 == 0x004d) && (id2 == 0xd072)) {
281 		/* configure Atheros AR8035 - actually nothing to do */
282 		printf("configure Atheros AR8035 Ethernet Phy at address %d\n",
283 		       phydev->addr);
284 	} else {
285 		printf("Unknown Ethernet-Phy: 0x%04x 0x%04x\n", id1, id2);
286 		ret = -EINVAL;
287 		goto free_phydev;
288 	}
289 
290 	ret = fec_probe(bis, -1, IMX_FEC_BASE, bus, phydev);
291 	if (ret)
292 		goto free_phydev;
293 
294 	return 0;
295 
296 free_phydev:
297 	free(phydev);
298 free_bus:
299 	free(bus);
300 	return ret;
301 }
302 
303 int mx6_rgmii_rework(struct phy_device *phydev)
304 {
305 	unsigned short id1, id2;
306 	unsigned short val;
307 
308 	/* check whether KSZ9031 or AR8035 has to be configured */
309 	id1 = phy_read(phydev, MDIO_DEVAD_NONE, 2);
310 	id2 = phy_read(phydev, MDIO_DEVAD_NONE, 3);
311 
312 	if ((id1 == 0x22) && ((id2 & 0xFFF0) == 0x1620)) {
313 		/* finalize phy configuration for Micrel KSZ9031 */
314 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, 2);
315 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 4);
316 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, MII_KSZ9031_MOD_DATA_POST_INC_W | 0x2);
317 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 0x0000);
318 
319 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, 2);
320 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 5);
321 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, MII_KSZ9031_MOD_DATA_POST_INC_W | 0x2);
322 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, MII_KSZ9031_MOD_REG);
323 
324 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, 2);
325 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 6);
326 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, MII_KSZ9031_MOD_DATA_POST_INC_W | 0x2);
327 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 0xFFFF);
328 
329 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, 2);
330 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 8);
331 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, MII_KSZ9031_MOD_DATA_POST_INC_W | 0x2);
332 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 0x3FFF);
333 
334 		/* fix KSZ9031 link up issue */
335 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, 0x0);
336 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 0x4);
337 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, MII_KSZ9031_MOD_DATA_NO_POST_INC);
338 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 0x6);
339 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, MII_KSZ9031_MOD_REG);
340 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 0x3);
341 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, MII_KSZ9031_MOD_DATA_NO_POST_INC);
342 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 0x1A80);
343 	}
344 
345 	if ((id1 == 0x004d) && (id2 == 0xd072)) {
346 		/* enable AR8035 ouput a 125MHz clk from CLK_25M */
347 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, 0x7);
348 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, MII_KSZ9031_MOD_DATA_POST_INC_RW | 0x16);
349 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, MII_KSZ9031_MOD_DATA_NO_POST_INC | 0x7);
350 		val = phy_read(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA);
351 		val &= 0xfe63;
352 		val |= 0x18;
353 		phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, val);
354 
355 		/* introduce tx clock delay */
356 		phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x5);
357 		val = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e);
358 		val |= 0x0100;
359 		phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, val);
360 
361 		/* disable hibernation */
362 		phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0xb);
363 		val = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e);
364 		phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x3c40);
365 	}
366 	return 0;
367 }
368 
369 int board_phy_config(struct phy_device *phydev)
370 {
371 	mx6_rgmii_rework(phydev);
372 
373 	if (phydev->drv->config)
374 		phydev->drv->config(phydev);
375 
376 	return 0;
377 }
378 
379 static void setup_iomux_uart(void)
380 {
381 	imx_iomux_v3_setup_multiple_pads(uart2_pads, ARRAY_SIZE(uart2_pads));
382 }
383 
384 #ifdef CONFIG_FSL_ESDHC
385 static struct fsl_esdhc_cfg usdhc_cfg[] = {
386 	{USDHC2_BASE_ADDR},
387 	{USDHC3_BASE_ADDR},
388 	{USDHC4_BASE_ADDR},
389 };
390 
391 int board_mmc_getcd(struct mmc *mmc)
392 {
393 	struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
394 	int ret = 0;
395 
396 	switch (cfg->esdhc_base) {
397 	case USDHC2_BASE_ADDR:
398 		gpio_direction_input(IMX_GPIO_NR(1, 4));
399 		ret = !gpio_get_value(IMX_GPIO_NR(1, 4));
400 		break;
401 	case USDHC3_BASE_ADDR:
402 		ret = 1;	/* eMMC is always present */
403 		break;
404 	case USDHC4_BASE_ADDR:
405 		gpio_direction_input(IMX_GPIO_NR(2, 6));
406 		ret = !gpio_get_value(IMX_GPIO_NR(2, 6));
407 		break;
408 	default:
409 		printf("Bad USDHC interface\n");
410 	}
411 
412 	return ret;
413 }
414 
415 int board_mmc_init(bd_t *bis)
416 {
417 	s32 status = 0;
418 	int i;
419 
420 	usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
421 	usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
422 	usdhc_cfg[2].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
423 
424 	imx_iomux_v3_setup_multiple_pads(usdhc2_pads, ARRAY_SIZE(usdhc2_pads));
425 	imx_iomux_v3_setup_multiple_pads(usdhc3_pads, ARRAY_SIZE(usdhc3_pads));
426 	imx_iomux_v3_setup_multiple_pads(usdhc4_pads, ARRAY_SIZE(usdhc4_pads));
427 
428 	for (i = 0; i < ARRAY_SIZE(usdhc_cfg); i++) {
429 		status = fsl_esdhc_initialize(bis, &usdhc_cfg[i]);
430 		if (status)
431 			return status;
432 	}
433 
434 	return 0;
435 }
436 #endif
437 
438 int board_ehci_hcd_init(int port)
439 {
440 	switch (port) {
441 	case 0:
442 		imx_iomux_v3_setup_multiple_pads(usb_otg_pads,
443 						 ARRAY_SIZE(usb_otg_pads));
444 		/*
445 		 * set daisy chain for otg_pin_id on 6q.
446 		 * for 6dl, this bit is reserved
447 		 */
448 		imx_iomux_set_gpr_register(1, 13, 1, 1);
449 		break;
450 	case 1:
451 		/* nothing to do */
452 		break;
453 	default:
454 		printf("Invalid USB port: %d\n", port);
455 		return -EINVAL;
456 	}
457 
458 	return 0;
459 }
460 
461 int board_ehci_power(int port, int on)
462 {
463 	switch (port) {
464 	case 0:
465 		break;
466 	case 1:
467 		gpio_direction_output(IMX_GPIO_NR(5, 5), on);
468 		break;
469 	default:
470 		printf("Invalid USB port: %d\n", port);
471 		return -EINVAL;
472 	}
473 
474 	return 0;
475 }
476 
477 struct display_info_t {
478 	int bus;
479 	int addr;
480 	int pixfmt;
481 	int (*detect)(struct display_info_t const *dev);
482 	void (*enable)(struct display_info_t const *dev);
483 	struct fb_videomode mode;
484 };
485 
486 static void disable_lvds(struct display_info_t const *dev)
487 {
488 	struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
489 
490 	clrbits_le32(&iomux->gpr[2], IOMUXC_GPR2_LVDS_CH0_MODE_MASK |
491 		     IOMUXC_GPR2_LVDS_CH1_MODE_MASK);
492 }
493 
494 static void do_enable_hdmi(struct display_info_t const *dev)
495 {
496 	disable_lvds(dev);
497 	imx_enable_hdmi_phy();
498 }
499 
500 static struct display_info_t const displays[] = {
501 {
502 	.bus = -1,
503 	.addr = 0,
504 	.pixfmt = IPU_PIX_FMT_RGB666,
505 	.detect = NULL,
506 	.enable = NULL,
507 	.mode = {
508 		.name =
509 		"Hannstar-XGA",
510 		.refresh = 60,
511 		.xres = 1024,
512 		.yres = 768,
513 		.pixclock = 15385,
514 		.left_margin = 220,
515 		.right_margin = 40,
516 		.upper_margin = 21,
517 		.lower_margin = 7,
518 		.hsync_len = 60,
519 		.vsync_len = 10,
520 		.sync = FB_SYNC_EXT,
521 		.vmode = FB_VMODE_NONINTERLACED } },
522 {
523 	.bus = -1,
524 	.addr = 0,
525 	.pixfmt = IPU_PIX_FMT_RGB24,
526 	.detect = NULL,
527 	.enable = do_enable_hdmi,
528 	.mode = {
529 		.name = "HDMI",
530 		.refresh = 60,
531 		.xres = 1024,
532 		.yres = 768,
533 		.pixclock = 15385,
534 		.left_margin = 220,
535 		.right_margin = 40,
536 		.upper_margin = 21,
537 		.lower_margin = 7,
538 		.hsync_len = 60,
539 		.vsync_len = 10,
540 		.sync = FB_SYNC_EXT,
541 		.vmode = FB_VMODE_NONINTERLACED } }
542 };
543 
544 int board_video_skip(void)
545 {
546 	int i;
547 	int ret;
548 	char const *panel = getenv("panel");
549 	if (!panel) {
550 		for (i = 0; i < ARRAY_SIZE(displays); i++) {
551 			struct display_info_t const *dev = displays + i;
552 			if (dev->detect && dev->detect(dev)) {
553 				panel = dev->mode.name;
554 				printf("auto-detected panel %s\n", panel);
555 				break;
556 			}
557 		}
558 		if (!panel) {
559 			panel = displays[0].mode.name;
560 			printf("No panel detected: default to %s\n", panel);
561 			i = 0;
562 		}
563 	} else {
564 		for (i = 0; i < ARRAY_SIZE(displays); i++) {
565 			if (!strcmp(panel, displays[i].mode.name))
566 				break;
567 		}
568 	}
569 	if (i < ARRAY_SIZE(displays)) {
570 		ret = ipuv3_fb_init(&displays[i].mode, 0, displays[i].pixfmt);
571 		if (!ret) {
572 			if (displays[i].enable)
573 				displays[i].enable(displays + i);
574 			printf("Display: %s (%ux%u)\n",
575 			       displays[i].mode.name, displays[i].mode.xres,
576 			       displays[i].mode.yres);
577 		} else
578 			printf("LCD %s cannot be configured: %d\n",
579 			       displays[i].mode.name, ret);
580 	} else {
581 		printf("unsupported panel %s\n", panel);
582 		return -EINVAL;
583 	}
584 
585 	return 0;
586 }
587 
588 static void setup_display(void)
589 {
590 	struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
591 	struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
592 	int reg;
593 
594 	enable_ipu_clock();
595 	imx_setup_hdmi();
596 
597 	/* Turn on LDB0, LDB1, IPU,IPU DI0 clocks */
598 	setbits_le32(&mxc_ccm->CCGR3, MXC_CCM_CCGR3_LDB_DI0_MASK |
599 		     MXC_CCM_CCGR3_LDB_DI1_MASK);
600 
601 	/* set LDB0, LDB1 clk select to 011/011 */
602 	reg = readl(&mxc_ccm->cs2cdr);
603 	reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK |
604 		 MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK);
605 	reg |= (3 << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET) |
606 		(3 << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET);
607 	writel(reg, &mxc_ccm->cs2cdr);
608 
609 	setbits_le32(&mxc_ccm->cscmr2, MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV |
610 		     MXC_CCM_CSCMR2_LDB_DI1_IPU_DIV);
611 
612 	setbits_le32(&mxc_ccm->chsccdr, CHSCCDR_CLK_SEL_LDB_DI0 <<
613 		     MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET |
614 		     CHSCCDR_CLK_SEL_LDB_DI0 <<
615 		     MXC_CCM_CHSCCDR_IPU1_DI1_CLK_SEL_OFFSET);
616 
617 	reg = IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES
618 		| IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_LOW
619 		| IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_LOW
620 		| IOMUXC_GPR2_BIT_MAPPING_CH1_SPWG
621 		| IOMUXC_GPR2_DATA_WIDTH_CH1_18BIT
622 		| IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG
623 		| IOMUXC_GPR2_DATA_WIDTH_CH0_18BIT
624 		| IOMUXC_GPR2_LVDS_CH0_MODE_DISABLED
625 		| IOMUXC_GPR2_LVDS_CH1_MODE_ENABLED_DI0;
626 	writel(reg, &iomux->gpr[2]);
627 
628 	reg = readl(&iomux->gpr[3]);
629 	reg = (reg & ~(IOMUXC_GPR3_LVDS1_MUX_CTL_MASK |
630 		       IOMUXC_GPR3_HDMI_MUX_CTL_MASK)) |
631 		(IOMUXC_GPR3_MUX_SRC_IPU1_DI0 <<
632 		 IOMUXC_GPR3_LVDS1_MUX_CTL_OFFSET);
633 	writel(reg, &iomux->gpr[3]);
634 }
635 
636 /*
637  * Do not overwrite the console
638  * Use always serial for U-Boot console
639  */
640 int overwrite_console(void)
641 {
642 	return 1;
643 }
644 
645 int board_early_init_f(void)
646 {
647 	setup_iomux_uart();
648 	setup_display();
649 
650 	return 0;
651 }
652 
653 int board_init(void)
654 {
655 	/* address of boot parameters */
656 	gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
657 
658 	setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1);
659 
660 #ifdef CONFIG_CMD_SATA
661 	setup_sata();
662 #endif
663 
664 	return 0;
665 }
666 
667 int checkboard(void)
668 {
669 	puts("Board: Conga-QEVAL QMX6 Quad\n");
670 
671 	return 0;
672 }
673 
674 #ifdef CONFIG_CMD_BMODE
675 static const struct boot_mode board_boot_modes[] = {
676 	/* 4 bit bus width */
677 	{"mmc0",	MAKE_CFGVAL(0x50, 0x20, 0x00, 0x00)},
678 	{"mmc1",	MAKE_CFGVAL(0x50, 0x38, 0x00, 0x00)},
679 	{NULL,		0},
680 };
681 #endif
682 
683 int misc_init_r(void)
684 {
685 #ifdef CONFIG_CMD_BMODE
686 	add_board_boot_modes(board_boot_modes);
687 #endif
688 	return 0;
689 }
690