1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * MediaTek xHCI Host Controller Driver |
4 | * |
5 | * Copyright (c) 2015 MediaTek Inc. |
6 | * Author: |
7 | * Chunfeng Yun <chunfeng.yun@mediatek.com> |
8 | */ |
9 | |
10 | #include <linux/bitfield.h> |
11 | #include <linux/dma-mapping.h> |
12 | #include <linux/iopoll.h> |
13 | #include <linux/kernel.h> |
14 | #include <linux/mfd/syscon.h> |
15 | #include <linux/module.h> |
16 | #include <linux/of.h> |
17 | #include <linux/platform_device.h> |
18 | #include <linux/pm_runtime.h> |
19 | #include <linux/pm_wakeirq.h> |
20 | #include <linux/regmap.h> |
21 | #include <linux/regulator/consumer.h> |
22 | #include <linux/reset.h> |
23 | |
24 | #include "xhci.h" |
25 | #include "xhci-mtk.h" |
26 | |
27 | /* ip_pw_ctrl0 register */ |
28 | #define CTRL0_IP_SW_RST BIT(0) |
29 | |
30 | /* ip_pw_ctrl1 register */ |
31 | #define CTRL1_IP_HOST_PDN BIT(0) |
32 | |
33 | /* ip_pw_ctrl2 register */ |
34 | #define CTRL2_IP_DEV_PDN BIT(0) |
35 | |
36 | /* ip_pw_sts1 register */ |
37 | #define STS1_IP_SLEEP_STS BIT(30) |
38 | #define STS1_U3_MAC_RST BIT(16) |
39 | #define STS1_XHCI_RST BIT(11) |
40 | #define STS1_SYS125_RST BIT(10) |
41 | #define STS1_REF_RST BIT(8) |
42 | #define STS1_SYSPLL_STABLE BIT(0) |
43 | |
44 | /* ip_xhci_cap register */ |
45 | #define CAP_U3_PORT_NUM(p) ((p) & 0xff) |
46 | #define CAP_U2_PORT_NUM(p) (((p) >> 8) & 0xff) |
47 | |
48 | /* u3_ctrl_p register */ |
49 | #define CTRL_U3_PORT_HOST_SEL BIT(2) |
50 | #define CTRL_U3_PORT_PDN BIT(1) |
51 | #define CTRL_U3_PORT_DIS BIT(0) |
52 | |
53 | /* u2_ctrl_p register */ |
54 | #define CTRL_U2_PORT_HOST_SEL BIT(2) |
55 | #define CTRL_U2_PORT_PDN BIT(1) |
56 | #define CTRL_U2_PORT_DIS BIT(0) |
57 | |
58 | /* u2_phy_pll register */ |
59 | #define CTRL_U2_FORCE_PLL_STB BIT(28) |
60 | |
61 | /* xHCI CSR */ |
62 | #define LS_EOF_CFG 0x930 |
63 | #define LSEOF_OFFSET 0x89 |
64 | |
65 | #define FS_EOF_CFG 0x934 |
66 | #define FSEOF_OFFSET 0x2e |
67 | |
68 | #define SS_GEN1_EOF_CFG 0x93c |
69 | #define SSG1EOF_OFFSET 0x78 |
70 | |
71 | #define HFCNTR_CFG 0x944 |
72 | #define ITP_DELTA_CLK (0xa << 1) |
73 | #define ITP_DELTA_CLK_MASK GENMASK(5, 1) |
74 | #define FRMCNT_LEV1_RANG (0x12b << 8) |
75 | #define FRMCNT_LEV1_RANG_MASK GENMASK(19, 8) |
76 | |
77 | #define HSCH_CFG1 0x960 |
78 | #define SCH3_RXFIFO_DEPTH_MASK GENMASK(21, 20) |
79 | |
80 | #define SS_GEN2_EOF_CFG 0x990 |
81 | #define SSG2EOF_OFFSET 0x3c |
82 | |
83 | #define XSEOF_OFFSET_MASK GENMASK(11, 0) |
84 | |
85 | /* usb remote wakeup registers in syscon */ |
86 | |
87 | /* mt8173 etc */ |
88 | #define PERI_WK_CTRL1 0x4 |
89 | #define WC1_IS_C(x) (((x) & 0xf) << 26) /* cycle debounce */ |
90 | #define WC1_IS_EN BIT(25) |
91 | #define WC1_IS_P BIT(6) /* polarity for ip sleep */ |
92 | |
93 | /* mt8183 */ |
94 | #define PERI_WK_CTRL0 0x0 |
95 | #define WC0_IS_C(x) ((u32)(((x) & 0xf) << 28)) /* cycle debounce */ |
96 | #define WC0_IS_P BIT(12) /* polarity */ |
97 | #define WC0_IS_EN BIT(6) |
98 | |
99 | /* mt8192 */ |
100 | #define WC0_SSUSB0_CDEN BIT(6) |
101 | #define WC0_IS_SPM_EN BIT(1) |
102 | |
103 | /* mt8195 */ |
104 | #define PERI_WK_CTRL0_8195 0x04 |
105 | #define WC0_IS_P_95 BIT(30) /* polarity */ |
106 | #define WC0_IS_C_95(x) ((u32)(((x) & 0x7) << 27)) |
107 | #define WC0_IS_EN_P3_95 BIT(26) |
108 | #define WC0_IS_EN_P2_95 BIT(25) |
109 | #define WC0_IS_EN_P1_95 BIT(24) |
110 | |
111 | #define PERI_WK_CTRL1_8195 0x20 |
112 | #define WC1_IS_C_95(x) ((u32)(((x) & 0xf) << 28)) |
113 | #define WC1_IS_P_95 BIT(12) |
114 | #define WC1_IS_EN_P0_95 BIT(6) |
115 | |
116 | /* mt2712 etc */ |
117 | #define PERI_SSUSB_SPM_CTRL 0x0 |
118 | #define SSC_IP_SLEEP_EN BIT(4) |
119 | #define SSC_SPM_INT_EN BIT(1) |
120 | |
121 | #define SCH_FIFO_TO_KB(x) ((x) >> 10) |
122 | |
123 | enum ssusb_uwk_vers { |
124 | SSUSB_UWK_V1 = 1, |
125 | SSUSB_UWK_V2, |
126 | SSUSB_UWK_V1_1 = 101, /* specific revision 1.01 */ |
127 | SSUSB_UWK_V1_2, /* specific revision 1.2 */ |
128 | SSUSB_UWK_V1_3, /* mt8195 IP0 */ |
129 | SSUSB_UWK_V1_4, /* mt8195 IP1 */ |
130 | SSUSB_UWK_V1_5, /* mt8195 IP2 */ |
131 | SSUSB_UWK_V1_6, /* mt8195 IP3 */ |
132 | }; |
133 | |
134 | /* |
135 | * MT8195 has 4 controllers, the controller1~3's default SOF/ITP interval |
136 | * is calculated from the frame counter clock 24M, but in fact, the clock |
137 | * is 48M, add workaround for it. |
138 | */ |
139 | static void xhci_mtk_set_frame_interval(struct xhci_hcd_mtk *mtk) |
140 | { |
141 | struct device *dev = mtk->dev; |
142 | struct usb_hcd *hcd = mtk->hcd; |
143 | u32 value; |
144 | |
145 | if (!of_device_is_compatible(device: dev->of_node, "mediatek,mt8195-xhci" )) |
146 | return; |
147 | |
148 | value = readl(addr: hcd->regs + HFCNTR_CFG); |
149 | value &= ~(ITP_DELTA_CLK_MASK | FRMCNT_LEV1_RANG_MASK); |
150 | value |= (ITP_DELTA_CLK | FRMCNT_LEV1_RANG); |
151 | writel(val: value, addr: hcd->regs + HFCNTR_CFG); |
152 | |
153 | value = readl(addr: hcd->regs + LS_EOF_CFG); |
154 | value &= ~XSEOF_OFFSET_MASK; |
155 | value |= LSEOF_OFFSET; |
156 | writel(val: value, addr: hcd->regs + LS_EOF_CFG); |
157 | |
158 | value = readl(addr: hcd->regs + FS_EOF_CFG); |
159 | value &= ~XSEOF_OFFSET_MASK; |
160 | value |= FSEOF_OFFSET; |
161 | writel(val: value, addr: hcd->regs + FS_EOF_CFG); |
162 | |
163 | value = readl(addr: hcd->regs + SS_GEN1_EOF_CFG); |
164 | value &= ~XSEOF_OFFSET_MASK; |
165 | value |= SSG1EOF_OFFSET; |
166 | writel(val: value, addr: hcd->regs + SS_GEN1_EOF_CFG); |
167 | |
168 | value = readl(addr: hcd->regs + SS_GEN2_EOF_CFG); |
169 | value &= ~XSEOF_OFFSET_MASK; |
170 | value |= SSG2EOF_OFFSET; |
171 | writel(val: value, addr: hcd->regs + SS_GEN2_EOF_CFG); |
172 | } |
173 | |
174 | /* |
175 | * workaround: usb3.2 gen1 isoc rx hw issue |
176 | * host send out unexpected ACK afer device fininsh a burst transfer with |
177 | * a short packet. |
178 | */ |
179 | static void xhci_mtk_rxfifo_depth_set(struct xhci_hcd_mtk *mtk) |
180 | { |
181 | struct usb_hcd *hcd = mtk->hcd; |
182 | u32 value; |
183 | |
184 | if (!mtk->rxfifo_depth) |
185 | return; |
186 | |
187 | value = readl(addr: hcd->regs + HSCH_CFG1); |
188 | value &= ~SCH3_RXFIFO_DEPTH_MASK; |
189 | value |= FIELD_PREP(SCH3_RXFIFO_DEPTH_MASK, |
190 | SCH_FIFO_TO_KB(mtk->rxfifo_depth) - 1); |
191 | writel(val: value, addr: hcd->regs + HSCH_CFG1); |
192 | } |
193 | |
194 | static void xhci_mtk_init_quirk(struct xhci_hcd_mtk *mtk) |
195 | { |
196 | /* workaround only for mt8195 */ |
197 | xhci_mtk_set_frame_interval(mtk); |
198 | |
199 | /* workaround for SoCs using SSUSB about before IPM v1.6.0 */ |
200 | xhci_mtk_rxfifo_depth_set(mtk); |
201 | } |
202 | |
203 | static int xhci_mtk_host_enable(struct xhci_hcd_mtk *mtk) |
204 | { |
205 | struct mu3c_ippc_regs __iomem *ippc = mtk->ippc_regs; |
206 | u32 value, check_val; |
207 | int u3_ports_disabled = 0; |
208 | int ret; |
209 | int i; |
210 | |
211 | if (!mtk->has_ippc) |
212 | return 0; |
213 | |
214 | /* power on host ip */ |
215 | value = readl(addr: &ippc->ip_pw_ctr1); |
216 | value &= ~CTRL1_IP_HOST_PDN; |
217 | writel(val: value, addr: &ippc->ip_pw_ctr1); |
218 | |
219 | /* power on and enable u3 ports except skipped ones */ |
220 | for (i = 0; i < mtk->num_u3_ports; i++) { |
221 | if ((0x1 << i) & mtk->u3p_dis_msk) { |
222 | u3_ports_disabled++; |
223 | continue; |
224 | } |
225 | |
226 | value = readl(addr: &ippc->u3_ctrl_p[i]); |
227 | value &= ~(CTRL_U3_PORT_PDN | CTRL_U3_PORT_DIS); |
228 | value |= CTRL_U3_PORT_HOST_SEL; |
229 | writel(val: value, addr: &ippc->u3_ctrl_p[i]); |
230 | } |
231 | |
232 | /* power on and enable all u2 ports except skipped ones */ |
233 | for (i = 0; i < mtk->num_u2_ports; i++) { |
234 | if (BIT(i) & mtk->u2p_dis_msk) |
235 | continue; |
236 | |
237 | value = readl(addr: &ippc->u2_ctrl_p[i]); |
238 | value &= ~(CTRL_U2_PORT_PDN | CTRL_U2_PORT_DIS); |
239 | value |= CTRL_U2_PORT_HOST_SEL; |
240 | writel(val: value, addr: &ippc->u2_ctrl_p[i]); |
241 | } |
242 | |
243 | /* |
244 | * wait for clocks to be stable, and clock domains reset to |
245 | * be inactive after power on and enable ports |
246 | */ |
247 | check_val = STS1_SYSPLL_STABLE | STS1_REF_RST | |
248 | STS1_SYS125_RST | STS1_XHCI_RST; |
249 | |
250 | if (mtk->num_u3_ports > u3_ports_disabled) |
251 | check_val |= STS1_U3_MAC_RST; |
252 | |
253 | ret = readl_poll_timeout(&ippc->ip_pw_sts1, value, |
254 | (check_val == (value & check_val)), 100, 20000); |
255 | if (ret) { |
256 | dev_err(mtk->dev, "clocks are not stable (0x%x)\n" , value); |
257 | return ret; |
258 | } |
259 | |
260 | return 0; |
261 | } |
262 | |
263 | static int xhci_mtk_host_disable(struct xhci_hcd_mtk *mtk) |
264 | { |
265 | struct mu3c_ippc_regs __iomem *ippc = mtk->ippc_regs; |
266 | u32 value; |
267 | int ret; |
268 | int i; |
269 | |
270 | if (!mtk->has_ippc) |
271 | return 0; |
272 | |
273 | /* power down u3 ports except skipped ones */ |
274 | for (i = 0; i < mtk->num_u3_ports; i++) { |
275 | if ((0x1 << i) & mtk->u3p_dis_msk) |
276 | continue; |
277 | |
278 | value = readl(addr: &ippc->u3_ctrl_p[i]); |
279 | value |= CTRL_U3_PORT_PDN; |
280 | writel(val: value, addr: &ippc->u3_ctrl_p[i]); |
281 | } |
282 | |
283 | /* power down all u2 ports except skipped ones */ |
284 | for (i = 0; i < mtk->num_u2_ports; i++) { |
285 | if (BIT(i) & mtk->u2p_dis_msk) |
286 | continue; |
287 | |
288 | value = readl(addr: &ippc->u2_ctrl_p[i]); |
289 | value |= CTRL_U2_PORT_PDN; |
290 | writel(val: value, addr: &ippc->u2_ctrl_p[i]); |
291 | } |
292 | |
293 | /* power down host ip */ |
294 | value = readl(addr: &ippc->ip_pw_ctr1); |
295 | value |= CTRL1_IP_HOST_PDN; |
296 | writel(val: value, addr: &ippc->ip_pw_ctr1); |
297 | |
298 | /* wait for host ip to sleep */ |
299 | ret = readl_poll_timeout(&ippc->ip_pw_sts1, value, |
300 | (value & STS1_IP_SLEEP_STS), 100, 100000); |
301 | if (ret) |
302 | dev_err(mtk->dev, "ip sleep failed!!!\n" ); |
303 | else /* workaound for platforms using low level latch */ |
304 | usleep_range(min: 100, max: 200); |
305 | |
306 | return ret; |
307 | } |
308 | |
309 | static int xhci_mtk_ssusb_config(struct xhci_hcd_mtk *mtk) |
310 | { |
311 | struct mu3c_ippc_regs __iomem *ippc = mtk->ippc_regs; |
312 | u32 value; |
313 | |
314 | if (!mtk->has_ippc) |
315 | return 0; |
316 | |
317 | /* reset whole ip */ |
318 | value = readl(addr: &ippc->ip_pw_ctr0); |
319 | value |= CTRL0_IP_SW_RST; |
320 | writel(val: value, addr: &ippc->ip_pw_ctr0); |
321 | udelay(1); |
322 | value = readl(addr: &ippc->ip_pw_ctr0); |
323 | value &= ~CTRL0_IP_SW_RST; |
324 | writel(val: value, addr: &ippc->ip_pw_ctr0); |
325 | |
326 | /* |
327 | * device ip is default power-on in fact |
328 | * power down device ip, otherwise ip-sleep will fail |
329 | */ |
330 | value = readl(addr: &ippc->ip_pw_ctr2); |
331 | value |= CTRL2_IP_DEV_PDN; |
332 | writel(val: value, addr: &ippc->ip_pw_ctr2); |
333 | |
334 | value = readl(addr: &ippc->ip_xhci_cap); |
335 | mtk->num_u3_ports = CAP_U3_PORT_NUM(value); |
336 | mtk->num_u2_ports = CAP_U2_PORT_NUM(value); |
337 | dev_dbg(mtk->dev, "%s u2p:%d, u3p:%d\n" , __func__, |
338 | mtk->num_u2_ports, mtk->num_u3_ports); |
339 | |
340 | return xhci_mtk_host_enable(mtk); |
341 | } |
342 | |
343 | /* only clocks can be turn off for ip-sleep wakeup mode */ |
344 | static void usb_wakeup_ip_sleep_set(struct xhci_hcd_mtk *mtk, bool enable) |
345 | { |
346 | u32 reg, msk, val; |
347 | |
348 | switch (mtk->uwk_vers) { |
349 | case SSUSB_UWK_V1: |
350 | reg = mtk->uwk_reg_base + PERI_WK_CTRL1; |
351 | msk = WC1_IS_EN | WC1_IS_C(0xf) | WC1_IS_P; |
352 | val = enable ? (WC1_IS_EN | WC1_IS_C(0x8)) : 0; |
353 | break; |
354 | case SSUSB_UWK_V1_1: |
355 | reg = mtk->uwk_reg_base + PERI_WK_CTRL0; |
356 | msk = WC0_IS_EN | WC0_IS_C(0xf) | WC0_IS_P; |
357 | val = enable ? (WC0_IS_EN | WC0_IS_C(0x1)) : 0; |
358 | break; |
359 | case SSUSB_UWK_V1_2: |
360 | reg = mtk->uwk_reg_base + PERI_WK_CTRL0; |
361 | msk = WC0_SSUSB0_CDEN | WC0_IS_SPM_EN; |
362 | val = enable ? msk : 0; |
363 | break; |
364 | case SSUSB_UWK_V1_3: |
365 | reg = mtk->uwk_reg_base + PERI_WK_CTRL1_8195; |
366 | msk = WC1_IS_EN_P0_95 | WC1_IS_C_95(0xf) | WC1_IS_P_95; |
367 | val = enable ? (WC1_IS_EN_P0_95 | WC1_IS_C_95(0x1)) : 0; |
368 | break; |
369 | case SSUSB_UWK_V1_4: |
370 | reg = mtk->uwk_reg_base + PERI_WK_CTRL0_8195; |
371 | msk = WC0_IS_EN_P1_95 | WC0_IS_C_95(0x7) | WC0_IS_P_95; |
372 | val = enable ? (WC0_IS_EN_P1_95 | WC0_IS_C_95(0x1)) : 0; |
373 | break; |
374 | case SSUSB_UWK_V1_5: |
375 | reg = mtk->uwk_reg_base + PERI_WK_CTRL0_8195; |
376 | msk = WC0_IS_EN_P2_95 | WC0_IS_C_95(0x7) | WC0_IS_P_95; |
377 | val = enable ? (WC0_IS_EN_P2_95 | WC0_IS_C_95(0x1)) : 0; |
378 | break; |
379 | case SSUSB_UWK_V1_6: |
380 | reg = mtk->uwk_reg_base + PERI_WK_CTRL0_8195; |
381 | msk = WC0_IS_EN_P3_95 | WC0_IS_C_95(0x7) | WC0_IS_P_95; |
382 | val = enable ? (WC0_IS_EN_P3_95 | WC0_IS_C_95(0x1)) : 0; |
383 | break; |
384 | case SSUSB_UWK_V2: |
385 | reg = mtk->uwk_reg_base + PERI_SSUSB_SPM_CTRL; |
386 | msk = SSC_IP_SLEEP_EN | SSC_SPM_INT_EN; |
387 | val = enable ? msk : 0; |
388 | break; |
389 | default: |
390 | return; |
391 | } |
392 | regmap_update_bits(map: mtk->uwk, reg, mask: msk, val); |
393 | } |
394 | |
395 | static int usb_wakeup_of_property_parse(struct xhci_hcd_mtk *mtk, |
396 | struct device_node *dn) |
397 | { |
398 | struct of_phandle_args args; |
399 | int ret; |
400 | |
401 | /* Wakeup function is optional */ |
402 | mtk->uwk_en = of_property_read_bool(np: dn, propname: "wakeup-source" ); |
403 | if (!mtk->uwk_en) |
404 | return 0; |
405 | |
406 | ret = of_parse_phandle_with_fixed_args(np: dn, |
407 | list_name: "mediatek,syscon-wakeup" , cell_count: 2, index: 0, out_args: &args); |
408 | if (ret) |
409 | return ret; |
410 | |
411 | mtk->uwk_reg_base = args.args[0]; |
412 | mtk->uwk_vers = args.args[1]; |
413 | mtk->uwk = syscon_node_to_regmap(np: args.np); |
414 | of_node_put(node: args.np); |
415 | dev_info(mtk->dev, "uwk - reg:0x%x, version:%d\n" , |
416 | mtk->uwk_reg_base, mtk->uwk_vers); |
417 | |
418 | return PTR_ERR_OR_ZERO(ptr: mtk->uwk); |
419 | } |
420 | |
421 | static void usb_wakeup_set(struct xhci_hcd_mtk *mtk, bool enable) |
422 | { |
423 | if (mtk->uwk_en) |
424 | usb_wakeup_ip_sleep_set(mtk, enable); |
425 | } |
426 | |
427 | static int xhci_mtk_clks_get(struct xhci_hcd_mtk *mtk) |
428 | { |
429 | struct clk_bulk_data *clks = mtk->clks; |
430 | |
431 | clks[0].id = "sys_ck" ; |
432 | clks[1].id = "xhci_ck" ; |
433 | clks[2].id = "ref_ck" ; |
434 | clks[3].id = "mcu_ck" ; |
435 | clks[4].id = "dma_ck" ; |
436 | clks[5].id = "frmcnt_ck" ; |
437 | |
438 | return devm_clk_bulk_get_optional(dev: mtk->dev, BULK_CLKS_NUM, clks); |
439 | } |
440 | |
441 | static int xhci_mtk_vregs_get(struct xhci_hcd_mtk *mtk) |
442 | { |
443 | struct regulator_bulk_data *supplies = mtk->supplies; |
444 | |
445 | supplies[0].supply = "vbus" ; |
446 | supplies[1].supply = "vusb33" ; |
447 | |
448 | return devm_regulator_bulk_get(dev: mtk->dev, BULK_VREGS_NUM, consumers: supplies); |
449 | } |
450 | |
451 | static void xhci_mtk_quirks(struct device *dev, struct xhci_hcd *xhci) |
452 | { |
453 | struct usb_hcd *hcd = xhci_to_hcd(xhci); |
454 | struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd); |
455 | |
456 | xhci->quirks |= XHCI_MTK_HOST; |
457 | /* |
458 | * MTK host controller gives a spurious successful event after a |
459 | * short transfer. Ignore it. |
460 | */ |
461 | xhci->quirks |= XHCI_SPURIOUS_SUCCESS; |
462 | if (mtk->lpm_support) |
463 | xhci->quirks |= XHCI_LPM_SUPPORT; |
464 | if (mtk->u2_lpm_disable) |
465 | xhci->quirks |= XHCI_HW_LPM_DISABLE; |
466 | |
467 | /* |
468 | * MTK xHCI 0.96: PSA is 1 by default even if doesn't support stream, |
469 | * and it's 3 when support it. |
470 | */ |
471 | if (xhci->hci_version < 0x100 && HCC_MAX_PSA(xhci->hcc_params) == 4) |
472 | xhci->quirks |= XHCI_BROKEN_STREAMS; |
473 | } |
474 | |
475 | /* called during probe() after chip reset completes */ |
476 | static int xhci_mtk_setup(struct usb_hcd *hcd) |
477 | { |
478 | struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd); |
479 | int ret; |
480 | |
481 | if (usb_hcd_is_primary_hcd(hcd)) { |
482 | ret = xhci_mtk_ssusb_config(mtk); |
483 | if (ret) |
484 | return ret; |
485 | |
486 | xhci_mtk_init_quirk(mtk); |
487 | } |
488 | |
489 | ret = xhci_gen_setup(hcd, get_quirks: xhci_mtk_quirks); |
490 | if (ret) |
491 | return ret; |
492 | |
493 | if (usb_hcd_is_primary_hcd(hcd)) |
494 | ret = xhci_mtk_sch_init(mtk); |
495 | |
496 | return ret; |
497 | } |
498 | |
499 | static const struct xhci_driver_overrides xhci_mtk_overrides __initconst = { |
500 | .reset = xhci_mtk_setup, |
501 | .add_endpoint = xhci_mtk_add_ep, |
502 | .drop_endpoint = xhci_mtk_drop_ep, |
503 | .check_bandwidth = xhci_mtk_check_bandwidth, |
504 | .reset_bandwidth = xhci_mtk_reset_bandwidth, |
505 | }; |
506 | |
507 | static struct hc_driver __read_mostly xhci_mtk_hc_driver; |
508 | |
509 | static int xhci_mtk_probe(struct platform_device *pdev) |
510 | { |
511 | struct device *dev = &pdev->dev; |
512 | struct device_node *node = dev->of_node; |
513 | struct xhci_hcd_mtk *mtk; |
514 | const struct hc_driver *driver; |
515 | struct xhci_hcd *xhci; |
516 | struct resource *res; |
517 | struct usb_hcd *usb3_hcd; |
518 | struct usb_hcd *hcd; |
519 | int ret = -ENODEV; |
520 | int wakeup_irq; |
521 | int irq; |
522 | |
523 | if (usb_disabled()) |
524 | return -ENODEV; |
525 | |
526 | driver = &xhci_mtk_hc_driver; |
527 | mtk = devm_kzalloc(dev, size: sizeof(*mtk), GFP_KERNEL); |
528 | if (!mtk) |
529 | return -ENOMEM; |
530 | |
531 | mtk->dev = dev; |
532 | |
533 | ret = xhci_mtk_vregs_get(mtk); |
534 | if (ret) |
535 | return dev_err_probe(dev, err: ret, fmt: "Failed to get regulators\n" ); |
536 | |
537 | ret = xhci_mtk_clks_get(mtk); |
538 | if (ret) |
539 | return ret; |
540 | |
541 | irq = platform_get_irq_byname_optional(dev: pdev, name: "host" ); |
542 | if (irq < 0) { |
543 | if (irq == -EPROBE_DEFER) |
544 | return irq; |
545 | |
546 | /* for backward compatibility */ |
547 | irq = platform_get_irq(pdev, 0); |
548 | if (irq < 0) |
549 | return irq; |
550 | } |
551 | |
552 | wakeup_irq = platform_get_irq_byname_optional(dev: pdev, name: "wakeup" ); |
553 | if (wakeup_irq == -EPROBE_DEFER) |
554 | return wakeup_irq; |
555 | |
556 | mtk->lpm_support = of_property_read_bool(np: node, propname: "usb3-lpm-capable" ); |
557 | mtk->u2_lpm_disable = of_property_read_bool(np: node, propname: "usb2-lpm-disable" ); |
558 | /* optional property, ignore the error if it does not exist */ |
559 | of_property_read_u32(np: node, propname: "mediatek,u3p-dis-msk" , |
560 | out_value: &mtk->u3p_dis_msk); |
561 | of_property_read_u32(np: node, propname: "mediatek,u2p-dis-msk" , |
562 | out_value: &mtk->u2p_dis_msk); |
563 | |
564 | of_property_read_u32(np: node, propname: "rx-fifo-depth" , out_value: &mtk->rxfifo_depth); |
565 | |
566 | ret = usb_wakeup_of_property_parse(mtk, dn: node); |
567 | if (ret) { |
568 | dev_err(dev, "failed to parse uwk property\n" ); |
569 | return ret; |
570 | } |
571 | |
572 | pm_runtime_set_active(dev); |
573 | pm_runtime_use_autosuspend(dev); |
574 | pm_runtime_set_autosuspend_delay(dev, delay: 4000); |
575 | pm_runtime_enable(dev); |
576 | pm_runtime_get_sync(dev); |
577 | |
578 | ret = regulator_bulk_enable(BULK_VREGS_NUM, consumers: mtk->supplies); |
579 | if (ret) |
580 | goto disable_pm; |
581 | |
582 | ret = clk_bulk_prepare_enable(BULK_CLKS_NUM, clks: mtk->clks); |
583 | if (ret) |
584 | goto disable_ldos; |
585 | |
586 | ret = device_reset_optional(dev); |
587 | if (ret) { |
588 | dev_err_probe(dev, err: ret, fmt: "failed to reset controller\n" ); |
589 | goto disable_clk; |
590 | } |
591 | |
592 | hcd = usb_create_hcd(driver, dev, bus_name: dev_name(dev)); |
593 | if (!hcd) { |
594 | ret = -ENOMEM; |
595 | goto disable_clk; |
596 | } |
597 | |
598 | /* |
599 | * USB 2.0 roothub is stored in the platform_device. |
600 | * Swap it with mtk HCD. |
601 | */ |
602 | mtk->hcd = platform_get_drvdata(pdev); |
603 | platform_set_drvdata(pdev, data: mtk); |
604 | |
605 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mac" ); |
606 | hcd->regs = devm_ioremap_resource(dev, res); |
607 | if (IS_ERR(ptr: hcd->regs)) { |
608 | ret = PTR_ERR(ptr: hcd->regs); |
609 | goto put_usb2_hcd; |
610 | } |
611 | hcd->rsrc_start = res->start; |
612 | hcd->rsrc_len = resource_size(res); |
613 | |
614 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ippc" ); |
615 | if (res) { /* ippc register is optional */ |
616 | mtk->ippc_regs = devm_ioremap_resource(dev, res); |
617 | if (IS_ERR(ptr: mtk->ippc_regs)) { |
618 | ret = PTR_ERR(ptr: mtk->ippc_regs); |
619 | goto put_usb2_hcd; |
620 | } |
621 | mtk->has_ippc = true; |
622 | } |
623 | |
624 | device_init_wakeup(dev, enable: true); |
625 | dma_set_max_seg_size(dev, UINT_MAX); |
626 | |
627 | xhci = hcd_to_xhci(hcd); |
628 | xhci->main_hcd = hcd; |
629 | xhci->allow_single_roothub = 1; |
630 | |
631 | /* |
632 | * imod_interval is the interrupt moderation value in nanoseconds. |
633 | * The increment interval is 8 times as much as that defined in |
634 | * the xHCI spec on MTK's controller. |
635 | */ |
636 | xhci->imod_interval = 5000; |
637 | device_property_read_u32(dev, propname: "imod-interval-ns" , val: &xhci->imod_interval); |
638 | |
639 | ret = usb_add_hcd(hcd, irqnum: irq, IRQF_SHARED); |
640 | if (ret) |
641 | goto disable_device_wakeup; |
642 | |
643 | if (!xhci_has_one_roothub(xhci)) { |
644 | xhci->shared_hcd = usb_create_shared_hcd(driver, dev, |
645 | bus_name: dev_name(dev), shared_hcd: hcd); |
646 | if (!xhci->shared_hcd) { |
647 | ret = -ENOMEM; |
648 | goto dealloc_usb2_hcd; |
649 | } |
650 | } |
651 | |
652 | usb3_hcd = xhci_get_usb3_hcd(xhci); |
653 | if (usb3_hcd && HCC_MAX_PSA(xhci->hcc_params) >= 4 && |
654 | !(xhci->quirks & XHCI_BROKEN_STREAMS)) |
655 | usb3_hcd->can_do_streams = 1; |
656 | |
657 | if (xhci->shared_hcd) { |
658 | ret = usb_add_hcd(hcd: xhci->shared_hcd, irqnum: irq, IRQF_SHARED); |
659 | if (ret) |
660 | goto put_usb3_hcd; |
661 | } |
662 | |
663 | if (wakeup_irq > 0) { |
664 | ret = dev_pm_set_dedicated_wake_irq_reverse(dev, irq: wakeup_irq); |
665 | if (ret) { |
666 | dev_err(dev, "set wakeup irq %d failed\n" , wakeup_irq); |
667 | goto dealloc_usb3_hcd; |
668 | } |
669 | dev_info(dev, "wakeup irq %d\n" , wakeup_irq); |
670 | } |
671 | |
672 | device_enable_async_suspend(dev); |
673 | pm_runtime_mark_last_busy(dev); |
674 | pm_runtime_put_autosuspend(dev); |
675 | pm_runtime_forbid(dev); |
676 | |
677 | return 0; |
678 | |
679 | dealloc_usb3_hcd: |
680 | usb_remove_hcd(hcd: xhci->shared_hcd); |
681 | |
682 | put_usb3_hcd: |
683 | usb_put_hcd(hcd: xhci->shared_hcd); |
684 | |
685 | dealloc_usb2_hcd: |
686 | xhci_mtk_sch_exit(mtk); |
687 | usb_remove_hcd(hcd); |
688 | |
689 | disable_device_wakeup: |
690 | device_init_wakeup(dev, enable: false); |
691 | |
692 | put_usb2_hcd: |
693 | usb_put_hcd(hcd); |
694 | |
695 | disable_clk: |
696 | clk_bulk_disable_unprepare(BULK_CLKS_NUM, clks: mtk->clks); |
697 | |
698 | disable_ldos: |
699 | regulator_bulk_disable(BULK_VREGS_NUM, consumers: mtk->supplies); |
700 | |
701 | disable_pm: |
702 | pm_runtime_put_noidle(dev); |
703 | pm_runtime_disable(dev); |
704 | return ret; |
705 | } |
706 | |
707 | static void xhci_mtk_remove(struct platform_device *pdev) |
708 | { |
709 | struct xhci_hcd_mtk *mtk = platform_get_drvdata(pdev); |
710 | struct usb_hcd *hcd = mtk->hcd; |
711 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); |
712 | struct usb_hcd *shared_hcd = xhci->shared_hcd; |
713 | struct device *dev = &pdev->dev; |
714 | |
715 | pm_runtime_get_sync(dev); |
716 | xhci->xhc_state |= XHCI_STATE_REMOVING; |
717 | dev_pm_clear_wake_irq(dev); |
718 | device_init_wakeup(dev, enable: false); |
719 | |
720 | if (shared_hcd) { |
721 | usb_remove_hcd(hcd: shared_hcd); |
722 | xhci->shared_hcd = NULL; |
723 | } |
724 | usb_remove_hcd(hcd); |
725 | |
726 | if (shared_hcd) |
727 | usb_put_hcd(hcd: shared_hcd); |
728 | |
729 | usb_put_hcd(hcd); |
730 | xhci_mtk_sch_exit(mtk); |
731 | clk_bulk_disable_unprepare(BULK_CLKS_NUM, clks: mtk->clks); |
732 | regulator_bulk_disable(BULK_VREGS_NUM, consumers: mtk->supplies); |
733 | |
734 | pm_runtime_disable(dev); |
735 | pm_runtime_put_noidle(dev); |
736 | pm_runtime_set_suspended(dev); |
737 | } |
738 | |
739 | static int __maybe_unused xhci_mtk_suspend(struct device *dev) |
740 | { |
741 | struct xhci_hcd_mtk *mtk = dev_get_drvdata(dev); |
742 | struct usb_hcd *hcd = mtk->hcd; |
743 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); |
744 | struct usb_hcd *shared_hcd = xhci->shared_hcd; |
745 | int ret; |
746 | |
747 | xhci_dbg(xhci, "%s: stop port polling\n" , __func__); |
748 | clear_bit(HCD_FLAG_POLL_RH, addr: &hcd->flags); |
749 | del_timer_sync(timer: &hcd->rh_timer); |
750 | if (shared_hcd) { |
751 | clear_bit(HCD_FLAG_POLL_RH, addr: &shared_hcd->flags); |
752 | del_timer_sync(timer: &shared_hcd->rh_timer); |
753 | } |
754 | |
755 | ret = xhci_mtk_host_disable(mtk); |
756 | if (ret) |
757 | goto restart_poll_rh; |
758 | |
759 | clk_bulk_disable_unprepare(BULK_CLKS_NUM, clks: mtk->clks); |
760 | usb_wakeup_set(mtk, enable: true); |
761 | return 0; |
762 | |
763 | restart_poll_rh: |
764 | xhci_dbg(xhci, "%s: restart port polling\n" , __func__); |
765 | if (shared_hcd) { |
766 | set_bit(HCD_FLAG_POLL_RH, addr: &shared_hcd->flags); |
767 | usb_hcd_poll_rh_status(hcd: shared_hcd); |
768 | } |
769 | set_bit(HCD_FLAG_POLL_RH, addr: &hcd->flags); |
770 | usb_hcd_poll_rh_status(hcd); |
771 | return ret; |
772 | } |
773 | |
774 | static int __maybe_unused xhci_mtk_resume(struct device *dev) |
775 | { |
776 | struct xhci_hcd_mtk *mtk = dev_get_drvdata(dev); |
777 | struct usb_hcd *hcd = mtk->hcd; |
778 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); |
779 | struct usb_hcd *shared_hcd = xhci->shared_hcd; |
780 | int ret; |
781 | |
782 | usb_wakeup_set(mtk, enable: false); |
783 | ret = clk_bulk_prepare_enable(BULK_CLKS_NUM, clks: mtk->clks); |
784 | if (ret) |
785 | goto enable_wakeup; |
786 | |
787 | ret = xhci_mtk_host_enable(mtk); |
788 | if (ret) |
789 | goto disable_clks; |
790 | |
791 | xhci_dbg(xhci, "%s: restart port polling\n" , __func__); |
792 | if (shared_hcd) { |
793 | set_bit(HCD_FLAG_POLL_RH, addr: &shared_hcd->flags); |
794 | usb_hcd_poll_rh_status(hcd: shared_hcd); |
795 | } |
796 | set_bit(HCD_FLAG_POLL_RH, addr: &hcd->flags); |
797 | usb_hcd_poll_rh_status(hcd); |
798 | return 0; |
799 | |
800 | disable_clks: |
801 | clk_bulk_disable_unprepare(BULK_CLKS_NUM, clks: mtk->clks); |
802 | enable_wakeup: |
803 | usb_wakeup_set(mtk, enable: true); |
804 | return ret; |
805 | } |
806 | |
807 | static int __maybe_unused xhci_mtk_runtime_suspend(struct device *dev) |
808 | { |
809 | struct xhci_hcd_mtk *mtk = dev_get_drvdata(dev); |
810 | struct xhci_hcd *xhci = hcd_to_xhci(hcd: mtk->hcd); |
811 | int ret = 0; |
812 | |
813 | if (xhci->xhc_state) |
814 | return -ESHUTDOWN; |
815 | |
816 | if (device_may_wakeup(dev)) |
817 | ret = xhci_mtk_suspend(dev); |
818 | |
819 | /* -EBUSY: let PM automatically reschedule another autosuspend */ |
820 | return ret ? -EBUSY : 0; |
821 | } |
822 | |
823 | static int __maybe_unused xhci_mtk_runtime_resume(struct device *dev) |
824 | { |
825 | struct xhci_hcd_mtk *mtk = dev_get_drvdata(dev); |
826 | struct xhci_hcd *xhci = hcd_to_xhci(hcd: mtk->hcd); |
827 | int ret = 0; |
828 | |
829 | if (xhci->xhc_state) |
830 | return -ESHUTDOWN; |
831 | |
832 | if (device_may_wakeup(dev)) |
833 | ret = xhci_mtk_resume(dev); |
834 | |
835 | return ret; |
836 | } |
837 | |
838 | static const struct dev_pm_ops xhci_mtk_pm_ops = { |
839 | SET_SYSTEM_SLEEP_PM_OPS(xhci_mtk_suspend, xhci_mtk_resume) |
840 | SET_RUNTIME_PM_OPS(xhci_mtk_runtime_suspend, |
841 | xhci_mtk_runtime_resume, NULL) |
842 | }; |
843 | |
844 | #define DEV_PM_OPS (IS_ENABLED(CONFIG_PM) ? &xhci_mtk_pm_ops : NULL) |
845 | |
846 | static const struct of_device_id mtk_xhci_of_match[] = { |
847 | { .compatible = "mediatek,mt8173-xhci" }, |
848 | { .compatible = "mediatek,mt8195-xhci" }, |
849 | { .compatible = "mediatek,mtk-xhci" }, |
850 | { }, |
851 | }; |
852 | MODULE_DEVICE_TABLE(of, mtk_xhci_of_match); |
853 | |
854 | static struct platform_driver mtk_xhci_driver = { |
855 | .probe = xhci_mtk_probe, |
856 | .remove_new = xhci_mtk_remove, |
857 | .driver = { |
858 | .name = "xhci-mtk" , |
859 | .pm = DEV_PM_OPS, |
860 | .of_match_table = mtk_xhci_of_match, |
861 | }, |
862 | }; |
863 | |
864 | static int __init xhci_mtk_init(void) |
865 | { |
866 | xhci_init_driver(drv: &xhci_mtk_hc_driver, over: &xhci_mtk_overrides); |
867 | return platform_driver_register(&mtk_xhci_driver); |
868 | } |
869 | module_init(xhci_mtk_init); |
870 | |
871 | static void __exit xhci_mtk_exit(void) |
872 | { |
873 | platform_driver_unregister(&mtk_xhci_driver); |
874 | } |
875 | module_exit(xhci_mtk_exit); |
876 | |
877 | MODULE_AUTHOR("Chunfeng Yun <chunfeng.yun@mediatek.com>" ); |
878 | MODULE_DESCRIPTION("MediaTek xHCI Host Controller Driver" ); |
879 | MODULE_LICENSE("GPL v2" ); |
880 | |