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