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