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