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 #if defined(CONFIG_QE) 30 31 #define UEC_VERBOSE_DEBUG 32 #define ugphy_printk(format, arg...) \ 33 printf(format "\n", ## arg) 34 35 #define ugphy_dbg(format, arg...) \ 36 ugphy_printk(format , ## arg) 37 #define ugphy_err(format, arg...) \ 38 ugphy_printk(format , ## arg) 39 #define ugphy_info(format, arg...) \ 40 ugphy_printk(format , ## arg) 41 #define ugphy_warn(format, arg...) \ 42 ugphy_printk(format , ## arg) 43 44 #ifdef UEC_VERBOSE_DEBUG 45 #define ugphy_vdbg ugphy_dbg 46 #else 47 #define ugphy_vdbg(ugeth, fmt, args...) do { } while (0) 48 #endif /* UEC_VERBOSE_DEBUG */ 49 50 static void config_genmii_advert (struct uec_mii_info *mii_info); 51 static void genmii_setup_forced (struct uec_mii_info *mii_info); 52 static void genmii_restart_aneg (struct uec_mii_info *mii_info); 53 static int gbit_config_aneg (struct uec_mii_info *mii_info); 54 static int genmii_config_aneg (struct uec_mii_info *mii_info); 55 static int genmii_update_link (struct uec_mii_info *mii_info); 56 static int genmii_read_status (struct uec_mii_info *mii_info); 57 u16 phy_read (struct uec_mii_info *mii_info, u16 regnum); 58 void phy_write (struct uec_mii_info *mii_info, u16 regnum, u16 val); 59 60 /* Write value to the PHY for this device to the register at regnum, */ 61 /* waiting until the write is done before it returns. All PHY */ 62 /* configuration has to be done through the TSEC1 MIIM regs */ 63 void write_phy_reg (struct eth_device *dev, int mii_id, int regnum, int value) 64 { 65 uec_private_t *ugeth = (uec_private_t *) dev->priv; 66 uec_t *ug_regs; 67 enet_tbi_mii_reg_e mii_reg = (enet_tbi_mii_reg_e) regnum; 68 u32 tmp_reg; 69 70 ug_regs = ugeth->uec_regs; 71 72 /* Stop the MII management read cycle */ 73 out_be32 (&ug_regs->miimcom, 0); 74 /* Setting up the MII Mangement Address Register */ 75 tmp_reg = ((u32) mii_id << MIIMADD_PHY_ADDRESS_SHIFT) | mii_reg; 76 out_be32 (&ug_regs->miimadd, tmp_reg); 77 78 /* Setting up the MII Mangement Control Register with the value */ 79 out_be32 (&ug_regs->miimcon, (u32) value); 80 81 /* Wait till MII management write is complete */ 82 while ((in_be32 (&ug_regs->miimind)) & MIIMIND_BUSY); 83 84 udelay (100000); 85 } 86 87 /* Reads from register regnum in the PHY for device dev, */ 88 /* returning the value. Clears miimcom first. All PHY */ 89 /* configuration has to be done through the TSEC1 MIIM regs */ 90 int read_phy_reg (struct eth_device *dev, int mii_id, int regnum) 91 { 92 uec_private_t *ugeth = (uec_private_t *) dev->priv; 93 uec_t *ug_regs; 94 enet_tbi_mii_reg_e mii_reg = (enet_tbi_mii_reg_e) regnum; 95 u32 tmp_reg; 96 u16 value; 97 98 ug_regs = ugeth->uec_regs; 99 100 /* Setting up the MII Mangement Address Register */ 101 tmp_reg = ((u32) mii_id << MIIMADD_PHY_ADDRESS_SHIFT) | mii_reg; 102 out_be32 (&ug_regs->miimadd, tmp_reg); 103 104 /* Perform an MII management read cycle */ 105 out_be32 (&ug_regs->miimcom, 0); 106 out_be32 (&ug_regs->miimcom, MIIMCOM_READ_CYCLE); 107 108 /* Wait till MII management write is complete */ 109 while ((in_be32 (&ug_regs->miimind)) & 110 (MIIMIND_NOT_VALID | MIIMIND_BUSY)); 111 112 udelay (100000); 113 114 /* Read MII management status */ 115 value = (u16) in_be32 (&ug_regs->miimstat); 116 if (value == 0xffff) 117 ugphy_warn 118 ("read wrong value : mii_id %d,mii_reg %d, base %08x", 119 mii_id, mii_reg, (u32) & (ug_regs->miimcfg)); 120 121 return (value); 122 } 123 124 void mii_clear_phy_interrupt (struct uec_mii_info *mii_info) 125 { 126 if (mii_info->phyinfo->ack_interrupt) 127 mii_info->phyinfo->ack_interrupt (mii_info); 128 } 129 130 void mii_configure_phy_interrupt (struct uec_mii_info *mii_info, 131 u32 interrupts) 132 { 133 mii_info->interrupts = interrupts; 134 if (mii_info->phyinfo->config_intr) 135 mii_info->phyinfo->config_intr (mii_info); 136 } 137 138 /* Writes MII_ADVERTISE with the appropriate values, after 139 * sanitizing advertise to make sure only supported features 140 * are advertised 141 */ 142 static void config_genmii_advert (struct uec_mii_info *mii_info) 143 { 144 u32 advertise; 145 u16 adv; 146 147 /* Only allow advertising what this PHY supports */ 148 mii_info->advertising &= mii_info->phyinfo->features; 149 advertise = mii_info->advertising; 150 151 /* Setup standard advertisement */ 152 adv = phy_read (mii_info, PHY_ANAR); 153 adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4); 154 if (advertise & ADVERTISED_10baseT_Half) 155 adv |= ADVERTISE_10HALF; 156 if (advertise & ADVERTISED_10baseT_Full) 157 adv |= ADVERTISE_10FULL; 158 if (advertise & ADVERTISED_100baseT_Half) 159 adv |= ADVERTISE_100HALF; 160 if (advertise & ADVERTISED_100baseT_Full) 161 adv |= ADVERTISE_100FULL; 162 phy_write (mii_info, PHY_ANAR, adv); 163 } 164 165 static void genmii_setup_forced (struct uec_mii_info *mii_info) 166 { 167 u16 ctrl; 168 u32 features = mii_info->phyinfo->features; 169 170 ctrl = phy_read (mii_info, PHY_BMCR); 171 172 ctrl &= ~(PHY_BMCR_DPLX | PHY_BMCR_100_MBPS | 173 PHY_BMCR_1000_MBPS | PHY_BMCR_AUTON); 174 ctrl |= PHY_BMCR_RESET; 175 176 switch (mii_info->speed) { 177 case SPEED_1000: 178 if (features & (SUPPORTED_1000baseT_Half 179 | SUPPORTED_1000baseT_Full)) { 180 ctrl |= PHY_BMCR_1000_MBPS; 181 break; 182 } 183 mii_info->speed = SPEED_100; 184 case SPEED_100: 185 if (features & (SUPPORTED_100baseT_Half 186 | SUPPORTED_100baseT_Full)) { 187 ctrl |= PHY_BMCR_100_MBPS; 188 break; 189 } 190 mii_info->speed = SPEED_10; 191 case SPEED_10: 192 if (features & (SUPPORTED_10baseT_Half 193 | SUPPORTED_10baseT_Full)) 194 break; 195 default: /* Unsupported speed! */ 196 ugphy_err ("%s: Bad speed!", mii_info->dev->name); 197 break; 198 } 199 200 phy_write (mii_info, PHY_BMCR, ctrl); 201 } 202 203 /* Enable and Restart Autonegotiation */ 204 static void genmii_restart_aneg (struct uec_mii_info *mii_info) 205 { 206 u16 ctl; 207 208 ctl = phy_read (mii_info, PHY_BMCR); 209 ctl |= (PHY_BMCR_AUTON | PHY_BMCR_RST_NEG); 210 phy_write (mii_info, PHY_BMCR, ctl); 211 } 212 213 static int gbit_config_aneg (struct uec_mii_info *mii_info) 214 { 215 u16 adv; 216 u32 advertise; 217 218 if (mii_info->autoneg) { 219 /* Configure the ADVERTISE register */ 220 config_genmii_advert (mii_info); 221 advertise = mii_info->advertising; 222 223 adv = phy_read (mii_info, MII_1000BASETCONTROL); 224 adv &= ~(MII_1000BASETCONTROL_FULLDUPLEXCAP | 225 MII_1000BASETCONTROL_HALFDUPLEXCAP); 226 if (advertise & SUPPORTED_1000baseT_Half) 227 adv |= MII_1000BASETCONTROL_HALFDUPLEXCAP; 228 if (advertise & SUPPORTED_1000baseT_Full) 229 adv |= MII_1000BASETCONTROL_FULLDUPLEXCAP; 230 phy_write (mii_info, MII_1000BASETCONTROL, adv); 231 232 /* Start/Restart aneg */ 233 genmii_restart_aneg (mii_info); 234 } else 235 genmii_setup_forced (mii_info); 236 237 return 0; 238 } 239 240 static int marvell_config_aneg (struct uec_mii_info *mii_info) 241 { 242 /* The Marvell PHY has an errata which requires 243 * that certain registers get written in order 244 * to restart autonegotiation */ 245 phy_write (mii_info, PHY_BMCR, PHY_BMCR_RESET); 246 247 phy_write (mii_info, 0x1d, 0x1f); 248 phy_write (mii_info, 0x1e, 0x200c); 249 phy_write (mii_info, 0x1d, 0x5); 250 phy_write (mii_info, 0x1e, 0); 251 phy_write (mii_info, 0x1e, 0x100); 252 253 gbit_config_aneg (mii_info); 254 255 return 0; 256 } 257 258 static int genmii_config_aneg (struct uec_mii_info *mii_info) 259 { 260 if (mii_info->autoneg) { 261 config_genmii_advert (mii_info); 262 genmii_restart_aneg (mii_info); 263 } else 264 genmii_setup_forced (mii_info); 265 266 return 0; 267 } 268 269 static int genmii_update_link (struct uec_mii_info *mii_info) 270 { 271 u16 status; 272 273 /* Do a fake read */ 274 phy_read (mii_info, PHY_BMSR); 275 276 /* Read link and autonegotiation status */ 277 status = phy_read (mii_info, PHY_BMSR); 278 if ((status & PHY_BMSR_LS) == 0) 279 mii_info->link = 0; 280 else 281 mii_info->link = 1; 282 283 /* If we are autonegotiating, and not done, 284 * return an error */ 285 if (mii_info->autoneg && !(status & PHY_BMSR_AUTN_COMP)) 286 return -EAGAIN; 287 288 return 0; 289 } 290 291 static int genmii_read_status (struct uec_mii_info *mii_info) 292 { 293 u16 status; 294 int err; 295 296 /* Update the link, but return if there 297 * was an error */ 298 err = genmii_update_link (mii_info); 299 if (err) 300 return err; 301 302 if (mii_info->autoneg) { 303 status = phy_read (mii_info, PHY_ANLPAR); 304 305 if (status & (PHY_ANLPAR_10FD | PHY_ANLPAR_TXFD)) 306 mii_info->duplex = DUPLEX_FULL; 307 else 308 mii_info->duplex = DUPLEX_HALF; 309 if (status & (PHY_ANLPAR_TXFD | PHY_ANLPAR_TX)) 310 mii_info->speed = SPEED_100; 311 else 312 mii_info->speed = SPEED_10; 313 mii_info->pause = 0; 314 } 315 /* On non-aneg, we assume what we put in BMCR is the speed, 316 * though magic-aneg shouldn't prevent this case from occurring 317 */ 318 319 return 0; 320 } 321 322 static int marvell_read_status (struct uec_mii_info *mii_info) 323 { 324 u16 status; 325 int err; 326 327 /* Update the link, but return if there 328 * was an error */ 329 err = genmii_update_link (mii_info); 330 if (err) 331 return err; 332 333 /* If the link is up, read the speed and duplex */ 334 /* If we aren't autonegotiating, assume speeds 335 * are as set */ 336 if (mii_info->autoneg && mii_info->link) { 337 int speed; 338 339 status = phy_read (mii_info, MII_M1011_PHY_SPEC_STATUS); 340 341 /* Get the duplexity */ 342 if (status & MII_M1011_PHY_SPEC_STATUS_FULLDUPLEX) 343 mii_info->duplex = DUPLEX_FULL; 344 else 345 mii_info->duplex = DUPLEX_HALF; 346 347 /* Get the speed */ 348 speed = status & MII_M1011_PHY_SPEC_STATUS_SPD_MASK; 349 switch (speed) { 350 case MII_M1011_PHY_SPEC_STATUS_1000: 351 mii_info->speed = SPEED_1000; 352 break; 353 case MII_M1011_PHY_SPEC_STATUS_100: 354 mii_info->speed = SPEED_100; 355 break; 356 default: 357 mii_info->speed = SPEED_10; 358 break; 359 } 360 mii_info->pause = 0; 361 } 362 363 return 0; 364 } 365 366 static int marvell_ack_interrupt (struct uec_mii_info *mii_info) 367 { 368 /* Clear the interrupts by reading the reg */ 369 phy_read (mii_info, MII_M1011_IEVENT); 370 371 return 0; 372 } 373 374 static int marvell_config_intr (struct uec_mii_info *mii_info) 375 { 376 if (mii_info->interrupts == MII_INTERRUPT_ENABLED) 377 phy_write (mii_info, MII_M1011_IMASK, MII_M1011_IMASK_INIT); 378 else 379 phy_write (mii_info, MII_M1011_IMASK, MII_M1011_IMASK_CLEAR); 380 381 return 0; 382 } 383 384 static int dm9161_init (struct uec_mii_info *mii_info) 385 { 386 /* Reset the PHY */ 387 phy_write (mii_info, PHY_BMCR, phy_read (mii_info, PHY_BMCR) | 388 PHY_BMCR_RESET); 389 /* PHY and MAC connect */ 390 phy_write (mii_info, PHY_BMCR, phy_read (mii_info, PHY_BMCR) & 391 ~PHY_BMCR_ISO); 392 #ifdef CONFIG_RMII_MODE 393 phy_write (mii_info, MII_DM9161_SCR, MII_DM9161_SCR_RMII_INIT); 394 #else 395 phy_write (mii_info, MII_DM9161_SCR, MII_DM9161_SCR_INIT); 396 #endif 397 config_genmii_advert (mii_info); 398 /* Start/restart aneg */ 399 genmii_config_aneg (mii_info); 400 /* Delay to wait the aneg compeleted */ 401 udelay (3000000); 402 403 return 0; 404 } 405 406 static int dm9161_config_aneg (struct uec_mii_info *mii_info) 407 { 408 return 0; 409 } 410 411 static int dm9161_read_status (struct uec_mii_info *mii_info) 412 { 413 u16 status; 414 int err; 415 416 /* Update the link, but return if there was an error */ 417 err = genmii_update_link (mii_info); 418 if (err) 419 return err; 420 /* If the link is up, read the speed and duplex 421 If we aren't autonegotiating assume speeds are as set */ 422 if (mii_info->autoneg && mii_info->link) { 423 status = phy_read (mii_info, MII_DM9161_SCSR); 424 if (status & (MII_DM9161_SCSR_100F | MII_DM9161_SCSR_100H)) 425 mii_info->speed = SPEED_100; 426 else 427 mii_info->speed = SPEED_10; 428 429 if (status & (MII_DM9161_SCSR_100F | MII_DM9161_SCSR_10F)) 430 mii_info->duplex = DUPLEX_FULL; 431 else 432 mii_info->duplex = DUPLEX_HALF; 433 } 434 435 return 0; 436 } 437 438 static int dm9161_ack_interrupt (struct uec_mii_info *mii_info) 439 { 440 /* Clear the interrupt by reading the reg */ 441 phy_read (mii_info, MII_DM9161_INTR); 442 443 return 0; 444 } 445 446 static int dm9161_config_intr (struct uec_mii_info *mii_info) 447 { 448 if (mii_info->interrupts == MII_INTERRUPT_ENABLED) 449 phy_write (mii_info, MII_DM9161_INTR, MII_DM9161_INTR_INIT); 450 else 451 phy_write (mii_info, MII_DM9161_INTR, MII_DM9161_INTR_STOP); 452 453 return 0; 454 } 455 456 static void dm9161_close (struct uec_mii_info *mii_info) 457 { 458 } 459 460 static struct phy_info phy_info_dm9161 = { 461 .phy_id = 0x0181b880, 462 .phy_id_mask = 0x0ffffff0, 463 .name = "Davicom DM9161E", 464 .init = dm9161_init, 465 .config_aneg = dm9161_config_aneg, 466 .read_status = dm9161_read_status, 467 .close = dm9161_close, 468 }; 469 470 static struct phy_info phy_info_dm9161a = { 471 .phy_id = 0x0181b8a0, 472 .phy_id_mask = 0x0ffffff0, 473 .name = "Davicom DM9161A", 474 .features = MII_BASIC_FEATURES, 475 .init = dm9161_init, 476 .config_aneg = dm9161_config_aneg, 477 .read_status = dm9161_read_status, 478 .ack_interrupt = dm9161_ack_interrupt, 479 .config_intr = dm9161_config_intr, 480 .close = dm9161_close, 481 }; 482 483 static struct phy_info phy_info_marvell = { 484 .phy_id = 0x01410c00, 485 .phy_id_mask = 0xffffff00, 486 .name = "Marvell 88E11x1", 487 .features = MII_GBIT_FEATURES, 488 .config_aneg = &marvell_config_aneg, 489 .read_status = &marvell_read_status, 490 .ack_interrupt = &marvell_ack_interrupt, 491 .config_intr = &marvell_config_intr, 492 }; 493 494 static struct phy_info phy_info_genmii = { 495 .phy_id = 0x00000000, 496 .phy_id_mask = 0x00000000, 497 .name = "Generic MII", 498 .features = MII_BASIC_FEATURES, 499 .config_aneg = genmii_config_aneg, 500 .read_status = genmii_read_status, 501 }; 502 503 static struct phy_info *phy_info[] = { 504 &phy_info_dm9161, 505 &phy_info_dm9161a, 506 &phy_info_marvell, 507 &phy_info_genmii, 508 NULL 509 }; 510 511 u16 phy_read (struct uec_mii_info *mii_info, u16 regnum) 512 { 513 return mii_info->mdio_read (mii_info->dev, mii_info->mii_id, regnum); 514 } 515 516 void phy_write (struct uec_mii_info *mii_info, u16 regnum, u16 val) 517 { 518 mii_info->mdio_write (mii_info->dev, mii_info->mii_id, regnum, val); 519 } 520 521 /* Use the PHY ID registers to determine what type of PHY is attached 522 * to device dev. return a struct phy_info structure describing that PHY 523 */ 524 struct phy_info *get_phy_info (struct uec_mii_info *mii_info) 525 { 526 u16 phy_reg; 527 u32 phy_ID; 528 int i; 529 struct phy_info *theInfo = NULL; 530 531 /* Grab the bits from PHYIR1, and put them in the upper half */ 532 phy_reg = phy_read (mii_info, PHY_PHYIDR1); 533 phy_ID = (phy_reg & 0xffff) << 16; 534 535 /* Grab the bits from PHYIR2, and put them in the lower half */ 536 phy_reg = phy_read (mii_info, PHY_PHYIDR2); 537 phy_ID |= (phy_reg & 0xffff); 538 539 /* loop through all the known PHY types, and find one that */ 540 /* matches the ID we read from the PHY. */ 541 for (i = 0; phy_info[i]; i++) 542 if (phy_info[i]->phy_id == 543 (phy_ID & phy_info[i]->phy_id_mask)) { 544 theInfo = phy_info[i]; 545 break; 546 } 547 548 /* This shouldn't happen, as we have generic PHY support */ 549 if (theInfo == NULL) { 550 ugphy_info ("UEC: PHY id %x is not supported!", phy_ID); 551 return NULL; 552 } else { 553 ugphy_info ("UEC: PHY is %s (%x)", theInfo->name, phy_ID); 554 } 555 556 return theInfo; 557 } 558 559 void marvell_phy_interface_mode (struct eth_device *dev, 560 enet_interface_e mode) 561 { 562 uec_private_t *uec = (uec_private_t *) dev->priv; 563 struct uec_mii_info *mii_info; 564 565 if (!uec->mii_info) { 566 printf ("%s: the PHY not intialized\n", __FUNCTION__); 567 return; 568 } 569 mii_info = uec->mii_info; 570 571 if (mode == ENET_100_RGMII) { 572 phy_write (mii_info, 0x00, 0x9140); 573 phy_write (mii_info, 0x1d, 0x001f); 574 phy_write (mii_info, 0x1e, 0x200c); 575 phy_write (mii_info, 0x1d, 0x0005); 576 phy_write (mii_info, 0x1e, 0x0000); 577 phy_write (mii_info, 0x1e, 0x0100); 578 phy_write (mii_info, 0x09, 0x0e00); 579 phy_write (mii_info, 0x04, 0x01e1); 580 phy_write (mii_info, 0x00, 0x9140); 581 phy_write (mii_info, 0x00, 0x1000); 582 udelay (100000); 583 phy_write (mii_info, 0x00, 0x2900); 584 phy_write (mii_info, 0x14, 0x0cd2); 585 phy_write (mii_info, 0x00, 0xa100); 586 phy_write (mii_info, 0x09, 0x0000); 587 phy_write (mii_info, 0x1b, 0x800b); 588 phy_write (mii_info, 0x04, 0x05e1); 589 phy_write (mii_info, 0x00, 0xa100); 590 phy_write (mii_info, 0x00, 0x2100); 591 udelay (1000000); 592 } else if (mode == ENET_10_RGMII) { 593 phy_write (mii_info, 0x14, 0x8e40); 594 phy_write (mii_info, 0x1b, 0x800b); 595 phy_write (mii_info, 0x14, 0x0c82); 596 phy_write (mii_info, 0x00, 0x8100); 597 udelay (1000000); 598 } 599 } 600 601 void change_phy_interface_mode (struct eth_device *dev, enet_interface_e mode) 602 { 603 #ifdef CONFIG_PHY_MODE_NEED_CHANGE 604 marvell_phy_interface_mode (dev, mode); 605 #endif 606 } 607 #endif /* CONFIG_QE */ 608