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