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