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