Merge tag 'x86-urgent-2024-03-24' of git://git.kernel.org/pub/scm/linux/kernel/git...
[sfrench/cifs-2.6.git] / drivers / usb / mtu3 / mtu3_host.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * mtu3_dr.c - dual role switch and host glue layer
4  *
5  * Copyright (C) 2016 MediaTek Inc.
6  *
7  * Author: Chunfeng Yun <chunfeng.yun@mediatek.com>
8  */
9
10 #include <linux/clk.h>
11 #include <linux/irq.h>
12 #include <linux/kernel.h>
13 #include <linux/mfd/syscon.h>
14 #include <linux/of.h>
15 #include <linux/of_platform.h>
16 #include <linux/regmap.h>
17
18 #include "mtu3.h"
19 #include "mtu3_dr.h"
20
21 /* mt8173 etc */
22 #define PERI_WK_CTRL1   0x4
23 #define WC1_IS_C(x)     (((x) & 0xf) << 26)  /* cycle debounce */
24 #define WC1_IS_EN       BIT(25)
25 #define WC1_IS_P        BIT(6)  /* polarity for ip sleep */
26
27 /* mt8183 */
28 #define PERI_WK_CTRL0   0x0
29 #define WC0_IS_C(x)     ((u32)(((x) & 0xf) << 28))  /* cycle debounce */
30 #define WC0_IS_P        BIT(12) /* polarity */
31 #define WC0_IS_EN       BIT(6)
32
33 /* mt8192 */
34 #define WC0_SSUSB0_CDEN         BIT(6)
35 #define WC0_IS_SPM_EN           BIT(1)
36
37 /* mt8195 */
38 #define PERI_WK_CTRL0_8195      0x04
39 #define WC0_IS_P_95             BIT(30) /* polarity */
40 #define WC0_IS_C_95(x)          ((u32)(((x) & 0x7) << 27))
41 #define WC0_IS_EN_P3_95         BIT(26)
42 #define WC0_IS_EN_P2_95         BIT(25)
43
44 #define PERI_WK_CTRL1_8195      0x20
45 #define WC1_IS_C_95(x)          ((u32)(((x) & 0xf) << 28))
46 #define WC1_IS_P_95             BIT(12)
47 #define WC1_IS_EN_P0_95         BIT(6)
48
49 /* mt2712 etc */
50 #define PERI_SSUSB_SPM_CTRL     0x0
51 #define SSC_IP_SLEEP_EN BIT(4)
52 #define SSC_SPM_INT_EN          BIT(1)
53
54 enum ssusb_uwk_vers {
55         SSUSB_UWK_V1 = 1,
56         SSUSB_UWK_V2,
57         SSUSB_UWK_V1_1 = 101,   /* specific revision 1.01 */
58         SSUSB_UWK_V1_2,         /* specific revision 1.02 */
59         SSUSB_UWK_V1_3,         /* mt8195 IP0 */
60         SSUSB_UWK_V1_5 = 105,   /* mt8195 IP2 */
61         SSUSB_UWK_V1_6,         /* mt8195 IP3 */
62 };
63
64 /*
65  * ip-sleep wakeup mode:
66  * all clocks can be turn off, but power domain should be kept on
67  */
68 static void ssusb_wakeup_ip_sleep_set(struct ssusb_mtk *ssusb, bool enable)
69 {
70         u32 reg, msk, val;
71
72         switch (ssusb->uwk_vers) {
73         case SSUSB_UWK_V1:
74                 reg = ssusb->uwk_reg_base + PERI_WK_CTRL1;
75                 msk = WC1_IS_EN | WC1_IS_C(0xf) | WC1_IS_P;
76                 val = enable ? (WC1_IS_EN | WC1_IS_C(0x8)) : 0;
77                 break;
78         case SSUSB_UWK_V1_1:
79                 reg = ssusb->uwk_reg_base + PERI_WK_CTRL0;
80                 msk = WC0_IS_EN | WC0_IS_C(0xf) | WC0_IS_P;
81                 val = enable ? (WC0_IS_EN | WC0_IS_C(0x1)) : 0;
82                 break;
83         case SSUSB_UWK_V1_2:
84                 reg = ssusb->uwk_reg_base + PERI_WK_CTRL0;
85                 msk = WC0_SSUSB0_CDEN | WC0_IS_SPM_EN;
86                 val = enable ? msk : 0;
87                 break;
88         case SSUSB_UWK_V1_3:
89                 reg = ssusb->uwk_reg_base + PERI_WK_CTRL1_8195;
90                 msk = WC1_IS_EN_P0_95 | WC1_IS_C_95(0xf) | WC1_IS_P_95;
91                 val = enable ? (WC1_IS_EN_P0_95 | WC1_IS_C_95(0x1)) : 0;
92                 break;
93         case SSUSB_UWK_V1_5:
94                 reg = ssusb->uwk_reg_base + PERI_WK_CTRL0_8195;
95                 msk = WC0_IS_EN_P2_95 | WC0_IS_C_95(0x7) | WC0_IS_P_95;
96                 val = enable ? (WC0_IS_EN_P2_95 | WC0_IS_C_95(0x1)) : 0;
97                 break;
98         case SSUSB_UWK_V1_6:
99                 reg = ssusb->uwk_reg_base + PERI_WK_CTRL0_8195;
100                 msk = WC0_IS_EN_P3_95 | WC0_IS_C_95(0x7) | WC0_IS_P_95;
101                 val = enable ? (WC0_IS_EN_P3_95 | WC0_IS_C_95(0x1)) : 0;
102                 break;
103         case SSUSB_UWK_V2:
104                 reg = ssusb->uwk_reg_base + PERI_SSUSB_SPM_CTRL;
105                 msk = SSC_IP_SLEEP_EN | SSC_SPM_INT_EN;
106                 val = enable ? msk : 0;
107                 break;
108         default:
109                 return;
110         }
111         regmap_update_bits(ssusb->uwk, reg, msk, val);
112 }
113
114 int ssusb_wakeup_of_property_parse(struct ssusb_mtk *ssusb,
115                                 struct device_node *dn)
116 {
117         struct of_phandle_args args;
118         int ret;
119
120         /* wakeup function is optional */
121         ssusb->uwk_en = of_property_read_bool(dn, "wakeup-source");
122         if (!ssusb->uwk_en)
123                 return 0;
124
125         ret = of_parse_phandle_with_fixed_args(dn,
126                                 "mediatek,syscon-wakeup", 2, 0, &args);
127         if (ret)
128                 return ret;
129
130         ssusb->uwk_reg_base = args.args[0];
131         ssusb->uwk_vers = args.args[1];
132         ssusb->uwk = syscon_node_to_regmap(args.np);
133         of_node_put(args.np);
134         dev_info(ssusb->dev, "uwk - reg:0x%x, version:%d\n",
135                         ssusb->uwk_reg_base, ssusb->uwk_vers);
136
137         return PTR_ERR_OR_ZERO(ssusb->uwk);
138 }
139
140 void ssusb_wakeup_set(struct ssusb_mtk *ssusb, bool enable)
141 {
142         if (ssusb->uwk_en)
143                 ssusb_wakeup_ip_sleep_set(ssusb, enable);
144 }
145
146 static void host_ports_num_get(struct ssusb_mtk *ssusb)
147 {
148         u32 xhci_cap;
149
150         xhci_cap = mtu3_readl(ssusb->ippc_base, U3D_SSUSB_IP_XHCI_CAP);
151         ssusb->u2_ports = SSUSB_IP_XHCI_U2_PORT_NUM(xhci_cap);
152         ssusb->u3_ports = SSUSB_IP_XHCI_U3_PORT_NUM(xhci_cap);
153
154         dev_dbg(ssusb->dev, "host - u2_ports:%d, u3_ports:%d\n",
155                  ssusb->u2_ports, ssusb->u3_ports);
156 }
157
158 /* only configure ports will be used later */
159 static int ssusb_host_enable(struct ssusb_mtk *ssusb)
160 {
161         void __iomem *ibase = ssusb->ippc_base;
162         int num_u3p = ssusb->u3_ports;
163         int num_u2p = ssusb->u2_ports;
164         int u3_ports_disabled;
165         u32 check_clk;
166         u32 value;
167         int i;
168
169         /* power on host ip */
170         mtu3_clrbits(ibase, U3D_SSUSB_IP_PW_CTRL1, SSUSB_IP_HOST_PDN);
171
172         /* power on and enable u3 ports except skipped ones */
173         u3_ports_disabled = 0;
174         for (i = 0; i < num_u3p; i++) {
175                 if ((0x1 << i) & ssusb->u3p_dis_msk) {
176                         u3_ports_disabled++;
177                         continue;
178                 }
179
180                 value = mtu3_readl(ibase, SSUSB_U3_CTRL(i));
181                 value &= ~(SSUSB_U3_PORT_PDN | SSUSB_U3_PORT_DIS);
182                 value |= SSUSB_U3_PORT_HOST_SEL;
183                 mtu3_writel(ibase, SSUSB_U3_CTRL(i), value);
184         }
185
186         /* power on and enable all u2 ports */
187         for (i = 0; i < num_u2p; i++) {
188                 if ((0x1 << i) & ssusb->u2p_dis_msk)
189                         continue;
190
191                 value = mtu3_readl(ibase, SSUSB_U2_CTRL(i));
192                 value &= ~(SSUSB_U2_PORT_PDN | SSUSB_U2_PORT_DIS);
193                 value |= SSUSB_U2_PORT_HOST_SEL;
194                 mtu3_writel(ibase, SSUSB_U2_CTRL(i), value);
195         }
196
197         check_clk = SSUSB_XHCI_RST_B_STS;
198         if (num_u3p > u3_ports_disabled)
199                 check_clk = SSUSB_U3_MAC_RST_B_STS;
200
201         return ssusb_check_clocks(ssusb, check_clk);
202 }
203
204 static int ssusb_host_disable(struct ssusb_mtk *ssusb)
205 {
206         void __iomem *ibase = ssusb->ippc_base;
207         int num_u3p = ssusb->u3_ports;
208         int num_u2p = ssusb->u2_ports;
209         u32 value;
210         int i;
211
212         /* power down and disable u3 ports except skipped ones */
213         for (i = 0; i < num_u3p; i++) {
214                 if ((0x1 << i) & ssusb->u3p_dis_msk)
215                         continue;
216
217                 value = mtu3_readl(ibase, SSUSB_U3_CTRL(i));
218                 value |= SSUSB_U3_PORT_PDN | SSUSB_U3_PORT_DIS;
219                 mtu3_writel(ibase, SSUSB_U3_CTRL(i), value);
220         }
221
222         /* power down and disable u2 ports except skipped ones */
223         for (i = 0; i < num_u2p; i++) {
224                 if ((0x1 << i) & ssusb->u2p_dis_msk)
225                         continue;
226
227                 value = mtu3_readl(ibase, SSUSB_U2_CTRL(i));
228                 value |= SSUSB_U2_PORT_PDN | SSUSB_U2_PORT_DIS;
229                 mtu3_writel(ibase, SSUSB_U2_CTRL(i), value);
230         }
231
232         /* power down host ip */
233         mtu3_setbits(ibase, U3D_SSUSB_IP_PW_CTRL1, SSUSB_IP_HOST_PDN);
234
235         return 0;
236 }
237
238 int ssusb_host_resume(struct ssusb_mtk *ssusb, bool p0_skipped)
239 {
240         void __iomem *ibase = ssusb->ippc_base;
241         int u3p_skip_msk = ssusb->u3p_dis_msk;
242         int u2p_skip_msk = ssusb->u2p_dis_msk;
243         int num_u3p = ssusb->u3_ports;
244         int num_u2p = ssusb->u2_ports;
245         u32 value;
246         int i;
247
248         if (p0_skipped) {
249                 u2p_skip_msk |= 0x1;
250                 if (ssusb->otg_switch.is_u3_drd)
251                         u3p_skip_msk |= 0x1;
252         }
253
254         /* power on host ip */
255         mtu3_clrbits(ibase, U3D_SSUSB_IP_PW_CTRL1, SSUSB_IP_HOST_PDN);
256
257         /* power on u3 ports except skipped ones */
258         for (i = 0; i < num_u3p; i++) {
259                 if ((0x1 << i) & u3p_skip_msk)
260                         continue;
261
262                 value = mtu3_readl(ibase, SSUSB_U3_CTRL(i));
263                 value &= ~SSUSB_U3_PORT_PDN;
264                 mtu3_writel(ibase, SSUSB_U3_CTRL(i), value);
265         }
266
267         /* power on all u2 ports except skipped ones */
268         for (i = 0; i < num_u2p; i++) {
269                 if ((0x1 << i) & u2p_skip_msk)
270                         continue;
271
272                 value = mtu3_readl(ibase, SSUSB_U2_CTRL(i));
273                 value &= ~SSUSB_U2_PORT_PDN;
274                 mtu3_writel(ibase, SSUSB_U2_CTRL(i), value);
275         }
276
277         return 0;
278 }
279
280 /* here not skip port0 due to PDN can be set repeatedly */
281 int ssusb_host_suspend(struct ssusb_mtk *ssusb)
282 {
283         void __iomem *ibase = ssusb->ippc_base;
284         int num_u3p = ssusb->u3_ports;
285         int num_u2p = ssusb->u2_ports;
286         u32 value;
287         int i;
288
289         /* power down u3 ports except skipped ones */
290         for (i = 0; i < num_u3p; i++) {
291                 if ((0x1 << i) & ssusb->u3p_dis_msk)
292                         continue;
293
294                 value = mtu3_readl(ibase, SSUSB_U3_CTRL(i));
295                 value |= SSUSB_U3_PORT_PDN;
296                 mtu3_writel(ibase, SSUSB_U3_CTRL(i), value);
297         }
298
299         /* power down u2 ports except skipped ones */
300         for (i = 0; i < num_u2p; i++) {
301                 if ((0x1 << i) & ssusb->u2p_dis_msk)
302                         continue;
303
304                 value = mtu3_readl(ibase, SSUSB_U2_CTRL(i));
305                 value |= SSUSB_U2_PORT_PDN;
306                 mtu3_writel(ibase, SSUSB_U2_CTRL(i), value);
307         }
308
309         /* power down host ip */
310         mtu3_setbits(ibase, U3D_SSUSB_IP_PW_CTRL1, SSUSB_IP_HOST_PDN);
311
312         return 0;
313 }
314
315 static void ssusb_host_setup(struct ssusb_mtk *ssusb)
316 {
317         host_ports_num_get(ssusb);
318
319         /*
320          * power on host and power on/enable all ports
321          * if support OTG, gadget driver will switch port0 to device mode
322          */
323         ssusb_host_enable(ssusb);
324         ssusb_set_force_mode(ssusb, MTU3_DR_FORCE_HOST);
325
326         /* if port0 supports dual-role, works as host mode by default */
327         ssusb_set_vbus(&ssusb->otg_switch, 1);
328 }
329
330 static void ssusb_host_cleanup(struct ssusb_mtk *ssusb)
331 {
332         if (ssusb->is_host)
333                 ssusb_set_vbus(&ssusb->otg_switch, 0);
334
335         ssusb_host_disable(ssusb);
336 }
337
338 /*
339  * If host supports multiple ports, the VBUSes(5V) of ports except port0
340  * which supports OTG are better to be enabled by default in DTS.
341  * Because the host driver will keep link with devices attached when system
342  * enters suspend mode, so no need to control VBUSes after initialization.
343  */
344 int ssusb_host_init(struct ssusb_mtk *ssusb, struct device_node *parent_dn)
345 {
346         struct device *parent_dev = ssusb->dev;
347         int ret;
348
349         ssusb_host_setup(ssusb);
350
351         ret = of_platform_populate(parent_dn, NULL, NULL, parent_dev);
352         if (ret) {
353                 dev_dbg(parent_dev, "failed to create child devices at %pOF\n",
354                                 parent_dn);
355                 return ret;
356         }
357
358         dev_info(parent_dev, "xHCI platform device register success...\n");
359
360         return 0;
361 }
362
363 void ssusb_host_exit(struct ssusb_mtk *ssusb)
364 {
365         of_platform_depopulate(ssusb->dev);
366         ssusb_host_cleanup(ssusb);
367 }