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