phy-mt65xx-usb3.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772
  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. /* version V1 sub-banks offset base address */
  25. /* banks shared by multiple phys */
  26. #define SSUSB_SIFSLV_V1_SPLLC 0x000 /* shared by u3 phys */
  27. #define SSUSB_SIFSLV_V1_U2FREQ 0x100 /* shared by u2 phys */
  28. /* u2 phy bank */
  29. #define SSUSB_SIFSLV_V1_U2PHY_COM 0x000
  30. /* u3 phy banks */
  31. #define SSUSB_SIFSLV_V1_U3PHYD 0x000
  32. #define SSUSB_SIFSLV_V1_U3PHYA 0x200
  33. /* version V2 sub-banks offset base address */
  34. /* u2 phy banks */
  35. #define SSUSB_SIFSLV_V2_MISC 0x000
  36. #define SSUSB_SIFSLV_V2_U2FREQ 0x100
  37. #define SSUSB_SIFSLV_V2_U2PHY_COM 0x300
  38. /* u3 phy banks */
  39. #define SSUSB_SIFSLV_V2_SPLLC 0x000
  40. #define SSUSB_SIFSLV_V2_CHIP 0x100
  41. #define SSUSB_SIFSLV_V2_U3PHYD 0x200
  42. #define SSUSB_SIFSLV_V2_U3PHYA 0x400
  43. #define U3P_USBPHYACR0 0x000
  44. #define PA0_RG_U2PLL_FORCE_ON BIT(15)
  45. #define PA0_RG_USB20_INTR_EN BIT(5)
  46. #define U3P_USBPHYACR2 0x008
  47. #define PA2_RG_SIF_U2PLL_FORCE_EN BIT(18)
  48. #define U3P_USBPHYACR5 0x014
  49. #define PA5_RG_U2_HSTX_SRCAL_EN BIT(15)
  50. #define PA5_RG_U2_HSTX_SRCTRL GENMASK(14, 12)
  51. #define PA5_RG_U2_HSTX_SRCTRL_VAL(x) ((0x7 & (x)) << 12)
  52. #define PA5_RG_U2_HS_100U_U3_EN BIT(11)
  53. #define U3P_USBPHYACR6 0x018
  54. #define PA6_RG_U2_BC11_SW_EN BIT(23)
  55. #define PA6_RG_U2_OTG_VBUSCMP_EN BIT(20)
  56. #define PA6_RG_U2_SQTH GENMASK(3, 0)
  57. #define PA6_RG_U2_SQTH_VAL(x) (0xf & (x))
  58. #define U3P_U2PHYACR4 0x020
  59. #define P2C_RG_USB20_GPIO_CTL BIT(9)
  60. #define P2C_USB20_GPIO_MODE BIT(8)
  61. #define P2C_U2_GPIO_CTR_MSK (P2C_RG_USB20_GPIO_CTL | P2C_USB20_GPIO_MODE)
  62. #define U3D_U2PHYDCR0 0x060
  63. #define P2C_RG_SIF_U2PLL_FORCE_ON BIT(24)
  64. #define U3P_U2PHYDTM0 0x068
  65. #define P2C_FORCE_UART_EN BIT(26)
  66. #define P2C_FORCE_DATAIN BIT(23)
  67. #define P2C_FORCE_DM_PULLDOWN BIT(21)
  68. #define P2C_FORCE_DP_PULLDOWN BIT(20)
  69. #define P2C_FORCE_XCVRSEL BIT(19)
  70. #define P2C_FORCE_SUSPENDM BIT(18)
  71. #define P2C_FORCE_TERMSEL BIT(17)
  72. #define P2C_RG_DATAIN GENMASK(13, 10)
  73. #define P2C_RG_DATAIN_VAL(x) ((0xf & (x)) << 10)
  74. #define P2C_RG_DMPULLDOWN BIT(7)
  75. #define P2C_RG_DPPULLDOWN BIT(6)
  76. #define P2C_RG_XCVRSEL GENMASK(5, 4)
  77. #define P2C_RG_XCVRSEL_VAL(x) ((0x3 & (x)) << 4)
  78. #define P2C_RG_SUSPENDM BIT(3)
  79. #define P2C_RG_TERMSEL BIT(2)
  80. #define P2C_DTM0_PART_MASK \
  81. (P2C_FORCE_DATAIN | P2C_FORCE_DM_PULLDOWN | \
  82. P2C_FORCE_DP_PULLDOWN | P2C_FORCE_XCVRSEL | \
  83. P2C_FORCE_TERMSEL | P2C_RG_DMPULLDOWN | \
  84. P2C_RG_DPPULLDOWN | P2C_RG_TERMSEL)
  85. #define U3P_U2PHYDTM1 0x06C
  86. #define P2C_RG_UART_EN BIT(16)
  87. #define P2C_RG_VBUSVALID BIT(5)
  88. #define P2C_RG_SESSEND BIT(4)
  89. #define P2C_RG_AVALID BIT(2)
  90. #define U3P_U3_PHYA_REG6 0x018
  91. #define P3A_RG_TX_EIDLE_CM GENMASK(31, 28)
  92. #define P3A_RG_TX_EIDLE_CM_VAL(x) ((0xf & (x)) << 28)
  93. #define U3P_U3_PHYA_REG9 0x024
  94. #define P3A_RG_RX_DAC_MUX GENMASK(5, 1)
  95. #define P3A_RG_RX_DAC_MUX_VAL(x) ((0x1f & (x)) << 1)
  96. #define U3P_U3_PHYA_DA_REG0 0x100
  97. #define P3A_RG_XTAL_EXT_EN_U3 GENMASK(11, 10)
  98. #define P3A_RG_XTAL_EXT_EN_U3_VAL(x) ((0x3 & (x)) << 10)
  99. #define U3P_U3_PHYD_LFPS1 0x00c
  100. #define P3D_RG_FWAKE_TH GENMASK(21, 16)
  101. #define P3D_RG_FWAKE_TH_VAL(x) ((0x3f & (x)) << 16)
  102. #define U3P_U3_PHYD_CDR1 0x05c
  103. #define P3D_RG_CDR_BIR_LTD1 GENMASK(28, 24)
  104. #define P3D_RG_CDR_BIR_LTD1_VAL(x) ((0x1f & (x)) << 24)
  105. #define P3D_RG_CDR_BIR_LTD0 GENMASK(12, 8)
  106. #define P3D_RG_CDR_BIR_LTD0_VAL(x) ((0x1f & (x)) << 8)
  107. #define U3P_U3_PHYD_RXDET1 0x128
  108. #define P3D_RG_RXDET_STB2_SET GENMASK(17, 9)
  109. #define P3D_RG_RXDET_STB2_SET_VAL(x) ((0x1ff & (x)) << 9)
  110. #define U3P_U3_PHYD_RXDET2 0x12c
  111. #define P3D_RG_RXDET_STB2_SET_P3 GENMASK(8, 0)
  112. #define P3D_RG_RXDET_STB2_SET_P3_VAL(x) (0x1ff & (x))
  113. #define U3P_SPLLC_XTALCTL3 0x018
  114. #define XC3_RG_U3_XTAL_RX_PWD BIT(9)
  115. #define XC3_RG_U3_FRC_XTAL_RX_PWD BIT(8)
  116. #define U3P_U2FREQ_FMCR0 0x00
  117. #define P2F_RG_MONCLK_SEL GENMASK(27, 26)
  118. #define P2F_RG_MONCLK_SEL_VAL(x) ((0x3 & (x)) << 26)
  119. #define P2F_RG_FREQDET_EN BIT(24)
  120. #define P2F_RG_CYCLECNT GENMASK(23, 0)
  121. #define P2F_RG_CYCLECNT_VAL(x) ((P2F_RG_CYCLECNT) & (x))
  122. #define U3P_U2FREQ_VALUE 0x0c
  123. #define U3P_U2FREQ_FMMONR1 0x10
  124. #define P2F_USB_FM_VALID BIT(0)
  125. #define P2F_RG_FRCK_EN BIT(8)
  126. #define U3P_REF_CLK 26 /* MHZ */
  127. #define U3P_SLEW_RATE_COEF 28
  128. #define U3P_SR_COEF_DIVISOR 1000
  129. #define U3P_FM_DET_CYCLE_CNT 1024
  130. enum mt_phy_version {
  131. MT_PHY_V1 = 1,
  132. MT_PHY_V2,
  133. };
  134. struct mt65xx_phy_pdata {
  135. /* avoid RX sensitivity level degradation only for mt8173 */
  136. bool avoid_rx_sen_degradation;
  137. enum mt_phy_version version;
  138. };
  139. struct u2phy_banks {
  140. void __iomem *misc;
  141. void __iomem *fmreg;
  142. void __iomem *com;
  143. };
  144. struct u3phy_banks {
  145. void __iomem *spllc;
  146. void __iomem *chip;
  147. void __iomem *phyd; /* include u3phyd_bank2 */
  148. void __iomem *phya; /* include u3phya_da */
  149. };
  150. struct mt65xx_phy_instance {
  151. struct phy *phy;
  152. void __iomem *port_base;
  153. union {
  154. struct u2phy_banks u2_banks;
  155. struct u3phy_banks u3_banks;
  156. };
  157. struct clk *ref_clk; /* reference clock of anolog phy */
  158. u32 index;
  159. u8 type;
  160. };
  161. struct mt65xx_u3phy {
  162. struct device *dev;
  163. void __iomem *sif_base; /* only shared sif */
  164. /* deprecated, use @ref_clk instead in phy instance */
  165. struct clk *u3phya_ref; /* reference clock of usb3 anolog phy */
  166. const struct mt65xx_phy_pdata *pdata;
  167. struct mt65xx_phy_instance **phys;
  168. int nphys;
  169. };
  170. static void hs_slew_rate_calibrate(struct mt65xx_u3phy *u3phy,
  171. struct mt65xx_phy_instance *instance)
  172. {
  173. struct u2phy_banks *u2_banks = &instance->u2_banks;
  174. void __iomem *fmreg = u2_banks->fmreg;
  175. void __iomem *com = u2_banks->com;
  176. int calibration_val;
  177. int fm_out;
  178. u32 tmp;
  179. /* enable USB ring oscillator */
  180. tmp = readl(com + U3P_USBPHYACR5);
  181. tmp |= PA5_RG_U2_HSTX_SRCAL_EN;
  182. writel(tmp, com + U3P_USBPHYACR5);
  183. udelay(1);
  184. /*enable free run clock */
  185. tmp = readl(fmreg + U3P_U2FREQ_FMMONR1);
  186. tmp |= P2F_RG_FRCK_EN;
  187. writel(tmp, fmreg + U3P_U2FREQ_FMMONR1);
  188. /* set cycle count as 1024, and select u2 channel */
  189. tmp = readl(fmreg + U3P_U2FREQ_FMCR0);
  190. tmp &= ~(P2F_RG_CYCLECNT | P2F_RG_MONCLK_SEL);
  191. tmp |= P2F_RG_CYCLECNT_VAL(U3P_FM_DET_CYCLE_CNT);
  192. if (u3phy->pdata->version == MT_PHY_V1)
  193. tmp |= P2F_RG_MONCLK_SEL_VAL(instance->index >> 1);
  194. writel(tmp, fmreg + U3P_U2FREQ_FMCR0);
  195. /* enable frequency meter */
  196. tmp = readl(fmreg + U3P_U2FREQ_FMCR0);
  197. tmp |= P2F_RG_FREQDET_EN;
  198. writel(tmp, fmreg + U3P_U2FREQ_FMCR0);
  199. /* ignore return value */
  200. readl_poll_timeout(fmreg + U3P_U2FREQ_FMMONR1, tmp,
  201. (tmp & P2F_USB_FM_VALID), 10, 200);
  202. fm_out = readl(fmreg + U3P_U2FREQ_VALUE);
  203. /* disable frequency meter */
  204. tmp = readl(fmreg + U3P_U2FREQ_FMCR0);
  205. tmp &= ~P2F_RG_FREQDET_EN;
  206. writel(tmp, fmreg + U3P_U2FREQ_FMCR0);
  207. /*disable free run clock */
  208. tmp = readl(fmreg + U3P_U2FREQ_FMMONR1);
  209. tmp &= ~P2F_RG_FRCK_EN;
  210. writel(tmp, fmreg + U3P_U2FREQ_FMMONR1);
  211. if (fm_out) {
  212. /* ( 1024 / FM_OUT ) x reference clock frequency x 0.028 */
  213. tmp = U3P_FM_DET_CYCLE_CNT * U3P_REF_CLK * U3P_SLEW_RATE_COEF;
  214. tmp /= fm_out;
  215. calibration_val = DIV_ROUND_CLOSEST(tmp, U3P_SR_COEF_DIVISOR);
  216. } else {
  217. /* if FM detection fail, set default value */
  218. calibration_val = 4;
  219. }
  220. dev_dbg(u3phy->dev, "phy:%d, fm_out:%d, calib:%d\n",
  221. instance->index, fm_out, calibration_val);
  222. /* set HS slew rate */
  223. tmp = readl(com + U3P_USBPHYACR5);
  224. tmp &= ~PA5_RG_U2_HSTX_SRCTRL;
  225. tmp |= PA5_RG_U2_HSTX_SRCTRL_VAL(calibration_val);
  226. writel(tmp, com + U3P_USBPHYACR5);
  227. /* disable USB ring oscillator */
  228. tmp = readl(com + U3P_USBPHYACR5);
  229. tmp &= ~PA5_RG_U2_HSTX_SRCAL_EN;
  230. writel(tmp, com + U3P_USBPHYACR5);
  231. }
  232. static void u3_phy_instance_init(struct mt65xx_u3phy *u3phy,
  233. struct mt65xx_phy_instance *instance)
  234. {
  235. struct u3phy_banks *u3_banks = &instance->u3_banks;
  236. u32 tmp;
  237. /* gating PCIe Analog XTAL clock */
  238. tmp = readl(u3_banks->spllc + U3P_SPLLC_XTALCTL3);
  239. tmp |= XC3_RG_U3_XTAL_RX_PWD | XC3_RG_U3_FRC_XTAL_RX_PWD;
  240. writel(tmp, u3_banks->spllc + U3P_SPLLC_XTALCTL3);
  241. /* gating XSQ */
  242. tmp = readl(u3_banks->phya + U3P_U3_PHYA_DA_REG0);
  243. tmp &= ~P3A_RG_XTAL_EXT_EN_U3;
  244. tmp |= P3A_RG_XTAL_EXT_EN_U3_VAL(2);
  245. writel(tmp, u3_banks->phya + U3P_U3_PHYA_DA_REG0);
  246. tmp = readl(u3_banks->phya + U3P_U3_PHYA_REG9);
  247. tmp &= ~P3A_RG_RX_DAC_MUX;
  248. tmp |= P3A_RG_RX_DAC_MUX_VAL(4);
  249. writel(tmp, u3_banks->phya + U3P_U3_PHYA_REG9);
  250. tmp = readl(u3_banks->phya + U3P_U3_PHYA_REG6);
  251. tmp &= ~P3A_RG_TX_EIDLE_CM;
  252. tmp |= P3A_RG_TX_EIDLE_CM_VAL(0xe);
  253. writel(tmp, u3_banks->phya + U3P_U3_PHYA_REG6);
  254. tmp = readl(u3_banks->phyd + U3P_U3_PHYD_CDR1);
  255. tmp &= ~(P3D_RG_CDR_BIR_LTD0 | P3D_RG_CDR_BIR_LTD1);
  256. tmp |= P3D_RG_CDR_BIR_LTD0_VAL(0xc) | P3D_RG_CDR_BIR_LTD1_VAL(0x3);
  257. writel(tmp, u3_banks->phyd + U3P_U3_PHYD_CDR1);
  258. tmp = readl(u3_banks->phyd + U3P_U3_PHYD_LFPS1);
  259. tmp &= ~P3D_RG_FWAKE_TH;
  260. tmp |= P3D_RG_FWAKE_TH_VAL(0x34);
  261. writel(tmp, u3_banks->phyd + U3P_U3_PHYD_LFPS1);
  262. tmp = readl(u3_banks->phyd + U3P_U3_PHYD_RXDET1);
  263. tmp &= ~P3D_RG_RXDET_STB2_SET;
  264. tmp |= P3D_RG_RXDET_STB2_SET_VAL(0x10);
  265. writel(tmp, u3_banks->phyd + U3P_U3_PHYD_RXDET1);
  266. tmp = readl(u3_banks->phyd + U3P_U3_PHYD_RXDET2);
  267. tmp &= ~P3D_RG_RXDET_STB2_SET_P3;
  268. tmp |= P3D_RG_RXDET_STB2_SET_P3_VAL(0x10);
  269. writel(tmp, u3_banks->phyd + U3P_U3_PHYD_RXDET2);
  270. dev_dbg(u3phy->dev, "%s(%d)\n", __func__, instance->index);
  271. }
  272. static void phy_instance_init(struct mt65xx_u3phy *u3phy,
  273. struct mt65xx_phy_instance *instance)
  274. {
  275. struct u2phy_banks *u2_banks = &instance->u2_banks;
  276. void __iomem *com = u2_banks->com;
  277. u32 index = instance->index;
  278. u32 tmp;
  279. /* switch to USB function. (system register, force ip into usb mode) */
  280. tmp = readl(com + U3P_U2PHYDTM0);
  281. tmp &= ~P2C_FORCE_UART_EN;
  282. tmp |= P2C_RG_XCVRSEL_VAL(1) | P2C_RG_DATAIN_VAL(0);
  283. writel(tmp, com + U3P_U2PHYDTM0);
  284. tmp = readl(com + U3P_U2PHYDTM1);
  285. tmp &= ~P2C_RG_UART_EN;
  286. writel(tmp, com + U3P_U2PHYDTM1);
  287. tmp = readl(com + U3P_USBPHYACR0);
  288. tmp |= PA0_RG_USB20_INTR_EN;
  289. writel(tmp, com + U3P_USBPHYACR0);
  290. /* disable switch 100uA current to SSUSB */
  291. tmp = readl(com + U3P_USBPHYACR5);
  292. tmp &= ~PA5_RG_U2_HS_100U_U3_EN;
  293. writel(tmp, com + U3P_USBPHYACR5);
  294. if (!index) {
  295. tmp = readl(com + U3P_U2PHYACR4);
  296. tmp &= ~P2C_U2_GPIO_CTR_MSK;
  297. writel(tmp, com + U3P_U2PHYACR4);
  298. }
  299. if (u3phy->pdata->avoid_rx_sen_degradation) {
  300. if (!index) {
  301. tmp = readl(com + U3P_USBPHYACR2);
  302. tmp |= PA2_RG_SIF_U2PLL_FORCE_EN;
  303. writel(tmp, com + U3P_USBPHYACR2);
  304. tmp = readl(com + U3D_U2PHYDCR0);
  305. tmp &= ~P2C_RG_SIF_U2PLL_FORCE_ON;
  306. writel(tmp, com + U3D_U2PHYDCR0);
  307. } else {
  308. tmp = readl(com + U3D_U2PHYDCR0);
  309. tmp |= P2C_RG_SIF_U2PLL_FORCE_ON;
  310. writel(tmp, com + U3D_U2PHYDCR0);
  311. tmp = readl(com + U3P_U2PHYDTM0);
  312. tmp |= P2C_RG_SUSPENDM | P2C_FORCE_SUSPENDM;
  313. writel(tmp, com + U3P_U2PHYDTM0);
  314. }
  315. }
  316. tmp = readl(com + U3P_USBPHYACR6);
  317. tmp &= ~PA6_RG_U2_BC11_SW_EN; /* DP/DM BC1.1 path Disable */
  318. tmp &= ~PA6_RG_U2_SQTH;
  319. tmp |= PA6_RG_U2_SQTH_VAL(2);
  320. writel(tmp, com + U3P_USBPHYACR6);
  321. dev_dbg(u3phy->dev, "%s(%d)\n", __func__, index);
  322. }
  323. static void phy_instance_power_on(struct mt65xx_u3phy *u3phy,
  324. struct mt65xx_phy_instance *instance)
  325. {
  326. struct u2phy_banks *u2_banks = &instance->u2_banks;
  327. void __iomem *com = u2_banks->com;
  328. u32 index = instance->index;
  329. u32 tmp;
  330. /* (force_suspendm=0) (let suspendm=1, enable usb 480MHz pll) */
  331. tmp = readl(com + U3P_U2PHYDTM0);
  332. tmp &= ~(P2C_FORCE_SUSPENDM | P2C_RG_XCVRSEL);
  333. tmp &= ~(P2C_RG_DATAIN | P2C_DTM0_PART_MASK);
  334. writel(tmp, com + U3P_U2PHYDTM0);
  335. /* OTG Enable */
  336. tmp = readl(com + U3P_USBPHYACR6);
  337. tmp |= PA6_RG_U2_OTG_VBUSCMP_EN;
  338. writel(tmp, com + U3P_USBPHYACR6);
  339. tmp = readl(com + U3P_U2PHYDTM1);
  340. tmp |= P2C_RG_VBUSVALID | P2C_RG_AVALID;
  341. tmp &= ~P2C_RG_SESSEND;
  342. writel(tmp, com + U3P_U2PHYDTM1);
  343. if (u3phy->pdata->avoid_rx_sen_degradation && index) {
  344. tmp = readl(com + U3D_U2PHYDCR0);
  345. tmp |= P2C_RG_SIF_U2PLL_FORCE_ON;
  346. writel(tmp, com + U3D_U2PHYDCR0);
  347. tmp = readl(com + U3P_U2PHYDTM0);
  348. tmp |= P2C_RG_SUSPENDM | P2C_FORCE_SUSPENDM;
  349. writel(tmp, com + U3P_U2PHYDTM0);
  350. }
  351. dev_dbg(u3phy->dev, "%s(%d)\n", __func__, index);
  352. }
  353. static void phy_instance_power_off(struct mt65xx_u3phy *u3phy,
  354. struct mt65xx_phy_instance *instance)
  355. {
  356. struct u2phy_banks *u2_banks = &instance->u2_banks;
  357. void __iomem *com = u2_banks->com;
  358. u32 index = instance->index;
  359. u32 tmp;
  360. tmp = readl(com + U3P_U2PHYDTM0);
  361. tmp &= ~(P2C_RG_XCVRSEL | P2C_RG_DATAIN);
  362. tmp |= P2C_FORCE_SUSPENDM;
  363. writel(tmp, com + U3P_U2PHYDTM0);
  364. /* OTG Disable */
  365. tmp = readl(com + U3P_USBPHYACR6);
  366. tmp &= ~PA6_RG_U2_OTG_VBUSCMP_EN;
  367. writel(tmp, com + U3P_USBPHYACR6);
  368. /* let suspendm=0, set utmi into analog power down */
  369. tmp = readl(com + U3P_U2PHYDTM0);
  370. tmp &= ~P2C_RG_SUSPENDM;
  371. writel(tmp, com + U3P_U2PHYDTM0);
  372. udelay(1);
  373. tmp = readl(com + U3P_U2PHYDTM1);
  374. tmp &= ~(P2C_RG_VBUSVALID | P2C_RG_AVALID);
  375. tmp |= P2C_RG_SESSEND;
  376. writel(tmp, com + U3P_U2PHYDTM1);
  377. if (u3phy->pdata->avoid_rx_sen_degradation && index) {
  378. tmp = readl(com + U3D_U2PHYDCR0);
  379. tmp &= ~P2C_RG_SIF_U2PLL_FORCE_ON;
  380. writel(tmp, com + U3D_U2PHYDCR0);
  381. }
  382. dev_dbg(u3phy->dev, "%s(%d)\n", __func__, index);
  383. }
  384. static void phy_instance_exit(struct mt65xx_u3phy *u3phy,
  385. struct mt65xx_phy_instance *instance)
  386. {
  387. struct u2phy_banks *u2_banks = &instance->u2_banks;
  388. void __iomem *com = u2_banks->com;
  389. u32 index = instance->index;
  390. u32 tmp;
  391. if (u3phy->pdata->avoid_rx_sen_degradation && index) {
  392. tmp = readl(com + U3D_U2PHYDCR0);
  393. tmp &= ~P2C_RG_SIF_U2PLL_FORCE_ON;
  394. writel(tmp, com + U3D_U2PHYDCR0);
  395. tmp = readl(com + U3P_U2PHYDTM0);
  396. tmp &= ~P2C_FORCE_SUSPENDM;
  397. writel(tmp, com + U3P_U2PHYDTM0);
  398. }
  399. }
  400. static void phy_v1_banks_init(struct mt65xx_u3phy *u3phy,
  401. struct mt65xx_phy_instance *instance)
  402. {
  403. struct u2phy_banks *u2_banks = &instance->u2_banks;
  404. struct u3phy_banks *u3_banks = &instance->u3_banks;
  405. if (instance->type == PHY_TYPE_USB2) {
  406. u2_banks->misc = NULL;
  407. u2_banks->fmreg = u3phy->sif_base + SSUSB_SIFSLV_V1_U2FREQ;
  408. u2_banks->com = instance->port_base + SSUSB_SIFSLV_V1_U2PHY_COM;
  409. } else if (instance->type == PHY_TYPE_USB3) {
  410. u3_banks->spllc = u3phy->sif_base + SSUSB_SIFSLV_V1_SPLLC;
  411. u3_banks->chip = NULL;
  412. u3_banks->phyd = instance->port_base + SSUSB_SIFSLV_V1_U3PHYD;
  413. u3_banks->phya = instance->port_base + SSUSB_SIFSLV_V1_U3PHYA;
  414. }
  415. }
  416. static void phy_v2_banks_init(struct mt65xx_u3phy *u3phy,
  417. struct mt65xx_phy_instance *instance)
  418. {
  419. struct u2phy_banks *u2_banks = &instance->u2_banks;
  420. struct u3phy_banks *u3_banks = &instance->u3_banks;
  421. if (instance->type == PHY_TYPE_USB2) {
  422. u2_banks->misc = instance->port_base + SSUSB_SIFSLV_V2_MISC;
  423. u2_banks->fmreg = instance->port_base + SSUSB_SIFSLV_V2_U2FREQ;
  424. u2_banks->com = instance->port_base + SSUSB_SIFSLV_V2_U2PHY_COM;
  425. } else if (instance->type == PHY_TYPE_USB3) {
  426. u3_banks->spllc = instance->port_base + SSUSB_SIFSLV_V2_SPLLC;
  427. u3_banks->chip = instance->port_base + SSUSB_SIFSLV_V2_CHIP;
  428. u3_banks->phyd = instance->port_base + SSUSB_SIFSLV_V2_U3PHYD;
  429. u3_banks->phya = instance->port_base + SSUSB_SIFSLV_V2_U3PHYA;
  430. }
  431. }
  432. static int mt65xx_phy_init(struct phy *phy)
  433. {
  434. struct mt65xx_phy_instance *instance = phy_get_drvdata(phy);
  435. struct mt65xx_u3phy *u3phy = dev_get_drvdata(phy->dev.parent);
  436. int ret;
  437. ret = clk_prepare_enable(u3phy->u3phya_ref);
  438. if (ret) {
  439. dev_err(u3phy->dev, "failed to enable u3phya_ref\n");
  440. return ret;
  441. }
  442. ret = clk_prepare_enable(instance->ref_clk);
  443. if (ret) {
  444. dev_err(u3phy->dev, "failed to enable ref_clk\n");
  445. return ret;
  446. }
  447. if (instance->type == PHY_TYPE_USB2)
  448. phy_instance_init(u3phy, instance);
  449. else
  450. u3_phy_instance_init(u3phy, instance);
  451. return 0;
  452. }
  453. static int mt65xx_phy_power_on(struct phy *phy)
  454. {
  455. struct mt65xx_phy_instance *instance = phy_get_drvdata(phy);
  456. struct mt65xx_u3phy *u3phy = dev_get_drvdata(phy->dev.parent);
  457. if (instance->type == PHY_TYPE_USB2) {
  458. phy_instance_power_on(u3phy, instance);
  459. hs_slew_rate_calibrate(u3phy, instance);
  460. }
  461. return 0;
  462. }
  463. static int mt65xx_phy_power_off(struct phy *phy)
  464. {
  465. struct mt65xx_phy_instance *instance = phy_get_drvdata(phy);
  466. struct mt65xx_u3phy *u3phy = dev_get_drvdata(phy->dev.parent);
  467. if (instance->type == PHY_TYPE_USB2)
  468. phy_instance_power_off(u3phy, instance);
  469. return 0;
  470. }
  471. static int mt65xx_phy_exit(struct phy *phy)
  472. {
  473. struct mt65xx_phy_instance *instance = phy_get_drvdata(phy);
  474. struct mt65xx_u3phy *u3phy = dev_get_drvdata(phy->dev.parent);
  475. if (instance->type == PHY_TYPE_USB2)
  476. phy_instance_exit(u3phy, instance);
  477. clk_disable_unprepare(instance->ref_clk);
  478. clk_disable_unprepare(u3phy->u3phya_ref);
  479. return 0;
  480. }
  481. static struct phy *mt65xx_phy_xlate(struct device *dev,
  482. struct of_phandle_args *args)
  483. {
  484. struct mt65xx_u3phy *u3phy = dev_get_drvdata(dev);
  485. struct mt65xx_phy_instance *instance = NULL;
  486. struct device_node *phy_np = args->np;
  487. int index;
  488. if (args->args_count != 1) {
  489. dev_err(dev, "invalid number of cells in 'phy' property\n");
  490. return ERR_PTR(-EINVAL);
  491. }
  492. for (index = 0; index < u3phy->nphys; index++)
  493. if (phy_np == u3phy->phys[index]->phy->dev.of_node) {
  494. instance = u3phy->phys[index];
  495. break;
  496. }
  497. if (!instance) {
  498. dev_err(dev, "failed to find appropriate phy\n");
  499. return ERR_PTR(-EINVAL);
  500. }
  501. instance->type = args->args[0];
  502. if (!(instance->type == PHY_TYPE_USB2 ||
  503. instance->type == PHY_TYPE_USB3)) {
  504. dev_err(dev, "unsupported device type: %d\n", instance->type);
  505. return ERR_PTR(-EINVAL);
  506. }
  507. if (u3phy->pdata->version == MT_PHY_V1) {
  508. phy_v1_banks_init(u3phy, instance);
  509. } else if (u3phy->pdata->version == MT_PHY_V2) {
  510. phy_v2_banks_init(u3phy, instance);
  511. } else {
  512. dev_err(dev, "phy version is not supported\n");
  513. return ERR_PTR(-EINVAL);
  514. }
  515. return instance->phy;
  516. }
  517. static const struct phy_ops mt65xx_u3phy_ops = {
  518. .init = mt65xx_phy_init,
  519. .exit = mt65xx_phy_exit,
  520. .power_on = mt65xx_phy_power_on,
  521. .power_off = mt65xx_phy_power_off,
  522. .owner = THIS_MODULE,
  523. };
  524. static const struct mt65xx_phy_pdata mt2701_pdata = {
  525. .avoid_rx_sen_degradation = false,
  526. .version = MT_PHY_V1,
  527. };
  528. static const struct mt65xx_phy_pdata mt2712_pdata = {
  529. .avoid_rx_sen_degradation = false,
  530. .version = MT_PHY_V2,
  531. };
  532. static const struct mt65xx_phy_pdata mt8173_pdata = {
  533. .avoid_rx_sen_degradation = true,
  534. .version = MT_PHY_V1,
  535. };
  536. static const struct of_device_id mt65xx_u3phy_id_table[] = {
  537. { .compatible = "mediatek,mt2701-u3phy", .data = &mt2701_pdata },
  538. { .compatible = "mediatek,mt2712-u3phy", .data = &mt2712_pdata },
  539. { .compatible = "mediatek,mt8173-u3phy", .data = &mt8173_pdata },
  540. { },
  541. };
  542. MODULE_DEVICE_TABLE(of, mt65xx_u3phy_id_table);
  543. static int mt65xx_u3phy_probe(struct platform_device *pdev)
  544. {
  545. const struct of_device_id *match;
  546. struct device *dev = &pdev->dev;
  547. struct device_node *np = dev->of_node;
  548. struct device_node *child_np;
  549. struct phy_provider *provider;
  550. struct resource *sif_res;
  551. struct mt65xx_u3phy *u3phy;
  552. struct resource res;
  553. int port, retval;
  554. match = of_match_node(mt65xx_u3phy_id_table, pdev->dev.of_node);
  555. if (!match)
  556. return -EINVAL;
  557. u3phy = devm_kzalloc(dev, sizeof(*u3phy), GFP_KERNEL);
  558. if (!u3phy)
  559. return -ENOMEM;
  560. u3phy->pdata = match->data;
  561. u3phy->nphys = of_get_child_count(np);
  562. u3phy->phys = devm_kcalloc(dev, u3phy->nphys,
  563. sizeof(*u3phy->phys), GFP_KERNEL);
  564. if (!u3phy->phys)
  565. return -ENOMEM;
  566. u3phy->dev = dev;
  567. platform_set_drvdata(pdev, u3phy);
  568. if (u3phy->pdata->version == MT_PHY_V1) {
  569. /* get banks shared by multiple phys */
  570. sif_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  571. u3phy->sif_base = devm_ioremap_resource(dev, sif_res);
  572. if (IS_ERR(u3phy->sif_base)) {
  573. dev_err(dev, "failed to remap sif regs\n");
  574. return PTR_ERR(u3phy->sif_base);
  575. }
  576. }
  577. /* it's deprecated, make it optional for backward compatibility */
  578. u3phy->u3phya_ref = devm_clk_get(dev, "u3phya_ref");
  579. if (IS_ERR(u3phy->u3phya_ref)) {
  580. if (PTR_ERR(u3phy->u3phya_ref) == -EPROBE_DEFER)
  581. return -EPROBE_DEFER;
  582. u3phy->u3phya_ref = NULL;
  583. }
  584. port = 0;
  585. for_each_child_of_node(np, child_np) {
  586. struct mt65xx_phy_instance *instance;
  587. struct phy *phy;
  588. instance = devm_kzalloc(dev, sizeof(*instance), GFP_KERNEL);
  589. if (!instance) {
  590. retval = -ENOMEM;
  591. goto put_child;
  592. }
  593. u3phy->phys[port] = instance;
  594. phy = devm_phy_create(dev, child_np, &mt65xx_u3phy_ops);
  595. if (IS_ERR(phy)) {
  596. dev_err(dev, "failed to create phy\n");
  597. retval = PTR_ERR(phy);
  598. goto put_child;
  599. }
  600. retval = of_address_to_resource(child_np, 0, &res);
  601. if (retval) {
  602. dev_err(dev, "failed to get address resource(id-%d)\n",
  603. port);
  604. goto put_child;
  605. }
  606. instance->port_base = devm_ioremap_resource(&phy->dev, &res);
  607. if (IS_ERR(instance->port_base)) {
  608. dev_err(dev, "failed to remap phy regs\n");
  609. retval = PTR_ERR(instance->port_base);
  610. goto put_child;
  611. }
  612. instance->phy = phy;
  613. instance->index = port;
  614. phy_set_drvdata(phy, instance);
  615. port++;
  616. /* if deprecated clock is provided, ignore instance's one */
  617. if (u3phy->u3phya_ref)
  618. continue;
  619. instance->ref_clk = devm_clk_get(&phy->dev, "ref");
  620. if (IS_ERR(instance->ref_clk)) {
  621. dev_err(dev, "failed to get ref_clk(id-%d)\n", port);
  622. retval = PTR_ERR(instance->ref_clk);
  623. goto put_child;
  624. }
  625. }
  626. provider = devm_of_phy_provider_register(dev, mt65xx_phy_xlate);
  627. return PTR_ERR_OR_ZERO(provider);
  628. put_child:
  629. of_node_put(child_np);
  630. return retval;
  631. }
  632. static struct platform_driver mt65xx_u3phy_driver = {
  633. .probe = mt65xx_u3phy_probe,
  634. .driver = {
  635. .name = "mt65xx-u3phy",
  636. .of_match_table = mt65xx_u3phy_id_table,
  637. },
  638. };
  639. module_platform_driver(mt65xx_u3phy_driver);
  640. MODULE_AUTHOR("Chunfeng Yun <chunfeng.yun@mediatek.com>");
  641. MODULE_DESCRIPTION("mt65xx USB PHY driver");
  642. MODULE_LICENSE("GPL v2");