blob: 574891e5ec6df3965c57f1890f46e214f10eb177 [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)) {
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
Otavio Salvadore6b47822015-07-28 20:24:41 -0300224 return 0;
225}
226
227int 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
297free_phydev:
298 free(phydev);
299free_bus:
300 free(bus);
301 return ret;
302}
303
304int 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
370int 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
Otavio Salvador0378d632015-07-23 11:02:28 -0300377 return 0;
378}
379
SARTRE Leodce71762013-06-03 23:30:36 +0000380static 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
Otavio Salvadord08683f2015-07-23 11:02:21 -0300386static struct fsl_esdhc_cfg usdhc_cfg[] = {
SARTRE Leodce71762013-06-03 23:30:36 +0000387 {USDHC2_BASE_ADDR},
Otavio Salvadordff4c302015-07-23 11:02:24 -0300388 {USDHC3_BASE_ADDR},
SARTRE Leodce71762013-06-03 23:30:36 +0000389 {USDHC4_BASE_ADDR},
390};
391
392int 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;
Otavio Salvadordff4c302015-07-23 11:02:24 -0300402 case USDHC3_BASE_ADDR:
403 ret = 1; /* eMMC is always present */
404 break;
SARTRE Leodce71762013-06-03 23:30:36 +0000405 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
416int board_mmc_init(bd_t *bis)
417{
418 s32 status = 0;
Otavio Salvador7b4a64b2015-07-23 11:02:22 -0300419 int i;
SARTRE Leodce71762013-06-03 23:30:36 +0000420
421 usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
Otavio Salvadordff4c302015-07-23 11:02:24 -0300422 usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
423 usdhc_cfg[2].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
SARTRE Leodce71762013-06-03 23:30:36 +0000424
Otavio Salvadora2f9bcb2015-07-23 11:02:23 -0300425 imx_iomux_v3_setup_multiple_pads(usdhc2_pads, ARRAY_SIZE(usdhc2_pads));
Otavio Salvadordff4c302015-07-23 11:02:24 -0300426 imx_iomux_v3_setup_multiple_pads(usdhc3_pads, ARRAY_SIZE(usdhc3_pads));
Otavio Salvadora2f9bcb2015-07-23 11:02:23 -0300427 imx_iomux_v3_setup_multiple_pads(usdhc4_pads, ARRAY_SIZE(usdhc4_pads));
SARTRE Leodce71762013-06-03 23:30:36 +0000428
Otavio Salvador7b4a64b2015-07-23 11:02:22 -0300429 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 }
SARTRE Leodce71762013-06-03 23:30:36 +0000434
Otavio Salvador7b4a64b2015-07-23 11:02:22 -0300435 return 0;
SARTRE Leodce71762013-06-03 23:30:36 +0000436}
437#endif
438
Otavio Salvadorc8762d02015-07-23 11:02:29 -0300439int 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
462int 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
Otavio Salvador6c46cd12015-07-23 11:02:30 -0300478struct 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
487static 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
495static void do_enable_hdmi(struct display_info_t const *dev)
496{
497 disable_lvds(dev);
498 imx_enable_hdmi_phy();
499}
500
501static 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
545int 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
589static 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 */
641int overwrite_console(void)
642{
643 return 1;
644}
645
SARTRE Leodce71762013-06-03 23:30:36 +0000646int board_early_init_f(void)
647{
648 setup_iomux_uart();
Otavio Salvador6c46cd12015-07-23 11:02:30 -0300649 setup_display();
SARTRE Leodce71762013-06-03 23:30:36 +0000650
651 return 0;
652}
653
654int board_init(void)
655{
656 /* address of boot parameters */
657 gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
658
Otavio Salvador0378d632015-07-23 11:02:28 -0300659 setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1);
660
Otavio Salvadordf82d002015-07-23 11:02:31 -0300661#ifdef CONFIG_CMD_SATA
662 setup_sata();
663#endif
664
SARTRE Leodce71762013-06-03 23:30:36 +0000665 return 0;
666}
667
668int checkboard(void)
669{
670 puts("Board: Conga-QEVAL QMX6 Quad\n");
671
672 return 0;
673}
674
675#ifdef CONFIG_CMD_BMODE
676static 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
684int misc_init_r(void)
685{
686#ifdef CONFIG_CMD_BMODE
687 add_board_boot_modes(board_boot_modes);
688#endif
689 return 0;
690}