xref: /openbmc/u-boot/board/freescale/t1040qds/eth.c (revision 5b7672fc49af1b771a7e318522b010fd5b11c4ab)
1*5b7672fcSPrabhakar Kushwaha /*
2*5b7672fcSPrabhakar Kushwaha  * Copyright 2013 Freescale Semiconductor, Inc.
3*5b7672fcSPrabhakar Kushwaha  *
4*5b7672fcSPrabhakar Kushwaha  * SPDX-License-Identifier:	GPL-2.0+
5*5b7672fcSPrabhakar Kushwaha  */
6*5b7672fcSPrabhakar Kushwaha 
7*5b7672fcSPrabhakar Kushwaha /*
8*5b7672fcSPrabhakar Kushwaha  * The RGMII PHYs are provided by the two on-board PHY connected to
9*5b7672fcSPrabhakar Kushwaha  * dTSEC instances 4 and 5. The SGMII PHYs are provided by one on-board
10*5b7672fcSPrabhakar Kushwaha  * PHY or by the standard four-port SGMII riser card (VSC).
11*5b7672fcSPrabhakar Kushwaha  */
12*5b7672fcSPrabhakar Kushwaha 
13*5b7672fcSPrabhakar Kushwaha #include <common.h>
14*5b7672fcSPrabhakar Kushwaha #include <netdev.h>
15*5b7672fcSPrabhakar Kushwaha #include <asm/fsl_serdes.h>
16*5b7672fcSPrabhakar Kushwaha #include <asm/immap_85xx.h>
17*5b7672fcSPrabhakar Kushwaha #include <fm_eth.h>
18*5b7672fcSPrabhakar Kushwaha #include <fsl_mdio.h>
19*5b7672fcSPrabhakar Kushwaha #include <malloc.h>
20*5b7672fcSPrabhakar Kushwaha #include <asm/fsl_dtsec.h>
21*5b7672fcSPrabhakar Kushwaha 
22*5b7672fcSPrabhakar Kushwaha #include "../common/fman.h"
23*5b7672fcSPrabhakar Kushwaha #include "../common/qixis.h"
24*5b7672fcSPrabhakar Kushwaha 
25*5b7672fcSPrabhakar Kushwaha #include "t1040qds_qixis.h"
26*5b7672fcSPrabhakar Kushwaha 
27*5b7672fcSPrabhakar Kushwaha #ifdef CONFIG_FMAN_ENET
28*5b7672fcSPrabhakar Kushwaha  /* - In T1040 there are only 8 SERDES lanes, spread across 2 SERDES banks.
29*5b7672fcSPrabhakar Kushwaha  *   Bank 1 -> Lanes A, B, C, D
30*5b7672fcSPrabhakar Kushwaha  *   Bank 2 -> Lanes E, F, G, H
31*5b7672fcSPrabhakar Kushwaha  */
32*5b7672fcSPrabhakar Kushwaha 
33*5b7672fcSPrabhakar Kushwaha  /* Mapping of 8 SERDES lanes to T1040 QDS board slots. A value of '0' here
34*5b7672fcSPrabhakar Kushwaha   * means that the mapping must be determined dynamically, or that the lane
35*5b7672fcSPrabhakar Kushwaha   * maps to something other than a board slot.
36*5b7672fcSPrabhakar Kushwaha   */
37*5b7672fcSPrabhakar Kushwaha static u8 lane_to_slot[] = {
38*5b7672fcSPrabhakar Kushwaha 	0, 0, 0, 0, 0, 0, 0, 0
39*5b7672fcSPrabhakar Kushwaha };
40*5b7672fcSPrabhakar Kushwaha 
41*5b7672fcSPrabhakar Kushwaha /* On the Vitesse VSC8234XHG SGMII riser card there are 4 SGMII PHYs
42*5b7672fcSPrabhakar Kushwaha  * housed.
43*5b7672fcSPrabhakar Kushwaha  */
44*5b7672fcSPrabhakar Kushwaha static int riser_phy_addr[] = {
45*5b7672fcSPrabhakar Kushwaha 	CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR,
46*5b7672fcSPrabhakar Kushwaha 	CONFIG_SYS_FM1_DTSEC2_RISER_PHY_ADDR,
47*5b7672fcSPrabhakar Kushwaha 	CONFIG_SYS_FM1_DTSEC3_RISER_PHY_ADDR,
48*5b7672fcSPrabhakar Kushwaha 	CONFIG_SYS_FM1_DTSEC4_RISER_PHY_ADDR,
49*5b7672fcSPrabhakar Kushwaha };
50*5b7672fcSPrabhakar Kushwaha 
51*5b7672fcSPrabhakar Kushwaha /* Slot2 does not have EMI connections */
52*5b7672fcSPrabhakar Kushwaha #define EMI_NONE	0xFFFFFFFF
53*5b7672fcSPrabhakar Kushwaha #define EMI1_RGMII0	0
54*5b7672fcSPrabhakar Kushwaha #define EMI1_RGMII1	1
55*5b7672fcSPrabhakar Kushwaha #define EMI1_SLOT1	2
56*5b7672fcSPrabhakar Kushwaha #define EMI1_SLOT3	3
57*5b7672fcSPrabhakar Kushwaha #define EMI1_SLOT4	4
58*5b7672fcSPrabhakar Kushwaha #define EMI1_SLOT5	5
59*5b7672fcSPrabhakar Kushwaha #define EMI1_SLOT6	6
60*5b7672fcSPrabhakar Kushwaha #define EMI1_SLOT7	7
61*5b7672fcSPrabhakar Kushwaha #define EMI2		8
62*5b7672fcSPrabhakar Kushwaha 
63*5b7672fcSPrabhakar Kushwaha static int mdio_mux[NUM_FM_PORTS];
64*5b7672fcSPrabhakar Kushwaha 
65*5b7672fcSPrabhakar Kushwaha static const char * const mdio_names[] = {
66*5b7672fcSPrabhakar Kushwaha 	"T1040_QDS_MDIO0",
67*5b7672fcSPrabhakar Kushwaha 	"T1040_QDS_MDIO1",
68*5b7672fcSPrabhakar Kushwaha 	"T1040_QDS_MDIO2",
69*5b7672fcSPrabhakar Kushwaha 	"T1040_QDS_MDIO3",
70*5b7672fcSPrabhakar Kushwaha 	"T1040_QDS_MDIO4",
71*5b7672fcSPrabhakar Kushwaha 	"T1040_QDS_MDIO5",
72*5b7672fcSPrabhakar Kushwaha 	"T1040_QDS_MDIO6",
73*5b7672fcSPrabhakar Kushwaha 	"T1040_QDS_MDIO7",
74*5b7672fcSPrabhakar Kushwaha };
75*5b7672fcSPrabhakar Kushwaha 
76*5b7672fcSPrabhakar Kushwaha struct t1040_qds_mdio {
77*5b7672fcSPrabhakar Kushwaha 	u8 muxval;
78*5b7672fcSPrabhakar Kushwaha 	struct mii_dev *realbus;
79*5b7672fcSPrabhakar Kushwaha };
80*5b7672fcSPrabhakar Kushwaha 
81*5b7672fcSPrabhakar Kushwaha static const char *t1040_qds_mdio_name_for_muxval(u8 muxval)
82*5b7672fcSPrabhakar Kushwaha {
83*5b7672fcSPrabhakar Kushwaha 	return mdio_names[muxval];
84*5b7672fcSPrabhakar Kushwaha }
85*5b7672fcSPrabhakar Kushwaha 
86*5b7672fcSPrabhakar Kushwaha struct mii_dev *mii_dev_for_muxval(u8 muxval)
87*5b7672fcSPrabhakar Kushwaha {
88*5b7672fcSPrabhakar Kushwaha 	struct mii_dev *bus;
89*5b7672fcSPrabhakar Kushwaha 	const char *name = t1040_qds_mdio_name_for_muxval(muxval);
90*5b7672fcSPrabhakar Kushwaha 
91*5b7672fcSPrabhakar Kushwaha 	if (!name) {
92*5b7672fcSPrabhakar Kushwaha 		printf("No bus for muxval %x\n", muxval);
93*5b7672fcSPrabhakar Kushwaha 		return NULL;
94*5b7672fcSPrabhakar Kushwaha 	}
95*5b7672fcSPrabhakar Kushwaha 
96*5b7672fcSPrabhakar Kushwaha 	bus = miiphy_get_dev_by_name(name);
97*5b7672fcSPrabhakar Kushwaha 
98*5b7672fcSPrabhakar Kushwaha 	if (!bus) {
99*5b7672fcSPrabhakar Kushwaha 		printf("No bus by name %s\n", name);
100*5b7672fcSPrabhakar Kushwaha 		return NULL;
101*5b7672fcSPrabhakar Kushwaha 	}
102*5b7672fcSPrabhakar Kushwaha 
103*5b7672fcSPrabhakar Kushwaha 	return bus;
104*5b7672fcSPrabhakar Kushwaha }
105*5b7672fcSPrabhakar Kushwaha 
106*5b7672fcSPrabhakar Kushwaha static void t1040_qds_mux_mdio(u8 muxval)
107*5b7672fcSPrabhakar Kushwaha {
108*5b7672fcSPrabhakar Kushwaha 	u8 brdcfg4;
109*5b7672fcSPrabhakar Kushwaha 	if (muxval <= 7) {
110*5b7672fcSPrabhakar Kushwaha 		brdcfg4 = QIXIS_READ(brdcfg[4]);
111*5b7672fcSPrabhakar Kushwaha 		brdcfg4 &= ~BRDCFG4_EMISEL_MASK;
112*5b7672fcSPrabhakar Kushwaha 		brdcfg4 |= (muxval << BRDCFG4_EMISEL_SHIFT);
113*5b7672fcSPrabhakar Kushwaha 		QIXIS_WRITE(brdcfg[4], brdcfg4);
114*5b7672fcSPrabhakar Kushwaha 	}
115*5b7672fcSPrabhakar Kushwaha }
116*5b7672fcSPrabhakar Kushwaha 
117*5b7672fcSPrabhakar Kushwaha static int t1040_qds_mdio_read(struct mii_dev *bus, int addr, int devad,
118*5b7672fcSPrabhakar Kushwaha 				int regnum)
119*5b7672fcSPrabhakar Kushwaha {
120*5b7672fcSPrabhakar Kushwaha 	struct t1040_qds_mdio *priv = bus->priv;
121*5b7672fcSPrabhakar Kushwaha 
122*5b7672fcSPrabhakar Kushwaha 	t1040_qds_mux_mdio(priv->muxval);
123*5b7672fcSPrabhakar Kushwaha 
124*5b7672fcSPrabhakar Kushwaha 	return priv->realbus->read(priv->realbus, addr, devad, regnum);
125*5b7672fcSPrabhakar Kushwaha }
126*5b7672fcSPrabhakar Kushwaha 
127*5b7672fcSPrabhakar Kushwaha static int t1040_qds_mdio_write(struct mii_dev *bus, int addr, int devad,
128*5b7672fcSPrabhakar Kushwaha 				int regnum, u16 value)
129*5b7672fcSPrabhakar Kushwaha {
130*5b7672fcSPrabhakar Kushwaha 	struct t1040_qds_mdio *priv = bus->priv;
131*5b7672fcSPrabhakar Kushwaha 
132*5b7672fcSPrabhakar Kushwaha 	t1040_qds_mux_mdio(priv->muxval);
133*5b7672fcSPrabhakar Kushwaha 
134*5b7672fcSPrabhakar Kushwaha 	return priv->realbus->write(priv->realbus, addr, devad, regnum, value);
135*5b7672fcSPrabhakar Kushwaha }
136*5b7672fcSPrabhakar Kushwaha 
137*5b7672fcSPrabhakar Kushwaha static int t1040_qds_mdio_reset(struct mii_dev *bus)
138*5b7672fcSPrabhakar Kushwaha {
139*5b7672fcSPrabhakar Kushwaha 	struct t1040_qds_mdio *priv = bus->priv;
140*5b7672fcSPrabhakar Kushwaha 
141*5b7672fcSPrabhakar Kushwaha 	return priv->realbus->reset(priv->realbus);
142*5b7672fcSPrabhakar Kushwaha }
143*5b7672fcSPrabhakar Kushwaha 
144*5b7672fcSPrabhakar Kushwaha static int t1040_qds_mdio_init(char *realbusname, u8 muxval)
145*5b7672fcSPrabhakar Kushwaha {
146*5b7672fcSPrabhakar Kushwaha 	struct t1040_qds_mdio *pmdio;
147*5b7672fcSPrabhakar Kushwaha 	struct mii_dev *bus = mdio_alloc();
148*5b7672fcSPrabhakar Kushwaha 
149*5b7672fcSPrabhakar Kushwaha 	if (!bus) {
150*5b7672fcSPrabhakar Kushwaha 		printf("Failed to allocate t1040_qds MDIO bus\n");
151*5b7672fcSPrabhakar Kushwaha 		return -1;
152*5b7672fcSPrabhakar Kushwaha 	}
153*5b7672fcSPrabhakar Kushwaha 
154*5b7672fcSPrabhakar Kushwaha 	pmdio = malloc(sizeof(*pmdio));
155*5b7672fcSPrabhakar Kushwaha 	if (!pmdio) {
156*5b7672fcSPrabhakar Kushwaha 		printf("Failed to allocate t1040_qds private data\n");
157*5b7672fcSPrabhakar Kushwaha 		free(bus);
158*5b7672fcSPrabhakar Kushwaha 		return -1;
159*5b7672fcSPrabhakar Kushwaha 	}
160*5b7672fcSPrabhakar Kushwaha 
161*5b7672fcSPrabhakar Kushwaha 	bus->read = t1040_qds_mdio_read;
162*5b7672fcSPrabhakar Kushwaha 	bus->write = t1040_qds_mdio_write;
163*5b7672fcSPrabhakar Kushwaha 	bus->reset = t1040_qds_mdio_reset;
164*5b7672fcSPrabhakar Kushwaha 	sprintf(bus->name, t1040_qds_mdio_name_for_muxval(muxval));
165*5b7672fcSPrabhakar Kushwaha 
166*5b7672fcSPrabhakar Kushwaha 	pmdio->realbus = miiphy_get_dev_by_name(realbusname);
167*5b7672fcSPrabhakar Kushwaha 
168*5b7672fcSPrabhakar Kushwaha 	if (!pmdio->realbus) {
169*5b7672fcSPrabhakar Kushwaha 		printf("No bus with name %s\n", realbusname);
170*5b7672fcSPrabhakar Kushwaha 		free(bus);
171*5b7672fcSPrabhakar Kushwaha 		free(pmdio);
172*5b7672fcSPrabhakar Kushwaha 		return -1;
173*5b7672fcSPrabhakar Kushwaha 	}
174*5b7672fcSPrabhakar Kushwaha 
175*5b7672fcSPrabhakar Kushwaha 	pmdio->muxval = muxval;
176*5b7672fcSPrabhakar Kushwaha 	bus->priv = pmdio;
177*5b7672fcSPrabhakar Kushwaha 
178*5b7672fcSPrabhakar Kushwaha 	return mdio_register(bus);
179*5b7672fcSPrabhakar Kushwaha }
180*5b7672fcSPrabhakar Kushwaha 
181*5b7672fcSPrabhakar Kushwaha /*
182*5b7672fcSPrabhakar Kushwaha  * Initialize the lane_to_slot[] array.
183*5b7672fcSPrabhakar Kushwaha  *
184*5b7672fcSPrabhakar Kushwaha  * On the T1040QDS board the mapping is controlled by ?? register.
185*5b7672fcSPrabhakar Kushwaha  */
186*5b7672fcSPrabhakar Kushwaha static void initialize_lane_to_slot(void)
187*5b7672fcSPrabhakar Kushwaha {
188*5b7672fcSPrabhakar Kushwaha 	ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR;
189*5b7672fcSPrabhakar Kushwaha 	int serdes1_prtcl = (in_be32(&gur->rcwsr[4]) &
190*5b7672fcSPrabhakar Kushwaha 				FSL_CORENET2_RCWSR4_SRDS1_PRTCL)
191*5b7672fcSPrabhakar Kushwaha 		>> FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;
192*5b7672fcSPrabhakar Kushwaha 
193*5b7672fcSPrabhakar Kushwaha 	QIXIS_WRITE(cms[0], 0x07);
194*5b7672fcSPrabhakar Kushwaha 
195*5b7672fcSPrabhakar Kushwaha 	switch (serdes1_prtcl) {
196*5b7672fcSPrabhakar Kushwaha 	case 0x60:
197*5b7672fcSPrabhakar Kushwaha 	case 0x66:
198*5b7672fcSPrabhakar Kushwaha 	case 0x67:
199*5b7672fcSPrabhakar Kushwaha 	case 0x69:
200*5b7672fcSPrabhakar Kushwaha 		lane_to_slot[1] = 7;
201*5b7672fcSPrabhakar Kushwaha 		lane_to_slot[2] = 6;
202*5b7672fcSPrabhakar Kushwaha 		lane_to_slot[3] = 5;
203*5b7672fcSPrabhakar Kushwaha 		break;
204*5b7672fcSPrabhakar Kushwaha 	case 0x86:
205*5b7672fcSPrabhakar Kushwaha 		lane_to_slot[1] = 7;
206*5b7672fcSPrabhakar Kushwaha 		lane_to_slot[2] = 7;
207*5b7672fcSPrabhakar Kushwaha 		lane_to_slot[3] = 7;
208*5b7672fcSPrabhakar Kushwaha 		break;
209*5b7672fcSPrabhakar Kushwaha 	case 0x87:
210*5b7672fcSPrabhakar Kushwaha 		lane_to_slot[1] = 7;
211*5b7672fcSPrabhakar Kushwaha 		lane_to_slot[2] = 7;
212*5b7672fcSPrabhakar Kushwaha 		lane_to_slot[3] = 7;
213*5b7672fcSPrabhakar Kushwaha 		lane_to_slot[7] = 7;
214*5b7672fcSPrabhakar Kushwaha 		break;
215*5b7672fcSPrabhakar Kushwaha 	case 0x89:
216*5b7672fcSPrabhakar Kushwaha 		lane_to_slot[1] = 7;
217*5b7672fcSPrabhakar Kushwaha 		lane_to_slot[2] = 7;
218*5b7672fcSPrabhakar Kushwaha 		lane_to_slot[3] = 7;
219*5b7672fcSPrabhakar Kushwaha 		lane_to_slot[7] = 7;
220*5b7672fcSPrabhakar Kushwaha 		break;
221*5b7672fcSPrabhakar Kushwaha 	case 0x8d:
222*5b7672fcSPrabhakar Kushwaha 		lane_to_slot[1] = 7;
223*5b7672fcSPrabhakar Kushwaha 		lane_to_slot[2] = 7;
224*5b7672fcSPrabhakar Kushwaha 		lane_to_slot[3] = 7;
225*5b7672fcSPrabhakar Kushwaha 		lane_to_slot[5] = 3;
226*5b7672fcSPrabhakar Kushwaha 		lane_to_slot[6] = 3;
227*5b7672fcSPrabhakar Kushwaha 		lane_to_slot[7] = 3;
228*5b7672fcSPrabhakar Kushwaha 		break;
229*5b7672fcSPrabhakar Kushwaha 	case 0x8F:
230*5b7672fcSPrabhakar Kushwaha 	case 0x85:
231*5b7672fcSPrabhakar Kushwaha 		lane_to_slot[1] = 7;
232*5b7672fcSPrabhakar Kushwaha 		lane_to_slot[2] = 6;
233*5b7672fcSPrabhakar Kushwaha 		lane_to_slot[3] = 5;
234*5b7672fcSPrabhakar Kushwaha 		lane_to_slot[6] = 3;
235*5b7672fcSPrabhakar Kushwaha 		lane_to_slot[7] = 3;
236*5b7672fcSPrabhakar Kushwaha 		break;
237*5b7672fcSPrabhakar Kushwaha 	case 0xA5:
238*5b7672fcSPrabhakar Kushwaha 		lane_to_slot[1] = 7;
239*5b7672fcSPrabhakar Kushwaha 		lane_to_slot[6] = 3;
240*5b7672fcSPrabhakar Kushwaha 		lane_to_slot[7] = 3;
241*5b7672fcSPrabhakar Kushwaha 		break;
242*5b7672fcSPrabhakar Kushwaha 	case 0xA7:
243*5b7672fcSPrabhakar Kushwaha 		lane_to_slot[1] = 7;
244*5b7672fcSPrabhakar Kushwaha 		lane_to_slot[7] = 7;
245*5b7672fcSPrabhakar Kushwaha 		break;
246*5b7672fcSPrabhakar Kushwaha 	case 0xAA:
247*5b7672fcSPrabhakar Kushwaha 		lane_to_slot[1] = 7;
248*5b7672fcSPrabhakar Kushwaha 		lane_to_slot[6] = 7;
249*5b7672fcSPrabhakar Kushwaha 		lane_to_slot[7] = 7;
250*5b7672fcSPrabhakar Kushwaha 		break;
251*5b7672fcSPrabhakar Kushwaha 	case 0x40:
252*5b7672fcSPrabhakar Kushwaha 		lane_to_slot[2] = 7;
253*5b7672fcSPrabhakar Kushwaha 		lane_to_slot[3] = 7;
254*5b7672fcSPrabhakar Kushwaha 		break;
255*5b7672fcSPrabhakar Kushwaha 	default:
256*5b7672fcSPrabhakar Kushwaha 		printf("qds: Fman: Unsupported SerDes Protocol 0x%02x\n",
257*5b7672fcSPrabhakar Kushwaha 		       serdes1_prtcl);
258*5b7672fcSPrabhakar Kushwaha 		break;
259*5b7672fcSPrabhakar Kushwaha 	}
260*5b7672fcSPrabhakar Kushwaha }
261*5b7672fcSPrabhakar Kushwaha 
262*5b7672fcSPrabhakar Kushwaha /*
263*5b7672fcSPrabhakar Kushwaha  * Given the following ...
264*5b7672fcSPrabhakar Kushwaha  *
265*5b7672fcSPrabhakar Kushwaha  * 1) A pointer to an Fman Ethernet node (as identified by the 'compat'
266*5b7672fcSPrabhakar Kushwaha  * compatible string and 'addr' physical address)
267*5b7672fcSPrabhakar Kushwaha  *
268*5b7672fcSPrabhakar Kushwaha  * 2) An Fman port
269*5b7672fcSPrabhakar Kushwaha  *
270*5b7672fcSPrabhakar Kushwaha  * ... update the phy-handle property of the Ethernet node to point to the
271*5b7672fcSPrabhakar Kushwaha  * right PHY. This assumes that we already know the PHY for each port.
272*5b7672fcSPrabhakar Kushwaha  *
273*5b7672fcSPrabhakar Kushwaha  * The offset of the Fman Ethernet node is also passed in for convenience, but
274*5b7672fcSPrabhakar Kushwaha  * it is not used, and we recalculate the offset anyway.
275*5b7672fcSPrabhakar Kushwaha  *
276*5b7672fcSPrabhakar Kushwaha  * Note that what we call "Fman ports" (enum fm_port) is really an Fman MAC.
277*5b7672fcSPrabhakar Kushwaha  * Inside the Fman, "ports" are things that connect to MACs. We only call them
278*5b7672fcSPrabhakar Kushwaha  * ports in U-Boot because on previous Ethernet devices (e.g. Gianfar), MACs
279*5b7672fcSPrabhakar Kushwaha  * and ports are the same thing.
280*5b7672fcSPrabhakar Kushwaha  *
281*5b7672fcSPrabhakar Kushwaha  */
282*5b7672fcSPrabhakar Kushwaha void board_ft_fman_fixup_port(void *fdt, char *compat, phys_addr_t addr,
283*5b7672fcSPrabhakar Kushwaha 			      enum fm_port port, int offset)
284*5b7672fcSPrabhakar Kushwaha {
285*5b7672fcSPrabhakar Kushwaha 	phy_interface_t intf = fm_info_get_enet_if(port);
286*5b7672fcSPrabhakar Kushwaha 	char phy[16];
287*5b7672fcSPrabhakar Kushwaha 
288*5b7672fcSPrabhakar Kushwaha 	/* The RGMII PHY is identified by the MAC connected to it */
289*5b7672fcSPrabhakar Kushwaha 	if (intf == PHY_INTERFACE_MODE_RGMII) {
290*5b7672fcSPrabhakar Kushwaha 		sprintf(phy, "rgmii_phy%u", port == FM1_DTSEC4 ? 1 : 2);
291*5b7672fcSPrabhakar Kushwaha 		fdt_set_phy_handle(fdt, compat, addr, phy);
292*5b7672fcSPrabhakar Kushwaha 	}
293*5b7672fcSPrabhakar Kushwaha 
294*5b7672fcSPrabhakar Kushwaha 	/* The SGMII PHY is identified by the MAC connected to it */
295*5b7672fcSPrabhakar Kushwaha 	if (intf == PHY_INTERFACE_MODE_SGMII) {
296*5b7672fcSPrabhakar Kushwaha 		int lane = serdes_get_first_lane(FSL_SRDS_1, SGMII_FM1_DTSEC1
297*5b7672fcSPrabhakar Kushwaha 						 + port);
298*5b7672fcSPrabhakar Kushwaha 		u8 slot;
299*5b7672fcSPrabhakar Kushwaha 		if (lane < 0)
300*5b7672fcSPrabhakar Kushwaha 			return;
301*5b7672fcSPrabhakar Kushwaha 		slot = lane_to_slot[lane];
302*5b7672fcSPrabhakar Kushwaha 		if (slot) {
303*5b7672fcSPrabhakar Kushwaha 			/* Slot housing a SGMII riser card */
304*5b7672fcSPrabhakar Kushwaha 			sprintf(phy, "phy_s%x_%02x", slot,
305*5b7672fcSPrabhakar Kushwaha 				(fm_info_get_phy_address(port - FM1_DTSEC1)-
306*5b7672fcSPrabhakar Kushwaha 				CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR + 1));
307*5b7672fcSPrabhakar Kushwaha 			fdt_set_phy_handle(fdt, compat, addr, phy);
308*5b7672fcSPrabhakar Kushwaha 		}
309*5b7672fcSPrabhakar Kushwaha 	}
310*5b7672fcSPrabhakar Kushwaha }
311*5b7672fcSPrabhakar Kushwaha 
312*5b7672fcSPrabhakar Kushwaha void fdt_fixup_board_enet(void *fdt)
313*5b7672fcSPrabhakar Kushwaha {
314*5b7672fcSPrabhakar Kushwaha 	int i, lane, idx;
315*5b7672fcSPrabhakar Kushwaha 
316*5b7672fcSPrabhakar Kushwaha 	for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) {
317*5b7672fcSPrabhakar Kushwaha 		idx = i - FM1_DTSEC1;
318*5b7672fcSPrabhakar Kushwaha 		switch (fm_info_get_enet_if(i)) {
319*5b7672fcSPrabhakar Kushwaha 		case PHY_INTERFACE_MODE_SGMII:
320*5b7672fcSPrabhakar Kushwaha 			lane = serdes_get_first_lane(FSL_SRDS_1,
321*5b7672fcSPrabhakar Kushwaha 						     SGMII_FM1_DTSEC1 + idx);
322*5b7672fcSPrabhakar Kushwaha 			if (lane < 0)
323*5b7672fcSPrabhakar Kushwaha 				break;
324*5b7672fcSPrabhakar Kushwaha 
325*5b7672fcSPrabhakar Kushwaha 			switch (mdio_mux[i]) {
326*5b7672fcSPrabhakar Kushwaha 			case EMI1_SLOT3:
327*5b7672fcSPrabhakar Kushwaha 				fdt_status_okay_by_alias(fdt, "emi1_slot3");
328*5b7672fcSPrabhakar Kushwaha 				break;
329*5b7672fcSPrabhakar Kushwaha 			case EMI1_SLOT5:
330*5b7672fcSPrabhakar Kushwaha 				fdt_status_okay_by_alias(fdt, "emi1_slot5");
331*5b7672fcSPrabhakar Kushwaha 				break;
332*5b7672fcSPrabhakar Kushwaha 			case EMI1_SLOT6:
333*5b7672fcSPrabhakar Kushwaha 				fdt_status_okay_by_alias(fdt, "emi1_slot6");
334*5b7672fcSPrabhakar Kushwaha 				break;
335*5b7672fcSPrabhakar Kushwaha 			case EMI1_SLOT7:
336*5b7672fcSPrabhakar Kushwaha 				fdt_status_okay_by_alias(fdt, "emi1_slot7");
337*5b7672fcSPrabhakar Kushwaha 				break;
338*5b7672fcSPrabhakar Kushwaha 			}
339*5b7672fcSPrabhakar Kushwaha 		break;
340*5b7672fcSPrabhakar Kushwaha 		case PHY_INTERFACE_MODE_RGMII:
341*5b7672fcSPrabhakar Kushwaha 			if (i == FM1_DTSEC4)
342*5b7672fcSPrabhakar Kushwaha 				fdt_status_okay_by_alias(fdt, "emi1_rgmii0");
343*5b7672fcSPrabhakar Kushwaha 
344*5b7672fcSPrabhakar Kushwaha 			if (i == FM1_DTSEC5)
345*5b7672fcSPrabhakar Kushwaha 				fdt_status_okay_by_alias(fdt, "emi1_rgmii1");
346*5b7672fcSPrabhakar Kushwaha 			break;
347*5b7672fcSPrabhakar Kushwaha 		default:
348*5b7672fcSPrabhakar Kushwaha 			break;
349*5b7672fcSPrabhakar Kushwaha 		}
350*5b7672fcSPrabhakar Kushwaha 	}
351*5b7672fcSPrabhakar Kushwaha }
352*5b7672fcSPrabhakar Kushwaha #endif /* #ifdef CONFIG_FMAN_ENET */
353*5b7672fcSPrabhakar Kushwaha 
354*5b7672fcSPrabhakar Kushwaha static void set_brdcfg9_for_gtx_clk(void)
355*5b7672fcSPrabhakar Kushwaha {
356*5b7672fcSPrabhakar Kushwaha 	u8 brdcfg9;
357*5b7672fcSPrabhakar Kushwaha 	brdcfg9 = QIXIS_READ(brdcfg[9]);
358*5b7672fcSPrabhakar Kushwaha 	brdcfg9 |= (1 << 5);
359*5b7672fcSPrabhakar Kushwaha 	QIXIS_WRITE(brdcfg[9], brdcfg9);
360*5b7672fcSPrabhakar Kushwaha }
361*5b7672fcSPrabhakar Kushwaha 
362*5b7672fcSPrabhakar Kushwaha void t1040_handle_phy_interface_sgmii(int i)
363*5b7672fcSPrabhakar Kushwaha {
364*5b7672fcSPrabhakar Kushwaha 	int lane, idx, slot;
365*5b7672fcSPrabhakar Kushwaha 	idx = i - FM1_DTSEC1;
366*5b7672fcSPrabhakar Kushwaha 	lane = serdes_get_first_lane(FSL_SRDS_1,
367*5b7672fcSPrabhakar Kushwaha 			SGMII_FM1_DTSEC1 + idx);
368*5b7672fcSPrabhakar Kushwaha 
369*5b7672fcSPrabhakar Kushwaha 	if (lane < 0)
370*5b7672fcSPrabhakar Kushwaha 		return;
371*5b7672fcSPrabhakar Kushwaha 	slot = lane_to_slot[lane];
372*5b7672fcSPrabhakar Kushwaha 
373*5b7672fcSPrabhakar Kushwaha 	switch (slot) {
374*5b7672fcSPrabhakar Kushwaha 	case 1:
375*5b7672fcSPrabhakar Kushwaha 		mdio_mux[i] = EMI1_SLOT1;
376*5b7672fcSPrabhakar Kushwaha 		fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i]));
377*5b7672fcSPrabhakar Kushwaha 		break;
378*5b7672fcSPrabhakar Kushwaha 	case 3:
379*5b7672fcSPrabhakar Kushwaha 		if (FM1_DTSEC4 == i)
380*5b7672fcSPrabhakar Kushwaha 			fm_info_set_phy_address(i, riser_phy_addr[0]);
381*5b7672fcSPrabhakar Kushwaha 		if (FM1_DTSEC5 == i)
382*5b7672fcSPrabhakar Kushwaha 			fm_info_set_phy_address(i, riser_phy_addr[1]);
383*5b7672fcSPrabhakar Kushwaha 
384*5b7672fcSPrabhakar Kushwaha 		mdio_mux[i] = EMI1_SLOT3;
385*5b7672fcSPrabhakar Kushwaha 
386*5b7672fcSPrabhakar Kushwaha 		fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i]));
387*5b7672fcSPrabhakar Kushwaha 		break;
388*5b7672fcSPrabhakar Kushwaha 	case 4:
389*5b7672fcSPrabhakar Kushwaha 		mdio_mux[i] = EMI1_SLOT4;
390*5b7672fcSPrabhakar Kushwaha 		fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i]));
391*5b7672fcSPrabhakar Kushwaha 		break;
392*5b7672fcSPrabhakar Kushwaha 	case 5:
393*5b7672fcSPrabhakar Kushwaha 		/* Slot housing a SGMII riser card? */
394*5b7672fcSPrabhakar Kushwaha 		fm_info_set_phy_address(i, riser_phy_addr[0]);
395*5b7672fcSPrabhakar Kushwaha 		mdio_mux[i] = EMI1_SLOT5;
396*5b7672fcSPrabhakar Kushwaha 		fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i]));
397*5b7672fcSPrabhakar Kushwaha 		break;
398*5b7672fcSPrabhakar Kushwaha 	case 6:
399*5b7672fcSPrabhakar Kushwaha 		/* Slot housing a SGMII riser card? */
400*5b7672fcSPrabhakar Kushwaha 		fm_info_set_phy_address(i, riser_phy_addr[0]);
401*5b7672fcSPrabhakar Kushwaha 		mdio_mux[i] = EMI1_SLOT6;
402*5b7672fcSPrabhakar Kushwaha 		fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i]));
403*5b7672fcSPrabhakar Kushwaha 		break;
404*5b7672fcSPrabhakar Kushwaha 	case 7:
405*5b7672fcSPrabhakar Kushwaha 		if (FM1_DTSEC1 == i)
406*5b7672fcSPrabhakar Kushwaha 			fm_info_set_phy_address(i, riser_phy_addr[0]);
407*5b7672fcSPrabhakar Kushwaha 		if (FM1_DTSEC2 == i)
408*5b7672fcSPrabhakar Kushwaha 			fm_info_set_phy_address(i, riser_phy_addr[1]);
409*5b7672fcSPrabhakar Kushwaha 		if (FM1_DTSEC3 == i)
410*5b7672fcSPrabhakar Kushwaha 			fm_info_set_phy_address(i, riser_phy_addr[2]);
411*5b7672fcSPrabhakar Kushwaha 
412*5b7672fcSPrabhakar Kushwaha 		mdio_mux[i] = EMI1_SLOT7;
413*5b7672fcSPrabhakar Kushwaha 		fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i]));
414*5b7672fcSPrabhakar Kushwaha 		break;
415*5b7672fcSPrabhakar Kushwaha 	default:
416*5b7672fcSPrabhakar Kushwaha 		break;
417*5b7672fcSPrabhakar Kushwaha 	}
418*5b7672fcSPrabhakar Kushwaha 	fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i]));
419*5b7672fcSPrabhakar Kushwaha }
420*5b7672fcSPrabhakar Kushwaha void t1040_handle_phy_interface_rgmii(int i)
421*5b7672fcSPrabhakar Kushwaha {
422*5b7672fcSPrabhakar Kushwaha 	fm_info_set_phy_address(i, i == FM1_DTSEC5 ?
423*5b7672fcSPrabhakar Kushwaha 			CONFIG_SYS_FM1_DTSEC5_PHY_ADDR :
424*5b7672fcSPrabhakar Kushwaha 			CONFIG_SYS_FM1_DTSEC4_PHY_ADDR);
425*5b7672fcSPrabhakar Kushwaha 	mdio_mux[i] = (i == FM1_DTSEC5) ? EMI1_RGMII1 :
426*5b7672fcSPrabhakar Kushwaha 		EMI1_RGMII0;
427*5b7672fcSPrabhakar Kushwaha 	fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i]));
428*5b7672fcSPrabhakar Kushwaha }
429*5b7672fcSPrabhakar Kushwaha 
430*5b7672fcSPrabhakar Kushwaha int board_eth_init(bd_t *bis)
431*5b7672fcSPrabhakar Kushwaha {
432*5b7672fcSPrabhakar Kushwaha #ifdef CONFIG_FMAN_ENET
433*5b7672fcSPrabhakar Kushwaha 	struct memac_mdio_info memac_mdio_info;
434*5b7672fcSPrabhakar Kushwaha 	unsigned int i;
435*5b7672fcSPrabhakar Kushwaha 
436*5b7672fcSPrabhakar Kushwaha 	printf("Initializing Fman\n");
437*5b7672fcSPrabhakar Kushwaha 	set_brdcfg9_for_gtx_clk();
438*5b7672fcSPrabhakar Kushwaha 
439*5b7672fcSPrabhakar Kushwaha 	initialize_lane_to_slot();
440*5b7672fcSPrabhakar Kushwaha 
441*5b7672fcSPrabhakar Kushwaha 	/* Initialize the mdio_mux array so we can recognize empty elements */
442*5b7672fcSPrabhakar Kushwaha 	for (i = 0; i < NUM_FM_PORTS; i++)
443*5b7672fcSPrabhakar Kushwaha 		mdio_mux[i] = EMI_NONE;
444*5b7672fcSPrabhakar Kushwaha 
445*5b7672fcSPrabhakar Kushwaha 	memac_mdio_info.regs =
446*5b7672fcSPrabhakar Kushwaha 		(struct memac_mdio_controller *)CONFIG_SYS_FM1_DTSEC_MDIO_ADDR;
447*5b7672fcSPrabhakar Kushwaha 	memac_mdio_info.name = DEFAULT_FM_MDIO_NAME;
448*5b7672fcSPrabhakar Kushwaha 
449*5b7672fcSPrabhakar Kushwaha 	/* Register the real 1G MDIO bus */
450*5b7672fcSPrabhakar Kushwaha 	fm_memac_mdio_init(bis, &memac_mdio_info);
451*5b7672fcSPrabhakar Kushwaha 
452*5b7672fcSPrabhakar Kushwaha 	/* Register the muxing front-ends to the MDIO buses */
453*5b7672fcSPrabhakar Kushwaha 	t1040_qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_RGMII0);
454*5b7672fcSPrabhakar Kushwaha 	t1040_qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_RGMII1);
455*5b7672fcSPrabhakar Kushwaha 	t1040_qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT1);
456*5b7672fcSPrabhakar Kushwaha 	t1040_qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT3);
457*5b7672fcSPrabhakar Kushwaha 	t1040_qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT4);
458*5b7672fcSPrabhakar Kushwaha 	t1040_qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT5);
459*5b7672fcSPrabhakar Kushwaha 	t1040_qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT6);
460*5b7672fcSPrabhakar Kushwaha 	t1040_qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT7);
461*5b7672fcSPrabhakar Kushwaha 
462*5b7672fcSPrabhakar Kushwaha 	/*
463*5b7672fcSPrabhakar Kushwaha 	 * Program on board RGMII PHY addresses. If the SGMII Riser
464*5b7672fcSPrabhakar Kushwaha 	 * card used, we'll override the PHY address later. For any DTSEC that
465*5b7672fcSPrabhakar Kushwaha 	 * is RGMII, we'll also override its PHY address later. We assume that
466*5b7672fcSPrabhakar Kushwaha 	 * DTSEC4 and DTSEC5 are used for RGMII.
467*5b7672fcSPrabhakar Kushwaha 	 */
468*5b7672fcSPrabhakar Kushwaha 	fm_info_set_phy_address(FM1_DTSEC4, CONFIG_SYS_FM1_DTSEC4_PHY_ADDR);
469*5b7672fcSPrabhakar Kushwaha 	fm_info_set_phy_address(FM1_DTSEC5, CONFIG_SYS_FM1_DTSEC5_PHY_ADDR);
470*5b7672fcSPrabhakar Kushwaha 
471*5b7672fcSPrabhakar Kushwaha 	for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) {
472*5b7672fcSPrabhakar Kushwaha 		switch (fm_info_get_enet_if(i)) {
473*5b7672fcSPrabhakar Kushwaha 		case PHY_INTERFACE_MODE_QSGMII:
474*5b7672fcSPrabhakar Kushwaha 			break;
475*5b7672fcSPrabhakar Kushwaha 		case PHY_INTERFACE_MODE_SGMII:
476*5b7672fcSPrabhakar Kushwaha 			t1040_handle_phy_interface_sgmii(i);
477*5b7672fcSPrabhakar Kushwaha 			break;
478*5b7672fcSPrabhakar Kushwaha 
479*5b7672fcSPrabhakar Kushwaha 		case PHY_INTERFACE_MODE_RGMII:
480*5b7672fcSPrabhakar Kushwaha 			/* Only DTSEC4 and DTSEC5 can be routed to RGMII */
481*5b7672fcSPrabhakar Kushwaha 			t1040_handle_phy_interface_rgmii(i);
482*5b7672fcSPrabhakar Kushwaha 			break;
483*5b7672fcSPrabhakar Kushwaha 		default:
484*5b7672fcSPrabhakar Kushwaha 			break;
485*5b7672fcSPrabhakar Kushwaha 		}
486*5b7672fcSPrabhakar Kushwaha 	}
487*5b7672fcSPrabhakar Kushwaha 
488*5b7672fcSPrabhakar Kushwaha 	cpu_eth_init(bis);
489*5b7672fcSPrabhakar Kushwaha #endif
490*5b7672fcSPrabhakar Kushwaha 
491*5b7672fcSPrabhakar Kushwaha 	return pci_eth_init(bis);
492*5b7672fcSPrabhakar Kushwaha }
493