blob: cf5607b2c808c3ac09491c86a498e3cca1aa1c4f [file] [log] [blame]
SARTRE Leodce71762013-06-03 23:30:36 +00001/*
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 *
Wolfgang Denkbd8ec7e2013-10-07 13:07:26 +02007 * SPDX-License-Identifier: GPL-2.0+
SARTRE Leodce71762013-06-03 23:30:36 +00008 */
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>
Otavio Salvadordf82d002015-07-23 11:02:31 -030018#include <asm/imx-common/sata.h>
SARTRE Leodce71762013-06-03 23:30:36 +000019#include <asm/imx-common/boot_mode.h>
Otavio Salvador0378d632015-07-23 11:02:28 -030020#include <asm/imx-common/mxc_i2c.h>
Otavio Salvador6c46cd12015-07-23 11:02:30 -030021#include <asm/arch/mxc_hdmi.h>
22#include <asm/arch/crm_regs.h>
SARTRE Leodce71762013-06-03 23:30:36 +000023#include <mmc.h>
24#include <fsl_esdhc.h>
Otavio Salvador0378d632015-07-23 11:02:28 -030025#include <i2c.h>
26#include <power/pmic.h>
27#include <power/pfuze100_pmic.h>
Otavio Salvador6c46cd12015-07-23 11:02:30 -030028#include <linux/fb.h>
29#include <ipu_pixfmt.h>
Otavio Salvadore6b47822015-07-28 20:24:41 -030030#include <malloc.h>
31#include <miiphy.h>
32#include <netdev.h>
33#include <micrel.h>
SARTRE Leodce71762013-06-03 23:30:36 +000034
35DECLARE_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
Otavio Salvador0378d632015-07-23 11:02:28 -030043#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
Otavio Salvadore6b47822015-07-28 20:24:41 -030050
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
SARTRE Leodce71762013-06-03 23:30:36 +000055int dram_init(void)
56{
57 gd->ram_size = get_ram_size((void *)PHYS_SDRAM, PHYS_SDRAM_SIZE);
58
59 return 0;
60}
61
Otavio Salvadord08683f2015-07-23 11:02:21 -030062static iomux_v3_cfg_t const uart2_pads[] = {
Eric Nelson3d3be0a2013-11-04 17:00:51 -070063 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),
SARTRE Leodce71762013-06-03 23:30:36 +000065};
66
Otavio Salvadord08683f2015-07-23 11:02:21 -030067static iomux_v3_cfg_t const usdhc2_pads[] = {
Eric Nelson3d3be0a2013-11-04 17:00:51 -070068 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),
SARTRE Leodce71762013-06-03 23:30:36 +000075};
76
Otavio Salvadordff4c302015-07-23 11:02:24 -030077static 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
Otavio Salvadord08683f2015-07-23 11:02:21 -030091static iomux_v3_cfg_t const usdhc4_pads[] = {
Eric Nelson3d3be0a2013-11-04 17:00:51 -070092 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 */
SARTRE Leodce71762013-06-03 23:30:36 +0000103};
104
Otavio Salvadorc8762d02015-07-23 11:02:29 -0300105static 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
Otavio Salvadore6b47822015-07-28 20:24:41 -0300110static 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
128static 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
137static 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
Otavio Salvador0378d632015-07-23 11:02:28 -0300155#define PC MUX_PAD_CTRL(I2C_PAD_CTRL)
156struct 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
171struct interface_level {
172 char *name;
173 uchar value;
174};
175
176static struct interface_level mipi_levels[] = {
177 {"0V0", 0x00},
178 {"2V5", 0x17},
179};
180
181/* setup board specific PMIC */
182int 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)) {
Otavio Salvador6cfffff2015-09-17 15:13:18 -0300215 printf("set MIPI level %s\n", mipi_levels[i].name);
Otavio Salvador0378d632015-07-23 11:02:28 -0300216 ret = pmic_reg_write(p, PFUZE100_VGEN4VOL,
217 mipi_levels[i].value);
218 if (ret)
219 return ret;
220 }
221 }
222
Otavio Salvadore6b47822015-07-28 20:24:41 -0300223 return 0;
224}
225
226int 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
296free_phydev:
297 free(phydev);
298free_bus:
299 free(bus);
300 return ret;
301}
302
303int 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
369int 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
Otavio Salvador0378d632015-07-23 11:02:28 -0300376 return 0;
377}
378
SARTRE Leodce71762013-06-03 23:30:36 +0000379static 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
Otavio Salvadord08683f2015-07-23 11:02:21 -0300385static struct fsl_esdhc_cfg usdhc_cfg[] = {
SARTRE Leodce71762013-06-03 23:30:36 +0000386 {USDHC2_BASE_ADDR},
Otavio Salvadordff4c302015-07-23 11:02:24 -0300387 {USDHC3_BASE_ADDR},
SARTRE Leodce71762013-06-03 23:30:36 +0000388 {USDHC4_BASE_ADDR},
389};
390
391int 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;
Otavio Salvadordff4c302015-07-23 11:02:24 -0300401 case USDHC3_BASE_ADDR:
402 ret = 1; /* eMMC is always present */
403 break;
SARTRE Leodce71762013-06-03 23:30:36 +0000404 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
415int board_mmc_init(bd_t *bis)
416{
417 s32 status = 0;
Otavio Salvador7b4a64b2015-07-23 11:02:22 -0300418 int i;
SARTRE Leodce71762013-06-03 23:30:36 +0000419
420 usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
Otavio Salvadordff4c302015-07-23 11:02:24 -0300421 usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
422 usdhc_cfg[2].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
SARTRE Leodce71762013-06-03 23:30:36 +0000423
Otavio Salvadora2f9bcb2015-07-23 11:02:23 -0300424 imx_iomux_v3_setup_multiple_pads(usdhc2_pads, ARRAY_SIZE(usdhc2_pads));
Otavio Salvadordff4c302015-07-23 11:02:24 -0300425 imx_iomux_v3_setup_multiple_pads(usdhc3_pads, ARRAY_SIZE(usdhc3_pads));
Otavio Salvadora2f9bcb2015-07-23 11:02:23 -0300426 imx_iomux_v3_setup_multiple_pads(usdhc4_pads, ARRAY_SIZE(usdhc4_pads));
SARTRE Leodce71762013-06-03 23:30:36 +0000427
Otavio Salvador7b4a64b2015-07-23 11:02:22 -0300428 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 }
SARTRE Leodce71762013-06-03 23:30:36 +0000433
Otavio Salvador7b4a64b2015-07-23 11:02:22 -0300434 return 0;
SARTRE Leodce71762013-06-03 23:30:36 +0000435}
436#endif
437
Otavio Salvadorc8762d02015-07-23 11:02:29 -0300438int 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
461int 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
Otavio Salvador6c46cd12015-07-23 11:02:30 -0300477struct 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
486static 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
494static void do_enable_hdmi(struct display_info_t const *dev)
495{
496 disable_lvds(dev);
497 imx_enable_hdmi_phy();
498}
499
500static 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
544int 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
588static 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 */
640int overwrite_console(void)
641{
642 return 1;
643}
644
SARTRE Leodce71762013-06-03 23:30:36 +0000645int board_early_init_f(void)
646{
647 setup_iomux_uart();
Otavio Salvador6c46cd12015-07-23 11:02:30 -0300648 setup_display();
SARTRE Leodce71762013-06-03 23:30:36 +0000649
650 return 0;
651}
652
653int board_init(void)
654{
655 /* address of boot parameters */
656 gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
657
Otavio Salvador0378d632015-07-23 11:02:28 -0300658 setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1);
659
Otavio Salvadordf82d002015-07-23 11:02:31 -0300660#ifdef CONFIG_CMD_SATA
661 setup_sata();
662#endif
663
SARTRE Leodce71762013-06-03 23:30:36 +0000664 return 0;
665}
666
667int checkboard(void)
668{
669 puts("Board: Conga-QEVAL QMX6 Quad\n");
670
671 return 0;
672}
673
674#ifdef CONFIG_CMD_BMODE
675static 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
683int misc_init_r(void)
684{
685#ifdef CONFIG_CMD_BMODE
686 add_board_boot_modes(board_boot_modes);
687#endif
688 return 0;
689}