ti.c 9.9 KB

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