Merge git://git.denx.de/u-boot-tegra
[platform/kernel/u-boot.git] / board / freescale / ls2080aqds / eth.c
1 /*
2  * Copyright 2015 Freescale Semiconductor, Inc.
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>
17 #include <fsl-mc/fsl_mc.h>
18 #include <fsl-mc/ldpaa_wriop.h>
19
20 #include "../common/qixis.h"
21
22 #include "ls2080aqds_qixis.h"
23
24 #define MC_BOOT_ENV_VAR "mcinitcmd"
25
26 #if defined(CONFIG_FSL_MC_ENET) && !defined(CONFIG_SPL_BUILD)
27  /* - In LS2080A there are only 16 SERDES lanes, spread across 2 SERDES banks.
28  *   Bank 1 -> Lanes A, B, C, D, E, F, G, H
29  *   Bank 2 -> Lanes A,B, C, D, E, F, G, H
30  */
31
32  /* Mapping of 16 SERDES lanes to LS2080A QDS board slots. A value of '0' here
33   * means that the mapping must be determined dynamically, or that the lane
34   * maps to something other than a board slot.
35   */
36
37 static u8 lane_to_slot_fsm1[] = {
38         0, 0, 0, 0, 0, 0, 0, 0
39 };
40
41 static u8 lane_to_slot_fsm2[] = {
42         0, 0, 0, 0, 0, 0, 0, 0
43 };
44
45 /* On the Vitesse VSC8234XHG SGMII riser card there are 4 SGMII PHYs
46  * housed.
47  */
48
49 static int xqsgii_riser_phy_addr[] = {
50         XQSGMII_CARD_PHY1_PORT0_ADDR,
51         XQSGMII_CARD_PHY2_PORT0_ADDR,
52         XQSGMII_CARD_PHY3_PORT0_ADDR,
53         XQSGMII_CARD_PHY4_PORT0_ADDR,
54         XQSGMII_CARD_PHY3_PORT2_ADDR,
55         XQSGMII_CARD_PHY1_PORT2_ADDR,
56         XQSGMII_CARD_PHY4_PORT2_ADDR,
57         XQSGMII_CARD_PHY2_PORT2_ADDR,
58 };
59
60 static int sgmii_riser_phy_addr[] = {
61         SGMII_CARD_PORT1_PHY_ADDR,
62         SGMII_CARD_PORT2_PHY_ADDR,
63         SGMII_CARD_PORT3_PHY_ADDR,
64         SGMII_CARD_PORT4_PHY_ADDR,
65 };
66
67 /* Slot2 does not have EMI connections */
68 #define EMI_NONE        0xFF
69 #define EMI1_SLOT1      0
70 #define EMI1_SLOT2      1
71 #define EMI1_SLOT3      2
72 #define EMI1_SLOT4      3
73 #define EMI1_SLOT5      4
74 #define EMI1_SLOT6      5
75 #define EMI2            6
76 #define SFP_TX          0
77
78 static const char * const mdio_names[] = {
79         "LS2080A_QDS_MDIO0",
80         "LS2080A_QDS_MDIO1",
81         "LS2080A_QDS_MDIO2",
82         "LS2080A_QDS_MDIO3",
83         "LS2080A_QDS_MDIO4",
84         "LS2080A_QDS_MDIO5",
85         DEFAULT_WRIOP_MDIO2_NAME,
86 };
87
88 struct ls2080a_qds_mdio {
89         u8 muxval;
90         struct mii_dev *realbus;
91 };
92
93 static void sgmii_configure_repeater(int serdes_port)
94 {
95         struct mii_dev *bus;
96         uint8_t a = 0xf;
97         int i, j, ret;
98         int dpmac_id = 0, dpmac, mii_bus = 0;
99         unsigned short value;
100         char dev[2][20] = {"LS2080A_QDS_MDIO0", "LS2080A_QDS_MDIO3"};
101         uint8_t i2c_addr[] = {0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5f, 0x60};
102
103         uint8_t ch_a_eq[] = {0x1, 0x2, 0x3, 0x7};
104         uint8_t ch_a_ctl2[] = {0x81, 0x82, 0x83, 0x84};
105         uint8_t ch_b_eq[] = {0x1, 0x2, 0x3, 0x7};
106         uint8_t ch_b_ctl2[] = {0x81, 0x82, 0x83, 0x84};
107
108         int *riser_phy_addr = &xqsgii_riser_phy_addr[0];
109
110         /* Set I2c to Slot 1 */
111         i2c_write(0x77, 0, 0, &a, 1);
112
113         for (dpmac = 0; dpmac < 8; dpmac++) {
114                 /* Check the PHY status */
115                 switch (serdes_port) {
116                 case 1:
117                         mii_bus = 0;
118                         dpmac_id = dpmac + 1;
119                         break;
120                 case 2:
121                         mii_bus = 1;
122                         dpmac_id = dpmac + 9;
123                         a = 0xb;
124                         i2c_write(0x76, 0, 0, &a, 1);
125                         break;
126                 }
127
128                 ret = miiphy_set_current_dev(dev[mii_bus]);
129                 if (ret > 0)
130                         goto error;
131
132                 bus = mdio_get_current_dev();
133                 debug("Reading from bus %s\n", bus->name);
134
135                 ret = miiphy_write(dev[mii_bus], riser_phy_addr[dpmac], 0x1f,
136                                    3);
137                 if (ret > 0)
138                         goto error;
139
140                 mdelay(10);
141                 ret = miiphy_read(dev[mii_bus], riser_phy_addr[dpmac], 0x11,
142                                   &value);
143                 if (ret > 0)
144                         goto error;
145
146                 mdelay(10);
147
148                 if ((value & 0xfff) == 0x401) {
149                         printf("DPMAC %d:PHY is ..... Configured\n", dpmac_id);
150                         miiphy_write(dev[mii_bus], riser_phy_addr[dpmac],
151                                      0x1f, 0);
152                         continue;
153                 }
154
155                 for (i = 0; i < 4; i++) {
156                         for (j = 0; j < 4; j++) {
157                                 a = 0x18;
158                                 i2c_write(i2c_addr[dpmac], 6, 1, &a, 1);
159                                 a = 0x38;
160                                 i2c_write(i2c_addr[dpmac], 4, 1, &a, 1);
161                                 a = 0x4;
162                                 i2c_write(i2c_addr[dpmac], 8, 1, &a, 1);
163
164                                 i2c_write(i2c_addr[dpmac], 0xf, 1,
165                                           &ch_a_eq[i], 1);
166                                 i2c_write(i2c_addr[dpmac], 0x11, 1,
167                                           &ch_a_ctl2[j], 1);
168
169                                 i2c_write(i2c_addr[dpmac], 0x16, 1,
170                                           &ch_b_eq[i], 1);
171                                 i2c_write(i2c_addr[dpmac], 0x18, 1,
172                                           &ch_b_ctl2[j], 1);
173
174                                 a = 0x14;
175                                 i2c_write(i2c_addr[dpmac], 0x23, 1, &a, 1);
176                                 a = 0xb5;
177                                 i2c_write(i2c_addr[dpmac], 0x2d, 1, &a, 1);
178                                 a = 0x20;
179                                 i2c_write(i2c_addr[dpmac], 4, 1, &a, 1);
180                                 mdelay(100);
181                                 ret = miiphy_read(dev[mii_bus],
182                                                   riser_phy_addr[dpmac],
183                                                   0x11, &value);
184                                 if (ret > 0)
185                                         goto error;
186
187                                 mdelay(100);
188                                 ret = miiphy_read(dev[mii_bus],
189                                                   riser_phy_addr[dpmac],
190                                                   0x11, &value);
191                                 if (ret > 0)
192                                         goto error;
193
194                                 if ((value & 0xfff) == 0x401) {
195                                         printf("DPMAC %d :PHY is configured ",
196                                                dpmac_id);
197                                         printf("after setting repeater 0x%x\n",
198                                                value);
199                                         i = 5;
200                                         j = 5;
201                                 } else {
202                                         printf("DPMAC %d :PHY is failed to ",
203                                                dpmac_id);
204                                         printf("configure the repeater 0x%x\n",
205                                                value);
206                                 }
207                         }
208                 }
209                 miiphy_write(dev[mii_bus], riser_phy_addr[dpmac], 0x1f, 0);
210         }
211 error:
212         if (ret)
213                 printf("DPMAC %d ..... FAILED to configure PHY\n", dpmac_id);
214         return;
215 }
216
217 static void qsgmii_configure_repeater(int dpmac)
218 {
219         uint8_t a = 0xf;
220         int i, j;
221         int i2c_phy_addr = 0;
222         int phy_addr = 0;
223         int i2c_addr[] = {0x58, 0x59, 0x5a, 0x5b};
224
225         uint8_t ch_a_eq[] = {0x1, 0x2, 0x3, 0x7};
226         uint8_t ch_a_ctl2[] = {0x81, 0x82, 0x83, 0x84};
227         uint8_t ch_b_eq[] = {0x1, 0x2, 0x3, 0x7};
228         uint8_t ch_b_ctl2[] = {0x81, 0x82, 0x83, 0x84};
229
230         const char *dev = "LS2080A_QDS_MDIO0";
231         int ret = 0;
232         unsigned short value;
233
234         /* Set I2c to Slot 1 */
235         i2c_write(0x77, 0, 0, &a, 1);
236
237         switch (dpmac) {
238         case 1:
239         case 2:
240         case 3:
241         case 4:
242                 i2c_phy_addr = i2c_addr[0];
243                 phy_addr = 0;
244                 break;
245
246         case 5:
247         case 6:
248         case 7:
249         case 8:
250                 i2c_phy_addr = i2c_addr[1];
251                 phy_addr = 4;
252                 break;
253
254         case 9:
255         case 10:
256         case 11:
257         case 12:
258                 i2c_phy_addr = i2c_addr[2];
259                 phy_addr = 8;
260                 break;
261
262         case 13:
263         case 14:
264         case 15:
265         case 16:
266                 i2c_phy_addr = i2c_addr[3];
267                 phy_addr = 0xc;
268                 break;
269         }
270
271         /* Check the PHY status */
272         ret = miiphy_set_current_dev(dev);
273         ret = miiphy_write(dev, phy_addr, 0x1f, 3);
274         mdelay(10);
275         ret = miiphy_read(dev, phy_addr, 0x11, &value);
276         mdelay(10);
277         ret = miiphy_read(dev, phy_addr, 0x11, &value);
278         mdelay(10);
279         if ((value & 0xf) == 0xf) {
280                 printf("DPMAC %d :PHY is ..... Configured\n", dpmac);
281                 return;
282         }
283
284         for (i = 0; i < 4; i++) {
285                 for (j = 0; j < 4; j++) {
286                         a = 0x18;
287                         i2c_write(i2c_phy_addr, 6, 1, &a, 1);
288                         a = 0x38;
289                         i2c_write(i2c_phy_addr, 4, 1, &a, 1);
290                         a = 0x4;
291                         i2c_write(i2c_phy_addr, 8, 1, &a, 1);
292
293                         i2c_write(i2c_phy_addr, 0xf, 1, &ch_a_eq[i], 1);
294                         i2c_write(i2c_phy_addr, 0x11, 1, &ch_a_ctl2[j], 1);
295
296                         i2c_write(i2c_phy_addr, 0x16, 1, &ch_b_eq[i], 1);
297                         i2c_write(i2c_phy_addr, 0x18, 1, &ch_b_ctl2[j], 1);
298
299                         a = 0x14;
300                         i2c_write(i2c_phy_addr, 0x23, 1, &a, 1);
301                         a = 0xb5;
302                         i2c_write(i2c_phy_addr, 0x2d, 1, &a, 1);
303                         a = 0x20;
304                         i2c_write(i2c_phy_addr, 4, 1, &a, 1);
305                         mdelay(100);
306                         ret = miiphy_read(dev, phy_addr, 0x11, &value);
307                         if (ret > 0)
308                                 goto error;
309                         mdelay(1);
310                         ret = miiphy_read(dev, phy_addr, 0x11, &value);
311                         if (ret > 0)
312                                 goto error;
313                         mdelay(10);
314                         if ((value & 0xf) == 0xf) {
315                                 printf("DPMAC %d :PHY is ..... Configured\n",
316                                        dpmac);
317                                 return;
318                         }
319                 }
320         }
321 error:
322         printf("DPMAC %d :PHY ..... FAILED to configure PHY\n", dpmac);
323         return;
324 }
325
326 static const char *ls2080a_qds_mdio_name_for_muxval(u8 muxval)
327 {
328         return mdio_names[muxval];
329 }
330
331 struct mii_dev *mii_dev_for_muxval(u8 muxval)
332 {
333         struct mii_dev *bus;
334         const char *name = ls2080a_qds_mdio_name_for_muxval(muxval);
335
336         if (!name) {
337                 printf("No bus for muxval %x\n", muxval);
338                 return NULL;
339         }
340
341         bus = miiphy_get_dev_by_name(name);
342
343         if (!bus) {
344                 printf("No bus by name %s\n", name);
345                 return NULL;
346         }
347
348         return bus;
349 }
350
351 static void ls2080a_qds_enable_SFP_TX(u8 muxval)
352 {
353         u8 brdcfg9;
354
355         brdcfg9 = QIXIS_READ(brdcfg[9]);
356         brdcfg9 &= ~BRDCFG9_SFPTX_MASK;
357         brdcfg9 |= (muxval << BRDCFG9_SFPTX_SHIFT);
358         QIXIS_WRITE(brdcfg[9], brdcfg9);
359 }
360
361 static void ls2080a_qds_mux_mdio(u8 muxval)
362 {
363         u8 brdcfg4;
364
365         if (muxval <= 5) {
366                 brdcfg4 = QIXIS_READ(brdcfg[4]);
367                 brdcfg4 &= ~BRDCFG4_EMISEL_MASK;
368                 brdcfg4 |= (muxval << BRDCFG4_EMISEL_SHIFT);
369                 QIXIS_WRITE(brdcfg[4], brdcfg4);
370         }
371 }
372
373 static int ls2080a_qds_mdio_read(struct mii_dev *bus, int addr,
374                                  int devad, int regnum)
375 {
376         struct ls2080a_qds_mdio *priv = bus->priv;
377
378         ls2080a_qds_mux_mdio(priv->muxval);
379
380         return priv->realbus->read(priv->realbus, addr, devad, regnum);
381 }
382
383 static int ls2080a_qds_mdio_write(struct mii_dev *bus, int addr, int devad,
384                                   int regnum, u16 value)
385 {
386         struct ls2080a_qds_mdio *priv = bus->priv;
387
388         ls2080a_qds_mux_mdio(priv->muxval);
389
390         return priv->realbus->write(priv->realbus, addr, devad, regnum, value);
391 }
392
393 static int ls2080a_qds_mdio_reset(struct mii_dev *bus)
394 {
395         struct ls2080a_qds_mdio *priv = bus->priv;
396
397         return priv->realbus->reset(priv->realbus);
398 }
399
400 static int ls2080a_qds_mdio_init(char *realbusname, u8 muxval)
401 {
402         struct ls2080a_qds_mdio *pmdio;
403         struct mii_dev *bus = mdio_alloc();
404
405         if (!bus) {
406                 printf("Failed to allocate ls2080a_qds MDIO bus\n");
407                 return -1;
408         }
409
410         pmdio = malloc(sizeof(*pmdio));
411         if (!pmdio) {
412                 printf("Failed to allocate ls2080a_qds private data\n");
413                 free(bus);
414                 return -1;
415         }
416
417         bus->read = ls2080a_qds_mdio_read;
418         bus->write = ls2080a_qds_mdio_write;
419         bus->reset = ls2080a_qds_mdio_reset;
420         strcpy(bus->name, ls2080a_qds_mdio_name_for_muxval(muxval));
421
422         pmdio->realbus = miiphy_get_dev_by_name(realbusname);
423
424         if (!pmdio->realbus) {
425                 printf("No bus with name %s\n", realbusname);
426                 free(bus);
427                 free(pmdio);
428                 return -1;
429         }
430
431         pmdio->muxval = muxval;
432         bus->priv = pmdio;
433
434         return mdio_register(bus);
435 }
436
437 /*
438  * Initialize the dpmac_info array.
439  *
440  */
441 static void initialize_dpmac_to_slot(void)
442 {
443         struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
444         int serdes1_prtcl = (in_le32(&gur->rcwsr[28]) &
445                                 FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK)
446                 >> FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
447         int serdes2_prtcl = (in_le32(&gur->rcwsr[28]) &
448                                 FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_MASK)
449                 >> FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_SHIFT;
450
451         char *env_hwconfig;
452         env_hwconfig = env_get("hwconfig");
453
454         switch (serdes1_prtcl) {
455         case 0x07:
456         case 0x09:
457         case 0x33:
458                 printf("qds: WRIOP: Supported SerDes1 Protocol 0x%02x\n",
459                        serdes1_prtcl);
460                 lane_to_slot_fsm1[0] = EMI1_SLOT1;
461                 lane_to_slot_fsm1[1] = EMI1_SLOT1;
462                 lane_to_slot_fsm1[2] = EMI1_SLOT1;
463                 lane_to_slot_fsm1[3] = EMI1_SLOT1;
464                 if (hwconfig_f("xqsgmii", env_hwconfig)) {
465                         lane_to_slot_fsm1[4] = EMI1_SLOT1;
466                         lane_to_slot_fsm1[5] = EMI1_SLOT1;
467                         lane_to_slot_fsm1[6] = EMI1_SLOT1;
468                         lane_to_slot_fsm1[7] = EMI1_SLOT1;
469                 } else {
470                         lane_to_slot_fsm1[4] = EMI1_SLOT2;
471                         lane_to_slot_fsm1[5] = EMI1_SLOT2;
472                         lane_to_slot_fsm1[6] = EMI1_SLOT2;
473                         lane_to_slot_fsm1[7] = EMI1_SLOT2;
474                 }
475                 break;
476
477         case 0x39:
478                 printf("qds: WRIOP: Supported SerDes1 Protocol 0x%02x\n",
479                        serdes1_prtcl);
480                 if (hwconfig_f("xqsgmii", env_hwconfig)) {
481                         lane_to_slot_fsm1[0] = EMI1_SLOT3;
482                         lane_to_slot_fsm1[1] = EMI1_SLOT3;
483                         lane_to_slot_fsm1[2] = EMI1_SLOT3;
484                         lane_to_slot_fsm1[3] = EMI_NONE;
485                 } else {
486                         lane_to_slot_fsm1[0] = EMI_NONE;
487                         lane_to_slot_fsm1[1] = EMI_NONE;
488                         lane_to_slot_fsm1[2] = EMI_NONE;
489                         lane_to_slot_fsm1[3] = EMI_NONE;
490                 }
491                 lane_to_slot_fsm1[4] = EMI1_SLOT3;
492                 lane_to_slot_fsm1[5] = EMI1_SLOT3;
493                 lane_to_slot_fsm1[6] = EMI1_SLOT3;
494                 lane_to_slot_fsm1[7] = EMI_NONE;
495                 break;
496
497         case 0x4D:
498                 printf("qds: WRIOP: Supported SerDes1 Protocol 0x%02x\n",
499                        serdes1_prtcl);
500                 if (hwconfig_f("xqsgmii", env_hwconfig)) {
501                         lane_to_slot_fsm1[0] = EMI1_SLOT3;
502                         lane_to_slot_fsm1[1] = EMI1_SLOT3;
503                         lane_to_slot_fsm1[2] = EMI_NONE;
504                         lane_to_slot_fsm1[3] = EMI_NONE;
505                 } else {
506                         lane_to_slot_fsm1[0] = EMI_NONE;
507                         lane_to_slot_fsm1[1] = EMI_NONE;
508                         lane_to_slot_fsm1[2] = EMI_NONE;
509                         lane_to_slot_fsm1[3] = EMI_NONE;
510                 }
511                 lane_to_slot_fsm1[4] = EMI1_SLOT3;
512                 lane_to_slot_fsm1[5] = EMI1_SLOT3;
513                 lane_to_slot_fsm1[6] = EMI_NONE;
514                 lane_to_slot_fsm1[7] = EMI_NONE;
515                 break;
516
517         case 0x2A:
518         case 0x4B:
519         case 0x4C:
520                 printf("qds: WRIOP: Supported SerDes1 Protocol 0x%02x\n",
521                        serdes1_prtcl);
522                 break;
523         default:
524                 printf("%s qds: WRIOP: Unsupported SerDes1 Protocol 0x%02x\n",
525                        __func__, serdes1_prtcl);
526                 break;
527         }
528
529         switch (serdes2_prtcl) {
530         case 0x07:
531         case 0x08:
532         case 0x09:
533         case 0x49:
534                 printf("qds: WRIOP: Supported SerDes2 Protocol 0x%02x\n",
535                        serdes2_prtcl);
536                 lane_to_slot_fsm2[0] = EMI1_SLOT4;
537                 lane_to_slot_fsm2[1] = EMI1_SLOT4;
538                 lane_to_slot_fsm2[2] = EMI1_SLOT4;
539                 lane_to_slot_fsm2[3] = EMI1_SLOT4;
540
541                 if (hwconfig_f("xqsgmii", env_hwconfig)) {
542                         lane_to_slot_fsm2[4] = EMI1_SLOT4;
543                         lane_to_slot_fsm2[5] = EMI1_SLOT4;
544                         lane_to_slot_fsm2[6] = EMI1_SLOT4;
545                         lane_to_slot_fsm2[7] = EMI1_SLOT4;
546                 } else {
547                         /* No MDIO physical connection */
548                         lane_to_slot_fsm2[4] = EMI1_SLOT6;
549                         lane_to_slot_fsm2[5] = EMI1_SLOT6;
550                         lane_to_slot_fsm2[6] = EMI1_SLOT6;
551                         lane_to_slot_fsm2[7] = EMI1_SLOT6;
552                 }
553                 break;
554
555         case 0x47:
556                 printf("qds: WRIOP: Supported SerDes2 Protocol 0x%02x\n",
557                        serdes2_prtcl);
558                 lane_to_slot_fsm2[0] = EMI_NONE;
559                 lane_to_slot_fsm2[1] = EMI1_SLOT5;
560                 lane_to_slot_fsm2[2] = EMI1_SLOT5;
561                 lane_to_slot_fsm2[3] = EMI1_SLOT5;
562
563                 if (hwconfig_f("xqsgmii", env_hwconfig)) {
564                         lane_to_slot_fsm2[4] = EMI_NONE;
565                         lane_to_slot_fsm2[5] = EMI1_SLOT5;
566                         lane_to_slot_fsm2[6] = EMI1_SLOT5;
567                         lane_to_slot_fsm2[7] = EMI1_SLOT5;
568                 }
569                 break;
570
571         case 0x57:
572                 printf("qds: WRIOP: Supported SerDes2 Protocol 0x%02x\n",
573                        serdes2_prtcl);
574                 if (hwconfig_f("xqsgmii", env_hwconfig)) {
575                         lane_to_slot_fsm2[0] = EMI_NONE;
576                         lane_to_slot_fsm2[1] = EMI_NONE;
577                         lane_to_slot_fsm2[2] = EMI_NONE;
578                         lane_to_slot_fsm2[3] = EMI_NONE;
579                 }
580                 lane_to_slot_fsm2[4] = EMI_NONE;
581                 lane_to_slot_fsm2[5] = EMI_NONE;
582                 lane_to_slot_fsm2[6] = EMI1_SLOT5;
583                 lane_to_slot_fsm2[7] = EMI1_SLOT5;
584                 break;
585
586         default:
587                 printf(" %s qds: WRIOP: Unsupported SerDes2 Protocol 0x%02x\n",
588                        __func__ , serdes2_prtcl);
589                 break;
590         }
591 }
592
593 void ls2080a_handle_phy_interface_sgmii(int dpmac_id)
594 {
595         int lane, slot;
596         struct mii_dev *bus;
597         struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
598         int serdes1_prtcl = (in_le32(&gur->rcwsr[28]) &
599                                 FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK)
600                 >> FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
601         int serdes2_prtcl = (in_le32(&gur->rcwsr[28]) &
602                                 FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_MASK)
603                 >> FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_SHIFT;
604
605         int *riser_phy_addr;
606         char *env_hwconfig = env_get("hwconfig");
607
608         if (hwconfig_f("xqsgmii", env_hwconfig))
609                 riser_phy_addr = &xqsgii_riser_phy_addr[0];
610         else
611                 riser_phy_addr = &sgmii_riser_phy_addr[0];
612
613         if (dpmac_id > WRIOP1_DPMAC9)
614                 goto serdes2;
615
616         switch (serdes1_prtcl) {
617         case 0x07:
618         case 0x39:
619         case 0x4D:
620                 lane = serdes_get_first_lane(FSL_SRDS_1, SGMII1 + dpmac_id - 1);
621
622                 slot = lane_to_slot_fsm1[lane];
623
624                 switch (++slot) {
625                 case 1:
626                         /* Slot housing a SGMII riser card? */
627                         wriop_set_phy_address(dpmac_id,
628                                               riser_phy_addr[dpmac_id - 1]);
629                         dpmac_info[dpmac_id].board_mux = EMI1_SLOT1;
630                         bus = mii_dev_for_muxval(EMI1_SLOT1);
631                         wriop_set_mdio(dpmac_id, bus);
632                         break;
633                 case 2:
634                         /* Slot housing a SGMII riser card? */
635                         wriop_set_phy_address(dpmac_id,
636                                               riser_phy_addr[dpmac_id - 1]);
637                         dpmac_info[dpmac_id].board_mux = EMI1_SLOT2;
638                         bus = mii_dev_for_muxval(EMI1_SLOT2);
639                         wriop_set_mdio(dpmac_id, bus);
640                         break;
641                 case 3:
642                         if (slot == EMI_NONE)
643                                 return;
644                         if (serdes1_prtcl == 0x39) {
645                                 wriop_set_phy_address(dpmac_id,
646                                         riser_phy_addr[dpmac_id - 2]);
647                                 if (dpmac_id >= 6 && hwconfig_f("xqsgmii",
648                                                                 env_hwconfig))
649                                         wriop_set_phy_address(dpmac_id,
650                                                 riser_phy_addr[dpmac_id - 3]);
651                         } else {
652                                 wriop_set_phy_address(dpmac_id,
653                                         riser_phy_addr[dpmac_id - 2]);
654                                 if (dpmac_id >= 7 && hwconfig_f("xqsgmii",
655                                                                 env_hwconfig))
656                                         wriop_set_phy_address(dpmac_id,
657                                                 riser_phy_addr[dpmac_id - 3]);
658                         }
659                         dpmac_info[dpmac_id].board_mux = EMI1_SLOT3;
660                         bus = mii_dev_for_muxval(EMI1_SLOT3);
661                         wriop_set_mdio(dpmac_id, bus);
662                         break;
663                 case 4:
664                         break;
665                 case 5:
666                         break;
667                 case 6:
668                         break;
669                 }
670         break;
671         default:
672                 printf("%s qds: WRIOP: Unsupported SerDes1 Protocol 0x%02x\n",
673                        __func__ , serdes1_prtcl);
674         break;
675         }
676
677 serdes2:
678         switch (serdes2_prtcl) {
679         case 0x07:
680         case 0x08:
681         case 0x49:
682         case 0x47:
683         case 0x57:
684                 lane = serdes_get_first_lane(FSL_SRDS_2, SGMII9 +
685                                                         (dpmac_id - 9));
686                 slot = lane_to_slot_fsm2[lane];
687
688                 switch (++slot) {
689                 case 1:
690                         break;
691                 case 3:
692                         break;
693                 case 4:
694                         /* Slot housing a SGMII riser card? */
695                         wriop_set_phy_address(dpmac_id,
696                                               riser_phy_addr[dpmac_id - 9]);
697                         dpmac_info[dpmac_id].board_mux = EMI1_SLOT4;
698                         bus = mii_dev_for_muxval(EMI1_SLOT4);
699                         wriop_set_mdio(dpmac_id, bus);
700                 break;
701                 case 5:
702                         if (slot == EMI_NONE)
703                                 return;
704                         if (serdes2_prtcl == 0x47) {
705                                 wriop_set_phy_address(dpmac_id,
706                                               riser_phy_addr[dpmac_id - 10]);
707                                 if (dpmac_id >= 14 && hwconfig_f("xqsgmii",
708                                                                  env_hwconfig))
709                                         wriop_set_phy_address(dpmac_id,
710                                                 riser_phy_addr[dpmac_id - 11]);
711                         } else {
712                                 wriop_set_phy_address(dpmac_id,
713                                         riser_phy_addr[dpmac_id - 11]);
714                         }
715                         dpmac_info[dpmac_id].board_mux = EMI1_SLOT5;
716                         bus = mii_dev_for_muxval(EMI1_SLOT5);
717                         wriop_set_mdio(dpmac_id, bus);
718                         break;
719                 case 6:
720                         /* Slot housing a SGMII riser card? */
721                         wriop_set_phy_address(dpmac_id,
722                                               riser_phy_addr[dpmac_id - 13]);
723                         dpmac_info[dpmac_id].board_mux = EMI1_SLOT6;
724                         bus = mii_dev_for_muxval(EMI1_SLOT6);
725                         wriop_set_mdio(dpmac_id, bus);
726                 break;
727         }
728         break;
729         default:
730                 printf("%s qds: WRIOP: Unsupported SerDes2 Protocol 0x%02x\n",
731                        __func__, serdes2_prtcl);
732         break;
733         }
734 }
735
736 void ls2080a_handle_phy_interface_qsgmii(int dpmac_id)
737 {
738         int lane = 0, slot;
739         struct mii_dev *bus;
740         struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
741         int serdes1_prtcl = (in_le32(&gur->rcwsr[28]) &
742                                 FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK)
743                 >> FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
744
745         switch (serdes1_prtcl) {
746         case 0x33:
747                 switch (dpmac_id) {
748                 case 1:
749                 case 2:
750                 case 3:
751                 case 4:
752                         lane = serdes_get_first_lane(FSL_SRDS_1, QSGMII_A);
753                 break;
754                 case 5:
755                 case 6:
756                 case 7:
757                 case 8:
758                         lane = serdes_get_first_lane(FSL_SRDS_1, QSGMII_B);
759                 break;
760                 case 9:
761                 case 10:
762                 case 11:
763                 case 12:
764                         lane = serdes_get_first_lane(FSL_SRDS_1, QSGMII_C);
765                 break;
766                 case 13:
767                 case 14:
768                 case 15:
769                 case 16:
770                         lane = serdes_get_first_lane(FSL_SRDS_1, QSGMII_D);
771                 break;
772         }
773
774                 slot = lane_to_slot_fsm1[lane];
775
776                 switch (++slot) {
777                 case 1:
778                         /* Slot housing a QSGMII riser card? */
779                         wriop_set_phy_address(dpmac_id, dpmac_id - 1);
780                         dpmac_info[dpmac_id].board_mux = EMI1_SLOT1;
781                         bus = mii_dev_for_muxval(EMI1_SLOT1);
782                         wriop_set_mdio(dpmac_id, bus);
783                         break;
784                 case 3:
785                         break;
786                 case 4:
787                         break;
788                 case 5:
789                 break;
790                 case 6:
791                         break;
792         }
793         break;
794         default:
795                 printf("qds: WRIOP: Unsupported SerDes Protocol 0x%02x\n",
796                        serdes1_prtcl);
797         break;
798         }
799
800         qsgmii_configure_repeater(dpmac_id);
801 }
802
803 void ls2080a_handle_phy_interface_xsgmii(int i)
804 {
805         struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
806         int serdes1_prtcl = (in_le32(&gur->rcwsr[28]) &
807                                 FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK)
808                 >> FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
809
810         switch (serdes1_prtcl) {
811         case 0x2A:
812         case 0x4B:
813         case 0x4C:
814                 /*
815                  * XFI does not need a PHY to work, but to avoid U-Boot use
816                  * default PHY address which is zero to a MAC when it found
817                  * a MAC has no PHY address, we give a PHY address to XFI
818                  * MAC, and should not use a real XAUI PHY address, since
819                  * MDIO can access it successfully, and then MDIO thinks
820                  * the XAUI card is used for the XFI MAC, which will cause
821                  * error.
822                  */
823                 wriop_set_phy_address(i, i + 4);
824                 ls2080a_qds_enable_SFP_TX(SFP_TX);
825
826                 break;
827         default:
828                 printf("qds: WRIOP: Unsupported SerDes Protocol 0x%02x\n",
829                        serdes1_prtcl);
830                 break;
831         }
832 }
833 #endif
834
835 int board_eth_init(bd_t *bis)
836 {
837         int error;
838 #if defined(CONFIG_FSL_MC_ENET) && !defined(CONFIG_SPL_BUILD)
839         struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
840         int serdes1_prtcl = (in_le32(&gur->rcwsr[28]) &
841                                 FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK)
842                 >> FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
843         int serdes2_prtcl = (in_le32(&gur->rcwsr[28]) &
844                                 FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_MASK)
845                 >> FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_SHIFT;
846
847         struct memac_mdio_info *memac_mdio0_info;
848         struct memac_mdio_info *memac_mdio1_info;
849         unsigned int i;
850         char *env_hwconfig;
851
852         env_hwconfig = env_get("hwconfig");
853
854         initialize_dpmac_to_slot();
855
856         memac_mdio0_info = (struct memac_mdio_info *)malloc(
857                                         sizeof(struct memac_mdio_info));
858         memac_mdio0_info->regs =
859                 (struct memac_mdio_controller *)
860                                         CONFIG_SYS_FSL_WRIOP1_MDIO1;
861         memac_mdio0_info->name = DEFAULT_WRIOP_MDIO1_NAME;
862
863         /* Register the real MDIO1 bus */
864         fm_memac_mdio_init(bis, memac_mdio0_info);
865
866         memac_mdio1_info = (struct memac_mdio_info *)malloc(
867                                         sizeof(struct memac_mdio_info));
868         memac_mdio1_info->regs =
869                 (struct memac_mdio_controller *)
870                                         CONFIG_SYS_FSL_WRIOP1_MDIO2;
871         memac_mdio1_info->name = DEFAULT_WRIOP_MDIO2_NAME;
872
873         /* Register the real MDIO2 bus */
874         fm_memac_mdio_init(bis, memac_mdio1_info);
875
876         /* Register the muxing front-ends to the MDIO buses */
877         ls2080a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT1);
878         ls2080a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT2);
879         ls2080a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT3);
880         ls2080a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT4);
881         ls2080a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT5);
882         ls2080a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT6);
883
884         ls2080a_qds_mdio_init(DEFAULT_WRIOP_MDIO2_NAME, EMI2);
885
886         for (i = WRIOP1_DPMAC1; i < NUM_WRIOP_PORTS; i++) {
887                 switch (wriop_get_enet_if(i)) {
888                 case PHY_INTERFACE_MODE_QSGMII:
889                         ls2080a_handle_phy_interface_qsgmii(i);
890                         break;
891                 case PHY_INTERFACE_MODE_SGMII:
892                         ls2080a_handle_phy_interface_sgmii(i);
893                         break;
894                 case PHY_INTERFACE_MODE_XGMII:
895                         ls2080a_handle_phy_interface_xsgmii(i);
896                         break;
897                 default:
898                         break;
899
900                 if (i == 16)
901                         i = NUM_WRIOP_PORTS;
902                 }
903         }
904
905         error = cpu_eth_init(bis);
906
907         if (hwconfig_f("xqsgmii", env_hwconfig)) {
908                 if (serdes1_prtcl == 0x7)
909                         sgmii_configure_repeater(1);
910                 if (serdes2_prtcl == 0x7 || serdes2_prtcl == 0x8 ||
911                     serdes2_prtcl == 0x49)
912                         sgmii_configure_repeater(2);
913         }
914 #endif
915         error = pci_eth_init(bis);
916         return error;
917 }
918
919 #if defined(CONFIG_RESET_PHY_R)
920 void reset_phy(void)
921 {
922         mc_env_boot();
923 }
924 #endif /* CONFIG_RESET_PHY_R */