dp83848.c 3.0 KB

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