pcs-xpcs-wx.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. // SPDX-License-Identifier: GPL-2.0
  2. /* Copyright (c) 2015 - 2023 Beijing WangXun Technology Co., Ltd. */
  3. #include <linux/pcs/pcs-xpcs.h>
  4. #include <linux/mdio.h>
  5. #include "pcs-xpcs.h"
  6. /* VR_XS_PMA_MMD */
  7. #define TXGBE_PMA_MMD 0x8020
  8. #define TXGBE_TX_GENCTL1 0x11
  9. #define TXGBE_TX_GENCTL1_VBOOST_LVL GENMASK(10, 8)
  10. #define TXGBE_TX_GENCTL1_VBOOST_EN0 BIT(4)
  11. #define TXGBE_TX_GEN_CTL2 0x12
  12. #define TXGBE_TX_GEN_CTL2_TX0_WIDTH(v) FIELD_PREP(GENMASK(9, 8), v)
  13. #define TXGBE_TX_RATE_CTL 0x14
  14. #define TXGBE_TX_RATE_CTL_TX0_RATE(v) FIELD_PREP(GENMASK(2, 0), v)
  15. #define TXGBE_RX_GEN_CTL2 0x32
  16. #define TXGBE_RX_GEN_CTL2_RX0_WIDTH(v) FIELD_PREP(GENMASK(9, 8), v)
  17. #define TXGBE_RX_GEN_CTL3 0x33
  18. #define TXGBE_RX_GEN_CTL3_LOS_TRSHLD0 GENMASK(2, 0)
  19. #define TXGBE_RX_RATE_CTL 0x34
  20. #define TXGBE_RX_RATE_CTL_RX0_RATE(v) FIELD_PREP(GENMASK(1, 0), v)
  21. #define TXGBE_RX_EQ_ATTN_CTL 0x37
  22. #define TXGBE_RX_EQ_ATTN_LVL0 GENMASK(2, 0)
  23. #define TXGBE_RX_EQ_CTL0 0x38
  24. #define TXGBE_RX_EQ_CTL0_VGA1_GAIN(v) FIELD_PREP(GENMASK(15, 12), v)
  25. #define TXGBE_RX_EQ_CTL0_VGA2_GAIN(v) FIELD_PREP(GENMASK(11, 8), v)
  26. #define TXGBE_RX_EQ_CTL0_CTLE_POLE(v) FIELD_PREP(GENMASK(7, 5), v)
  27. #define TXGBE_RX_EQ_CTL0_CTLE_BOOST(v) FIELD_PREP(GENMASK(4, 0), v)
  28. #define TXGBE_RX_EQ_CTL4 0x3C
  29. #define TXGBE_RX_EQ_CTL4_CONT_OFF_CAN0 BIT(4)
  30. #define TXGBE_RX_EQ_CTL4_CONT_ADAPT0 BIT(0)
  31. #define TXGBE_AFE_DFE_ENABLE 0x3D
  32. #define TXGBE_DFE_EN_0 BIT(4)
  33. #define TXGBE_AFE_EN_0 BIT(0)
  34. #define TXGBE_DFE_TAP_CTL0 0x3E
  35. #define TXGBE_MPLLA_CTL0 0x51
  36. #define TXGBE_MPLLA_CTL2 0x53
  37. #define TXGBE_MPLLA_CTL2_DIV16P5_CLK_EN BIT(10)
  38. #define TXGBE_MPLLA_CTL2_DIV10_CLK_EN BIT(9)
  39. #define TXGBE_MPLLA_CTL3 0x57
  40. #define TXGBE_MISC_CTL0 0x70
  41. #define TXGBE_MISC_CTL0_PLL BIT(15)
  42. #define TXGBE_MISC_CTL0_CR_PARA_SEL BIT(14)
  43. #define TXGBE_MISC_CTL0_RX_VREF(v) FIELD_PREP(GENMASK(12, 8), v)
  44. #define TXGBE_VCO_CAL_LD0 0x72
  45. #define TXGBE_VCO_CAL_REF0 0x76
  46. static int txgbe_read_pma(struct dw_xpcs *xpcs, int reg)
  47. {
  48. return xpcs_read(xpcs, MDIO_MMD_PMAPMD, TXGBE_PMA_MMD + reg);
  49. }
  50. static int txgbe_write_pma(struct dw_xpcs *xpcs, int reg, u16 val)
  51. {
  52. return xpcs_write(xpcs, MDIO_MMD_PMAPMD, TXGBE_PMA_MMD + reg, val);
  53. }
  54. static void txgbe_pma_config_10gbaser(struct dw_xpcs *xpcs)
  55. {
  56. int val;
  57. txgbe_write_pma(xpcs, TXGBE_MPLLA_CTL0, 0x21);
  58. txgbe_write_pma(xpcs, TXGBE_MPLLA_CTL3, 0);
  59. val = txgbe_read_pma(xpcs, TXGBE_TX_GENCTL1);
  60. val = u16_replace_bits(val, 0x5, TXGBE_TX_GENCTL1_VBOOST_LVL);
  61. txgbe_write_pma(xpcs, TXGBE_TX_GENCTL1, val);
  62. txgbe_write_pma(xpcs, TXGBE_MISC_CTL0, TXGBE_MISC_CTL0_PLL |
  63. TXGBE_MISC_CTL0_CR_PARA_SEL | TXGBE_MISC_CTL0_RX_VREF(0xF));
  64. txgbe_write_pma(xpcs, TXGBE_VCO_CAL_LD0, 0x549);
  65. txgbe_write_pma(xpcs, TXGBE_VCO_CAL_REF0, 0x29);
  66. txgbe_write_pma(xpcs, TXGBE_TX_RATE_CTL, 0);
  67. txgbe_write_pma(xpcs, TXGBE_RX_RATE_CTL, 0);
  68. txgbe_write_pma(xpcs, TXGBE_TX_GEN_CTL2, TXGBE_TX_GEN_CTL2_TX0_WIDTH(3));
  69. txgbe_write_pma(xpcs, TXGBE_RX_GEN_CTL2, TXGBE_RX_GEN_CTL2_RX0_WIDTH(3));
  70. txgbe_write_pma(xpcs, TXGBE_MPLLA_CTL2, TXGBE_MPLLA_CTL2_DIV16P5_CLK_EN |
  71. TXGBE_MPLLA_CTL2_DIV10_CLK_EN);
  72. txgbe_write_pma(xpcs, TXGBE_RX_EQ_CTL0, TXGBE_RX_EQ_CTL0_CTLE_POLE(2) |
  73. TXGBE_RX_EQ_CTL0_CTLE_BOOST(5));
  74. val = txgbe_read_pma(xpcs, TXGBE_RX_EQ_ATTN_CTL);
  75. val &= ~TXGBE_RX_EQ_ATTN_LVL0;
  76. txgbe_write_pma(xpcs, TXGBE_RX_EQ_ATTN_CTL, val);
  77. txgbe_write_pma(xpcs, TXGBE_DFE_TAP_CTL0, 0xBE);
  78. val = txgbe_read_pma(xpcs, TXGBE_AFE_DFE_ENABLE);
  79. val &= ~(TXGBE_DFE_EN_0 | TXGBE_AFE_EN_0);
  80. txgbe_write_pma(xpcs, TXGBE_AFE_DFE_ENABLE, val);
  81. val = txgbe_read_pma(xpcs, TXGBE_RX_EQ_CTL4);
  82. val &= ~TXGBE_RX_EQ_CTL4_CONT_ADAPT0;
  83. txgbe_write_pma(xpcs, TXGBE_RX_EQ_CTL4, val);
  84. }
  85. static void txgbe_pma_config_1g(struct dw_xpcs *xpcs)
  86. {
  87. int val;
  88. val = txgbe_read_pma(xpcs, TXGBE_TX_GENCTL1);
  89. val = u16_replace_bits(val, 0x5, TXGBE_TX_GENCTL1_VBOOST_LVL);
  90. val &= ~TXGBE_TX_GENCTL1_VBOOST_EN0;
  91. txgbe_write_pma(xpcs, TXGBE_TX_GENCTL1, val);
  92. txgbe_write_pma(xpcs, TXGBE_MISC_CTL0, TXGBE_MISC_CTL0_PLL |
  93. TXGBE_MISC_CTL0_CR_PARA_SEL | TXGBE_MISC_CTL0_RX_VREF(0xF));
  94. txgbe_write_pma(xpcs, TXGBE_RX_EQ_CTL0, TXGBE_RX_EQ_CTL0_VGA1_GAIN(7) |
  95. TXGBE_RX_EQ_CTL0_VGA2_GAIN(7) | TXGBE_RX_EQ_CTL0_CTLE_BOOST(6));
  96. val = txgbe_read_pma(xpcs, TXGBE_RX_EQ_ATTN_CTL);
  97. val &= ~TXGBE_RX_EQ_ATTN_LVL0;
  98. txgbe_write_pma(xpcs, TXGBE_RX_EQ_ATTN_CTL, val);
  99. txgbe_write_pma(xpcs, TXGBE_DFE_TAP_CTL0, 0);
  100. val = txgbe_read_pma(xpcs, TXGBE_RX_GEN_CTL3);
  101. val = u16_replace_bits(val, 0x4, TXGBE_RX_GEN_CTL3_LOS_TRSHLD0);
  102. txgbe_write_pma(xpcs, TXGBE_RX_GEN_CTL3, val);
  103. txgbe_write_pma(xpcs, TXGBE_MPLLA_CTL0, 0x20);
  104. txgbe_write_pma(xpcs, TXGBE_MPLLA_CTL3, 0x46);
  105. txgbe_write_pma(xpcs, TXGBE_VCO_CAL_LD0, 0x540);
  106. txgbe_write_pma(xpcs, TXGBE_VCO_CAL_REF0, 0x2A);
  107. txgbe_write_pma(xpcs, TXGBE_AFE_DFE_ENABLE, 0);
  108. txgbe_write_pma(xpcs, TXGBE_RX_EQ_CTL4, TXGBE_RX_EQ_CTL4_CONT_OFF_CAN0);
  109. txgbe_write_pma(xpcs, TXGBE_TX_RATE_CTL, TXGBE_TX_RATE_CTL_TX0_RATE(3));
  110. txgbe_write_pma(xpcs, TXGBE_RX_RATE_CTL, TXGBE_RX_RATE_CTL_RX0_RATE(3));
  111. txgbe_write_pma(xpcs, TXGBE_TX_GEN_CTL2, TXGBE_TX_GEN_CTL2_TX0_WIDTH(1));
  112. txgbe_write_pma(xpcs, TXGBE_RX_GEN_CTL2, TXGBE_RX_GEN_CTL2_RX0_WIDTH(1));
  113. txgbe_write_pma(xpcs, TXGBE_MPLLA_CTL2, TXGBE_MPLLA_CTL2_DIV10_CLK_EN);
  114. }
  115. static int txgbe_pcs_poll_power_up(struct dw_xpcs *xpcs)
  116. {
  117. int val, ret;
  118. /* Wait xpcs power-up good */
  119. ret = read_poll_timeout(xpcs_read_vpcs, val,
  120. (val & DW_PSEQ_ST) == DW_PSEQ_ST_GOOD,
  121. 10000, 1000000, false,
  122. xpcs, DW_VR_XS_PCS_DIG_STS);
  123. if (ret < 0)
  124. dev_err(&xpcs->mdiodev->dev, "xpcs power-up timeout\n");
  125. return ret;
  126. }
  127. static int txgbe_pma_init_done(struct dw_xpcs *xpcs)
  128. {
  129. int val, ret;
  130. xpcs_write_vpcs(xpcs, DW_VR_XS_PCS_DIG_CTRL1, DW_VR_RST | DW_EN_VSMMD1);
  131. /* wait pma initialization done */
  132. ret = read_poll_timeout(xpcs_read_vpcs, val, !(val & DW_VR_RST),
  133. 100000, 10000000, false,
  134. xpcs, DW_VR_XS_PCS_DIG_CTRL1);
  135. if (ret < 0)
  136. dev_err(&xpcs->mdiodev->dev, "xpcs pma initialization timeout\n");
  137. return ret;
  138. }
  139. static bool txgbe_xpcs_mode_quirk(struct dw_xpcs *xpcs)
  140. {
  141. int ret;
  142. /* When txgbe do LAN reset, PCS will change to default 10GBASE-R mode */
  143. ret = xpcs_read(xpcs, MDIO_MMD_PCS, MDIO_CTRL2);
  144. ret &= MDIO_PCS_CTRL2_TYPE;
  145. if ((ret == MDIO_PCS_CTRL2_10GBR &&
  146. xpcs->interface != PHY_INTERFACE_MODE_10GBASER) ||
  147. xpcs->interface == PHY_INTERFACE_MODE_SGMII)
  148. return true;
  149. return false;
  150. }
  151. int txgbe_xpcs_switch_mode(struct dw_xpcs *xpcs, phy_interface_t interface)
  152. {
  153. int val, ret;
  154. switch (interface) {
  155. case PHY_INTERFACE_MODE_10GBASER:
  156. case PHY_INTERFACE_MODE_SGMII:
  157. case PHY_INTERFACE_MODE_1000BASEX:
  158. break;
  159. default:
  160. return 0;
  161. }
  162. if (xpcs->interface == interface && !txgbe_xpcs_mode_quirk(xpcs))
  163. return 0;
  164. xpcs->interface = interface;
  165. ret = txgbe_pcs_poll_power_up(xpcs);
  166. if (ret < 0)
  167. return ret;
  168. if (interface == PHY_INTERFACE_MODE_10GBASER) {
  169. xpcs_write(xpcs, MDIO_MMD_PCS, MDIO_CTRL2, MDIO_PCS_CTRL2_10GBR);
  170. val = xpcs_read(xpcs, MDIO_MMD_PMAPMD, MDIO_CTRL1);
  171. val |= MDIO_CTRL1_SPEED10G;
  172. xpcs_write(xpcs, MDIO_MMD_PMAPMD, MDIO_CTRL1, val);
  173. txgbe_pma_config_10gbaser(xpcs);
  174. } else {
  175. xpcs_write(xpcs, MDIO_MMD_PCS, MDIO_CTRL2, MDIO_PCS_CTRL2_10GBX);
  176. xpcs_write(xpcs, MDIO_MMD_PMAPMD, MDIO_CTRL1, 0);
  177. xpcs_write(xpcs, MDIO_MMD_PCS, MDIO_CTRL1, 0);
  178. txgbe_pma_config_1g(xpcs);
  179. }
  180. return txgbe_pma_init_done(xpcs);
  181. }