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