144937214SPrabhakar Kushwaha /*
244937214SPrabhakar Kushwaha  * Copyright 2015 Freescale Semiconductor, Inc.
344937214SPrabhakar Kushwaha  *
444937214SPrabhakar Kushwaha  * SPDX-License-Identifier:	GPL-2.0+
544937214SPrabhakar Kushwaha  */
644937214SPrabhakar Kushwaha 
744937214SPrabhakar Kushwaha #include <common.h>
844937214SPrabhakar Kushwaha #include <netdev.h>
944937214SPrabhakar Kushwaha #include <asm/io.h>
1044937214SPrabhakar Kushwaha #include <asm/arch/fsl_serdes.h>
1144937214SPrabhakar Kushwaha #include <hwconfig.h>
1244937214SPrabhakar Kushwaha #include <fsl_mdio.h>
1344937214SPrabhakar Kushwaha #include <malloc.h>
1444937214SPrabhakar Kushwaha #include <fm_eth.h>
1544937214SPrabhakar Kushwaha #include <i2c.h>
1644937214SPrabhakar Kushwaha #include <miiphy.h>
1744937214SPrabhakar Kushwaha #include <fsl-mc/ldpaa_wriop.h>
1844937214SPrabhakar Kushwaha 
1944937214SPrabhakar Kushwaha #include "../common/qixis.h"
2044937214SPrabhakar Kushwaha 
2144937214SPrabhakar Kushwaha #include "ls2080aqds_qixis.h"
2244937214SPrabhakar Kushwaha 
2344937214SPrabhakar Kushwaha 
2444937214SPrabhakar Kushwaha #ifdef CONFIG_FSL_MC_ENET
2544937214SPrabhakar Kushwaha  /* - In LS2080A there are only 16 SERDES lanes, spread across 2 SERDES banks.
2644937214SPrabhakar Kushwaha  *   Bank 1 -> Lanes A, B, C, D, E, F, G, H
2744937214SPrabhakar Kushwaha  *   Bank 2 -> Lanes A,B, C, D, E, F, G, H
2844937214SPrabhakar Kushwaha  */
2944937214SPrabhakar Kushwaha 
3044937214SPrabhakar Kushwaha  /* Mapping of 16 SERDES lanes to LS2080A QDS board slots. A value of '0' here
3144937214SPrabhakar Kushwaha   * means that the mapping must be determined dynamically, or that the lane
3244937214SPrabhakar Kushwaha   * maps to something other than a board slot.
3344937214SPrabhakar Kushwaha   */
3444937214SPrabhakar Kushwaha 
3544937214SPrabhakar Kushwaha static u8 lane_to_slot_fsm1[] = {
3644937214SPrabhakar Kushwaha 	0, 0, 0, 0, 0, 0, 0, 0
3744937214SPrabhakar Kushwaha };
3844937214SPrabhakar Kushwaha 
3944937214SPrabhakar Kushwaha static u8 lane_to_slot_fsm2[] = {
4044937214SPrabhakar Kushwaha 	0, 0, 0, 0, 0, 0, 0, 0
4144937214SPrabhakar Kushwaha };
4244937214SPrabhakar Kushwaha 
4344937214SPrabhakar Kushwaha /* On the Vitesse VSC8234XHG SGMII riser card there are 4 SGMII PHYs
4444937214SPrabhakar Kushwaha  * housed.
4544937214SPrabhakar Kushwaha  */
4644937214SPrabhakar Kushwaha 
4744937214SPrabhakar Kushwaha static int xqsgii_riser_phy_addr[] = {
4844937214SPrabhakar Kushwaha 	XQSGMII_CARD_PHY1_PORT0_ADDR,
4944937214SPrabhakar Kushwaha 	XQSGMII_CARD_PHY2_PORT0_ADDR,
5044937214SPrabhakar Kushwaha 	XQSGMII_CARD_PHY3_PORT0_ADDR,
5144937214SPrabhakar Kushwaha 	XQSGMII_CARD_PHY4_PORT0_ADDR,
5244937214SPrabhakar Kushwaha 	XQSGMII_CARD_PHY3_PORT2_ADDR,
5344937214SPrabhakar Kushwaha 	XQSGMII_CARD_PHY1_PORT2_ADDR,
5444937214SPrabhakar Kushwaha 	XQSGMII_CARD_PHY4_PORT2_ADDR,
5544937214SPrabhakar Kushwaha 	XQSGMII_CARD_PHY2_PORT2_ADDR,
5644937214SPrabhakar Kushwaha };
5744937214SPrabhakar Kushwaha 
5844937214SPrabhakar Kushwaha static int sgmii_riser_phy_addr[] = {
5944937214SPrabhakar Kushwaha 	SGMII_CARD_PORT1_PHY_ADDR,
6044937214SPrabhakar Kushwaha 	SGMII_CARD_PORT2_PHY_ADDR,
6144937214SPrabhakar Kushwaha 	SGMII_CARD_PORT3_PHY_ADDR,
6244937214SPrabhakar Kushwaha 	SGMII_CARD_PORT4_PHY_ADDR,
6344937214SPrabhakar Kushwaha };
6444937214SPrabhakar Kushwaha 
6544937214SPrabhakar Kushwaha /* Slot2 does not have EMI connections */
6644937214SPrabhakar Kushwaha #define EMI_NONE	0xFFFFFFFF
6744937214SPrabhakar Kushwaha #define EMI1_SLOT1	0
6844937214SPrabhakar Kushwaha #define EMI1_SLOT2	1
6944937214SPrabhakar Kushwaha #define EMI1_SLOT3	2
7044937214SPrabhakar Kushwaha #define EMI1_SLOT4	3
7144937214SPrabhakar Kushwaha #define EMI1_SLOT5	4
7244937214SPrabhakar Kushwaha #define EMI1_SLOT6	5
7344937214SPrabhakar Kushwaha #define EMI2		6
7444937214SPrabhakar Kushwaha #define SFP_TX		0
7544937214SPrabhakar Kushwaha 
7644937214SPrabhakar Kushwaha static const char * const mdio_names[] = {
7744937214SPrabhakar Kushwaha 	"LS2080A_QDS_MDIO0",
7844937214SPrabhakar Kushwaha 	"LS2080A_QDS_MDIO1",
7944937214SPrabhakar Kushwaha 	"LS2080A_QDS_MDIO2",
8044937214SPrabhakar Kushwaha 	"LS2080A_QDS_MDIO3",
8144937214SPrabhakar Kushwaha 	"LS2080A_QDS_MDIO4",
8244937214SPrabhakar Kushwaha 	"LS2080A_QDS_MDIO5",
8344937214SPrabhakar Kushwaha 	DEFAULT_WRIOP_MDIO2_NAME,
8444937214SPrabhakar Kushwaha };
8544937214SPrabhakar Kushwaha 
8644937214SPrabhakar Kushwaha struct ls2080a_qds_mdio {
8744937214SPrabhakar Kushwaha 	u8 muxval;
8844937214SPrabhakar Kushwaha 	struct mii_dev *realbus;
8944937214SPrabhakar Kushwaha };
9044937214SPrabhakar Kushwaha 
9144937214SPrabhakar Kushwaha static void sgmii_configure_repeater(int serdes_port)
9244937214SPrabhakar Kushwaha {
9344937214SPrabhakar Kushwaha 	struct mii_dev *bus;
9444937214SPrabhakar Kushwaha 	uint8_t a = 0xf;
9544937214SPrabhakar Kushwaha 	int i, j, ret;
9644937214SPrabhakar Kushwaha 	int dpmac_id = 0, dpmac, mii_bus = 0;
9744937214SPrabhakar Kushwaha 	unsigned short value;
9844937214SPrabhakar Kushwaha 	char dev[2][20] = {"LS2080A_QDS_MDIO0", "LS2080A_QDS_MDIO3"};
9944937214SPrabhakar Kushwaha 	uint8_t i2c_addr[] = {0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5f, 0x60};
10044937214SPrabhakar Kushwaha 
10144937214SPrabhakar Kushwaha 	uint8_t ch_a_eq[] = {0x1, 0x2, 0x3, 0x7};
10244937214SPrabhakar Kushwaha 	uint8_t ch_a_ctl2[] = {0x81, 0x82, 0x83, 0x84};
10344937214SPrabhakar Kushwaha 	uint8_t ch_b_eq[] = {0x1, 0x2, 0x3, 0x7};
10444937214SPrabhakar Kushwaha 	uint8_t ch_b_ctl2[] = {0x81, 0x82, 0x83, 0x84};
10544937214SPrabhakar Kushwaha 
10644937214SPrabhakar Kushwaha 	int *riser_phy_addr = &xqsgii_riser_phy_addr[0];
10744937214SPrabhakar Kushwaha 
10844937214SPrabhakar Kushwaha 	/* Set I2c to Slot 1 */
10944937214SPrabhakar Kushwaha 	i2c_write(0x77, 0, 0, &a, 1);
11044937214SPrabhakar Kushwaha 
11144937214SPrabhakar Kushwaha 	for (dpmac = 0; dpmac < 8; dpmac++) {
11244937214SPrabhakar Kushwaha 		/* Check the PHY status */
11344937214SPrabhakar Kushwaha 		switch (serdes_port) {
11444937214SPrabhakar Kushwaha 		case 1:
11544937214SPrabhakar Kushwaha 			mii_bus = 0;
11644937214SPrabhakar Kushwaha 			dpmac_id = dpmac + 1;
11744937214SPrabhakar Kushwaha 			break;
11844937214SPrabhakar Kushwaha 		case 2:
11944937214SPrabhakar Kushwaha 			mii_bus = 1;
12044937214SPrabhakar Kushwaha 			dpmac_id = dpmac + 9;
12144937214SPrabhakar Kushwaha 			a = 0xb;
12244937214SPrabhakar Kushwaha 			i2c_write(0x76, 0, 0, &a, 1);
12344937214SPrabhakar Kushwaha 			break;
12444937214SPrabhakar Kushwaha 		}
12544937214SPrabhakar Kushwaha 
12644937214SPrabhakar Kushwaha 		ret = miiphy_set_current_dev(dev[mii_bus]);
12744937214SPrabhakar Kushwaha 		if (ret > 0)
12844937214SPrabhakar Kushwaha 			goto error;
12944937214SPrabhakar Kushwaha 
13044937214SPrabhakar Kushwaha 		bus = mdio_get_current_dev();
13144937214SPrabhakar Kushwaha 		debug("Reading from bus %s\n", bus->name);
13244937214SPrabhakar Kushwaha 
13344937214SPrabhakar Kushwaha 		ret = miiphy_write(dev[mii_bus], riser_phy_addr[dpmac], 0x1f,
13444937214SPrabhakar Kushwaha 				   3);
13544937214SPrabhakar Kushwaha 		if (ret > 0)
13644937214SPrabhakar Kushwaha 			goto error;
13744937214SPrabhakar Kushwaha 
13844937214SPrabhakar Kushwaha 		mdelay(10);
13944937214SPrabhakar Kushwaha 		ret = miiphy_read(dev[mii_bus], riser_phy_addr[dpmac], 0x11,
14044937214SPrabhakar Kushwaha 				  &value);
14144937214SPrabhakar Kushwaha 		if (ret > 0)
14244937214SPrabhakar Kushwaha 			goto error;
14344937214SPrabhakar Kushwaha 
14444937214SPrabhakar Kushwaha 		mdelay(10);
14544937214SPrabhakar Kushwaha 
14644937214SPrabhakar Kushwaha 		if ((value & 0xfff) == 0x40f) {
14744937214SPrabhakar Kushwaha 			printf("DPMAC %d:PHY is ..... Configured\n", dpmac_id);
14844937214SPrabhakar Kushwaha 			continue;
14944937214SPrabhakar Kushwaha 		}
15044937214SPrabhakar Kushwaha 
15144937214SPrabhakar Kushwaha 		for (i = 0; i < 4; i++) {
15244937214SPrabhakar Kushwaha 			for (j = 0; j < 4; j++) {
15344937214SPrabhakar Kushwaha 				a = 0x18;
15444937214SPrabhakar Kushwaha 				i2c_write(i2c_addr[dpmac], 6, 1, &a, 1);
15544937214SPrabhakar Kushwaha 				a = 0x38;
15644937214SPrabhakar Kushwaha 				i2c_write(i2c_addr[dpmac], 4, 1, &a, 1);
15744937214SPrabhakar Kushwaha 				a = 0x4;
15844937214SPrabhakar Kushwaha 				i2c_write(i2c_addr[dpmac], 8, 1, &a, 1);
15944937214SPrabhakar Kushwaha 
16044937214SPrabhakar Kushwaha 				i2c_write(i2c_addr[dpmac], 0xf, 1,
16144937214SPrabhakar Kushwaha 					  &ch_a_eq[i], 1);
16244937214SPrabhakar Kushwaha 				i2c_write(i2c_addr[dpmac], 0x11, 1,
16344937214SPrabhakar Kushwaha 					  &ch_a_ctl2[j], 1);
16444937214SPrabhakar Kushwaha 
16544937214SPrabhakar Kushwaha 				i2c_write(i2c_addr[dpmac], 0x16, 1,
16644937214SPrabhakar Kushwaha 					  &ch_b_eq[i], 1);
16744937214SPrabhakar Kushwaha 				i2c_write(i2c_addr[dpmac], 0x18, 1,
16844937214SPrabhakar Kushwaha 					  &ch_b_ctl2[j], 1);
16944937214SPrabhakar Kushwaha 
17044937214SPrabhakar Kushwaha 				a = 0x14;
17144937214SPrabhakar Kushwaha 				i2c_write(i2c_addr[dpmac], 0x23, 1, &a, 1);
17244937214SPrabhakar Kushwaha 				a = 0xb5;
17344937214SPrabhakar Kushwaha 				i2c_write(i2c_addr[dpmac], 0x2d, 1, &a, 1);
17444937214SPrabhakar Kushwaha 				a = 0x20;
17544937214SPrabhakar Kushwaha 				i2c_write(i2c_addr[dpmac], 4, 1, &a, 1);
17644937214SPrabhakar Kushwaha 				mdelay(100);
17744937214SPrabhakar Kushwaha 				ret = miiphy_read(dev[mii_bus],
17844937214SPrabhakar Kushwaha 						  riser_phy_addr[dpmac],
17944937214SPrabhakar Kushwaha 						  0x11, &value);
18044937214SPrabhakar Kushwaha 				if (ret > 0)
18144937214SPrabhakar Kushwaha 					goto error;
18244937214SPrabhakar Kushwaha 
18344937214SPrabhakar Kushwaha 				mdelay(1);
18444937214SPrabhakar Kushwaha 				ret = miiphy_read(dev[mii_bus],
18544937214SPrabhakar Kushwaha 						  riser_phy_addr[dpmac],
18644937214SPrabhakar Kushwaha 						  0x11, &value);
18744937214SPrabhakar Kushwaha 				if (ret > 0)
18844937214SPrabhakar Kushwaha 					goto error;
18944937214SPrabhakar Kushwaha 				mdelay(10);
19044937214SPrabhakar Kushwaha 
19144937214SPrabhakar Kushwaha 				if ((value & 0xfff) == 0x40f) {
19244937214SPrabhakar Kushwaha 					printf("DPMAC %d :PHY is configured ",
19344937214SPrabhakar Kushwaha 					       dpmac_id);
19444937214SPrabhakar Kushwaha 					printf("after setting repeater 0x%x\n",
19544937214SPrabhakar Kushwaha 					       value);
19644937214SPrabhakar Kushwaha 					i = 5;
19744937214SPrabhakar Kushwaha 					j = 5;
19844937214SPrabhakar Kushwaha 				} else
19944937214SPrabhakar Kushwaha 					printf("DPMAC %d :PHY is failed to ",
20044937214SPrabhakar Kushwaha 					       dpmac_id);
20144937214SPrabhakar Kushwaha 					printf("configure the repeater 0x%x\n",
20244937214SPrabhakar Kushwaha 					       value);
20344937214SPrabhakar Kushwaha 				}
20444937214SPrabhakar Kushwaha 		}
20544937214SPrabhakar Kushwaha 	}
20644937214SPrabhakar Kushwaha error:
20744937214SPrabhakar Kushwaha 	if (ret)
20844937214SPrabhakar Kushwaha 		printf("DPMAC %d ..... FAILED to configure PHY\n", dpmac_id);
20944937214SPrabhakar Kushwaha 	return;
21044937214SPrabhakar Kushwaha }
21144937214SPrabhakar Kushwaha 
21244937214SPrabhakar Kushwaha static void qsgmii_configure_repeater(int dpmac)
21344937214SPrabhakar Kushwaha {
21444937214SPrabhakar Kushwaha 	uint8_t a = 0xf;
21544937214SPrabhakar Kushwaha 	int i, j;
21644937214SPrabhakar Kushwaha 	int i2c_phy_addr = 0;
21744937214SPrabhakar Kushwaha 	int phy_addr = 0;
21844937214SPrabhakar Kushwaha 	int i2c_addr[] = {0x58, 0x59, 0x5a, 0x5b};
21944937214SPrabhakar Kushwaha 
22044937214SPrabhakar Kushwaha 	uint8_t ch_a_eq[] = {0x1, 0x2, 0x3, 0x7};
22144937214SPrabhakar Kushwaha 	uint8_t ch_a_ctl2[] = {0x81, 0x82, 0x83, 0x84};
22244937214SPrabhakar Kushwaha 	uint8_t ch_b_eq[] = {0x1, 0x2, 0x3, 0x7};
22344937214SPrabhakar Kushwaha 	uint8_t ch_b_ctl2[] = {0x81, 0x82, 0x83, 0x84};
22444937214SPrabhakar Kushwaha 
22544937214SPrabhakar Kushwaha 	const char *dev = "LS2080A_QDS_MDIO0";
22644937214SPrabhakar Kushwaha 	int ret = 0;
22744937214SPrabhakar Kushwaha 	unsigned short value;
22844937214SPrabhakar Kushwaha 
22944937214SPrabhakar Kushwaha 	/* Set I2c to Slot 1 */
23044937214SPrabhakar Kushwaha 	i2c_write(0x77, 0, 0, &a, 1);
23144937214SPrabhakar Kushwaha 
23244937214SPrabhakar Kushwaha 	switch (dpmac) {
23344937214SPrabhakar Kushwaha 	case 1:
23444937214SPrabhakar Kushwaha 	case 2:
23544937214SPrabhakar Kushwaha 	case 3:
23644937214SPrabhakar Kushwaha 	case 4:
23744937214SPrabhakar Kushwaha 		i2c_phy_addr = i2c_addr[0];
23844937214SPrabhakar Kushwaha 		phy_addr = 0;
23944937214SPrabhakar Kushwaha 		break;
24044937214SPrabhakar Kushwaha 
24144937214SPrabhakar Kushwaha 	case 5:
24244937214SPrabhakar Kushwaha 	case 6:
24344937214SPrabhakar Kushwaha 	case 7:
24444937214SPrabhakar Kushwaha 	case 8:
24544937214SPrabhakar Kushwaha 		i2c_phy_addr = i2c_addr[1];
24644937214SPrabhakar Kushwaha 		phy_addr = 4;
24744937214SPrabhakar Kushwaha 		break;
24844937214SPrabhakar Kushwaha 
24944937214SPrabhakar Kushwaha 	case 9:
25044937214SPrabhakar Kushwaha 	case 10:
25144937214SPrabhakar Kushwaha 	case 11:
25244937214SPrabhakar Kushwaha 	case 12:
25344937214SPrabhakar Kushwaha 		i2c_phy_addr = i2c_addr[2];
25444937214SPrabhakar Kushwaha 		phy_addr = 8;
25544937214SPrabhakar Kushwaha 		break;
25644937214SPrabhakar Kushwaha 
25744937214SPrabhakar Kushwaha 	case 13:
25844937214SPrabhakar Kushwaha 	case 14:
25944937214SPrabhakar Kushwaha 	case 15:
26044937214SPrabhakar Kushwaha 	case 16:
26144937214SPrabhakar Kushwaha 		i2c_phy_addr = i2c_addr[3];
26244937214SPrabhakar Kushwaha 		phy_addr = 0xc;
26344937214SPrabhakar Kushwaha 		break;
26444937214SPrabhakar Kushwaha 	}
26544937214SPrabhakar Kushwaha 
26644937214SPrabhakar Kushwaha 	/* Check the PHY status */
26744937214SPrabhakar Kushwaha 	ret = miiphy_set_current_dev(dev);
26844937214SPrabhakar Kushwaha 	ret = miiphy_write(dev, phy_addr, 0x1f, 3);
26944937214SPrabhakar Kushwaha 	mdelay(10);
27044937214SPrabhakar Kushwaha 	ret = miiphy_read(dev, phy_addr, 0x11, &value);
27144937214SPrabhakar Kushwaha 	mdelay(10);
27244937214SPrabhakar Kushwaha 	ret = miiphy_read(dev, phy_addr, 0x11, &value);
27344937214SPrabhakar Kushwaha 	mdelay(10);
27444937214SPrabhakar Kushwaha 	if ((value & 0xf) == 0xf) {
27544937214SPrabhakar Kushwaha 		printf("DPMAC %d :PHY is ..... Configured\n", dpmac);
27644937214SPrabhakar Kushwaha 		return;
27744937214SPrabhakar Kushwaha 	}
27844937214SPrabhakar Kushwaha 
27944937214SPrabhakar Kushwaha 	for (i = 0; i < 4; i++) {
28044937214SPrabhakar Kushwaha 		for (j = 0; j < 4; j++) {
28144937214SPrabhakar Kushwaha 			a = 0x18;
28244937214SPrabhakar Kushwaha 			i2c_write(i2c_phy_addr, 6, 1, &a, 1);
28344937214SPrabhakar Kushwaha 			a = 0x38;
28444937214SPrabhakar Kushwaha 			i2c_write(i2c_phy_addr, 4, 1, &a, 1);
28544937214SPrabhakar Kushwaha 			a = 0x4;
28644937214SPrabhakar Kushwaha 			i2c_write(i2c_phy_addr, 8, 1, &a, 1);
28744937214SPrabhakar Kushwaha 
28844937214SPrabhakar Kushwaha 			i2c_write(i2c_phy_addr, 0xf, 1, &ch_a_eq[i], 1);
28944937214SPrabhakar Kushwaha 			i2c_write(i2c_phy_addr, 0x11, 1, &ch_a_ctl2[j], 1);
29044937214SPrabhakar Kushwaha 
29144937214SPrabhakar Kushwaha 			i2c_write(i2c_phy_addr, 0x16, 1, &ch_b_eq[i], 1);
29244937214SPrabhakar Kushwaha 			i2c_write(i2c_phy_addr, 0x18, 1, &ch_b_ctl2[j], 1);
29344937214SPrabhakar Kushwaha 
29444937214SPrabhakar Kushwaha 			a = 0x14;
29544937214SPrabhakar Kushwaha 			i2c_write(i2c_phy_addr, 0x23, 1, &a, 1);
29644937214SPrabhakar Kushwaha 			a = 0xb5;
29744937214SPrabhakar Kushwaha 			i2c_write(i2c_phy_addr, 0x2d, 1, &a, 1);
29844937214SPrabhakar Kushwaha 			a = 0x20;
29944937214SPrabhakar Kushwaha 			i2c_write(i2c_phy_addr, 4, 1, &a, 1);
30044937214SPrabhakar Kushwaha 			mdelay(100);
30144937214SPrabhakar Kushwaha 			ret = miiphy_read(dev, phy_addr, 0x11, &value);
30244937214SPrabhakar Kushwaha 			if (ret > 0)
30344937214SPrabhakar Kushwaha 				goto error;
30444937214SPrabhakar Kushwaha 			mdelay(1);
30544937214SPrabhakar Kushwaha 			ret = miiphy_read(dev, phy_addr, 0x11, &value);
30644937214SPrabhakar Kushwaha 			if (ret > 0)
30744937214SPrabhakar Kushwaha 				goto error;
30844937214SPrabhakar Kushwaha 			mdelay(10);
30944937214SPrabhakar Kushwaha 			if ((value & 0xf) == 0xf) {
31044937214SPrabhakar Kushwaha 				printf("DPMAC %d :PHY is ..... Configured\n",
31144937214SPrabhakar Kushwaha 				       dpmac);
31244937214SPrabhakar Kushwaha 				return;
31344937214SPrabhakar Kushwaha 			}
31444937214SPrabhakar Kushwaha 		}
31544937214SPrabhakar Kushwaha 	}
31644937214SPrabhakar Kushwaha error:
31744937214SPrabhakar Kushwaha 	printf("DPMAC %d :PHY ..... FAILED to configure PHY\n", dpmac);
31844937214SPrabhakar Kushwaha 	return;
31944937214SPrabhakar Kushwaha }
32044937214SPrabhakar Kushwaha 
32144937214SPrabhakar Kushwaha static const char *ls2080a_qds_mdio_name_for_muxval(u8 muxval)
32244937214SPrabhakar Kushwaha {
32344937214SPrabhakar Kushwaha 	return mdio_names[muxval];
32444937214SPrabhakar Kushwaha }
32544937214SPrabhakar Kushwaha 
32644937214SPrabhakar Kushwaha struct mii_dev *mii_dev_for_muxval(u8 muxval)
32744937214SPrabhakar Kushwaha {
32844937214SPrabhakar Kushwaha 	struct mii_dev *bus;
32944937214SPrabhakar Kushwaha 	const char *name = ls2080a_qds_mdio_name_for_muxval(muxval);
33044937214SPrabhakar Kushwaha 
33144937214SPrabhakar Kushwaha 	if (!name) {
33244937214SPrabhakar Kushwaha 		printf("No bus for muxval %x\n", muxval);
33344937214SPrabhakar Kushwaha 		return NULL;
33444937214SPrabhakar Kushwaha 	}
33544937214SPrabhakar Kushwaha 
33644937214SPrabhakar Kushwaha 	bus = miiphy_get_dev_by_name(name);
33744937214SPrabhakar Kushwaha 
33844937214SPrabhakar Kushwaha 	if (!bus) {
33944937214SPrabhakar Kushwaha 		printf("No bus by name %s\n", name);
34044937214SPrabhakar Kushwaha 		return NULL;
34144937214SPrabhakar Kushwaha 	}
34244937214SPrabhakar Kushwaha 
34344937214SPrabhakar Kushwaha 	return bus;
34444937214SPrabhakar Kushwaha }
34544937214SPrabhakar Kushwaha 
34644937214SPrabhakar Kushwaha static void ls2080a_qds_enable_SFP_TX(u8 muxval)
34744937214SPrabhakar Kushwaha {
34844937214SPrabhakar Kushwaha 	u8 brdcfg9;
34944937214SPrabhakar Kushwaha 
35044937214SPrabhakar Kushwaha 	brdcfg9 = QIXIS_READ(brdcfg[9]);
35144937214SPrabhakar Kushwaha 	brdcfg9 &= ~BRDCFG9_SFPTX_MASK;
35244937214SPrabhakar Kushwaha 	brdcfg9 |= (muxval << BRDCFG9_SFPTX_SHIFT);
35344937214SPrabhakar Kushwaha 	QIXIS_WRITE(brdcfg[9], brdcfg9);
35444937214SPrabhakar Kushwaha }
35544937214SPrabhakar Kushwaha 
35644937214SPrabhakar Kushwaha static void ls2080a_qds_mux_mdio(u8 muxval)
35744937214SPrabhakar Kushwaha {
35844937214SPrabhakar Kushwaha 	u8 brdcfg4;
35944937214SPrabhakar Kushwaha 
36044937214SPrabhakar Kushwaha 	if (muxval <= 5) {
36144937214SPrabhakar Kushwaha 		brdcfg4 = QIXIS_READ(brdcfg[4]);
36244937214SPrabhakar Kushwaha 		brdcfg4 &= ~BRDCFG4_EMISEL_MASK;
36344937214SPrabhakar Kushwaha 		brdcfg4 |= (muxval << BRDCFG4_EMISEL_SHIFT);
36444937214SPrabhakar Kushwaha 		QIXIS_WRITE(brdcfg[4], brdcfg4);
36544937214SPrabhakar Kushwaha 	}
36644937214SPrabhakar Kushwaha }
36744937214SPrabhakar Kushwaha 
36844937214SPrabhakar Kushwaha static int ls2080a_qds_mdio_read(struct mii_dev *bus, int addr,
36944937214SPrabhakar Kushwaha 				 int devad, int regnum)
37044937214SPrabhakar Kushwaha {
37144937214SPrabhakar Kushwaha 	struct ls2080a_qds_mdio *priv = bus->priv;
37244937214SPrabhakar Kushwaha 
37344937214SPrabhakar Kushwaha 	ls2080a_qds_mux_mdio(priv->muxval);
37444937214SPrabhakar Kushwaha 
37544937214SPrabhakar Kushwaha 	return priv->realbus->read(priv->realbus, addr, devad, regnum);
37644937214SPrabhakar Kushwaha }
37744937214SPrabhakar Kushwaha 
37844937214SPrabhakar Kushwaha static int ls2080a_qds_mdio_write(struct mii_dev *bus, int addr, int devad,
37944937214SPrabhakar Kushwaha 				  int regnum, u16 value)
38044937214SPrabhakar Kushwaha {
38144937214SPrabhakar Kushwaha 	struct ls2080a_qds_mdio *priv = bus->priv;
38244937214SPrabhakar Kushwaha 
38344937214SPrabhakar Kushwaha 	ls2080a_qds_mux_mdio(priv->muxval);
38444937214SPrabhakar Kushwaha 
38544937214SPrabhakar Kushwaha 	return priv->realbus->write(priv->realbus, addr, devad, regnum, value);
38644937214SPrabhakar Kushwaha }
38744937214SPrabhakar Kushwaha 
38844937214SPrabhakar Kushwaha static int ls2080a_qds_mdio_reset(struct mii_dev *bus)
38944937214SPrabhakar Kushwaha {
39044937214SPrabhakar Kushwaha 	struct ls2080a_qds_mdio *priv = bus->priv;
39144937214SPrabhakar Kushwaha 
39244937214SPrabhakar Kushwaha 	return priv->realbus->reset(priv->realbus);
39344937214SPrabhakar Kushwaha }
39444937214SPrabhakar Kushwaha 
39544937214SPrabhakar Kushwaha static int ls2080a_qds_mdio_init(char *realbusname, u8 muxval)
39644937214SPrabhakar Kushwaha {
39744937214SPrabhakar Kushwaha 	struct ls2080a_qds_mdio *pmdio;
39844937214SPrabhakar Kushwaha 	struct mii_dev *bus = mdio_alloc();
39944937214SPrabhakar Kushwaha 
40044937214SPrabhakar Kushwaha 	if (!bus) {
40144937214SPrabhakar Kushwaha 		printf("Failed to allocate ls2080a_qds MDIO bus\n");
40244937214SPrabhakar Kushwaha 		return -1;
40344937214SPrabhakar Kushwaha 	}
40444937214SPrabhakar Kushwaha 
40544937214SPrabhakar Kushwaha 	pmdio = malloc(sizeof(*pmdio));
40644937214SPrabhakar Kushwaha 	if (!pmdio) {
40744937214SPrabhakar Kushwaha 		printf("Failed to allocate ls2080a_qds private data\n");
40844937214SPrabhakar Kushwaha 		free(bus);
40944937214SPrabhakar Kushwaha 		return -1;
41044937214SPrabhakar Kushwaha 	}
41144937214SPrabhakar Kushwaha 
41244937214SPrabhakar Kushwaha 	bus->read = ls2080a_qds_mdio_read;
41344937214SPrabhakar Kushwaha 	bus->write = ls2080a_qds_mdio_write;
41444937214SPrabhakar Kushwaha 	bus->reset = ls2080a_qds_mdio_reset;
415192bc694SBen Whitten 	strcpy(bus->name, ls2080a_qds_mdio_name_for_muxval(muxval));
41644937214SPrabhakar Kushwaha 
41744937214SPrabhakar Kushwaha 	pmdio->realbus = miiphy_get_dev_by_name(realbusname);
41844937214SPrabhakar Kushwaha 
41944937214SPrabhakar Kushwaha 	if (!pmdio->realbus) {
42044937214SPrabhakar Kushwaha 		printf("No bus with name %s\n", realbusname);
42144937214SPrabhakar Kushwaha 		free(bus);
42244937214SPrabhakar Kushwaha 		free(pmdio);
42344937214SPrabhakar Kushwaha 		return -1;
42444937214SPrabhakar Kushwaha 	}
42544937214SPrabhakar Kushwaha 
42644937214SPrabhakar Kushwaha 	pmdio->muxval = muxval;
42744937214SPrabhakar Kushwaha 	bus->priv = pmdio;
42844937214SPrabhakar Kushwaha 
42944937214SPrabhakar Kushwaha 	return mdio_register(bus);
43044937214SPrabhakar Kushwaha }
43144937214SPrabhakar Kushwaha 
43244937214SPrabhakar Kushwaha /*
43344937214SPrabhakar Kushwaha  * Initialize the dpmac_info array.
43444937214SPrabhakar Kushwaha  *
43544937214SPrabhakar Kushwaha  */
43644937214SPrabhakar Kushwaha static void initialize_dpmac_to_slot(void)
43744937214SPrabhakar Kushwaha {
43844937214SPrabhakar Kushwaha 	struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
43944937214SPrabhakar Kushwaha 	int serdes1_prtcl = (in_le32(&gur->rcwsr[28]) &
44044937214SPrabhakar Kushwaha 				FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK)
44144937214SPrabhakar Kushwaha 		>> FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
44244937214SPrabhakar Kushwaha 	int serdes2_prtcl = (in_le32(&gur->rcwsr[28]) &
44344937214SPrabhakar Kushwaha 				FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_MASK)
44444937214SPrabhakar Kushwaha 		>> FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_SHIFT;
44544937214SPrabhakar Kushwaha 
44644937214SPrabhakar Kushwaha 	char *env_hwconfig;
44744937214SPrabhakar Kushwaha 	env_hwconfig = getenv("hwconfig");
44844937214SPrabhakar Kushwaha 
44944937214SPrabhakar Kushwaha 	switch (serdes1_prtcl) {
45044937214SPrabhakar Kushwaha 	case 0x07:
45144937214SPrabhakar Kushwaha 	case 0x09:
45244937214SPrabhakar Kushwaha 	case 0x33:
45344937214SPrabhakar Kushwaha 		printf("qds: WRIOP: Supported SerDes1 Protocol 0x%02x\n",
45444937214SPrabhakar Kushwaha 		       serdes1_prtcl);
45544937214SPrabhakar Kushwaha 		lane_to_slot_fsm1[0] = EMI1_SLOT1;
45644937214SPrabhakar Kushwaha 		lane_to_slot_fsm1[1] = EMI1_SLOT1;
45744937214SPrabhakar Kushwaha 		lane_to_slot_fsm1[2] = EMI1_SLOT1;
45844937214SPrabhakar Kushwaha 		lane_to_slot_fsm1[3] = EMI1_SLOT1;
45944937214SPrabhakar Kushwaha 		if (hwconfig_f("xqsgmii", env_hwconfig)) {
46044937214SPrabhakar Kushwaha 			lane_to_slot_fsm1[4] = EMI1_SLOT1;
46144937214SPrabhakar Kushwaha 			lane_to_slot_fsm1[5] = EMI1_SLOT1;
46244937214SPrabhakar Kushwaha 			lane_to_slot_fsm1[6] = EMI1_SLOT1;
46344937214SPrabhakar Kushwaha 			lane_to_slot_fsm1[7] = EMI1_SLOT1;
46444937214SPrabhakar Kushwaha 		} else {
46544937214SPrabhakar Kushwaha 			lane_to_slot_fsm1[4] = EMI1_SLOT2;
46644937214SPrabhakar Kushwaha 			lane_to_slot_fsm1[5] = EMI1_SLOT2;
46744937214SPrabhakar Kushwaha 			lane_to_slot_fsm1[6] = EMI1_SLOT2;
46844937214SPrabhakar Kushwaha 			lane_to_slot_fsm1[7] = EMI1_SLOT2;
46944937214SPrabhakar Kushwaha 		}
47044937214SPrabhakar Kushwaha 		break;
47144937214SPrabhakar Kushwaha 
47244937214SPrabhakar Kushwaha 	case 0x2A:
47344937214SPrabhakar Kushwaha 		printf("qds: WRIOP: Supported SerDes1 Protocol 0x%02x\n",
47444937214SPrabhakar Kushwaha 		       serdes1_prtcl);
47544937214SPrabhakar Kushwaha 		break;
47644937214SPrabhakar Kushwaha 	default:
47744937214SPrabhakar Kushwaha 		printf("%s qds: WRIOP: Unsupported SerDes1 Protocol 0x%02x\n",
47844937214SPrabhakar Kushwaha 		       __func__, serdes1_prtcl);
47944937214SPrabhakar Kushwaha 		break;
48044937214SPrabhakar Kushwaha 	}
48144937214SPrabhakar Kushwaha 
48244937214SPrabhakar Kushwaha 	switch (serdes2_prtcl) {
48344937214SPrabhakar Kushwaha 	case 0x07:
48444937214SPrabhakar Kushwaha 	case 0x08:
48544937214SPrabhakar Kushwaha 	case 0x09:
48644937214SPrabhakar Kushwaha 	case 0x49:
48744937214SPrabhakar Kushwaha 		printf("qds: WRIOP: Supported SerDes2 Protocol 0x%02x\n",
48844937214SPrabhakar Kushwaha 		       serdes2_prtcl);
48944937214SPrabhakar Kushwaha 		lane_to_slot_fsm2[0] = EMI1_SLOT4;
49044937214SPrabhakar Kushwaha 		lane_to_slot_fsm2[1] = EMI1_SLOT4;
49144937214SPrabhakar Kushwaha 		lane_to_slot_fsm2[2] = EMI1_SLOT4;
49244937214SPrabhakar Kushwaha 		lane_to_slot_fsm2[3] = EMI1_SLOT4;
49344937214SPrabhakar Kushwaha 
49444937214SPrabhakar Kushwaha 		if (hwconfig_f("xqsgmii", env_hwconfig)) {
49544937214SPrabhakar Kushwaha 			lane_to_slot_fsm2[4] = EMI1_SLOT4;
49644937214SPrabhakar Kushwaha 			lane_to_slot_fsm2[5] = EMI1_SLOT4;
49744937214SPrabhakar Kushwaha 			lane_to_slot_fsm2[6] = EMI1_SLOT4;
49844937214SPrabhakar Kushwaha 			lane_to_slot_fsm2[7] = EMI1_SLOT4;
49944937214SPrabhakar Kushwaha 		} else {
50044937214SPrabhakar Kushwaha 			/* No MDIO physical connection */
50144937214SPrabhakar Kushwaha 			lane_to_slot_fsm2[4] = EMI1_SLOT6;
50244937214SPrabhakar Kushwaha 			lane_to_slot_fsm2[5] = EMI1_SLOT6;
50344937214SPrabhakar Kushwaha 			lane_to_slot_fsm2[6] = EMI1_SLOT6;
50444937214SPrabhakar Kushwaha 			lane_to_slot_fsm2[7] = EMI1_SLOT6;
50544937214SPrabhakar Kushwaha 		}
50644937214SPrabhakar Kushwaha 		break;
50744937214SPrabhakar Kushwaha 	default:
50844937214SPrabhakar Kushwaha 		printf(" %s qds: WRIOP: Unsupported SerDes2 Protocol 0x%02x\n",
50944937214SPrabhakar Kushwaha 		       __func__ , serdes2_prtcl);
51044937214SPrabhakar Kushwaha 		break;
51144937214SPrabhakar Kushwaha 	}
51244937214SPrabhakar Kushwaha }
51344937214SPrabhakar Kushwaha 
51444937214SPrabhakar Kushwaha void ls2080a_handle_phy_interface_sgmii(int dpmac_id)
51544937214SPrabhakar Kushwaha {
51644937214SPrabhakar Kushwaha 	int lane, slot;
51744937214SPrabhakar Kushwaha 	struct mii_dev *bus;
51844937214SPrabhakar Kushwaha 	struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
51944937214SPrabhakar Kushwaha 	int serdes1_prtcl = (in_le32(&gur->rcwsr[28]) &
52044937214SPrabhakar Kushwaha 				FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK)
52144937214SPrabhakar Kushwaha 		>> FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
52244937214SPrabhakar Kushwaha 	int serdes2_prtcl = (in_le32(&gur->rcwsr[28]) &
52344937214SPrabhakar Kushwaha 				FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_MASK)
52444937214SPrabhakar Kushwaha 		>> FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_SHIFT;
52544937214SPrabhakar Kushwaha 
52644937214SPrabhakar Kushwaha 	int *riser_phy_addr;
52744937214SPrabhakar Kushwaha 	char *env_hwconfig = getenv("hwconfig");
52844937214SPrabhakar Kushwaha 
52944937214SPrabhakar Kushwaha 	if (hwconfig_f("xqsgmii", env_hwconfig))
53044937214SPrabhakar Kushwaha 		riser_phy_addr = &xqsgii_riser_phy_addr[0];
53144937214SPrabhakar Kushwaha 	else
53244937214SPrabhakar Kushwaha 		riser_phy_addr = &sgmii_riser_phy_addr[0];
53344937214SPrabhakar Kushwaha 
53444937214SPrabhakar Kushwaha 	if (dpmac_id > WRIOP1_DPMAC9)
53544937214SPrabhakar Kushwaha 		goto serdes2;
53644937214SPrabhakar Kushwaha 
53744937214SPrabhakar Kushwaha 	switch (serdes1_prtcl) {
53844937214SPrabhakar Kushwaha 	case 0x07:
53944937214SPrabhakar Kushwaha 
54044937214SPrabhakar Kushwaha 		lane = serdes_get_first_lane(FSL_SRDS_1, SGMII1 + dpmac_id);
54144937214SPrabhakar Kushwaha 		slot = lane_to_slot_fsm1[lane];
54244937214SPrabhakar Kushwaha 
54344937214SPrabhakar Kushwaha 		switch (++slot) {
54444937214SPrabhakar Kushwaha 		case 1:
54544937214SPrabhakar Kushwaha 			/* Slot housing a SGMII riser card? */
54644937214SPrabhakar Kushwaha 			wriop_set_phy_address(dpmac_id,
54744937214SPrabhakar Kushwaha 					      riser_phy_addr[dpmac_id - 1]);
54844937214SPrabhakar Kushwaha 			dpmac_info[dpmac_id].board_mux = EMI1_SLOT1;
54944937214SPrabhakar Kushwaha 			bus = mii_dev_for_muxval(EMI1_SLOT1);
55044937214SPrabhakar Kushwaha 			wriop_set_mdio(dpmac_id, bus);
55144937214SPrabhakar Kushwaha 			dpmac_info[dpmac_id].phydev = phy_connect(
55244937214SPrabhakar Kushwaha 						dpmac_info[dpmac_id].bus,
55344937214SPrabhakar Kushwaha 						dpmac_info[dpmac_id].phy_addr,
55444937214SPrabhakar Kushwaha 						NULL,
55544937214SPrabhakar Kushwaha 						dpmac_info[dpmac_id].enet_if);
55644937214SPrabhakar Kushwaha 			phy_config(dpmac_info[dpmac_id].phydev);
55744937214SPrabhakar Kushwaha 			break;
55844937214SPrabhakar Kushwaha 		case 2:
55944937214SPrabhakar Kushwaha 			/* Slot housing a SGMII riser card? */
56044937214SPrabhakar Kushwaha 			wriop_set_phy_address(dpmac_id,
56144937214SPrabhakar Kushwaha 					      riser_phy_addr[dpmac_id - 1]);
56244937214SPrabhakar Kushwaha 			dpmac_info[dpmac_id].board_mux = EMI1_SLOT2;
56344937214SPrabhakar Kushwaha 			bus = mii_dev_for_muxval(EMI1_SLOT2);
56444937214SPrabhakar Kushwaha 			wriop_set_mdio(dpmac_id, bus);
56544937214SPrabhakar Kushwaha 			dpmac_info[dpmac_id].phydev = phy_connect(
56644937214SPrabhakar Kushwaha 						dpmac_info[dpmac_id].bus,
56744937214SPrabhakar Kushwaha 						dpmac_info[dpmac_id].phy_addr,
56844937214SPrabhakar Kushwaha 						NULL,
56944937214SPrabhakar Kushwaha 						dpmac_info[dpmac_id].enet_if);
57044937214SPrabhakar Kushwaha 			phy_config(dpmac_info[dpmac_id].phydev);
57144937214SPrabhakar Kushwaha 			break;
57244937214SPrabhakar Kushwaha 		case 3:
57344937214SPrabhakar Kushwaha 			break;
57444937214SPrabhakar Kushwaha 		case 4:
57544937214SPrabhakar Kushwaha 			break;
57644937214SPrabhakar Kushwaha 		case 5:
57744937214SPrabhakar Kushwaha 			break;
57844937214SPrabhakar Kushwaha 		case 6:
57944937214SPrabhakar Kushwaha 			break;
58044937214SPrabhakar Kushwaha 		}
58144937214SPrabhakar Kushwaha 	break;
58244937214SPrabhakar Kushwaha 	default:
58344937214SPrabhakar Kushwaha 		printf("%s qds: WRIOP: Unsupported SerDes1 Protocol 0x%02x\n",
58444937214SPrabhakar Kushwaha 		       __func__ , serdes1_prtcl);
58544937214SPrabhakar Kushwaha 	break;
58644937214SPrabhakar Kushwaha 	}
58744937214SPrabhakar Kushwaha 
58844937214SPrabhakar Kushwaha serdes2:
58944937214SPrabhakar Kushwaha 	switch (serdes2_prtcl) {
59044937214SPrabhakar Kushwaha 	case 0x07:
59144937214SPrabhakar Kushwaha 	case 0x08:
59244937214SPrabhakar Kushwaha 	case 0x49:
59344937214SPrabhakar Kushwaha 		lane = serdes_get_first_lane(FSL_SRDS_2, SGMII9 +
59444937214SPrabhakar Kushwaha 							(dpmac_id - 9));
59544937214SPrabhakar Kushwaha 		slot = lane_to_slot_fsm2[lane];
59644937214SPrabhakar Kushwaha 
59744937214SPrabhakar Kushwaha 		switch (++slot) {
59844937214SPrabhakar Kushwaha 		case 1:
59944937214SPrabhakar Kushwaha 			break;
60044937214SPrabhakar Kushwaha 		case 3:
60144937214SPrabhakar Kushwaha 			break;
60244937214SPrabhakar Kushwaha 		case 4:
60344937214SPrabhakar Kushwaha 			/* Slot housing a SGMII riser card? */
60444937214SPrabhakar Kushwaha 			wriop_set_phy_address(dpmac_id,
60544937214SPrabhakar Kushwaha 					      riser_phy_addr[dpmac_id - 9]);
60644937214SPrabhakar Kushwaha 			dpmac_info[dpmac_id].board_mux = EMI1_SLOT4;
60744937214SPrabhakar Kushwaha 			bus = mii_dev_for_muxval(EMI1_SLOT4);
60844937214SPrabhakar Kushwaha 			wriop_set_mdio(dpmac_id, bus);
60944937214SPrabhakar Kushwaha 			dpmac_info[dpmac_id].phydev = phy_connect(
61044937214SPrabhakar Kushwaha 						dpmac_info[dpmac_id].bus,
61144937214SPrabhakar Kushwaha 						dpmac_info[dpmac_id].phy_addr,
61244937214SPrabhakar Kushwaha 						NULL,
61344937214SPrabhakar Kushwaha 						dpmac_info[dpmac_id].enet_if);
61444937214SPrabhakar Kushwaha 			phy_config(dpmac_info[dpmac_id].phydev);
61544937214SPrabhakar Kushwaha 		break;
61644937214SPrabhakar Kushwaha 		case 5:
61744937214SPrabhakar Kushwaha 		break;
61844937214SPrabhakar Kushwaha 		case 6:
61944937214SPrabhakar Kushwaha 			/* Slot housing a SGMII riser card? */
62044937214SPrabhakar Kushwaha 			wriop_set_phy_address(dpmac_id,
62144937214SPrabhakar Kushwaha 					      riser_phy_addr[dpmac_id - 13]);
62244937214SPrabhakar Kushwaha 			dpmac_info[dpmac_id].board_mux = EMI1_SLOT6;
62344937214SPrabhakar Kushwaha 			bus = mii_dev_for_muxval(EMI1_SLOT6);
62444937214SPrabhakar Kushwaha 			wriop_set_mdio(dpmac_id, bus);
62544937214SPrabhakar Kushwaha 		break;
62644937214SPrabhakar Kushwaha 	}
62744937214SPrabhakar Kushwaha 	break;
62844937214SPrabhakar Kushwaha 	default:
62944937214SPrabhakar Kushwaha 		printf("%s qds: WRIOP: Unsupported SerDes2 Protocol 0x%02x\n",
63044937214SPrabhakar Kushwaha 		       __func__, serdes2_prtcl);
63144937214SPrabhakar Kushwaha 	break;
63244937214SPrabhakar Kushwaha 	}
63344937214SPrabhakar Kushwaha }
63444937214SPrabhakar Kushwaha 
63544937214SPrabhakar Kushwaha void ls2080a_handle_phy_interface_qsgmii(int dpmac_id)
63644937214SPrabhakar Kushwaha {
63744937214SPrabhakar Kushwaha 	int lane = 0, slot;
63844937214SPrabhakar Kushwaha 	struct mii_dev *bus;
63944937214SPrabhakar Kushwaha 	struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
64044937214SPrabhakar Kushwaha 	int serdes1_prtcl = (in_le32(&gur->rcwsr[28]) &
64144937214SPrabhakar Kushwaha 				FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK)
64244937214SPrabhakar Kushwaha 		>> FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
64344937214SPrabhakar Kushwaha 
64444937214SPrabhakar Kushwaha 	switch (serdes1_prtcl) {
64544937214SPrabhakar Kushwaha 	case 0x33:
64644937214SPrabhakar Kushwaha 		switch (dpmac_id) {
64744937214SPrabhakar Kushwaha 		case 1:
64844937214SPrabhakar Kushwaha 		case 2:
64944937214SPrabhakar Kushwaha 		case 3:
65044937214SPrabhakar Kushwaha 		case 4:
65144937214SPrabhakar Kushwaha 			lane = serdes_get_first_lane(FSL_SRDS_1, QSGMII_A);
65244937214SPrabhakar Kushwaha 		break;
65344937214SPrabhakar Kushwaha 		case 5:
65444937214SPrabhakar Kushwaha 		case 6:
65544937214SPrabhakar Kushwaha 		case 7:
65644937214SPrabhakar Kushwaha 		case 8:
65744937214SPrabhakar Kushwaha 			lane = serdes_get_first_lane(FSL_SRDS_1, QSGMII_B);
65844937214SPrabhakar Kushwaha 		break;
65944937214SPrabhakar Kushwaha 		case 9:
66044937214SPrabhakar Kushwaha 		case 10:
66144937214SPrabhakar Kushwaha 		case 11:
66244937214SPrabhakar Kushwaha 		case 12:
66344937214SPrabhakar Kushwaha 			lane = serdes_get_first_lane(FSL_SRDS_1, QSGMII_C);
66444937214SPrabhakar Kushwaha 		break;
66544937214SPrabhakar Kushwaha 		case 13:
66644937214SPrabhakar Kushwaha 		case 14:
66744937214SPrabhakar Kushwaha 		case 15:
66844937214SPrabhakar Kushwaha 		case 16:
66944937214SPrabhakar Kushwaha 			lane = serdes_get_first_lane(FSL_SRDS_1, QSGMII_D);
67044937214SPrabhakar Kushwaha 		break;
67144937214SPrabhakar Kushwaha 	}
67244937214SPrabhakar Kushwaha 
67344937214SPrabhakar Kushwaha 		slot = lane_to_slot_fsm1[lane];
67444937214SPrabhakar Kushwaha 
67544937214SPrabhakar Kushwaha 		switch (++slot) {
67644937214SPrabhakar Kushwaha 		case 1:
67744937214SPrabhakar Kushwaha 			/* Slot housing a QSGMII riser card? */
67844937214SPrabhakar Kushwaha 			wriop_set_phy_address(dpmac_id, dpmac_id - 1);
67944937214SPrabhakar Kushwaha 			dpmac_info[dpmac_id].board_mux = EMI1_SLOT1;
68044937214SPrabhakar Kushwaha 			bus = mii_dev_for_muxval(EMI1_SLOT1);
68144937214SPrabhakar Kushwaha 			wriop_set_mdio(dpmac_id, bus);
68244937214SPrabhakar Kushwaha 			dpmac_info[dpmac_id].phydev = phy_connect(
68344937214SPrabhakar Kushwaha 						dpmac_info[dpmac_id].bus,
68444937214SPrabhakar Kushwaha 						dpmac_info[dpmac_id].phy_addr,
68544937214SPrabhakar Kushwaha 						NULL,
68644937214SPrabhakar Kushwaha 						dpmac_info[dpmac_id].enet_if);
68744937214SPrabhakar Kushwaha 
68844937214SPrabhakar Kushwaha 			phy_config(dpmac_info[dpmac_id].phydev);
68944937214SPrabhakar Kushwaha 			break;
69044937214SPrabhakar Kushwaha 		case 3:
69144937214SPrabhakar Kushwaha 			break;
69244937214SPrabhakar Kushwaha 		case 4:
69344937214SPrabhakar Kushwaha 			break;
69444937214SPrabhakar Kushwaha 		case 5:
69544937214SPrabhakar Kushwaha 		break;
69644937214SPrabhakar Kushwaha 		case 6:
69744937214SPrabhakar Kushwaha 			break;
69844937214SPrabhakar Kushwaha 	}
69944937214SPrabhakar Kushwaha 	break;
70044937214SPrabhakar Kushwaha 	default:
70144937214SPrabhakar Kushwaha 		printf("qds: WRIOP: Unsupported SerDes Protocol 0x%02x\n",
70244937214SPrabhakar Kushwaha 		       serdes1_prtcl);
70344937214SPrabhakar Kushwaha 	break;
70444937214SPrabhakar Kushwaha 	}
70544937214SPrabhakar Kushwaha 
70644937214SPrabhakar Kushwaha 	qsgmii_configure_repeater(dpmac_id);
70744937214SPrabhakar Kushwaha }
70844937214SPrabhakar Kushwaha 
70944937214SPrabhakar Kushwaha void ls2080a_handle_phy_interface_xsgmii(int i)
71044937214SPrabhakar Kushwaha {
71144937214SPrabhakar Kushwaha 	struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
71244937214SPrabhakar Kushwaha 	int serdes1_prtcl = (in_le32(&gur->rcwsr[28]) &
71344937214SPrabhakar Kushwaha 				FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK)
71444937214SPrabhakar Kushwaha 		>> FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
71544937214SPrabhakar Kushwaha 
71644937214SPrabhakar Kushwaha 	switch (serdes1_prtcl) {
71744937214SPrabhakar Kushwaha 	case 0x2A:
71844937214SPrabhakar Kushwaha 		/*
719*a187559eSBin Meng 		 * XFI does not need a PHY to work, but to avoid U-Boot use
72044937214SPrabhakar Kushwaha 		 * default PHY address which is zero to a MAC when it found
72144937214SPrabhakar Kushwaha 		 * a MAC has no PHY address, we give a PHY address to XFI
72244937214SPrabhakar Kushwaha 		 * MAC, and should not use a real XAUI PHY address, since
72344937214SPrabhakar Kushwaha 		 * MDIO can access it successfully, and then MDIO thinks
72444937214SPrabhakar Kushwaha 		 * the XAUI card is used for the XFI MAC, which will cause
72544937214SPrabhakar Kushwaha 		 * error.
72644937214SPrabhakar Kushwaha 		 */
72744937214SPrabhakar Kushwaha 		wriop_set_phy_address(i, i + 4);
72844937214SPrabhakar Kushwaha 		ls2080a_qds_enable_SFP_TX(SFP_TX);
72944937214SPrabhakar Kushwaha 
73044937214SPrabhakar Kushwaha 		break;
73144937214SPrabhakar Kushwaha 	default:
73244937214SPrabhakar Kushwaha 		printf("qds: WRIOP: Unsupported SerDes Protocol 0x%02x\n",
73344937214SPrabhakar Kushwaha 		       serdes1_prtcl);
73444937214SPrabhakar Kushwaha 		break;
73544937214SPrabhakar Kushwaha 	}
73644937214SPrabhakar Kushwaha }
73744937214SPrabhakar Kushwaha #endif
73844937214SPrabhakar Kushwaha 
73944937214SPrabhakar Kushwaha int board_eth_init(bd_t *bis)
74044937214SPrabhakar Kushwaha {
74144937214SPrabhakar Kushwaha 	int error;
74244937214SPrabhakar Kushwaha #ifdef CONFIG_FSL_MC_ENET
74344937214SPrabhakar Kushwaha 	struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
74444937214SPrabhakar Kushwaha 	int serdes1_prtcl = (in_le32(&gur->rcwsr[28]) &
74544937214SPrabhakar Kushwaha 				FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK)
74644937214SPrabhakar Kushwaha 		>> FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
74744937214SPrabhakar Kushwaha 	int serdes2_prtcl = (in_le32(&gur->rcwsr[28]) &
74844937214SPrabhakar Kushwaha 				FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_MASK)
74944937214SPrabhakar Kushwaha 		>> FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_SHIFT;
75044937214SPrabhakar Kushwaha 
75144937214SPrabhakar Kushwaha 	struct memac_mdio_info *memac_mdio0_info;
75244937214SPrabhakar Kushwaha 	struct memac_mdio_info *memac_mdio1_info;
75344937214SPrabhakar Kushwaha 	unsigned int i;
75444937214SPrabhakar Kushwaha 	char *env_hwconfig;
75544937214SPrabhakar Kushwaha 
75644937214SPrabhakar Kushwaha 	env_hwconfig = getenv("hwconfig");
75744937214SPrabhakar Kushwaha 
75844937214SPrabhakar Kushwaha 	initialize_dpmac_to_slot();
75944937214SPrabhakar Kushwaha 
76044937214SPrabhakar Kushwaha 	memac_mdio0_info = (struct memac_mdio_info *)malloc(
76144937214SPrabhakar Kushwaha 					sizeof(struct memac_mdio_info));
76244937214SPrabhakar Kushwaha 	memac_mdio0_info->regs =
76344937214SPrabhakar Kushwaha 		(struct memac_mdio_controller *)
76444937214SPrabhakar Kushwaha 					CONFIG_SYS_FSL_WRIOP1_MDIO1;
76544937214SPrabhakar Kushwaha 	memac_mdio0_info->name = DEFAULT_WRIOP_MDIO1_NAME;
76644937214SPrabhakar Kushwaha 
76744937214SPrabhakar Kushwaha 	/* Register the real MDIO1 bus */
76844937214SPrabhakar Kushwaha 	fm_memac_mdio_init(bis, memac_mdio0_info);
76944937214SPrabhakar Kushwaha 
77044937214SPrabhakar Kushwaha 	memac_mdio1_info = (struct memac_mdio_info *)malloc(
77144937214SPrabhakar Kushwaha 					sizeof(struct memac_mdio_info));
77244937214SPrabhakar Kushwaha 	memac_mdio1_info->regs =
77344937214SPrabhakar Kushwaha 		(struct memac_mdio_controller *)
77444937214SPrabhakar Kushwaha 					CONFIG_SYS_FSL_WRIOP1_MDIO2;
77544937214SPrabhakar Kushwaha 	memac_mdio1_info->name = DEFAULT_WRIOP_MDIO2_NAME;
77644937214SPrabhakar Kushwaha 
77744937214SPrabhakar Kushwaha 	/* Register the real MDIO2 bus */
77844937214SPrabhakar Kushwaha 	fm_memac_mdio_init(bis, memac_mdio1_info);
77944937214SPrabhakar Kushwaha 
78044937214SPrabhakar Kushwaha 	/* Register the muxing front-ends to the MDIO buses */
78144937214SPrabhakar Kushwaha 	ls2080a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT1);
78244937214SPrabhakar Kushwaha 	ls2080a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT2);
78344937214SPrabhakar Kushwaha 	ls2080a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT3);
78444937214SPrabhakar Kushwaha 	ls2080a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT4);
78544937214SPrabhakar Kushwaha 	ls2080a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT5);
78644937214SPrabhakar Kushwaha 	ls2080a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT6);
78744937214SPrabhakar Kushwaha 
78844937214SPrabhakar Kushwaha 	ls2080a_qds_mdio_init(DEFAULT_WRIOP_MDIO2_NAME, EMI2);
78944937214SPrabhakar Kushwaha 
79044937214SPrabhakar Kushwaha 	for (i = WRIOP1_DPMAC1; i < NUM_WRIOP_PORTS; i++) {
79144937214SPrabhakar Kushwaha 		switch (wriop_get_enet_if(i)) {
79244937214SPrabhakar Kushwaha 		case PHY_INTERFACE_MODE_QSGMII:
79344937214SPrabhakar Kushwaha 			ls2080a_handle_phy_interface_qsgmii(i);
79444937214SPrabhakar Kushwaha 			break;
79544937214SPrabhakar Kushwaha 		case PHY_INTERFACE_MODE_SGMII:
79644937214SPrabhakar Kushwaha 			ls2080a_handle_phy_interface_sgmii(i);
79744937214SPrabhakar Kushwaha 			break;
79844937214SPrabhakar Kushwaha 		case PHY_INTERFACE_MODE_XGMII:
79944937214SPrabhakar Kushwaha 			ls2080a_handle_phy_interface_xsgmii(i);
80044937214SPrabhakar Kushwaha 			break;
80144937214SPrabhakar Kushwaha 		default:
80244937214SPrabhakar Kushwaha 			break;
80344937214SPrabhakar Kushwaha 
80444937214SPrabhakar Kushwaha 		if (i == 16)
80544937214SPrabhakar Kushwaha 			i = NUM_WRIOP_PORTS;
80644937214SPrabhakar Kushwaha 		}
80744937214SPrabhakar Kushwaha 	}
80844937214SPrabhakar Kushwaha 
80944937214SPrabhakar Kushwaha 	error = cpu_eth_init(bis);
81044937214SPrabhakar Kushwaha 
81144937214SPrabhakar Kushwaha 	if (hwconfig_f("xqsgmii", env_hwconfig)) {
81244937214SPrabhakar Kushwaha 		if (serdes1_prtcl == 0x7)
81344937214SPrabhakar Kushwaha 			sgmii_configure_repeater(1);
81444937214SPrabhakar Kushwaha 		if (serdes2_prtcl == 0x7 || serdes2_prtcl == 0x8 ||
81544937214SPrabhakar Kushwaha 		    serdes2_prtcl == 0x49)
81644937214SPrabhakar Kushwaha 			sgmii_configure_repeater(2);
81744937214SPrabhakar Kushwaha 	}
81844937214SPrabhakar Kushwaha #endif
81944937214SPrabhakar Kushwaha 	error = pci_eth_init(bis);
82044937214SPrabhakar Kushwaha 	return error;
82144937214SPrabhakar Kushwaha }
82244937214SPrabhakar Kushwaha 
82344937214SPrabhakar Kushwaha #ifdef CONFIG_FSL_MC_ENET
82444937214SPrabhakar Kushwaha 
82544937214SPrabhakar Kushwaha #endif
826