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