Commit f02229021d2698e97915740ed491ddc3f0975f2e
Committed by
Stefano Babic
1 parent
066f876bf6
Exists in
v2017.01-smarct4x
and in
30 other branches
cgtqmx6eval: Add Ethernet support
cgtqmx6eval can be populated with a AR8035 or KSZ9031 depending on the board revision. Add Ethernet support. Signed-off-by: Otavio Salvador <otavio@ossystems.com.br>
Showing 3 changed files with 224 additions and 0 deletions Side-by-side Diff
board/congatec/cgtqmx6eval/cgtqmx6eval.c
... | ... | @@ -27,6 +27,10 @@ |
27 | 27 | #include <power/pfuze100_pmic.h> |
28 | 28 | #include <linux/fb.h> |
29 | 29 | #include <ipu_pixfmt.h> |
30 | +#include <malloc.h> | |
31 | +#include <miiphy.h> | |
32 | +#include <netdev.h> | |
33 | +#include <micrel.h> | |
30 | 34 | |
31 | 35 | DECLARE_GLOBAL_DATA_PTR; |
32 | 36 | |
... | ... | @@ -43,6 +47,11 @@ |
43 | 47 | |
44 | 48 | #define MX6Q_QMX6_PFUZE_MUX IMX_GPIO_NR(6, 9) |
45 | 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 | + | |
46 | 55 | int dram_init(void) |
47 | 56 | { |
48 | 57 | gd->ram_size = get_ram_size((void *)PHYS_SDRAM, PHYS_SDRAM_SIZE); |
... | ... | @@ -98,6 +107,51 @@ |
98 | 107 | MX6_PAD_GPIO_1__USB_OTG_ID | MUX_PAD_CTRL(NO_PAD_CTRL), |
99 | 108 | }; |
100 | 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 | + | |
101 | 155 | #define PC MUX_PAD_CTRL(I2C_PAD_CTRL) |
102 | 156 | struct i2c_pads_info i2c_pad_info1 = { |
103 | 157 | .scl = { |
... | ... | @@ -166,6 +220,159 @@ |
166 | 220 | return ret; |
167 | 221 | } |
168 | 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); | |
169 | 376 | |
170 | 377 | return 0; |
171 | 378 | } |
include/configs/cgtqmx6eval.h
... | ... | @@ -97,6 +97,19 @@ |
97 | 97 | #define CONFIG_LBA48 |
98 | 98 | #define CONFIG_LIBATA |
99 | 99 | |
100 | +/* Ethernet */ | |
101 | +#define CONFIG_CMD_PING | |
102 | +#define CONFIG_CMD_DHCP | |
103 | +#define CONFIG_CMD_MII | |
104 | +#define CONFIG_FEC_MXC | |
105 | +#define CONFIG_MII | |
106 | +#define IMX_FEC_BASE ENET_BASE_ADDR | |
107 | +#define CONFIG_FEC_XCV_TYPE RGMII | |
108 | +#define CONFIG_ETHPRIME "FEC" | |
109 | +#define CONFIG_FEC_MXC_PHYADDR 6 | |
110 | +#define CONFIG_PHYLIB | |
111 | +#define CONFIG_PHY_ATHEROS | |
112 | + | |
100 | 113 | /* Command definition */ |
101 | 114 | |
102 | 115 | #define CONFIG_MXC_UART_BASE UART2_BASE |
include/micrel.h
... | ... | @@ -20,6 +20,10 @@ |
20 | 20 | #define MII_KSZ9031_EXT_RGMII_TX_DATA_SKEW 0x6 |
21 | 21 | #define MII_KSZ9031_EXT_RGMII_CLOCK_SKEW 0x8 |
22 | 22 | |
23 | +/* Registers */ | |
24 | +#define MMD_ACCESS_CONTROL 0xd | |
25 | +#define MMD_ACCESS_REG_DATA 0xe | |
26 | + | |
23 | 27 | struct phy_device; |
24 | 28 | int ksz9021_phy_extended_write(struct phy_device *phydev, int regnum, u16 val); |
25 | 29 | int ksz9021_phy_extended_read(struct phy_device *phydev, int regnum); |