Rename SPL_USB_HOST_SUPPORT to SPL_USB_HOST
[platform/kernel/u-boot.git] / drivers / usb / mtu3 / mtu3_plat.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2016 MediaTek Inc.
4  *
5  * Author: Chunfeng Yun <chunfeng.yun@mediatek.com>
6  */
7
8 #include <common.h>
9 #include <dm/lists.h>
10 #include <linux/iopoll.h>
11
12 #include "mtu3.h"
13 #include "mtu3_dr.h"
14
15 void ssusb_set_force_mode(struct ssusb_mtk *ssusb,
16                           enum mtu3_dr_force_mode mode)
17 {
18         u32 value;
19
20         value = mtu3_readl(ssusb->ippc_base, SSUSB_U2_CTRL(0));
21         switch (mode) {
22         case MTU3_DR_FORCE_DEVICE:
23                 value |= SSUSB_U2_PORT_FORCE_IDDIG | SSUSB_U2_PORT_RG_IDDIG;
24                 break;
25         case MTU3_DR_FORCE_HOST:
26                 value |= SSUSB_U2_PORT_FORCE_IDDIG;
27                 value &= ~SSUSB_U2_PORT_RG_IDDIG;
28                 break;
29         case MTU3_DR_FORCE_NONE:
30                 value &= ~(SSUSB_U2_PORT_FORCE_IDDIG | SSUSB_U2_PORT_RG_IDDIG);
31                 break;
32         default:
33                 return;
34         }
35         mtu3_writel(ssusb->ippc_base, SSUSB_U2_CTRL(0), value);
36 }
37
38 /* u2-port0 should be powered on and enabled; */
39 int ssusb_check_clocks(struct ssusb_mtk *ssusb, u32 ex_clks)
40 {
41         void __iomem *ibase = ssusb->ippc_base;
42         u32 value, check_val;
43         int ret;
44
45         check_val = ex_clks | SSUSB_SYS125_RST_B_STS | SSUSB_SYSPLL_STABLE |
46                         SSUSB_REF_RST_B_STS;
47
48         ret = readl_poll_timeout(ibase + U3D_SSUSB_IP_PW_STS1, value,
49                                  ((value & check_val) == check_val), 10000);
50         if (ret) {
51                 dev_err(ssusb->dev, "clks of sts1 are not stable!\n");
52                 return ret;
53         }
54
55         ret = readl_poll_timeout(ibase + U3D_SSUSB_IP_PW_STS2, value,
56                                  (value & SSUSB_U2_MAC_SYS_RST_B_STS), 10000);
57         if (ret) {
58                 dev_err(ssusb->dev, "mac2 clock is not stable\n");
59                 return ret;
60         }
61
62         return 0;
63 }
64
65 int ssusb_phy_setup(struct ssusb_mtk *ssusb)
66 {
67         struct udevice *dev = ssusb->dev;
68         struct phy_bulk *phys = &ssusb->phys;
69         int ret;
70
71         ret = generic_phy_get_bulk(dev, phys);
72         if (ret)
73                 return ret;
74
75         ret = generic_phy_init_bulk(phys);
76         if (ret)
77                 return ret;
78
79         ret = generic_phy_power_on_bulk(phys);
80         if (ret)
81                 generic_phy_exit_bulk(phys);
82
83         return ret;
84 }
85
86 void ssusb_phy_shutdown(struct ssusb_mtk *ssusb)
87 {
88         generic_phy_power_off_bulk(&ssusb->phys);
89         generic_phy_exit_bulk(&ssusb->phys);
90 }
91
92 static int ssusb_rscs_init(struct ssusb_mtk *ssusb)
93 {
94         int ret = 0;
95
96         ret = regulator_set_enable(ssusb->vusb33_supply, true);
97         if (ret < 0 && ret != -ENOSYS) {
98                 dev_err(ssusb->dev, "failed to enable vusb33\n");
99                 goto vusb33_err;
100         }
101
102         ret = clk_enable_bulk(&ssusb->clks);
103         if (ret)
104                 goto clks_err;
105
106         ret = ssusb_phy_setup(ssusb);
107         if (ret) {
108                 dev_err(ssusb->dev, "failed to setup phy\n");
109                 goto phy_err;
110         }
111
112         return 0;
113
114 phy_err:
115         clk_disable_bulk(&ssusb->clks);
116 clks_err:
117         regulator_set_enable(ssusb->vusb33_supply, false);
118 vusb33_err:
119         return ret;
120 }
121
122 static void ssusb_rscs_exit(struct ssusb_mtk *ssusb)
123 {
124         clk_disable_bulk(&ssusb->clks);
125         regulator_set_enable(ssusb->vusb33_supply, false);
126         ssusb_phy_shutdown(ssusb);
127 }
128
129 static void ssusb_ip_sw_reset(struct ssusb_mtk *ssusb)
130 {
131         /* reset whole ip (xhci & u3d) */
132         mtu3_setbits(ssusb->ippc_base, U3D_SSUSB_IP_PW_CTRL0, SSUSB_IP_SW_RST);
133         udelay(1);
134         mtu3_clrbits(ssusb->ippc_base, U3D_SSUSB_IP_PW_CTRL0, SSUSB_IP_SW_RST);
135 }
136
137 static int get_ssusb_rscs(struct udevice *dev, struct ssusb_mtk *ssusb)
138 {
139         struct udevice *child;
140         int ret;
141
142         ret = device_get_supply_regulator(dev, "vusb33-supply",
143                                           &ssusb->vusb33_supply);
144         if (ret)        /* optional, ignore error */
145                 dev_warn(dev, "can't get optional vusb33 %d\n", ret);
146
147         ret = device_get_supply_regulator(dev, "vbus-supply",
148                                           &ssusb->vbus_supply);
149         if (ret)        /* optional, ignore error */
150                 dev_warn(dev, "can't get optional vbus regulator %d!\n", ret);
151
152         ret = clk_get_bulk(dev, &ssusb->clks);
153         if (ret) {
154                 dev_err(dev, "failed to get clocks %d!\n", ret);
155                 return ret;
156         }
157
158         ssusb->ippc_base = devfdt_remap_addr_name(dev, "ippc");
159         if (!ssusb->ippc_base) {
160                 dev_err(dev, "error mapping memory for ippc\n");
161                 return -ENODEV;
162         }
163
164         ret = device_find_first_child(dev, &child);
165         if (ret || !child) {
166                 dev_err(dev, "failed to get child %d!\n", ret);
167                 return ret;
168         }
169
170         ssusb->mac_base = devfdt_remap_addr_name(child, "mac");
171         if (!ssusb->mac_base) {
172                 dev_err(dev, "error mapping memory for mac\n");
173                 return -ENODEV;
174         }
175
176         ssusb->dr_mode = usb_get_dr_mode(dev_ofnode(child));
177
178         if (ssusb->dr_mode == USB_DR_MODE_UNKNOWN ||
179                 ssusb->dr_mode == USB_DR_MODE_OTG)
180                 ssusb->dr_mode = USB_DR_MODE_PERIPHERAL;
181
182         if (IS_ENABLED(CONFIG_USB_MTU3_GADGET))
183                 ssusb->dr_mode = USB_DR_MODE_PERIPHERAL;
184         else if (IS_ENABLED(CONFIG_USB_MTU3_HOST))
185                 ssusb->dr_mode = USB_DR_MODE_HOST;
186
187         dev_info(dev, "dr_mode: %d, ippc: 0x%p, mac: 0x%p\n",
188                  ssusb->dr_mode, ssusb->ippc_base, ssusb->mac_base);
189
190         return 0;
191 }
192
193 static int mtu3_probe(struct udevice *dev)
194 {
195         struct ssusb_mtk *ssusb = dev_get_priv(dev);
196         int ret = -ENOMEM;
197
198         ssusb->dev = dev;
199
200         ret = get_ssusb_rscs(dev, ssusb);
201         if (ret)
202                 return ret;
203
204         ret = ssusb_rscs_init(ssusb);
205         if (ret)
206                 return ret;
207
208         ssusb_ip_sw_reset(ssusb);
209
210         return 0;
211 }
212
213 static int mtu3_remove(struct udevice *dev)
214 {
215         struct ssusb_mtk *ssusb = dev_to_ssusb(dev);
216
217         ssusb_rscs_exit(ssusb);
218         return 0;
219 }
220
221 static const struct udevice_id ssusb_of_match[] = {
222         {.compatible = "mediatek,ssusb",},
223         {},
224 };
225
226 #if CONFIG_IS_ENABLED(DM_USB_GADGET)
227 int dm_usb_gadget_handle_interrupts(struct udevice *dev)
228 {
229         struct mtu3 *mtu = dev_get_priv(dev);
230
231         mtu3_irq(0, mtu);
232
233         return 0;
234 }
235
236 static int mtu3_gadget_probe(struct udevice *dev)
237 {
238         struct ssusb_mtk *ssusb = dev_to_ssusb(dev->parent);
239         struct mtu3 *mtu = dev_get_priv(dev);
240
241         mtu->dev = dev;
242         ssusb->u3d = mtu;
243         return ssusb_gadget_init(ssusb);
244 }
245
246 static int mtu3_gadget_remove(struct udevice *dev)
247 {
248         struct mtu3 *mtu = dev_get_priv(dev);
249
250         ssusb_gadget_exit(mtu->ssusb);
251         return 0;
252 }
253
254 U_BOOT_DRIVER(mtu3_peripheral) = {
255         .name = "mtu3-peripheral",
256         .id = UCLASS_USB_GADGET_GENERIC,
257         .of_match = ssusb_of_match,
258         .probe = mtu3_gadget_probe,
259         .remove = mtu3_gadget_remove,
260         .priv_auto      = sizeof(struct mtu3),
261 };
262 #endif
263
264 #if defined(CONFIG_SPL_USB_HOST) || \
265         (!defined(CONFIG_SPL_BUILD) && defined(CONFIG_USB_HOST))
266 static int mtu3_host_probe(struct udevice *dev)
267 {
268         struct ssusb_mtk *ssusb = dev_to_ssusb(dev->parent);
269         struct mtu3_host *u3h = dev_get_priv(dev);
270         struct xhci_hcor *hcor;
271         int rc;
272
273         u3h->dev = dev;
274         ssusb->u3h = u3h;
275         rc = ssusb_host_init(ssusb);
276         if (rc)
277                 return rc;
278
279         u3h->ctrl.quirks = XHCI_MTK_HOST;
280         hcor = (struct xhci_hcor *)((uintptr_t)u3h->hcd +
281                         HC_LENGTH(xhci_readl(&u3h->hcd->cr_capbase)));
282
283         return xhci_register(dev, u3h->hcd, hcor);
284 }
285
286 static int mtu3_host_remove(struct udevice *dev)
287 {
288         struct mtu3_host *u3h = dev_get_priv(dev);
289
290         xhci_deregister(dev);
291         ssusb_host_exit(u3h->ssusb);
292         return 0;
293 }
294
295 U_BOOT_DRIVER(mtu3_host) = {
296         .name = "mtu3-host",
297         .id = UCLASS_USB,
298         .of_match = ssusb_of_match,
299         .probe = mtu3_host_probe,
300         .remove = mtu3_host_remove,
301         .priv_auto      = sizeof(struct mtu3_host),
302         .ops = &xhci_usb_ops,
303         .flags = DM_FLAG_ALLOC_PRIV_DMA,
304 };
305 #endif
306
307 static int mtu3_glue_bind(struct udevice *parent)
308 {
309         struct udevice *dev;
310         enum usb_dr_mode dr_mode;
311         const char *driver;
312         const char *name;
313         ofnode node;
314         int ret;
315
316         node = ofnode_by_compatible(dev_ofnode(parent), "mediatek,ssusb");
317         if (!ofnode_valid(node))
318                 return -ENODEV;
319
320         name = ofnode_get_name(node);
321         dr_mode = usb_get_dr_mode(node);
322
323         switch (dr_mode) {
324 #if CONFIG_IS_ENABLED(DM_USB_GADGET)
325         case USB_DR_MODE_PERIPHERAL:
326         case USB_DR_MODE_OTG:
327                 dev_dbg(parent, "%s: dr_mode: peripheral\n", __func__);
328                 driver = "mtu3-peripheral";
329                 break;
330 #endif
331
332 #if defined(CONFIG_SPL_USB_HOST) || \
333         (!defined(CONFIG_SPL_BUILD) && defined(CONFIG_USB_HOST))
334         case USB_DR_MODE_HOST:
335                 dev_dbg(parent, "%s: dr_mode: host\n", __func__);
336                 driver = "mtu3-host";
337                 break;
338 #endif
339         default:
340                 dev_err(parent, "%s: unsupported dr_mode %d\n",
341                         __func__, dr_mode);
342                 return -ENODEV;
343         };
344
345         dev_dbg(parent, "%s: node name: %s, driver %s, dr_mode %d\n",
346                 __func__, name, driver, dr_mode);
347
348         ret = device_bind_driver_to_node(parent, driver, name, node, &dev);
349         if (ret)
350                 dev_err(parent, "%s: not able to bind usb device mode\n",
351                         __func__);
352
353         return ret;
354 }
355
356 static const struct udevice_id mtu3_of_match[] = {
357         {.compatible = "mediatek,mtu3",},
358         {},
359 };
360
361 U_BOOT_DRIVER(mtu3) = {
362         .name = "mtu3",
363         .id = UCLASS_NOP,
364         .of_match = mtu3_of_match,
365         .bind = mtu3_glue_bind,
366         .probe = mtu3_probe,
367         .remove = mtu3_remove,
368         .priv_auto      = sizeof(struct ssusb_mtk),
369 };