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