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 #include <config.h> 13 #include <common.h> 14 #include <dm.h> 15 #include <errno.h> 16 #include <fdtdec.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] = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev), 124 ofcfg->grp[i].name, -1); 125 offset = ofcfg->grp[i].off; 126 if (val[i] == -1) { 127 /* Default register value for KSZ9021 */ 128 regval |= ofcfg->grp[i].dflt << offset; 129 } else { 130 changed = 1; /* Value was changed in OF */ 131 /* Calculate the register value and fix corner cases */ 132 if (val[i] > ps_to_regval * 0xf) { 133 max = (1 << ofcfg->grp[i].size) - 1; 134 regval |= max << offset; 135 } else { 136 regval |= (val[i] / ps_to_regval) << offset; 137 } 138 } 139 } 140 141 if (!changed) 142 return 0; 143 144 return drv->writeext(phydev, 0, ofcfg->devad, ofcfg->reg, regval); 145 } 146 147 static int ksz9021_of_config(struct phy_device *phydev) 148 { 149 struct ksz90x1_ofcfg ofcfg[] = { 150 { MII_KSZ9021_EXT_RGMII_RX_DATA_SKEW, 0, ksz90x1_rxd_grp, 4 }, 151 { MII_KSZ9021_EXT_RGMII_TX_DATA_SKEW, 0, ksz90x1_txd_grp, 4 }, 152 { MII_KSZ9021_EXT_RGMII_CLOCK_SKEW, 0, ksz9021_clk_grp, 4 }, 153 }; 154 int i, ret = 0; 155 156 for (i = 0; i < ARRAY_SIZE(ofcfg); i++) { 157 ret = ksz90x1_of_config_group(phydev, &(ofcfg[i])); 158 if (ret) 159 return ret; 160 } 161 162 return 0; 163 } 164 165 static int ksz9031_of_config(struct phy_device *phydev) 166 { 167 struct ksz90x1_ofcfg ofcfg[] = { 168 { MII_KSZ9031_EXT_RGMII_CTRL_SIG_SKEW, 2, ksz9031_ctl_grp, 2 }, 169 { MII_KSZ9031_EXT_RGMII_RX_DATA_SKEW, 2, ksz90x1_rxd_grp, 4 }, 170 { MII_KSZ9031_EXT_RGMII_TX_DATA_SKEW, 2, ksz90x1_txd_grp, 4 }, 171 { MII_KSZ9031_EXT_RGMII_CLOCK_SKEW, 2, ksz9031_clk_grp, 2 }, 172 }; 173 int i, ret = 0; 174 175 for (i = 0; i < ARRAY_SIZE(ofcfg); i++) { 176 ret = ksz90x1_of_config_group(phydev, &(ofcfg[i])); 177 if (ret) 178 return ret; 179 } 180 181 return 0; 182 } 183 184 static int ksz9031_center_flp_timing(struct phy_device *phydev) 185 { 186 struct phy_driver *drv = phydev->drv; 187 int ret = 0; 188 189 if (!drv || !drv->writeext) 190 return -EOPNOTSUPP; 191 192 ret = drv->writeext(phydev, 0, 0, MII_KSZ9031_FLP_BURST_TX_LO, 0x1A80); 193 if (ret) 194 return ret; 195 196 ret = drv->writeext(phydev, 0, 0, MII_KSZ9031_FLP_BURST_TX_HI, 0x6); 197 return ret; 198 } 199 200 #else /* !CONFIG_DM_ETH */ 201 static int ksz9021_of_config(struct phy_device *phydev) 202 { 203 return 0; 204 } 205 206 static int ksz9031_of_config(struct phy_device *phydev) 207 { 208 return 0; 209 } 210 211 static int ksz9031_center_flp_timing(struct phy_device *phydev) 212 { 213 return 0; 214 } 215 #endif 216 217 /* 218 * KSZ9021 219 */ 220 int ksz9021_phy_extended_write(struct phy_device *phydev, int regnum, u16 val) 221 { 222 /* extended registers */ 223 phy_write(phydev, MDIO_DEVAD_NONE, 224 MII_KSZ9021_EXTENDED_CTRL, regnum | 0x8000); 225 return phy_write(phydev, MDIO_DEVAD_NONE, 226 MII_KSZ9021_EXTENDED_DATAW, val); 227 } 228 229 int ksz9021_phy_extended_read(struct phy_device *phydev, int regnum) 230 { 231 /* extended registers */ 232 phy_write(phydev, MDIO_DEVAD_NONE, MII_KSZ9021_EXTENDED_CTRL, regnum); 233 return phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ9021_EXTENDED_DATAR); 234 } 235 236 237 static int ksz9021_phy_extread(struct phy_device *phydev, int addr, int devaddr, 238 int regnum) 239 { 240 return ksz9021_phy_extended_read(phydev, regnum); 241 } 242 243 static int ksz9021_phy_extwrite(struct phy_device *phydev, int addr, 244 int devaddr, int regnum, u16 val) 245 { 246 return ksz9021_phy_extended_write(phydev, regnum, val); 247 } 248 249 static int ksz9021_config(struct phy_device *phydev) 250 { 251 unsigned ctrl1000 = 0; 252 const unsigned master = CTRL1000_PREFER_MASTER | 253 CTRL1000_CONFIG_MASTER | CTRL1000_MANUAL_CONFIG; 254 unsigned features = phydev->drv->features; 255 int ret; 256 257 ret = ksz9021_of_config(phydev); 258 if (ret) 259 return ret; 260 261 if (env_get("disable_giga")) 262 features &= ~(SUPPORTED_1000baseT_Half | 263 SUPPORTED_1000baseT_Full); 264 /* force master mode for 1000BaseT due to chip errata */ 265 if (features & SUPPORTED_1000baseT_Half) 266 ctrl1000 |= ADVERTISE_1000HALF | master; 267 if (features & SUPPORTED_1000baseT_Full) 268 ctrl1000 |= ADVERTISE_1000FULL | master; 269 phydev->advertising = features; 270 phydev->supported = features; 271 phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, ctrl1000); 272 genphy_config_aneg(phydev); 273 genphy_restart_aneg(phydev); 274 return 0; 275 } 276 277 static struct phy_driver ksz9021_driver = { 278 .name = "Micrel ksz9021", 279 .uid = 0x221610, 280 .mask = 0xfffff0, 281 .features = PHY_GBIT_FEATURES, 282 .config = &ksz9021_config, 283 .startup = &ksz90xx_startup, 284 .shutdown = &genphy_shutdown, 285 .writeext = &ksz9021_phy_extwrite, 286 .readext = &ksz9021_phy_extread, 287 }; 288 289 /* 290 * KSZ9031 291 */ 292 int ksz9031_phy_extended_write(struct phy_device *phydev, 293 int devaddr, int regnum, u16 mode, u16 val) 294 { 295 /*select register addr for mmd*/ 296 phy_write(phydev, MDIO_DEVAD_NONE, 297 MII_KSZ9031_MMD_ACCES_CTRL, devaddr); 298 /*select register for mmd*/ 299 phy_write(phydev, MDIO_DEVAD_NONE, 300 MII_KSZ9031_MMD_REG_DATA, regnum); 301 /*setup mode*/ 302 phy_write(phydev, MDIO_DEVAD_NONE, 303 MII_KSZ9031_MMD_ACCES_CTRL, (mode | devaddr)); 304 /*write the value*/ 305 return phy_write(phydev, MDIO_DEVAD_NONE, 306 MII_KSZ9031_MMD_REG_DATA, val); 307 } 308 309 int ksz9031_phy_extended_read(struct phy_device *phydev, int devaddr, 310 int regnum, u16 mode) 311 { 312 phy_write(phydev, MDIO_DEVAD_NONE, 313 MII_KSZ9031_MMD_ACCES_CTRL, devaddr); 314 phy_write(phydev, MDIO_DEVAD_NONE, 315 MII_KSZ9031_MMD_REG_DATA, regnum); 316 phy_write(phydev, MDIO_DEVAD_NONE, 317 MII_KSZ9031_MMD_ACCES_CTRL, (devaddr | mode)); 318 return phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ9031_MMD_REG_DATA); 319 } 320 321 static int ksz9031_phy_extread(struct phy_device *phydev, int addr, int devaddr, 322 int regnum) 323 { 324 return ksz9031_phy_extended_read(phydev, devaddr, regnum, 325 MII_KSZ9031_MOD_DATA_NO_POST_INC); 326 } 327 328 static int ksz9031_phy_extwrite(struct phy_device *phydev, int addr, 329 int devaddr, int regnum, u16 val) 330 { 331 return ksz9031_phy_extended_write(phydev, devaddr, regnum, 332 MII_KSZ9031_MOD_DATA_POST_INC_RW, val); 333 } 334 335 static int ksz9031_config(struct phy_device *phydev) 336 { 337 int ret; 338 339 ret = ksz9031_of_config(phydev); 340 if (ret) 341 return ret; 342 ret = ksz9031_center_flp_timing(phydev); 343 if (ret) 344 return ret; 345 346 /* add an option to disable the gigabit feature of this PHY */ 347 if (env_get("disable_giga")) { 348 unsigned features; 349 unsigned bmcr; 350 351 /* disable speed 1000 in features supported by the PHY */ 352 features = phydev->drv->features; 353 features &= ~(SUPPORTED_1000baseT_Half | 354 SUPPORTED_1000baseT_Full); 355 phydev->advertising = phydev->supported = features; 356 357 /* disable speed 1000 in Basic Control Register */ 358 bmcr = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR); 359 bmcr &= ~(1 << 6); 360 phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, bmcr); 361 362 /* disable speed 1000 in 1000Base-T Control Register */ 363 phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, 0); 364 365 /* start autoneg */ 366 genphy_config_aneg(phydev); 367 genphy_restart_aneg(phydev); 368 369 return 0; 370 } 371 372 return genphy_config(phydev); 373 } 374 375 static struct phy_driver ksz9031_driver = { 376 .name = "Micrel ksz9031", 377 .uid = 0x221620, 378 .mask = 0xfffff0, 379 .features = PHY_GBIT_FEATURES, 380 .config = &ksz9031_config, 381 .startup = &ksz90xx_startup, 382 .shutdown = &genphy_shutdown, 383 .writeext = &ksz9031_phy_extwrite, 384 .readext = &ksz9031_phy_extread, 385 }; 386 387 int phy_micrel_ksz90x1_init(void) 388 { 389 phy_register(&ksz9021_driver); 390 phy_register(&ksz9031_driver); 391 return 0; 392 } 393