15b7672fcSPrabhakar Kushwaha /* 25b7672fcSPrabhakar Kushwaha * Copyright 2013 Freescale Semiconductor, Inc. 35b7672fcSPrabhakar Kushwaha * 45b7672fcSPrabhakar Kushwaha * SPDX-License-Identifier: GPL-2.0+ 55b7672fcSPrabhakar Kushwaha */ 65b7672fcSPrabhakar Kushwaha 75b7672fcSPrabhakar Kushwaha /* 85b7672fcSPrabhakar Kushwaha * The RGMII PHYs are provided by the two on-board PHY connected to 95b7672fcSPrabhakar Kushwaha * dTSEC instances 4 and 5. The SGMII PHYs are provided by one on-board 105b7672fcSPrabhakar Kushwaha * PHY or by the standard four-port SGMII riser card (VSC). 115b7672fcSPrabhakar Kushwaha */ 125b7672fcSPrabhakar Kushwaha 135b7672fcSPrabhakar Kushwaha #include <common.h> 145b7672fcSPrabhakar Kushwaha #include <netdev.h> 155b7672fcSPrabhakar Kushwaha #include <asm/fsl_serdes.h> 165b7672fcSPrabhakar Kushwaha #include <asm/immap_85xx.h> 175b7672fcSPrabhakar Kushwaha #include <fm_eth.h> 185b7672fcSPrabhakar Kushwaha #include <fsl_mdio.h> 195b7672fcSPrabhakar Kushwaha #include <malloc.h> 205b7672fcSPrabhakar Kushwaha #include <asm/fsl_dtsec.h> 21*a83fccc2SCodrin Ciubotariu #include <vsc9953.h> 225b7672fcSPrabhakar Kushwaha 235b7672fcSPrabhakar Kushwaha #include "../common/fman.h" 245b7672fcSPrabhakar Kushwaha #include "../common/qixis.h" 255b7672fcSPrabhakar Kushwaha 265b7672fcSPrabhakar Kushwaha #include "t1040qds_qixis.h" 275b7672fcSPrabhakar Kushwaha 285b7672fcSPrabhakar Kushwaha #ifdef CONFIG_FMAN_ENET 295b7672fcSPrabhakar Kushwaha /* - In T1040 there are only 8 SERDES lanes, spread across 2 SERDES banks. 305b7672fcSPrabhakar Kushwaha * Bank 1 -> Lanes A, B, C, D 315b7672fcSPrabhakar Kushwaha * Bank 2 -> Lanes E, F, G, H 325b7672fcSPrabhakar Kushwaha */ 335b7672fcSPrabhakar Kushwaha 345b7672fcSPrabhakar Kushwaha /* Mapping of 8 SERDES lanes to T1040 QDS board slots. A value of '0' here 355b7672fcSPrabhakar Kushwaha * means that the mapping must be determined dynamically, or that the lane 365b7672fcSPrabhakar Kushwaha * maps to something other than a board slot. 375b7672fcSPrabhakar Kushwaha */ 385b7672fcSPrabhakar Kushwaha static u8 lane_to_slot[] = { 395b7672fcSPrabhakar Kushwaha 0, 0, 0, 0, 0, 0, 0, 0 405b7672fcSPrabhakar Kushwaha }; 415b7672fcSPrabhakar Kushwaha 425b7672fcSPrabhakar Kushwaha /* On the Vitesse VSC8234XHG SGMII riser card there are 4 SGMII PHYs 435b7672fcSPrabhakar Kushwaha * housed. 445b7672fcSPrabhakar Kushwaha */ 455b7672fcSPrabhakar Kushwaha static int riser_phy_addr[] = { 465b7672fcSPrabhakar Kushwaha CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR, 475b7672fcSPrabhakar Kushwaha CONFIG_SYS_FM1_DTSEC2_RISER_PHY_ADDR, 485b7672fcSPrabhakar Kushwaha CONFIG_SYS_FM1_DTSEC3_RISER_PHY_ADDR, 495b7672fcSPrabhakar Kushwaha CONFIG_SYS_FM1_DTSEC4_RISER_PHY_ADDR, 505b7672fcSPrabhakar Kushwaha }; 515b7672fcSPrabhakar Kushwaha 525b7672fcSPrabhakar Kushwaha /* Slot2 does not have EMI connections */ 535b7672fcSPrabhakar Kushwaha #define EMI_NONE 0xFFFFFFFF 545b7672fcSPrabhakar Kushwaha #define EMI1_RGMII0 0 555b7672fcSPrabhakar Kushwaha #define EMI1_RGMII1 1 565b7672fcSPrabhakar Kushwaha #define EMI1_SLOT1 2 575b7672fcSPrabhakar Kushwaha #define EMI1_SLOT3 3 585b7672fcSPrabhakar Kushwaha #define EMI1_SLOT4 4 595b7672fcSPrabhakar Kushwaha #define EMI1_SLOT5 5 605b7672fcSPrabhakar Kushwaha #define EMI1_SLOT6 6 615b7672fcSPrabhakar Kushwaha #define EMI1_SLOT7 7 625b7672fcSPrabhakar Kushwaha #define EMI2 8 635b7672fcSPrabhakar Kushwaha 645b7672fcSPrabhakar Kushwaha static int mdio_mux[NUM_FM_PORTS]; 655b7672fcSPrabhakar Kushwaha 665b7672fcSPrabhakar Kushwaha static const char * const mdio_names[] = { 675b7672fcSPrabhakar Kushwaha "T1040_QDS_MDIO0", 685b7672fcSPrabhakar Kushwaha "T1040_QDS_MDIO1", 695b7672fcSPrabhakar Kushwaha "T1040_QDS_MDIO2", 705b7672fcSPrabhakar Kushwaha "T1040_QDS_MDIO3", 715b7672fcSPrabhakar Kushwaha "T1040_QDS_MDIO4", 725b7672fcSPrabhakar Kushwaha "T1040_QDS_MDIO5", 735b7672fcSPrabhakar Kushwaha "T1040_QDS_MDIO6", 745b7672fcSPrabhakar Kushwaha "T1040_QDS_MDIO7", 755b7672fcSPrabhakar Kushwaha }; 765b7672fcSPrabhakar Kushwaha 775b7672fcSPrabhakar Kushwaha struct t1040_qds_mdio { 785b7672fcSPrabhakar Kushwaha u8 muxval; 795b7672fcSPrabhakar Kushwaha struct mii_dev *realbus; 805b7672fcSPrabhakar Kushwaha }; 815b7672fcSPrabhakar Kushwaha 825b7672fcSPrabhakar Kushwaha static const char *t1040_qds_mdio_name_for_muxval(u8 muxval) 835b7672fcSPrabhakar Kushwaha { 845b7672fcSPrabhakar Kushwaha return mdio_names[muxval]; 855b7672fcSPrabhakar Kushwaha } 865b7672fcSPrabhakar Kushwaha 875b7672fcSPrabhakar Kushwaha struct mii_dev *mii_dev_for_muxval(u8 muxval) 885b7672fcSPrabhakar Kushwaha { 895b7672fcSPrabhakar Kushwaha struct mii_dev *bus; 905b7672fcSPrabhakar Kushwaha const char *name = t1040_qds_mdio_name_for_muxval(muxval); 915b7672fcSPrabhakar Kushwaha 925b7672fcSPrabhakar Kushwaha if (!name) { 935b7672fcSPrabhakar Kushwaha printf("No bus for muxval %x\n", muxval); 945b7672fcSPrabhakar Kushwaha return NULL; 955b7672fcSPrabhakar Kushwaha } 965b7672fcSPrabhakar Kushwaha 975b7672fcSPrabhakar Kushwaha bus = miiphy_get_dev_by_name(name); 985b7672fcSPrabhakar Kushwaha 995b7672fcSPrabhakar Kushwaha if (!bus) { 1005b7672fcSPrabhakar Kushwaha printf("No bus by name %s\n", name); 1015b7672fcSPrabhakar Kushwaha return NULL; 1025b7672fcSPrabhakar Kushwaha } 1035b7672fcSPrabhakar Kushwaha 1045b7672fcSPrabhakar Kushwaha return bus; 1055b7672fcSPrabhakar Kushwaha } 1065b7672fcSPrabhakar Kushwaha 1075b7672fcSPrabhakar Kushwaha static void t1040_qds_mux_mdio(u8 muxval) 1085b7672fcSPrabhakar Kushwaha { 1095b7672fcSPrabhakar Kushwaha u8 brdcfg4; 1105b7672fcSPrabhakar Kushwaha if (muxval <= 7) { 1115b7672fcSPrabhakar Kushwaha brdcfg4 = QIXIS_READ(brdcfg[4]); 1125b7672fcSPrabhakar Kushwaha brdcfg4 &= ~BRDCFG4_EMISEL_MASK; 1135b7672fcSPrabhakar Kushwaha brdcfg4 |= (muxval << BRDCFG4_EMISEL_SHIFT); 1145b7672fcSPrabhakar Kushwaha QIXIS_WRITE(brdcfg[4], brdcfg4); 1155b7672fcSPrabhakar Kushwaha } 1165b7672fcSPrabhakar Kushwaha } 1175b7672fcSPrabhakar Kushwaha 1185b7672fcSPrabhakar Kushwaha static int t1040_qds_mdio_read(struct mii_dev *bus, int addr, int devad, 1195b7672fcSPrabhakar Kushwaha int regnum) 1205b7672fcSPrabhakar Kushwaha { 1215b7672fcSPrabhakar Kushwaha struct t1040_qds_mdio *priv = bus->priv; 1225b7672fcSPrabhakar Kushwaha 1235b7672fcSPrabhakar Kushwaha t1040_qds_mux_mdio(priv->muxval); 1245b7672fcSPrabhakar Kushwaha 1255b7672fcSPrabhakar Kushwaha return priv->realbus->read(priv->realbus, addr, devad, regnum); 1265b7672fcSPrabhakar Kushwaha } 1275b7672fcSPrabhakar Kushwaha 1285b7672fcSPrabhakar Kushwaha static int t1040_qds_mdio_write(struct mii_dev *bus, int addr, int devad, 1295b7672fcSPrabhakar Kushwaha int regnum, u16 value) 1305b7672fcSPrabhakar Kushwaha { 1315b7672fcSPrabhakar Kushwaha struct t1040_qds_mdio *priv = bus->priv; 1325b7672fcSPrabhakar Kushwaha 1335b7672fcSPrabhakar Kushwaha t1040_qds_mux_mdio(priv->muxval); 1345b7672fcSPrabhakar Kushwaha 1355b7672fcSPrabhakar Kushwaha return priv->realbus->write(priv->realbus, addr, devad, regnum, value); 1365b7672fcSPrabhakar Kushwaha } 1375b7672fcSPrabhakar Kushwaha 1385b7672fcSPrabhakar Kushwaha static int t1040_qds_mdio_reset(struct mii_dev *bus) 1395b7672fcSPrabhakar Kushwaha { 1405b7672fcSPrabhakar Kushwaha struct t1040_qds_mdio *priv = bus->priv; 1415b7672fcSPrabhakar Kushwaha 1425b7672fcSPrabhakar Kushwaha return priv->realbus->reset(priv->realbus); 1435b7672fcSPrabhakar Kushwaha } 1445b7672fcSPrabhakar Kushwaha 1455b7672fcSPrabhakar Kushwaha static int t1040_qds_mdio_init(char *realbusname, u8 muxval) 1465b7672fcSPrabhakar Kushwaha { 1475b7672fcSPrabhakar Kushwaha struct t1040_qds_mdio *pmdio; 1485b7672fcSPrabhakar Kushwaha struct mii_dev *bus = mdio_alloc(); 1495b7672fcSPrabhakar Kushwaha 1505b7672fcSPrabhakar Kushwaha if (!bus) { 1515b7672fcSPrabhakar Kushwaha printf("Failed to allocate t1040_qds MDIO bus\n"); 1525b7672fcSPrabhakar Kushwaha return -1; 1535b7672fcSPrabhakar Kushwaha } 1545b7672fcSPrabhakar Kushwaha 1555b7672fcSPrabhakar Kushwaha pmdio = malloc(sizeof(*pmdio)); 1565b7672fcSPrabhakar Kushwaha if (!pmdio) { 1575b7672fcSPrabhakar Kushwaha printf("Failed to allocate t1040_qds private data\n"); 1585b7672fcSPrabhakar Kushwaha free(bus); 1595b7672fcSPrabhakar Kushwaha return -1; 1605b7672fcSPrabhakar Kushwaha } 1615b7672fcSPrabhakar Kushwaha 1625b7672fcSPrabhakar Kushwaha bus->read = t1040_qds_mdio_read; 1635b7672fcSPrabhakar Kushwaha bus->write = t1040_qds_mdio_write; 1645b7672fcSPrabhakar Kushwaha bus->reset = t1040_qds_mdio_reset; 1655b7672fcSPrabhakar Kushwaha sprintf(bus->name, t1040_qds_mdio_name_for_muxval(muxval)); 1665b7672fcSPrabhakar Kushwaha 1675b7672fcSPrabhakar Kushwaha pmdio->realbus = miiphy_get_dev_by_name(realbusname); 1685b7672fcSPrabhakar Kushwaha 1695b7672fcSPrabhakar Kushwaha if (!pmdio->realbus) { 1705b7672fcSPrabhakar Kushwaha printf("No bus with name %s\n", realbusname); 1715b7672fcSPrabhakar Kushwaha free(bus); 1725b7672fcSPrabhakar Kushwaha free(pmdio); 1735b7672fcSPrabhakar Kushwaha return -1; 1745b7672fcSPrabhakar Kushwaha } 1755b7672fcSPrabhakar Kushwaha 1765b7672fcSPrabhakar Kushwaha pmdio->muxval = muxval; 1775b7672fcSPrabhakar Kushwaha bus->priv = pmdio; 1785b7672fcSPrabhakar Kushwaha 1795b7672fcSPrabhakar Kushwaha return mdio_register(bus); 1805b7672fcSPrabhakar Kushwaha } 1815b7672fcSPrabhakar Kushwaha 1825b7672fcSPrabhakar Kushwaha /* 1835b7672fcSPrabhakar Kushwaha * Initialize the lane_to_slot[] array. 1845b7672fcSPrabhakar Kushwaha * 1855b7672fcSPrabhakar Kushwaha * On the T1040QDS board the mapping is controlled by ?? register. 1865b7672fcSPrabhakar Kushwaha */ 1875b7672fcSPrabhakar Kushwaha static void initialize_lane_to_slot(void) 1885b7672fcSPrabhakar Kushwaha { 1895b7672fcSPrabhakar Kushwaha ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR; 1905b7672fcSPrabhakar Kushwaha int serdes1_prtcl = (in_be32(&gur->rcwsr[4]) & 1915b7672fcSPrabhakar Kushwaha FSL_CORENET2_RCWSR4_SRDS1_PRTCL) 1925b7672fcSPrabhakar Kushwaha >> FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT; 1935b7672fcSPrabhakar Kushwaha 1945b7672fcSPrabhakar Kushwaha QIXIS_WRITE(cms[0], 0x07); 1955b7672fcSPrabhakar Kushwaha 1965b7672fcSPrabhakar Kushwaha switch (serdes1_prtcl) { 1975b7672fcSPrabhakar Kushwaha case 0x60: 1985b7672fcSPrabhakar Kushwaha case 0x66: 1995b7672fcSPrabhakar Kushwaha case 0x67: 2005b7672fcSPrabhakar Kushwaha case 0x69: 2015b7672fcSPrabhakar Kushwaha lane_to_slot[1] = 7; 2025b7672fcSPrabhakar Kushwaha lane_to_slot[2] = 6; 2035b7672fcSPrabhakar Kushwaha lane_to_slot[3] = 5; 2045b7672fcSPrabhakar Kushwaha break; 2055b7672fcSPrabhakar Kushwaha case 0x86: 2065b7672fcSPrabhakar Kushwaha lane_to_slot[1] = 7; 2075b7672fcSPrabhakar Kushwaha lane_to_slot[2] = 7; 2085b7672fcSPrabhakar Kushwaha lane_to_slot[3] = 7; 2095b7672fcSPrabhakar Kushwaha break; 2105b7672fcSPrabhakar Kushwaha case 0x87: 2115b7672fcSPrabhakar Kushwaha lane_to_slot[1] = 7; 2125b7672fcSPrabhakar Kushwaha lane_to_slot[2] = 7; 2135b7672fcSPrabhakar Kushwaha lane_to_slot[3] = 7; 2145b7672fcSPrabhakar Kushwaha lane_to_slot[7] = 7; 2155b7672fcSPrabhakar Kushwaha break; 2165b7672fcSPrabhakar Kushwaha case 0x89: 2175b7672fcSPrabhakar Kushwaha lane_to_slot[1] = 7; 2185b7672fcSPrabhakar Kushwaha lane_to_slot[2] = 7; 2195b7672fcSPrabhakar Kushwaha lane_to_slot[3] = 7; 220ea191e6dSCodrin Ciubotariu lane_to_slot[6] = 7; 2215b7672fcSPrabhakar Kushwaha lane_to_slot[7] = 7; 2225b7672fcSPrabhakar Kushwaha break; 2235b7672fcSPrabhakar Kushwaha case 0x8d: 2245b7672fcSPrabhakar Kushwaha lane_to_slot[1] = 7; 2255b7672fcSPrabhakar Kushwaha lane_to_slot[2] = 7; 2265b7672fcSPrabhakar Kushwaha lane_to_slot[3] = 7; 2275b7672fcSPrabhakar Kushwaha lane_to_slot[5] = 3; 2285b7672fcSPrabhakar Kushwaha lane_to_slot[6] = 3; 2295b7672fcSPrabhakar Kushwaha lane_to_slot[7] = 3; 2305b7672fcSPrabhakar Kushwaha break; 2315b7672fcSPrabhakar Kushwaha case 0x8F: 2325b7672fcSPrabhakar Kushwaha case 0x85: 2335b7672fcSPrabhakar Kushwaha lane_to_slot[1] = 7; 2345b7672fcSPrabhakar Kushwaha lane_to_slot[2] = 6; 2355b7672fcSPrabhakar Kushwaha lane_to_slot[3] = 5; 2365b7672fcSPrabhakar Kushwaha lane_to_slot[6] = 3; 2375b7672fcSPrabhakar Kushwaha lane_to_slot[7] = 3; 2385b7672fcSPrabhakar Kushwaha break; 2395b7672fcSPrabhakar Kushwaha case 0xA5: 2405b7672fcSPrabhakar Kushwaha lane_to_slot[1] = 7; 2415b7672fcSPrabhakar Kushwaha lane_to_slot[6] = 3; 2425b7672fcSPrabhakar Kushwaha lane_to_slot[7] = 3; 2435b7672fcSPrabhakar Kushwaha break; 2445b7672fcSPrabhakar Kushwaha case 0xA7: 2455b7672fcSPrabhakar Kushwaha lane_to_slot[1] = 7; 2465273aa38SPriyanka Jain lane_to_slot[2] = 6; 2475273aa38SPriyanka Jain lane_to_slot[3] = 5; 2485b7672fcSPrabhakar Kushwaha lane_to_slot[7] = 7; 2495b7672fcSPrabhakar Kushwaha break; 2505b7672fcSPrabhakar Kushwaha case 0xAA: 2515b7672fcSPrabhakar Kushwaha lane_to_slot[1] = 7; 2525b7672fcSPrabhakar Kushwaha lane_to_slot[6] = 7; 2535b7672fcSPrabhakar Kushwaha lane_to_slot[7] = 7; 2545b7672fcSPrabhakar Kushwaha break; 2555b7672fcSPrabhakar Kushwaha case 0x40: 2565b7672fcSPrabhakar Kushwaha lane_to_slot[2] = 7; 2575b7672fcSPrabhakar Kushwaha lane_to_slot[3] = 7; 2585b7672fcSPrabhakar Kushwaha break; 2595b7672fcSPrabhakar Kushwaha default: 2605b7672fcSPrabhakar Kushwaha printf("qds: Fman: Unsupported SerDes Protocol 0x%02x\n", 2615b7672fcSPrabhakar Kushwaha serdes1_prtcl); 2625b7672fcSPrabhakar Kushwaha break; 2635b7672fcSPrabhakar Kushwaha } 2645b7672fcSPrabhakar Kushwaha } 2655b7672fcSPrabhakar Kushwaha 2665b7672fcSPrabhakar Kushwaha /* 2675b7672fcSPrabhakar Kushwaha * Given the following ... 2685b7672fcSPrabhakar Kushwaha * 2695b7672fcSPrabhakar Kushwaha * 1) A pointer to an Fman Ethernet node (as identified by the 'compat' 2705b7672fcSPrabhakar Kushwaha * compatible string and 'addr' physical address) 2715b7672fcSPrabhakar Kushwaha * 2725b7672fcSPrabhakar Kushwaha * 2) An Fman port 2735b7672fcSPrabhakar Kushwaha * 2745b7672fcSPrabhakar Kushwaha * ... update the phy-handle property of the Ethernet node to point to the 2755b7672fcSPrabhakar Kushwaha * right PHY. This assumes that we already know the PHY for each port. 2765b7672fcSPrabhakar Kushwaha * 2775b7672fcSPrabhakar Kushwaha * The offset of the Fman Ethernet node is also passed in for convenience, but 2785b7672fcSPrabhakar Kushwaha * it is not used, and we recalculate the offset anyway. 2795b7672fcSPrabhakar Kushwaha * 2805b7672fcSPrabhakar Kushwaha * Note that what we call "Fman ports" (enum fm_port) is really an Fman MAC. 2815b7672fcSPrabhakar Kushwaha * Inside the Fman, "ports" are things that connect to MACs. We only call them 2825b7672fcSPrabhakar Kushwaha * ports in U-Boot because on previous Ethernet devices (e.g. Gianfar), MACs 2835b7672fcSPrabhakar Kushwaha * and ports are the same thing. 2845b7672fcSPrabhakar Kushwaha * 2855b7672fcSPrabhakar Kushwaha */ 2865b7672fcSPrabhakar Kushwaha void board_ft_fman_fixup_port(void *fdt, char *compat, phys_addr_t addr, 2875b7672fcSPrabhakar Kushwaha enum fm_port port, int offset) 2885b7672fcSPrabhakar Kushwaha { 2895b7672fcSPrabhakar Kushwaha phy_interface_t intf = fm_info_get_enet_if(port); 2905b7672fcSPrabhakar Kushwaha char phy[16]; 2915b7672fcSPrabhakar Kushwaha 2925b7672fcSPrabhakar Kushwaha /* The RGMII PHY is identified by the MAC connected to it */ 2935b7672fcSPrabhakar Kushwaha if (intf == PHY_INTERFACE_MODE_RGMII) { 2945b7672fcSPrabhakar Kushwaha sprintf(phy, "rgmii_phy%u", port == FM1_DTSEC4 ? 1 : 2); 2955b7672fcSPrabhakar Kushwaha fdt_set_phy_handle(fdt, compat, addr, phy); 2965b7672fcSPrabhakar Kushwaha } 2975b7672fcSPrabhakar Kushwaha 2985b7672fcSPrabhakar Kushwaha /* The SGMII PHY is identified by the MAC connected to it */ 2995b7672fcSPrabhakar Kushwaha if (intf == PHY_INTERFACE_MODE_SGMII) { 3005b7672fcSPrabhakar Kushwaha int lane = serdes_get_first_lane(FSL_SRDS_1, SGMII_FM1_DTSEC1 3015b7672fcSPrabhakar Kushwaha + port); 3025b7672fcSPrabhakar Kushwaha u8 slot; 3035b7672fcSPrabhakar Kushwaha if (lane < 0) 3045b7672fcSPrabhakar Kushwaha return; 3055b7672fcSPrabhakar Kushwaha slot = lane_to_slot[lane]; 3065b7672fcSPrabhakar Kushwaha if (slot) { 3075b7672fcSPrabhakar Kushwaha /* Slot housing a SGMII riser card */ 3085b7672fcSPrabhakar Kushwaha sprintf(phy, "phy_s%x_%02x", slot, 3095b7672fcSPrabhakar Kushwaha (fm_info_get_phy_address(port - FM1_DTSEC1)- 3105b7672fcSPrabhakar Kushwaha CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR + 1)); 3115b7672fcSPrabhakar Kushwaha fdt_set_phy_handle(fdt, compat, addr, phy); 3125b7672fcSPrabhakar Kushwaha } 3135b7672fcSPrabhakar Kushwaha } 3145b7672fcSPrabhakar Kushwaha } 3155b7672fcSPrabhakar Kushwaha 3165b7672fcSPrabhakar Kushwaha void fdt_fixup_board_enet(void *fdt) 3175b7672fcSPrabhakar Kushwaha { 3185b7672fcSPrabhakar Kushwaha int i, lane, idx; 3195b7672fcSPrabhakar Kushwaha 3205b7672fcSPrabhakar Kushwaha for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) { 3215b7672fcSPrabhakar Kushwaha idx = i - FM1_DTSEC1; 3225b7672fcSPrabhakar Kushwaha switch (fm_info_get_enet_if(i)) { 3235b7672fcSPrabhakar Kushwaha case PHY_INTERFACE_MODE_SGMII: 3245b7672fcSPrabhakar Kushwaha lane = serdes_get_first_lane(FSL_SRDS_1, 3255b7672fcSPrabhakar Kushwaha SGMII_FM1_DTSEC1 + idx); 3265b7672fcSPrabhakar Kushwaha if (lane < 0) 3275b7672fcSPrabhakar Kushwaha break; 3285b7672fcSPrabhakar Kushwaha 3295b7672fcSPrabhakar Kushwaha switch (mdio_mux[i]) { 3305b7672fcSPrabhakar Kushwaha case EMI1_SLOT3: 3315b7672fcSPrabhakar Kushwaha fdt_status_okay_by_alias(fdt, "emi1_slot3"); 3325b7672fcSPrabhakar Kushwaha break; 3335b7672fcSPrabhakar Kushwaha case EMI1_SLOT5: 3345b7672fcSPrabhakar Kushwaha fdt_status_okay_by_alias(fdt, "emi1_slot5"); 3355b7672fcSPrabhakar Kushwaha break; 3365b7672fcSPrabhakar Kushwaha case EMI1_SLOT6: 3375b7672fcSPrabhakar Kushwaha fdt_status_okay_by_alias(fdt, "emi1_slot6"); 3385b7672fcSPrabhakar Kushwaha break; 3395b7672fcSPrabhakar Kushwaha case EMI1_SLOT7: 3405b7672fcSPrabhakar Kushwaha fdt_status_okay_by_alias(fdt, "emi1_slot7"); 3415b7672fcSPrabhakar Kushwaha break; 3425b7672fcSPrabhakar Kushwaha } 3435b7672fcSPrabhakar Kushwaha break; 3445b7672fcSPrabhakar Kushwaha case PHY_INTERFACE_MODE_RGMII: 3455b7672fcSPrabhakar Kushwaha if (i == FM1_DTSEC4) 3465b7672fcSPrabhakar Kushwaha fdt_status_okay_by_alias(fdt, "emi1_rgmii0"); 3475b7672fcSPrabhakar Kushwaha 3485b7672fcSPrabhakar Kushwaha if (i == FM1_DTSEC5) 3495b7672fcSPrabhakar Kushwaha fdt_status_okay_by_alias(fdt, "emi1_rgmii1"); 3505b7672fcSPrabhakar Kushwaha break; 3515b7672fcSPrabhakar Kushwaha default: 3525b7672fcSPrabhakar Kushwaha break; 3535b7672fcSPrabhakar Kushwaha } 3545b7672fcSPrabhakar Kushwaha } 3555b7672fcSPrabhakar Kushwaha } 3565b7672fcSPrabhakar Kushwaha #endif /* #ifdef CONFIG_FMAN_ENET */ 3575b7672fcSPrabhakar Kushwaha 3585b7672fcSPrabhakar Kushwaha static void set_brdcfg9_for_gtx_clk(void) 3595b7672fcSPrabhakar Kushwaha { 3605b7672fcSPrabhakar Kushwaha u8 brdcfg9; 3615b7672fcSPrabhakar Kushwaha brdcfg9 = QIXIS_READ(brdcfg[9]); 3626666017fSvijay rai /* Initializing EPHY2 clock to RGMII mode */ 3636666017fSvijay rai brdcfg9 &= ~(BRDCFG9_EPHY2_MASK); 3646666017fSvijay rai brdcfg9 |= (BRDCFG9_EPHY2_VAL); 3655b7672fcSPrabhakar Kushwaha QIXIS_WRITE(brdcfg[9], brdcfg9); 3665b7672fcSPrabhakar Kushwaha } 3675b7672fcSPrabhakar Kushwaha 3685b7672fcSPrabhakar Kushwaha void t1040_handle_phy_interface_sgmii(int i) 3695b7672fcSPrabhakar Kushwaha { 3705b7672fcSPrabhakar Kushwaha int lane, idx, slot; 3715b7672fcSPrabhakar Kushwaha idx = i - FM1_DTSEC1; 3725b7672fcSPrabhakar Kushwaha lane = serdes_get_first_lane(FSL_SRDS_1, 3735b7672fcSPrabhakar Kushwaha SGMII_FM1_DTSEC1 + idx); 3745b7672fcSPrabhakar Kushwaha 3755b7672fcSPrabhakar Kushwaha if (lane < 0) 3765b7672fcSPrabhakar Kushwaha return; 3775b7672fcSPrabhakar Kushwaha slot = lane_to_slot[lane]; 3785b7672fcSPrabhakar Kushwaha 3795b7672fcSPrabhakar Kushwaha switch (slot) { 3805b7672fcSPrabhakar Kushwaha case 1: 3815b7672fcSPrabhakar Kushwaha mdio_mux[i] = EMI1_SLOT1; 3825b7672fcSPrabhakar Kushwaha fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i])); 3835b7672fcSPrabhakar Kushwaha break; 3845b7672fcSPrabhakar Kushwaha case 3: 3855b7672fcSPrabhakar Kushwaha if (FM1_DTSEC4 == i) 3865b7672fcSPrabhakar Kushwaha fm_info_set_phy_address(i, riser_phy_addr[0]); 3875b7672fcSPrabhakar Kushwaha if (FM1_DTSEC5 == i) 3885b7672fcSPrabhakar Kushwaha fm_info_set_phy_address(i, riser_phy_addr[1]); 3895b7672fcSPrabhakar Kushwaha 3905b7672fcSPrabhakar Kushwaha mdio_mux[i] = EMI1_SLOT3; 3915b7672fcSPrabhakar Kushwaha 3925b7672fcSPrabhakar Kushwaha fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i])); 3935b7672fcSPrabhakar Kushwaha break; 3945b7672fcSPrabhakar Kushwaha case 4: 3955b7672fcSPrabhakar Kushwaha mdio_mux[i] = EMI1_SLOT4; 3965b7672fcSPrabhakar Kushwaha fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i])); 3975b7672fcSPrabhakar Kushwaha break; 3985b7672fcSPrabhakar Kushwaha case 5: 3995b7672fcSPrabhakar Kushwaha /* Slot housing a SGMII riser card? */ 4005b7672fcSPrabhakar Kushwaha fm_info_set_phy_address(i, riser_phy_addr[0]); 4015b7672fcSPrabhakar Kushwaha mdio_mux[i] = EMI1_SLOT5; 4025b7672fcSPrabhakar Kushwaha fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i])); 4035b7672fcSPrabhakar Kushwaha break; 4045b7672fcSPrabhakar Kushwaha case 6: 4055b7672fcSPrabhakar Kushwaha /* Slot housing a SGMII riser card? */ 4065b7672fcSPrabhakar Kushwaha fm_info_set_phy_address(i, riser_phy_addr[0]); 4075b7672fcSPrabhakar Kushwaha mdio_mux[i] = EMI1_SLOT6; 4085b7672fcSPrabhakar Kushwaha fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i])); 4095b7672fcSPrabhakar Kushwaha break; 4105b7672fcSPrabhakar Kushwaha case 7: 4115b7672fcSPrabhakar Kushwaha if (FM1_DTSEC1 == i) 4125b7672fcSPrabhakar Kushwaha fm_info_set_phy_address(i, riser_phy_addr[0]); 4135b7672fcSPrabhakar Kushwaha if (FM1_DTSEC2 == i) 4145b7672fcSPrabhakar Kushwaha fm_info_set_phy_address(i, riser_phy_addr[1]); 4155b7672fcSPrabhakar Kushwaha if (FM1_DTSEC3 == i) 4165b7672fcSPrabhakar Kushwaha fm_info_set_phy_address(i, riser_phy_addr[2]); 4175273aa38SPriyanka Jain if (FM1_DTSEC5 == i) 4185273aa38SPriyanka Jain fm_info_set_phy_address(i, riser_phy_addr[3]); 4195b7672fcSPrabhakar Kushwaha 4205b7672fcSPrabhakar Kushwaha mdio_mux[i] = EMI1_SLOT7; 4215b7672fcSPrabhakar Kushwaha fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i])); 4225b7672fcSPrabhakar Kushwaha break; 4235b7672fcSPrabhakar Kushwaha default: 4245b7672fcSPrabhakar Kushwaha break; 4255b7672fcSPrabhakar Kushwaha } 4265b7672fcSPrabhakar Kushwaha fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i])); 4275b7672fcSPrabhakar Kushwaha } 4285b7672fcSPrabhakar Kushwaha void t1040_handle_phy_interface_rgmii(int i) 4295b7672fcSPrabhakar Kushwaha { 4305b7672fcSPrabhakar Kushwaha fm_info_set_phy_address(i, i == FM1_DTSEC5 ? 4315b7672fcSPrabhakar Kushwaha CONFIG_SYS_FM1_DTSEC5_PHY_ADDR : 4325b7672fcSPrabhakar Kushwaha CONFIG_SYS_FM1_DTSEC4_PHY_ADDR); 4335b7672fcSPrabhakar Kushwaha mdio_mux[i] = (i == FM1_DTSEC5) ? EMI1_RGMII1 : 4345b7672fcSPrabhakar Kushwaha EMI1_RGMII0; 4355b7672fcSPrabhakar Kushwaha fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i])); 4365b7672fcSPrabhakar Kushwaha } 4375b7672fcSPrabhakar Kushwaha 4385b7672fcSPrabhakar Kushwaha int board_eth_init(bd_t *bis) 4395b7672fcSPrabhakar Kushwaha { 4405b7672fcSPrabhakar Kushwaha #ifdef CONFIG_FMAN_ENET 4415b7672fcSPrabhakar Kushwaha struct memac_mdio_info memac_mdio_info; 4425b7672fcSPrabhakar Kushwaha unsigned int i; 443*a83fccc2SCodrin Ciubotariu #ifdef CONFIG_VSC9953 444*a83fccc2SCodrin Ciubotariu int lane; 445*a83fccc2SCodrin Ciubotariu int phy_addr; 446*a83fccc2SCodrin Ciubotariu phy_interface_t phy_int; 447*a83fccc2SCodrin Ciubotariu struct mii_dev *bus; 448*a83fccc2SCodrin Ciubotariu #endif 4495b7672fcSPrabhakar Kushwaha 4505b7672fcSPrabhakar Kushwaha printf("Initializing Fman\n"); 4515b7672fcSPrabhakar Kushwaha set_brdcfg9_for_gtx_clk(); 4525b7672fcSPrabhakar Kushwaha 4535b7672fcSPrabhakar Kushwaha initialize_lane_to_slot(); 4545b7672fcSPrabhakar Kushwaha 4555b7672fcSPrabhakar Kushwaha /* Initialize the mdio_mux array so we can recognize empty elements */ 4565b7672fcSPrabhakar Kushwaha for (i = 0; i < NUM_FM_PORTS; i++) 4575b7672fcSPrabhakar Kushwaha mdio_mux[i] = EMI_NONE; 4585b7672fcSPrabhakar Kushwaha 4595b7672fcSPrabhakar Kushwaha memac_mdio_info.regs = 4605b7672fcSPrabhakar Kushwaha (struct memac_mdio_controller *)CONFIG_SYS_FM1_DTSEC_MDIO_ADDR; 4615b7672fcSPrabhakar Kushwaha memac_mdio_info.name = DEFAULT_FM_MDIO_NAME; 4625b7672fcSPrabhakar Kushwaha 4635b7672fcSPrabhakar Kushwaha /* Register the real 1G MDIO bus */ 4645b7672fcSPrabhakar Kushwaha fm_memac_mdio_init(bis, &memac_mdio_info); 4655b7672fcSPrabhakar Kushwaha 4665b7672fcSPrabhakar Kushwaha /* Register the muxing front-ends to the MDIO buses */ 4675b7672fcSPrabhakar Kushwaha t1040_qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_RGMII0); 4685b7672fcSPrabhakar Kushwaha t1040_qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_RGMII1); 4695b7672fcSPrabhakar Kushwaha t1040_qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT1); 4705b7672fcSPrabhakar Kushwaha t1040_qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT3); 4715b7672fcSPrabhakar Kushwaha t1040_qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT4); 4725b7672fcSPrabhakar Kushwaha t1040_qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT5); 4735b7672fcSPrabhakar Kushwaha t1040_qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT6); 4745b7672fcSPrabhakar Kushwaha t1040_qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT7); 4755b7672fcSPrabhakar Kushwaha 4765b7672fcSPrabhakar Kushwaha /* 4775b7672fcSPrabhakar Kushwaha * Program on board RGMII PHY addresses. If the SGMII Riser 4785b7672fcSPrabhakar Kushwaha * card used, we'll override the PHY address later. For any DTSEC that 4795b7672fcSPrabhakar Kushwaha * is RGMII, we'll also override its PHY address later. We assume that 4805b7672fcSPrabhakar Kushwaha * DTSEC4 and DTSEC5 are used for RGMII. 4815b7672fcSPrabhakar Kushwaha */ 4825b7672fcSPrabhakar Kushwaha fm_info_set_phy_address(FM1_DTSEC4, CONFIG_SYS_FM1_DTSEC4_PHY_ADDR); 4835b7672fcSPrabhakar Kushwaha fm_info_set_phy_address(FM1_DTSEC5, CONFIG_SYS_FM1_DTSEC5_PHY_ADDR); 4845b7672fcSPrabhakar Kushwaha 4855b7672fcSPrabhakar Kushwaha for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) { 4865b7672fcSPrabhakar Kushwaha switch (fm_info_get_enet_if(i)) { 4875b7672fcSPrabhakar Kushwaha case PHY_INTERFACE_MODE_QSGMII: 488d9fb29c7SCodrin Ciubotariu fm_info_set_mdio(i, NULL); 4895b7672fcSPrabhakar Kushwaha break; 4905b7672fcSPrabhakar Kushwaha case PHY_INTERFACE_MODE_SGMII: 4915b7672fcSPrabhakar Kushwaha t1040_handle_phy_interface_sgmii(i); 4925b7672fcSPrabhakar Kushwaha break; 4935b7672fcSPrabhakar Kushwaha 4945b7672fcSPrabhakar Kushwaha case PHY_INTERFACE_MODE_RGMII: 4955b7672fcSPrabhakar Kushwaha /* Only DTSEC4 and DTSEC5 can be routed to RGMII */ 4965b7672fcSPrabhakar Kushwaha t1040_handle_phy_interface_rgmii(i); 4975b7672fcSPrabhakar Kushwaha break; 4985b7672fcSPrabhakar Kushwaha default: 4995b7672fcSPrabhakar Kushwaha break; 5005b7672fcSPrabhakar Kushwaha } 5015b7672fcSPrabhakar Kushwaha } 5025b7672fcSPrabhakar Kushwaha 503*a83fccc2SCodrin Ciubotariu #ifdef CONFIG_VSC9953 504*a83fccc2SCodrin Ciubotariu for (i = 0; i < VSC9953_MAX_PORTS; i++) { 505*a83fccc2SCodrin Ciubotariu lane = -1; 506*a83fccc2SCodrin Ciubotariu phy_addr = 0; 507*a83fccc2SCodrin Ciubotariu phy_int = PHY_INTERFACE_MODE_NONE; 508*a83fccc2SCodrin Ciubotariu switch (i) { 509*a83fccc2SCodrin Ciubotariu case 0: 510*a83fccc2SCodrin Ciubotariu case 1: 511*a83fccc2SCodrin Ciubotariu case 2: 512*a83fccc2SCodrin Ciubotariu case 3: 513*a83fccc2SCodrin Ciubotariu lane = serdes_get_first_lane(FSL_SRDS_1, QSGMII_SW1_A); 514*a83fccc2SCodrin Ciubotariu /* PHYs connected over QSGMII */ 515*a83fccc2SCodrin Ciubotariu if (lane >= 0) { 516*a83fccc2SCodrin Ciubotariu phy_addr = CONFIG_SYS_FM1_QSGMII21_PHY_ADDR + 517*a83fccc2SCodrin Ciubotariu i; 518*a83fccc2SCodrin Ciubotariu phy_int = PHY_INTERFACE_MODE_QSGMII; 519*a83fccc2SCodrin Ciubotariu break; 520*a83fccc2SCodrin Ciubotariu } 521*a83fccc2SCodrin Ciubotariu lane = serdes_get_first_lane(FSL_SRDS_1, 522*a83fccc2SCodrin Ciubotariu SGMII_SW1_MAC1 + i); 523*a83fccc2SCodrin Ciubotariu 524*a83fccc2SCodrin Ciubotariu if (lane < 0) 525*a83fccc2SCodrin Ciubotariu break; 526*a83fccc2SCodrin Ciubotariu 527*a83fccc2SCodrin Ciubotariu /* PHYs connected over QSGMII */ 528*a83fccc2SCodrin Ciubotariu if (i != 3 || lane_to_slot[lane] == 7) 529*a83fccc2SCodrin Ciubotariu phy_addr = CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR 530*a83fccc2SCodrin Ciubotariu + i; 531*a83fccc2SCodrin Ciubotariu else 532*a83fccc2SCodrin Ciubotariu phy_addr = CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR; 533*a83fccc2SCodrin Ciubotariu phy_int = PHY_INTERFACE_MODE_SGMII; 534*a83fccc2SCodrin Ciubotariu break; 535*a83fccc2SCodrin Ciubotariu case 4: 536*a83fccc2SCodrin Ciubotariu case 5: 537*a83fccc2SCodrin Ciubotariu case 6: 538*a83fccc2SCodrin Ciubotariu case 7: 539*a83fccc2SCodrin Ciubotariu lane = serdes_get_first_lane(FSL_SRDS_1, QSGMII_SW1_B); 540*a83fccc2SCodrin Ciubotariu /* PHYs connected over QSGMII */ 541*a83fccc2SCodrin Ciubotariu if (lane >= 0) { 542*a83fccc2SCodrin Ciubotariu phy_addr = CONFIG_SYS_FM1_QSGMII11_PHY_ADDR + 543*a83fccc2SCodrin Ciubotariu i - 4; 544*a83fccc2SCodrin Ciubotariu phy_int = PHY_INTERFACE_MODE_QSGMII; 545*a83fccc2SCodrin Ciubotariu break; 546*a83fccc2SCodrin Ciubotariu } 547*a83fccc2SCodrin Ciubotariu lane = serdes_get_first_lane(FSL_SRDS_1, 548*a83fccc2SCodrin Ciubotariu SGMII_SW1_MAC1 + i); 549*a83fccc2SCodrin Ciubotariu /* PHYs connected over SGMII */ 550*a83fccc2SCodrin Ciubotariu if (lane >= 0) { 551*a83fccc2SCodrin Ciubotariu phy_addr = CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR 552*a83fccc2SCodrin Ciubotariu + i - 3; 553*a83fccc2SCodrin Ciubotariu phy_int = PHY_INTERFACE_MODE_SGMII; 554*a83fccc2SCodrin Ciubotariu } 555*a83fccc2SCodrin Ciubotariu break; 556*a83fccc2SCodrin Ciubotariu case 8: 557*a83fccc2SCodrin Ciubotariu if (serdes_get_first_lane(FSL_SRDS_1, 558*a83fccc2SCodrin Ciubotariu SGMII_FM1_DTSEC1) < 0) 559*a83fccc2SCodrin Ciubotariu /* FM1@DTSEC1 is connected to SW1@PORT8 */ 560*a83fccc2SCodrin Ciubotariu vsc9953_port_enable(i); 561*a83fccc2SCodrin Ciubotariu break; 562*a83fccc2SCodrin Ciubotariu case 9: 563*a83fccc2SCodrin Ciubotariu if (serdes_get_first_lane(FSL_SRDS_1, 564*a83fccc2SCodrin Ciubotariu SGMII_FM1_DTSEC2) < 0) { 565*a83fccc2SCodrin Ciubotariu /* Enable L2 On MAC2 using SCFG */ 566*a83fccc2SCodrin Ciubotariu struct ccsr_scfg *scfg = (struct ccsr_scfg *) 567*a83fccc2SCodrin Ciubotariu CONFIG_SYS_MPC85xx_SCFG; 568*a83fccc2SCodrin Ciubotariu 569*a83fccc2SCodrin Ciubotariu out_be32(&scfg->esgmiiselcr, 570*a83fccc2SCodrin Ciubotariu in_be32(&scfg->esgmiiselcr) | 571*a83fccc2SCodrin Ciubotariu (0x80000000)); 572*a83fccc2SCodrin Ciubotariu vsc9953_port_enable(i); 573*a83fccc2SCodrin Ciubotariu } 574*a83fccc2SCodrin Ciubotariu break; 575*a83fccc2SCodrin Ciubotariu } 576*a83fccc2SCodrin Ciubotariu 577*a83fccc2SCodrin Ciubotariu if (lane >= 0) { 578*a83fccc2SCodrin Ciubotariu bus = mii_dev_for_muxval(lane_to_slot[lane]); 579*a83fccc2SCodrin Ciubotariu vsc9953_port_info_set_mdio(i, bus); 580*a83fccc2SCodrin Ciubotariu vsc9953_port_enable(i); 581*a83fccc2SCodrin Ciubotariu } 582*a83fccc2SCodrin Ciubotariu vsc9953_port_info_set_phy_address(i, phy_addr); 583*a83fccc2SCodrin Ciubotariu vsc9953_port_info_set_phy_int(i, phy_int); 584*a83fccc2SCodrin Ciubotariu } 585*a83fccc2SCodrin Ciubotariu 586*a83fccc2SCodrin Ciubotariu #endif 5875b7672fcSPrabhakar Kushwaha cpu_eth_init(bis); 5885b7672fcSPrabhakar Kushwaha #endif 5895b7672fcSPrabhakar Kushwaha 5905b7672fcSPrabhakar Kushwaha return pci_eth_init(bis); 5915b7672fcSPrabhakar Kushwaha } 592