ti.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. /*
  2. * TI PHY drivers
  3. *
  4. * SPDX-License-Identifier: GPL-2.0
  5. *
  6. */
  7. #include <common.h>
  8. #include <phy.h>
  9. /* TI DP83867 */
  10. #define DP83867_DEVADDR 0x1f
  11. #define MII_DP83867_PHYCTRL 0x10
  12. #define MII_DP83867_MICR 0x12
  13. #define DP83867_CTRL 0x1f
  14. /* Extended Registers */
  15. #define DP83867_RGMIICTL 0x0032
  16. #define DP83867_RGMIIDCTL 0x0086
  17. #define DP83867_SW_RESET BIT(15)
  18. #define DP83867_SW_RESTART BIT(14)
  19. /* MICR Interrupt bits */
  20. #define MII_DP83867_MICR_AN_ERR_INT_EN BIT(15)
  21. #define MII_DP83867_MICR_SPEED_CHNG_INT_EN BIT(14)
  22. #define MII_DP83867_MICR_DUP_MODE_CHNG_INT_EN BIT(13)
  23. #define MII_DP83867_MICR_PAGE_RXD_INT_EN BIT(12)
  24. #define MII_DP83867_MICR_AUTONEG_COMP_INT_EN BIT(11)
  25. #define MII_DP83867_MICR_LINK_STS_CHNG_INT_EN BIT(10)
  26. #define MII_DP83867_MICR_FALSE_CARRIER_INT_EN BIT(8)
  27. #define MII_DP83867_MICR_SLEEP_MODE_CHNG_INT_EN BIT(4)
  28. #define MII_DP83867_MICR_WOL_INT_EN BIT(3)
  29. #define MII_DP83867_MICR_XGMII_ERR_INT_EN BIT(2)
  30. #define MII_DP83867_MICR_POL_CHNG_INT_EN BIT(1)
  31. #define MII_DP83867_MICR_JABBER_INT_EN BIT(0)
  32. /* RGMIICTL bits */
  33. #define DP83867_RGMII_TX_CLK_DELAY_EN BIT(1)
  34. #define DP83867_RGMII_RX_CLK_DELAY_EN BIT(0)
  35. /* PHY CTRL bits */
  36. #define DP83867_PHYCR_FIFO_DEPTH_SHIFT 14
  37. #define DP83867_MDI_CROSSOVER 5
  38. #define DP83867_MDI_CROSSOVER_AUTO 2
  39. /* RGMIIDCTL bits */
  40. #define DP83867_RGMII_TX_CLK_DELAY_SHIFT 4
  41. #define MII_MMD_CTRL 0x0d /* MMD Access Control Register */
  42. #define MII_MMD_DATA 0x0e /* MMD Access Data Register */
  43. /* MMD Access Control register fields */
  44. #define MII_MMD_CTRL_DEVAD_MASK 0x1f /* Mask MMD DEVAD*/
  45. #define MII_MMD_CTRL_ADDR 0x0000 /* Address */
  46. #define MII_MMD_CTRL_NOINCR 0x4000 /* no post increment */
  47. #define MII_MMD_CTRL_INCR_RDWT 0x8000 /* post increment on reads & writes */
  48. #define MII_MMD_CTRL_INCR_ON_WT 0xC000 /* post increment on writes only */
  49. /**
  50. * phy_read_mmd_indirect - reads data from the MMD registers
  51. * @phydev: The PHY device bus
  52. * @prtad: MMD Address
  53. * @devad: MMD DEVAD
  54. * @addr: PHY address on the MII bus
  55. *
  56. * Description: it reads data from the MMD registers (clause 22 to access to
  57. * clause 45) of the specified phy address.
  58. * To read these registers we have:
  59. * 1) Write reg 13 // DEVAD
  60. * 2) Write reg 14 // MMD Address
  61. * 3) Write reg 13 // MMD Data Command for MMD DEVAD
  62. * 3) Read reg 14 // Read MMD data
  63. */
  64. int phy_read_mmd_indirect(struct phy_device *phydev, int prtad,
  65. int devad, int addr)
  66. {
  67. int value = -1;
  68. /* Write the desired MMD Devad */
  69. phy_write(phydev, addr, MII_MMD_CTRL, devad);
  70. /* Write the desired MMD register address */
  71. phy_write(phydev, addr, MII_MMD_DATA, prtad);
  72. /* Select the Function : DATA with no post increment */
  73. phy_write(phydev, addr, MII_MMD_CTRL, (devad | MII_MMD_CTRL_NOINCR));
  74. /* Read the content of the MMD's selected register */
  75. value = phy_read(phydev, addr, MII_MMD_DATA);
  76. return value;
  77. }
  78. /**
  79. * phy_write_mmd_indirect - writes data to the MMD registers
  80. * @phydev: The PHY device
  81. * @prtad: MMD Address
  82. * @devad: MMD DEVAD
  83. * @addr: PHY address on the MII bus
  84. * @data: data to write in the MMD register
  85. *
  86. * Description: Write data from the MMD registers of the specified
  87. * phy address.
  88. * To write these registers we have:
  89. * 1) Write reg 13 // DEVAD
  90. * 2) Write reg 14 // MMD Address
  91. * 3) Write reg 13 // MMD Data Command for MMD DEVAD
  92. * 3) Write reg 14 // Write MMD data
  93. */
  94. void phy_write_mmd_indirect(struct phy_device *phydev, int prtad,
  95. int devad, int addr, u32 data)
  96. {
  97. /* Write the desired MMD Devad */
  98. phy_write(phydev, addr, MII_MMD_CTRL, devad);
  99. /* Write the desired MMD register address */
  100. phy_write(phydev, addr, MII_MMD_DATA, prtad);
  101. /* Select the Function : DATA with no post increment */
  102. phy_write(phydev, addr, MII_MMD_CTRL, (devad | MII_MMD_CTRL_NOINCR));
  103. /* Write the data into MMD's selected register */
  104. phy_write(phydev, addr, MII_MMD_DATA, data);
  105. }
  106. /**
  107. * phy_interface_is_rgmii - Convenience function for testing if a PHY interface
  108. * is RGMII (all variants)
  109. * @phydev: the phy_device struct
  110. */
  111. static inline bool phy_interface_is_rgmii(struct phy_device *phydev)
  112. {
  113. return phydev->interface >= PHY_INTERFACE_MODE_RGMII &&
  114. phydev->interface <= PHY_INTERFACE_MODE_RGMII_TXID;
  115. }
  116. /* User setting - can be taken from DTS */
  117. #define RX_ID_DELAY 8
  118. #define TX_ID_DELAY 0xa
  119. #define FIFO_DEPTH 1
  120. static int dp83867_config(struct phy_device *phydev)
  121. {
  122. unsigned int val, delay;
  123. int ret;
  124. /* Restart the PHY. */
  125. val = phy_read(phydev, MDIO_DEVAD_NONE, DP83867_CTRL);
  126. phy_write(phydev, MDIO_DEVAD_NONE, DP83867_CTRL,
  127. val | DP83867_SW_RESTART);
  128. if (phy_interface_is_rgmii(phydev)) {
  129. ret = phy_write(phydev, MDIO_DEVAD_NONE, MII_DP83867_PHYCTRL,
  130. (DP83867_MDI_CROSSOVER_AUTO << DP83867_MDI_CROSSOVER) |
  131. (FIFO_DEPTH << DP83867_PHYCR_FIFO_DEPTH_SHIFT));
  132. if (ret)
  133. return ret;
  134. }
  135. if ((phydev->interface >= PHY_INTERFACE_MODE_RGMII_ID) &&
  136. (phydev->interface <= PHY_INTERFACE_MODE_RGMII_RXID)) {
  137. val = phy_read_mmd_indirect(phydev, DP83867_RGMIICTL,
  138. DP83867_DEVADDR, phydev->addr);
  139. if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
  140. val |= (DP83867_RGMII_TX_CLK_DELAY_EN |
  141. DP83867_RGMII_RX_CLK_DELAY_EN);
  142. if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
  143. val |= DP83867_RGMII_TX_CLK_DELAY_EN;
  144. if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
  145. val |= DP83867_RGMII_RX_CLK_DELAY_EN;
  146. phy_write_mmd_indirect(phydev, DP83867_RGMIICTL,
  147. DP83867_DEVADDR, phydev->addr, val);
  148. delay = (RX_ID_DELAY |
  149. (TX_ID_DELAY << DP83867_RGMII_TX_CLK_DELAY_SHIFT));
  150. phy_write_mmd_indirect(phydev, DP83867_RGMIIDCTL,
  151. DP83867_DEVADDR, phydev->addr, delay);
  152. }
  153. genphy_config_aneg(phydev);
  154. return 0;
  155. }
  156. static struct phy_driver DP83867_driver = {
  157. .name = "TI DP83867",
  158. .uid = 0x2000a231,
  159. .mask = 0xfffffff0,
  160. .features = PHY_GBIT_FEATURES,
  161. .config = &dp83867_config,
  162. .startup = &genphy_startup,
  163. .shutdown = &genphy_shutdown,
  164. };
  165. int phy_ti_init(void)
  166. {
  167. phy_register(&DP83867_driver);
  168. return 0;
  169. }