]>
Commit | Line | Data |
---|---|---|
7769776a AK |
1 | /* |
2 | * Copyright 2017 NXP | |
3 | * | |
4 | * SPDX-License-Identifier: GPL-2.0+ | |
5 | */ | |
6 | ||
7 | #include <common.h> | |
8 | #include <netdev.h> | |
9 | #include <asm/io.h> | |
10 | #include <asm/arch/fsl_serdes.h> | |
11 | #include <hwconfig.h> | |
12 | #include <fsl_mdio.h> | |
13 | #include <malloc.h> | |
14 | #include <fm_eth.h> | |
15 | #include <i2c.h> | |
16 | #include <miiphy.h> | |
c48deb90 | 17 | #include <fsl-mc/fsl_mc.h> |
7769776a AK |
18 | #include <fsl-mc/ldpaa_wriop.h> |
19 | ||
20 | #include "../common/qixis.h" | |
21 | ||
22 | #include "ls1088a_qixis.h" | |
23 | ||
7769776a AK |
24 | #ifdef CONFIG_FSL_MC_ENET |
25 | ||
26 | #define SFP_TX 0 | |
27 | ||
28 | /* - In LS1088A A there are only 16 SERDES lanes, spread across 2 SERDES banks. | |
29 | * Bank 1 -> Lanes A, B, C, D, | |
30 | * Bank 2 -> Lanes A,B, C, D, | |
31 | */ | |
32 | ||
33 | /* Mapping of 8 SERDES lanes to LS1088A QDS board slots. A value of '0' here | |
34 | * means that the mapping must be determined dynamically, or that the lane | |
35 | * maps to something other than a board slot. | |
36 | */ | |
37 | ||
38 | static u8 lane_to_slot_fsm1[] = { | |
39 | 0, 0, 0, 0, 0, 0, 0, 0 | |
40 | }; | |
41 | ||
42 | /* On the Vitesse VSC8234XHG SGMII riser card there are 4 SGMII PHYs | |
43 | * housed. | |
44 | */ | |
45 | ||
46 | static int xqsgii_riser_phy_addr[] = { | |
47 | XQSGMII_CARD_PHY1_PORT0_ADDR, | |
48 | XQSGMII_CARD_PHY2_PORT0_ADDR, | |
49 | XQSGMII_CARD_PHY3_PORT0_ADDR, | |
50 | XQSGMII_CARD_PHY4_PORT0_ADDR, | |
51 | XQSGMII_CARD_PHY3_PORT2_ADDR, | |
52 | XQSGMII_CARD_PHY1_PORT2_ADDR, | |
53 | XQSGMII_CARD_PHY4_PORT2_ADDR, | |
54 | XQSGMII_CARD_PHY2_PORT2_ADDR, | |
55 | }; | |
56 | ||
57 | static int sgmii_riser_phy_addr[] = { | |
58 | SGMII_CARD_PORT1_PHY_ADDR, | |
59 | SGMII_CARD_PORT2_PHY_ADDR, | |
60 | SGMII_CARD_PORT3_PHY_ADDR, | |
61 | SGMII_CARD_PORT4_PHY_ADDR, | |
62 | }; | |
63 | ||
64 | /* Slot2 does not have EMI connections */ | |
65 | #define EMI_NONE 0xFF | |
66 | #define EMI1_RGMII1 0 | |
67 | #define EMI1_RGMII2 1 | |
68 | #define EMI1_SLOT1 2 | |
69 | ||
70 | static const char * const mdio_names[] = { | |
71 | "LS1088A_QDS_MDIO0", | |
72 | "LS1088A_QDS_MDIO1", | |
73 | "LS1088A_QDS_MDIO2", | |
74 | DEFAULT_WRIOP_MDIO2_NAME, | |
75 | }; | |
76 | ||
77 | struct ls1088a_qds_mdio { | |
78 | u8 muxval; | |
79 | struct mii_dev *realbus; | |
80 | }; | |
81 | ||
82 | static void sgmii_configure_repeater(int dpmac) | |
83 | { | |
84 | struct mii_dev *bus; | |
85 | uint8_t a = 0xf; | |
86 | int i, j, ret; | |
87 | unsigned short value; | |
88 | const char *dev = "LS1088A_QDS_MDIO2"; | |
89 | int i2c_addr[] = {0x58, 0x59, 0x5a, 0x5b}; | |
90 | int i2c_phy_addr = 0; | |
91 | int phy_addr = 0; | |
92 | ||
93 | uint8_t ch_a_eq[] = {0x1, 0x2, 0x3, 0x7}; | |
94 | uint8_t ch_a_ctl2[] = {0x81, 0x82, 0x83, 0x84}; | |
95 | uint8_t ch_b_eq[] = {0x1, 0x2, 0x3, 0x7}; | |
96 | uint8_t ch_b_ctl2[] = {0x81, 0x82, 0x83, 0x84}; | |
97 | ||
98 | /* Set I2c to Slot 1 */ | |
99 | i2c_write(0x77, 0, 0, &a, 1); | |
100 | ||
101 | switch (dpmac) { | |
102 | case 1: | |
103 | i2c_phy_addr = i2c_addr[1]; | |
104 | phy_addr = 4; | |
105 | break; | |
106 | case 2: | |
107 | i2c_phy_addr = i2c_addr[0]; | |
108 | phy_addr = 0; | |
109 | break; | |
110 | case 3: | |
111 | i2c_phy_addr = i2c_addr[3]; | |
112 | phy_addr = 0xc; | |
113 | break; | |
114 | case 7: | |
115 | i2c_phy_addr = i2c_addr[2]; | |
116 | phy_addr = 8; | |
117 | break; | |
118 | } | |
119 | ||
120 | /* Check the PHY status */ | |
121 | ret = miiphy_set_current_dev(dev); | |
122 | if (ret > 0) | |
123 | goto error; | |
124 | ||
125 | bus = mdio_get_current_dev(); | |
126 | debug("Reading from bus %s\n", bus->name); | |
127 | ||
128 | ret = miiphy_write(dev, phy_addr, 0x1f, 3); | |
129 | if (ret > 0) | |
130 | goto error; | |
131 | ||
132 | mdelay(10); | |
133 | ret = miiphy_read(dev, phy_addr, 0x11, &value); | |
134 | if (ret > 0) | |
135 | goto error; | |
136 | ||
137 | mdelay(10); | |
138 | ||
139 | if ((value & 0xfff) == 0x401) { | |
140 | miiphy_write(dev, phy_addr, 0x1f, 0); | |
141 | printf("DPMAC %d:PHY is ..... Configured\n", dpmac); | |
142 | return; | |
143 | } | |
144 | ||
145 | for (i = 0; i < 4; i++) { | |
146 | for (j = 0; j < 4; j++) { | |
147 | a = 0x18; | |
148 | i2c_write(i2c_phy_addr, 6, 1, &a, 1); | |
149 | a = 0x38; | |
150 | i2c_write(i2c_phy_addr, 4, 1, &a, 1); | |
151 | a = 0x4; | |
152 | i2c_write(i2c_phy_addr, 8, 1, &a, 1); | |
153 | ||
154 | i2c_write(i2c_phy_addr, 0xf, 1, | |
155 | &ch_a_eq[i], 1); | |
156 | i2c_write(i2c_phy_addr, 0x11, 1, | |
157 | &ch_a_ctl2[j], 1); | |
158 | ||
159 | i2c_write(i2c_phy_addr, 0x16, 1, | |
160 | &ch_b_eq[i], 1); | |
161 | i2c_write(i2c_phy_addr, 0x18, 1, | |
162 | &ch_b_ctl2[j], 1); | |
163 | ||
164 | a = 0x14; | |
165 | i2c_write(i2c_phy_addr, 0x23, 1, &a, 1); | |
166 | a = 0xb5; | |
167 | i2c_write(i2c_phy_addr, 0x2d, 1, &a, 1); | |
168 | a = 0x20; | |
169 | i2c_write(i2c_phy_addr, 4, 1, &a, 1); | |
170 | mdelay(100); | |
171 | ret = miiphy_read(dev, phy_addr, 0x11, &value); | |
172 | if (ret > 0) | |
173 | goto error; | |
174 | ||
175 | mdelay(100); | |
176 | ret = miiphy_read(dev, phy_addr, 0x11, &value); | |
177 | if (ret > 0) | |
178 | goto error; | |
179 | ||
180 | if ((value & 0xfff) == 0x401) { | |
181 | printf("DPMAC %d :PHY is configured ", | |
182 | dpmac); | |
183 | printf("after setting repeater 0x%x\n", | |
184 | value); | |
185 | i = 5; | |
186 | j = 5; | |
187 | } else { | |
188 | printf("DPMAC %d :PHY is failed to ", | |
189 | dpmac); | |
190 | printf("configure the repeater 0x%x\n", value); | |
191 | } | |
192 | } | |
193 | } | |
194 | miiphy_write(dev, phy_addr, 0x1f, 0); | |
195 | error: | |
196 | if (ret) | |
197 | printf("DPMAC %d ..... FAILED to configure PHY\n", dpmac); | |
198 | return; | |
199 | } | |
200 | ||
201 | static void qsgmii_configure_repeater(int dpmac) | |
202 | { | |
203 | uint8_t a = 0xf; | |
204 | int i, j; | |
205 | int i2c_phy_addr = 0; | |
206 | int phy_addr = 0; | |
207 | int i2c_addr[] = {0x58, 0x59, 0x5a, 0x5b}; | |
208 | ||
209 | uint8_t ch_a_eq[] = {0x1, 0x2, 0x3, 0x7}; | |
210 | uint8_t ch_a_ctl2[] = {0x81, 0x82, 0x83, 0x84}; | |
211 | uint8_t ch_b_eq[] = {0x1, 0x2, 0x3, 0x7}; | |
212 | uint8_t ch_b_ctl2[] = {0x81, 0x82, 0x83, 0x84}; | |
213 | ||
214 | const char *dev = mdio_names[EMI1_SLOT1]; | |
215 | int ret = 0; | |
216 | unsigned short value; | |
217 | ||
218 | /* Set I2c to Slot 1 */ | |
219 | i2c_write(0x77, 0, 0, &a, 1); | |
220 | ||
221 | switch (dpmac) { | |
222 | case 7: | |
223 | case 8: | |
224 | case 9: | |
225 | case 10: | |
226 | i2c_phy_addr = i2c_addr[2]; | |
227 | phy_addr = 8; | |
228 | break; | |
229 | ||
230 | case 3: | |
231 | case 4: | |
232 | case 5: | |
233 | case 6: | |
234 | i2c_phy_addr = i2c_addr[3]; | |
235 | phy_addr = 0xc; | |
236 | break; | |
237 | } | |
238 | ||
239 | /* Check the PHY status */ | |
240 | ret = miiphy_set_current_dev(dev); | |
241 | ret = miiphy_write(dev, phy_addr, 0x1f, 3); | |
242 | mdelay(10); | |
243 | ret = miiphy_read(dev, phy_addr, 0x11, &value); | |
244 | mdelay(10); | |
245 | ret = miiphy_read(dev, phy_addr, 0x11, &value); | |
246 | mdelay(10); | |
247 | if ((value & 0xf) == 0xf) { | |
248 | miiphy_write(dev, phy_addr, 0x1f, 0); | |
249 | printf("DPMAC %d :PHY is ..... Configured\n", dpmac); | |
250 | return; | |
251 | } | |
252 | ||
253 | for (i = 0; i < 4; i++) { | |
254 | for (j = 0; j < 4; j++) { | |
255 | a = 0x18; | |
256 | i2c_write(i2c_phy_addr, 6, 1, &a, 1); | |
257 | a = 0x38; | |
258 | i2c_write(i2c_phy_addr, 4, 1, &a, 1); | |
259 | a = 0x4; | |
260 | i2c_write(i2c_phy_addr, 8, 1, &a, 1); | |
261 | ||
262 | i2c_write(i2c_phy_addr, 0xf, 1, &ch_a_eq[i], 1); | |
263 | i2c_write(i2c_phy_addr, 0x11, 1, &ch_a_ctl2[j], 1); | |
264 | ||
265 | i2c_write(i2c_phy_addr, 0x16, 1, &ch_b_eq[i], 1); | |
266 | i2c_write(i2c_phy_addr, 0x18, 1, &ch_b_ctl2[j], 1); | |
267 | ||
268 | a = 0x14; | |
269 | i2c_write(i2c_phy_addr, 0x23, 1, &a, 1); | |
270 | a = 0xb5; | |
271 | i2c_write(i2c_phy_addr, 0x2d, 1, &a, 1); | |
272 | a = 0x20; | |
273 | i2c_write(i2c_phy_addr, 4, 1, &a, 1); | |
274 | mdelay(100); | |
275 | ret = miiphy_read(dev, phy_addr, 0x11, &value); | |
276 | if (ret > 0) | |
277 | goto error; | |
278 | mdelay(1); | |
279 | ret = miiphy_read(dev, phy_addr, 0x11, &value); | |
280 | if (ret > 0) | |
281 | goto error; | |
282 | mdelay(10); | |
283 | if ((value & 0xf) == 0xf) { | |
284 | miiphy_write(dev, phy_addr, 0x1f, 0); | |
285 | printf("DPMAC %d :PHY is ..... Configured\n", | |
286 | dpmac); | |
287 | return; | |
288 | } | |
289 | } | |
290 | } | |
291 | error: | |
292 | printf("DPMAC %d :PHY ..... FAILED to configure PHY\n", dpmac); | |
293 | return; | |
294 | } | |
295 | ||
296 | static const char *ls1088a_qds_mdio_name_for_muxval(u8 muxval) | |
297 | { | |
298 | return mdio_names[muxval]; | |
299 | } | |
300 | ||
301 | struct mii_dev *mii_dev_for_muxval(u8 muxval) | |
302 | { | |
303 | struct mii_dev *bus; | |
304 | const char *name = ls1088a_qds_mdio_name_for_muxval(muxval); | |
305 | ||
306 | if (!name) { | |
307 | printf("No bus for muxval %x\n", muxval); | |
308 | return NULL; | |
309 | } | |
310 | ||
311 | bus = miiphy_get_dev_by_name(name); | |
312 | ||
313 | if (!bus) { | |
314 | printf("No bus by name %s\n", name); | |
315 | return NULL; | |
316 | } | |
317 | ||
318 | return bus; | |
319 | } | |
320 | ||
321 | static void ls1088a_qds_enable_SFP_TX(u8 muxval) | |
322 | { | |
323 | u8 brdcfg9; | |
324 | ||
325 | brdcfg9 = QIXIS_READ(brdcfg[9]); | |
326 | brdcfg9 &= ~BRDCFG9_SFPTX_MASK; | |
327 | brdcfg9 |= (muxval << BRDCFG9_SFPTX_SHIFT); | |
328 | QIXIS_WRITE(brdcfg[9], brdcfg9); | |
329 | } | |
330 | ||
331 | static void ls1088a_qds_mux_mdio(u8 muxval) | |
332 | { | |
333 | u8 brdcfg4; | |
334 | ||
335 | if (muxval <= 5) { | |
336 | brdcfg4 = QIXIS_READ(brdcfg[4]); | |
337 | brdcfg4 &= ~BRDCFG4_EMISEL_MASK; | |
338 | brdcfg4 |= (muxval << BRDCFG4_EMISEL_SHIFT); | |
339 | QIXIS_WRITE(brdcfg[4], brdcfg4); | |
340 | } | |
341 | } | |
342 | ||
343 | static int ls1088a_qds_mdio_read(struct mii_dev *bus, int addr, | |
344 | int devad, int regnum) | |
345 | { | |
346 | struct ls1088a_qds_mdio *priv = bus->priv; | |
347 | ||
348 | ls1088a_qds_mux_mdio(priv->muxval); | |
349 | ||
350 | return priv->realbus->read(priv->realbus, addr, devad, regnum); | |
351 | } | |
352 | ||
353 | static int ls1088a_qds_mdio_write(struct mii_dev *bus, int addr, int devad, | |
354 | int regnum, u16 value) | |
355 | { | |
356 | struct ls1088a_qds_mdio *priv = bus->priv; | |
357 | ||
358 | ls1088a_qds_mux_mdio(priv->muxval); | |
359 | ||
360 | return priv->realbus->write(priv->realbus, addr, devad, regnum, value); | |
361 | } | |
362 | ||
363 | static int ls1088a_qds_mdio_reset(struct mii_dev *bus) | |
364 | { | |
365 | struct ls1088a_qds_mdio *priv = bus->priv; | |
366 | ||
367 | return priv->realbus->reset(priv->realbus); | |
368 | } | |
369 | ||
370 | static int ls1088a_qds_mdio_init(char *realbusname, u8 muxval) | |
371 | { | |
372 | struct ls1088a_qds_mdio *pmdio; | |
373 | struct mii_dev *bus = mdio_alloc(); | |
374 | ||
375 | if (!bus) { | |
376 | printf("Failed to allocate ls1088a_qds MDIO bus\n"); | |
377 | return -1; | |
378 | } | |
379 | ||
380 | pmdio = malloc(sizeof(*pmdio)); | |
381 | if (!pmdio) { | |
382 | printf("Failed to allocate ls1088a_qds private data\n"); | |
383 | free(bus); | |
384 | return -1; | |
385 | } | |
386 | ||
387 | bus->read = ls1088a_qds_mdio_read; | |
388 | bus->write = ls1088a_qds_mdio_write; | |
389 | bus->reset = ls1088a_qds_mdio_reset; | |
390 | sprintf(bus->name, ls1088a_qds_mdio_name_for_muxval(muxval)); | |
391 | ||
392 | pmdio->realbus = miiphy_get_dev_by_name(realbusname); | |
393 | ||
394 | if (!pmdio->realbus) { | |
395 | printf("No bus with name %s\n", realbusname); | |
396 | free(bus); | |
397 | free(pmdio); | |
398 | return -1; | |
399 | } | |
400 | ||
401 | pmdio->muxval = muxval; | |
402 | bus->priv = pmdio; | |
403 | ||
404 | return mdio_register(bus); | |
405 | } | |
406 | ||
407 | /* | |
408 | * Initialize the dpmac_info array. | |
409 | * | |
410 | */ | |
411 | static void initialize_dpmac_to_slot(void) | |
412 | { | |
413 | struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR; | |
414 | u32 serdes1_prtcl, cfg; | |
415 | ||
416 | cfg = in_le32(&gur->rcwsr[FSL_CHASSIS3_SRDS1_REGSR - 1]) & | |
417 | FSL_CHASSIS3_SRDS1_PRTCL_MASK; | |
418 | cfg >>= FSL_CHASSIS3_SRDS1_PRTCL_SHIFT; | |
419 | serdes1_prtcl = serdes_get_number(FSL_SRDS_1, cfg); | |
420 | ||
421 | switch (serdes1_prtcl) { | |
422 | case 0x12: | |
423 | printf("qds: WRIOP: Supported SerDes1 Protocol 0x%02x\n", | |
424 | serdes1_prtcl); | |
425 | lane_to_slot_fsm1[0] = EMI1_SLOT1 - 1; | |
426 | lane_to_slot_fsm1[1] = EMI1_SLOT1 - 1; | |
427 | lane_to_slot_fsm1[2] = EMI1_SLOT1 - 1; | |
428 | lane_to_slot_fsm1[3] = EMI1_SLOT1 - 1; | |
429 | break; | |
430 | case 0x15: | |
431 | case 0x1D: | |
432 | printf("qds: WRIOP: Supported SerDes1 Protocol 0x%02x\n", | |
433 | serdes1_prtcl); | |
434 | lane_to_slot_fsm1[0] = EMI1_SLOT1 - 1; | |
435 | lane_to_slot_fsm1[1] = EMI1_SLOT1 - 1; | |
436 | lane_to_slot_fsm1[2] = EMI_NONE; | |
437 | lane_to_slot_fsm1[3] = EMI_NONE; | |
438 | break; | |
439 | case 0x1E: | |
440 | printf("qds: WRIOP: Supported SerDes1 Protocol 0x%02x\n", | |
441 | serdes1_prtcl); | |
442 | lane_to_slot_fsm1[0] = EMI1_SLOT1 - 1; | |
443 | lane_to_slot_fsm1[1] = EMI1_SLOT1 - 1; | |
444 | lane_to_slot_fsm1[2] = EMI1_SLOT1 - 1; | |
445 | lane_to_slot_fsm1[3] = EMI_NONE; | |
446 | break; | |
447 | case 0x3A: | |
448 | printf("qds: WRIOP: Supported SerDes1 Protocol 0x%02x\n", | |
449 | serdes1_prtcl); | |
450 | lane_to_slot_fsm1[0] = EMI1_SLOT1 - 1; | |
451 | lane_to_slot_fsm1[1] = EMI_NONE; | |
452 | lane_to_slot_fsm1[2] = EMI1_SLOT1 - 1; | |
453 | lane_to_slot_fsm1[3] = EMI1_SLOT1 - 1; | |
454 | break; | |
455 | ||
456 | default: | |
457 | printf("%s qds: WRIOP: Unsupported SerDes1 Protocol 0x%02x\n", | |
458 | __func__, serdes1_prtcl); | |
459 | break; | |
460 | } | |
461 | } | |
462 | ||
463 | void ls1088a_handle_phy_interface_sgmii(int dpmac_id) | |
464 | { | |
465 | struct mii_dev *bus; | |
466 | struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR; | |
467 | u32 serdes1_prtcl, cfg; | |
468 | ||
469 | cfg = in_le32(&gur->rcwsr[FSL_CHASSIS3_SRDS1_REGSR - 1]) & | |
470 | FSL_CHASSIS3_SRDS1_PRTCL_MASK; | |
471 | cfg >>= FSL_CHASSIS3_SRDS1_PRTCL_SHIFT; | |
472 | serdes1_prtcl = serdes_get_number(FSL_SRDS_1, cfg); | |
473 | ||
474 | int *riser_phy_addr; | |
475 | char *env_hwconfig = env_get("hwconfig"); | |
476 | ||
477 | if (hwconfig_f("xqsgmii", env_hwconfig)) | |
478 | riser_phy_addr = &xqsgii_riser_phy_addr[0]; | |
479 | else | |
480 | riser_phy_addr = &sgmii_riser_phy_addr[0]; | |
481 | ||
482 | switch (serdes1_prtcl) { | |
483 | case 0x12: | |
484 | case 0x15: | |
485 | case 0x1E: | |
486 | case 0x3A: | |
487 | switch (dpmac_id) { | |
488 | case 1: | |
489 | wriop_set_phy_address(dpmac_id, riser_phy_addr[1]); | |
490 | break; | |
491 | case 2: | |
492 | wriop_set_phy_address(dpmac_id, riser_phy_addr[0]); | |
493 | break; | |
494 | case 3: | |
495 | wriop_set_phy_address(dpmac_id, riser_phy_addr[3]); | |
496 | break; | |
497 | case 7: | |
498 | wriop_set_phy_address(dpmac_id, riser_phy_addr[2]); | |
499 | break; | |
500 | default: | |
501 | printf("WRIOP: Wrong DPMAC%d set to SGMII", dpmac_id); | |
502 | break; | |
503 | } | |
504 | break; | |
505 | default: | |
506 | printf("%s qds: WRIOP: Unsupported SerDes1 Protocol 0x%02x\n", | |
507 | __func__, serdes1_prtcl); | |
508 | return; | |
509 | } | |
510 | dpmac_info[dpmac_id].board_mux = EMI1_SLOT1; | |
511 | bus = mii_dev_for_muxval(EMI1_SLOT1); | |
512 | wriop_set_mdio(dpmac_id, bus); | |
513 | } | |
514 | ||
515 | void ls1088a_handle_phy_interface_qsgmii(int dpmac_id) | |
516 | { | |
517 | struct mii_dev *bus; | |
518 | struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR; | |
519 | u32 serdes1_prtcl, cfg; | |
520 | ||
521 | cfg = in_le32(&gur->rcwsr[FSL_CHASSIS3_SRDS1_REGSR - 1]) & | |
522 | FSL_CHASSIS3_SRDS1_PRTCL_MASK; | |
523 | cfg >>= FSL_CHASSIS3_SRDS1_PRTCL_SHIFT; | |
524 | serdes1_prtcl = serdes_get_number(FSL_SRDS_1, cfg); | |
525 | ||
526 | switch (serdes1_prtcl) { | |
527 | case 0x1D: | |
528 | case 0x1E: | |
529 | switch (dpmac_id) { | |
530 | case 3: | |
531 | case 4: | |
532 | case 5: | |
533 | case 6: | |
534 | wriop_set_phy_address(dpmac_id, dpmac_id + 9); | |
535 | break; | |
536 | case 7: | |
537 | case 8: | |
538 | case 9: | |
539 | case 10: | |
540 | wriop_set_phy_address(dpmac_id, dpmac_id + 1); | |
541 | break; | |
542 | } | |
543 | ||
544 | dpmac_info[dpmac_id].board_mux = EMI1_SLOT1; | |
545 | bus = mii_dev_for_muxval(EMI1_SLOT1); | |
546 | wriop_set_mdio(dpmac_id, bus); | |
547 | break; | |
548 | default: | |
549 | printf("qds: WRIOP: Unsupported SerDes Protocol 0x%02x\n", | |
550 | serdes1_prtcl); | |
551 | break; | |
552 | } | |
553 | } | |
554 | ||
555 | void ls1088a_handle_phy_interface_xsgmii(int i) | |
556 | { | |
557 | struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR; | |
558 | u32 serdes1_prtcl, cfg; | |
559 | ||
560 | cfg = in_le32(&gur->rcwsr[FSL_CHASSIS3_SRDS1_REGSR - 1]) & | |
561 | FSL_CHASSIS3_SRDS1_PRTCL_MASK; | |
562 | cfg >>= FSL_CHASSIS3_SRDS1_PRTCL_SHIFT; | |
563 | serdes1_prtcl = serdes_get_number(FSL_SRDS_1, cfg); | |
564 | ||
565 | switch (serdes1_prtcl) { | |
566 | case 0x15: | |
567 | case 0x1D: | |
568 | case 0x1E: | |
569 | wriop_set_phy_address(i, i + 26); | |
570 | ls1088a_qds_enable_SFP_TX(SFP_TX); | |
571 | break; | |
572 | default: | |
573 | printf("qds: WRIOP: Unsupported SerDes Protocol 0x%02x\n", | |
574 | serdes1_prtcl); | |
575 | break; | |
576 | } | |
577 | } | |
9f244b35 PK |
578 | |
579 | static void ls1088a_handle_phy_interface_rgmii(int dpmac_id) | |
580 | { | |
581 | struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR; | |
582 | u32 serdes1_prtcl, cfg; | |
583 | struct mii_dev *bus; | |
584 | ||
585 | cfg = in_le32(&gur->rcwsr[FSL_CHASSIS3_SRDS1_REGSR - 1]) & | |
586 | FSL_CHASSIS3_SRDS1_PRTCL_MASK; | |
587 | cfg >>= FSL_CHASSIS3_SRDS1_PRTCL_SHIFT; | |
588 | serdes1_prtcl = serdes_get_number(FSL_SRDS_1, cfg); | |
589 | ||
590 | switch (dpmac_id) { | |
591 | case 4: | |
592 | wriop_set_phy_address(dpmac_id, RGMII_PHY1_ADDR); | |
593 | dpmac_info[dpmac_id].board_mux = EMI1_RGMII1; | |
594 | bus = mii_dev_for_muxval(EMI1_RGMII1); | |
595 | wriop_set_mdio(dpmac_id, bus); | |
596 | break; | |
597 | case 5: | |
598 | wriop_set_phy_address(dpmac_id, RGMII_PHY2_ADDR); | |
599 | dpmac_info[dpmac_id].board_mux = EMI1_RGMII2; | |
600 | bus = mii_dev_for_muxval(EMI1_RGMII2); | |
601 | wriop_set_mdio(dpmac_id, bus); | |
602 | break; | |
603 | default: | |
604 | printf("qds: WRIOP: Unsupported RGMII SerDes Protocol 0x%02x\n", | |
605 | serdes1_prtcl); | |
606 | break; | |
607 | } | |
608 | } | |
7769776a AK |
609 | #endif |
610 | ||
611 | int board_eth_init(bd_t *bis) | |
612 | { | |
613 | int error = 0, i; | |
7769776a AK |
614 | #ifdef CONFIG_FSL_MC_ENET |
615 | struct memac_mdio_info *memac_mdio0_info; | |
616 | char *env_hwconfig = env_get("hwconfig"); | |
617 | ||
618 | initialize_dpmac_to_slot(); | |
619 | ||
620 | memac_mdio0_info = (struct memac_mdio_info *)malloc( | |
621 | sizeof(struct memac_mdio_info)); | |
622 | memac_mdio0_info->regs = | |
623 | (struct memac_mdio_controller *) | |
624 | CONFIG_SYS_FSL_WRIOP1_MDIO1; | |
625 | memac_mdio0_info->name = DEFAULT_WRIOP_MDIO1_NAME; | |
626 | ||
627 | /* Register the real MDIO1 bus */ | |
628 | fm_memac_mdio_init(bis, memac_mdio0_info); | |
7769776a AK |
629 | /* Register the muxing front-ends to the MDIO buses */ |
630 | ls1088a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_RGMII1); | |
631 | ls1088a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_RGMII2); | |
632 | ls1088a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT1); | |
633 | ||
634 | for (i = WRIOP1_DPMAC1; i < NUM_WRIOP_PORTS; i++) { | |
635 | switch (wriop_get_enet_if(i)) { | |
9f244b35 | 636 | case PHY_INTERFACE_MODE_RGMII: |
2af1b08a | 637 | case PHY_INTERFACE_MODE_RGMII_ID: |
9f244b35 PK |
638 | ls1088a_handle_phy_interface_rgmii(i); |
639 | break; | |
7769776a AK |
640 | case PHY_INTERFACE_MODE_QSGMII: |
641 | ls1088a_handle_phy_interface_qsgmii(i); | |
642 | break; | |
643 | case PHY_INTERFACE_MODE_SGMII: | |
644 | ls1088a_handle_phy_interface_sgmii(i); | |
645 | break; | |
646 | case PHY_INTERFACE_MODE_XGMII: | |
647 | ls1088a_handle_phy_interface_xsgmii(i); | |
648 | break; | |
649 | default: | |
650 | break; | |
651 | ||
652 | if (i == 16) | |
653 | i = NUM_WRIOP_PORTS; | |
654 | } | |
655 | } | |
656 | ||
7769776a AK |
657 | error = cpu_eth_init(bis); |
658 | ||
659 | if (hwconfig_f("xqsgmii", env_hwconfig)) { | |
660 | for (i = WRIOP1_DPMAC1; i < NUM_WRIOP_PORTS; i++) { | |
661 | switch (wriop_get_enet_if(i)) { | |
662 | case PHY_INTERFACE_MODE_QSGMII: | |
663 | qsgmii_configure_repeater(i); | |
664 | break; | |
665 | case PHY_INTERFACE_MODE_SGMII: | |
666 | sgmii_configure_repeater(i); | |
667 | break; | |
668 | default: | |
669 | break; | |
670 | } | |
671 | ||
672 | if (i == 16) | |
673 | i = NUM_WRIOP_PORTS; | |
674 | } | |
675 | } | |
676 | #endif | |
677 | error = pci_eth_init(bis); | |
678 | return error; | |
679 | } | |
c48deb90 BP |
680 | |
681 | #if defined(CONFIG_RESET_PHY_R) | |
682 | void reset_phy(void) | |
683 | { | |
684 | mc_env_boot(); | |
685 | } | |
686 | #endif /* CONFIG_RESET_PHY_R */ |