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