blob: f42b5022c4c2855aedad204173a5293384dd12e8 [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>
Simon Glass0f2af882020-05-10 11:40:05 -06009#include <log.h>
Simon Glass0c364412019-12-28 10:44:48 -070010#include <net.h>
Ashish Kumar1ef4c772017-08-31 16:12:55 +053011#include <netdev.h>
12#include <asm/io.h>
13#include <asm/arch/fsl_serdes.h>
14#include <hwconfig.h>
15#include <fsl_mdio.h>
16#include <malloc.h>
Ashish Kumarbc6ceca2018-04-13 12:28:45 +053017#include <phy.h>
Ashish Kumar1ef4c772017-08-31 16:12:55 +053018#include <fm_eth.h>
19#include <i2c.h>
20#include <miiphy.h>
Bogdan Purcareata33ba9392017-10-05 06:56:53 +000021#include <fsl-mc/fsl_mc.h>
Ashish Kumar1ef4c772017-08-31 16:12:55 +053022#include <fsl-mc/ldpaa_wriop.h>
23
24#include "../common/qixis.h"
25
26#include "ls1088a_qixis.h"
27
Ashish Kumar1ef4c772017-08-31 16:12:55 +053028#ifdef CONFIG_FSL_MC_ENET
29
30#define SFP_TX 0
31
32 /* - In LS1088A A there are only 16 SERDES lanes, spread across 2 SERDES banks.
33 * Bank 1 -> Lanes A, B, C, D,
34 * Bank 2 -> Lanes A,B, C, D,
35 */
36
37 /* Mapping of 8 SERDES lanes to LS1088A 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
42static u8 lane_to_slot_fsm1[] = {
43 0, 0, 0, 0, 0, 0, 0, 0
44};
45
46/* On the Vitesse VSC8234XHG SGMII riser card there are 4 SGMII PHYs
47 * housed.
48 */
49
50static int xqsgii_riser_phy_addr[] = {
51 XQSGMII_CARD_PHY1_PORT0_ADDR,
52 XQSGMII_CARD_PHY2_PORT0_ADDR,
53 XQSGMII_CARD_PHY3_PORT0_ADDR,
54 XQSGMII_CARD_PHY4_PORT0_ADDR,
55 XQSGMII_CARD_PHY3_PORT2_ADDR,
56 XQSGMII_CARD_PHY1_PORT2_ADDR,
57 XQSGMII_CARD_PHY4_PORT2_ADDR,
58 XQSGMII_CARD_PHY2_PORT2_ADDR,
59};
60
61static int sgmii_riser_phy_addr[] = {
62 SGMII_CARD_PORT1_PHY_ADDR,
63 SGMII_CARD_PORT2_PHY_ADDR,
64 SGMII_CARD_PORT3_PHY_ADDR,
65 SGMII_CARD_PORT4_PHY_ADDR,
66};
67
68/* Slot2 does not have EMI connections */
69#define EMI_NONE 0xFF
70#define EMI1_RGMII1 0
71#define EMI1_RGMII2 1
72#define EMI1_SLOT1 2
73
74static const char * const mdio_names[] = {
75 "LS1088A_QDS_MDIO0",
76 "LS1088A_QDS_MDIO1",
77 "LS1088A_QDS_MDIO2",
78 DEFAULT_WRIOP_MDIO2_NAME,
79};
80
81struct ls1088a_qds_mdio {
82 u8 muxval;
83 struct mii_dev *realbus;
84};
85
Chuanhua Handddcadb2019-07-26 20:25:35 +080086struct reg_pair {
87 uint addr;
88 u8 *val;
89};
90
Ashish Kumar1ef4c772017-08-31 16:12:55 +053091static void sgmii_configure_repeater(int dpmac)
92{
93 struct mii_dev *bus;
94 uint8_t a = 0xf;
Chuanhua Handddcadb2019-07-26 20:25:35 +080095 int i, j, k, ret;
Ashish Kumar1ef4c772017-08-31 16:12:55 +053096 unsigned short value;
97 const char *dev = "LS1088A_QDS_MDIO2";
98 int i2c_addr[] = {0x58, 0x59, 0x5a, 0x5b};
99 int i2c_phy_addr = 0;
100 int phy_addr = 0;
101
102 uint8_t ch_a_eq[] = {0x1, 0x2, 0x3, 0x7};
103 uint8_t ch_a_ctl2[] = {0x81, 0x82, 0x83, 0x84};
104 uint8_t ch_b_eq[] = {0x1, 0x2, 0x3, 0x7};
105 uint8_t ch_b_ctl2[] = {0x81, 0x82, 0x83, 0x84};
106
Chuanhua Handddcadb2019-07-26 20:25:35 +0800107 u8 reg_val[6] = {0x18, 0x38, 0x4, 0x14, 0xb5, 0x20};
108 struct reg_pair reg_pair[10] = {
109 {6, &reg_val[0]}, {4, &reg_val[1]},
110 {8, &reg_val[2]}, {0xf, NULL},
111 {0x11, NULL}, {0x16, NULL},
112 {0x18, NULL}, {0x23, &reg_val[3]},
113 {0x2d, &reg_val[4]}, {4, &reg_val[5]},
114 };
115#ifdef CONFIG_DM_I2C
116 struct udevice *udev;
117#endif
118
Ashish Kumar1ef4c772017-08-31 16:12:55 +0530119 /* Set I2c to Slot 1 */
Chuanhua Handddcadb2019-07-26 20:25:35 +0800120#ifndef CONFIG_DM_I2C
121 ret = i2c_write(0x77, 0, 0, &a, 1);
122#else
123 ret = i2c_get_chip_for_busnum(0, 0x77, 1, &udev);
124 if (!ret)
125 ret = dm_i2c_write(udev, 0, &a, 1);
126#endif
127 if (ret)
128 goto error;
Ashish Kumar1ef4c772017-08-31 16:12:55 +0530129
130 switch (dpmac) {
131 case 1:
132 i2c_phy_addr = i2c_addr[1];
133 phy_addr = 4;
134 break;
135 case 2:
136 i2c_phy_addr = i2c_addr[0];
137 phy_addr = 0;
138 break;
139 case 3:
140 i2c_phy_addr = i2c_addr[3];
141 phy_addr = 0xc;
142 break;
143 case 7:
144 i2c_phy_addr = i2c_addr[2];
145 phy_addr = 8;
146 break;
147 }
148
149 /* Check the PHY status */
150 ret = miiphy_set_current_dev(dev);
151 if (ret > 0)
152 goto error;
153
154 bus = mdio_get_current_dev();
155 debug("Reading from bus %s\n", bus->name);
156
157 ret = miiphy_write(dev, phy_addr, 0x1f, 3);
158 if (ret > 0)
159 goto error;
160
161 mdelay(10);
162 ret = miiphy_read(dev, phy_addr, 0x11, &value);
163 if (ret > 0)
164 goto error;
165
166 mdelay(10);
167
168 if ((value & 0xfff) == 0x401) {
169 miiphy_write(dev, phy_addr, 0x1f, 0);
170 printf("DPMAC %d:PHY is ..... Configured\n", dpmac);
171 return;
172 }
173
Chuanhua Handddcadb2019-07-26 20:25:35 +0800174#ifdef CONFIG_DM_I2C
175 i2c_get_chip_for_busnum(0, i2c_phy_addr, 1, &udev);
176#endif
177
Ashish Kumar1ef4c772017-08-31 16:12:55 +0530178 for (i = 0; i < 4; i++) {
179 for (j = 0; j < 4; j++) {
Chuanhua Handddcadb2019-07-26 20:25:35 +0800180 reg_pair[3].val = &ch_a_eq[i];
181 reg_pair[4].val = &ch_a_ctl2[j];
182 reg_pair[5].val = &ch_b_eq[i];
183 reg_pair[6].val = &ch_b_ctl2[j];
184 for (k = 0; k < 10; k++) {
185#ifndef CONFIG_DM_I2C
186 ret = i2c_write(i2c_phy_addr,
187 reg_pair[k].addr,
188 1, reg_pair[k].val, 1);
189#else
190 ret = i2c_get_chip_for_busnum(0,
191 i2c_phy_addr,
192 1, &udev);
193 if (!ret)
194 ret = dm_i2c_write(udev,
195 reg_pair[k].addr,
196 reg_pair[k].val, 1);
197#endif
198 if (ret)
199 goto error;
200 }
Ashish Kumar1ef4c772017-08-31 16:12:55 +0530201
Ashish Kumar1ef4c772017-08-31 16:12:55 +0530202 mdelay(100);
203 ret = miiphy_read(dev, phy_addr, 0x11, &value);
204 if (ret > 0)
205 goto error;
206
207 mdelay(100);
208 ret = miiphy_read(dev, phy_addr, 0x11, &value);
209 if (ret > 0)
210 goto error;
211
212 if ((value & 0xfff) == 0x401) {
213 printf("DPMAC %d :PHY is configured ",
214 dpmac);
215 printf("after setting repeater 0x%x\n",
216 value);
217 i = 5;
218 j = 5;
219 } else {
220 printf("DPMAC %d :PHY is failed to ",
221 dpmac);
222 printf("configure the repeater 0x%x\n", value);
223 }
224 }
225 }
226 miiphy_write(dev, phy_addr, 0x1f, 0);
227error:
228 if (ret)
229 printf("DPMAC %d ..... FAILED to configure PHY\n", dpmac);
230 return;
231}
232
233static void qsgmii_configure_repeater(int dpmac)
234{
235 uint8_t a = 0xf;
Chuanhua Handddcadb2019-07-26 20:25:35 +0800236 int i, j, k;
Ashish Kumar1ef4c772017-08-31 16:12:55 +0530237 int i2c_phy_addr = 0;
238 int phy_addr = 0;
239 int i2c_addr[] = {0x58, 0x59, 0x5a, 0x5b};
240
241 uint8_t ch_a_eq[] = {0x1, 0x2, 0x3, 0x7};
242 uint8_t ch_a_ctl2[] = {0x81, 0x82, 0x83, 0x84};
243 uint8_t ch_b_eq[] = {0x1, 0x2, 0x3, 0x7};
244 uint8_t ch_b_ctl2[] = {0x81, 0x82, 0x83, 0x84};
245
Chuanhua Handddcadb2019-07-26 20:25:35 +0800246 u8 reg_val[6] = {0x18, 0x38, 0x4, 0x14, 0xb5, 0x20};
247 struct reg_pair reg_pair[10] = {
248 {6, &reg_val[0]}, {4, &reg_val[1]},
249 {8, &reg_val[2]}, {0xf, NULL},
250 {0x11, NULL}, {0x16, NULL},
251 {0x18, NULL}, {0x23, &reg_val[3]},
252 {0x2d, &reg_val[4]}, {4, &reg_val[5]},
253 };
254
Ashish Kumar1ef4c772017-08-31 16:12:55 +0530255 const char *dev = mdio_names[EMI1_SLOT1];
256 int ret = 0;
257 unsigned short value;
Chuanhua Handddcadb2019-07-26 20:25:35 +0800258#ifdef CONFIG_DM_I2C
259 struct udevice *udev;
260#endif
Ashish Kumar1ef4c772017-08-31 16:12:55 +0530261
262 /* Set I2c to Slot 1 */
Chuanhua Handddcadb2019-07-26 20:25:35 +0800263#ifndef CONFIG_DM_I2C
264 ret = i2c_write(0x77, 0, 0, &a, 1);
265#else
266 ret = i2c_get_chip_for_busnum(0, 0x77, 1, &udev);
267 if (!ret)
268 ret = dm_i2c_write(udev, 0, &a, 1);
269#endif
270 if (ret)
271 goto error;
Ashish Kumar1ef4c772017-08-31 16:12:55 +0530272
273 switch (dpmac) {
274 case 7:
275 case 8:
276 case 9:
277 case 10:
278 i2c_phy_addr = i2c_addr[2];
279 phy_addr = 8;
280 break;
281
282 case 3:
283 case 4:
284 case 5:
285 case 6:
286 i2c_phy_addr = i2c_addr[3];
287 phy_addr = 0xc;
288 break;
289 }
290
291 /* Check the PHY status */
292 ret = miiphy_set_current_dev(dev);
293 ret = miiphy_write(dev, phy_addr, 0x1f, 3);
294 mdelay(10);
295 ret = miiphy_read(dev, phy_addr, 0x11, &value);
296 mdelay(10);
297 ret = miiphy_read(dev, phy_addr, 0x11, &value);
298 mdelay(10);
299 if ((value & 0xf) == 0xf) {
300 miiphy_write(dev, phy_addr, 0x1f, 0);
301 printf("DPMAC %d :PHY is ..... Configured\n", dpmac);
302 return;
303 }
304
Chuanhua Handddcadb2019-07-26 20:25:35 +0800305#ifdef CONFIG_DM_I2C
306 i2c_get_chip_for_busnum(0, i2c_phy_addr, 1, &udev);
307#endif
308
Ashish Kumar1ef4c772017-08-31 16:12:55 +0530309 for (i = 0; i < 4; i++) {
310 for (j = 0; j < 4; j++) {
Chuanhua Handddcadb2019-07-26 20:25:35 +0800311 reg_pair[3].val = &ch_a_eq[i];
312 reg_pair[4].val = &ch_a_ctl2[j];
313 reg_pair[5].val = &ch_b_eq[i];
314 reg_pair[6].val = &ch_b_ctl2[j];
Ashish Kumar1ef4c772017-08-31 16:12:55 +0530315
Chuanhua Handddcadb2019-07-26 20:25:35 +0800316 for (k = 0; k < 10; k++) {
317#ifndef CONFIG_DM_I2C
318 ret = i2c_write(i2c_phy_addr,
319 reg_pair[k].addr,
320 1, reg_pair[k].val, 1);
321#else
322 ret = i2c_get_chip_for_busnum(0,
323 i2c_addr[dpmac],
324 1, &udev);
325 if (!ret)
326 ret = dm_i2c_write(udev,
327 reg_pair[k].addr,
328 reg_pair[k].val, 1);
329#endif
330 if (ret)
331 goto error;
332 }
Ashish Kumar1ef4c772017-08-31 16:12:55 +0530333
Ashish Kumar1ef4c772017-08-31 16:12:55 +0530334 ret = miiphy_read(dev, phy_addr, 0x11, &value);
335 if (ret > 0)
336 goto error;
337 mdelay(1);
338 ret = miiphy_read(dev, phy_addr, 0x11, &value);
339 if (ret > 0)
340 goto error;
341 mdelay(10);
342 if ((value & 0xf) == 0xf) {
343 miiphy_write(dev, phy_addr, 0x1f, 0);
344 printf("DPMAC %d :PHY is ..... Configured\n",
345 dpmac);
346 return;
347 }
348 }
349 }
350error:
351 printf("DPMAC %d :PHY ..... FAILED to configure PHY\n", dpmac);
352 return;
353}
354
355static const char *ls1088a_qds_mdio_name_for_muxval(u8 muxval)
356{
357 return mdio_names[muxval];
358}
359
360struct mii_dev *mii_dev_for_muxval(u8 muxval)
361{
362 struct mii_dev *bus;
363 const char *name = ls1088a_qds_mdio_name_for_muxval(muxval);
364
365 if (!name) {
366 printf("No bus for muxval %x\n", muxval);
367 return NULL;
368 }
369
370 bus = miiphy_get_dev_by_name(name);
371
372 if (!bus) {
373 printf("No bus by name %s\n", name);
374 return NULL;
375 }
376
377 return bus;
378}
379
380static void ls1088a_qds_enable_SFP_TX(u8 muxval)
381{
382 u8 brdcfg9;
383
384 brdcfg9 = QIXIS_READ(brdcfg[9]);
385 brdcfg9 &= ~BRDCFG9_SFPTX_MASK;
386 brdcfg9 |= (muxval << BRDCFG9_SFPTX_SHIFT);
387 QIXIS_WRITE(brdcfg[9], brdcfg9);
388}
389
390static void ls1088a_qds_mux_mdio(u8 muxval)
391{
392 u8 brdcfg4;
393
394 if (muxval <= 5) {
395 brdcfg4 = QIXIS_READ(brdcfg[4]);
396 brdcfg4 &= ~BRDCFG4_EMISEL_MASK;
397 brdcfg4 |= (muxval << BRDCFG4_EMISEL_SHIFT);
398 QIXIS_WRITE(brdcfg[4], brdcfg4);
399 }
400}
401
402static int ls1088a_qds_mdio_read(struct mii_dev *bus, int addr,
403 int devad, int regnum)
404{
405 struct ls1088a_qds_mdio *priv = bus->priv;
406
407 ls1088a_qds_mux_mdio(priv->muxval);
408
409 return priv->realbus->read(priv->realbus, addr, devad, regnum);
410}
411
412static int ls1088a_qds_mdio_write(struct mii_dev *bus, int addr, int devad,
413 int regnum, u16 value)
414{
415 struct ls1088a_qds_mdio *priv = bus->priv;
416
417 ls1088a_qds_mux_mdio(priv->muxval);
418
419 return priv->realbus->write(priv->realbus, addr, devad, regnum, value);
420}
421
422static int ls1088a_qds_mdio_reset(struct mii_dev *bus)
423{
424 struct ls1088a_qds_mdio *priv = bus->priv;
425
426 return priv->realbus->reset(priv->realbus);
427}
428
429static int ls1088a_qds_mdio_init(char *realbusname, u8 muxval)
430{
431 struct ls1088a_qds_mdio *pmdio;
432 struct mii_dev *bus = mdio_alloc();
433
434 if (!bus) {
435 printf("Failed to allocate ls1088a_qds MDIO bus\n");
436 return -1;
437 }
438
439 pmdio = malloc(sizeof(*pmdio));
440 if (!pmdio) {
441 printf("Failed to allocate ls1088a_qds private data\n");
442 free(bus);
443 return -1;
444 }
445
446 bus->read = ls1088a_qds_mdio_read;
447 bus->write = ls1088a_qds_mdio_write;
448 bus->reset = ls1088a_qds_mdio_reset;
449 sprintf(bus->name, ls1088a_qds_mdio_name_for_muxval(muxval));
450
451 pmdio->realbus = miiphy_get_dev_by_name(realbusname);
452
453 if (!pmdio->realbus) {
454 printf("No bus with name %s\n", realbusname);
455 free(bus);
456 free(pmdio);
457 return -1;
458 }
459
460 pmdio->muxval = muxval;
461 bus->priv = pmdio;
462
463 return mdio_register(bus);
464}
465
466/*
467 * Initialize the dpmac_info array.
468 *
469 */
470static void initialize_dpmac_to_slot(void)
471{
472 struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
473 u32 serdes1_prtcl, cfg;
474
475 cfg = in_le32(&gur->rcwsr[FSL_CHASSIS3_SRDS1_REGSR - 1]) &
476 FSL_CHASSIS3_SRDS1_PRTCL_MASK;
477 cfg >>= FSL_CHASSIS3_SRDS1_PRTCL_SHIFT;
478 serdes1_prtcl = serdes_get_number(FSL_SRDS_1, cfg);
479
480 switch (serdes1_prtcl) {
481 case 0x12:
482 printf("qds: WRIOP: Supported SerDes1 Protocol 0x%02x\n",
483 serdes1_prtcl);
484 lane_to_slot_fsm1[0] = EMI1_SLOT1 - 1;
485 lane_to_slot_fsm1[1] = EMI1_SLOT1 - 1;
486 lane_to_slot_fsm1[2] = EMI1_SLOT1 - 1;
487 lane_to_slot_fsm1[3] = EMI1_SLOT1 - 1;
488 break;
489 case 0x15:
490 case 0x1D:
491 printf("qds: WRIOP: Supported SerDes1 Protocol 0x%02x\n",
492 serdes1_prtcl);
493 lane_to_slot_fsm1[0] = EMI1_SLOT1 - 1;
494 lane_to_slot_fsm1[1] = EMI1_SLOT1 - 1;
495 lane_to_slot_fsm1[2] = EMI_NONE;
496 lane_to_slot_fsm1[3] = EMI_NONE;
497 break;
498 case 0x1E:
499 printf("qds: WRIOP: Supported SerDes1 Protocol 0x%02x\n",
500 serdes1_prtcl);
501 lane_to_slot_fsm1[0] = EMI1_SLOT1 - 1;
502 lane_to_slot_fsm1[1] = EMI1_SLOT1 - 1;
503 lane_to_slot_fsm1[2] = EMI1_SLOT1 - 1;
504 lane_to_slot_fsm1[3] = EMI_NONE;
505 break;
506 case 0x3A:
507 printf("qds: WRIOP: Supported SerDes1 Protocol 0x%02x\n",
508 serdes1_prtcl);
509 lane_to_slot_fsm1[0] = EMI1_SLOT1 - 1;
510 lane_to_slot_fsm1[1] = EMI_NONE;
511 lane_to_slot_fsm1[2] = EMI1_SLOT1 - 1;
512 lane_to_slot_fsm1[3] = EMI1_SLOT1 - 1;
513 break;
514
515 default:
516 printf("%s qds: WRIOP: Unsupported SerDes1 Protocol 0x%02x\n",
517 __func__, serdes1_prtcl);
518 break;
519 }
520}
521
522void ls1088a_handle_phy_interface_sgmii(int dpmac_id)
523{
524 struct mii_dev *bus;
525 struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
526 u32 serdes1_prtcl, cfg;
527
528 cfg = in_le32(&gur->rcwsr[FSL_CHASSIS3_SRDS1_REGSR - 1]) &
529 FSL_CHASSIS3_SRDS1_PRTCL_MASK;
530 cfg >>= FSL_CHASSIS3_SRDS1_PRTCL_SHIFT;
531 serdes1_prtcl = serdes_get_number(FSL_SRDS_1, cfg);
532
533 int *riser_phy_addr;
534 char *env_hwconfig = env_get("hwconfig");
535
536 if (hwconfig_f("xqsgmii", env_hwconfig))
537 riser_phy_addr = &xqsgii_riser_phy_addr[0];
538 else
539 riser_phy_addr = &sgmii_riser_phy_addr[0];
540
541 switch (serdes1_prtcl) {
542 case 0x12:
543 case 0x15:
544 case 0x1E:
545 case 0x3A:
546 switch (dpmac_id) {
547 case 1:
Pankaj Bansal50adb5e2018-10-10 14:08:34 +0530548 wriop_set_phy_address(dpmac_id, 0, riser_phy_addr[1]);
Ashish Kumar1ef4c772017-08-31 16:12:55 +0530549 break;
550 case 2:
Pankaj Bansal50adb5e2018-10-10 14:08:34 +0530551 wriop_set_phy_address(dpmac_id, 0, riser_phy_addr[0]);
Ashish Kumar1ef4c772017-08-31 16:12:55 +0530552 break;
553 case 3:
Pankaj Bansal50adb5e2018-10-10 14:08:34 +0530554 wriop_set_phy_address(dpmac_id, 0, riser_phy_addr[3]);
Ashish Kumar1ef4c772017-08-31 16:12:55 +0530555 break;
556 case 7:
Pankaj Bansal50adb5e2018-10-10 14:08:34 +0530557 wriop_set_phy_address(dpmac_id, 0, riser_phy_addr[2]);
Ashish Kumar1ef4c772017-08-31 16:12:55 +0530558 break;
559 default:
560 printf("WRIOP: Wrong DPMAC%d set to SGMII", dpmac_id);
561 break;
562 }
563 break;
564 default:
565 printf("%s qds: WRIOP: Unsupported SerDes1 Protocol 0x%02x\n",
566 __func__, serdes1_prtcl);
567 return;
568 }
569 dpmac_info[dpmac_id].board_mux = EMI1_SLOT1;
570 bus = mii_dev_for_muxval(EMI1_SLOT1);
571 wriop_set_mdio(dpmac_id, bus);
572}
573
574void ls1088a_handle_phy_interface_qsgmii(int dpmac_id)
575{
576 struct mii_dev *bus;
577 struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
578 u32 serdes1_prtcl, cfg;
579
580 cfg = in_le32(&gur->rcwsr[FSL_CHASSIS3_SRDS1_REGSR - 1]) &
581 FSL_CHASSIS3_SRDS1_PRTCL_MASK;
582 cfg >>= FSL_CHASSIS3_SRDS1_PRTCL_SHIFT;
583 serdes1_prtcl = serdes_get_number(FSL_SRDS_1, cfg);
584
585 switch (serdes1_prtcl) {
586 case 0x1D:
587 case 0x1E:
588 switch (dpmac_id) {
589 case 3:
590 case 4:
591 case 5:
592 case 6:
Pankaj Bansal50adb5e2018-10-10 14:08:34 +0530593 wriop_set_phy_address(dpmac_id, 0, dpmac_id + 9);
Ashish Kumar1ef4c772017-08-31 16:12:55 +0530594 break;
595 case 7:
596 case 8:
597 case 9:
598 case 10:
Pankaj Bansal50adb5e2018-10-10 14:08:34 +0530599 wriop_set_phy_address(dpmac_id, 0, dpmac_id + 1);
Ashish Kumar1ef4c772017-08-31 16:12:55 +0530600 break;
601 }
602
603 dpmac_info[dpmac_id].board_mux = EMI1_SLOT1;
604 bus = mii_dev_for_muxval(EMI1_SLOT1);
605 wriop_set_mdio(dpmac_id, bus);
606 break;
607 default:
608 printf("qds: WRIOP: Unsupported SerDes Protocol 0x%02x\n",
609 serdes1_prtcl);
610 break;
611 }
612}
613
614void ls1088a_handle_phy_interface_xsgmii(int i)
615{
616 struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
617 u32 serdes1_prtcl, cfg;
618
619 cfg = in_le32(&gur->rcwsr[FSL_CHASSIS3_SRDS1_REGSR - 1]) &
620 FSL_CHASSIS3_SRDS1_PRTCL_MASK;
621 cfg >>= FSL_CHASSIS3_SRDS1_PRTCL_SHIFT;
622 serdes1_prtcl = serdes_get_number(FSL_SRDS_1, cfg);
623
624 switch (serdes1_prtcl) {
625 case 0x15:
626 case 0x1D:
627 case 0x1E:
Pankaj Bansal50adb5e2018-10-10 14:08:34 +0530628 wriop_set_phy_address(i, 0, i + 26);
Ashish Kumar1ef4c772017-08-31 16:12:55 +0530629 ls1088a_qds_enable_SFP_TX(SFP_TX);
630 break;
631 default:
632 printf("qds: WRIOP: Unsupported SerDes Protocol 0x%02x\n",
633 serdes1_prtcl);
634 break;
635 }
636}
Prabhakar Kushwaha05f37b02017-08-31 16:37:32 +0530637
638static void ls1088a_handle_phy_interface_rgmii(int dpmac_id)
639{
640 struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
641 u32 serdes1_prtcl, cfg;
642 struct mii_dev *bus;
643
644 cfg = in_le32(&gur->rcwsr[FSL_CHASSIS3_SRDS1_REGSR - 1]) &
645 FSL_CHASSIS3_SRDS1_PRTCL_MASK;
646 cfg >>= FSL_CHASSIS3_SRDS1_PRTCL_SHIFT;
647 serdes1_prtcl = serdes_get_number(FSL_SRDS_1, cfg);
648
649 switch (dpmac_id) {
650 case 4:
Pankaj Bansal50adb5e2018-10-10 14:08:34 +0530651 wriop_set_phy_address(dpmac_id, 0, RGMII_PHY1_ADDR);
Prabhakar Kushwaha05f37b02017-08-31 16:37:32 +0530652 dpmac_info[dpmac_id].board_mux = EMI1_RGMII1;
653 bus = mii_dev_for_muxval(EMI1_RGMII1);
654 wriop_set_mdio(dpmac_id, bus);
655 break;
656 case 5:
Pankaj Bansal50adb5e2018-10-10 14:08:34 +0530657 wriop_set_phy_address(dpmac_id, 0, RGMII_PHY2_ADDR);
Prabhakar Kushwaha05f37b02017-08-31 16:37:32 +0530658 dpmac_info[dpmac_id].board_mux = EMI1_RGMII2;
659 bus = mii_dev_for_muxval(EMI1_RGMII2);
660 wriop_set_mdio(dpmac_id, bus);
661 break;
662 default:
663 printf("qds: WRIOP: Unsupported RGMII SerDes Protocol 0x%02x\n",
664 serdes1_prtcl);
665 break;
666 }
667}
Ashish Kumar1ef4c772017-08-31 16:12:55 +0530668#endif
669
670int board_eth_init(bd_t *bis)
671{
672 int error = 0, i;
Ashish Kumar1ef4c772017-08-31 16:12:55 +0530673#ifdef CONFIG_FSL_MC_ENET
674 struct memac_mdio_info *memac_mdio0_info;
675 char *env_hwconfig = env_get("hwconfig");
676
677 initialize_dpmac_to_slot();
678
679 memac_mdio0_info = (struct memac_mdio_info *)malloc(
680 sizeof(struct memac_mdio_info));
681 memac_mdio0_info->regs =
682 (struct memac_mdio_controller *)
683 CONFIG_SYS_FSL_WRIOP1_MDIO1;
684 memac_mdio0_info->name = DEFAULT_WRIOP_MDIO1_NAME;
685
686 /* Register the real MDIO1 bus */
687 fm_memac_mdio_init(bis, memac_mdio0_info);
Ashish Kumar1ef4c772017-08-31 16:12:55 +0530688 /* Register the muxing front-ends to the MDIO buses */
689 ls1088a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_RGMII1);
690 ls1088a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_RGMII2);
691 ls1088a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT1);
692
693 for (i = WRIOP1_DPMAC1; i < NUM_WRIOP_PORTS; i++) {
694 switch (wriop_get_enet_if(i)) {
Prabhakar Kushwaha05f37b02017-08-31 16:37:32 +0530695 case PHY_INTERFACE_MODE_RGMII:
Ashish Kumar856c9dc2017-10-12 15:21:54 +0530696 case PHY_INTERFACE_MODE_RGMII_ID:
Prabhakar Kushwaha05f37b02017-08-31 16:37:32 +0530697 ls1088a_handle_phy_interface_rgmii(i);
698 break;
Ashish Kumar1ef4c772017-08-31 16:12:55 +0530699 case PHY_INTERFACE_MODE_QSGMII:
700 ls1088a_handle_phy_interface_qsgmii(i);
701 break;
702 case PHY_INTERFACE_MODE_SGMII:
703 ls1088a_handle_phy_interface_sgmii(i);
704 break;
705 case PHY_INTERFACE_MODE_XGMII:
706 ls1088a_handle_phy_interface_xsgmii(i);
707 break;
708 default:
709 break;
710
711 if (i == 16)
712 i = NUM_WRIOP_PORTS;
713 }
714 }
715
Ashish Kumar1ef4c772017-08-31 16:12:55 +0530716 error = cpu_eth_init(bis);
717
718 if (hwconfig_f("xqsgmii", env_hwconfig)) {
719 for (i = WRIOP1_DPMAC1; i < NUM_WRIOP_PORTS; i++) {
720 switch (wriop_get_enet_if(i)) {
721 case PHY_INTERFACE_MODE_QSGMII:
722 qsgmii_configure_repeater(i);
723 break;
724 case PHY_INTERFACE_MODE_SGMII:
725 sgmii_configure_repeater(i);
726 break;
727 default:
728 break;
729 }
730
731 if (i == 16)
732 i = NUM_WRIOP_PORTS;
733 }
734 }
735#endif
736 error = pci_eth_init(bis);
737 return error;
738}
Bogdan Purcareata33ba9392017-10-05 06:56:53 +0000739
740#if defined(CONFIG_RESET_PHY_R)
741void reset_phy(void)
742{
743 mc_env_boot();
744}
745#endif /* CONFIG_RESET_PHY_R */