ti.c 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * TI PHY drivers
  4. *
  5. */
  6. #include <common.h>
  7. #include <phy.h>
  8. #include <linux/compat.h>
  9. #include <malloc.h>
  10. #include <fdtdec.h>
  11. #include <dm.h>
  12. #include <dt-bindings/net/ti-dp83867.h>
  13. DECLARE_GLOBAL_DATA_PTR;
  14. /* TI DP83867 */
  15. #define DP83867_DEVADDR 0x1f
  16. #define MII_DP83867_PHYCTRL 0x10
  17. #define MII_DP83867_MICR 0x12
  18. #define MII_DP83867_CFG2 0x14
  19. #define MII_DP83867_BISCR 0x16
  20. #define DP83867_CTRL 0x1f
  21. /* Extended Registers */
  22. #define DP83867_RGMIICTL 0x0032
  23. #define DP83867_RGMIIDCTL 0x0086
  24. #define DP83867_IO_MUX_CFG 0x0170
  25. #define DP83867_SW_RESET BIT(15)
  26. #define DP83867_SW_RESTART BIT(14)
  27. /* MICR Interrupt bits */
  28. #define MII_DP83867_MICR_AN_ERR_INT_EN BIT(15)
  29. #define MII_DP83867_MICR_SPEED_CHNG_INT_EN BIT(14)
  30. #define MII_DP83867_MICR_DUP_MODE_CHNG_INT_EN BIT(13)
  31. #define MII_DP83867_MICR_PAGE_RXD_INT_EN BIT(12)
  32. #define MII_DP83867_MICR_AUTONEG_COMP_INT_EN BIT(11)
  33. #define MII_DP83867_MICR_LINK_STS_CHNG_INT_EN BIT(10)
  34. #define MII_DP83867_MICR_FALSE_CARRIER_INT_EN BIT(8)
  35. #define MII_DP83867_MICR_SLEEP_MODE_CHNG_INT_EN BIT(4)
  36. #define MII_DP83867_MICR_WOL_INT_EN BIT(3)
  37. #define MII_DP83867_MICR_XGMII_ERR_INT_EN BIT(2)
  38. #define MII_DP83867_MICR_POL_CHNG_INT_EN BIT(1)
  39. #define MII_DP83867_MICR_JABBER_INT_EN BIT(0)
  40. /* RGMIICTL bits */
  41. #define DP83867_RGMII_TX_CLK_DELAY_EN BIT(1)
  42. #define DP83867_RGMII_RX_CLK_DELAY_EN BIT(0)
  43. /* PHY CTRL bits */
  44. #define DP83867_PHYCR_FIFO_DEPTH_SHIFT 14
  45. #define DP83867_MDI_CROSSOVER 5
  46. #define DP83867_MDI_CROSSOVER_AUTO 2
  47. #define DP83867_MDI_CROSSOVER_MDIX 2
  48. #define DP83867_PHYCTRL_SGMIIEN 0x0800
  49. #define DP83867_PHYCTRL_RXFIFO_SHIFT 12
  50. #define DP83867_PHYCTRL_TXFIFO_SHIFT 14
  51. /* RGMIIDCTL bits */
  52. #define DP83867_RGMII_TX_CLK_DELAY_SHIFT 4
  53. /* CFG2 bits */
  54. #define MII_DP83867_CFG2_SPEEDOPT_10EN 0x0040
  55. #define MII_DP83867_CFG2_SGMII_AUTONEGEN 0x0080
  56. #define MII_DP83867_CFG2_SPEEDOPT_ENH 0x0100
  57. #define MII_DP83867_CFG2_SPEEDOPT_CNT 0x0800
  58. #define MII_DP83867_CFG2_SPEEDOPT_INTLOW 0x2000
  59. #define MII_DP83867_CFG2_MASK 0x003F
  60. #define MII_MMD_CTRL 0x0d /* MMD Access Control Register */
  61. #define MII_MMD_DATA 0x0e /* MMD Access Data Register */
  62. /* MMD Access Control register fields */
  63. #define MII_MMD_CTRL_DEVAD_MASK 0x1f /* Mask MMD DEVAD*/
  64. #define MII_MMD_CTRL_ADDR 0x0000 /* Address */
  65. #define MII_MMD_CTRL_NOINCR 0x4000 /* no post increment */
  66. #define MII_MMD_CTRL_INCR_RDWT 0x8000 /* post increment on reads & writes */
  67. #define MII_MMD_CTRL_INCR_ON_WT 0xC000 /* post increment on writes only */
  68. /* User setting - can be taken from DTS */
  69. #define DEFAULT_RX_ID_DELAY DP83867_RGMIIDCTL_2_25_NS
  70. #define DEFAULT_TX_ID_DELAY DP83867_RGMIIDCTL_2_75_NS
  71. #define DEFAULT_FIFO_DEPTH DP83867_PHYCR_FIFO_DEPTH_4_B_NIB
  72. /* IO_MUX_CFG bits */
  73. #define DP83867_IO_MUX_CFG_IO_IMPEDANCE_CTRL 0x1f
  74. #define DP83867_IO_MUX_CFG_IO_IMPEDANCE_MAX 0x0
  75. #define DP83867_IO_MUX_CFG_IO_IMPEDANCE_MIN 0x1f
  76. struct dp83867_private {
  77. int rx_id_delay;
  78. int tx_id_delay;
  79. int fifo_depth;
  80. int io_impedance;
  81. };
  82. /**
  83. * phy_read_mmd_indirect - reads data from the MMD registers
  84. * @phydev: The PHY device bus
  85. * @prtad: MMD Address
  86. * @devad: MMD DEVAD
  87. * @addr: PHY address on the MII bus
  88. *
  89. * Description: it reads data from the MMD registers (clause 22 to access to
  90. * clause 45) of the specified phy address.
  91. * To read these registers we have:
  92. * 1) Write reg 13 // DEVAD
  93. * 2) Write reg 14 // MMD Address
  94. * 3) Write reg 13 // MMD Data Command for MMD DEVAD
  95. * 3) Read reg 14 // Read MMD data
  96. */
  97. int phy_read_mmd_indirect(struct phy_device *phydev, int prtad,
  98. int devad, int addr)
  99. {
  100. int value = -1;
  101. /* Write the desired MMD Devad */
  102. phy_write(phydev, addr, MII_MMD_CTRL, devad);
  103. /* Write the desired MMD register address */
  104. phy_write(phydev, addr, MII_MMD_DATA, prtad);
  105. /* Select the Function : DATA with no post increment */
  106. phy_write(phydev, addr, MII_MMD_CTRL, (devad | MII_MMD_CTRL_NOINCR));
  107. /* Read the content of the MMD's selected register */
  108. value = phy_read(phydev, addr, MII_MMD_DATA);
  109. return value;
  110. }
  111. /**
  112. * phy_write_mmd_indirect - writes data to the MMD registers
  113. * @phydev: The PHY device
  114. * @prtad: MMD Address
  115. * @devad: MMD DEVAD
  116. * @addr: PHY address on the MII bus
  117. * @data: data to write in the MMD register
  118. *
  119. * Description: Write data from the MMD registers of the specified
  120. * phy address.
  121. * To write these registers we have:
  122. * 1) Write reg 13 // DEVAD
  123. * 2) Write reg 14 // MMD Address
  124. * 3) Write reg 13 // MMD Data Command for MMD DEVAD
  125. * 3) Write reg 14 // Write MMD data
  126. */
  127. void phy_write_mmd_indirect(struct phy_device *phydev, int prtad,
  128. int devad, int addr, u32 data)
  129. {
  130. /* Write the desired MMD Devad */
  131. phy_write(phydev, addr, MII_MMD_CTRL, devad);
  132. /* Write the desired MMD register address */
  133. phy_write(phydev, addr, MII_MMD_DATA, prtad);
  134. /* Select the Function : DATA with no post increment */
  135. phy_write(phydev, addr, MII_MMD_CTRL, (devad | MII_MMD_CTRL_NOINCR));
  136. /* Write the data into MMD's selected register */
  137. phy_write(phydev, addr, MII_MMD_DATA, data);
  138. }
  139. #if defined(CONFIG_DM_ETH)
  140. /**
  141. * dp83867_data_init - Convenience function for setting PHY specific data
  142. *
  143. * @phydev: the phy_device struct
  144. */
  145. static int dp83867_of_init(struct phy_device *phydev)
  146. {
  147. struct dp83867_private *dp83867 = phydev->priv;
  148. struct udevice *dev = phydev->dev;
  149. int node = dev_of_offset(dev);
  150. const void *fdt = gd->fdt_blob;
  151. if (fdtdec_get_bool(fdt, node, "ti,max-output-impedance"))
  152. dp83867->io_impedance = DP83867_IO_MUX_CFG_IO_IMPEDANCE_MAX;
  153. else if (fdtdec_get_bool(fdt, node, "ti,min-output-impedance"))
  154. dp83867->io_impedance = DP83867_IO_MUX_CFG_IO_IMPEDANCE_MIN;
  155. else
  156. dp83867->io_impedance = -EINVAL;
  157. dp83867->rx_id_delay = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev),
  158. "ti,rx-internal-delay", -1);
  159. dp83867->tx_id_delay = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev),
  160. "ti,tx-internal-delay", -1);
  161. dp83867->fifo_depth = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev),
  162. "ti,fifo-depth", -1);
  163. return 0;
  164. }
  165. #else
  166. static int dp83867_of_init(struct phy_device *phydev)
  167. {
  168. struct dp83867_private *dp83867 = phydev->priv;
  169. dp83867->rx_id_delay = DEFAULT_RX_ID_DELAY;
  170. dp83867->tx_id_delay = DEFAULT_TX_ID_DELAY;
  171. dp83867->fifo_depth = DEFAULT_FIFO_DEPTH;
  172. dp83867->io_impedance = -EINVAL;
  173. return 0;
  174. }
  175. #endif
  176. static int dp83867_config(struct phy_device *phydev)
  177. {
  178. struct dp83867_private *dp83867;
  179. unsigned int val, delay, cfg2;
  180. int ret;
  181. if (!phydev->priv) {
  182. dp83867 = kzalloc(sizeof(*dp83867), GFP_KERNEL);
  183. if (!dp83867)
  184. return -ENOMEM;
  185. phydev->priv = dp83867;
  186. ret = dp83867_of_init(phydev);
  187. if (ret)
  188. goto err_out;
  189. } else {
  190. dp83867 = (struct dp83867_private *)phydev->priv;
  191. }
  192. /* Restart the PHY. */
  193. val = phy_read(phydev, MDIO_DEVAD_NONE, DP83867_CTRL);
  194. phy_write(phydev, MDIO_DEVAD_NONE, DP83867_CTRL,
  195. val | DP83867_SW_RESTART);
  196. if (phy_interface_is_rgmii(phydev)) {
  197. ret = phy_write(phydev, MDIO_DEVAD_NONE, MII_DP83867_PHYCTRL,
  198. (DP83867_MDI_CROSSOVER_AUTO << DP83867_MDI_CROSSOVER) |
  199. (dp83867->fifo_depth << DP83867_PHYCR_FIFO_DEPTH_SHIFT));
  200. if (ret)
  201. goto err_out;
  202. } else if (phy_interface_is_sgmii(phydev)) {
  203. phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR,
  204. (BMCR_ANENABLE | BMCR_FULLDPLX | BMCR_SPEED1000));
  205. cfg2 = phy_read(phydev, phydev->addr, MII_DP83867_CFG2);
  206. cfg2 &= MII_DP83867_CFG2_MASK;
  207. cfg2 |= (MII_DP83867_CFG2_SPEEDOPT_10EN |
  208. MII_DP83867_CFG2_SGMII_AUTONEGEN |
  209. MII_DP83867_CFG2_SPEEDOPT_ENH |
  210. MII_DP83867_CFG2_SPEEDOPT_CNT |
  211. MII_DP83867_CFG2_SPEEDOPT_INTLOW);
  212. phy_write(phydev, MDIO_DEVAD_NONE, MII_DP83867_CFG2, cfg2);
  213. phy_write_mmd_indirect(phydev, DP83867_RGMIICTL,
  214. DP83867_DEVADDR, phydev->addr, 0x0);
  215. phy_write(phydev, MDIO_DEVAD_NONE, MII_DP83867_PHYCTRL,
  216. DP83867_PHYCTRL_SGMIIEN |
  217. (DP83867_MDI_CROSSOVER_MDIX <<
  218. DP83867_MDI_CROSSOVER) |
  219. (dp83867->fifo_depth << DP83867_PHYCTRL_RXFIFO_SHIFT) |
  220. (dp83867->fifo_depth << DP83867_PHYCTRL_TXFIFO_SHIFT));
  221. phy_write(phydev, MDIO_DEVAD_NONE, MII_DP83867_BISCR, 0x0);
  222. }
  223. if (phy_interface_is_rgmii(phydev)) {
  224. val = phy_read_mmd_indirect(phydev, DP83867_RGMIICTL,
  225. DP83867_DEVADDR, phydev->addr);
  226. if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
  227. val |= (DP83867_RGMII_TX_CLK_DELAY_EN |
  228. DP83867_RGMII_RX_CLK_DELAY_EN);
  229. if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
  230. val |= DP83867_RGMII_TX_CLK_DELAY_EN;
  231. if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
  232. val |= DP83867_RGMII_RX_CLK_DELAY_EN;
  233. phy_write_mmd_indirect(phydev, DP83867_RGMIICTL,
  234. DP83867_DEVADDR, phydev->addr, val);
  235. delay = (dp83867->rx_id_delay |
  236. (dp83867->tx_id_delay << DP83867_RGMII_TX_CLK_DELAY_SHIFT));
  237. phy_write_mmd_indirect(phydev, DP83867_RGMIIDCTL,
  238. DP83867_DEVADDR, phydev->addr, delay);
  239. if (dp83867->io_impedance >= 0) {
  240. val = phy_read_mmd_indirect(phydev,
  241. DP83867_IO_MUX_CFG,
  242. DP83867_DEVADDR,
  243. phydev->addr);
  244. val &= ~DP83867_IO_MUX_CFG_IO_IMPEDANCE_CTRL;
  245. val |= dp83867->io_impedance &
  246. DP83867_IO_MUX_CFG_IO_IMPEDANCE_CTRL;
  247. phy_write_mmd_indirect(phydev, DP83867_IO_MUX_CFG,
  248. DP83867_DEVADDR, phydev->addr,
  249. val);
  250. }
  251. }
  252. genphy_config_aneg(phydev);
  253. return 0;
  254. err_out:
  255. kfree(dp83867);
  256. return ret;
  257. }
  258. static struct phy_driver DP83867_driver = {
  259. .name = "TI DP83867",
  260. .uid = 0x2000a231,
  261. .mask = 0xfffffff0,
  262. .features = PHY_GBIT_FEATURES,
  263. .config = &dp83867_config,
  264. .startup = &genphy_startup,
  265. .shutdown = &genphy_shutdown,
  266. };
  267. int phy_ti_init(void)
  268. {
  269. phy_register(&DP83867_driver);
  270. return 0;
  271. }