phy-mt65xx-usb3.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635
  1. /*
  2. * Copyright (c) 2015 MediaTek Inc.
  3. * Author: Chunfeng Yun <chunfeng.yun@mediatek.com>
  4. *
  5. * This software is licensed under the terms of the GNU General Public
  6. * License version 2, as published by the Free Software Foundation, and
  7. * may be copied, distributed, and modified under those terms.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. */
  15. #include <dt-bindings/phy/phy.h>
  16. #include <linux/clk.h>
  17. #include <linux/delay.h>
  18. #include <linux/io.h>
  19. #include <linux/iopoll.h>
  20. #include <linux/module.h>
  21. #include <linux/of_address.h>
  22. #include <linux/phy/phy.h>
  23. #include <linux/platform_device.h>
  24. /*
  25. * for sifslv2 register, but exclude port's;
  26. * relative to USB3_SIF2_BASE base address
  27. */
  28. #define SSUSB_SIFSLV_SPLLC 0x0000
  29. #define SSUSB_SIFSLV_U2FREQ 0x0100
  30. /* offsets of sub-segment in each port registers */
  31. #define SSUSB_SIFSLV_U2PHY_COM_BASE 0x0000
  32. #define SSUSB_SIFSLV_U3PHYD_BASE 0x0100
  33. #define SSUSB_USB30_PHYA_SIV_B_BASE 0x0300
  34. #define SSUSB_SIFSLV_U3PHYA_DA_BASE 0x0400
  35. #define U3P_USBPHYACR0 (SSUSB_SIFSLV_U2PHY_COM_BASE + 0x0000)
  36. #define PA0_RG_U2PLL_FORCE_ON BIT(15)
  37. #define U3P_USBPHYACR2 (SSUSB_SIFSLV_U2PHY_COM_BASE + 0x0008)
  38. #define PA2_RG_SIF_U2PLL_FORCE_EN BIT(18)
  39. #define U3P_USBPHYACR5 (SSUSB_SIFSLV_U2PHY_COM_BASE + 0x0014)
  40. #define PA5_RG_U2_HSTX_SRCAL_EN BIT(15)
  41. #define PA5_RG_U2_HSTX_SRCTRL GENMASK(14, 12)
  42. #define PA5_RG_U2_HSTX_SRCTRL_VAL(x) ((0x7 & (x)) << 12)
  43. #define PA5_RG_U2_HS_100U_U3_EN BIT(11)
  44. #define U3P_USBPHYACR6 (SSUSB_SIFSLV_U2PHY_COM_BASE + 0x0018)
  45. #define PA6_RG_U2_ISO_EN BIT(31)
  46. #define PA6_RG_U2_BC11_SW_EN BIT(23)
  47. #define PA6_RG_U2_OTG_VBUSCMP_EN BIT(20)
  48. #define PA6_RG_U2_SQTH GENMASK(3, 0)
  49. #define PA6_RG_U2_SQTH_VAL(x) (0xf & (x))
  50. #define U3P_U2PHYACR4 (SSUSB_SIFSLV_U2PHY_COM_BASE + 0x0020)
  51. #define P2C_RG_USB20_GPIO_CTL BIT(9)
  52. #define P2C_USB20_GPIO_MODE BIT(8)
  53. #define P2C_U2_GPIO_CTR_MSK (P2C_RG_USB20_GPIO_CTL | P2C_USB20_GPIO_MODE)
  54. #define U3D_U2PHYDCR0 (SSUSB_SIFSLV_U2PHY_COM_BASE + 0x0060)
  55. #define P2C_RG_SIF_U2PLL_FORCE_ON BIT(24)
  56. #define U3P_U2PHYDTM0 (SSUSB_SIFSLV_U2PHY_COM_BASE + 0x0068)
  57. #define P2C_FORCE_UART_EN BIT(26)
  58. #define P2C_FORCE_DATAIN BIT(23)
  59. #define P2C_FORCE_DM_PULLDOWN BIT(21)
  60. #define P2C_FORCE_DP_PULLDOWN BIT(20)
  61. #define P2C_FORCE_XCVRSEL BIT(19)
  62. #define P2C_FORCE_SUSPENDM BIT(18)
  63. #define P2C_FORCE_TERMSEL BIT(17)
  64. #define P2C_RG_DATAIN GENMASK(13, 10)
  65. #define P2C_RG_DATAIN_VAL(x) ((0xf & (x)) << 10)
  66. #define P2C_RG_DMPULLDOWN BIT(7)
  67. #define P2C_RG_DPPULLDOWN BIT(6)
  68. #define P2C_RG_XCVRSEL GENMASK(5, 4)
  69. #define P2C_RG_XCVRSEL_VAL(x) ((0x3 & (x)) << 4)
  70. #define P2C_RG_SUSPENDM BIT(3)
  71. #define P2C_RG_TERMSEL BIT(2)
  72. #define P2C_DTM0_PART_MASK \
  73. (P2C_FORCE_DATAIN | P2C_FORCE_DM_PULLDOWN | \
  74. P2C_FORCE_DP_PULLDOWN | P2C_FORCE_XCVRSEL | \
  75. P2C_FORCE_TERMSEL | P2C_RG_DMPULLDOWN | \
  76. P2C_RG_DPPULLDOWN | P2C_RG_TERMSEL)
  77. #define U3P_U2PHYDTM1 (SSUSB_SIFSLV_U2PHY_COM_BASE + 0x006C)
  78. #define P2C_RG_UART_EN BIT(16)
  79. #define P2C_RG_VBUSVALID BIT(5)
  80. #define P2C_RG_SESSEND BIT(4)
  81. #define P2C_RG_AVALID BIT(2)
  82. #define U3P_U3_PHYA_REG0 (SSUSB_USB30_PHYA_SIV_B_BASE + 0x0000)
  83. #define P3A_RG_U3_VUSB10_ON BIT(5)
  84. #define U3P_U3_PHYA_REG6 (SSUSB_USB30_PHYA_SIV_B_BASE + 0x0018)
  85. #define P3A_RG_TX_EIDLE_CM GENMASK(31, 28)
  86. #define P3A_RG_TX_EIDLE_CM_VAL(x) ((0xf & (x)) << 28)
  87. #define U3P_U3_PHYA_REG9 (SSUSB_USB30_PHYA_SIV_B_BASE + 0x0024)
  88. #define P3A_RG_RX_DAC_MUX GENMASK(5, 1)
  89. #define P3A_RG_RX_DAC_MUX_VAL(x) ((0x1f & (x)) << 1)
  90. #define U3P_U3PHYA_DA_REG0 (SSUSB_SIFSLV_U3PHYA_DA_BASE + 0x0000)
  91. #define P3A_RG_XTAL_EXT_EN_U3 GENMASK(11, 10)
  92. #define P3A_RG_XTAL_EXT_EN_U3_VAL(x) ((0x3 & (x)) << 10)
  93. #define U3P_PHYD_CDR1 (SSUSB_SIFSLV_U3PHYD_BASE + 0x005c)
  94. #define P3D_RG_CDR_BIR_LTD1 GENMASK(28, 24)
  95. #define P3D_RG_CDR_BIR_LTD1_VAL(x) ((0x1f & (x)) << 24)
  96. #define P3D_RG_CDR_BIR_LTD0 GENMASK(12, 8)
  97. #define P3D_RG_CDR_BIR_LTD0_VAL(x) ((0x1f & (x)) << 8)
  98. #define U3P_XTALCTL3 (SSUSB_SIFSLV_SPLLC + 0x0018)
  99. #define XC3_RG_U3_XTAL_RX_PWD BIT(9)
  100. #define XC3_RG_U3_FRC_XTAL_RX_PWD BIT(8)
  101. #define U3P_U2FREQ_FMCR0 (SSUSB_SIFSLV_U2FREQ + 0x00)
  102. #define P2F_RG_MONCLK_SEL GENMASK(27, 26)
  103. #define P2F_RG_MONCLK_SEL_VAL(x) ((0x3 & (x)) << 26)
  104. #define P2F_RG_FREQDET_EN BIT(24)
  105. #define P2F_RG_CYCLECNT GENMASK(23, 0)
  106. #define P2F_RG_CYCLECNT_VAL(x) ((P2F_RG_CYCLECNT) & (x))
  107. #define U3P_U2FREQ_VALUE (SSUSB_SIFSLV_U2FREQ + 0x0c)
  108. #define U3P_U2FREQ_FMMONR1 (SSUSB_SIFSLV_U2FREQ + 0x10)
  109. #define P2F_USB_FM_VALID BIT(0)
  110. #define P2F_RG_FRCK_EN BIT(8)
  111. #define U3P_REF_CLK 26 /* MHZ */
  112. #define U3P_SLEW_RATE_COEF 28
  113. #define U3P_SR_COEF_DIVISOR 1000
  114. #define U3P_FM_DET_CYCLE_CNT 1024
  115. struct mt65xx_phy_pdata {
  116. /* avoid RX sensitivity level degradation only for mt8173 */
  117. bool avoid_rx_sen_degradation;
  118. };
  119. struct mt65xx_phy_instance {
  120. struct phy *phy;
  121. void __iomem *port_base;
  122. u32 index;
  123. u8 type;
  124. };
  125. struct mt65xx_u3phy {
  126. struct device *dev;
  127. void __iomem *sif_base; /* include sif2, but exclude port's */
  128. struct clk *u3phya_ref; /* reference clock of usb3 anolog phy */
  129. const struct mt65xx_phy_pdata *pdata;
  130. struct mt65xx_phy_instance **phys;
  131. int nphys;
  132. };
  133. static void hs_slew_rate_calibrate(struct mt65xx_u3phy *u3phy,
  134. struct mt65xx_phy_instance *instance)
  135. {
  136. void __iomem *sif_base = u3phy->sif_base;
  137. int calibration_val;
  138. int fm_out;
  139. u32 tmp;
  140. /* enable USB ring oscillator */
  141. tmp = readl(instance->port_base + U3P_USBPHYACR5);
  142. tmp |= PA5_RG_U2_HSTX_SRCAL_EN;
  143. writel(tmp, instance->port_base + U3P_USBPHYACR5);
  144. udelay(1);
  145. /*enable free run clock */
  146. tmp = readl(sif_base + U3P_U2FREQ_FMMONR1);
  147. tmp |= P2F_RG_FRCK_EN;
  148. writel(tmp, sif_base + U3P_U2FREQ_FMMONR1);
  149. /* set cycle count as 1024, and select u2 channel */
  150. tmp = readl(sif_base + U3P_U2FREQ_FMCR0);
  151. tmp &= ~(P2F_RG_CYCLECNT | P2F_RG_MONCLK_SEL);
  152. tmp |= P2F_RG_CYCLECNT_VAL(U3P_FM_DET_CYCLE_CNT);
  153. tmp |= P2F_RG_MONCLK_SEL_VAL(instance->index);
  154. writel(tmp, sif_base + U3P_U2FREQ_FMCR0);
  155. /* enable frequency meter */
  156. tmp = readl(sif_base + U3P_U2FREQ_FMCR0);
  157. tmp |= P2F_RG_FREQDET_EN;
  158. writel(tmp, sif_base + U3P_U2FREQ_FMCR0);
  159. /* ignore return value */
  160. readl_poll_timeout(sif_base + U3P_U2FREQ_FMMONR1, tmp,
  161. (tmp & P2F_USB_FM_VALID), 10, 200);
  162. fm_out = readl(sif_base + U3P_U2FREQ_VALUE);
  163. /* disable frequency meter */
  164. tmp = readl(sif_base + U3P_U2FREQ_FMCR0);
  165. tmp &= ~P2F_RG_FREQDET_EN;
  166. writel(tmp, sif_base + U3P_U2FREQ_FMCR0);
  167. /*disable free run clock */
  168. tmp = readl(sif_base + U3P_U2FREQ_FMMONR1);
  169. tmp &= ~P2F_RG_FRCK_EN;
  170. writel(tmp, sif_base + U3P_U2FREQ_FMMONR1);
  171. if (fm_out) {
  172. /* ( 1024 / FM_OUT ) x reference clock frequency x 0.028 */
  173. tmp = U3P_FM_DET_CYCLE_CNT * U3P_REF_CLK * U3P_SLEW_RATE_COEF;
  174. tmp /= fm_out;
  175. calibration_val = DIV_ROUND_CLOSEST(tmp, U3P_SR_COEF_DIVISOR);
  176. } else {
  177. /* if FM detection fail, set default value */
  178. calibration_val = 4;
  179. }
  180. dev_dbg(u3phy->dev, "phy:%d, fm_out:%d, calib:%d\n",
  181. instance->index, fm_out, calibration_val);
  182. /* set HS slew rate */
  183. tmp = readl(instance->port_base + U3P_USBPHYACR5);
  184. tmp &= ~PA5_RG_U2_HSTX_SRCTRL;
  185. tmp |= PA5_RG_U2_HSTX_SRCTRL_VAL(calibration_val);
  186. writel(tmp, instance->port_base + U3P_USBPHYACR5);
  187. /* disable USB ring oscillator */
  188. tmp = readl(instance->port_base + U3P_USBPHYACR5);
  189. tmp &= ~PA5_RG_U2_HSTX_SRCAL_EN;
  190. writel(tmp, instance->port_base + U3P_USBPHYACR5);
  191. }
  192. static void phy_instance_init(struct mt65xx_u3phy *u3phy,
  193. struct mt65xx_phy_instance *instance)
  194. {
  195. void __iomem *port_base = instance->port_base;
  196. u32 index = instance->index;
  197. u32 tmp;
  198. /* switch to USB function. (system register, force ip into usb mode) */
  199. tmp = readl(port_base + U3P_U2PHYDTM0);
  200. tmp &= ~P2C_FORCE_UART_EN;
  201. tmp |= P2C_RG_XCVRSEL_VAL(1) | P2C_RG_DATAIN_VAL(0);
  202. writel(tmp, port_base + U3P_U2PHYDTM0);
  203. tmp = readl(port_base + U3P_U2PHYDTM1);
  204. tmp &= ~P2C_RG_UART_EN;
  205. writel(tmp, port_base + U3P_U2PHYDTM1);
  206. if (!index) {
  207. tmp = readl(port_base + U3P_U2PHYACR4);
  208. tmp &= ~P2C_U2_GPIO_CTR_MSK;
  209. writel(tmp, port_base + U3P_U2PHYACR4);
  210. }
  211. if (u3phy->pdata->avoid_rx_sen_degradation) {
  212. if (!index) {
  213. tmp = readl(port_base + U3P_USBPHYACR2);
  214. tmp |= PA2_RG_SIF_U2PLL_FORCE_EN;
  215. writel(tmp, port_base + U3P_USBPHYACR2);
  216. tmp = readl(port_base + U3D_U2PHYDCR0);
  217. tmp &= ~P2C_RG_SIF_U2PLL_FORCE_ON;
  218. writel(tmp, port_base + U3D_U2PHYDCR0);
  219. } else {
  220. tmp = readl(port_base + U3D_U2PHYDCR0);
  221. tmp |= P2C_RG_SIF_U2PLL_FORCE_ON;
  222. writel(tmp, port_base + U3D_U2PHYDCR0);
  223. tmp = readl(port_base + U3P_U2PHYDTM0);
  224. tmp |= P2C_RG_SUSPENDM | P2C_FORCE_SUSPENDM;
  225. writel(tmp, port_base + U3P_U2PHYDTM0);
  226. }
  227. }
  228. tmp = readl(port_base + U3P_USBPHYACR6);
  229. tmp &= ~PA6_RG_U2_BC11_SW_EN; /* DP/DM BC1.1 path Disable */
  230. tmp &= ~PA6_RG_U2_SQTH;
  231. tmp |= PA6_RG_U2_SQTH_VAL(2);
  232. writel(tmp, port_base + U3P_USBPHYACR6);
  233. tmp = readl(port_base + U3P_U3PHYA_DA_REG0);
  234. tmp &= ~P3A_RG_XTAL_EXT_EN_U3;
  235. tmp |= P3A_RG_XTAL_EXT_EN_U3_VAL(2);
  236. writel(tmp, port_base + U3P_U3PHYA_DA_REG0);
  237. tmp = readl(port_base + U3P_U3_PHYA_REG9);
  238. tmp &= ~P3A_RG_RX_DAC_MUX;
  239. tmp |= P3A_RG_RX_DAC_MUX_VAL(4);
  240. writel(tmp, port_base + U3P_U3_PHYA_REG9);
  241. tmp = readl(port_base + U3P_U3_PHYA_REG6);
  242. tmp &= ~P3A_RG_TX_EIDLE_CM;
  243. tmp |= P3A_RG_TX_EIDLE_CM_VAL(0xe);
  244. writel(tmp, port_base + U3P_U3_PHYA_REG6);
  245. tmp = readl(port_base + U3P_PHYD_CDR1);
  246. tmp &= ~(P3D_RG_CDR_BIR_LTD0 | P3D_RG_CDR_BIR_LTD1);
  247. tmp |= P3D_RG_CDR_BIR_LTD0_VAL(0xc) | P3D_RG_CDR_BIR_LTD1_VAL(0x3);
  248. writel(tmp, port_base + U3P_PHYD_CDR1);
  249. dev_dbg(u3phy->dev, "%s(%d)\n", __func__, index);
  250. }
  251. static void phy_instance_power_on(struct mt65xx_u3phy *u3phy,
  252. struct mt65xx_phy_instance *instance)
  253. {
  254. void __iomem *port_base = instance->port_base;
  255. u32 index = instance->index;
  256. u32 tmp;
  257. if (!index) {
  258. /* Set RG_SSUSB_VUSB10_ON as 1 after VUSB10 ready */
  259. tmp = readl(port_base + U3P_U3_PHYA_REG0);
  260. tmp |= P3A_RG_U3_VUSB10_ON;
  261. writel(tmp, port_base + U3P_U3_PHYA_REG0);
  262. }
  263. /* (force_suspendm=0) (let suspendm=1, enable usb 480MHz pll) */
  264. tmp = readl(port_base + U3P_U2PHYDTM0);
  265. tmp &= ~(P2C_FORCE_SUSPENDM | P2C_RG_XCVRSEL);
  266. tmp &= ~(P2C_RG_DATAIN | P2C_DTM0_PART_MASK);
  267. writel(tmp, port_base + U3P_U2PHYDTM0);
  268. /* OTG Enable */
  269. tmp = readl(port_base + U3P_USBPHYACR6);
  270. tmp |= PA6_RG_U2_OTG_VBUSCMP_EN;
  271. writel(tmp, port_base + U3P_USBPHYACR6);
  272. if (!index) {
  273. tmp = readl(u3phy->sif_base + U3P_XTALCTL3);
  274. tmp |= XC3_RG_U3_XTAL_RX_PWD | XC3_RG_U3_FRC_XTAL_RX_PWD;
  275. writel(tmp, u3phy->sif_base + U3P_XTALCTL3);
  276. /* switch 100uA current to SSUSB */
  277. tmp = readl(port_base + U3P_USBPHYACR5);
  278. tmp |= PA5_RG_U2_HS_100U_U3_EN;
  279. writel(tmp, port_base + U3P_USBPHYACR5);
  280. }
  281. tmp = readl(port_base + U3P_U2PHYDTM1);
  282. tmp |= P2C_RG_VBUSVALID | P2C_RG_AVALID;
  283. tmp &= ~P2C_RG_SESSEND;
  284. writel(tmp, port_base + U3P_U2PHYDTM1);
  285. /* USB 2.0 slew rate calibration */
  286. tmp = readl(port_base + U3P_USBPHYACR5);
  287. tmp &= ~PA5_RG_U2_HSTX_SRCTRL;
  288. tmp |= PA5_RG_U2_HSTX_SRCTRL_VAL(4);
  289. writel(tmp, port_base + U3P_USBPHYACR5);
  290. if (u3phy->pdata->avoid_rx_sen_degradation && index) {
  291. tmp = readl(port_base + U3D_U2PHYDCR0);
  292. tmp |= P2C_RG_SIF_U2PLL_FORCE_ON;
  293. writel(tmp, port_base + U3D_U2PHYDCR0);
  294. tmp = readl(port_base + U3P_U2PHYDTM0);
  295. tmp |= P2C_RG_SUSPENDM | P2C_FORCE_SUSPENDM;
  296. writel(tmp, port_base + U3P_U2PHYDTM0);
  297. }
  298. dev_dbg(u3phy->dev, "%s(%d)\n", __func__, index);
  299. }
  300. static void phy_instance_power_off(struct mt65xx_u3phy *u3phy,
  301. struct mt65xx_phy_instance *instance)
  302. {
  303. void __iomem *port_base = instance->port_base;
  304. u32 index = instance->index;
  305. u32 tmp;
  306. tmp = readl(port_base + U3P_U2PHYDTM0);
  307. tmp &= ~(P2C_RG_XCVRSEL | P2C_RG_DATAIN);
  308. tmp |= P2C_FORCE_SUSPENDM;
  309. writel(tmp, port_base + U3P_U2PHYDTM0);
  310. /* OTG Disable */
  311. tmp = readl(port_base + U3P_USBPHYACR6);
  312. tmp &= ~PA6_RG_U2_OTG_VBUSCMP_EN;
  313. writel(tmp, port_base + U3P_USBPHYACR6);
  314. if (!index) {
  315. /* switch 100uA current back to USB2.0 */
  316. tmp = readl(port_base + U3P_USBPHYACR5);
  317. tmp &= ~PA5_RG_U2_HS_100U_U3_EN;
  318. writel(tmp, port_base + U3P_USBPHYACR5);
  319. }
  320. /* let suspendm=0, set utmi into analog power down */
  321. tmp = readl(port_base + U3P_U2PHYDTM0);
  322. tmp &= ~P2C_RG_SUSPENDM;
  323. writel(tmp, port_base + U3P_U2PHYDTM0);
  324. udelay(1);
  325. tmp = readl(port_base + U3P_U2PHYDTM1);
  326. tmp &= ~(P2C_RG_VBUSVALID | P2C_RG_AVALID);
  327. tmp |= P2C_RG_SESSEND;
  328. writel(tmp, port_base + U3P_U2PHYDTM1);
  329. if (!index) {
  330. tmp = readl(port_base + U3P_U3_PHYA_REG0);
  331. tmp &= ~P3A_RG_U3_VUSB10_ON;
  332. writel(tmp, port_base + U3P_U3_PHYA_REG0);
  333. }
  334. if (u3phy->pdata->avoid_rx_sen_degradation && index) {
  335. tmp = readl(port_base + U3D_U2PHYDCR0);
  336. tmp &= ~P2C_RG_SIF_U2PLL_FORCE_ON;
  337. writel(tmp, port_base + U3D_U2PHYDCR0);
  338. }
  339. dev_dbg(u3phy->dev, "%s(%d)\n", __func__, index);
  340. }
  341. static void phy_instance_exit(struct mt65xx_u3phy *u3phy,
  342. struct mt65xx_phy_instance *instance)
  343. {
  344. void __iomem *port_base = instance->port_base;
  345. u32 index = instance->index;
  346. u32 tmp;
  347. if (u3phy->pdata->avoid_rx_sen_degradation && index) {
  348. tmp = readl(port_base + U3D_U2PHYDCR0);
  349. tmp &= ~P2C_RG_SIF_U2PLL_FORCE_ON;
  350. writel(tmp, port_base + U3D_U2PHYDCR0);
  351. tmp = readl(port_base + U3P_U2PHYDTM0);
  352. tmp &= ~P2C_FORCE_SUSPENDM;
  353. writel(tmp, port_base + U3P_U2PHYDTM0);
  354. }
  355. }
  356. static int mt65xx_phy_init(struct phy *phy)
  357. {
  358. struct mt65xx_phy_instance *instance = phy_get_drvdata(phy);
  359. struct mt65xx_u3phy *u3phy = dev_get_drvdata(phy->dev.parent);
  360. int ret;
  361. ret = clk_prepare_enable(u3phy->u3phya_ref);
  362. if (ret) {
  363. dev_err(u3phy->dev, "failed to enable u3phya_ref\n");
  364. return ret;
  365. }
  366. phy_instance_init(u3phy, instance);
  367. return 0;
  368. }
  369. static int mt65xx_phy_power_on(struct phy *phy)
  370. {
  371. struct mt65xx_phy_instance *instance = phy_get_drvdata(phy);
  372. struct mt65xx_u3phy *u3phy = dev_get_drvdata(phy->dev.parent);
  373. phy_instance_power_on(u3phy, instance);
  374. hs_slew_rate_calibrate(u3phy, instance);
  375. return 0;
  376. }
  377. static int mt65xx_phy_power_off(struct phy *phy)
  378. {
  379. struct mt65xx_phy_instance *instance = phy_get_drvdata(phy);
  380. struct mt65xx_u3phy *u3phy = dev_get_drvdata(phy->dev.parent);
  381. phy_instance_power_off(u3phy, instance);
  382. return 0;
  383. }
  384. static int mt65xx_phy_exit(struct phy *phy)
  385. {
  386. struct mt65xx_phy_instance *instance = phy_get_drvdata(phy);
  387. struct mt65xx_u3phy *u3phy = dev_get_drvdata(phy->dev.parent);
  388. phy_instance_exit(u3phy, instance);
  389. clk_disable_unprepare(u3phy->u3phya_ref);
  390. return 0;
  391. }
  392. static struct phy *mt65xx_phy_xlate(struct device *dev,
  393. struct of_phandle_args *args)
  394. {
  395. struct mt65xx_u3phy *u3phy = dev_get_drvdata(dev);
  396. struct mt65xx_phy_instance *instance = NULL;
  397. struct device_node *phy_np = args->np;
  398. int index;
  399. if (args->args_count != 1) {
  400. dev_err(dev, "invalid number of cells in 'phy' property\n");
  401. return ERR_PTR(-EINVAL);
  402. }
  403. for (index = 0; index < u3phy->nphys; index++)
  404. if (phy_np == u3phy->phys[index]->phy->dev.of_node) {
  405. instance = u3phy->phys[index];
  406. break;
  407. }
  408. if (!instance) {
  409. dev_err(dev, "failed to find appropriate phy\n");
  410. return ERR_PTR(-EINVAL);
  411. }
  412. instance->type = args->args[0];
  413. if (!(instance->type == PHY_TYPE_USB2 ||
  414. instance->type == PHY_TYPE_USB3)) {
  415. dev_err(dev, "unsupported device type: %d\n", instance->type);
  416. return ERR_PTR(-EINVAL);
  417. }
  418. return instance->phy;
  419. }
  420. static struct phy_ops mt65xx_u3phy_ops = {
  421. .init = mt65xx_phy_init,
  422. .exit = mt65xx_phy_exit,
  423. .power_on = mt65xx_phy_power_on,
  424. .power_off = mt65xx_phy_power_off,
  425. .owner = THIS_MODULE,
  426. };
  427. static const struct mt65xx_phy_pdata mt2701_pdata = {
  428. .avoid_rx_sen_degradation = false,
  429. };
  430. static const struct mt65xx_phy_pdata mt8173_pdata = {
  431. .avoid_rx_sen_degradation = true,
  432. };
  433. static const struct of_device_id mt65xx_u3phy_id_table[] = {
  434. { .compatible = "mediatek,mt2701-u3phy", .data = &mt2701_pdata },
  435. { .compatible = "mediatek,mt8173-u3phy", .data = &mt8173_pdata },
  436. { },
  437. };
  438. MODULE_DEVICE_TABLE(of, mt65xx_u3phy_id_table);
  439. static int mt65xx_u3phy_probe(struct platform_device *pdev)
  440. {
  441. const struct of_device_id *match;
  442. struct device *dev = &pdev->dev;
  443. struct device_node *np = dev->of_node;
  444. struct device_node *child_np;
  445. struct phy_provider *provider;
  446. struct resource *sif_res;
  447. struct mt65xx_u3phy *u3phy;
  448. struct resource res;
  449. int port, retval;
  450. match = of_match_node(mt65xx_u3phy_id_table, pdev->dev.of_node);
  451. if (!match)
  452. return -EINVAL;
  453. u3phy = devm_kzalloc(dev, sizeof(*u3phy), GFP_KERNEL);
  454. if (!u3phy)
  455. return -ENOMEM;
  456. u3phy->pdata = match->data;
  457. u3phy->nphys = of_get_child_count(np);
  458. u3phy->phys = devm_kcalloc(dev, u3phy->nphys,
  459. sizeof(*u3phy->phys), GFP_KERNEL);
  460. if (!u3phy->phys)
  461. return -ENOMEM;
  462. u3phy->dev = dev;
  463. platform_set_drvdata(pdev, u3phy);
  464. sif_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  465. u3phy->sif_base = devm_ioremap_resource(dev, sif_res);
  466. if (IS_ERR(u3phy->sif_base)) {
  467. dev_err(dev, "failed to remap sif regs\n");
  468. return PTR_ERR(u3phy->sif_base);
  469. }
  470. u3phy->u3phya_ref = devm_clk_get(dev, "u3phya_ref");
  471. if (IS_ERR(u3phy->u3phya_ref)) {
  472. dev_err(dev, "error to get u3phya_ref\n");
  473. return PTR_ERR(u3phy->u3phya_ref);
  474. }
  475. port = 0;
  476. for_each_child_of_node(np, child_np) {
  477. struct mt65xx_phy_instance *instance;
  478. struct phy *phy;
  479. instance = devm_kzalloc(dev, sizeof(*instance), GFP_KERNEL);
  480. if (!instance) {
  481. retval = -ENOMEM;
  482. goto put_child;
  483. }
  484. u3phy->phys[port] = instance;
  485. phy = devm_phy_create(dev, child_np, &mt65xx_u3phy_ops);
  486. if (IS_ERR(phy)) {
  487. dev_err(dev, "failed to create phy\n");
  488. retval = PTR_ERR(phy);
  489. goto put_child;
  490. }
  491. retval = of_address_to_resource(child_np, 0, &res);
  492. if (retval) {
  493. dev_err(dev, "failed to get address resource(id-%d)\n",
  494. port);
  495. goto put_child;
  496. }
  497. instance->port_base = devm_ioremap_resource(&phy->dev, &res);
  498. if (IS_ERR(instance->port_base)) {
  499. dev_err(dev, "failed to remap phy regs\n");
  500. retval = PTR_ERR(instance->port_base);
  501. goto put_child;
  502. }
  503. instance->phy = phy;
  504. instance->index = port;
  505. phy_set_drvdata(phy, instance);
  506. port++;
  507. }
  508. provider = devm_of_phy_provider_register(dev, mt65xx_phy_xlate);
  509. return PTR_ERR_OR_ZERO(provider);
  510. put_child:
  511. of_node_put(child_np);
  512. return retval;
  513. }
  514. static struct platform_driver mt65xx_u3phy_driver = {
  515. .probe = mt65xx_u3phy_probe,
  516. .driver = {
  517. .name = "mt65xx-u3phy",
  518. .of_match_table = mt65xx_u3phy_id_table,
  519. },
  520. };
  521. module_platform_driver(mt65xx_u3phy_driver);
  522. MODULE_AUTHOR("Chunfeng Yun <chunfeng.yun@mediatek.com>");
  523. MODULE_DESCRIPTION("mt65xx USB PHY driver");
  524. MODULE_LICENSE("GPL v2");