mt76x8-usb-phy.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2019 Stefan Roese <sr@denx.de>
  4. *
  5. * Derived from linux/drivers/phy/ralink/phy-ralink-usb.c
  6. * Copyright (C) 2017 John Crispin <john@phrozen.org>
  7. */
  8. #include <clk.h>
  9. #include <common.h>
  10. #include <dm.h>
  11. #include <generic-phy.h>
  12. #include <log.h>
  13. #include <reset.h>
  14. #include <asm/io.h>
  15. #include <linux/bitops.h>
  16. #include <linux/delay.h>
  17. #define OFS_U2_PHY_AC0 0x800
  18. #define USBPLL_FBDIV_S 16
  19. #define USBPLL_FBDIV_M GENMASK(22, 16)
  20. #define BG_TRIM_S 8
  21. #define BG_TRIM_M GENMASK(11, 8)
  22. #define BG_RBSEL_S 6
  23. #define BG_RBSEL_M GENMASK(7, 6)
  24. #define BG_RASEL_S 4
  25. #define BG_RASEL_M GENMASK(5, 4)
  26. #define BGR_DIV_S 2
  27. #define BGR_DIV_M GENMASK(3, 2)
  28. #define CHP_EN BIT(1)
  29. #define OFS_U2_PHY_AC1 0x804
  30. #define VRT_VREF_SEL_S 28
  31. #define VRT_VREF_SEL_M GENMASK(30, 28)
  32. #define TERM_VREF_SEL_S 24
  33. #define TERM_VREF_SEL_M GENMASK(26, 24)
  34. #define USBPLL_RSVD BIT(4)
  35. #define USBPLL_ACCEN BIT(3)
  36. #define USBPLL_LF BIT(2)
  37. #define OFS_U2_PHY_AC2 0x808
  38. #define OFS_U2_PHY_ACR0 0x810
  39. #define HSTX_SRCAL_EN BIT(23)
  40. #define HSTX_SRCTRL_S 16
  41. #define HSTX_SRCTRL_M GENMASK(18, 16)
  42. #define OFS_U2_PHY_ACR3 0x81C
  43. #define HSTX_DBIST_S 28
  44. #define HSTX_DBIST_M GENMASK(31, 28)
  45. #define HSRX_BIAS_EN_SEL_S 20
  46. #define HSRX_BIAS_EN_SEL_M GENMASK(21, 20)
  47. #define OFS_U2_PHY_DCR0 0x860
  48. #define PHYD_RESERVE_S 8
  49. #define PHYD_RESERVE_M GENMASK(23, 8)
  50. #define CDR_FILT_S 0
  51. #define CDR_FILT_M GENMASK(3, 0)
  52. #define OFS_U2_PHY_DTM0 0x868
  53. #define FORCE_USB_CLKEN BIT(25)
  54. #define OFS_FM_CR0 0xf00
  55. #define FREQDET_EN BIT(24)
  56. #define CYCLECNT_S 0
  57. #define CYCLECNT_M GENMASK(23, 0)
  58. #define OFS_FM_MONR0 0xf0c
  59. #define OFS_FM_MONR1 0xf10
  60. #define FRCK_EN BIT(8)
  61. #define U2_SR_COEF_7628 32
  62. struct mt76x8_usb_phy {
  63. void __iomem *base;
  64. struct clk cg; /* for clock gating */
  65. struct reset_ctl rst_phy;
  66. };
  67. static void phy_w32(struct mt76x8_usb_phy *phy, u32 reg, u32 val)
  68. {
  69. writel(val, phy->base + reg);
  70. }
  71. static u32 phy_r32(struct mt76x8_usb_phy *phy, u32 reg)
  72. {
  73. return readl(phy->base + reg);
  74. }
  75. static void phy_rmw32(struct mt76x8_usb_phy *phy, u32 reg, u32 clr, u32 set)
  76. {
  77. clrsetbits_32(phy->base + reg, clr, set);
  78. }
  79. static void mt76x8_usb_phy_init(struct mt76x8_usb_phy *phy)
  80. {
  81. phy_r32(phy, OFS_U2_PHY_AC2);
  82. phy_r32(phy, OFS_U2_PHY_ACR0);
  83. phy_r32(phy, OFS_U2_PHY_DCR0);
  84. phy_w32(phy, OFS_U2_PHY_DCR0,
  85. (0xffff << PHYD_RESERVE_S) | (2 << CDR_FILT_S));
  86. phy_r32(phy, OFS_U2_PHY_DCR0);
  87. phy_w32(phy, OFS_U2_PHY_DCR0,
  88. (0x5555 << PHYD_RESERVE_S) | (2 << CDR_FILT_S));
  89. phy_r32(phy, OFS_U2_PHY_DCR0);
  90. phy_w32(phy, OFS_U2_PHY_DCR0,
  91. (0xaaaa << PHYD_RESERVE_S) | (2 << CDR_FILT_S));
  92. phy_r32(phy, OFS_U2_PHY_DCR0);
  93. phy_w32(phy, OFS_U2_PHY_DCR0,
  94. (4 << PHYD_RESERVE_S) | (2 << CDR_FILT_S));
  95. phy_r32(phy, OFS_U2_PHY_DCR0);
  96. phy_w32(phy, OFS_U2_PHY_AC0,
  97. (0x48 << USBPLL_FBDIV_S) | (8 << BG_TRIM_S) |
  98. (1 << BG_RBSEL_S) | (2 << BG_RASEL_S) | (2 << BGR_DIV_S) |
  99. CHP_EN);
  100. phy_w32(phy, OFS_U2_PHY_AC1,
  101. (4 << VRT_VREF_SEL_S) | (4 << TERM_VREF_SEL_S) | USBPLL_RSVD |
  102. USBPLL_ACCEN | USBPLL_LF);
  103. phy_w32(phy, OFS_U2_PHY_ACR3,
  104. (12 << HSTX_DBIST_S) | (2 << HSRX_BIAS_EN_SEL_S));
  105. phy_w32(phy, OFS_U2_PHY_DTM0, FORCE_USB_CLKEN);
  106. }
  107. static void mt76x8_usb_phy_sr_calibrate(struct mt76x8_usb_phy *phy)
  108. {
  109. u32 fmout, tmp = 4;
  110. int i;
  111. /* Enable HS TX SR calibration */
  112. phy_rmw32(phy, OFS_U2_PHY_ACR0, 0, HSTX_SRCAL_EN);
  113. mdelay(1);
  114. /* Enable free run clock */
  115. phy_rmw32(phy, OFS_FM_MONR1, 0, FRCK_EN);
  116. /* Set cycle count = 0x400 */
  117. phy_rmw32(phy, OFS_FM_CR0, CYCLECNT_M, 0x400 << CYCLECNT_S);
  118. /* Enable frequency meter */
  119. phy_rmw32(phy, OFS_FM_CR0, 0, FREQDET_EN);
  120. /* Wait for FM detection done, set timeout to 10ms */
  121. for (i = 0; i < 10; i++) {
  122. fmout = phy_r32(phy, OFS_FM_MONR0);
  123. if (fmout)
  124. break;
  125. mdelay(1);
  126. }
  127. /* Disable frequency meter */
  128. phy_rmw32(phy, OFS_FM_CR0, FREQDET_EN, 0);
  129. /* Disable free run clock */
  130. phy_rmw32(phy, OFS_FM_MONR1, FRCK_EN, 0);
  131. /* Disable HS TX SR calibration */
  132. phy_rmw32(phy, OFS_U2_PHY_ACR0, HSTX_SRCAL_EN, 0);
  133. mdelay(1);
  134. if (fmout) {
  135. /*
  136. * set reg = (1024 / FM_OUT) * 25 * 0.028
  137. * (round to the nearest digits)
  138. */
  139. tmp = (((1024 * 25 * U2_SR_COEF_7628) / fmout) + 500) / 1000;
  140. }
  141. phy_rmw32(phy, OFS_U2_PHY_ACR0, HSTX_SRCTRL_M,
  142. (tmp << HSTX_SRCTRL_S) & HSTX_SRCTRL_M);
  143. }
  144. static int mt76x8_usb_phy_power_on(struct phy *_phy)
  145. {
  146. struct mt76x8_usb_phy *phy = dev_get_priv(_phy->dev);
  147. clk_enable(&phy->cg);
  148. reset_deassert(&phy->rst_phy);
  149. /*
  150. * The SDK kernel had a delay of 100ms. however on device
  151. * testing showed that 10ms is enough
  152. */
  153. mdelay(10);
  154. mt76x8_usb_phy_init(phy);
  155. mt76x8_usb_phy_sr_calibrate(phy);
  156. return 0;
  157. }
  158. static int mt76x8_usb_phy_power_off(struct phy *_phy)
  159. {
  160. struct mt76x8_usb_phy *phy = dev_get_priv(_phy->dev);
  161. clk_disable(&phy->cg);
  162. reset_assert(&phy->rst_phy);
  163. return 0;
  164. }
  165. static int mt76x8_usb_phy_probe(struct udevice *dev)
  166. {
  167. struct mt76x8_usb_phy *phy = dev_get_priv(dev);
  168. int ret;
  169. phy->base = dev_read_addr_ptr(dev);
  170. if (!phy->base)
  171. return -EINVAL;
  172. /* clock gate */
  173. ret = clk_get_by_name(dev, "cg", &phy->cg);
  174. if (ret)
  175. return ret;
  176. ret = reset_get_by_name(dev, "phy", &phy->rst_phy);
  177. if (ret)
  178. return ret;
  179. return 0;
  180. }
  181. static struct phy_ops mt76x8_usb_phy_ops = {
  182. .power_on = mt76x8_usb_phy_power_on,
  183. .power_off = mt76x8_usb_phy_power_off,
  184. };
  185. static const struct udevice_id mt76x8_usb_phy_ids[] = {
  186. { .compatible = "mediatek,mt7628-usbphy" },
  187. { }
  188. };
  189. U_BOOT_DRIVER(mt76x8_usb_phy) = {
  190. .name = "mt76x8_usb_phy",
  191. .id = UCLASS_PHY,
  192. .of_match = mt76x8_usb_phy_ids,
  193. .ops = &mt76x8_usb_phy_ops,
  194. .probe = mt76x8_usb_phy_probe,
  195. .priv_auto_alloc_size = sizeof(struct mt76x8_usb_phy),
  196. };