blob: 5879198e4d34181e43ab3f2ca1838ac839c21b3f [file] [log] [blame]
Shengzhou Liuc4d0e812013-11-22 17:39:11 +08001/*
2 * Copyright 2013 Freescale Semiconductor, Inc.
3 *
4 * Shengzhou Liu <Shengzhou.Liu@freescale.com>
5 *
6 * SPDX-License-Identifier: GPL-2.0+
7 */
8
9#include <common.h>
10#include <command.h>
11#include <netdev.h>
12#include <asm/mmu.h>
13#include <asm/processor.h>
14#include <asm/immap_85xx.h>
15#include <asm/fsl_law.h>
16#include <asm/fsl_serdes.h>
17#include <asm/fsl_portals.h>
18#include <asm/fsl_liodn.h>
19#include <malloc.h>
20#include <fm_eth.h>
21#include <fsl_mdio.h>
22#include <miiphy.h>
23#include <phy.h>
24#include <asm/fsl_dtsec.h>
25#include <asm/fsl_serdes.h>
26#include "../common/qixis.h"
27#include "../common/fman.h"
Shengzhou Liu254887a2014-02-21 13:16:19 +080028#include "t208xqds_qixis.h"
Shengzhou Liuc4d0e812013-11-22 17:39:11 +080029
30#define EMI_NONE 0xFFFFFFFF
31#define EMI1_RGMII1 0
32#define EMI1_RGMII2 1
33#define EMI1_SLOT1 2
Shengzhou Liu254887a2014-02-21 13:16:19 +080034#if defined(CONFIG_T2080QDS)
Shengzhou Liuc4d0e812013-11-22 17:39:11 +080035#define EMI1_SLOT2 6
36#define EMI1_SLOT3 3
37#define EMI1_SLOT4 4
38#define EMI1_SLOT5 5
Shengzhou Liu6b7679c2014-03-06 15:07:39 +080039#define EMI2 7
Shengzhou Liu254887a2014-02-21 13:16:19 +080040#elif defined(CONFIG_T2081QDS)
41#define EMI1_SLOT2 3
42#define EMI1_SLOT3 4
43#define EMI1_SLOT5 5
44#define EMI1_SLOT6 6
45#define EMI1_SLOT7 7
Shengzhou Liu254887a2014-02-21 13:16:19 +080046#define EMI2 8
Shengzhou Liu6b7679c2014-03-06 15:07:39 +080047#endif
Shengzhou Liuc4d0e812013-11-22 17:39:11 +080048
49static int mdio_mux[NUM_FM_PORTS];
50
51static const char * const mdio_names[] = {
Shengzhou Liu254887a2014-02-21 13:16:19 +080052#if defined(CONFIG_T2080QDS)
Shengzhou Liuc4d0e812013-11-22 17:39:11 +080053 "T2080QDS_MDIO_RGMII1",
54 "T2080QDS_MDIO_RGMII2",
55 "T2080QDS_MDIO_SLOT1",
56 "T2080QDS_MDIO_SLOT3",
57 "T2080QDS_MDIO_SLOT4",
58 "T2080QDS_MDIO_SLOT5",
59 "T2080QDS_MDIO_SLOT2",
60 "T2080QDS_MDIO_10GC",
Shengzhou Liu254887a2014-02-21 13:16:19 +080061#elif defined(CONFIG_T2081QDS)
62 "T2081QDS_MDIO_RGMII1",
63 "T2081QDS_MDIO_RGMII2",
64 "T2081QDS_MDIO_SLOT1",
65 "T2081QDS_MDIO_SLOT2",
66 "T2081QDS_MDIO_SLOT3",
67 "T2081QDS_MDIO_SLOT5",
68 "T2081QDS_MDIO_SLOT6",
69 "T2081QDS_MDIO_SLOT7",
70 "T2081QDS_MDIO_10GC",
71#endif
Shengzhou Liuc4d0e812013-11-22 17:39:11 +080072};
73
74/* Map SerDes1 8 lanes to default slot, will be initialized dynamically */
Shengzhou Liu254887a2014-02-21 13:16:19 +080075#if defined(CONFIG_T2080QDS)
Shengzhou Liuc4d0e812013-11-22 17:39:11 +080076static u8 lane_to_slot[] = {3, 3, 3, 3, 1, 1, 1, 1};
Shengzhou Liu254887a2014-02-21 13:16:19 +080077#elif defined(CONFIG_T2081QDS)
78static u8 lane_to_slot[] = {2, 2, 2, 2, 1, 1, 1, 1};
79#endif
Shengzhou Liuc4d0e812013-11-22 17:39:11 +080080
Shengzhou Liu254887a2014-02-21 13:16:19 +080081static const char *t208xqds_mdio_name_for_muxval(u8 muxval)
Shengzhou Liuc4d0e812013-11-22 17:39:11 +080082{
83 return mdio_names[muxval];
84}
85
86struct mii_dev *mii_dev_for_muxval(u8 muxval)
87{
88 struct mii_dev *bus;
Shengzhou Liu254887a2014-02-21 13:16:19 +080089 const char *name = t208xqds_mdio_name_for_muxval(muxval);
Shengzhou Liuc4d0e812013-11-22 17:39:11 +080090
91 if (!name) {
92 printf("No bus for muxval %x\n", muxval);
93 return NULL;
94 }
95
96 bus = miiphy_get_dev_by_name(name);
97
98 if (!bus) {
99 printf("No bus by name %s\n", name);
100 return NULL;
101 }
102
103 return bus;
104}
105
Shengzhou Liu254887a2014-02-21 13:16:19 +0800106struct t208xqds_mdio {
Shengzhou Liuc4d0e812013-11-22 17:39:11 +0800107 u8 muxval;
108 struct mii_dev *realbus;
109};
110
Shengzhou Liu254887a2014-02-21 13:16:19 +0800111static void t208xqds_mux_mdio(u8 muxval)
Shengzhou Liuc4d0e812013-11-22 17:39:11 +0800112{
113 u8 brdcfg4;
Shengzhou Liu254887a2014-02-21 13:16:19 +0800114 if (muxval < 8) {
Shengzhou Liuc4d0e812013-11-22 17:39:11 +0800115 brdcfg4 = QIXIS_READ(brdcfg[4]);
116 brdcfg4 &= ~BRDCFG4_EMISEL_MASK;
117 brdcfg4 |= (muxval << BRDCFG4_EMISEL_SHIFT);
118 QIXIS_WRITE(brdcfg[4], brdcfg4);
119 }
120}
121
Shengzhou Liu254887a2014-02-21 13:16:19 +0800122static int t208xqds_mdio_read(struct mii_dev *bus, int addr, int devad,
Shengzhou Liuc4d0e812013-11-22 17:39:11 +0800123 int regnum)
124{
Shengzhou Liu254887a2014-02-21 13:16:19 +0800125 struct t208xqds_mdio *priv = bus->priv;
Shengzhou Liuc4d0e812013-11-22 17:39:11 +0800126
Shengzhou Liu254887a2014-02-21 13:16:19 +0800127 t208xqds_mux_mdio(priv->muxval);
Shengzhou Liuc4d0e812013-11-22 17:39:11 +0800128
129 return priv->realbus->read(priv->realbus, addr, devad, regnum);
130}
131
Shengzhou Liu254887a2014-02-21 13:16:19 +0800132static int t208xqds_mdio_write(struct mii_dev *bus, int addr, int devad,
Shengzhou Liuc4d0e812013-11-22 17:39:11 +0800133 int regnum, u16 value)
134{
Shengzhou Liu254887a2014-02-21 13:16:19 +0800135 struct t208xqds_mdio *priv = bus->priv;
Shengzhou Liuc4d0e812013-11-22 17:39:11 +0800136
Shengzhou Liu254887a2014-02-21 13:16:19 +0800137 t208xqds_mux_mdio(priv->muxval);
Shengzhou Liuc4d0e812013-11-22 17:39:11 +0800138
139 return priv->realbus->write(priv->realbus, addr, devad, regnum, value);
140}
141
Shengzhou Liu254887a2014-02-21 13:16:19 +0800142static int t208xqds_mdio_reset(struct mii_dev *bus)
Shengzhou Liuc4d0e812013-11-22 17:39:11 +0800143{
Shengzhou Liu254887a2014-02-21 13:16:19 +0800144 struct t208xqds_mdio *priv = bus->priv;
Shengzhou Liuc4d0e812013-11-22 17:39:11 +0800145
146 return priv->realbus->reset(priv->realbus);
147}
148
Shengzhou Liu254887a2014-02-21 13:16:19 +0800149static int t208xqds_mdio_init(char *realbusname, u8 muxval)
Shengzhou Liuc4d0e812013-11-22 17:39:11 +0800150{
Shengzhou Liu254887a2014-02-21 13:16:19 +0800151 struct t208xqds_mdio *pmdio;
Shengzhou Liuc4d0e812013-11-22 17:39:11 +0800152 struct mii_dev *bus = mdio_alloc();
153
154 if (!bus) {
Shengzhou Liu254887a2014-02-21 13:16:19 +0800155 printf("Failed to allocate t208xqds MDIO bus\n");
Shengzhou Liuc4d0e812013-11-22 17:39:11 +0800156 return -1;
157 }
158
159 pmdio = malloc(sizeof(*pmdio));
160 if (!pmdio) {
Shengzhou Liu254887a2014-02-21 13:16:19 +0800161 printf("Failed to allocate t208xqds private data\n");
Shengzhou Liuc4d0e812013-11-22 17:39:11 +0800162 free(bus);
163 return -1;
164 }
165
Shengzhou Liu254887a2014-02-21 13:16:19 +0800166 bus->read = t208xqds_mdio_read;
167 bus->write = t208xqds_mdio_write;
168 bus->reset = t208xqds_mdio_reset;
169 sprintf(bus->name, t208xqds_mdio_name_for_muxval(muxval));
Shengzhou Liuc4d0e812013-11-22 17:39:11 +0800170
171 pmdio->realbus = miiphy_get_dev_by_name(realbusname);
172
173 if (!pmdio->realbus) {
174 printf("No bus with name %s\n", realbusname);
175 free(bus);
176 free(pmdio);
177 return -1;
178 }
179
180 pmdio->muxval = muxval;
181 bus->priv = pmdio;
Shengzhou Liuc4d0e812013-11-22 17:39:11 +0800182 return mdio_register(bus);
183}
184
185void board_ft_fman_fixup_port(void *fdt, char *compat, phys_addr_t addr,
186 enum fm_port port, int offset)
187{
188 int phy;
189 char alias[20];
190 struct fixed_link f_link;
191 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
192 u32 srds_s1 = in_be32(&gur->rcwsr[4]) &
193 FSL_CORENET2_RCWSR4_SRDS1_PRTCL;
194
195 srds_s1 >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;
196
197 if (fm_info_get_enet_if(port) == PHY_INTERFACE_MODE_SGMII) {
198 phy = fm_info_get_phy_address(port);
199 switch (port) {
Shengzhou Liu254887a2014-02-21 13:16:19 +0800200#if defined(CONFIG_T2080QDS)
Shengzhou Liuc4d0e812013-11-22 17:39:11 +0800201 case FM1_DTSEC1:
202 case FM1_DTSEC2:
203 case FM1_DTSEC9:
204 case FM1_DTSEC10:
Shengzhou Liu254887a2014-02-21 13:16:19 +0800205 if (mdio_mux[port] == EMI1_SLOT2) {
206 sprintf(alias, "phy_sgmii_s2_%x", phy);
207 fdt_set_phy_handle(fdt, compat, addr, alias);
208 fdt_status_okay_by_alias(fdt, "emi1_slot2");
209 } else if (mdio_mux[port] == EMI1_SLOT3) {
210 sprintf(alias, "phy_sgmii_s3_%x", phy);
211 fdt_set_phy_handle(fdt, compat, addr, alias);
212 fdt_status_okay_by_alias(fdt, "emi1_slot3");
213 }
Shengzhou Liuc4d0e812013-11-22 17:39:11 +0800214 break;
215 case FM1_DTSEC5:
216 case FM1_DTSEC6:
217 if (mdio_mux[port] == EMI1_SLOT1) {
218 sprintf(alias, "phy_sgmii_s1_%x", phy);
219 fdt_set_phy_handle(fdt, compat, addr, alias);
220 fdt_status_okay_by_alias(fdt, "emi1_slot1");
221 } else if (mdio_mux[port] == EMI1_SLOT2) {
222 sprintf(alias, "phy_sgmii_s2_%x", phy);
223 fdt_set_phy_handle(fdt, compat, addr, alias);
224 fdt_status_okay_by_alias(fdt, "emi1_slot2");
225 }
226 break;
Shengzhou Liu254887a2014-02-21 13:16:19 +0800227#elif defined(CONFIG_T2081QDS)
228 case FM1_DTSEC1:
229 case FM1_DTSEC2:
230 case FM1_DTSEC5:
231 case FM1_DTSEC6:
232 case FM1_DTSEC9:
233 case FM1_DTSEC10:
234 if (mdio_mux[port] == EMI1_SLOT2) {
235 sprintf(alias, "phy_sgmii_s2_%x", phy);
236 fdt_set_phy_handle(fdt, compat, addr, alias);
237 fdt_status_okay_by_alias(fdt, "emi1_slot2");
238 } else if (mdio_mux[port] == EMI1_SLOT3) {
239 sprintf(alias, "phy_sgmii_s3_%x", phy);
240 fdt_set_phy_handle(fdt, compat, addr, alias);
241 fdt_status_okay_by_alias(fdt, "emi1_slot3");
242 } else if (mdio_mux[port] == EMI1_SLOT5) {
243 sprintf(alias, "phy_sgmii_s5_%x", phy);
244 fdt_set_phy_handle(fdt, compat, addr, alias);
245 fdt_status_okay_by_alias(fdt, "emi1_slot5");
246 } else if (mdio_mux[port] == EMI1_SLOT6) {
247 sprintf(alias, "phy_sgmii_s6_%x", phy);
248 fdt_set_phy_handle(fdt, compat, addr, alias);
249 fdt_status_okay_by_alias(fdt, "emi1_slot6");
250 } else if (mdio_mux[port] == EMI1_SLOT7) {
251 sprintf(alias, "phy_sgmii_s7_%x", phy);
252 fdt_set_phy_handle(fdt, compat, addr, alias);
253 fdt_status_okay_by_alias(fdt, "emi1_slot7");
254 }
255 break;
256#endif
Shengzhou Liuc4d0e812013-11-22 17:39:11 +0800257 default:
258 break;
259 }
260
261 } else if (fm_info_get_enet_if(port) == PHY_INTERFACE_MODE_XGMII) {
262 switch (srds_s1) {
263 case 0x66: /* XFI interface */
264 case 0x6b:
265 case 0x6c:
266 case 0x6d:
267 case 0x71:
268 f_link.phy_id = port;
269 f_link.duplex = 1;
270 f_link.link_speed = 10000;
271 f_link.pause = 0;
272 f_link.asym_pause = 0;
273 /* no PHY for XFI */
274 fdt_delprop(fdt, offset, "phy-handle");
275 fdt_setprop(fdt, offset, "fixed-link", &f_link,
276 sizeof(f_link));
277 break;
278 default:
279 break;
280 }
281 }
282}
283
284void fdt_fixup_board_enet(void *fdt)
285{
286 return;
287}
288
289/*
Shengzhou Liu254887a2014-02-21 13:16:19 +0800290 * This function reads RCW to check if Serdes1{A:H} is configured
291 * to slot 1/2/3/4/5/6/7 and update the lane_to_slot[] array accordingly
Shengzhou Liuc4d0e812013-11-22 17:39:11 +0800292 */
293static void initialize_lane_to_slot(void)
294{
295 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
296 u32 srds_s1 = in_be32(&gur->rcwsr[4]) &
297 FSL_CORENET2_RCWSR4_SRDS1_PRTCL;
298
299 srds_s1 >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;
300
301 switch (srds_s1) {
Shengzhou Liu254887a2014-02-21 13:16:19 +0800302#if defined(CONFIG_T2080QDS)
Shengzhou Liuc4d0e812013-11-22 17:39:11 +0800303 case 0x51:
304 case 0x5f:
305 case 0x65:
306 case 0x6b:
307 case 0x71:
308 lane_to_slot[5] = 2;
309 lane_to_slot[6] = 2;
310 lane_to_slot[7] = 2;
311 break;
312 case 0xa6:
313 case 0x8e:
314 case 0x8f:
315 case 0x82:
316 case 0x83:
317 case 0xd3:
318 case 0xd9:
319 case 0xcb:
320 lane_to_slot[6] = 2;
321 lane_to_slot[7] = 2;
322 break;
323 case 0xda:
324 lane_to_slot[4] = 3;
325 lane_to_slot[5] = 3;
326 lane_to_slot[6] = 3;
327 lane_to_slot[7] = 3;
328 break;
Shengzhou Liu254887a2014-02-21 13:16:19 +0800329#elif defined(CONFIG_T2081QDS)
330 case 0x6b:
331 lane_to_slot[4] = 1;
332 lane_to_slot[5] = 3;
333 lane_to_slot[6] = 3;
334 lane_to_slot[7] = 3;
335 break;
336 case 0xca:
337 case 0xcb:
338 lane_to_slot[1] = 7;
339 lane_to_slot[2] = 6;
340 lane_to_slot[3] = 5;
341 lane_to_slot[5] = 3;
342 lane_to_slot[6] = 3;
343 lane_to_slot[7] = 3;
344 break;
345 case 0xf2:
346 lane_to_slot[1] = 7;
347 lane_to_slot[2] = 7;
348 lane_to_slot[3] = 7;
349 lane_to_slot[5] = 4;
350 lane_to_slot[6] = 3;
351 lane_to_slot[7] = 7;
352 break;
353#endif
Shengzhou Liuc4d0e812013-11-22 17:39:11 +0800354 default:
355 break;
356 }
357}
358
359int board_eth_init(bd_t *bis)
360{
361#if defined(CONFIG_FMAN_ENET)
362 int i, idx, lane, slot, interface;
363 struct memac_mdio_info dtsec_mdio_info;
364 struct memac_mdio_info tgec_mdio_info;
365 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
366 u32 rcwsr13 = in_be32(&gur->rcwsr[13]);
367 u32 srds_s1;
368
369 srds_s1 = in_be32(&gur->rcwsr[4]) &
370 FSL_CORENET2_RCWSR4_SRDS1_PRTCL;
371 srds_s1 >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;
372
373 initialize_lane_to_slot();
374
375 /* Initialize the mdio_mux array so we can recognize empty elements */
376 for (i = 0; i < NUM_FM_PORTS; i++)
377 mdio_mux[i] = EMI_NONE;
378
379 dtsec_mdio_info.regs =
380 (struct memac_mdio_controller *)CONFIG_SYS_FM1_DTSEC_MDIO_ADDR;
381
382 dtsec_mdio_info.name = DEFAULT_FM_MDIO_NAME;
383
384 /* Register the 1G MDIO bus */
385 fm_memac_mdio_init(bis, &dtsec_mdio_info);
386
387 tgec_mdio_info.regs =
388 (struct memac_mdio_controller *)CONFIG_SYS_FM1_TGEC_MDIO_ADDR;
389 tgec_mdio_info.name = DEFAULT_FM_TGEC_MDIO_NAME;
390
391 /* Register the 10G MDIO bus */
392 fm_memac_mdio_init(bis, &tgec_mdio_info);
393
394 /* Register the muxing front-ends to the MDIO buses */
Shengzhou Liu254887a2014-02-21 13:16:19 +0800395 t208xqds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_RGMII1);
396 t208xqds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_RGMII2);
397 t208xqds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT1);
398 t208xqds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT2);
399 t208xqds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT3);
400#if defined(CONFIG_T2080QDS)
401 t208xqds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT4);
402#endif
403 t208xqds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT5);
404#if defined(CONFIG_T2081QDS)
405 t208xqds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT6);
406 t208xqds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT7);
407#endif
408 t208xqds_mdio_init(DEFAULT_FM_TGEC_MDIO_NAME, EMI2);
Shengzhou Liuc4d0e812013-11-22 17:39:11 +0800409
410 /* Set the two on-board RGMII PHY address */
411 fm_info_set_phy_address(FM1_DTSEC3, RGMII_PHY1_ADDR);
412 if ((rcwsr13 & FSL_CORENET_RCWSR13_EC2) ==
413 FSL_CORENET_RCWSR13_EC2_DTSEC4_RGMII)
414 fm_info_set_phy_address(FM1_DTSEC4, RGMII_PHY2_ADDR);
415 else
416 fm_info_set_phy_address(FM1_DTSEC10, RGMII_PHY2_ADDR);
417
418 switch (srds_s1) {
Shengzhou Liu9752eb62014-05-15 19:24:11 +0800419 case 0x1b:
Shengzhou Liuc4d0e812013-11-22 17:39:11 +0800420 case 0x1c:
421 case 0x95:
422 case 0xa2:
423 case 0x94:
Shengzhou Liu254887a2014-02-21 13:16:19 +0800424 /* T2080QDS: SGMII in Slot3; T2081QDS: SGMII in Slot2 */
Shengzhou Liuc4d0e812013-11-22 17:39:11 +0800425 fm_info_set_phy_address(FM1_DTSEC9, SGMII_CARD_PORT1_PHY_ADDR);
426 fm_info_set_phy_address(FM1_DTSEC10, SGMII_CARD_PORT2_PHY_ADDR);
427 fm_info_set_phy_address(FM1_DTSEC1, SGMII_CARD_PORT3_PHY_ADDR);
428 fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_PORT4_PHY_ADDR);
Shengzhou Liu254887a2014-02-21 13:16:19 +0800429 /* T2080QDS: SGMII in Slot2; T2081QDS: SGMII in Slot1 */
Shengzhou Liuc4d0e812013-11-22 17:39:11 +0800430 fm_info_set_phy_address(FM1_DTSEC5, SGMII_CARD_PORT3_PHY_ADDR);
431 fm_info_set_phy_address(FM1_DTSEC6, SGMII_CARD_PORT4_PHY_ADDR);
432 break;
Shengzhou Liu9752eb62014-05-15 19:24:11 +0800433 case 0x50:
Shengzhou Liuc4d0e812013-11-22 17:39:11 +0800434 case 0x51:
Shengzhou Liu9752eb62014-05-15 19:24:11 +0800435 case 0x5e:
Shengzhou Liuc4d0e812013-11-22 17:39:11 +0800436 case 0x5f:
Shengzhou Liu9752eb62014-05-15 19:24:11 +0800437 case 0x64:
Shengzhou Liuc4d0e812013-11-22 17:39:11 +0800438 case 0x65:
Shengzhou Liu254887a2014-02-21 13:16:19 +0800439 /* T2080QDS: XAUI/HiGig in Slot3; T2081QDS: in Slot2 */
Shengzhou Liuc4d0e812013-11-22 17:39:11 +0800440 fm_info_set_phy_address(FM1_10GEC1, FM1_10GEC1_PHY_ADDR);
Shengzhou Liu254887a2014-02-21 13:16:19 +0800441 /* T2080QDS: SGMII in Slot2; T2081QDS: in Slot3 */
Shengzhou Liuc4d0e812013-11-22 17:39:11 +0800442 fm_info_set_phy_address(FM1_DTSEC5, SGMII_CARD_PORT3_PHY_ADDR);
443 fm_info_set_phy_address(FM1_DTSEC6, SGMII_CARD_PORT4_PHY_ADDR);
444 break;
445 case 0x66:
Shengzhou Liu9752eb62014-05-15 19:24:11 +0800446 case 0x67:
Shengzhou Liuc4d0e812013-11-22 17:39:11 +0800447 /*
448 * XFI does not need a PHY to work, but to avoid U-boot use
449 * default PHY address which is zero to a MAC when it found
450 * a MAC has no PHY address, we give a PHY address to XFI
451 * MAC, and should not use a real XAUI PHY address, since
452 * MDIO can access it successfully, and then MDIO thinks
453 * the XAUI card is used for the XFI MAC, which will cause
454 * error.
455 */
456 fm_info_set_phy_address(FM1_10GEC1, 4);
457 fm_info_set_phy_address(FM1_10GEC2, 5);
458 fm_info_set_phy_address(FM1_10GEC3, 6);
459 fm_info_set_phy_address(FM1_10GEC4, 7);
460 break;
Shengzhou Liu9752eb62014-05-15 19:24:11 +0800461 case 0x6a:
Shengzhou Liuc4d0e812013-11-22 17:39:11 +0800462 case 0x6b:
463 fm_info_set_phy_address(FM1_10GEC1, 4);
464 fm_info_set_phy_address(FM1_10GEC2, 5);
465 fm_info_set_phy_address(FM1_10GEC3, 6);
466 fm_info_set_phy_address(FM1_10GEC4, 7);
Shengzhou Liu254887a2014-02-21 13:16:19 +0800467 /* T2080QDS: SGMII in Slot2; T2081QDS: in Slot3 */
Shengzhou Liuc4d0e812013-11-22 17:39:11 +0800468 fm_info_set_phy_address(FM1_DTSEC5, SGMII_CARD_PORT3_PHY_ADDR);
469 fm_info_set_phy_address(FM1_DTSEC6, SGMII_CARD_PORT2_PHY_ADDR);
470 break;
471 case 0x6c:
472 case 0x6d:
Shengzhou Liu1576b552014-01-03 14:48:44 +0800473 fm_info_set_phy_address(FM1_10GEC1, 4);
474 fm_info_set_phy_address(FM1_10GEC2, 5);
Shengzhou Liu254887a2014-02-21 13:16:19 +0800475 /* T2080QDS: SGMII in Slot3; T2081QDS: in Slot2 */
Shengzhou Liuc4d0e812013-11-22 17:39:11 +0800476 fm_info_set_phy_address(FM1_DTSEC1, SGMII_CARD_PORT3_PHY_ADDR);
Shengzhou Liu1576b552014-01-03 14:48:44 +0800477 fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_PORT4_PHY_ADDR);
Shengzhou Liuc4d0e812013-11-22 17:39:11 +0800478 break;
Shengzhou Liu9752eb62014-05-15 19:24:11 +0800479 case 0x70:
Shengzhou Liuc4d0e812013-11-22 17:39:11 +0800480 case 0x71:
481 /* SGMII in Slot3 */
482 fm_info_set_phy_address(FM1_DTSEC1, SGMII_CARD_PORT3_PHY_ADDR);
483 fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_PORT4_PHY_ADDR);
484 /* SGMII in Slot2 */
485 fm_info_set_phy_address(FM1_DTSEC5, SGMII_CARD_PORT3_PHY_ADDR);
486 fm_info_set_phy_address(FM1_DTSEC6, SGMII_CARD_PORT2_PHY_ADDR);
487 break;
488 case 0xa6:
489 case 0x8e:
490 case 0x8f:
491 case 0x82:
492 case 0x83:
493 /* SGMII in Slot3 */
494 fm_info_set_phy_address(FM1_DTSEC9, SGMII_CARD_PORT1_PHY_ADDR);
495 fm_info_set_phy_address(FM1_DTSEC10, SGMII_CARD_PORT2_PHY_ADDR);
496 fm_info_set_phy_address(FM1_DTSEC1, SGMII_CARD_PORT3_PHY_ADDR);
497 fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_PORT4_PHY_ADDR);
498 /* SGMII in Slot2 */
499 fm_info_set_phy_address(FM1_DTSEC5, SGMII_CARD_PORT3_PHY_ADDR);
500 fm_info_set_phy_address(FM1_DTSEC6, SGMII_CARD_PORT2_PHY_ADDR);
501 break;
502 case 0xa4:
503 case 0x96:
504 case 0x8a:
505 /* SGMII in Slot3 */
506 fm_info_set_phy_address(FM1_DTSEC9, SGMII_CARD_PORT1_PHY_ADDR);
507 fm_info_set_phy_address(FM1_DTSEC10, SGMII_CARD_PORT2_PHY_ADDR);
508 fm_info_set_phy_address(FM1_DTSEC1, SGMII_CARD_PORT3_PHY_ADDR);
509 fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_PORT4_PHY_ADDR);
510 break;
Shengzhou Liu254887a2014-02-21 13:16:19 +0800511#if defined(CONFIG_T2080QDS)
Shengzhou Liuc4d0e812013-11-22 17:39:11 +0800512 case 0xd9:
513 case 0xd3:
514 case 0xcb:
515 /* SGMII in Slot3 */
516 fm_info_set_phy_address(FM1_DTSEC10, SGMII_CARD_PORT2_PHY_ADDR);
517 fm_info_set_phy_address(FM1_DTSEC1, SGMII_CARD_PORT3_PHY_ADDR);
518 fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_PORT4_PHY_ADDR);
519 /* SGMII in Slot2 */
520 fm_info_set_phy_address(FM1_DTSEC5, SGMII_CARD_PORT3_PHY_ADDR);
521 fm_info_set_phy_address(FM1_DTSEC6, SGMII_CARD_PORT2_PHY_ADDR);
522 break;
Shengzhou Liu254887a2014-02-21 13:16:19 +0800523#elif defined(CONFIG_T2081QDS)
524 case 0xca:
525 case 0xcb:
526 /* SGMII in Slot3 */
527 fm_info_set_phy_address(FM1_DTSEC5, SGMII_CARD_PORT1_PHY_ADDR);
528 fm_info_set_phy_address(FM1_DTSEC6, SGMII_CARD_PORT2_PHY_ADDR);
529 /* SGMII in Slot5 */
530 fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_PORT1_PHY_ADDR);
531 /* SGMII in Slot6 */
532 fm_info_set_phy_address(FM1_DTSEC1, SGMII_CARD_PORT1_PHY_ADDR);
533 /* SGMII in Slot7 */
534 fm_info_set_phy_address(FM1_DTSEC10, SGMII_CARD_PORT3_PHY_ADDR);
535 break;
536#endif
537 case 0xf2:
538 /* T2080QDS: SGMII in Slot3; T2081QDS: SGMII in Slot7 */
539 fm_info_set_phy_address(FM1_DTSEC1, SGMII_CARD_PORT1_PHY_ADDR);
540 fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_PORT2_PHY_ADDR);
541 fm_info_set_phy_address(FM1_DTSEC10, SGMII_CARD_PORT3_PHY_ADDR);
542 fm_info_set_phy_address(FM1_DTSEC6, SGMII_CARD_PORT4_PHY_ADDR);
543 break;
Shengzhou Liuc4d0e812013-11-22 17:39:11 +0800544 default:
Shengzhou Liuc4d0e812013-11-22 17:39:11 +0800545 break;
546 }
547
548 for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) {
549 idx = i - FM1_DTSEC1;
550 interface = fm_info_get_enet_if(i);
551 switch (interface) {
552 case PHY_INTERFACE_MODE_SGMII:
553 lane = serdes_get_first_lane(FSL_SRDS_1,
554 SGMII_FM1_DTSEC1 + idx);
555 if (lane < 0)
556 break;
557 slot = lane_to_slot[lane];
558 debug("FM1@DTSEC%u expects SGMII in slot %u\n",
559 idx + 1, slot);
560 if (QIXIS_READ(present2) & (1 << (slot - 1)))
561 fm_disable_port(i);
562
563 switch (slot) {
564 case 1:
565 mdio_mux[i] = EMI1_SLOT1;
566 fm_info_set_mdio(i, mii_dev_for_muxval(
567 mdio_mux[i]));
568 break;
569 case 2:
570 mdio_mux[i] = EMI1_SLOT2;
571 fm_info_set_mdio(i, mii_dev_for_muxval(
572 mdio_mux[i]));
573 break;
Shengzhou Liu1576b552014-01-03 14:48:44 +0800574 case 3:
575 mdio_mux[i] = EMI1_SLOT3;
576 fm_info_set_mdio(i, mii_dev_for_muxval(
Shengzhou Liu254887a2014-02-21 13:16:19 +0800577 mdio_mux[i]));
Shengzhou Liu1576b552014-01-03 14:48:44 +0800578 break;
Shengzhou Liu254887a2014-02-21 13:16:19 +0800579#if defined(CONFIG_T2081QDS)
580 case 5:
581 mdio_mux[i] = EMI1_SLOT5;
582 fm_info_set_mdio(i, mii_dev_for_muxval(
583 mdio_mux[i]));
584 break;
585 case 6:
586 mdio_mux[i] = EMI1_SLOT6;
587 fm_info_set_mdio(i, mii_dev_for_muxval(
588 mdio_mux[i]));
589 break;
590 case 7:
591 mdio_mux[i] = EMI1_SLOT7;
592 fm_info_set_mdio(i, mii_dev_for_muxval(
593 mdio_mux[i]));
594 break;
595#endif
Shengzhou Liu1576b552014-01-03 14:48:44 +0800596 }
Shengzhou Liuc4d0e812013-11-22 17:39:11 +0800597 break;
598 case PHY_INTERFACE_MODE_RGMII:
599 if (i == FM1_DTSEC3)
600 mdio_mux[i] = EMI1_RGMII1;
601 else if (i == FM1_DTSEC4 || FM1_DTSEC10)
602 mdio_mux[i] = EMI1_RGMII2;
603 fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i]));
604 break;
605 default:
606 break;
607 }
608 }
609
610 for (i = FM1_10GEC1; i < FM1_10GEC1 + CONFIG_SYS_NUM_FM1_10GEC; i++) {
611 idx = i - FM1_10GEC1;
612 switch (fm_info_get_enet_if(i)) {
613 case PHY_INTERFACE_MODE_XGMII:
614 if (srds_s1 == 0x51) {
615 lane = serdes_get_first_lane(FSL_SRDS_1,
616 XAUI_FM1_MAC9 + idx);
617 } else if ((srds_s1 == 0x5f) || (srds_s1 == 0x65)) {
618 lane = serdes_get_first_lane(FSL_SRDS_1,
619 HIGIG_FM1_MAC9 + idx);
620 } else {
621 if (i == FM1_10GEC1 || i == FM1_10GEC2)
622 lane = serdes_get_first_lane(FSL_SRDS_1,
623 XFI_FM1_MAC9 + idx);
624 else
625 lane = serdes_get_first_lane(FSL_SRDS_1,
626 XFI_FM1_MAC1 + idx);
627 }
628
629 if (lane < 0)
630 break;
631 mdio_mux[i] = EMI2;
632 fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i]));
633
634 if ((srds_s1 == 0x66) || (srds_s1 == 0x6b) ||
Shengzhou Liu9752eb62014-05-15 19:24:11 +0800635 (srds_s1 == 0x6a) || (srds_s1 == 0x70) ||
Shengzhou Liuc4d0e812013-11-22 17:39:11 +0800636 (srds_s1 == 0x6c) || (srds_s1 == 0x6d) ||
637 (srds_s1 == 0x71)) {
638 /* As XFI is in cage intead of a slot, so
639 * ensure doesn't disable the corresponding port
640 */
641 break;
642 }
643
644 slot = lane_to_slot[lane];
645 if (QIXIS_READ(present2) & (1 << (slot - 1)))
646 fm_disable_port(i);
647 break;
648 default:
649 break;
650 }
651 }
652
653 cpu_eth_init(bis);
654#endif /* CONFIG_FMAN_ENET */
655
656 return pci_eth_init(bis);
657}