1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Copyright (c) 2015 MediaTek Inc. |
4 | * Author: Chunfeng Yun <chunfeng.yun@mediatek.com> |
5 | * |
6 | */ |
7 | |
8 | #include <dt-bindings/phy/phy.h> |
9 | #include <linux/clk.h> |
10 | #include <linux/debugfs.h> |
11 | #include <linux/delay.h> |
12 | #include <linux/iopoll.h> |
13 | #include <linux/mfd/syscon.h> |
14 | #include <linux/module.h> |
15 | #include <linux/nvmem-consumer.h> |
16 | #include <linux/of.h> |
17 | #include <linux/of_address.h> |
18 | #include <linux/phy/phy.h> |
19 | #include <linux/platform_device.h> |
20 | #include <linux/regmap.h> |
21 | |
22 | #include "phy-mtk-io.h" |
23 | |
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 | #define SSUSB_SIFSLV_V1_CHIP 0x300 /* shared by u3 phys */ |
29 | /* u2 phy bank */ |
30 | #define SSUSB_SIFSLV_V1_U2PHY_COM 0x000 |
31 | /* u3/pcie/sata phy banks */ |
32 | #define SSUSB_SIFSLV_V1_U3PHYD 0x000 |
33 | #define SSUSB_SIFSLV_V1_U3PHYA 0x200 |
34 | |
35 | /* version V2/V3 sub-banks offset base address */ |
36 | /* V3: U2FREQ is not used anymore, but reserved */ |
37 | /* u2 phy banks */ |
38 | #define SSUSB_SIFSLV_V2_MISC 0x000 |
39 | #define SSUSB_SIFSLV_V2_U2FREQ 0x100 |
40 | #define SSUSB_SIFSLV_V2_U2PHY_COM 0x300 |
41 | /* u3/pcie/sata phy banks */ |
42 | #define SSUSB_SIFSLV_V2_SPLLC 0x000 |
43 | #define SSUSB_SIFSLV_V2_CHIP 0x100 |
44 | #define SSUSB_SIFSLV_V2_U3PHYD 0x200 |
45 | #define SSUSB_SIFSLV_V2_U3PHYA 0x400 |
46 | |
47 | #define U3P_MISC_REG1 0x04 |
48 | #define MR1_EFUSE_AUTO_LOAD_DIS BIT(6) |
49 | |
50 | #define U3P_USBPHYACR0 0x000 |
51 | #define PA0_RG_U2PLL_FORCE_ON BIT(15) |
52 | #define PA0_USB20_PLL_PREDIV GENMASK(7, 6) |
53 | #define PA0_RG_USB20_INTR_EN BIT(5) |
54 | |
55 | #define U3P_USBPHYACR1 0x004 |
56 | #define PA1_RG_INTR_CAL GENMASK(23, 19) |
57 | #define PA1_RG_VRT_SEL GENMASK(14, 12) |
58 | #define PA1_RG_TERM_SEL GENMASK(10, 8) |
59 | |
60 | #define U3P_USBPHYACR2 0x008 |
61 | #define PA2_RG_U2PLL_BW GENMASK(21, 19) |
62 | #define PA2_RG_SIF_U2PLL_FORCE_EN BIT(18) |
63 | |
64 | #define U3P_USBPHYACR5 0x014 |
65 | #define PA5_RG_U2_HSTX_SRCAL_EN BIT(15) |
66 | #define PA5_RG_U2_HSTX_SRCTRL GENMASK(14, 12) |
67 | #define PA5_RG_U2_HS_100U_U3_EN BIT(11) |
68 | |
69 | #define U3P_USBPHYACR6 0x018 |
70 | #define PA6_RG_U2_PRE_EMP GENMASK(31, 30) |
71 | #define PA6_RG_U2_BC11_SW_EN BIT(23) |
72 | #define PA6_RG_U2_OTG_VBUSCMP_EN BIT(20) |
73 | #define PA6_RG_U2_DISCTH GENMASK(7, 4) |
74 | #define PA6_RG_U2_SQTH GENMASK(3, 0) |
75 | |
76 | #define U3P_U2PHYACR4 0x020 |
77 | #define P2C_RG_USB20_GPIO_CTL BIT(9) |
78 | #define P2C_USB20_GPIO_MODE BIT(8) |
79 | #define P2C_U2_GPIO_CTR_MSK (P2C_RG_USB20_GPIO_CTL | P2C_USB20_GPIO_MODE) |
80 | |
81 | #define U3P_U2PHYA_RESV 0x030 |
82 | #define P2R_RG_U2PLL_FBDIV_26M 0x1bb13b |
83 | #define P2R_RG_U2PLL_FBDIV_48M 0x3c0000 |
84 | |
85 | #define U3P_U2PHYA_RESV1 0x044 |
86 | #define P2R_RG_U2PLL_REFCLK_SEL BIT(5) |
87 | #define P2R_RG_U2PLL_FRA_EN BIT(3) |
88 | |
89 | #define U3D_U2PHYDCR0 0x060 |
90 | #define P2C_RG_SIF_U2PLL_FORCE_ON BIT(24) |
91 | |
92 | #define U3P_U2PHYDTM0 0x068 |
93 | #define P2C_FORCE_UART_EN BIT(26) |
94 | #define P2C_FORCE_DATAIN BIT(23) |
95 | #define P2C_FORCE_DM_PULLDOWN BIT(21) |
96 | #define P2C_FORCE_DP_PULLDOWN BIT(20) |
97 | #define P2C_FORCE_XCVRSEL BIT(19) |
98 | #define P2C_FORCE_SUSPENDM BIT(18) |
99 | #define P2C_FORCE_TERMSEL BIT(17) |
100 | #define P2C_RG_DATAIN GENMASK(13, 10) |
101 | #define P2C_RG_DMPULLDOWN BIT(7) |
102 | #define P2C_RG_DPPULLDOWN BIT(6) |
103 | #define P2C_RG_XCVRSEL GENMASK(5, 4) |
104 | #define P2C_RG_SUSPENDM BIT(3) |
105 | #define P2C_RG_TERMSEL BIT(2) |
106 | #define P2C_DTM0_PART_MASK \ |
107 | (P2C_FORCE_DATAIN | P2C_FORCE_DM_PULLDOWN | \ |
108 | P2C_FORCE_DP_PULLDOWN | P2C_FORCE_XCVRSEL | \ |
109 | P2C_FORCE_TERMSEL | P2C_RG_DMPULLDOWN | \ |
110 | P2C_RG_DPPULLDOWN | P2C_RG_TERMSEL) |
111 | |
112 | #define U3P_U2PHYDTM1 0x06C |
113 | #define P2C_RG_UART_EN BIT(16) |
114 | #define P2C_FORCE_IDDIG BIT(9) |
115 | #define P2C_RG_VBUSVALID BIT(5) |
116 | #define P2C_RG_SESSEND BIT(4) |
117 | #define P2C_RG_AVALID BIT(2) |
118 | #define P2C_RG_IDDIG BIT(1) |
119 | |
120 | #define U3P_U2PHYBC12C 0x080 |
121 | #define P2C_RG_CHGDT_EN BIT(0) |
122 | |
123 | #define U3P_U3_CHIP_GPIO_CTLD 0x0c |
124 | #define P3C_REG_IP_SW_RST BIT(31) |
125 | #define P3C_MCU_BUS_CK_GATE_EN BIT(30) |
126 | #define P3C_FORCE_IP_SW_RST BIT(29) |
127 | |
128 | #define U3P_U3_CHIP_GPIO_CTLE 0x10 |
129 | #define P3C_RG_SWRST_U3_PHYD BIT(25) |
130 | #define P3C_RG_SWRST_U3_PHYD_FORCE_EN BIT(24) |
131 | |
132 | #define U3P_U3_PHYA_REG0 0x000 |
133 | #define P3A_RG_IEXT_INTR GENMASK(15, 10) |
134 | #define P3A_RG_CLKDRV_OFF GENMASK(3, 2) |
135 | |
136 | #define U3P_U3_PHYA_REG1 0x004 |
137 | #define P3A_RG_CLKDRV_AMP GENMASK(31, 29) |
138 | |
139 | #define U3P_U3_PHYA_REG6 0x018 |
140 | #define P3A_RG_TX_EIDLE_CM GENMASK(31, 28) |
141 | |
142 | #define U3P_U3_PHYA_REG9 0x024 |
143 | #define P3A_RG_RX_DAC_MUX GENMASK(5, 1) |
144 | |
145 | #define U3P_U3_PHYA_DA_REG0 0x100 |
146 | #define P3A_RG_XTAL_EXT_PE2H GENMASK(17, 16) |
147 | #define P3A_RG_XTAL_EXT_PE1H GENMASK(13, 12) |
148 | #define P3A_RG_XTAL_EXT_EN_U3 GENMASK(11, 10) |
149 | |
150 | #define U3P_U3_PHYA_DA_REG4 0x108 |
151 | #define P3A_RG_PLL_DIVEN_PE2H GENMASK(21, 19) |
152 | #define P3A_RG_PLL_BC_PE2H GENMASK(7, 6) |
153 | |
154 | #define U3P_U3_PHYA_DA_REG5 0x10c |
155 | #define P3A_RG_PLL_BR_PE2H GENMASK(29, 28) |
156 | #define P3A_RG_PLL_IC_PE2H GENMASK(15, 12) |
157 | |
158 | #define U3P_U3_PHYA_DA_REG6 0x110 |
159 | #define P3A_RG_PLL_IR_PE2H GENMASK(19, 16) |
160 | |
161 | #define U3P_U3_PHYA_DA_REG7 0x114 |
162 | #define P3A_RG_PLL_BP_PE2H GENMASK(19, 16) |
163 | |
164 | #define U3P_U3_PHYA_DA_REG20 0x13c |
165 | #define P3A_RG_PLL_DELTA1_PE2H GENMASK(31, 16) |
166 | |
167 | #define U3P_U3_PHYA_DA_REG25 0x148 |
168 | #define P3A_RG_PLL_DELTA_PE2H GENMASK(15, 0) |
169 | |
170 | #define U3P_U3_PHYD_LFPS1 0x00c |
171 | #define P3D_RG_FWAKE_TH GENMASK(21, 16) |
172 | |
173 | #define U3P_U3_PHYD_IMPCAL0 0x010 |
174 | #define P3D_RG_FORCE_TX_IMPEL BIT(31) |
175 | #define P3D_RG_TX_IMPEL GENMASK(28, 24) |
176 | |
177 | #define U3P_U3_PHYD_IMPCAL1 0x014 |
178 | #define P3D_RG_FORCE_RX_IMPEL BIT(31) |
179 | #define P3D_RG_RX_IMPEL GENMASK(28, 24) |
180 | |
181 | #define U3P_U3_PHYD_RSV 0x054 |
182 | #define P3D_RG_EFUSE_AUTO_LOAD_DIS BIT(12) |
183 | |
184 | #define U3P_U3_PHYD_CDR1 0x05c |
185 | #define P3D_RG_CDR_BIR_LTD1 GENMASK(28, 24) |
186 | #define P3D_RG_CDR_BIR_LTD0 GENMASK(12, 8) |
187 | |
188 | #define U3P_U3_PHYD_TOP1 0x100 |
189 | #define P3D_RG_PHY_MODE GENMASK(2, 1) |
190 | #define P3D_RG_FORCE_PHY_MODE BIT(0) |
191 | |
192 | #define U3P_U3_PHYD_RXDET1 0x128 |
193 | #define P3D_RG_RXDET_STB2_SET GENMASK(17, 9) |
194 | |
195 | #define U3P_U3_PHYD_RXDET2 0x12c |
196 | #define P3D_RG_RXDET_STB2_SET_P3 GENMASK(8, 0) |
197 | |
198 | #define U3P_SPLLC_XTALCTL3 0x018 |
199 | #define XC3_RG_U3_XTAL_RX_PWD BIT(9) |
200 | #define XC3_RG_U3_FRC_XTAL_RX_PWD BIT(8) |
201 | |
202 | #define U3P_U2FREQ_FMCR0 0x00 |
203 | #define P2F_RG_MONCLK_SEL GENMASK(27, 26) |
204 | #define P2F_RG_FREQDET_EN BIT(24) |
205 | #define P2F_RG_CYCLECNT GENMASK(23, 0) |
206 | |
207 | #define U3P_U2FREQ_VALUE 0x0c |
208 | |
209 | #define U3P_U2FREQ_FMMONR1 0x10 |
210 | #define P2F_USB_FM_VALID BIT(0) |
211 | #define P2F_RG_FRCK_EN BIT(8) |
212 | |
213 | #define U3P_REF_CLK 26 /* MHZ */ |
214 | #define U3P_SLEW_RATE_COEF 28 |
215 | #define U3P_SR_COEF_DIVISOR 1000 |
216 | #define U3P_FM_DET_CYCLE_CNT 1024 |
217 | |
218 | /* SATA register setting */ |
219 | #define PHYD_CTRL_SIGNAL_MODE4 0x1c |
220 | /* CDR Charge Pump P-path current adjustment */ |
221 | #define RG_CDR_BICLTD1_GEN1_MSK GENMASK(23, 20) |
222 | #define RG_CDR_BICLTD0_GEN1_MSK GENMASK(11, 8) |
223 | |
224 | #define PHYD_DESIGN_OPTION2 0x24 |
225 | /* Symbol lock count selection */ |
226 | #define RG_LOCK_CNT_SEL_MSK GENMASK(5, 4) |
227 | |
228 | #define PHYD_DESIGN_OPTION9 0x40 |
229 | /* COMWAK GAP width window */ |
230 | #define RG_TG_MAX_MSK GENMASK(20, 16) |
231 | /* COMINIT GAP width window */ |
232 | #define RG_T2_MAX_MSK GENMASK(13, 8) |
233 | /* COMWAK GAP width window */ |
234 | #define RG_TG_MIN_MSK GENMASK(7, 5) |
235 | /* COMINIT GAP width window */ |
236 | #define RG_T2_MIN_MSK GENMASK(4, 0) |
237 | |
238 | #define ANA_RG_CTRL_SIGNAL1 0x4c |
239 | /* TX driver tail current control for 0dB de-empahsis mdoe for Gen1 speed */ |
240 | #define RG_IDRV_0DB_GEN1_MSK GENMASK(13, 8) |
241 | |
242 | #define ANA_RG_CTRL_SIGNAL4 0x58 |
243 | #define RG_CDR_BICLTR_GEN1_MSK GENMASK(23, 20) |
244 | /* Loop filter R1 resistance adjustment for Gen1 speed */ |
245 | #define RG_CDR_BR_GEN2_MSK GENMASK(10, 8) |
246 | |
247 | #define ANA_RG_CTRL_SIGNAL6 0x60 |
248 | /* I-path capacitance adjustment for Gen1 */ |
249 | #define RG_CDR_BC_GEN1_MSK GENMASK(28, 24) |
250 | #define RG_CDR_BIRLTR_GEN1_MSK GENMASK(4, 0) |
251 | |
252 | #define ANA_EQ_EYE_CTRL_SIGNAL1 0x6c |
253 | /* RX Gen1 LEQ tuning step */ |
254 | #define RG_EQ_DLEQ_LFI_GEN1_MSK GENMASK(11, 8) |
255 | |
256 | #define ANA_EQ_EYE_CTRL_SIGNAL4 0xd8 |
257 | #define RG_CDR_BIRLTD0_GEN1_MSK GENMASK(20, 16) |
258 | |
259 | #define ANA_EQ_EYE_CTRL_SIGNAL5 0xdc |
260 | #define RG_CDR_BIRLTD0_GEN3_MSK GENMASK(4, 0) |
261 | |
262 | /* PHY switch between pcie/usb3/sgmii/sata */ |
263 | #define USB_PHY_SWITCH_CTRL 0x0 |
264 | #define RG_PHY_SW_TYPE GENMASK(3, 0) |
265 | #define RG_PHY_SW_PCIE 0x0 |
266 | #define RG_PHY_SW_USB3 0x1 |
267 | #define RG_PHY_SW_SGMII 0x2 |
268 | #define RG_PHY_SW_SATA 0x3 |
269 | |
270 | #define TPHY_CLKS_CNT 2 |
271 | |
272 | #define USER_BUF_LEN(count) min_t(size_t, 8, (count)) |
273 | |
274 | enum mtk_phy_version { |
275 | MTK_PHY_V1 = 1, |
276 | MTK_PHY_V2, |
277 | MTK_PHY_V3, |
278 | }; |
279 | |
280 | struct mtk_phy_pdata { |
281 | /* avoid RX sensitivity level degradation only for mt8173 */ |
282 | bool avoid_rx_sen_degradation; |
283 | /* |
284 | * workaround only for mt8195, HW fix it for others of V3, |
285 | * u2phy should use integer mode instead of fractional mode of |
286 | * 48M PLL, fix it by switching PLL to 26M from default 48M |
287 | */ |
288 | bool sw_pll_48m_to_26m; |
289 | /* |
290 | * Some SoCs (e.g. mt8195) drop a bit when use auto load efuse, |
291 | * support sw way, also support it for v2/v3 optionally. |
292 | */ |
293 | bool sw_efuse_supported; |
294 | enum mtk_phy_version version; |
295 | }; |
296 | |
297 | struct u2phy_banks { |
298 | void __iomem *misc; |
299 | void __iomem *fmreg; |
300 | void __iomem *com; |
301 | }; |
302 | |
303 | struct u3phy_banks { |
304 | void __iomem *spllc; |
305 | void __iomem *chip; |
306 | void __iomem *phyd; /* include u3phyd_bank2 */ |
307 | void __iomem *phya; /* include u3phya_da */ |
308 | }; |
309 | |
310 | struct mtk_phy_instance { |
311 | struct phy *phy; |
312 | void __iomem *port_base; |
313 | union { |
314 | struct u2phy_banks u2_banks; |
315 | struct u3phy_banks u3_banks; |
316 | }; |
317 | struct clk_bulk_data clks[TPHY_CLKS_CNT]; |
318 | u32 index; |
319 | u32 type; |
320 | struct regmap *type_sw; |
321 | u32 type_sw_reg; |
322 | u32 type_sw_index; |
323 | u32 efuse_sw_en; |
324 | u32 efuse_intr; |
325 | u32 efuse_tx_imp; |
326 | u32 efuse_rx_imp; |
327 | int eye_src; |
328 | int eye_vrt; |
329 | int eye_term; |
330 | int intr; |
331 | int discth; |
332 | int pre_emphasis; |
333 | bool bc12_en; |
334 | bool type_force_mode; |
335 | }; |
336 | |
337 | struct mtk_tphy { |
338 | struct device *dev; |
339 | void __iomem *sif_base; /* only shared sif */ |
340 | const struct mtk_phy_pdata *pdata; |
341 | struct mtk_phy_instance **phys; |
342 | int nphys; |
343 | int src_ref_clk; /* MHZ, reference clock for slew rate calibrate */ |
344 | int src_coef; /* coefficient for slew rate calibrate */ |
345 | }; |
346 | |
347 | #if IS_ENABLED(CONFIG_DEBUG_FS) |
348 | |
349 | enum u2_phy_params { |
350 | U2P_EYE_VRT = 0, |
351 | U2P_EYE_TERM, |
352 | U2P_EFUSE_EN, |
353 | U2P_EFUSE_INTR, |
354 | U2P_DISCTH, |
355 | U2P_PRE_EMPHASIS, |
356 | }; |
357 | |
358 | enum u3_phy_params { |
359 | U3P_EFUSE_EN = 0, |
360 | U3P_EFUSE_INTR, |
361 | U3P_EFUSE_TX_IMP, |
362 | U3P_EFUSE_RX_IMP, |
363 | }; |
364 | |
365 | static const char *const u2_phy_files[] = { |
366 | [U2P_EYE_VRT] = "vrt" , |
367 | [U2P_EYE_TERM] = "term" , |
368 | [U2P_EFUSE_EN] = "efuse" , |
369 | [U2P_EFUSE_INTR] = "intr" , |
370 | [U2P_DISCTH] = "discth" , |
371 | [U2P_PRE_EMPHASIS] = "preemph" , |
372 | }; |
373 | |
374 | static const char *const u3_phy_files[] = { |
375 | [U3P_EFUSE_EN] = "efuse" , |
376 | [U3P_EFUSE_INTR] = "intr" , |
377 | [U3P_EFUSE_TX_IMP] = "tx-imp" , |
378 | [U3P_EFUSE_RX_IMP] = "rx-imp" , |
379 | }; |
380 | |
381 | static int u2_phy_params_show(struct seq_file *sf, void *unused) |
382 | { |
383 | struct mtk_phy_instance *inst = sf->private; |
384 | const char *fname = file_dentry(file: sf->file)->d_iname; |
385 | struct u2phy_banks *u2_banks = &inst->u2_banks; |
386 | void __iomem *com = u2_banks->com; |
387 | u32 max = 0; |
388 | u32 tmp = 0; |
389 | u32 val = 0; |
390 | int ret; |
391 | |
392 | ret = match_string(array: u2_phy_files, ARRAY_SIZE(u2_phy_files), string: fname); |
393 | if (ret < 0) |
394 | return ret; |
395 | |
396 | switch (ret) { |
397 | case U2P_EYE_VRT: |
398 | tmp = readl(addr: com + U3P_USBPHYACR1); |
399 | val = FIELD_GET(PA1_RG_VRT_SEL, tmp); |
400 | max = FIELD_MAX(PA1_RG_VRT_SEL); |
401 | break; |
402 | |
403 | case U2P_EYE_TERM: |
404 | tmp = readl(addr: com + U3P_USBPHYACR1); |
405 | val = FIELD_GET(PA1_RG_TERM_SEL, tmp); |
406 | max = FIELD_MAX(PA1_RG_TERM_SEL); |
407 | break; |
408 | |
409 | case U2P_EFUSE_EN: |
410 | if (u2_banks->misc) { |
411 | tmp = readl(addr: u2_banks->misc + U3P_MISC_REG1); |
412 | max = 1; |
413 | } |
414 | |
415 | val = !!(tmp & MR1_EFUSE_AUTO_LOAD_DIS); |
416 | break; |
417 | |
418 | case U2P_EFUSE_INTR: |
419 | tmp = readl(addr: com + U3P_USBPHYACR1); |
420 | val = FIELD_GET(PA1_RG_INTR_CAL, tmp); |
421 | max = FIELD_MAX(PA1_RG_INTR_CAL); |
422 | break; |
423 | |
424 | case U2P_DISCTH: |
425 | tmp = readl(addr: com + U3P_USBPHYACR6); |
426 | val = FIELD_GET(PA6_RG_U2_DISCTH, tmp); |
427 | max = FIELD_MAX(PA6_RG_U2_DISCTH); |
428 | break; |
429 | |
430 | case U2P_PRE_EMPHASIS: |
431 | tmp = readl(addr: com + U3P_USBPHYACR6); |
432 | val = FIELD_GET(PA6_RG_U2_PRE_EMP, tmp); |
433 | max = FIELD_MAX(PA6_RG_U2_PRE_EMP); |
434 | break; |
435 | |
436 | default: |
437 | seq_printf(m: sf, fmt: "invalid, %d\n" , ret); |
438 | break; |
439 | } |
440 | |
441 | seq_printf(m: sf, fmt: "%s : %d [0, %d]\n" , fname, val, max); |
442 | |
443 | return 0; |
444 | } |
445 | |
446 | static int u2_phy_params_open(struct inode *inode, struct file *file) |
447 | { |
448 | return single_open(file, u2_phy_params_show, inode->i_private); |
449 | } |
450 | |
451 | static ssize_t u2_phy_params_write(struct file *file, const char __user *ubuf, |
452 | size_t count, loff_t *ppos) |
453 | { |
454 | const char *fname = file_dentry(file)->d_iname; |
455 | struct seq_file *sf = file->private_data; |
456 | struct mtk_phy_instance *inst = sf->private; |
457 | struct u2phy_banks *u2_banks = &inst->u2_banks; |
458 | void __iomem *com = u2_banks->com; |
459 | ssize_t rc; |
460 | u32 val; |
461 | int ret; |
462 | |
463 | rc = kstrtouint_from_user(s: ubuf, USER_BUF_LEN(count), base: 0, res: &val); |
464 | if (rc) |
465 | return rc; |
466 | |
467 | ret = match_string(array: u2_phy_files, ARRAY_SIZE(u2_phy_files), string: fname); |
468 | if (ret < 0) |
469 | return (ssize_t)ret; |
470 | |
471 | switch (ret) { |
472 | case U2P_EYE_VRT: |
473 | mtk_phy_update_field(com + U3P_USBPHYACR1, PA1_RG_VRT_SEL, val); |
474 | break; |
475 | |
476 | case U2P_EYE_TERM: |
477 | mtk_phy_update_field(com + U3P_USBPHYACR1, PA1_RG_TERM_SEL, val); |
478 | break; |
479 | |
480 | case U2P_EFUSE_EN: |
481 | if (u2_banks->misc) |
482 | mtk_phy_update_field(u2_banks->misc + U3P_MISC_REG1, |
483 | MR1_EFUSE_AUTO_LOAD_DIS, !!val); |
484 | break; |
485 | |
486 | case U2P_EFUSE_INTR: |
487 | mtk_phy_update_field(com + U3P_USBPHYACR1, PA1_RG_INTR_CAL, val); |
488 | break; |
489 | |
490 | case U2P_DISCTH: |
491 | mtk_phy_update_field(com + U3P_USBPHYACR6, PA6_RG_U2_DISCTH, val); |
492 | break; |
493 | |
494 | case U2P_PRE_EMPHASIS: |
495 | mtk_phy_update_field(com + U3P_USBPHYACR6, PA6_RG_U2_PRE_EMP, val); |
496 | break; |
497 | |
498 | default: |
499 | break; |
500 | } |
501 | |
502 | return count; |
503 | } |
504 | |
505 | static const struct file_operations u2_phy_fops = { |
506 | .open = u2_phy_params_open, |
507 | .write = u2_phy_params_write, |
508 | .read = seq_read, |
509 | .llseek = seq_lseek, |
510 | .release = single_release, |
511 | }; |
512 | |
513 | static void u2_phy_dbgfs_files_create(struct mtk_phy_instance *inst) |
514 | { |
515 | u32 count = ARRAY_SIZE(u2_phy_files); |
516 | int i; |
517 | |
518 | for (i = 0; i < count; i++) |
519 | debugfs_create_file(name: u2_phy_files[i], mode: 0644, parent: inst->phy->debugfs, |
520 | data: inst, fops: &u2_phy_fops); |
521 | } |
522 | |
523 | static int u3_phy_params_show(struct seq_file *sf, void *unused) |
524 | { |
525 | struct mtk_phy_instance *inst = sf->private; |
526 | const char *fname = file_dentry(file: sf->file)->d_iname; |
527 | struct u3phy_banks *u3_banks = &inst->u3_banks; |
528 | u32 val = 0; |
529 | u32 max = 0; |
530 | u32 tmp; |
531 | int ret; |
532 | |
533 | ret = match_string(array: u3_phy_files, ARRAY_SIZE(u3_phy_files), string: fname); |
534 | if (ret < 0) |
535 | return ret; |
536 | |
537 | switch (ret) { |
538 | case U3P_EFUSE_EN: |
539 | tmp = readl(addr: u3_banks->phyd + U3P_U3_PHYD_RSV); |
540 | val = !!(tmp & P3D_RG_EFUSE_AUTO_LOAD_DIS); |
541 | max = 1; |
542 | break; |
543 | |
544 | case U3P_EFUSE_INTR: |
545 | tmp = readl(addr: u3_banks->phya + U3P_U3_PHYA_REG0); |
546 | val = FIELD_GET(P3A_RG_IEXT_INTR, tmp); |
547 | max = FIELD_MAX(P3A_RG_IEXT_INTR); |
548 | break; |
549 | |
550 | case U3P_EFUSE_TX_IMP: |
551 | tmp = readl(addr: u3_banks->phyd + U3P_U3_PHYD_IMPCAL0); |
552 | val = FIELD_GET(P3D_RG_TX_IMPEL, tmp); |
553 | max = FIELD_MAX(P3D_RG_TX_IMPEL); |
554 | break; |
555 | |
556 | case U3P_EFUSE_RX_IMP: |
557 | tmp = readl(addr: u3_banks->phyd + U3P_U3_PHYD_IMPCAL1); |
558 | val = FIELD_GET(P3D_RG_RX_IMPEL, tmp); |
559 | max = FIELD_MAX(P3D_RG_RX_IMPEL); |
560 | break; |
561 | |
562 | default: |
563 | seq_printf(m: sf, fmt: "invalid, %d\n" , ret); |
564 | break; |
565 | } |
566 | |
567 | seq_printf(m: sf, fmt: "%s : %d [0, %d]\n" , fname, val, max); |
568 | |
569 | return 0; |
570 | } |
571 | |
572 | static int u3_phy_params_open(struct inode *inode, struct file *file) |
573 | { |
574 | return single_open(file, u3_phy_params_show, inode->i_private); |
575 | } |
576 | |
577 | static ssize_t u3_phy_params_write(struct file *file, const char __user *ubuf, |
578 | size_t count, loff_t *ppos) |
579 | { |
580 | const char *fname = file_dentry(file)->d_iname; |
581 | struct seq_file *sf = file->private_data; |
582 | struct mtk_phy_instance *inst = sf->private; |
583 | struct u3phy_banks *u3_banks = &inst->u3_banks; |
584 | void __iomem *phyd = u3_banks->phyd; |
585 | ssize_t rc; |
586 | u32 val; |
587 | int ret; |
588 | |
589 | rc = kstrtouint_from_user(s: ubuf, USER_BUF_LEN(count), base: 0, res: &val); |
590 | if (rc) |
591 | return rc; |
592 | |
593 | ret = match_string(array: u3_phy_files, ARRAY_SIZE(u3_phy_files), string: fname); |
594 | if (ret < 0) |
595 | return (ssize_t)ret; |
596 | |
597 | switch (ret) { |
598 | case U3P_EFUSE_EN: |
599 | mtk_phy_update_field(phyd + U3P_U3_PHYD_RSV, |
600 | P3D_RG_EFUSE_AUTO_LOAD_DIS, !!val); |
601 | break; |
602 | |
603 | case U3P_EFUSE_INTR: |
604 | mtk_phy_update_field(u3_banks->phya + U3P_U3_PHYA_REG0, |
605 | P3A_RG_IEXT_INTR, val); |
606 | break; |
607 | |
608 | case U3P_EFUSE_TX_IMP: |
609 | mtk_phy_update_field(phyd + U3P_U3_PHYD_IMPCAL0, P3D_RG_TX_IMPEL, val); |
610 | mtk_phy_set_bits(reg: phyd + U3P_U3_PHYD_IMPCAL0, P3D_RG_FORCE_TX_IMPEL); |
611 | break; |
612 | |
613 | case U3P_EFUSE_RX_IMP: |
614 | mtk_phy_update_field(phyd + U3P_U3_PHYD_IMPCAL1, P3D_RG_RX_IMPEL, val); |
615 | mtk_phy_set_bits(reg: phyd + U3P_U3_PHYD_IMPCAL1, P3D_RG_FORCE_RX_IMPEL); |
616 | break; |
617 | |
618 | default: |
619 | break; |
620 | } |
621 | |
622 | return count; |
623 | } |
624 | |
625 | static const struct file_operations u3_phy_fops = { |
626 | .open = u3_phy_params_open, |
627 | .write = u3_phy_params_write, |
628 | .read = seq_read, |
629 | .llseek = seq_lseek, |
630 | .release = single_release, |
631 | }; |
632 | |
633 | static void u3_phy_dbgfs_files_create(struct mtk_phy_instance *inst) |
634 | { |
635 | u32 count = ARRAY_SIZE(u3_phy_files); |
636 | int i; |
637 | |
638 | for (i = 0; i < count; i++) |
639 | debugfs_create_file(name: u3_phy_files[i], mode: 0644, parent: inst->phy->debugfs, |
640 | data: inst, fops: &u3_phy_fops); |
641 | } |
642 | |
643 | static int phy_type_show(struct seq_file *sf, void *unused) |
644 | { |
645 | struct mtk_phy_instance *inst = sf->private; |
646 | const char *type; |
647 | |
648 | switch (inst->type) { |
649 | case PHY_TYPE_USB2: |
650 | type = "USB2" ; |
651 | break; |
652 | case PHY_TYPE_USB3: |
653 | type = "USB3" ; |
654 | break; |
655 | case PHY_TYPE_PCIE: |
656 | type = "PCIe" ; |
657 | break; |
658 | case PHY_TYPE_SGMII: |
659 | type = "SGMII" ; |
660 | break; |
661 | case PHY_TYPE_SATA: |
662 | type = "SATA" ; |
663 | break; |
664 | default: |
665 | type = "" ; |
666 | } |
667 | |
668 | seq_printf(m: sf, fmt: "%s\n" , type); |
669 | |
670 | return 0; |
671 | } |
672 | DEFINE_SHOW_ATTRIBUTE(phy_type); |
673 | |
674 | /* these files will be removed when phy is released by phy core */ |
675 | static void phy_debugfs_init(struct mtk_phy_instance *inst) |
676 | { |
677 | debugfs_create_file(name: "type" , mode: 0444, parent: inst->phy->debugfs, data: inst, fops: &phy_type_fops); |
678 | |
679 | switch (inst->type) { |
680 | case PHY_TYPE_USB2: |
681 | u2_phy_dbgfs_files_create(inst); |
682 | break; |
683 | case PHY_TYPE_USB3: |
684 | case PHY_TYPE_PCIE: |
685 | u3_phy_dbgfs_files_create(inst); |
686 | break; |
687 | default: |
688 | break; |
689 | } |
690 | } |
691 | |
692 | #else |
693 | |
694 | static void phy_debugfs_init(struct mtk_phy_instance *inst) |
695 | {} |
696 | |
697 | #endif |
698 | |
699 | static void hs_slew_rate_calibrate(struct mtk_tphy *tphy, |
700 | struct mtk_phy_instance *instance) |
701 | { |
702 | struct u2phy_banks *u2_banks = &instance->u2_banks; |
703 | void __iomem *fmreg = u2_banks->fmreg; |
704 | void __iomem *com = u2_banks->com; |
705 | int calibration_val; |
706 | int fm_out; |
707 | u32 tmp; |
708 | |
709 | /* HW V3 doesn't support slew rate cal anymore */ |
710 | if (tphy->pdata->version == MTK_PHY_V3) |
711 | return; |
712 | |
713 | /* use force value */ |
714 | if (instance->eye_src) |
715 | return; |
716 | |
717 | /* enable USB ring oscillator */ |
718 | mtk_phy_set_bits(reg: com + U3P_USBPHYACR5, PA5_RG_U2_HSTX_SRCAL_EN); |
719 | udelay(1); |
720 | |
721 | /*enable free run clock */ |
722 | mtk_phy_set_bits(reg: fmreg + U3P_U2FREQ_FMMONR1, P2F_RG_FRCK_EN); |
723 | |
724 | /* set cycle count as 1024, and select u2 channel */ |
725 | tmp = readl(addr: fmreg + U3P_U2FREQ_FMCR0); |
726 | tmp &= ~(P2F_RG_CYCLECNT | P2F_RG_MONCLK_SEL); |
727 | tmp |= FIELD_PREP(P2F_RG_CYCLECNT, U3P_FM_DET_CYCLE_CNT); |
728 | if (tphy->pdata->version == MTK_PHY_V1) |
729 | tmp |= FIELD_PREP(P2F_RG_MONCLK_SEL, instance->index >> 1); |
730 | |
731 | writel(val: tmp, addr: fmreg + U3P_U2FREQ_FMCR0); |
732 | |
733 | /* enable frequency meter */ |
734 | mtk_phy_set_bits(reg: fmreg + U3P_U2FREQ_FMCR0, P2F_RG_FREQDET_EN); |
735 | |
736 | /* ignore return value */ |
737 | readl_poll_timeout(fmreg + U3P_U2FREQ_FMMONR1, tmp, |
738 | (tmp & P2F_USB_FM_VALID), 10, 200); |
739 | |
740 | fm_out = readl(addr: fmreg + U3P_U2FREQ_VALUE); |
741 | |
742 | /* disable frequency meter */ |
743 | mtk_phy_clear_bits(reg: fmreg + U3P_U2FREQ_FMCR0, P2F_RG_FREQDET_EN); |
744 | |
745 | /*disable free run clock */ |
746 | mtk_phy_clear_bits(reg: fmreg + U3P_U2FREQ_FMMONR1, P2F_RG_FRCK_EN); |
747 | |
748 | if (fm_out) { |
749 | /* ( 1024 / FM_OUT ) x reference clock frequency x coef */ |
750 | tmp = tphy->src_ref_clk * tphy->src_coef; |
751 | tmp = (tmp * U3P_FM_DET_CYCLE_CNT) / fm_out; |
752 | calibration_val = DIV_ROUND_CLOSEST(tmp, U3P_SR_COEF_DIVISOR); |
753 | } else { |
754 | /* if FM detection fail, set default value */ |
755 | calibration_val = 4; |
756 | } |
757 | dev_dbg(tphy->dev, "phy:%d, fm_out:%d, calib:%d (clk:%d, coef:%d)\n" , |
758 | instance->index, fm_out, calibration_val, |
759 | tphy->src_ref_clk, tphy->src_coef); |
760 | |
761 | /* set HS slew rate */ |
762 | mtk_phy_update_field(com + U3P_USBPHYACR5, PA5_RG_U2_HSTX_SRCTRL, |
763 | calibration_val); |
764 | |
765 | /* disable USB ring oscillator */ |
766 | mtk_phy_clear_bits(reg: com + U3P_USBPHYACR5, PA5_RG_U2_HSTX_SRCAL_EN); |
767 | } |
768 | |
769 | static void u3_phy_instance_init(struct mtk_tphy *tphy, |
770 | struct mtk_phy_instance *instance) |
771 | { |
772 | struct u3phy_banks *u3_banks = &instance->u3_banks; |
773 | void __iomem *phya = u3_banks->phya; |
774 | void __iomem *phyd = u3_banks->phyd; |
775 | |
776 | if (instance->type_force_mode) { |
777 | /* force phy as usb mode, default is pcie rc mode */ |
778 | mtk_phy_update_field(phyd + U3P_U3_PHYD_TOP1, P3D_RG_PHY_MODE, 1); |
779 | mtk_phy_set_bits(reg: phyd + U3P_U3_PHYD_TOP1, P3D_RG_FORCE_PHY_MODE); |
780 | /* power down phy by ip and pipe reset */ |
781 | mtk_phy_set_bits(reg: u3_banks->chip + U3P_U3_CHIP_GPIO_CTLD, |
782 | P3C_FORCE_IP_SW_RST | P3C_MCU_BUS_CK_GATE_EN); |
783 | mtk_phy_set_bits(reg: u3_banks->chip + U3P_U3_CHIP_GPIO_CTLE, |
784 | P3C_RG_SWRST_U3_PHYD | P3C_RG_SWRST_U3_PHYD_FORCE_EN); |
785 | udelay(10); |
786 | /* power on phy again */ |
787 | mtk_phy_clear_bits(reg: u3_banks->chip + U3P_U3_CHIP_GPIO_CTLD, |
788 | P3C_FORCE_IP_SW_RST | P3C_MCU_BUS_CK_GATE_EN); |
789 | mtk_phy_clear_bits(reg: u3_banks->chip + U3P_U3_CHIP_GPIO_CTLE, |
790 | P3C_RG_SWRST_U3_PHYD | P3C_RG_SWRST_U3_PHYD_FORCE_EN); |
791 | } |
792 | |
793 | /* gating PCIe Analog XTAL clock */ |
794 | mtk_phy_set_bits(reg: u3_banks->spllc + U3P_SPLLC_XTALCTL3, |
795 | XC3_RG_U3_XTAL_RX_PWD | XC3_RG_U3_FRC_XTAL_RX_PWD); |
796 | |
797 | /* gating XSQ */ |
798 | mtk_phy_update_field(phya + U3P_U3_PHYA_DA_REG0, P3A_RG_XTAL_EXT_EN_U3, 2); |
799 | |
800 | mtk_phy_update_field(phya + U3P_U3_PHYA_REG9, P3A_RG_RX_DAC_MUX, 4); |
801 | |
802 | mtk_phy_update_field(phya + U3P_U3_PHYA_REG6, P3A_RG_TX_EIDLE_CM, 0xe); |
803 | |
804 | mtk_phy_update_bits(reg: u3_banks->phyd + U3P_U3_PHYD_CDR1, |
805 | P3D_RG_CDR_BIR_LTD0 | P3D_RG_CDR_BIR_LTD1, |
806 | FIELD_PREP(P3D_RG_CDR_BIR_LTD0, 0xc) | |
807 | FIELD_PREP(P3D_RG_CDR_BIR_LTD1, 0x3)); |
808 | |
809 | mtk_phy_update_field(phyd + U3P_U3_PHYD_LFPS1, P3D_RG_FWAKE_TH, 0x34); |
810 | |
811 | mtk_phy_update_field(phyd + U3P_U3_PHYD_RXDET1, P3D_RG_RXDET_STB2_SET, 0x10); |
812 | |
813 | mtk_phy_update_field(phyd + U3P_U3_PHYD_RXDET2, P3D_RG_RXDET_STB2_SET_P3, 0x10); |
814 | |
815 | dev_dbg(tphy->dev, "%s(%d)\n" , __func__, instance->index); |
816 | } |
817 | |
818 | static void u2_phy_pll_26m_set(struct mtk_tphy *tphy, |
819 | struct mtk_phy_instance *instance) |
820 | { |
821 | struct u2phy_banks *u2_banks = &instance->u2_banks; |
822 | void __iomem *com = u2_banks->com; |
823 | |
824 | if (!tphy->pdata->sw_pll_48m_to_26m) |
825 | return; |
826 | |
827 | mtk_phy_update_field(com + U3P_USBPHYACR0, PA0_USB20_PLL_PREDIV, 0); |
828 | |
829 | mtk_phy_update_field(com + U3P_USBPHYACR2, PA2_RG_U2PLL_BW, 3); |
830 | |
831 | writel(P2R_RG_U2PLL_FBDIV_26M, addr: com + U3P_U2PHYA_RESV); |
832 | |
833 | mtk_phy_set_bits(reg: com + U3P_U2PHYA_RESV1, |
834 | P2R_RG_U2PLL_FRA_EN | P2R_RG_U2PLL_REFCLK_SEL); |
835 | } |
836 | |
837 | static void u2_phy_instance_init(struct mtk_tphy *tphy, |
838 | struct mtk_phy_instance *instance) |
839 | { |
840 | struct u2phy_banks *u2_banks = &instance->u2_banks; |
841 | void __iomem *com = u2_banks->com; |
842 | u32 index = instance->index; |
843 | |
844 | /* switch to USB function, and enable usb pll */ |
845 | mtk_phy_clear_bits(reg: com + U3P_U2PHYDTM0, P2C_FORCE_UART_EN | P2C_FORCE_SUSPENDM); |
846 | |
847 | mtk_phy_clear_bits(reg: com + U3P_U2PHYDTM0, |
848 | P2C_RG_XCVRSEL | P2C_RG_DATAIN | P2C_DTM0_PART_MASK); |
849 | |
850 | mtk_phy_clear_bits(reg: com + U3P_U2PHYDTM1, P2C_RG_UART_EN); |
851 | |
852 | mtk_phy_set_bits(reg: com + U3P_USBPHYACR0, PA0_RG_USB20_INTR_EN); |
853 | |
854 | /* disable switch 100uA current to SSUSB */ |
855 | mtk_phy_clear_bits(reg: com + U3P_USBPHYACR5, PA5_RG_U2_HS_100U_U3_EN); |
856 | |
857 | mtk_phy_clear_bits(reg: com + U3P_U2PHYACR4, P2C_U2_GPIO_CTR_MSK); |
858 | |
859 | if (tphy->pdata->avoid_rx_sen_degradation) { |
860 | if (!index) { |
861 | mtk_phy_set_bits(reg: com + U3P_USBPHYACR2, PA2_RG_SIF_U2PLL_FORCE_EN); |
862 | |
863 | mtk_phy_clear_bits(reg: com + U3D_U2PHYDCR0, P2C_RG_SIF_U2PLL_FORCE_ON); |
864 | } else { |
865 | mtk_phy_set_bits(reg: com + U3D_U2PHYDCR0, P2C_RG_SIF_U2PLL_FORCE_ON); |
866 | |
867 | mtk_phy_set_bits(reg: com + U3P_U2PHYDTM0, |
868 | P2C_RG_SUSPENDM | P2C_FORCE_SUSPENDM); |
869 | } |
870 | } |
871 | |
872 | /* DP/DM BC1.1 path Disable */ |
873 | mtk_phy_clear_bits(reg: com + U3P_USBPHYACR6, PA6_RG_U2_BC11_SW_EN); |
874 | |
875 | mtk_phy_update_field(com + U3P_USBPHYACR6, PA6_RG_U2_SQTH, 2); |
876 | |
877 | /* Workaround only for mt8195, HW fix it for others (V3) */ |
878 | u2_phy_pll_26m_set(tphy, instance); |
879 | |
880 | dev_dbg(tphy->dev, "%s(%d)\n" , __func__, index); |
881 | } |
882 | |
883 | static void u2_phy_instance_power_on(struct mtk_tphy *tphy, |
884 | struct mtk_phy_instance *instance) |
885 | { |
886 | struct u2phy_banks *u2_banks = &instance->u2_banks; |
887 | void __iomem *com = u2_banks->com; |
888 | u32 index = instance->index; |
889 | |
890 | /* OTG Enable */ |
891 | mtk_phy_set_bits(reg: com + U3P_USBPHYACR6, PA6_RG_U2_OTG_VBUSCMP_EN); |
892 | |
893 | mtk_phy_set_bits(reg: com + U3P_U2PHYDTM1, P2C_RG_VBUSVALID | P2C_RG_AVALID); |
894 | |
895 | mtk_phy_clear_bits(reg: com + U3P_U2PHYDTM1, P2C_RG_SESSEND); |
896 | |
897 | if (tphy->pdata->avoid_rx_sen_degradation && index) { |
898 | mtk_phy_set_bits(reg: com + U3D_U2PHYDCR0, P2C_RG_SIF_U2PLL_FORCE_ON); |
899 | |
900 | mtk_phy_set_bits(reg: com + U3P_U2PHYDTM0, P2C_RG_SUSPENDM | P2C_FORCE_SUSPENDM); |
901 | } |
902 | dev_dbg(tphy->dev, "%s(%d)\n" , __func__, index); |
903 | } |
904 | |
905 | static void u2_phy_instance_power_off(struct mtk_tphy *tphy, |
906 | struct mtk_phy_instance *instance) |
907 | { |
908 | struct u2phy_banks *u2_banks = &instance->u2_banks; |
909 | void __iomem *com = u2_banks->com; |
910 | u32 index = instance->index; |
911 | |
912 | /* OTG Disable */ |
913 | mtk_phy_clear_bits(reg: com + U3P_USBPHYACR6, PA6_RG_U2_OTG_VBUSCMP_EN); |
914 | |
915 | mtk_phy_clear_bits(reg: com + U3P_U2PHYDTM1, P2C_RG_VBUSVALID | P2C_RG_AVALID); |
916 | |
917 | mtk_phy_set_bits(reg: com + U3P_U2PHYDTM1, P2C_RG_SESSEND); |
918 | |
919 | if (tphy->pdata->avoid_rx_sen_degradation && index) { |
920 | mtk_phy_clear_bits(reg: com + U3P_U2PHYDTM0, P2C_RG_SUSPENDM | P2C_FORCE_SUSPENDM); |
921 | |
922 | mtk_phy_clear_bits(reg: com + U3D_U2PHYDCR0, P2C_RG_SIF_U2PLL_FORCE_ON); |
923 | } |
924 | |
925 | dev_dbg(tphy->dev, "%s(%d)\n" , __func__, index); |
926 | } |
927 | |
928 | static void u2_phy_instance_exit(struct mtk_tphy *tphy, |
929 | struct mtk_phy_instance *instance) |
930 | { |
931 | struct u2phy_banks *u2_banks = &instance->u2_banks; |
932 | void __iomem *com = u2_banks->com; |
933 | u32 index = instance->index; |
934 | |
935 | if (tphy->pdata->avoid_rx_sen_degradation && index) { |
936 | mtk_phy_clear_bits(reg: com + U3D_U2PHYDCR0, P2C_RG_SIF_U2PLL_FORCE_ON); |
937 | |
938 | mtk_phy_clear_bits(reg: com + U3P_U2PHYDTM0, P2C_FORCE_SUSPENDM); |
939 | } |
940 | } |
941 | |
942 | static void u2_phy_instance_set_mode(struct mtk_tphy *tphy, |
943 | struct mtk_phy_instance *instance, |
944 | enum phy_mode mode) |
945 | { |
946 | struct u2phy_banks *u2_banks = &instance->u2_banks; |
947 | u32 tmp; |
948 | |
949 | tmp = readl(addr: u2_banks->com + U3P_U2PHYDTM1); |
950 | switch (mode) { |
951 | case PHY_MODE_USB_DEVICE: |
952 | tmp |= P2C_FORCE_IDDIG | P2C_RG_IDDIG; |
953 | break; |
954 | case PHY_MODE_USB_HOST: |
955 | tmp |= P2C_FORCE_IDDIG; |
956 | tmp &= ~P2C_RG_IDDIG; |
957 | break; |
958 | case PHY_MODE_USB_OTG: |
959 | tmp &= ~(P2C_FORCE_IDDIG | P2C_RG_IDDIG); |
960 | break; |
961 | default: |
962 | return; |
963 | } |
964 | writel(val: tmp, addr: u2_banks->com + U3P_U2PHYDTM1); |
965 | } |
966 | |
967 | static void pcie_phy_instance_init(struct mtk_tphy *tphy, |
968 | struct mtk_phy_instance *instance) |
969 | { |
970 | struct u3phy_banks *u3_banks = &instance->u3_banks; |
971 | void __iomem *phya = u3_banks->phya; |
972 | |
973 | if (tphy->pdata->version != MTK_PHY_V1) |
974 | return; |
975 | |
976 | mtk_phy_update_bits(reg: phya + U3P_U3_PHYA_DA_REG0, |
977 | P3A_RG_XTAL_EXT_PE1H | P3A_RG_XTAL_EXT_PE2H, |
978 | FIELD_PREP(P3A_RG_XTAL_EXT_PE1H, 0x2) | |
979 | FIELD_PREP(P3A_RG_XTAL_EXT_PE2H, 0x2)); |
980 | |
981 | /* ref clk drive */ |
982 | mtk_phy_update_field(phya + U3P_U3_PHYA_REG1, P3A_RG_CLKDRV_AMP, 0x4); |
983 | |
984 | mtk_phy_update_field(phya + U3P_U3_PHYA_REG0, P3A_RG_CLKDRV_OFF, 0x1); |
985 | |
986 | /* SSC delta -5000ppm */ |
987 | mtk_phy_update_field(phya + U3P_U3_PHYA_DA_REG20, P3A_RG_PLL_DELTA1_PE2H, 0x3c); |
988 | |
989 | mtk_phy_update_field(phya + U3P_U3_PHYA_DA_REG25, P3A_RG_PLL_DELTA_PE2H, 0x36); |
990 | |
991 | /* change pll BW 0.6M */ |
992 | mtk_phy_update_bits(reg: phya + U3P_U3_PHYA_DA_REG5, |
993 | P3A_RG_PLL_BR_PE2H | P3A_RG_PLL_IC_PE2H, |
994 | FIELD_PREP(P3A_RG_PLL_BR_PE2H, 0x1) | |
995 | FIELD_PREP(P3A_RG_PLL_IC_PE2H, 0x1)); |
996 | |
997 | mtk_phy_update_bits(reg: phya + U3P_U3_PHYA_DA_REG4, |
998 | P3A_RG_PLL_DIVEN_PE2H | P3A_RG_PLL_BC_PE2H, |
999 | FIELD_PREP(P3A_RG_PLL_BC_PE2H, 0x3)); |
1000 | |
1001 | mtk_phy_update_field(phya + U3P_U3_PHYA_DA_REG6, P3A_RG_PLL_IR_PE2H, 0x2); |
1002 | |
1003 | mtk_phy_update_field(phya + U3P_U3_PHYA_DA_REG7, P3A_RG_PLL_BP_PE2H, 0xa); |
1004 | |
1005 | /* Tx Detect Rx Timing: 10us -> 5us */ |
1006 | mtk_phy_update_field(u3_banks->phyd + U3P_U3_PHYD_RXDET1, |
1007 | P3D_RG_RXDET_STB2_SET, 0x10); |
1008 | |
1009 | mtk_phy_update_field(u3_banks->phyd + U3P_U3_PHYD_RXDET2, |
1010 | P3D_RG_RXDET_STB2_SET_P3, 0x10); |
1011 | |
1012 | /* wait for PCIe subsys register to active */ |
1013 | usleep_range(min: 2500, max: 3000); |
1014 | dev_dbg(tphy->dev, "%s(%d)\n" , __func__, instance->index); |
1015 | } |
1016 | |
1017 | static void pcie_phy_instance_power_on(struct mtk_tphy *tphy, |
1018 | struct mtk_phy_instance *instance) |
1019 | { |
1020 | struct u3phy_banks *bank = &instance->u3_banks; |
1021 | |
1022 | mtk_phy_clear_bits(reg: bank->chip + U3P_U3_CHIP_GPIO_CTLD, |
1023 | P3C_FORCE_IP_SW_RST | P3C_REG_IP_SW_RST); |
1024 | |
1025 | mtk_phy_clear_bits(reg: bank->chip + U3P_U3_CHIP_GPIO_CTLE, |
1026 | P3C_RG_SWRST_U3_PHYD_FORCE_EN | P3C_RG_SWRST_U3_PHYD); |
1027 | } |
1028 | |
1029 | static void pcie_phy_instance_power_off(struct mtk_tphy *tphy, |
1030 | struct mtk_phy_instance *instance) |
1031 | |
1032 | { |
1033 | struct u3phy_banks *bank = &instance->u3_banks; |
1034 | |
1035 | mtk_phy_set_bits(reg: bank->chip + U3P_U3_CHIP_GPIO_CTLD, |
1036 | P3C_FORCE_IP_SW_RST | P3C_REG_IP_SW_RST); |
1037 | |
1038 | mtk_phy_set_bits(reg: bank->chip + U3P_U3_CHIP_GPIO_CTLE, |
1039 | P3C_RG_SWRST_U3_PHYD_FORCE_EN | P3C_RG_SWRST_U3_PHYD); |
1040 | } |
1041 | |
1042 | static void sata_phy_instance_init(struct mtk_tphy *tphy, |
1043 | struct mtk_phy_instance *instance) |
1044 | { |
1045 | struct u3phy_banks *u3_banks = &instance->u3_banks; |
1046 | void __iomem *phyd = u3_banks->phyd; |
1047 | |
1048 | /* charge current adjustment */ |
1049 | mtk_phy_update_bits(reg: phyd + ANA_RG_CTRL_SIGNAL6, |
1050 | RG_CDR_BIRLTR_GEN1_MSK | RG_CDR_BC_GEN1_MSK, |
1051 | FIELD_PREP(RG_CDR_BIRLTR_GEN1_MSK, 0x6) | |
1052 | FIELD_PREP(RG_CDR_BC_GEN1_MSK, 0x1a)); |
1053 | |
1054 | mtk_phy_update_field(phyd + ANA_EQ_EYE_CTRL_SIGNAL4, RG_CDR_BIRLTD0_GEN1_MSK, 0x18); |
1055 | |
1056 | mtk_phy_update_field(phyd + ANA_EQ_EYE_CTRL_SIGNAL5, RG_CDR_BIRLTD0_GEN3_MSK, 0x06); |
1057 | |
1058 | mtk_phy_update_bits(reg: phyd + ANA_RG_CTRL_SIGNAL4, |
1059 | RG_CDR_BICLTR_GEN1_MSK | RG_CDR_BR_GEN2_MSK, |
1060 | FIELD_PREP(RG_CDR_BICLTR_GEN1_MSK, 0x0c) | |
1061 | FIELD_PREP(RG_CDR_BR_GEN2_MSK, 0x07)); |
1062 | |
1063 | mtk_phy_update_bits(reg: phyd + PHYD_CTRL_SIGNAL_MODE4, |
1064 | RG_CDR_BICLTD0_GEN1_MSK | RG_CDR_BICLTD1_GEN1_MSK, |
1065 | FIELD_PREP(RG_CDR_BICLTD0_GEN1_MSK, 0x08) | |
1066 | FIELD_PREP(RG_CDR_BICLTD1_GEN1_MSK, 0x02)); |
1067 | |
1068 | mtk_phy_update_field(phyd + PHYD_DESIGN_OPTION2, RG_LOCK_CNT_SEL_MSK, 0x02); |
1069 | |
1070 | mtk_phy_update_bits(reg: phyd + PHYD_DESIGN_OPTION9, |
1071 | RG_T2_MIN_MSK | RG_TG_MIN_MSK, |
1072 | FIELD_PREP(RG_T2_MIN_MSK, 0x12) | |
1073 | FIELD_PREP(RG_TG_MIN_MSK, 0x04)); |
1074 | |
1075 | mtk_phy_update_bits(reg: phyd + PHYD_DESIGN_OPTION9, |
1076 | RG_T2_MAX_MSK | RG_TG_MAX_MSK, |
1077 | FIELD_PREP(RG_T2_MAX_MSK, 0x31) | |
1078 | FIELD_PREP(RG_TG_MAX_MSK, 0x0e)); |
1079 | |
1080 | mtk_phy_update_field(phyd + ANA_RG_CTRL_SIGNAL1, RG_IDRV_0DB_GEN1_MSK, 0x20); |
1081 | |
1082 | mtk_phy_update_field(phyd + ANA_EQ_EYE_CTRL_SIGNAL1, RG_EQ_DLEQ_LFI_GEN1_MSK, 0x03); |
1083 | |
1084 | dev_dbg(tphy->dev, "%s(%d)\n" , __func__, instance->index); |
1085 | } |
1086 | |
1087 | static void phy_v1_banks_init(struct mtk_tphy *tphy, |
1088 | struct mtk_phy_instance *instance) |
1089 | { |
1090 | struct u2phy_banks *u2_banks = &instance->u2_banks; |
1091 | struct u3phy_banks *u3_banks = &instance->u3_banks; |
1092 | |
1093 | switch (instance->type) { |
1094 | case PHY_TYPE_USB2: |
1095 | u2_banks->misc = NULL; |
1096 | u2_banks->fmreg = tphy->sif_base + SSUSB_SIFSLV_V1_U2FREQ; |
1097 | u2_banks->com = instance->port_base + SSUSB_SIFSLV_V1_U2PHY_COM; |
1098 | break; |
1099 | case PHY_TYPE_USB3: |
1100 | case PHY_TYPE_PCIE: |
1101 | u3_banks->spllc = tphy->sif_base + SSUSB_SIFSLV_V1_SPLLC; |
1102 | u3_banks->chip = tphy->sif_base + SSUSB_SIFSLV_V1_CHIP; |
1103 | u3_banks->phyd = instance->port_base + SSUSB_SIFSLV_V1_U3PHYD; |
1104 | u3_banks->phya = instance->port_base + SSUSB_SIFSLV_V1_U3PHYA; |
1105 | break; |
1106 | case PHY_TYPE_SATA: |
1107 | u3_banks->phyd = instance->port_base + SSUSB_SIFSLV_V1_U3PHYD; |
1108 | break; |
1109 | default: |
1110 | dev_err(tphy->dev, "incompatible PHY type\n" ); |
1111 | return; |
1112 | } |
1113 | } |
1114 | |
1115 | static void phy_v2_banks_init(struct mtk_tphy *tphy, |
1116 | struct mtk_phy_instance *instance) |
1117 | { |
1118 | struct u2phy_banks *u2_banks = &instance->u2_banks; |
1119 | struct u3phy_banks *u3_banks = &instance->u3_banks; |
1120 | |
1121 | switch (instance->type) { |
1122 | case PHY_TYPE_USB2: |
1123 | u2_banks->misc = instance->port_base + SSUSB_SIFSLV_V2_MISC; |
1124 | u2_banks->fmreg = instance->port_base + SSUSB_SIFSLV_V2_U2FREQ; |
1125 | u2_banks->com = instance->port_base + SSUSB_SIFSLV_V2_U2PHY_COM; |
1126 | break; |
1127 | case PHY_TYPE_USB3: |
1128 | case PHY_TYPE_PCIE: |
1129 | u3_banks->spllc = instance->port_base + SSUSB_SIFSLV_V2_SPLLC; |
1130 | u3_banks->chip = instance->port_base + SSUSB_SIFSLV_V2_CHIP; |
1131 | u3_banks->phyd = instance->port_base + SSUSB_SIFSLV_V2_U3PHYD; |
1132 | u3_banks->phya = instance->port_base + SSUSB_SIFSLV_V2_U3PHYA; |
1133 | break; |
1134 | default: |
1135 | dev_err(tphy->dev, "incompatible PHY type\n" ); |
1136 | return; |
1137 | } |
1138 | } |
1139 | |
1140 | static void phy_parse_property(struct mtk_tphy *tphy, |
1141 | struct mtk_phy_instance *instance) |
1142 | { |
1143 | struct device *dev = &instance->phy->dev; |
1144 | |
1145 | if (instance->type == PHY_TYPE_USB3) |
1146 | instance->type_force_mode = device_property_read_bool(dev, propname: "mediatek,force-mode" ); |
1147 | |
1148 | if (instance->type != PHY_TYPE_USB2) |
1149 | return; |
1150 | |
1151 | instance->bc12_en = device_property_read_bool(dev, propname: "mediatek,bc12" ); |
1152 | device_property_read_u32(dev, propname: "mediatek,eye-src" , |
1153 | val: &instance->eye_src); |
1154 | device_property_read_u32(dev, propname: "mediatek,eye-vrt" , |
1155 | val: &instance->eye_vrt); |
1156 | device_property_read_u32(dev, propname: "mediatek,eye-term" , |
1157 | val: &instance->eye_term); |
1158 | device_property_read_u32(dev, propname: "mediatek,intr" , |
1159 | val: &instance->intr); |
1160 | device_property_read_u32(dev, propname: "mediatek,discth" , |
1161 | val: &instance->discth); |
1162 | device_property_read_u32(dev, propname: "mediatek,pre-emphasis" , |
1163 | val: &instance->pre_emphasis); |
1164 | dev_dbg(dev, "bc12:%d, src:%d, vrt:%d, term:%d, intr:%d, disc:%d\n" , |
1165 | instance->bc12_en, instance->eye_src, |
1166 | instance->eye_vrt, instance->eye_term, |
1167 | instance->intr, instance->discth); |
1168 | dev_dbg(dev, "pre-emp:%d\n" , instance->pre_emphasis); |
1169 | } |
1170 | |
1171 | static void u2_phy_props_set(struct mtk_tphy *tphy, |
1172 | struct mtk_phy_instance *instance) |
1173 | { |
1174 | struct u2phy_banks *u2_banks = &instance->u2_banks; |
1175 | void __iomem *com = u2_banks->com; |
1176 | |
1177 | if (instance->bc12_en) /* BC1.2 path Enable */ |
1178 | mtk_phy_set_bits(reg: com + U3P_U2PHYBC12C, P2C_RG_CHGDT_EN); |
1179 | |
1180 | if (tphy->pdata->version < MTK_PHY_V3 && instance->eye_src) |
1181 | mtk_phy_update_field(com + U3P_USBPHYACR5, PA5_RG_U2_HSTX_SRCTRL, |
1182 | instance->eye_src); |
1183 | |
1184 | if (instance->eye_vrt) |
1185 | mtk_phy_update_field(com + U3P_USBPHYACR1, PA1_RG_VRT_SEL, |
1186 | instance->eye_vrt); |
1187 | |
1188 | if (instance->eye_term) |
1189 | mtk_phy_update_field(com + U3P_USBPHYACR1, PA1_RG_TERM_SEL, |
1190 | instance->eye_term); |
1191 | |
1192 | if (instance->intr) { |
1193 | if (u2_banks->misc) |
1194 | mtk_phy_set_bits(reg: u2_banks->misc + U3P_MISC_REG1, |
1195 | MR1_EFUSE_AUTO_LOAD_DIS); |
1196 | |
1197 | mtk_phy_update_field(com + U3P_USBPHYACR1, PA1_RG_INTR_CAL, |
1198 | instance->intr); |
1199 | } |
1200 | |
1201 | if (instance->discth) |
1202 | mtk_phy_update_field(com + U3P_USBPHYACR6, PA6_RG_U2_DISCTH, |
1203 | instance->discth); |
1204 | |
1205 | if (instance->pre_emphasis) |
1206 | mtk_phy_update_field(com + U3P_USBPHYACR6, PA6_RG_U2_PRE_EMP, |
1207 | instance->pre_emphasis); |
1208 | } |
1209 | |
1210 | /* type switch for usb3/pcie/sgmii/sata */ |
1211 | static int phy_type_syscon_get(struct mtk_phy_instance *instance, |
1212 | struct device_node *dn) |
1213 | { |
1214 | struct of_phandle_args args; |
1215 | int ret; |
1216 | |
1217 | /* type switch function is optional */ |
1218 | if (!of_property_read_bool(np: dn, propname: "mediatek,syscon-type" )) |
1219 | return 0; |
1220 | |
1221 | ret = of_parse_phandle_with_fixed_args(np: dn, list_name: "mediatek,syscon-type" , |
1222 | cell_count: 2, index: 0, out_args: &args); |
1223 | if (ret) |
1224 | return ret; |
1225 | |
1226 | instance->type_sw_reg = args.args[0]; |
1227 | instance->type_sw_index = args.args[1] & 0x3; /* <=3 */ |
1228 | instance->type_sw = syscon_node_to_regmap(np: args.np); |
1229 | of_node_put(node: args.np); |
1230 | dev_info(&instance->phy->dev, "type_sw - reg %#x, index %d\n" , |
1231 | instance->type_sw_reg, instance->type_sw_index); |
1232 | |
1233 | return PTR_ERR_OR_ZERO(ptr: instance->type_sw); |
1234 | } |
1235 | |
1236 | static int phy_type_set(struct mtk_phy_instance *instance) |
1237 | { |
1238 | int type; |
1239 | u32 offset; |
1240 | |
1241 | if (!instance->type_sw) |
1242 | return 0; |
1243 | |
1244 | switch (instance->type) { |
1245 | case PHY_TYPE_USB3: |
1246 | type = RG_PHY_SW_USB3; |
1247 | break; |
1248 | case PHY_TYPE_PCIE: |
1249 | type = RG_PHY_SW_PCIE; |
1250 | break; |
1251 | case PHY_TYPE_SGMII: |
1252 | type = RG_PHY_SW_SGMII; |
1253 | break; |
1254 | case PHY_TYPE_SATA: |
1255 | type = RG_PHY_SW_SATA; |
1256 | break; |
1257 | case PHY_TYPE_USB2: |
1258 | default: |
1259 | return 0; |
1260 | } |
1261 | |
1262 | offset = instance->type_sw_index * BITS_PER_BYTE; |
1263 | regmap_update_bits(map: instance->type_sw, reg: instance->type_sw_reg, |
1264 | RG_PHY_SW_TYPE << offset, val: type << offset); |
1265 | |
1266 | return 0; |
1267 | } |
1268 | |
1269 | static int phy_efuse_get(struct mtk_tphy *tphy, struct mtk_phy_instance *instance) |
1270 | { |
1271 | struct device *dev = &instance->phy->dev; |
1272 | int ret = 0; |
1273 | |
1274 | /* tphy v1 doesn't support sw efuse, skip it */ |
1275 | if (!tphy->pdata->sw_efuse_supported) { |
1276 | instance->efuse_sw_en = 0; |
1277 | return 0; |
1278 | } |
1279 | |
1280 | /* software efuse is optional */ |
1281 | instance->efuse_sw_en = device_property_read_bool(dev, propname: "nvmem-cells" ); |
1282 | if (!instance->efuse_sw_en) |
1283 | return 0; |
1284 | |
1285 | switch (instance->type) { |
1286 | case PHY_TYPE_USB2: |
1287 | ret = nvmem_cell_read_variable_le_u32(dev, cell_id: "intr" , val: &instance->efuse_intr); |
1288 | if (ret) { |
1289 | dev_err(dev, "fail to get u2 intr efuse, %d\n" , ret); |
1290 | break; |
1291 | } |
1292 | |
1293 | /* no efuse, ignore it */ |
1294 | if (!instance->efuse_intr) { |
1295 | dev_warn(dev, "no u2 intr efuse, but dts enable it\n" ); |
1296 | instance->efuse_sw_en = 0; |
1297 | break; |
1298 | } |
1299 | |
1300 | dev_dbg(dev, "u2 efuse - intr %x\n" , instance->efuse_intr); |
1301 | break; |
1302 | |
1303 | case PHY_TYPE_USB3: |
1304 | case PHY_TYPE_PCIE: |
1305 | ret = nvmem_cell_read_variable_le_u32(dev, cell_id: "intr" , val: &instance->efuse_intr); |
1306 | if (ret) { |
1307 | dev_err(dev, "fail to get u3 intr efuse, %d\n" , ret); |
1308 | break; |
1309 | } |
1310 | |
1311 | ret = nvmem_cell_read_variable_le_u32(dev, cell_id: "rx_imp" , val: &instance->efuse_rx_imp); |
1312 | if (ret) { |
1313 | dev_err(dev, "fail to get u3 rx_imp efuse, %d\n" , ret); |
1314 | break; |
1315 | } |
1316 | |
1317 | ret = nvmem_cell_read_variable_le_u32(dev, cell_id: "tx_imp" , val: &instance->efuse_tx_imp); |
1318 | if (ret) { |
1319 | dev_err(dev, "fail to get u3 tx_imp efuse, %d\n" , ret); |
1320 | break; |
1321 | } |
1322 | |
1323 | /* no efuse, ignore it */ |
1324 | if (!instance->efuse_intr && |
1325 | !instance->efuse_rx_imp && |
1326 | !instance->efuse_tx_imp) { |
1327 | dev_warn(dev, "no u3 intr efuse, but dts enable it\n" ); |
1328 | instance->efuse_sw_en = 0; |
1329 | break; |
1330 | } |
1331 | |
1332 | dev_dbg(dev, "u3 efuse - intr %x, rx_imp %x, tx_imp %x\n" , |
1333 | instance->efuse_intr, instance->efuse_rx_imp,instance->efuse_tx_imp); |
1334 | break; |
1335 | default: |
1336 | dev_err(dev, "no sw efuse for type %d\n" , instance->type); |
1337 | ret = -EINVAL; |
1338 | } |
1339 | |
1340 | return ret; |
1341 | } |
1342 | |
1343 | static void phy_efuse_set(struct mtk_phy_instance *instance) |
1344 | { |
1345 | struct device *dev = &instance->phy->dev; |
1346 | struct u2phy_banks *u2_banks = &instance->u2_banks; |
1347 | struct u3phy_banks *u3_banks = &instance->u3_banks; |
1348 | |
1349 | if (!instance->efuse_sw_en) |
1350 | return; |
1351 | |
1352 | switch (instance->type) { |
1353 | case PHY_TYPE_USB2: |
1354 | mtk_phy_set_bits(reg: u2_banks->misc + U3P_MISC_REG1, MR1_EFUSE_AUTO_LOAD_DIS); |
1355 | |
1356 | mtk_phy_update_field(u2_banks->com + U3P_USBPHYACR1, PA1_RG_INTR_CAL, |
1357 | instance->efuse_intr); |
1358 | break; |
1359 | case PHY_TYPE_USB3: |
1360 | case PHY_TYPE_PCIE: |
1361 | mtk_phy_set_bits(reg: u3_banks->phyd + U3P_U3_PHYD_RSV, P3D_RG_EFUSE_AUTO_LOAD_DIS); |
1362 | |
1363 | mtk_phy_update_field(u3_banks->phyd + U3P_U3_PHYD_IMPCAL0, P3D_RG_TX_IMPEL, |
1364 | instance->efuse_tx_imp); |
1365 | mtk_phy_set_bits(reg: u3_banks->phyd + U3P_U3_PHYD_IMPCAL0, P3D_RG_FORCE_TX_IMPEL); |
1366 | |
1367 | mtk_phy_update_field(u3_banks->phyd + U3P_U3_PHYD_IMPCAL1, P3D_RG_RX_IMPEL, |
1368 | instance->efuse_rx_imp); |
1369 | mtk_phy_set_bits(reg: u3_banks->phyd + U3P_U3_PHYD_IMPCAL1, P3D_RG_FORCE_RX_IMPEL); |
1370 | |
1371 | mtk_phy_update_field(u3_banks->phya + U3P_U3_PHYA_REG0, P3A_RG_IEXT_INTR, |
1372 | instance->efuse_intr); |
1373 | break; |
1374 | default: |
1375 | dev_warn(dev, "no sw efuse for type %d\n" , instance->type); |
1376 | break; |
1377 | } |
1378 | } |
1379 | |
1380 | static int mtk_phy_init(struct phy *phy) |
1381 | { |
1382 | struct mtk_phy_instance *instance = phy_get_drvdata(phy); |
1383 | struct mtk_tphy *tphy = dev_get_drvdata(dev: phy->dev.parent); |
1384 | int ret; |
1385 | |
1386 | ret = clk_bulk_prepare_enable(TPHY_CLKS_CNT, clks: instance->clks); |
1387 | if (ret) |
1388 | return ret; |
1389 | |
1390 | phy_efuse_set(instance); |
1391 | |
1392 | switch (instance->type) { |
1393 | case PHY_TYPE_USB2: |
1394 | u2_phy_instance_init(tphy, instance); |
1395 | u2_phy_props_set(tphy, instance); |
1396 | break; |
1397 | case PHY_TYPE_USB3: |
1398 | u3_phy_instance_init(tphy, instance); |
1399 | break; |
1400 | case PHY_TYPE_PCIE: |
1401 | pcie_phy_instance_init(tphy, instance); |
1402 | break; |
1403 | case PHY_TYPE_SATA: |
1404 | sata_phy_instance_init(tphy, instance); |
1405 | break; |
1406 | case PHY_TYPE_SGMII: |
1407 | /* nothing to do, only used to set type */ |
1408 | break; |
1409 | default: |
1410 | dev_err(tphy->dev, "incompatible PHY type\n" ); |
1411 | clk_bulk_disable_unprepare(TPHY_CLKS_CNT, clks: instance->clks); |
1412 | return -EINVAL; |
1413 | } |
1414 | |
1415 | return 0; |
1416 | } |
1417 | |
1418 | static int mtk_phy_power_on(struct phy *phy) |
1419 | { |
1420 | struct mtk_phy_instance *instance = phy_get_drvdata(phy); |
1421 | struct mtk_tphy *tphy = dev_get_drvdata(dev: phy->dev.parent); |
1422 | |
1423 | if (instance->type == PHY_TYPE_USB2) { |
1424 | u2_phy_instance_power_on(tphy, instance); |
1425 | hs_slew_rate_calibrate(tphy, instance); |
1426 | } else if (instance->type == PHY_TYPE_PCIE) { |
1427 | pcie_phy_instance_power_on(tphy, instance); |
1428 | } |
1429 | |
1430 | return 0; |
1431 | } |
1432 | |
1433 | static int mtk_phy_power_off(struct phy *phy) |
1434 | { |
1435 | struct mtk_phy_instance *instance = phy_get_drvdata(phy); |
1436 | struct mtk_tphy *tphy = dev_get_drvdata(dev: phy->dev.parent); |
1437 | |
1438 | if (instance->type == PHY_TYPE_USB2) |
1439 | u2_phy_instance_power_off(tphy, instance); |
1440 | else if (instance->type == PHY_TYPE_PCIE) |
1441 | pcie_phy_instance_power_off(tphy, instance); |
1442 | |
1443 | return 0; |
1444 | } |
1445 | |
1446 | static int mtk_phy_exit(struct phy *phy) |
1447 | { |
1448 | struct mtk_phy_instance *instance = phy_get_drvdata(phy); |
1449 | struct mtk_tphy *tphy = dev_get_drvdata(dev: phy->dev.parent); |
1450 | |
1451 | if (instance->type == PHY_TYPE_USB2) |
1452 | u2_phy_instance_exit(tphy, instance); |
1453 | |
1454 | clk_bulk_disable_unprepare(TPHY_CLKS_CNT, clks: instance->clks); |
1455 | return 0; |
1456 | } |
1457 | |
1458 | static int mtk_phy_set_mode(struct phy *phy, enum phy_mode mode, int submode) |
1459 | { |
1460 | struct mtk_phy_instance *instance = phy_get_drvdata(phy); |
1461 | struct mtk_tphy *tphy = dev_get_drvdata(dev: phy->dev.parent); |
1462 | |
1463 | if (instance->type == PHY_TYPE_USB2) |
1464 | u2_phy_instance_set_mode(tphy, instance, mode); |
1465 | |
1466 | return 0; |
1467 | } |
1468 | |
1469 | static struct phy *mtk_phy_xlate(struct device *dev, |
1470 | const struct of_phandle_args *args) |
1471 | { |
1472 | struct mtk_tphy *tphy = dev_get_drvdata(dev); |
1473 | struct mtk_phy_instance *instance = NULL; |
1474 | struct device_node *phy_np = args->np; |
1475 | int index; |
1476 | int ret; |
1477 | |
1478 | if (args->args_count != 1) { |
1479 | dev_err(dev, "invalid number of cells in 'phy' property\n" ); |
1480 | return ERR_PTR(error: -EINVAL); |
1481 | } |
1482 | |
1483 | for (index = 0; index < tphy->nphys; index++) |
1484 | if (phy_np == tphy->phys[index]->phy->dev.of_node) { |
1485 | instance = tphy->phys[index]; |
1486 | break; |
1487 | } |
1488 | |
1489 | if (!instance) { |
1490 | dev_err(dev, "failed to find appropriate phy\n" ); |
1491 | return ERR_PTR(error: -EINVAL); |
1492 | } |
1493 | |
1494 | instance->type = args->args[0]; |
1495 | if (!(instance->type == PHY_TYPE_USB2 || |
1496 | instance->type == PHY_TYPE_USB3 || |
1497 | instance->type == PHY_TYPE_PCIE || |
1498 | instance->type == PHY_TYPE_SATA || |
1499 | instance->type == PHY_TYPE_SGMII)) { |
1500 | dev_err(dev, "unsupported device type: %d\n" , instance->type); |
1501 | return ERR_PTR(error: -EINVAL); |
1502 | } |
1503 | |
1504 | switch (tphy->pdata->version) { |
1505 | case MTK_PHY_V1: |
1506 | phy_v1_banks_init(tphy, instance); |
1507 | break; |
1508 | case MTK_PHY_V2: |
1509 | case MTK_PHY_V3: |
1510 | phy_v2_banks_init(tphy, instance); |
1511 | break; |
1512 | default: |
1513 | dev_err(dev, "phy version is not supported\n" ); |
1514 | return ERR_PTR(error: -EINVAL); |
1515 | } |
1516 | |
1517 | ret = phy_efuse_get(tphy, instance); |
1518 | if (ret) |
1519 | return ERR_PTR(error: ret); |
1520 | |
1521 | phy_parse_property(tphy, instance); |
1522 | phy_type_set(instance); |
1523 | phy_debugfs_init(inst: instance); |
1524 | |
1525 | return instance->phy; |
1526 | } |
1527 | |
1528 | static const struct phy_ops mtk_tphy_ops = { |
1529 | .init = mtk_phy_init, |
1530 | .exit = mtk_phy_exit, |
1531 | .power_on = mtk_phy_power_on, |
1532 | .power_off = mtk_phy_power_off, |
1533 | .set_mode = mtk_phy_set_mode, |
1534 | .owner = THIS_MODULE, |
1535 | }; |
1536 | |
1537 | static const struct mtk_phy_pdata tphy_v1_pdata = { |
1538 | .avoid_rx_sen_degradation = false, |
1539 | .version = MTK_PHY_V1, |
1540 | }; |
1541 | |
1542 | static const struct mtk_phy_pdata tphy_v2_pdata = { |
1543 | .avoid_rx_sen_degradation = false, |
1544 | .sw_efuse_supported = true, |
1545 | .version = MTK_PHY_V2, |
1546 | }; |
1547 | |
1548 | static const struct mtk_phy_pdata tphy_v3_pdata = { |
1549 | .sw_efuse_supported = true, |
1550 | .version = MTK_PHY_V3, |
1551 | }; |
1552 | |
1553 | static const struct mtk_phy_pdata mt8173_pdata = { |
1554 | .avoid_rx_sen_degradation = true, |
1555 | .version = MTK_PHY_V1, |
1556 | }; |
1557 | |
1558 | static const struct mtk_phy_pdata mt8195_pdata = { |
1559 | .sw_pll_48m_to_26m = true, |
1560 | .sw_efuse_supported = true, |
1561 | .version = MTK_PHY_V3, |
1562 | }; |
1563 | |
1564 | static const struct of_device_id mtk_tphy_id_table[] = { |
1565 | { .compatible = "mediatek,mt2701-u3phy" , .data = &tphy_v1_pdata }, |
1566 | { .compatible = "mediatek,mt2712-u3phy" , .data = &tphy_v2_pdata }, |
1567 | { .compatible = "mediatek,mt8173-u3phy" , .data = &mt8173_pdata }, |
1568 | { .compatible = "mediatek,mt8195-tphy" , .data = &mt8195_pdata }, |
1569 | { .compatible = "mediatek,generic-tphy-v1" , .data = &tphy_v1_pdata }, |
1570 | { .compatible = "mediatek,generic-tphy-v2" , .data = &tphy_v2_pdata }, |
1571 | { .compatible = "mediatek,generic-tphy-v3" , .data = &tphy_v3_pdata }, |
1572 | { }, |
1573 | }; |
1574 | MODULE_DEVICE_TABLE(of, mtk_tphy_id_table); |
1575 | |
1576 | static int mtk_tphy_probe(struct platform_device *pdev) |
1577 | { |
1578 | struct device *dev = &pdev->dev; |
1579 | struct device_node *np = dev->of_node; |
1580 | struct device_node *child_np; |
1581 | struct phy_provider *provider; |
1582 | struct resource *sif_res; |
1583 | struct mtk_tphy *tphy; |
1584 | struct resource res; |
1585 | int port, retval; |
1586 | |
1587 | tphy = devm_kzalloc(dev, size: sizeof(*tphy), GFP_KERNEL); |
1588 | if (!tphy) |
1589 | return -ENOMEM; |
1590 | |
1591 | tphy->pdata = of_device_get_match_data(dev); |
1592 | if (!tphy->pdata) |
1593 | return -EINVAL; |
1594 | |
1595 | tphy->nphys = of_get_child_count(np); |
1596 | tphy->phys = devm_kcalloc(dev, n: tphy->nphys, |
1597 | size: sizeof(*tphy->phys), GFP_KERNEL); |
1598 | if (!tphy->phys) |
1599 | return -ENOMEM; |
1600 | |
1601 | tphy->dev = dev; |
1602 | platform_set_drvdata(pdev, data: tphy); |
1603 | |
1604 | sif_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1605 | /* SATA phy of V1 needn't it if not shared with PCIe or USB */ |
1606 | if (sif_res && tphy->pdata->version == MTK_PHY_V1) { |
1607 | /* get banks shared by multiple phys */ |
1608 | tphy->sif_base = devm_ioremap_resource(dev, res: sif_res); |
1609 | if (IS_ERR(ptr: tphy->sif_base)) { |
1610 | dev_err(dev, "failed to remap sif regs\n" ); |
1611 | return PTR_ERR(ptr: tphy->sif_base); |
1612 | } |
1613 | } |
1614 | |
1615 | if (tphy->pdata->version < MTK_PHY_V3) { |
1616 | tphy->src_ref_clk = U3P_REF_CLK; |
1617 | tphy->src_coef = U3P_SLEW_RATE_COEF; |
1618 | /* update parameters of slew rate calibrate if exist */ |
1619 | device_property_read_u32(dev, propname: "mediatek,src-ref-clk-mhz" , |
1620 | val: &tphy->src_ref_clk); |
1621 | device_property_read_u32(dev, propname: "mediatek,src-coef" , |
1622 | val: &tphy->src_coef); |
1623 | } |
1624 | |
1625 | port = 0; |
1626 | for_each_child_of_node(np, child_np) { |
1627 | struct mtk_phy_instance *instance; |
1628 | struct clk_bulk_data *clks; |
1629 | struct device *subdev; |
1630 | struct phy *phy; |
1631 | |
1632 | instance = devm_kzalloc(dev, size: sizeof(*instance), GFP_KERNEL); |
1633 | if (!instance) { |
1634 | retval = -ENOMEM; |
1635 | goto put_child; |
1636 | } |
1637 | |
1638 | tphy->phys[port] = instance; |
1639 | |
1640 | phy = devm_phy_create(dev, node: child_np, ops: &mtk_tphy_ops); |
1641 | if (IS_ERR(ptr: phy)) { |
1642 | dev_err(dev, "failed to create phy\n" ); |
1643 | retval = PTR_ERR(ptr: phy); |
1644 | goto put_child; |
1645 | } |
1646 | |
1647 | subdev = &phy->dev; |
1648 | retval = of_address_to_resource(dev: child_np, index: 0, r: &res); |
1649 | if (retval) { |
1650 | dev_err(subdev, "failed to get address resource(id-%d)\n" , |
1651 | port); |
1652 | goto put_child; |
1653 | } |
1654 | |
1655 | instance->port_base = devm_ioremap_resource(dev: subdev, res: &res); |
1656 | if (IS_ERR(ptr: instance->port_base)) { |
1657 | retval = PTR_ERR(ptr: instance->port_base); |
1658 | goto put_child; |
1659 | } |
1660 | |
1661 | instance->phy = phy; |
1662 | instance->index = port; |
1663 | phy_set_drvdata(phy, data: instance); |
1664 | port++; |
1665 | |
1666 | clks = instance->clks; |
1667 | clks[0].id = "ref" ; /* digital (& analog) clock */ |
1668 | clks[1].id = "da_ref" ; /* analog clock */ |
1669 | retval = devm_clk_bulk_get_optional(dev: subdev, TPHY_CLKS_CNT, clks); |
1670 | if (retval) |
1671 | goto put_child; |
1672 | |
1673 | retval = phy_type_syscon_get(instance, dn: child_np); |
1674 | if (retval) |
1675 | goto put_child; |
1676 | } |
1677 | |
1678 | provider = devm_of_phy_provider_register(dev, mtk_phy_xlate); |
1679 | |
1680 | return PTR_ERR_OR_ZERO(ptr: provider); |
1681 | put_child: |
1682 | of_node_put(node: child_np); |
1683 | return retval; |
1684 | } |
1685 | |
1686 | static struct platform_driver mtk_tphy_driver = { |
1687 | .probe = mtk_tphy_probe, |
1688 | .driver = { |
1689 | .name = "mtk-tphy" , |
1690 | .of_match_table = mtk_tphy_id_table, |
1691 | }, |
1692 | }; |
1693 | |
1694 | module_platform_driver(mtk_tphy_driver); |
1695 | |
1696 | MODULE_AUTHOR("Chunfeng Yun <chunfeng.yun@mediatek.com>" ); |
1697 | MODULE_DESCRIPTION("MediaTek T-PHY driver" ); |
1698 | MODULE_LICENSE("GPL v2" ); |
1699 | |