ti.c 9.4 KB

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