1 /* 2 * Copyright (C) 2005 Freescale Semiconductor, Inc. 3 * 4 * Author: Shlomi Gridish 5 * 6 * Description: UCC GETH Driver -- PHY handling 7 * Driver for UEC on QE 8 * Based on 8260_io/fcc_enet.c 9 * 10 * This program is free software; you can redistribute it and/or modify it 11 * under the terms of the GNU General Public License as published by the 12 * Free Software Foundation; either version 2 of the License, or (at your 13 * option) any later version. 14 * 15 */ 16 17 #include "common.h" 18 #include "net.h" 19 #include "malloc.h" 20 #include "asm/errno.h" 21 #include "asm/immap_qe.h" 22 #include "asm/io.h" 23 #include "qe.h" 24 #include "uccf.h" 25 #include "uec.h" 26 #include "uec_phy.h" 27 #include "miiphy.h" 28 29 #define ugphy_printk(format, arg...) \ 30 printf(format "\n", ## arg) 31 32 #define ugphy_dbg(format, arg...) \ 33 ugphy_printk(format , ## arg) 34 #define ugphy_err(format, arg...) \ 35 ugphy_printk(format , ## arg) 36 #define ugphy_info(format, arg...) \ 37 ugphy_printk(format , ## arg) 38 #define ugphy_warn(format, arg...) \ 39 ugphy_printk(format , ## arg) 40 41 #ifdef UEC_VERBOSE_DEBUG 42 #define ugphy_vdbg ugphy_dbg 43 #else 44 #define ugphy_vdbg(ugeth, fmt, args...) do { } while (0) 45 #endif /* UEC_VERBOSE_DEBUG */ 46 47 /*--------------------------------------------------------------------+ 48 * Fixed PHY (PHY-less) support for Ethernet Ports. 49 * 50 * Copied from cpu/ppc4xx/4xx_enet.c 51 *--------------------------------------------------------------------*/ 52 53 /* 54 * Some boards do not have a PHY for each ethernet port. These ports 55 * are known as Fixed PHY (or PHY-less) ports. For such ports, set 56 * the appropriate CONFIG_PHY_ADDR equal to CONFIG_FIXED_PHY and 57 * then define CONFIG_SYS_FIXED_PHY_PORTS to define what the speed and 58 * duplex should be for these ports in the board configuration 59 * file. 60 * 61 * For Example: 62 * #define CONFIG_FIXED_PHY 0xFFFFFFFF 63 * 64 * #define CONFIG_PHY_ADDR CONFIG_FIXED_PHY 65 * #define CONFIG_PHY1_ADDR 1 66 * #define CONFIG_PHY2_ADDR CONFIG_FIXED_PHY 67 * #define CONFIG_PHY3_ADDR 3 68 * 69 * #define CONFIG_SYS_FIXED_PHY_PORT(devnum,speed,duplex) \ 70 * {devnum, speed, duplex}, 71 * 72 * #define CONFIG_SYS_FIXED_PHY_PORTS \ 73 * CONFIG_SYS_FIXED_PHY_PORT(0,SPEED_100,DUPLEX_FULL) \ 74 * CONFIG_SYS_FIXED_PHY_PORT(2,SPEED_100,DUPLEX_HALF) 75 */ 76 77 #ifndef CONFIG_FIXED_PHY 78 #define CONFIG_FIXED_PHY 0xFFFFFFFF /* Fixed PHY (PHY-less) */ 79 #endif 80 81 #ifndef CONFIG_SYS_FIXED_PHY_PORTS 82 #define CONFIG_SYS_FIXED_PHY_PORTS /* default is an empty array */ 83 #endif 84 85 struct fixed_phy_port { 86 unsigned int devnum; /* ethernet port */ 87 unsigned int speed; /* specified speed 10,100 or 1000 */ 88 unsigned int duplex; /* specified duplex FULL or HALF */ 89 }; 90 91 static const struct fixed_phy_port fixed_phy_port[] = { 92 CONFIG_SYS_FIXED_PHY_PORTS /* defined in board configuration file */ 93 }; 94 95 static void config_genmii_advert (struct uec_mii_info *mii_info); 96 static void genmii_setup_forced (struct uec_mii_info *mii_info); 97 static void genmii_restart_aneg (struct uec_mii_info *mii_info); 98 static int gbit_config_aneg (struct uec_mii_info *mii_info); 99 static int genmii_config_aneg (struct uec_mii_info *mii_info); 100 static int genmii_update_link (struct uec_mii_info *mii_info); 101 static int genmii_read_status (struct uec_mii_info *mii_info); 102 u16 phy_read (struct uec_mii_info *mii_info, u16 regnum); 103 void phy_write (struct uec_mii_info *mii_info, u16 regnum, u16 val); 104 105 /* Write value to the PHY for this device to the register at regnum, */ 106 /* waiting until the write is done before it returns. All PHY */ 107 /* configuration has to be done through the TSEC1 MIIM regs */ 108 void uec_write_phy_reg (struct eth_device *dev, int mii_id, int regnum, int value) 109 { 110 uec_private_t *ugeth = (uec_private_t *) dev->priv; 111 uec_mii_t *ug_regs; 112 enet_tbi_mii_reg_e mii_reg = (enet_tbi_mii_reg_e) regnum; 113 u32 tmp_reg; 114 115 ug_regs = ugeth->uec_mii_regs; 116 117 /* Stop the MII management read cycle */ 118 out_be32 (&ug_regs->miimcom, 0); 119 /* Setting up the MII Mangement Address Register */ 120 tmp_reg = ((u32) mii_id << MIIMADD_PHY_ADDRESS_SHIFT) | mii_reg; 121 out_be32 (&ug_regs->miimadd, tmp_reg); 122 123 /* Setting up the MII Mangement Control Register with the value */ 124 out_be32 (&ug_regs->miimcon, (u32) value); 125 sync(); 126 127 /* Wait till MII management write is complete */ 128 while ((in_be32 (&ug_regs->miimind)) & MIIMIND_BUSY); 129 } 130 131 /* Reads from register regnum in the PHY for device dev, */ 132 /* returning the value. Clears miimcom first. All PHY */ 133 /* configuration has to be done through the TSEC1 MIIM regs */ 134 int uec_read_phy_reg (struct eth_device *dev, int mii_id, int regnum) 135 { 136 uec_private_t *ugeth = (uec_private_t *) dev->priv; 137 uec_mii_t *ug_regs; 138 enet_tbi_mii_reg_e mii_reg = (enet_tbi_mii_reg_e) regnum; 139 u32 tmp_reg; 140 u16 value; 141 142 ug_regs = ugeth->uec_mii_regs; 143 144 /* Setting up the MII Mangement Address Register */ 145 tmp_reg = ((u32) mii_id << MIIMADD_PHY_ADDRESS_SHIFT) | mii_reg; 146 out_be32 (&ug_regs->miimadd, tmp_reg); 147 148 /* clear MII management command cycle */ 149 out_be32 (&ug_regs->miimcom, 0); 150 sync(); 151 152 /* Perform an MII management read cycle */ 153 out_be32 (&ug_regs->miimcom, MIIMCOM_READ_CYCLE); 154 155 /* Wait till MII management write is complete */ 156 while ((in_be32 (&ug_regs->miimind)) & 157 (MIIMIND_NOT_VALID | MIIMIND_BUSY)); 158 159 /* Read MII management status */ 160 value = (u16) in_be32 (&ug_regs->miimstat); 161 if (value == 0xffff) 162 ugphy_vdbg 163 ("read wrong value : mii_id %d,mii_reg %d, base %08x", 164 mii_id, mii_reg, (u32) & (ug_regs->miimcfg)); 165 166 return (value); 167 } 168 169 void mii_clear_phy_interrupt (struct uec_mii_info *mii_info) 170 { 171 if (mii_info->phyinfo->ack_interrupt) 172 mii_info->phyinfo->ack_interrupt (mii_info); 173 } 174 175 void mii_configure_phy_interrupt (struct uec_mii_info *mii_info, 176 u32 interrupts) 177 { 178 mii_info->interrupts = interrupts; 179 if (mii_info->phyinfo->config_intr) 180 mii_info->phyinfo->config_intr (mii_info); 181 } 182 183 /* Writes MII_ADVERTISE with the appropriate values, after 184 * sanitizing advertise to make sure only supported features 185 * are advertised 186 */ 187 static void config_genmii_advert (struct uec_mii_info *mii_info) 188 { 189 u32 advertise; 190 u16 adv; 191 192 /* Only allow advertising what this PHY supports */ 193 mii_info->advertising &= mii_info->phyinfo->features; 194 advertise = mii_info->advertising; 195 196 /* Setup standard advertisement */ 197 adv = phy_read (mii_info, PHY_ANAR); 198 adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4); 199 if (advertise & ADVERTISED_10baseT_Half) 200 adv |= ADVERTISE_10HALF; 201 if (advertise & ADVERTISED_10baseT_Full) 202 adv |= ADVERTISE_10FULL; 203 if (advertise & ADVERTISED_100baseT_Half) 204 adv |= ADVERTISE_100HALF; 205 if (advertise & ADVERTISED_100baseT_Full) 206 adv |= ADVERTISE_100FULL; 207 phy_write (mii_info, PHY_ANAR, adv); 208 } 209 210 static void genmii_setup_forced (struct uec_mii_info *mii_info) 211 { 212 u16 ctrl; 213 u32 features = mii_info->phyinfo->features; 214 215 ctrl = phy_read (mii_info, PHY_BMCR); 216 217 ctrl &= ~(PHY_BMCR_DPLX | PHY_BMCR_100_MBPS | 218 PHY_BMCR_1000_MBPS | PHY_BMCR_AUTON); 219 ctrl |= PHY_BMCR_RESET; 220 221 switch (mii_info->speed) { 222 case SPEED_1000: 223 if (features & (SUPPORTED_1000baseT_Half 224 | SUPPORTED_1000baseT_Full)) { 225 ctrl |= PHY_BMCR_1000_MBPS; 226 break; 227 } 228 mii_info->speed = SPEED_100; 229 case SPEED_100: 230 if (features & (SUPPORTED_100baseT_Half 231 | SUPPORTED_100baseT_Full)) { 232 ctrl |= PHY_BMCR_100_MBPS; 233 break; 234 } 235 mii_info->speed = SPEED_10; 236 case SPEED_10: 237 if (features & (SUPPORTED_10baseT_Half 238 | SUPPORTED_10baseT_Full)) 239 break; 240 default: /* Unsupported speed! */ 241 ugphy_err ("%s: Bad speed!", mii_info->dev->name); 242 break; 243 } 244 245 phy_write (mii_info, PHY_BMCR, ctrl); 246 } 247 248 /* Enable and Restart Autonegotiation */ 249 static void genmii_restart_aneg (struct uec_mii_info *mii_info) 250 { 251 u16 ctl; 252 253 ctl = phy_read (mii_info, PHY_BMCR); 254 ctl |= (PHY_BMCR_AUTON | PHY_BMCR_RST_NEG); 255 phy_write (mii_info, PHY_BMCR, ctl); 256 } 257 258 static int gbit_config_aneg (struct uec_mii_info *mii_info) 259 { 260 u16 adv; 261 u32 advertise; 262 263 if (mii_info->autoneg) { 264 /* Configure the ADVERTISE register */ 265 config_genmii_advert (mii_info); 266 advertise = mii_info->advertising; 267 268 adv = phy_read (mii_info, MII_1000BASETCONTROL); 269 adv &= ~(MII_1000BASETCONTROL_FULLDUPLEXCAP | 270 MII_1000BASETCONTROL_HALFDUPLEXCAP); 271 if (advertise & SUPPORTED_1000baseT_Half) 272 adv |= MII_1000BASETCONTROL_HALFDUPLEXCAP; 273 if (advertise & SUPPORTED_1000baseT_Full) 274 adv |= MII_1000BASETCONTROL_FULLDUPLEXCAP; 275 phy_write (mii_info, MII_1000BASETCONTROL, adv); 276 277 /* Start/Restart aneg */ 278 genmii_restart_aneg (mii_info); 279 } else 280 genmii_setup_forced (mii_info); 281 282 return 0; 283 } 284 285 static int marvell_config_aneg (struct uec_mii_info *mii_info) 286 { 287 /* The Marvell PHY has an errata which requires 288 * that certain registers get written in order 289 * to restart autonegotiation */ 290 phy_write (mii_info, PHY_BMCR, PHY_BMCR_RESET); 291 292 phy_write (mii_info, 0x1d, 0x1f); 293 phy_write (mii_info, 0x1e, 0x200c); 294 phy_write (mii_info, 0x1d, 0x5); 295 phy_write (mii_info, 0x1e, 0); 296 phy_write (mii_info, 0x1e, 0x100); 297 298 gbit_config_aneg (mii_info); 299 300 return 0; 301 } 302 303 static int genmii_config_aneg (struct uec_mii_info *mii_info) 304 { 305 if (mii_info->autoneg) { 306 config_genmii_advert (mii_info); 307 genmii_restart_aneg (mii_info); 308 } else 309 genmii_setup_forced (mii_info); 310 311 return 0; 312 } 313 314 static int genmii_update_link (struct uec_mii_info *mii_info) 315 { 316 u16 status; 317 318 /* Status is read once to clear old link state */ 319 phy_read (mii_info, PHY_BMSR); 320 321 /* 322 * Wait if the link is up, and autonegotiation is in progress 323 * (ie - we're capable and it's not done) 324 */ 325 status = phy_read(mii_info, PHY_BMSR); 326 if ((status & PHY_BMSR_LS) && (status & PHY_BMSR_AUTN_ABLE) 327 && !(status & PHY_BMSR_AUTN_COMP)) { 328 int i = 0; 329 330 while (!(status & PHY_BMSR_AUTN_COMP)) { 331 /* 332 * Timeout reached ? 333 */ 334 if (i > UGETH_AN_TIMEOUT) { 335 mii_info->link = 0; 336 return 0; 337 } 338 339 i++; 340 udelay(1000); /* 1 ms */ 341 status = phy_read(mii_info, PHY_BMSR); 342 } 343 mii_info->link = 1; 344 udelay(500000); /* another 500 ms (results in faster booting) */ 345 } else { 346 if (status & PHY_BMSR_LS) 347 mii_info->link = 1; 348 else 349 mii_info->link = 0; 350 } 351 352 return 0; 353 } 354 355 static int genmii_read_status (struct uec_mii_info *mii_info) 356 { 357 u16 status; 358 int err; 359 360 /* Update the link, but return if there 361 * was an error */ 362 err = genmii_update_link (mii_info); 363 if (err) 364 return err; 365 366 if (mii_info->autoneg) { 367 status = phy_read(mii_info, MII_1000BASETSTATUS); 368 369 if (status & (LPA_1000FULL | LPA_1000HALF)) { 370 mii_info->speed = SPEED_1000; 371 if (status & LPA_1000FULL) 372 mii_info->duplex = DUPLEX_FULL; 373 else 374 mii_info->duplex = DUPLEX_HALF; 375 } else { 376 status = phy_read(mii_info, PHY_ANLPAR); 377 378 if (status & (PHY_ANLPAR_10FD | PHY_ANLPAR_TXFD)) 379 mii_info->duplex = DUPLEX_FULL; 380 else 381 mii_info->duplex = DUPLEX_HALF; 382 if (status & (PHY_ANLPAR_TXFD | PHY_ANLPAR_TX)) 383 mii_info->speed = SPEED_100; 384 else 385 mii_info->speed = SPEED_10; 386 } 387 mii_info->pause = 0; 388 } 389 /* On non-aneg, we assume what we put in BMCR is the speed, 390 * though magic-aneg shouldn't prevent this case from occurring 391 */ 392 393 return 0; 394 } 395 396 static int bcm_init(struct uec_mii_info *mii_info) 397 { 398 struct eth_device *edev = mii_info->dev; 399 uec_private_t *uec = edev->priv; 400 401 gbit_config_aneg(mii_info); 402 403 if (uec->uec_info->enet_interface == ENET_1000_RGMII_RXID) { 404 u16 val; 405 int cnt = 50; 406 407 /* Wait for aneg to complete. */ 408 do 409 val = phy_read(mii_info, PHY_BMSR); 410 while (--cnt && !(val & PHY_BMSR_AUTN_COMP)); 411 412 /* Set RDX clk delay. */ 413 phy_write(mii_info, 0x18, 0x7 | (7 << 12)); 414 415 val = phy_read(mii_info, 0x18); 416 /* Set RDX-RXC skew. */ 417 val |= (1 << 8); 418 val |= (7 | (7 << 12)); 419 /* Write bits 14:0. */ 420 val |= (1 << 15); 421 phy_write(mii_info, 0x18, val); 422 } 423 424 return 0; 425 } 426 427 static int marvell_init(struct uec_mii_info *mii_info) 428 { 429 struct eth_device *edev = mii_info->dev; 430 uec_private_t *uec = edev->priv; 431 432 if (uec->uec_info->enet_interface == ENET_1000_RGMII_ID) { 433 int temp; 434 435 temp = phy_read(mii_info, MII_M1111_PHY_EXT_CR); 436 temp |= (MII_M1111_RX_DELAY | MII_M1111_TX_DELAY); 437 phy_write(mii_info, MII_M1111_PHY_EXT_CR, temp); 438 439 temp = phy_read(mii_info, MII_M1111_PHY_EXT_SR); 440 temp &= ~MII_M1111_HWCFG_MODE_MASK; 441 temp |= MII_M1111_HWCFG_MODE_RGMII; 442 phy_write(mii_info, MII_M1111_PHY_EXT_SR, temp); 443 444 phy_write(mii_info, PHY_BMCR, PHY_BMCR_RESET); 445 } 446 447 return 0; 448 } 449 450 static int marvell_read_status (struct uec_mii_info *mii_info) 451 { 452 u16 status; 453 int err; 454 455 /* Update the link, but return if there 456 * was an error */ 457 err = genmii_update_link (mii_info); 458 if (err) 459 return err; 460 461 /* If the link is up, read the speed and duplex */ 462 /* If we aren't autonegotiating, assume speeds 463 * are as set */ 464 if (mii_info->autoneg && mii_info->link) { 465 int speed; 466 467 status = phy_read (mii_info, MII_M1011_PHY_SPEC_STATUS); 468 469 /* Get the duplexity */ 470 if (status & MII_M1011_PHY_SPEC_STATUS_FULLDUPLEX) 471 mii_info->duplex = DUPLEX_FULL; 472 else 473 mii_info->duplex = DUPLEX_HALF; 474 475 /* Get the speed */ 476 speed = status & MII_M1011_PHY_SPEC_STATUS_SPD_MASK; 477 switch (speed) { 478 case MII_M1011_PHY_SPEC_STATUS_1000: 479 mii_info->speed = SPEED_1000; 480 break; 481 case MII_M1011_PHY_SPEC_STATUS_100: 482 mii_info->speed = SPEED_100; 483 break; 484 default: 485 mii_info->speed = SPEED_10; 486 break; 487 } 488 mii_info->pause = 0; 489 } 490 491 return 0; 492 } 493 494 static int marvell_ack_interrupt (struct uec_mii_info *mii_info) 495 { 496 /* Clear the interrupts by reading the reg */ 497 phy_read (mii_info, MII_M1011_IEVENT); 498 499 return 0; 500 } 501 502 static int marvell_config_intr (struct uec_mii_info *mii_info) 503 { 504 if (mii_info->interrupts == MII_INTERRUPT_ENABLED) 505 phy_write (mii_info, MII_M1011_IMASK, MII_M1011_IMASK_INIT); 506 else 507 phy_write (mii_info, MII_M1011_IMASK, MII_M1011_IMASK_CLEAR); 508 509 return 0; 510 } 511 512 static int dm9161_init (struct uec_mii_info *mii_info) 513 { 514 /* Reset the PHY */ 515 phy_write (mii_info, PHY_BMCR, phy_read (mii_info, PHY_BMCR) | 516 PHY_BMCR_RESET); 517 /* PHY and MAC connect */ 518 phy_write (mii_info, PHY_BMCR, phy_read (mii_info, PHY_BMCR) & 519 ~PHY_BMCR_ISO); 520 521 phy_write (mii_info, MII_DM9161_SCR, MII_DM9161_SCR_INIT); 522 523 config_genmii_advert (mii_info); 524 /* Start/restart aneg */ 525 genmii_config_aneg (mii_info); 526 527 return 0; 528 } 529 530 static int dm9161_config_aneg (struct uec_mii_info *mii_info) 531 { 532 return 0; 533 } 534 535 static int dm9161_read_status (struct uec_mii_info *mii_info) 536 { 537 u16 status; 538 int err; 539 540 /* Update the link, but return if there was an error */ 541 err = genmii_update_link (mii_info); 542 if (err) 543 return err; 544 /* If the link is up, read the speed and duplex 545 If we aren't autonegotiating assume speeds are as set */ 546 if (mii_info->autoneg && mii_info->link) { 547 status = phy_read (mii_info, MII_DM9161_SCSR); 548 if (status & (MII_DM9161_SCSR_100F | MII_DM9161_SCSR_100H)) 549 mii_info->speed = SPEED_100; 550 else 551 mii_info->speed = SPEED_10; 552 553 if (status & (MII_DM9161_SCSR_100F | MII_DM9161_SCSR_10F)) 554 mii_info->duplex = DUPLEX_FULL; 555 else 556 mii_info->duplex = DUPLEX_HALF; 557 } 558 559 return 0; 560 } 561 562 static int dm9161_ack_interrupt (struct uec_mii_info *mii_info) 563 { 564 /* Clear the interrupt by reading the reg */ 565 phy_read (mii_info, MII_DM9161_INTR); 566 567 return 0; 568 } 569 570 static int dm9161_config_intr (struct uec_mii_info *mii_info) 571 { 572 if (mii_info->interrupts == MII_INTERRUPT_ENABLED) 573 phy_write (mii_info, MII_DM9161_INTR, MII_DM9161_INTR_INIT); 574 else 575 phy_write (mii_info, MII_DM9161_INTR, MII_DM9161_INTR_STOP); 576 577 return 0; 578 } 579 580 static void dm9161_close (struct uec_mii_info *mii_info) 581 { 582 } 583 584 static int fixed_phy_aneg (struct uec_mii_info *mii_info) 585 { 586 mii_info->autoneg = 0; /* Turn off auto negotiation for fixed phy */ 587 return 0; 588 } 589 590 static int fixed_phy_read_status (struct uec_mii_info *mii_info) 591 { 592 int i = 0; 593 594 for (i = 0; i < ARRAY_SIZE(fixed_phy_port); i++) { 595 if (mii_info->mii_id == fixed_phy_port[i].devnum) { 596 mii_info->speed = fixed_phy_port[i].speed; 597 mii_info->duplex = fixed_phy_port[i].duplex; 598 mii_info->link = 1; /* Link is always UP */ 599 mii_info->pause = 0; 600 break; 601 } 602 } 603 return 0; 604 } 605 606 static struct phy_info phy_info_dm9161 = { 607 .phy_id = 0x0181b880, 608 .phy_id_mask = 0x0ffffff0, 609 .name = "Davicom DM9161E", 610 .init = dm9161_init, 611 .config_aneg = dm9161_config_aneg, 612 .read_status = dm9161_read_status, 613 .close = dm9161_close, 614 }; 615 616 static struct phy_info phy_info_dm9161a = { 617 .phy_id = 0x0181b8a0, 618 .phy_id_mask = 0x0ffffff0, 619 .name = "Davicom DM9161A", 620 .features = MII_BASIC_FEATURES, 621 .init = dm9161_init, 622 .config_aneg = dm9161_config_aneg, 623 .read_status = dm9161_read_status, 624 .ack_interrupt = dm9161_ack_interrupt, 625 .config_intr = dm9161_config_intr, 626 .close = dm9161_close, 627 }; 628 629 static struct phy_info phy_info_marvell = { 630 .phy_id = 0x01410c00, 631 .phy_id_mask = 0xffffff00, 632 .name = "Marvell 88E11x1", 633 .features = MII_GBIT_FEATURES, 634 .init = &marvell_init, 635 .config_aneg = &marvell_config_aneg, 636 .read_status = &marvell_read_status, 637 .ack_interrupt = &marvell_ack_interrupt, 638 .config_intr = &marvell_config_intr, 639 }; 640 641 static struct phy_info phy_info_bcm5481 = { 642 .phy_id = 0x0143bca0, 643 .phy_id_mask = 0xffffff0, 644 .name = "Broadcom 5481", 645 .features = MII_GBIT_FEATURES, 646 .read_status = genmii_read_status, 647 .init = bcm_init, 648 }; 649 650 static struct phy_info phy_info_fixedphy = { 651 .phy_id = CONFIG_FIXED_PHY, 652 .phy_id_mask = CONFIG_FIXED_PHY, 653 .name = "Fixed PHY", 654 .config_aneg = fixed_phy_aneg, 655 .read_status = fixed_phy_read_status, 656 }; 657 658 static struct phy_info phy_info_genmii = { 659 .phy_id = 0x00000000, 660 .phy_id_mask = 0x00000000, 661 .name = "Generic MII", 662 .features = MII_BASIC_FEATURES, 663 .config_aneg = genmii_config_aneg, 664 .read_status = genmii_read_status, 665 }; 666 667 static struct phy_info *phy_info[] = { 668 &phy_info_dm9161, 669 &phy_info_dm9161a, 670 &phy_info_marvell, 671 &phy_info_bcm5481, 672 &phy_info_fixedphy, 673 &phy_info_genmii, 674 NULL 675 }; 676 677 u16 phy_read (struct uec_mii_info *mii_info, u16 regnum) 678 { 679 return mii_info->mdio_read (mii_info->dev, mii_info->mii_id, regnum); 680 } 681 682 void phy_write (struct uec_mii_info *mii_info, u16 regnum, u16 val) 683 { 684 mii_info->mdio_write (mii_info->dev, mii_info->mii_id, regnum, val); 685 } 686 687 /* Use the PHY ID registers to determine what type of PHY is attached 688 * to device dev. return a struct phy_info structure describing that PHY 689 */ 690 struct phy_info *uec_get_phy_info (struct uec_mii_info *mii_info) 691 { 692 u16 phy_reg; 693 u32 phy_ID; 694 int i; 695 struct phy_info *theInfo = NULL; 696 697 /* Grab the bits from PHYIR1, and put them in the upper half */ 698 phy_reg = phy_read (mii_info, PHY_PHYIDR1); 699 phy_ID = (phy_reg & 0xffff) << 16; 700 701 /* Grab the bits from PHYIR2, and put them in the lower half */ 702 phy_reg = phy_read (mii_info, PHY_PHYIDR2); 703 phy_ID |= (phy_reg & 0xffff); 704 705 /* loop through all the known PHY types, and find one that */ 706 /* matches the ID we read from the PHY. */ 707 for (i = 0; phy_info[i]; i++) 708 if (phy_info[i]->phy_id == 709 (phy_ID & phy_info[i]->phy_id_mask)) { 710 theInfo = phy_info[i]; 711 break; 712 } 713 714 /* This shouldn't happen, as we have generic PHY support */ 715 if (theInfo == NULL) { 716 ugphy_info ("UEC: PHY id %x is not supported!", phy_ID); 717 return NULL; 718 } else { 719 ugphy_info ("UEC: PHY is %s (%x)", theInfo->name, phy_ID); 720 } 721 722 return theInfo; 723 } 724 725 void marvell_phy_interface_mode (struct eth_device *dev, 726 enet_interface_e mode) 727 { 728 uec_private_t *uec = (uec_private_t *) dev->priv; 729 struct uec_mii_info *mii_info; 730 u16 status; 731 732 if (!uec->mii_info) { 733 printf ("%s: the PHY not initialized\n", __FUNCTION__); 734 return; 735 } 736 mii_info = uec->mii_info; 737 738 if (mode == ENET_100_RGMII) { 739 phy_write (mii_info, 0x00, 0x9140); 740 phy_write (mii_info, 0x1d, 0x001f); 741 phy_write (mii_info, 0x1e, 0x200c); 742 phy_write (mii_info, 0x1d, 0x0005); 743 phy_write (mii_info, 0x1e, 0x0000); 744 phy_write (mii_info, 0x1e, 0x0100); 745 phy_write (mii_info, 0x09, 0x0e00); 746 phy_write (mii_info, 0x04, 0x01e1); 747 phy_write (mii_info, 0x00, 0x9140); 748 phy_write (mii_info, 0x00, 0x1000); 749 udelay (100000); 750 phy_write (mii_info, 0x00, 0x2900); 751 phy_write (mii_info, 0x14, 0x0cd2); 752 phy_write (mii_info, 0x00, 0xa100); 753 phy_write (mii_info, 0x09, 0x0000); 754 phy_write (mii_info, 0x1b, 0x800b); 755 phy_write (mii_info, 0x04, 0x05e1); 756 phy_write (mii_info, 0x00, 0xa100); 757 phy_write (mii_info, 0x00, 0x2100); 758 udelay (1000000); 759 } else if (mode == ENET_10_RGMII) { 760 phy_write (mii_info, 0x14, 0x8e40); 761 phy_write (mii_info, 0x1b, 0x800b); 762 phy_write (mii_info, 0x14, 0x0c82); 763 phy_write (mii_info, 0x00, 0x8100); 764 udelay (1000000); 765 } 766 767 /* handle 88e1111 rev.B2 erratum 5.6 */ 768 if (mii_info->autoneg) { 769 status = phy_read (mii_info, PHY_BMCR); 770 phy_write (mii_info, PHY_BMCR, status | PHY_BMCR_AUTON); 771 } 772 /* now the B2 will correctly report autoneg completion status */ 773 } 774 775 void change_phy_interface_mode (struct eth_device *dev, enet_interface_e mode) 776 { 777 #ifdef CONFIG_PHY_MODE_NEED_CHANGE 778 marvell_phy_interface_mode (dev, mode); 779 #endif 780 } 781