1 /* 2 * Micrel PHY drivers 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 * 6 * Copyright 2010-2011 Freescale Semiconductor, Inc. 7 * author Andy Fleming 8 * (C) 2012 NetModule AG, David Andrey, added KSZ9031 9 * (C) Copyright 2017 Adaptrum, Inc. 10 * Written by Alexandru Gagniuc <alex.g@adaptrum.com> for Adaptrum, Inc. 11 */ 12 13 #include <config.h> 14 #include <common.h> 15 #include <dm.h> 16 #include <errno.h> 17 #include <micrel.h> 18 #include <phy.h> 19 20 /* 21 * KSZ9021 - KSZ9031 common 22 */ 23 24 #define MII_KSZ90xx_PHY_CTL 0x1f 25 #define MIIM_KSZ90xx_PHYCTL_1000 (1 << 6) 26 #define MIIM_KSZ90xx_PHYCTL_100 (1 << 5) 27 #define MIIM_KSZ90xx_PHYCTL_10 (1 << 4) 28 #define MIIM_KSZ90xx_PHYCTL_DUPLEX (1 << 3) 29 30 /* KSZ9021 PHY Registers */ 31 #define MII_KSZ9021_EXTENDED_CTRL 0x0b 32 #define MII_KSZ9021_EXTENDED_DATAW 0x0c 33 #define MII_KSZ9021_EXTENDED_DATAR 0x0d 34 35 #define CTRL1000_PREFER_MASTER (1 << 10) 36 #define CTRL1000_CONFIG_MASTER (1 << 11) 37 #define CTRL1000_MANUAL_CONFIG (1 << 12) 38 39 /* KSZ9031 PHY Registers */ 40 #define MII_KSZ9031_MMD_ACCES_CTRL 0x0d 41 #define MII_KSZ9031_MMD_REG_DATA 0x0e 42 43 static int ksz90xx_startup(struct phy_device *phydev) 44 { 45 unsigned phy_ctl; 46 int ret; 47 48 ret = genphy_update_link(phydev); 49 if (ret) 50 return ret; 51 52 phy_ctl = phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ90xx_PHY_CTL); 53 54 if (phy_ctl & MIIM_KSZ90xx_PHYCTL_DUPLEX) 55 phydev->duplex = DUPLEX_FULL; 56 else 57 phydev->duplex = DUPLEX_HALF; 58 59 if (phy_ctl & MIIM_KSZ90xx_PHYCTL_1000) 60 phydev->speed = SPEED_1000; 61 else if (phy_ctl & MIIM_KSZ90xx_PHYCTL_100) 62 phydev->speed = SPEED_100; 63 else if (phy_ctl & MIIM_KSZ90xx_PHYCTL_10) 64 phydev->speed = SPEED_10; 65 return 0; 66 } 67 68 /* Common OF config bits for KSZ9021 and KSZ9031 */ 69 #ifdef CONFIG_DM_ETH 70 struct ksz90x1_reg_field { 71 const char *name; 72 const u8 size; /* Size of the bitfield, in bits */ 73 const u8 off; /* Offset from bit 0 */ 74 const u8 dflt; /* Default value */ 75 }; 76 77 struct ksz90x1_ofcfg { 78 const u16 reg; 79 const u16 devad; 80 const struct ksz90x1_reg_field *grp; 81 const u16 grpsz; 82 }; 83 84 static const struct ksz90x1_reg_field ksz90x1_rxd_grp[] = { 85 { "rxd0-skew-ps", 4, 0, 0x7 }, { "rxd1-skew-ps", 4, 4, 0x7 }, 86 { "rxd2-skew-ps", 4, 8, 0x7 }, { "rxd3-skew-ps", 4, 12, 0x7 } 87 }; 88 89 static const struct ksz90x1_reg_field ksz90x1_txd_grp[] = { 90 { "txd0-skew-ps", 4, 0, 0x7 }, { "txd1-skew-ps", 4, 4, 0x7 }, 91 { "txd2-skew-ps", 4, 8, 0x7 }, { "txd3-skew-ps", 4, 12, 0x7 }, 92 }; 93 94 static const struct ksz90x1_reg_field ksz9021_clk_grp[] = { 95 { "txen-skew-ps", 4, 0, 0x7 }, { "txc-skew-ps", 4, 4, 0x7 }, 96 { "rxdv-skew-ps", 4, 8, 0x7 }, { "rxc-skew-ps", 4, 12, 0x7 }, 97 }; 98 99 static const struct ksz90x1_reg_field ksz9031_ctl_grp[] = { 100 { "txen-skew-ps", 4, 0, 0x7 }, { "rxdv-skew-ps", 4, 4, 0x7 } 101 }; 102 103 static const struct ksz90x1_reg_field ksz9031_clk_grp[] = { 104 { "rxc-skew-ps", 5, 0, 0xf }, { "txc-skew-ps", 5, 5, 0xf } 105 }; 106 107 static int ksz90x1_of_config_group(struct phy_device *phydev, 108 struct ksz90x1_ofcfg *ofcfg) 109 { 110 struct udevice *dev = phydev->dev; 111 struct phy_driver *drv = phydev->drv; 112 const int ps_to_regval = 60; 113 int val[4]; 114 int i, changed = 0, offset, max; 115 u16 regval = 0; 116 117 if (!drv || !drv->writeext) 118 return -EOPNOTSUPP; 119 120 for (i = 0; i < ofcfg->grpsz; i++) { 121 val[i] = dev_read_u32_default(dev, ofcfg->grp[i].name, ~0); 122 offset = ofcfg->grp[i].off; 123 if (val[i] == -1) { 124 /* Default register value for KSZ9021 */ 125 regval |= ofcfg->grp[i].dflt << offset; 126 } else { 127 changed = 1; /* Value was changed in OF */ 128 /* Calculate the register value and fix corner cases */ 129 if (val[i] > ps_to_regval * 0xf) { 130 max = (1 << ofcfg->grp[i].size) - 1; 131 regval |= max << offset; 132 } else { 133 regval |= (val[i] / ps_to_regval) << offset; 134 } 135 } 136 } 137 138 if (!changed) 139 return 0; 140 141 return drv->writeext(phydev, 0, ofcfg->devad, ofcfg->reg, regval); 142 } 143 144 static int ksz9021_of_config(struct phy_device *phydev) 145 { 146 struct ksz90x1_ofcfg ofcfg[] = { 147 { MII_KSZ9021_EXT_RGMII_RX_DATA_SKEW, 0, ksz90x1_rxd_grp, 4 }, 148 { MII_KSZ9021_EXT_RGMII_TX_DATA_SKEW, 0, ksz90x1_txd_grp, 4 }, 149 { MII_KSZ9021_EXT_RGMII_CLOCK_SKEW, 0, ksz9021_clk_grp, 4 }, 150 }; 151 int i, ret = 0; 152 153 for (i = 0; i < ARRAY_SIZE(ofcfg); i++) { 154 ret = ksz90x1_of_config_group(phydev, &(ofcfg[i])); 155 if (ret) 156 return ret; 157 } 158 159 return 0; 160 } 161 162 static int ksz9031_of_config(struct phy_device *phydev) 163 { 164 struct ksz90x1_ofcfg ofcfg[] = { 165 { MII_KSZ9031_EXT_RGMII_CTRL_SIG_SKEW, 2, ksz9031_ctl_grp, 2 }, 166 { MII_KSZ9031_EXT_RGMII_RX_DATA_SKEW, 2, ksz90x1_rxd_grp, 4 }, 167 { MII_KSZ9031_EXT_RGMII_TX_DATA_SKEW, 2, ksz90x1_txd_grp, 4 }, 168 { MII_KSZ9031_EXT_RGMII_CLOCK_SKEW, 2, ksz9031_clk_grp, 2 }, 169 }; 170 int i, ret = 0; 171 172 for (i = 0; i < ARRAY_SIZE(ofcfg); i++) { 173 ret = ksz90x1_of_config_group(phydev, &(ofcfg[i])); 174 if (ret) 175 return ret; 176 } 177 178 return 0; 179 } 180 181 static int ksz9031_center_flp_timing(struct phy_device *phydev) 182 { 183 struct phy_driver *drv = phydev->drv; 184 int ret = 0; 185 186 if (!drv || !drv->writeext) 187 return -EOPNOTSUPP; 188 189 ret = drv->writeext(phydev, 0, 0, MII_KSZ9031_FLP_BURST_TX_LO, 0x1A80); 190 if (ret) 191 return ret; 192 193 ret = drv->writeext(phydev, 0, 0, MII_KSZ9031_FLP_BURST_TX_HI, 0x6); 194 return ret; 195 } 196 197 #else /* !CONFIG_DM_ETH */ 198 static int ksz9021_of_config(struct phy_device *phydev) 199 { 200 return 0; 201 } 202 203 static int ksz9031_of_config(struct phy_device *phydev) 204 { 205 return 0; 206 } 207 208 static int ksz9031_center_flp_timing(struct phy_device *phydev) 209 { 210 return 0; 211 } 212 #endif 213 214 /* 215 * KSZ9021 216 */ 217 int ksz9021_phy_extended_write(struct phy_device *phydev, int regnum, u16 val) 218 { 219 /* extended registers */ 220 phy_write(phydev, MDIO_DEVAD_NONE, 221 MII_KSZ9021_EXTENDED_CTRL, regnum | 0x8000); 222 return phy_write(phydev, MDIO_DEVAD_NONE, 223 MII_KSZ9021_EXTENDED_DATAW, val); 224 } 225 226 int ksz9021_phy_extended_read(struct phy_device *phydev, int regnum) 227 { 228 /* extended registers */ 229 phy_write(phydev, MDIO_DEVAD_NONE, MII_KSZ9021_EXTENDED_CTRL, regnum); 230 return phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ9021_EXTENDED_DATAR); 231 } 232 233 234 static int ksz9021_phy_extread(struct phy_device *phydev, int addr, int devaddr, 235 int regnum) 236 { 237 return ksz9021_phy_extended_read(phydev, regnum); 238 } 239 240 static int ksz9021_phy_extwrite(struct phy_device *phydev, int addr, 241 int devaddr, int regnum, u16 val) 242 { 243 return ksz9021_phy_extended_write(phydev, regnum, val); 244 } 245 246 static int ksz9021_config(struct phy_device *phydev) 247 { 248 unsigned ctrl1000 = 0; 249 const unsigned master = CTRL1000_PREFER_MASTER | 250 CTRL1000_CONFIG_MASTER | CTRL1000_MANUAL_CONFIG; 251 unsigned features = phydev->drv->features; 252 int ret; 253 254 ret = ksz9021_of_config(phydev); 255 if (ret) 256 return ret; 257 258 if (env_get("disable_giga")) 259 features &= ~(SUPPORTED_1000baseT_Half | 260 SUPPORTED_1000baseT_Full); 261 /* force master mode for 1000BaseT due to chip errata */ 262 if (features & SUPPORTED_1000baseT_Half) 263 ctrl1000 |= ADVERTISE_1000HALF | master; 264 if (features & SUPPORTED_1000baseT_Full) 265 ctrl1000 |= ADVERTISE_1000FULL | master; 266 phydev->advertising = features; 267 phydev->supported = features; 268 phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, ctrl1000); 269 genphy_config_aneg(phydev); 270 genphy_restart_aneg(phydev); 271 return 0; 272 } 273 274 static struct phy_driver ksz9021_driver = { 275 .name = "Micrel ksz9021", 276 .uid = 0x221610, 277 .mask = 0xfffff0, 278 .features = PHY_GBIT_FEATURES, 279 .config = &ksz9021_config, 280 .startup = &ksz90xx_startup, 281 .shutdown = &genphy_shutdown, 282 .writeext = &ksz9021_phy_extwrite, 283 .readext = &ksz9021_phy_extread, 284 }; 285 286 /* 287 * KSZ9031 288 */ 289 int ksz9031_phy_extended_write(struct phy_device *phydev, 290 int devaddr, int regnum, u16 mode, u16 val) 291 { 292 /*select register addr for mmd*/ 293 phy_write(phydev, MDIO_DEVAD_NONE, 294 MII_KSZ9031_MMD_ACCES_CTRL, devaddr); 295 /*select register for mmd*/ 296 phy_write(phydev, MDIO_DEVAD_NONE, 297 MII_KSZ9031_MMD_REG_DATA, regnum); 298 /*setup mode*/ 299 phy_write(phydev, MDIO_DEVAD_NONE, 300 MII_KSZ9031_MMD_ACCES_CTRL, (mode | devaddr)); 301 /*write the value*/ 302 return phy_write(phydev, MDIO_DEVAD_NONE, 303 MII_KSZ9031_MMD_REG_DATA, val); 304 } 305 306 int ksz9031_phy_extended_read(struct phy_device *phydev, int devaddr, 307 int regnum, u16 mode) 308 { 309 phy_write(phydev, MDIO_DEVAD_NONE, 310 MII_KSZ9031_MMD_ACCES_CTRL, devaddr); 311 phy_write(phydev, MDIO_DEVAD_NONE, 312 MII_KSZ9031_MMD_REG_DATA, regnum); 313 phy_write(phydev, MDIO_DEVAD_NONE, 314 MII_KSZ9031_MMD_ACCES_CTRL, (devaddr | mode)); 315 return phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ9031_MMD_REG_DATA); 316 } 317 318 static int ksz9031_phy_extread(struct phy_device *phydev, int addr, int devaddr, 319 int regnum) 320 { 321 return ksz9031_phy_extended_read(phydev, devaddr, regnum, 322 MII_KSZ9031_MOD_DATA_NO_POST_INC); 323 } 324 325 static int ksz9031_phy_extwrite(struct phy_device *phydev, int addr, 326 int devaddr, int regnum, u16 val) 327 { 328 return ksz9031_phy_extended_write(phydev, devaddr, regnum, 329 MII_KSZ9031_MOD_DATA_POST_INC_RW, val); 330 } 331 332 static int ksz9031_config(struct phy_device *phydev) 333 { 334 int ret; 335 336 ret = ksz9031_of_config(phydev); 337 if (ret) 338 return ret; 339 ret = ksz9031_center_flp_timing(phydev); 340 if (ret) 341 return ret; 342 343 /* add an option to disable the gigabit feature of this PHY */ 344 if (env_get("disable_giga")) { 345 unsigned features; 346 unsigned bmcr; 347 348 /* disable speed 1000 in features supported by the PHY */ 349 features = phydev->drv->features; 350 features &= ~(SUPPORTED_1000baseT_Half | 351 SUPPORTED_1000baseT_Full); 352 phydev->advertising = phydev->supported = features; 353 354 /* disable speed 1000 in Basic Control Register */ 355 bmcr = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR); 356 bmcr &= ~(1 << 6); 357 phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, bmcr); 358 359 /* disable speed 1000 in 1000Base-T Control Register */ 360 phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, 0); 361 362 /* start autoneg */ 363 genphy_config_aneg(phydev); 364 genphy_restart_aneg(phydev); 365 366 return 0; 367 } 368 369 return genphy_config(phydev); 370 } 371 372 static struct phy_driver ksz9031_driver = { 373 .name = "Micrel ksz9031", 374 .uid = 0x221620, 375 .mask = 0xfffff0, 376 .features = PHY_GBIT_FEATURES, 377 .config = &ksz9031_config, 378 .startup = &ksz90xx_startup, 379 .shutdown = &genphy_shutdown, 380 .writeext = &ksz9031_phy_extwrite, 381 .readext = &ksz9031_phy_extread, 382 }; 383 384 int phy_micrel_ksz90x1_init(void) 385 { 386 phy_register(&ksz9021_driver); 387 phy_register(&ksz9031_driver); 388 return 0; 389 } 390