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