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 printf("%s %d\n", __func__, priv->gemac_port); 166 167 /* PCS configuration done with corresponding GEMAC */ 168 bus.priv = gem_info[priv->gemac_port].gemac_base; 169 170 pfe_phy_read(&bus, 0, MDIO_DEVAD_NONE, 0x0); 171 pfe_phy_read(&bus, 0, MDIO_DEVAD_NONE, 0x1); 172 pfe_phy_read(&bus, 0, MDIO_DEVAD_NONE, 0x2); 173 pfe_phy_read(&bus, 0, MDIO_DEVAD_NONE, 0x3); 174 175 /* Reset serdes */ 176 pfe_phy_write(&bus, 0, MDIO_DEVAD_NONE, 0x0, 0x8000); 177 178 /* SGMII IF mode + AN enable only for 1G SGMII, not for 2.5G */ 179 value = PHY_SGMII_IF_MODE_SGMII; 180 if (!sgmii_2500) 181 value |= PHY_SGMII_IF_MODE_AN; 182 else 183 value |= PHY_SGMII_IF_MODE_SGMII_GBT; 184 185 pfe_phy_write(&bus, 0, MDIO_DEVAD_NONE, 0x14, value); 186 187 /* Dev ability according to SGMII specification */ 188 value = PHY_SGMII_DEV_ABILITY_SGMII; 189 pfe_phy_write(&bus, 0, MDIO_DEVAD_NONE, 0x4, value); 190 191 /* These values taken from validation team */ 192 if (!sgmii_2500) { 193 pfe_phy_write(&bus, 0, MDIO_DEVAD_NONE, 0x13, 0x0); 194 pfe_phy_write(&bus, 0, MDIO_DEVAD_NONE, 0x12, 0x400); 195 } else { 196 pfe_phy_write(&bus, 0, MDIO_DEVAD_NONE, 0x13, 0x7); 197 pfe_phy_write(&bus, 0, MDIO_DEVAD_NONE, 0x12, 0xa120); 198 } 199 200 /* Restart AN */ 201 value = PHY_SGMII_CR_DEF_VAL; 202 if (!sgmii_2500) 203 value |= PHY_SGMII_CR_RESET_AN; 204 /* Disable Auto neg for 2.5G SGMII as it doesn't support auto neg*/ 205 if (sgmii_2500) 206 value &= ~PHY_SGMII_ENABLE_AN; 207 pfe_phy_write(&bus, 0, MDIO_DEVAD_NONE, 0, value); 208 } 209 210 int pfe_phy_configure(struct pfe_eth_dev *priv, int dev_id, int phy_id) 211 { 212 struct phy_device *phydev = NULL; 213 struct udevice *dev = priv->dev; 214 struct gemac_s *gem = priv->gem; 215 struct ccsr_scfg *scfg = (struct ccsr_scfg *)CONFIG_SYS_FSL_SCFG_ADDR; 216 217 if (!gem->bus) 218 return -1; 219 220 /* Configure SGMII PCS */ 221 if (gem->phy_mode == PHY_INTERFACE_MODE_SGMII || 222 gem->phy_mode == PHY_INTERFACE_MODE_SGMII_2500) { 223 out_be32(&scfg->mdioselcr, 0x00000000); 224 pfe_configure_serdes(priv); 225 } 226 227 mdelay(100); 228 229 /* By this time on-chip SGMII initialization is done 230 * we can switch mdio interface to external PHYs 231 */ 232 out_be32(&scfg->mdioselcr, 0x80000000); 233 234 phydev = phy_connect(gem->bus, phy_id, dev, gem->phy_mode); 235 if (!phydev) { 236 printf("phy_connect failed\n"); 237 return -ENODEV; 238 } 239 240 phy_config(phydev); 241 242 priv->phydev = phydev; 243 244 return 0; 245 } 246 #endif 247 248 struct mii_dev *pfe_mdio_init(struct pfe_mdio_info *mdio_info) 249 { 250 struct mii_dev *bus; 251 int ret; 252 u32 mdio_speed; 253 u32 pclk = 250000000; 254 255 bus = mdio_alloc(); 256 if (!bus) { 257 printf("mdio_alloc failed\n"); 258 return NULL; 259 } 260 bus->read = pfe_phy_read; 261 bus->write = pfe_phy_write; 262 263 /* MAC1 MDIO used to communicate with external PHYS */ 264 bus->priv = mdio_info->reg_base; 265 sprintf(bus->name, mdio_info->name); 266 267 /* configure mdio speed */ 268 mdio_speed = (DIV_ROUND_UP(pclk, 4000000) << EMAC_MII_SPEED_SHIFT); 269 mdio_speed |= EMAC_HOLDTIME(0x5); 270 writel(mdio_speed, mdio_info->reg_base + EMAC_MII_CTRL_REG); 271 272 ret = mdio_register(bus); 273 if (ret) { 274 printf("mdio_register failed\n"); 275 free(bus); 276 return NULL; 277 } 278 return bus; 279 } 280 281 void pfe_set_mdio(int dev_id, struct mii_dev *bus) 282 { 283 gem_info[dev_id].bus = bus; 284 } 285 286 void pfe_set_phy_address_mode(int dev_id, int phy_id, int phy_mode) 287 { 288 gem_info[dev_id].phy_address = phy_id; 289 gem_info[dev_id].phy_mode = phy_mode; 290 } 291