1 /* 2 * Copyright 2014 Freescale Semiconductor, Inc. 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 * 6 * This file handles the board muxing between the RGMII/SGMII PHYs on 7 * Freescale LS1021AQDS board. The RGMII PHYs are the three on-board 1Gb 8 * ports. The SGMII PHYs are provided by the standard Freescale four-port 9 * SGMII riser card. 10 * 11 * Muxing is handled via the PIXIS BRDCFG4 register. The EMI1 bits control 12 * muxing among the RGMII PHYs and the SGMII PHYs. The value for RGMII depends 13 * on which port is used. The value for SGMII depends on which slot the riser 14 * is inserted in. 15 */ 16 17 #include <common.h> 18 #include <netdev.h> 19 #include <asm/arch/fsl_serdes.h> 20 #include <fsl_mdio.h> 21 #include <tsec.h> 22 #include <malloc.h> 23 24 #include "../common/sgmii_riser.h" 25 #include "../common/qixis.h" 26 27 #define EMI1_MASK 0x1f 28 #define EMI1_RGMII0 1 29 #define EMI1_RGMII1 2 30 #define EMI1_RGMII2 3 31 #define EMI1_SGMII1 0x1c 32 #define EMI1_SGMII2 0x1d 33 34 struct ls1021a_mdio { 35 struct mii_dev *realbus; 36 }; 37 38 static void ls1021a_mux_mdio(int addr) 39 { 40 u8 brdcfg4; 41 42 brdcfg4 = QIXIS_READ(brdcfg[4]); 43 brdcfg4 &= EMI1_MASK; 44 45 switch (addr) { 46 case EMI1_RGMII0: 47 brdcfg4 |= 0; 48 break; 49 case EMI1_RGMII1: 50 brdcfg4 |= 0x20; 51 break; 52 case EMI1_RGMII2: 53 brdcfg4 |= 0x40; 54 break; 55 case EMI1_SGMII1: 56 brdcfg4 |= 0x60; 57 break; 58 case EMI1_SGMII2: 59 brdcfg4 |= 0x80; 60 break; 61 default: 62 brdcfg4 |= 0xa0; 63 break; 64 } 65 66 QIXIS_WRITE(brdcfg[4], brdcfg4); 67 } 68 69 static int ls1021a_mdio_read(struct mii_dev *bus, int addr, int devad, 70 int regnum) 71 { 72 struct ls1021a_mdio *priv = bus->priv; 73 74 ls1021a_mux_mdio(addr); 75 76 return priv->realbus->read(priv->realbus, addr, devad, regnum); 77 } 78 79 static int ls1021a_mdio_write(struct mii_dev *bus, int addr, int devad, 80 int regnum, u16 value) 81 { 82 struct ls1021a_mdio *priv = bus->priv; 83 84 ls1021a_mux_mdio(addr); 85 86 return priv->realbus->write(priv->realbus, addr, devad, regnum, value); 87 } 88 89 static int ls1021a_mdio_reset(struct mii_dev *bus) 90 { 91 struct ls1021a_mdio *priv = bus->priv; 92 93 return priv->realbus->reset(priv->realbus); 94 } 95 96 static int ls1021a_mdio_init(char *realbusname, char *fakebusname) 97 { 98 struct ls1021a_mdio *lsmdio; 99 struct mii_dev *bus = mdio_alloc(); 100 101 if (!bus) { 102 printf("Failed to allocate LS102xA MDIO bus\n"); 103 return -1; 104 } 105 106 lsmdio = malloc(sizeof(*lsmdio)); 107 if (!lsmdio) { 108 printf("Failed to allocate LS102xA private data\n"); 109 free(bus); 110 return -1; 111 } 112 113 bus->read = ls1021a_mdio_read; 114 bus->write = ls1021a_mdio_write; 115 bus->reset = ls1021a_mdio_reset; 116 sprintf(bus->name, fakebusname); 117 118 lsmdio->realbus = miiphy_get_dev_by_name(realbusname); 119 120 if (!lsmdio->realbus) { 121 printf("No bus with name %s\n", realbusname); 122 free(bus); 123 free(lsmdio); 124 return -1; 125 } 126 127 bus->priv = lsmdio; 128 129 return mdio_register(bus); 130 } 131 132 int board_eth_init(bd_t *bis) 133 { 134 struct fsl_pq_mdio_info mdio_info; 135 struct tsec_info_struct tsec_info[3]; 136 int num = 0; 137 138 #ifdef CONFIG_TSEC1 139 SET_STD_TSEC_INFO(tsec_info[num], 1); 140 if (is_serdes_configured(SGMII_TSEC1)) { 141 puts("eTSEC1 is in sgmii mode\n"); 142 tsec_info[num].flags |= TSEC_SGMII; 143 tsec_info[num].mii_devname = "LS1021A_SGMII_MDIO"; 144 } else { 145 tsec_info[num].mii_devname = "LS1021A_RGMII_MDIO"; 146 } 147 num++; 148 #endif 149 #ifdef CONFIG_TSEC2 150 SET_STD_TSEC_INFO(tsec_info[num], 2); 151 if (is_serdes_configured(SGMII_TSEC2)) { 152 puts("eTSEC2 is in sgmii mode\n"); 153 tsec_info[num].flags |= TSEC_SGMII; 154 tsec_info[num].mii_devname = "LS1021A_SGMII_MDIO"; 155 } else { 156 tsec_info[num].mii_devname = "LS1021A_RGMII_MDIO"; 157 } 158 num++; 159 #endif 160 #ifdef CONFIG_TSEC3 161 SET_STD_TSEC_INFO(tsec_info[num], 3); 162 tsec_info[num].mii_devname = "LS1021A_RGMII_MDIO"; 163 num++; 164 #endif 165 if (!num) { 166 printf("No TSECs initialized\n"); 167 return 0; 168 } 169 170 #ifdef CONFIG_FSL_SGMII_RISER 171 fsl_sgmii_riser_init(tsec_info, num); 172 #endif 173 174 mdio_info.regs = (struct tsec_mii_mng *)CONFIG_SYS_MDIO_BASE_ADDR; 175 mdio_info.name = DEFAULT_MII_NAME; 176 177 fsl_pq_mdio_init(bis, &mdio_info); 178 179 /* Register the virtual MDIO front-ends */ 180 ls1021a_mdio_init(DEFAULT_MII_NAME, "LS1021A_RGMII_MDIO"); 181 ls1021a_mdio_init(DEFAULT_MII_NAME, "LS1021A_SGMII_MDIO"); 182 183 tsec_eth_init(bis, tsec_info, num); 184 185 return pci_eth_init(bis); 186 } 187