1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * RealTek PHY drivers 4 * 5 * Copyright 2010-2011, 2015 Freescale Semiconductor, Inc. 6 * author Andy Fleming 7 * Copyright 2016 Karsten Merker <merker@debian.org> 8 */ 9 #include <common.h> 10 #include <linux/bitops.h> 11 #include <phy.h> 12 13 #define PHY_RTL8211x_FORCE_MASTER BIT(1) 14 #define PHY_RTL8211E_PINE64_GIGABIT_FIX BIT(2) 15 16 #define PHY_AUTONEGOTIATE_TIMEOUT 5000 17 18 /* RTL8211x 1000BASE-T Control Register */ 19 #define MIIM_RTL8211x_CTRL1000T_MSCE BIT(12); 20 #define MIIM_RTL8211x_CTRL1000T_MASTER BIT(11); 21 22 /* RTL8211x PHY Status Register */ 23 #define MIIM_RTL8211x_PHY_STATUS 0x11 24 #define MIIM_RTL8211x_PHYSTAT_SPEED 0xc000 25 #define MIIM_RTL8211x_PHYSTAT_GBIT 0x8000 26 #define MIIM_RTL8211x_PHYSTAT_100 0x4000 27 #define MIIM_RTL8211x_PHYSTAT_DUPLEX 0x2000 28 #define MIIM_RTL8211x_PHYSTAT_SPDDONE 0x0800 29 #define MIIM_RTL8211x_PHYSTAT_LINK 0x0400 30 31 /* RTL8211x PHY Interrupt Enable Register */ 32 #define MIIM_RTL8211x_PHY_INER 0x12 33 #define MIIM_RTL8211x_PHY_INTR_ENA 0x9f01 34 #define MIIM_RTL8211x_PHY_INTR_DIS 0x0000 35 36 /* RTL8211x PHY Interrupt Status Register */ 37 #define MIIM_RTL8211x_PHY_INSR 0x13 38 39 /* RTL8211F PHY Status Register */ 40 #define MIIM_RTL8211F_PHY_STATUS 0x1a 41 #define MIIM_RTL8211F_AUTONEG_ENABLE 0x1000 42 #define MIIM_RTL8211F_PHYSTAT_SPEED 0x0030 43 #define MIIM_RTL8211F_PHYSTAT_GBIT 0x0020 44 #define MIIM_RTL8211F_PHYSTAT_100 0x0010 45 #define MIIM_RTL8211F_PHYSTAT_DUPLEX 0x0008 46 #define MIIM_RTL8211F_PHYSTAT_SPDDONE 0x0800 47 #define MIIM_RTL8211F_PHYSTAT_LINK 0x0004 48 49 #define MIIM_RTL8211E_CONFREG 0x1c 50 #define MIIM_RTL8211E_CONFREG_TXD 0x0002 51 #define MIIM_RTL8211E_CONFREG_RXD 0x0004 52 #define MIIM_RTL8211E_CONFREG_MAGIC 0xb400 /* Undocumented */ 53 54 #define MIIM_RTL8211E_EXT_PAGE_SELECT 0x1e 55 56 #define MIIM_RTL8211F_PAGE_SELECT 0x1f 57 #define MIIM_RTL8211F_TX_DELAY 0x100 58 #define MIIM_RTL8211F_LCR 0x10 59 60 static int rtl8211f_phy_extread(struct phy_device *phydev, int addr, 61 int devaddr, int regnum) 62 { 63 int oldpage = phy_read(phydev, MDIO_DEVAD_NONE, 64 MIIM_RTL8211F_PAGE_SELECT); 65 int val; 66 67 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT, devaddr); 68 val = phy_read(phydev, MDIO_DEVAD_NONE, regnum); 69 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT, oldpage); 70 71 return val; 72 } 73 74 static int rtl8211f_phy_extwrite(struct phy_device *phydev, int addr, 75 int devaddr, int regnum, u16 val) 76 { 77 int oldpage = phy_read(phydev, MDIO_DEVAD_NONE, 78 MIIM_RTL8211F_PAGE_SELECT); 79 80 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT, devaddr); 81 phy_write(phydev, MDIO_DEVAD_NONE, regnum, val); 82 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT, oldpage); 83 84 return 0; 85 } 86 87 static int rtl8211b_probe(struct phy_device *phydev) 88 { 89 #ifdef CONFIG_RTL8211X_PHY_FORCE_MASTER 90 phydev->flags |= PHY_RTL8211x_FORCE_MASTER; 91 #endif 92 93 return 0; 94 } 95 96 static int rtl8211e_probe(struct phy_device *phydev) 97 { 98 #ifdef CONFIG_RTL8211E_PINE64_GIGABIT_FIX 99 phydev->flags |= PHY_RTL8211E_PINE64_GIGABIT_FIX; 100 #endif 101 102 return 0; 103 } 104 105 /* RealTek RTL8211x */ 106 static int rtl8211x_config(struct phy_device *phydev) 107 { 108 phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET); 109 110 /* mask interrupt at init; if the interrupt is 111 * needed indeed, it should be explicitly enabled 112 */ 113 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211x_PHY_INER, 114 MIIM_RTL8211x_PHY_INTR_DIS); 115 116 if (phydev->flags & PHY_RTL8211x_FORCE_MASTER) { 117 unsigned int reg; 118 119 reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_CTRL1000); 120 /* force manual master/slave configuration */ 121 reg |= MIIM_RTL8211x_CTRL1000T_MSCE; 122 /* force master mode */ 123 reg |= MIIM_RTL8211x_CTRL1000T_MASTER; 124 phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, reg); 125 } 126 if (phydev->flags & PHY_RTL8211E_PINE64_GIGABIT_FIX) { 127 unsigned int reg; 128 129 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT, 130 7); 131 phy_write(phydev, MDIO_DEVAD_NONE, 132 MIIM_RTL8211E_EXT_PAGE_SELECT, 0xa4); 133 reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211E_CONFREG); 134 /* Ensure both internal delays are turned off */ 135 reg &= ~(MIIM_RTL8211E_CONFREG_TXD | MIIM_RTL8211E_CONFREG_RXD); 136 /* Flip the magic undocumented bits */ 137 reg |= MIIM_RTL8211E_CONFREG_MAGIC; 138 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211E_CONFREG, reg); 139 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT, 140 0); 141 } 142 /* read interrupt status just to clear it */ 143 phy_read(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211x_PHY_INER); 144 145 genphy_config_aneg(phydev); 146 147 return 0; 148 } 149 150 static int rtl8211f_config(struct phy_device *phydev) 151 { 152 u16 reg; 153 154 phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET); 155 156 phy_write(phydev, MDIO_DEVAD_NONE, 157 MIIM_RTL8211F_PAGE_SELECT, 0xd08); 158 reg = phy_read(phydev, MDIO_DEVAD_NONE, 0x11); 159 160 /* enable TX-delay for rgmii-id and rgmii-txid, otherwise disable it */ 161 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID || 162 phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) 163 reg |= MIIM_RTL8211F_TX_DELAY; 164 else 165 reg &= ~MIIM_RTL8211F_TX_DELAY; 166 167 phy_write(phydev, MDIO_DEVAD_NONE, 0x11, reg); 168 /* restore to default page 0 */ 169 phy_write(phydev, MDIO_DEVAD_NONE, 170 MIIM_RTL8211F_PAGE_SELECT, 0x0); 171 172 /* Set green LED for Link, yellow LED for Active */ 173 phy_write(phydev, MDIO_DEVAD_NONE, 174 MIIM_RTL8211F_PAGE_SELECT, 0xd04); 175 phy_write(phydev, MDIO_DEVAD_NONE, 0x10, 0x617f); 176 phy_write(phydev, MDIO_DEVAD_NONE, 177 MIIM_RTL8211F_PAGE_SELECT, 0x0); 178 179 genphy_config_aneg(phydev); 180 181 return 0; 182 } 183 184 static int rtl8211x_parse_status(struct phy_device *phydev) 185 { 186 unsigned int speed; 187 unsigned int mii_reg; 188 189 mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211x_PHY_STATUS); 190 191 if (!(mii_reg & MIIM_RTL8211x_PHYSTAT_SPDDONE)) { 192 int i = 0; 193 194 /* in case of timeout ->link is cleared */ 195 phydev->link = 1; 196 puts("Waiting for PHY realtime link"); 197 while (!(mii_reg & MIIM_RTL8211x_PHYSTAT_SPDDONE)) { 198 /* Timeout reached ? */ 199 if (i > PHY_AUTONEGOTIATE_TIMEOUT) { 200 puts(" TIMEOUT !\n"); 201 phydev->link = 0; 202 break; 203 } 204 205 if ((i++ % 1000) == 0) 206 putc('.'); 207 udelay(1000); /* 1 ms */ 208 mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, 209 MIIM_RTL8211x_PHY_STATUS); 210 } 211 puts(" done\n"); 212 udelay(500000); /* another 500 ms (results in faster booting) */ 213 } else { 214 if (mii_reg & MIIM_RTL8211x_PHYSTAT_LINK) 215 phydev->link = 1; 216 else 217 phydev->link = 0; 218 } 219 220 if (mii_reg & MIIM_RTL8211x_PHYSTAT_DUPLEX) 221 phydev->duplex = DUPLEX_FULL; 222 else 223 phydev->duplex = DUPLEX_HALF; 224 225 speed = (mii_reg & MIIM_RTL8211x_PHYSTAT_SPEED); 226 227 switch (speed) { 228 case MIIM_RTL8211x_PHYSTAT_GBIT: 229 phydev->speed = SPEED_1000; 230 break; 231 case MIIM_RTL8211x_PHYSTAT_100: 232 phydev->speed = SPEED_100; 233 break; 234 default: 235 phydev->speed = SPEED_10; 236 } 237 238 return 0; 239 } 240 241 static int rtl8211f_parse_status(struct phy_device *phydev) 242 { 243 unsigned int speed; 244 unsigned int mii_reg; 245 int i = 0; 246 247 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT, 0xa43); 248 mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PHY_STATUS); 249 250 phydev->link = 1; 251 while (!(mii_reg & MIIM_RTL8211F_PHYSTAT_LINK)) { 252 if (i > PHY_AUTONEGOTIATE_TIMEOUT) { 253 puts(" TIMEOUT !\n"); 254 phydev->link = 0; 255 break; 256 } 257 258 if ((i++ % 1000) == 0) 259 putc('.'); 260 udelay(1000); 261 mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, 262 MIIM_RTL8211F_PHY_STATUS); 263 } 264 265 if (mii_reg & MIIM_RTL8211F_PHYSTAT_DUPLEX) 266 phydev->duplex = DUPLEX_FULL; 267 else 268 phydev->duplex = DUPLEX_HALF; 269 270 speed = (mii_reg & MIIM_RTL8211F_PHYSTAT_SPEED); 271 272 switch (speed) { 273 case MIIM_RTL8211F_PHYSTAT_GBIT: 274 phydev->speed = SPEED_1000; 275 break; 276 case MIIM_RTL8211F_PHYSTAT_100: 277 phydev->speed = SPEED_100; 278 break; 279 default: 280 phydev->speed = SPEED_10; 281 } 282 283 return 0; 284 } 285 286 static int rtl8211x_startup(struct phy_device *phydev) 287 { 288 int ret; 289 290 /* Read the Status (2x to make sure link is right) */ 291 ret = genphy_update_link(phydev); 292 if (ret) 293 return ret; 294 295 return rtl8211x_parse_status(phydev); 296 } 297 298 static int rtl8211e_startup(struct phy_device *phydev) 299 { 300 int ret; 301 302 ret = genphy_update_link(phydev); 303 if (ret) 304 return ret; 305 306 return genphy_parse_link(phydev); 307 } 308 309 static int rtl8211f_startup(struct phy_device *phydev) 310 { 311 int ret; 312 313 /* Read the Status (2x to make sure link is right) */ 314 ret = genphy_update_link(phydev); 315 if (ret) 316 return ret; 317 /* Read the Status (2x to make sure link is right) */ 318 319 return rtl8211f_parse_status(phydev); 320 } 321 322 /* Support for RTL8211B PHY */ 323 static struct phy_driver RTL8211B_driver = { 324 .name = "RealTek RTL8211B", 325 .uid = 0x1cc912, 326 .mask = 0xffffff, 327 .features = PHY_GBIT_FEATURES, 328 .probe = &rtl8211b_probe, 329 .config = &rtl8211x_config, 330 .startup = &rtl8211x_startup, 331 .shutdown = &genphy_shutdown, 332 }; 333 334 /* Support for RTL8211E-VB-CG, RTL8211E-VL-CG and RTL8211EG-VB-CG PHYs */ 335 static struct phy_driver RTL8211E_driver = { 336 .name = "RealTek RTL8211E", 337 .uid = 0x1cc915, 338 .mask = 0xffffff, 339 .features = PHY_GBIT_FEATURES, 340 .probe = &rtl8211e_probe, 341 .config = &rtl8211x_config, 342 .startup = &rtl8211e_startup, 343 .shutdown = &genphy_shutdown, 344 }; 345 346 /* Support for RTL8211DN PHY */ 347 static struct phy_driver RTL8211DN_driver = { 348 .name = "RealTek RTL8211DN", 349 .uid = 0x1cc914, 350 .mask = 0xffffff, 351 .features = PHY_GBIT_FEATURES, 352 .config = &rtl8211x_config, 353 .startup = &rtl8211x_startup, 354 .shutdown = &genphy_shutdown, 355 }; 356 357 /* Support for RTL8211F PHY */ 358 static struct phy_driver RTL8211F_driver = { 359 .name = "RealTek RTL8211F", 360 .uid = 0x1cc916, 361 .mask = 0xffffff, 362 .features = PHY_GBIT_FEATURES, 363 .config = &rtl8211f_config, 364 .startup = &rtl8211f_startup, 365 .shutdown = &genphy_shutdown, 366 .readext = &rtl8211f_phy_extread, 367 .writeext = &rtl8211f_phy_extwrite, 368 }; 369 370 int phy_realtek_init(void) 371 { 372 phy_register(&RTL8211B_driver); 373 phy_register(&RTL8211E_driver); 374 phy_register(&RTL8211F_driver); 375 phy_register(&RTL8211DN_driver); 376 377 return 0; 378 } 379