1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright 2015-2016 Freescale Semiconductor, Inc. 4 * Copyright 2017 NXP 5 */ 6 #include <common.h> 7 #include <dm.h> 8 #include <dm/platform_data/pfe_dm_eth.h> 9 #include <net.h> 10 #include <net/pfe_eth/pfe_eth.h> 11 12 extern struct gemac_s gem_info[]; 13 #if defined(CONFIG_PHYLIB) 14 15 #define MDIO_TIMEOUT 5000 16 static int pfe_write_addr(struct mii_dev *bus, int phy_addr, int dev_addr, 17 int reg_addr) 18 { 19 void *reg_base = bus->priv; 20 u32 devadr; 21 u32 phy; 22 u32 reg_data; 23 int timeout = MDIO_TIMEOUT; 24 25 devadr = ((dev_addr & EMAC_MII_DATA_RA_MASK) << EMAC_MII_DATA_RA_SHIFT); 26 phy = ((phy_addr & EMAC_MII_DATA_PA_MASK) << EMAC_MII_DATA_PA_SHIFT); 27 28 reg_data = (EMAC_MII_DATA_TA | phy | devadr | reg_addr); 29 30 writel(reg_data, reg_base + EMAC_MII_DATA_REG); 31 32 /* 33 * wait for the MII interrupt 34 */ 35 while (!(readl(reg_base + EMAC_IEVENT_REG) & EMAC_IEVENT_MII)) { 36 if (timeout-- <= 0) { 37 printf("Phy MDIO read/write timeout\n"); 38 return -1; 39 } 40 } 41 42 /* 43 * clear MII interrupt 44 */ 45 writel(EMAC_IEVENT_MII, reg_base + EMAC_IEVENT_REG); 46 47 return 0; 48 } 49 50 static int pfe_phy_read(struct mii_dev *bus, int phy_addr, int dev_addr, 51 int reg_addr) 52 { 53 void *reg_base = bus->priv; 54 u32 reg; 55 u32 phy; 56 u32 reg_data; 57 u16 val; 58 int timeout = MDIO_TIMEOUT; 59 60 if (dev_addr == MDIO_DEVAD_NONE) { 61 reg = ((reg_addr & EMAC_MII_DATA_RA_MASK) << 62 EMAC_MII_DATA_RA_SHIFT); 63 } else { 64 pfe_write_addr(bus, phy_addr, dev_addr, reg_addr); 65 reg = ((dev_addr & EMAC_MII_DATA_RA_MASK) << 66 EMAC_MII_DATA_RA_SHIFT); 67 } 68 69 phy = ((phy_addr & EMAC_MII_DATA_PA_MASK) << EMAC_MII_DATA_PA_SHIFT); 70 71 if (dev_addr == MDIO_DEVAD_NONE) 72 reg_data = (EMAC_MII_DATA_ST | EMAC_MII_DATA_OP_RD | 73 EMAC_MII_DATA_TA | phy | reg); 74 else 75 reg_data = (EMAC_MII_DATA_OP_CL45_RD | EMAC_MII_DATA_TA | 76 phy | reg); 77 78 writel(reg_data, reg_base + EMAC_MII_DATA_REG); 79 80 /* 81 * wait for the MII interrupt 82 */ 83 while (!(readl(reg_base + EMAC_IEVENT_REG) & EMAC_IEVENT_MII)) { 84 if (timeout-- <= 0) { 85 printf("Phy MDIO read/write timeout\n"); 86 return -1; 87 } 88 } 89 90 /* 91 * clear MII interrupt 92 */ 93 writel(EMAC_IEVENT_MII, reg_base + EMAC_IEVENT_REG); 94 95 /* 96 * it's now safe to read the PHY's register 97 */ 98 val = (u16)readl(reg_base + EMAC_MII_DATA_REG); 99 debug("%s: %p phy: 0x%x reg:0x%08x val:%#x\n", __func__, reg_base, 100 phy_addr, reg_addr, val); 101 102 return val; 103 } 104 105 static int pfe_phy_write(struct mii_dev *bus, int phy_addr, int dev_addr, 106 int reg_addr, u16 data) 107 { 108 void *reg_base = bus->priv; 109 u32 reg; 110 u32 phy; 111 u32 reg_data; 112 int timeout = MDIO_TIMEOUT; 113 int val; 114 115 if (dev_addr == MDIO_DEVAD_NONE) { 116 reg = ((reg_addr & EMAC_MII_DATA_RA_MASK) << 117 EMAC_MII_DATA_RA_SHIFT); 118 } else { 119 pfe_write_addr(bus, phy_addr, dev_addr, reg_addr); 120 reg = ((dev_addr & EMAC_MII_DATA_RA_MASK) << 121 EMAC_MII_DATA_RA_SHIFT); 122 } 123 124 phy = ((phy_addr & EMAC_MII_DATA_PA_MASK) << EMAC_MII_DATA_PA_SHIFT); 125 126 if (dev_addr == MDIO_DEVAD_NONE) 127 reg_data = (EMAC_MII_DATA_ST | EMAC_MII_DATA_OP_WR | 128 EMAC_MII_DATA_TA | phy | reg | data); 129 else 130 reg_data = (EMAC_MII_DATA_OP_CL45_WR | EMAC_MII_DATA_TA | 131 phy | reg | data); 132 133 writel(reg_data, reg_base + EMAC_MII_DATA_REG); 134 135 /* 136 * wait for the MII interrupt 137 */ 138 while (!(readl(reg_base + EMAC_IEVENT_REG) & EMAC_IEVENT_MII)) { 139 if (timeout-- <= 0) { 140 printf("Phy MDIO read/write timeout\n"); 141 return -1; 142 } 143 } 144 145 /* 146 * clear MII interrupt 147 */ 148 writel(EMAC_IEVENT_MII, reg_base + EMAC_IEVENT_REG); 149 150 debug("%s: phy: %02x reg:%02x val:%#x\n", __func__, phy_addr, 151 reg_addr, data); 152 153 return val; 154 } 155 156 static void pfe_configure_serdes(struct pfe_eth_dev *priv) 157 { 158 struct mii_dev bus; 159 int value, sgmii_2500 = 0; 160 struct gemac_s *gem = priv->gem; 161 162 if (gem->phy_mode == PHY_INTERFACE_MODE_SGMII_2500) 163 sgmii_2500 = 1; 164 165 166 /* PCS configuration done with corresponding GEMAC */ 167 bus.priv = gem_info[priv->gemac_port].gemac_base; 168 169 pfe_phy_read(&bus, 0, MDIO_DEVAD_NONE, 0x0); 170 pfe_phy_read(&bus, 0, MDIO_DEVAD_NONE, 0x1); 171 pfe_phy_read(&bus, 0, MDIO_DEVAD_NONE, 0x2); 172 pfe_phy_read(&bus, 0, MDIO_DEVAD_NONE, 0x3); 173 174 /* Reset serdes */ 175 pfe_phy_write(&bus, 0, MDIO_DEVAD_NONE, 0x0, 0x8000); 176 177 /* SGMII IF mode + AN enable only for 1G SGMII, not for 2.5G */ 178 value = PHY_SGMII_IF_MODE_SGMII; 179 if (!sgmii_2500) 180 value |= PHY_SGMII_IF_MODE_AN; 181 else 182 value |= PHY_SGMII_IF_MODE_SGMII_GBT; 183 184 pfe_phy_write(&bus, 0, MDIO_DEVAD_NONE, 0x14, value); 185 186 /* Dev ability according to SGMII specification */ 187 value = PHY_SGMII_DEV_ABILITY_SGMII; 188 pfe_phy_write(&bus, 0, MDIO_DEVAD_NONE, 0x4, value); 189 190 /* These values taken from validation team */ 191 if (!sgmii_2500) { 192 pfe_phy_write(&bus, 0, MDIO_DEVAD_NONE, 0x13, 0x0); 193 pfe_phy_write(&bus, 0, MDIO_DEVAD_NONE, 0x12, 0x400); 194 } else { 195 pfe_phy_write(&bus, 0, MDIO_DEVAD_NONE, 0x13, 0x7); 196 pfe_phy_write(&bus, 0, MDIO_DEVAD_NONE, 0x12, 0xa120); 197 } 198 199 /* Restart AN */ 200 value = PHY_SGMII_CR_DEF_VAL; 201 if (!sgmii_2500) 202 value |= PHY_SGMII_CR_RESET_AN; 203 /* Disable Auto neg for 2.5G SGMII as it doesn't support auto neg*/ 204 if (sgmii_2500) 205 value &= ~PHY_SGMII_ENABLE_AN; 206 pfe_phy_write(&bus, 0, MDIO_DEVAD_NONE, 0, value); 207 } 208 209 int pfe_phy_configure(struct pfe_eth_dev *priv, int dev_id, int phy_id) 210 { 211 struct phy_device *phydev = NULL; 212 struct udevice *dev = priv->dev; 213 struct gemac_s *gem = priv->gem; 214 struct ccsr_scfg *scfg = (struct ccsr_scfg *)CONFIG_SYS_FSL_SCFG_ADDR; 215 216 if (!gem->bus) 217 return -1; 218 219 /* Configure SGMII PCS */ 220 if (gem->phy_mode == PHY_INTERFACE_MODE_SGMII || 221 gem->phy_mode == PHY_INTERFACE_MODE_SGMII_2500) { 222 out_be32(&scfg->mdioselcr, 0x00000000); 223 pfe_configure_serdes(priv); 224 } 225 226 mdelay(100); 227 228 /* By this time on-chip SGMII initialization is done 229 * we can switch mdio interface to external PHYs 230 */ 231 out_be32(&scfg->mdioselcr, 0x80000000); 232 233 phydev = phy_connect(gem->bus, phy_id, dev, gem->phy_mode); 234 if (!phydev) { 235 printf("phy_connect failed\n"); 236 return -ENODEV; 237 } 238 239 phy_config(phydev); 240 241 priv->phydev = phydev; 242 243 return 0; 244 } 245 #endif 246 247 struct mii_dev *pfe_mdio_init(struct pfe_mdio_info *mdio_info) 248 { 249 struct mii_dev *bus; 250 int ret; 251 u32 mdio_speed; 252 u32 pclk = 250000000; 253 254 bus = mdio_alloc(); 255 if (!bus) { 256 printf("mdio_alloc failed\n"); 257 return NULL; 258 } 259 bus->read = pfe_phy_read; 260 bus->write = pfe_phy_write; 261 262 /* MAC1 MDIO used to communicate with external PHYS */ 263 bus->priv = mdio_info->reg_base; 264 sprintf(bus->name, mdio_info->name); 265 266 /* configure mdio speed */ 267 mdio_speed = (DIV_ROUND_UP(pclk, 4000000) << EMAC_MII_SPEED_SHIFT); 268 mdio_speed |= EMAC_HOLDTIME(0x5); 269 writel(mdio_speed, mdio_info->reg_base + EMAC_MII_CTRL_REG); 270 271 ret = mdio_register(bus); 272 if (ret) { 273 printf("mdio_register failed\n"); 274 free(bus); 275 return NULL; 276 } 277 return bus; 278 } 279 280 void pfe_set_mdio(int dev_id, struct mii_dev *bus) 281 { 282 gem_info[dev_id].bus = bus; 283 } 284 285 void pfe_set_phy_address_mode(int dev_id, int phy_id, int phy_mode) 286 { 287 gem_info[dev_id].phy_address = phy_id; 288 gem_info[dev_id].phy_mode = phy_mode; 289 } 290