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#include <linux/delay.h> 13 14#define PHY_RTL8211x_FORCE_MASTER BIT(1) 15#define PHY_RTL8211F_FORCE_EEE_RXC_ON BIT(3) 16#define PHY_RTL8201F_S700_RMII_TIMINGS BIT(4) 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_CTRL_DELAY BIT(13) 53#define MIIM_RTL8211E_TX_DELAY BIT(12) 54#define MIIM_RTL8211E_RX_DELAY BIT(11) 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_RX_DELAY 0x8 61#define MIIM_RTL8211F_LCR 0x10 62 63#define RTL8201F_RMSR 0x10 64 65#define RMSR_RX_TIMING_SHIFT BIT(2) 66#define RMSR_RX_TIMING_MASK GENMASK(7, 4) 67#define RMSR_RX_TIMING_VAL 0x4 68#define RMSR_TX_TIMING_SHIFT BIT(3) 69#define RMSR_TX_TIMING_MASK GENMASK(11, 8) 70#define RMSR_TX_TIMING_VAL 0x5 71 72static int rtl8211f_phy_extread(struct phy_device *phydev, int addr, 73 int devaddr, int regnum) 74{ 75 int oldpage = phy_read(phydev, MDIO_DEVAD_NONE, 76 MIIM_RTL8211F_PAGE_SELECT); 77 int val; 78 79 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT, devaddr); 80 val = phy_read(phydev, MDIO_DEVAD_NONE, regnum); 81 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT, oldpage); 82 83 return val; 84} 85 86static int rtl8211f_phy_extwrite(struct phy_device *phydev, int addr, 87 int devaddr, int regnum, u16 val) 88{ 89 int oldpage = phy_read(phydev, MDIO_DEVAD_NONE, 90 MIIM_RTL8211F_PAGE_SELECT); 91 92 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT, devaddr); 93 phy_write(phydev, MDIO_DEVAD_NONE, regnum, val); 94 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT, oldpage); 95 96 return 0; 97} 98 99static int rtl8211b_probe(struct phy_device *phydev) 100{ 101#ifdef CONFIG_RTL8211X_PHY_FORCE_MASTER 102 phydev->flags |= PHY_RTL8211x_FORCE_MASTER; 103#endif 104 105 return 0; 106} 107 108static int rtl8211e_probe(struct phy_device *phydev) 109{ 110 return 0; 111} 112 113static int rtl8211f_probe(struct phy_device *phydev) 114{ 115#ifdef CONFIG_RTL8211F_PHY_FORCE_EEE_RXC_ON 116 phydev->flags |= PHY_RTL8211F_FORCE_EEE_RXC_ON; 117#endif 118 119 return 0; 120} 121 122static int rtl8210f_probe(struct phy_device *phydev) 123{ 124#ifdef CONFIG_RTL8201F_PHY_S700_RMII_TIMINGS 125 phydev->flags |= PHY_RTL8201F_S700_RMII_TIMINGS; 126#endif 127 128 return 0; 129} 130 131/* RealTek RTL8211x */ 132static int rtl8211x_config(struct phy_device *phydev) 133{ 134 phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET); 135 136 /* mask interrupt at init; if the interrupt is 137 * needed indeed, it should be explicitly enabled 138 */ 139 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211x_PHY_INER, 140 MIIM_RTL8211x_PHY_INTR_DIS); 141 142 if (phydev->flags & PHY_RTL8211x_FORCE_MASTER) { 143 unsigned int reg; 144 145 reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_CTRL1000); 146 /* force manual master/slave configuration */ 147 reg |= MIIM_RTL8211x_CTRL1000T_MSCE; 148 /* force master mode */ 149 reg |= MIIM_RTL8211x_CTRL1000T_MASTER; 150 phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, reg); 151 } 152 /* read interrupt status just to clear it */ 153 phy_read(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211x_PHY_INER); 154 155 genphy_config_aneg(phydev); 156 157 return 0; 158} 159 160/* RealTek RTL8201F */ 161static int rtl8201f_config(struct phy_device *phydev) 162{ 163 unsigned int reg; 164 165 if (phydev->flags & PHY_RTL8201F_S700_RMII_TIMINGS) { 166 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT, 167 7); 168 reg = phy_read(phydev, MDIO_DEVAD_NONE, RTL8201F_RMSR); 169 reg &= ~(RMSR_RX_TIMING_MASK | RMSR_TX_TIMING_MASK); 170 /* Set the needed Rx/Tx Timings for proper PHY operation */ 171 reg |= (RMSR_RX_TIMING_VAL << RMSR_RX_TIMING_SHIFT) 172 | (RMSR_TX_TIMING_VAL << RMSR_TX_TIMING_SHIFT); 173 phy_write(phydev, MDIO_DEVAD_NONE, RTL8201F_RMSR, reg); 174 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT, 175 0); 176 } 177 178 genphy_config_aneg(phydev); 179 180 return 0; 181} 182 183static int rtl8211e_config(struct phy_device *phydev) 184{ 185 int reg, val; 186 187 /* enable TX/RX delay for rgmii-* modes, and disable them for rgmii. */ 188 switch (phydev->interface) { 189 case PHY_INTERFACE_MODE_RGMII: 190 val = MIIM_RTL8211E_CTRL_DELAY; 191 break; 192 case PHY_INTERFACE_MODE_RGMII_ID: 193 val = MIIM_RTL8211E_CTRL_DELAY | MIIM_RTL8211E_TX_DELAY | 194 MIIM_RTL8211E_RX_DELAY; 195 break; 196 case PHY_INTERFACE_MODE_RGMII_RXID: 197 val = MIIM_RTL8211E_CTRL_DELAY | MIIM_RTL8211E_RX_DELAY; 198 break; 199 case PHY_INTERFACE_MODE_RGMII_TXID: 200 val = MIIM_RTL8211E_CTRL_DELAY | MIIM_RTL8211E_TX_DELAY; 201 break; 202 default: /* the rest of the modes imply leaving delays as is. */ 203 goto default_delay; 204 } 205 206 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT, 7); 207 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211E_EXT_PAGE_SELECT, 0xa4); 208 209 reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211E_CONFREG); 210 reg &= ~(MIIM_RTL8211E_TX_DELAY | MIIM_RTL8211E_RX_DELAY); 211 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211E_CONFREG, reg | val); 212 213 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT, 0); 214 215default_delay: 216 genphy_config_aneg(phydev); 217 218 return 0; 219} 220 221static int rtl8211f_config(struct phy_device *phydev) 222{ 223 u16 reg; 224 225 if (phydev->flags & PHY_RTL8211F_FORCE_EEE_RXC_ON) { 226 unsigned int reg; 227 228 reg = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1); 229 reg &= ~MDIO_PCS_CTRL1_CLKSTOP_EN; 230 phy_write_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1, reg); 231 } 232 233 phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET); 234 235 phy_write(phydev, MDIO_DEVAD_NONE, 236 MIIM_RTL8211F_PAGE_SELECT, 0xd08); 237 reg = phy_read(phydev, MDIO_DEVAD_NONE, 0x11); 238 239 /* enable TX-delay for rgmii-id and rgmii-txid, otherwise disable it */ 240 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID || 241 phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) 242 reg |= MIIM_RTL8211F_TX_DELAY; 243 else 244 reg &= ~MIIM_RTL8211F_TX_DELAY; 245 246 phy_write(phydev, MDIO_DEVAD_NONE, 0x11, reg); 247 248 /* enable RX-delay for rgmii-id and rgmii-rxid, otherwise disable it */ 249 reg = phy_read(phydev, MDIO_DEVAD_NONE, 0x15); 250 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID || 251 phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) 252 reg |= MIIM_RTL8211F_RX_DELAY; 253 else 254 reg &= ~MIIM_RTL8211F_RX_DELAY; 255 phy_write(phydev, MDIO_DEVAD_NONE, 0x15, reg); 256 257 /* restore to default page 0 */ 258 phy_write(phydev, MDIO_DEVAD_NONE, 259 MIIM_RTL8211F_PAGE_SELECT, 0x0); 260 261 /* Set green LED for Link, yellow LED for Active */ 262 phy_write(phydev, MDIO_DEVAD_NONE, 263 MIIM_RTL8211F_PAGE_SELECT, 0xd04); 264 phy_write(phydev, MDIO_DEVAD_NONE, 0x10, 0x617f); 265 phy_write(phydev, MDIO_DEVAD_NONE, 266 MIIM_RTL8211F_PAGE_SELECT, 0x0); 267 268 genphy_config_aneg(phydev); 269 270 return 0; 271} 272 273static int rtl8211x_parse_status(struct phy_device *phydev) 274{ 275 unsigned int speed; 276 unsigned int mii_reg; 277 278 mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211x_PHY_STATUS); 279 280 if (!(mii_reg & MIIM_RTL8211x_PHYSTAT_SPDDONE)) { 281 int i = 0; 282 283 /* in case of timeout ->link is cleared */ 284 phydev->link = 1; 285 puts("Waiting for PHY realtime link"); 286 while (!(mii_reg & MIIM_RTL8211x_PHYSTAT_SPDDONE)) { 287 /* Timeout reached ? */ 288 if (i > PHY_AUTONEGOTIATE_TIMEOUT) { 289 puts(" TIMEOUT !\n"); 290 phydev->link = 0; 291 break; 292 } 293 294 if ((i++ % 1000) == 0) 295 putc('.'); 296 udelay(1000); /* 1 ms */ 297 mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, 298 MIIM_RTL8211x_PHY_STATUS); 299 } 300 puts(" done\n"); 301 udelay(500000); /* another 500 ms (results in faster booting) */ 302 } else { 303 if (mii_reg & MIIM_RTL8211x_PHYSTAT_LINK) 304 phydev->link = 1; 305 else 306 phydev->link = 0; 307 } 308 309 if (mii_reg & MIIM_RTL8211x_PHYSTAT_DUPLEX) 310 phydev->duplex = DUPLEX_FULL; 311 else 312 phydev->duplex = DUPLEX_HALF; 313 314 speed = (mii_reg & MIIM_RTL8211x_PHYSTAT_SPEED); 315 316 switch (speed) { 317 case MIIM_RTL8211x_PHYSTAT_GBIT: 318 phydev->speed = SPEED_1000; 319 break; 320 case MIIM_RTL8211x_PHYSTAT_100: 321 phydev->speed = SPEED_100; 322 break; 323 default: 324 phydev->speed = SPEED_10; 325 } 326 327 return 0; 328} 329 330static int rtl8211f_parse_status(struct phy_device *phydev) 331{ 332 unsigned int speed; 333 unsigned int mii_reg; 334 int i = 0; 335 336 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT, 0xa43); 337 mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PHY_STATUS); 338 339 phydev->link = 1; 340 while (!(mii_reg & MIIM_RTL8211F_PHYSTAT_LINK)) { 341 if (i > PHY_AUTONEGOTIATE_TIMEOUT) { 342 puts(" TIMEOUT !\n"); 343 phydev->link = 0; 344 break; 345 } 346 347 if ((i++ % 1000) == 0) 348 putc('.'); 349 udelay(1000); 350 mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, 351 MIIM_RTL8211F_PHY_STATUS); 352 } 353 354 if (mii_reg & MIIM_RTL8211F_PHYSTAT_DUPLEX) 355 phydev->duplex = DUPLEX_FULL; 356 else 357 phydev->duplex = DUPLEX_HALF; 358 359 speed = (mii_reg & MIIM_RTL8211F_PHYSTAT_SPEED); 360 361 switch (speed) { 362 case MIIM_RTL8211F_PHYSTAT_GBIT: 363 phydev->speed = SPEED_1000; 364 break; 365 case MIIM_RTL8211F_PHYSTAT_100: 366 phydev->speed = SPEED_100; 367 break; 368 default: 369 phydev->speed = SPEED_10; 370 } 371 372 return 0; 373} 374 375static int rtl8211x_startup(struct phy_device *phydev) 376{ 377 int ret; 378 379 /* Read the Status (2x to make sure link is right) */ 380 ret = genphy_update_link(phydev); 381 if (ret) 382 return ret; 383 384 return rtl8211x_parse_status(phydev); 385} 386 387static int rtl8211f_startup(struct phy_device *phydev) 388{ 389 int ret; 390 391 /* Read the Status (2x to make sure link is right) */ 392 ret = genphy_update_link(phydev); 393 if (ret) 394 return ret; 395 /* Read the Status (2x to make sure link is right) */ 396 397 return rtl8211f_parse_status(phydev); 398} 399 400/* Support for RTL8211B PHY */ 401U_BOOT_PHY_DRIVER(rtl8211b) = { 402 .name = "RealTek RTL8211B", 403 .uid = 0x1cc912, 404 .mask = 0xffffff, 405 .features = PHY_GBIT_FEATURES, 406 .probe = &rtl8211b_probe, 407 .config = &rtl8211x_config, 408 .startup = &rtl8211x_startup, 409 .shutdown = &genphy_shutdown, 410}; 411 412/* Support for RTL8211E-VB-CG, RTL8211E-VL-CG and RTL8211EG-VB-CG PHYs */ 413U_BOOT_PHY_DRIVER(rtl8211e) = { 414 .name = "RealTek RTL8211E", 415 .uid = 0x1cc915, 416 .mask = 0xffffff, 417 .features = PHY_GBIT_FEATURES, 418 .probe = &rtl8211e_probe, 419 .config = &rtl8211e_config, 420 .startup = &genphy_startup, 421 .shutdown = &genphy_shutdown, 422}; 423 424/* Support for RTL8211DN PHY */ 425U_BOOT_PHY_DRIVER(rtl8211dn) = { 426 .name = "RealTek RTL8211DN", 427 .uid = 0x1cc914, 428 .mask = 0xffffff, 429 .features = PHY_GBIT_FEATURES, 430 .config = &rtl8211x_config, 431 .startup = &rtl8211x_startup, 432 .shutdown = &genphy_shutdown, 433}; 434 435/* Support for RTL8211F PHY */ 436U_BOOT_PHY_DRIVER(rtl8211f) = { 437 .name = "RealTek RTL8211F", 438 .uid = 0x1cc916, 439 .mask = 0xffffff, 440 .features = PHY_GBIT_FEATURES, 441 .probe = &rtl8211f_probe, 442 .config = &rtl8211f_config, 443 .startup = &rtl8211f_startup, 444 .shutdown = &genphy_shutdown, 445 .readext = &rtl8211f_phy_extread, 446 .writeext = &rtl8211f_phy_extwrite, 447}; 448 449/* Support for RTL8211F-VD PHY */ 450U_BOOT_PHY_DRIVER(rtl8211fvd) = { 451 .name = "RealTek RTL8211F-VD", 452 .uid = 0x1cc878, 453 .mask = 0xffffff, 454 .features = PHY_GBIT_FEATURES, 455 .probe = &rtl8211f_probe, 456 .config = &rtl8211f_config, 457 .startup = &rtl8211f_startup, 458 .shutdown = &genphy_shutdown, 459 .readext = &rtl8211f_phy_extread, 460 .writeext = &rtl8211f_phy_extwrite, 461}; 462 463/* Support for RTL8201F PHY */ 464U_BOOT_PHY_DRIVER(rtl8201f) = { 465 .name = "RealTek RTL8201F 10/100Mbps Ethernet", 466 .uid = 0x1cc816, 467 .mask = 0xffffff, 468 .features = PHY_BASIC_FEATURES, 469 .probe = &rtl8210f_probe, 470 .config = &rtl8201f_config, 471 .startup = &genphy_startup, 472 .shutdown = &genphy_shutdown, 473}; 474