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