dp83848.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. /*
  2. * National Semiconductor DP83848 PHY Driver for TI DaVinci
  3. * (TMS320DM644x) based boards.
  4. *
  5. * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
  6. *
  7. * --------------------------------------------------------
  8. *
  9. * SPDX-License-Identifier: GPL-2.0+
  10. */
  11. #include <common.h>
  12. #include <net.h>
  13. #include <dp83848.h>
  14. #include <asm/arch/emac_defs.h>
  15. #include "../../../drivers/net/davinci_emac.h"
  16. #ifdef CONFIG_DRIVER_TI_EMAC
  17. #ifdef CONFIG_CMD_NET
  18. int dp83848_is_phy_connected(int phy_addr)
  19. {
  20. u_int16_t id1, id2;
  21. if (!davinci_eth_phy_read(phy_addr, DP83848_PHYID1_REG, &id1))
  22. return(0);
  23. if (!davinci_eth_phy_read(phy_addr, DP83848_PHYID2_REG, &id2))
  24. return(0);
  25. if ((id1 == DP83848_PHYID1_OUI) && (id2 == DP83848_PHYID2_OUI))
  26. return(1);
  27. return(0);
  28. }
  29. int dp83848_get_link_speed(int phy_addr)
  30. {
  31. u_int16_t tmp;
  32. volatile emac_regs* emac = (emac_regs *)EMAC_BASE_ADDR;
  33. if (!davinci_eth_phy_read(phy_addr, DP83848_STAT_REG, &tmp))
  34. return(0);
  35. if (!(tmp & DP83848_LINK_STATUS)) /* link up? */
  36. return(0);
  37. if (!davinci_eth_phy_read(phy_addr, DP83848_PHY_STAT_REG, &tmp))
  38. return(0);
  39. /* Speed doesn't matter, there is no setting for it in EMAC... */
  40. if (tmp & DP83848_DUPLEX) {
  41. /* set DM644x EMAC for Full Duplex */
  42. emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE |
  43. EMAC_MACCONTROL_FULLDUPLEX_ENABLE;
  44. } else {
  45. /*set DM644x EMAC for Half Duplex */
  46. emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE;
  47. }
  48. return(1);
  49. }
  50. int dp83848_init_phy(int phy_addr)
  51. {
  52. int ret = 1;
  53. if (!dp83848_get_link_speed(phy_addr)) {
  54. /* Try another time */
  55. udelay(100000);
  56. ret = dp83848_get_link_speed(phy_addr);
  57. }
  58. /* Disable PHY Interrupts */
  59. davinci_eth_phy_write(phy_addr, DP83848_PHY_INTR_CTRL_REG, 0);
  60. return(ret);
  61. }
  62. int dp83848_auto_negotiate(int phy_addr)
  63. {
  64. u_int16_t tmp;
  65. if (!davinci_eth_phy_read(phy_addr, DP83848_CTL_REG, &tmp))
  66. return(0);
  67. /* Restart Auto_negotiation */
  68. tmp &= ~DP83848_AUTONEG; /* remove autonegotiation enable */
  69. tmp |= DP83848_ISOLATE; /* Electrically isolate PHY */
  70. davinci_eth_phy_write(phy_addr, DP83848_CTL_REG, tmp);
  71. /* Set the Auto_negotiation Advertisement Register
  72. * MII advertising for Next page, 100BaseTxFD and HD,
  73. * 10BaseTFD and HD, IEEE 802.3
  74. */
  75. tmp = DP83848_NP | DP83848_TX_FDX | DP83848_TX_HDX |
  76. DP83848_10_FDX | DP83848_10_HDX | DP83848_AN_IEEE_802_3;
  77. davinci_eth_phy_write(phy_addr, DP83848_ANA_REG, tmp);
  78. /* Read Control Register */
  79. if (!davinci_eth_phy_read(phy_addr, DP83848_CTL_REG, &tmp))
  80. return(0);
  81. tmp |= DP83848_SPEED_SELECT | DP83848_AUTONEG | DP83848_DUPLEX_MODE;
  82. davinci_eth_phy_write(phy_addr, DP83848_CTL_REG, tmp);
  83. /* Restart Auto_negotiation */
  84. tmp |= DP83848_RESTART_AUTONEG;
  85. davinci_eth_phy_write(phy_addr, DP83848_CTL_REG, tmp);
  86. /*check AutoNegotiate complete */
  87. udelay(10000);
  88. if (!davinci_eth_phy_read(phy_addr, DP83848_STAT_REG, &tmp))
  89. return(0);
  90. if (!(tmp & DP83848_AUTONEG_COMP))
  91. return(0);
  92. return (dp83848_get_link_speed(phy_addr));
  93. }
  94. #endif /* CONFIG_CMD_NET */
  95. #endif /* CONFIG_DRIVER_ETHER */