2 * Copyright 2013 Freescale Semiconductor, Inc.
4 * Shengzhou Liu <Shengzhou.Liu@freescale.com>
6 * SPDX-License-Identifier: GPL-2.0+
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>
24 #include <asm/fsl_dtsec.h>
25 #include <asm/fsl_serdes.h>
26 #include "../common/qixis.h"
27 #include "../common/fman.h"
28 #include "t208xqds_qixis.h"
30 #define EMI_NONE 0xFFFFFFFF
34 #if defined(CONFIG_T2080QDS)
40 #elif defined(CONFIG_T2081QDS)
49 static int mdio_mux[NUM_FM_PORTS];
51 static const char * const mdio_names[] = {
52 #if defined(CONFIG_T2080QDS)
53 "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",
61 #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",
74 /* Map SerDes1 8 lanes to default slot, will be initialized dynamically */
75 #if defined(CONFIG_T2080QDS)
76 static u8 lane_to_slot[] = {3, 3, 3, 3, 1, 1, 1, 1};
77 #elif defined(CONFIG_T2081QDS)
78 static u8 lane_to_slot[] = {2, 2, 2, 2, 1, 1, 1, 1};
81 static const char *t208xqds_mdio_name_for_muxval(u8 muxval)
83 return mdio_names[muxval];
86 struct mii_dev *mii_dev_for_muxval(u8 muxval)
89 const char *name = t208xqds_mdio_name_for_muxval(muxval);
92 printf("No bus for muxval %x\n", muxval);
96 bus = miiphy_get_dev_by_name(name);
99 printf("No bus by name %s\n", name);
106 struct t208xqds_mdio {
108 struct mii_dev *realbus;
111 static void t208xqds_mux_mdio(u8 muxval)
115 brdcfg4 = QIXIS_READ(brdcfg[4]);
116 brdcfg4 &= ~BRDCFG4_EMISEL_MASK;
117 brdcfg4 |= (muxval << BRDCFG4_EMISEL_SHIFT);
118 QIXIS_WRITE(brdcfg[4], brdcfg4);
122 static int t208xqds_mdio_read(struct mii_dev *bus, int addr, int devad,
125 struct t208xqds_mdio *priv = bus->priv;
127 t208xqds_mux_mdio(priv->muxval);
129 return priv->realbus->read(priv->realbus, addr, devad, regnum);
132 static int t208xqds_mdio_write(struct mii_dev *bus, int addr, int devad,
133 int regnum, u16 value)
135 struct t208xqds_mdio *priv = bus->priv;
137 t208xqds_mux_mdio(priv->muxval);
139 return priv->realbus->write(priv->realbus, addr, devad, regnum, value);
142 static int t208xqds_mdio_reset(struct mii_dev *bus)
144 struct t208xqds_mdio *priv = bus->priv;
146 return priv->realbus->reset(priv->realbus);
149 static int t208xqds_mdio_init(char *realbusname, u8 muxval)
151 struct t208xqds_mdio *pmdio;
152 struct mii_dev *bus = mdio_alloc();
155 printf("Failed to allocate t208xqds MDIO bus\n");
159 pmdio = malloc(sizeof(*pmdio));
161 printf("Failed to allocate t208xqds private data\n");
166 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));
171 pmdio->realbus = miiphy_get_dev_by_name(realbusname);
173 if (!pmdio->realbus) {
174 printf("No bus with name %s\n", realbusname);
180 pmdio->muxval = muxval;
182 return mdio_register(bus);
185 void board_ft_fman_fixup_port(void *fdt, char *compat, phys_addr_t addr,
186 enum fm_port port, int offset)
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;
195 srds_s1 >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;
197 if (fm_info_get_enet_if(port) == PHY_INTERFACE_MODE_SGMII) {
198 phy = fm_info_get_phy_address(port);
200 #if defined(CONFIG_T2080QDS)
205 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");
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");
227 #elif defined(CONFIG_T2081QDS)
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");
261 } else if (fm_info_get_enet_if(port) == PHY_INTERFACE_MODE_XGMII) {
263 case 0x66: /* XFI interface */
268 f_link.phy_id = port;
270 f_link.link_speed = 10000;
272 f_link.asym_pause = 0;
274 fdt_delprop(fdt, offset, "phy-handle");
275 fdt_setprop(fdt, offset, "fixed-link", &f_link,
284 void fdt_fixup_board_enet(void *fdt)
290 * 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
293 static void initialize_lane_to_slot(void)
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;
299 srds_s1 >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;
302 #if defined(CONFIG_T2080QDS)
329 #elif defined(CONFIG_T2081QDS)
359 int board_eth_init(bd_t *bis)
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]);
369 srds_s1 = in_be32(&gur->rcwsr[4]) &
370 FSL_CORENET2_RCWSR4_SRDS1_PRTCL;
371 srds_s1 >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;
373 initialize_lane_to_slot();
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;
379 dtsec_mdio_info.regs =
380 (struct memac_mdio_controller *)CONFIG_SYS_FM1_DTSEC_MDIO_ADDR;
382 dtsec_mdio_info.name = DEFAULT_FM_MDIO_NAME;
384 /* Register the 1G MDIO bus */
385 fm_memac_mdio_init(bis, &dtsec_mdio_info);
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;
391 /* Register the 10G MDIO bus */
392 fm_memac_mdio_init(bis, &tgec_mdio_info);
394 /* Register the muxing front-ends to the MDIO buses */
395 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);
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);
408 t208xqds_mdio_init(DEFAULT_FM_TGEC_MDIO_NAME, EMI2);
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);
416 fm_info_set_phy_address(FM1_DTSEC10, RGMII_PHY2_ADDR);
424 /* T2080QDS: SGMII in Slot3; T2081QDS: SGMII in Slot2 */
425 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);
429 /* T2080QDS: SGMII in Slot2; T2081QDS: SGMII in Slot1 */
430 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);
439 /* T2080QDS: XAUI/HiGig in Slot3; T2081QDS: in Slot2 */
440 fm_info_set_phy_address(FM1_10GEC1, FM1_10GEC1_PHY_ADDR);
441 /* T2080QDS: SGMII in Slot2; T2081QDS: in Slot3 */
442 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);
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
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);
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);
467 /* T2080QDS: SGMII in Slot2; T2081QDS: in Slot3 */
468 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);
473 fm_info_set_phy_address(FM1_10GEC1, 4);
474 fm_info_set_phy_address(FM1_10GEC2, 5);
475 /* T2080QDS: SGMII in Slot3; T2081QDS: in Slot2 */
476 fm_info_set_phy_address(FM1_DTSEC1, SGMII_CARD_PORT3_PHY_ADDR);
477 fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_PORT4_PHY_ADDR);
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);
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);
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);
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);
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);
511 #if defined(CONFIG_T2080QDS)
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);
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);
523 #elif defined(CONFIG_T2081QDS)
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);
530 fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_PORT1_PHY_ADDR);
532 fm_info_set_phy_address(FM1_DTSEC1, SGMII_CARD_PORT1_PHY_ADDR);
534 fm_info_set_phy_address(FM1_DTSEC10, SGMII_CARD_PORT3_PHY_ADDR);
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);
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);
552 case PHY_INTERFACE_MODE_SGMII:
553 lane = serdes_get_first_lane(FSL_SRDS_1,
554 SGMII_FM1_DTSEC1 + idx);
557 slot = lane_to_slot[lane];
558 debug("FM1@DTSEC%u expects SGMII in slot %u\n",
560 if (QIXIS_READ(present2) & (1 << (slot - 1)))
565 mdio_mux[i] = EMI1_SLOT1;
566 fm_info_set_mdio(i, mii_dev_for_muxval(
570 mdio_mux[i] = EMI1_SLOT2;
571 fm_info_set_mdio(i, mii_dev_for_muxval(
575 mdio_mux[i] = EMI1_SLOT3;
576 fm_info_set_mdio(i, mii_dev_for_muxval(
579 #if defined(CONFIG_T2081QDS)
581 mdio_mux[i] = EMI1_SLOT5;
582 fm_info_set_mdio(i, mii_dev_for_muxval(
586 mdio_mux[i] = EMI1_SLOT6;
587 fm_info_set_mdio(i, mii_dev_for_muxval(
591 mdio_mux[i] = EMI1_SLOT7;
592 fm_info_set_mdio(i, mii_dev_for_muxval(
598 case PHY_INTERFACE_MODE_RGMII:
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]));
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);
621 if (i == FM1_10GEC1 || i == FM1_10GEC2)
622 lane = serdes_get_first_lane(FSL_SRDS_1,
625 lane = serdes_get_first_lane(FSL_SRDS_1,
632 fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i]));
634 if ((srds_s1 == 0x66) || (srds_s1 == 0x6b) ||
635 (srds_s1 == 0x6a) || (srds_s1 == 0x70) ||
636 (srds_s1 == 0x6c) || (srds_s1 == 0x6d) ||
638 /* As XFI is in cage intead of a slot, so
639 * ensure doesn't disable the corresponding port
644 slot = lane_to_slot[lane];
645 if (QIXIS_READ(present2) & (1 << (slot - 1)))
654 #endif /* CONFIG_FMAN_ENET */
656 return pci_eth_init(bis);