Merge tag 'u-boot-atmel-fixes-2021.01-b' of https://gitlab.denx.de/u-boot/custodians...
[platform/kernel/u-boot.git] / drivers / usb / dwc3 / dwc3-generic.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Generic DWC3 Glue layer
4  *
5  * Copyright (C) 2016 - 2018 Xilinx, Inc.
6  *
7  * Based on dwc3-omap.c.
8  */
9
10 #include <common.h>
11 #include <cpu_func.h>
12 #include <log.h>
13 #include <dm.h>
14 #include <dm/device-internal.h>
15 #include <dm/lists.h>
16 #include <dwc3-uboot.h>
17 #include <linux/bitops.h>
18 #include <linux/delay.h>
19 #include <linux/usb/ch9.h>
20 #include <linux/usb/gadget.h>
21 #include <malloc.h>
22 #include <usb.h>
23 #include "core.h"
24 #include "gadget.h"
25 #include <reset.h>
26 #include <clk.h>
27 #include <usb/xhci.h>
28
29 struct dwc3_glue_data {
30         struct clk_bulk         clks;
31         struct reset_ctl_bulk   resets;
32         fdt_addr_t regs;
33 };
34
35 struct dwc3_generic_plat {
36         fdt_addr_t base;
37         u32 maximum_speed;
38         enum usb_dr_mode dr_mode;
39 };
40
41 struct dwc3_generic_priv {
42         void *base;
43         struct dwc3 dwc3;
44         struct phy_bulk phys;
45 };
46
47 struct dwc3_generic_host_priv {
48         struct xhci_ctrl xhci_ctrl;
49         struct dwc3_generic_priv gen_priv;
50 };
51
52 static int dwc3_generic_probe(struct udevice *dev,
53                               struct dwc3_generic_priv *priv)
54 {
55         int rc;
56         struct dwc3_generic_plat *plat = dev_get_platdata(dev);
57         struct dwc3 *dwc3 = &priv->dwc3;
58         struct dwc3_glue_data *glue = dev_get_platdata(dev->parent);
59
60         dwc3->dev = dev;
61         dwc3->maximum_speed = plat->maximum_speed;
62         dwc3->dr_mode = plat->dr_mode;
63 #if CONFIG_IS_ENABLED(OF_CONTROL)
64         dwc3_of_parse(dwc3);
65 #endif
66
67         /*
68          * It must hold whole USB3.0 OTG controller in resetting to hold pipe
69          * power state in P2 before initializing TypeC PHY on RK3399 platform.
70          */
71         if (device_is_compatible(dev->parent, "rockchip,rk3399-dwc3")) {
72                 reset_assert_bulk(&glue->resets);
73                 udelay(1);
74         }
75
76         rc = dwc3_setup_phy(dev, &priv->phys);
77         if (rc && rc != -ENOTSUPP)
78                 return rc;
79
80         if (device_is_compatible(dev->parent, "rockchip,rk3399-dwc3"))
81                 reset_deassert_bulk(&glue->resets);
82
83         priv->base = map_physmem(plat->base, DWC3_OTG_REGS_END, MAP_NOCACHE);
84         dwc3->regs = priv->base + DWC3_GLOBALS_REGS_START;
85
86
87         rc =  dwc3_init(dwc3);
88         if (rc) {
89                 unmap_physmem(priv->base, MAP_NOCACHE);
90                 return rc;
91         }
92
93         return 0;
94 }
95
96 static int dwc3_generic_remove(struct udevice *dev,
97                                struct dwc3_generic_priv *priv)
98 {
99         struct dwc3 *dwc3 = &priv->dwc3;
100
101         dwc3_remove(dwc3);
102         dwc3_shutdown_phy(dev, &priv->phys);
103         unmap_physmem(dwc3->regs, MAP_NOCACHE);
104
105         return 0;
106 }
107
108 static int dwc3_generic_ofdata_to_platdata(struct udevice *dev)
109 {
110         struct dwc3_generic_plat *plat = dev_get_platdata(dev);
111         ofnode node = dev->node;
112
113         plat->base = dev_read_addr(dev);
114
115         plat->maximum_speed = usb_get_maximum_speed(node);
116         if (plat->maximum_speed == USB_SPEED_UNKNOWN) {
117                 pr_info("No USB maximum speed specified. Using super speed\n");
118                 plat->maximum_speed = USB_SPEED_SUPER;
119         }
120
121         plat->dr_mode = usb_get_dr_mode(node);
122         if (plat->dr_mode == USB_DR_MODE_UNKNOWN) {
123                 pr_err("Invalid usb mode setup\n");
124                 return -ENODEV;
125         }
126
127         return 0;
128 }
129
130 #if CONFIG_IS_ENABLED(DM_USB_GADGET)
131 int dm_usb_gadget_handle_interrupts(struct udevice *dev)
132 {
133         struct dwc3_generic_priv *priv = dev_get_priv(dev);
134         struct dwc3 *dwc3 = &priv->dwc3;
135
136         dwc3_gadget_uboot_handle_interrupt(dwc3);
137
138         return 0;
139 }
140
141 static int dwc3_generic_peripheral_probe(struct udevice *dev)
142 {
143         struct dwc3_generic_priv *priv = dev_get_priv(dev);
144
145         return dwc3_generic_probe(dev, priv);
146 }
147
148 static int dwc3_generic_peripheral_remove(struct udevice *dev)
149 {
150         struct dwc3_generic_priv *priv = dev_get_priv(dev);
151
152         return dwc3_generic_remove(dev, priv);
153 }
154
155 U_BOOT_DRIVER(dwc3_generic_peripheral) = {
156         .name   = "dwc3-generic-peripheral",
157         .id     = UCLASS_USB_GADGET_GENERIC,
158         .ofdata_to_platdata = dwc3_generic_ofdata_to_platdata,
159         .probe = dwc3_generic_peripheral_probe,
160         .remove = dwc3_generic_peripheral_remove,
161         .priv_auto_alloc_size = sizeof(struct dwc3_generic_priv),
162         .platdata_auto_alloc_size = sizeof(struct dwc3_generic_plat),
163 };
164 #endif
165
166 #if defined(CONFIG_SPL_USB_HOST_SUPPORT) || !defined(CONFIG_SPL_BUILD)
167 static int dwc3_generic_host_probe(struct udevice *dev)
168 {
169         struct xhci_hcor *hcor;
170         struct xhci_hccr *hccr;
171         struct dwc3_generic_host_priv *priv = dev_get_priv(dev);
172         int rc;
173
174         rc = dwc3_generic_probe(dev, &priv->gen_priv);
175         if (rc)
176                 return rc;
177
178         hccr = (struct xhci_hccr *)priv->gen_priv.base;
179         hcor = (struct xhci_hcor *)(priv->gen_priv.base +
180                         HC_LENGTH(xhci_readl(&(hccr)->cr_capbase)));
181
182         return xhci_register(dev, hccr, hcor);
183 }
184
185 static int dwc3_generic_host_remove(struct udevice *dev)
186 {
187         struct dwc3_generic_host_priv *priv = dev_get_priv(dev);
188         int rc;
189
190         rc = xhci_deregister(dev);
191         if (rc)
192                 return rc;
193
194         return dwc3_generic_remove(dev, &priv->gen_priv);
195 }
196
197 U_BOOT_DRIVER(dwc3_generic_host) = {
198         .name   = "dwc3-generic-host",
199         .id     = UCLASS_USB,
200         .ofdata_to_platdata = dwc3_generic_ofdata_to_platdata,
201         .probe = dwc3_generic_host_probe,
202         .remove = dwc3_generic_host_remove,
203         .priv_auto_alloc_size = sizeof(struct dwc3_generic_host_priv),
204         .platdata_auto_alloc_size = sizeof(struct dwc3_generic_plat),
205         .ops = &xhci_usb_ops,
206         .flags = DM_FLAG_ALLOC_PRIV_DMA,
207 };
208 #endif
209
210 struct dwc3_glue_ops {
211         void (*select_dr_mode)(struct udevice *dev, int index,
212                                enum usb_dr_mode mode);
213 };
214
215 void dwc3_ti_select_dr_mode(struct udevice *dev, int index,
216                             enum usb_dr_mode mode)
217 {
218 #define USBOTGSS_UTMI_OTG_STATUS                0x0084
219 #define USBOTGSS_UTMI_OTG_OFFSET                0x0480
220
221 /* UTMI_OTG_STATUS REGISTER */
222 #define USBOTGSS_UTMI_OTG_STATUS_SW_MODE        BIT(31)
223 #define USBOTGSS_UTMI_OTG_STATUS_POWERPRESENT   BIT(9)
224 #define USBOTGSS_UTMI_OTG_STATUS_TXBITSTUFFENABLE BIT(8)
225 #define USBOTGSS_UTMI_OTG_STATUS_IDDIG          BIT(4)
226 #define USBOTGSS_UTMI_OTG_STATUS_SESSEND        BIT(3)
227 #define USBOTGSS_UTMI_OTG_STATUS_SESSVALID      BIT(2)
228 #define USBOTGSS_UTMI_OTG_STATUS_VBUSVALID      BIT(1)
229 enum dwc3_omap_utmi_mode {
230         DWC3_OMAP_UTMI_MODE_UNKNOWN = 0,
231         DWC3_OMAP_UTMI_MODE_HW,
232         DWC3_OMAP_UTMI_MODE_SW,
233 };
234
235         u32 use_id_pin;
236         u32 host_mode;
237         u32 reg;
238         u32 utmi_mode;
239         u32 utmi_status_offset = USBOTGSS_UTMI_OTG_STATUS;
240
241         struct dwc3_glue_data *glue = dev_get_platdata(dev);
242         void *base = map_physmem(glue->regs, 0x10000, MAP_NOCACHE);
243
244         if (device_is_compatible(dev, "ti,am437x-dwc3"))
245                 utmi_status_offset += USBOTGSS_UTMI_OTG_OFFSET;
246
247         utmi_mode = dev_read_u32_default(dev, "utmi-mode",
248                                          DWC3_OMAP_UTMI_MODE_UNKNOWN);
249         if (utmi_mode != DWC3_OMAP_UTMI_MODE_HW) {
250                 debug("%s: OTG is not supported. defaulting to PERIPHERAL\n",
251                       dev->name);
252                 mode = USB_DR_MODE_PERIPHERAL;
253         }
254
255         switch (mode)  {
256         case USB_DR_MODE_PERIPHERAL:
257                 use_id_pin = 0;
258                 host_mode = 0;
259                 break;
260         case USB_DR_MODE_HOST:
261                 use_id_pin = 0;
262                 host_mode = 1;
263                 break;
264         case USB_DR_MODE_OTG:
265         default:
266                 use_id_pin = 1;
267                 host_mode = 0;
268                 break;
269         }
270
271         reg = readl(base + utmi_status_offset);
272
273         reg &= ~(USBOTGSS_UTMI_OTG_STATUS_SW_MODE);
274         if (!use_id_pin)
275                 reg |= USBOTGSS_UTMI_OTG_STATUS_SW_MODE;
276
277         writel(reg, base + utmi_status_offset);
278
279         reg &= ~(USBOTGSS_UTMI_OTG_STATUS_SESSEND |
280                 USBOTGSS_UTMI_OTG_STATUS_VBUSVALID |
281                 USBOTGSS_UTMI_OTG_STATUS_IDDIG);
282
283         reg |= USBOTGSS_UTMI_OTG_STATUS_SESSVALID |
284                 USBOTGSS_UTMI_OTG_STATUS_POWERPRESENT;
285
286         if (!host_mode)
287                 reg |= USBOTGSS_UTMI_OTG_STATUS_IDDIG |
288                         USBOTGSS_UTMI_OTG_STATUS_VBUSVALID;
289
290         writel(reg, base + utmi_status_offset);
291
292         unmap_physmem(base, MAP_NOCACHE);
293 }
294
295 struct dwc3_glue_ops ti_ops = {
296         .select_dr_mode = dwc3_ti_select_dr_mode,
297 };
298
299 static int dwc3_glue_bind(struct udevice *parent)
300 {
301         ofnode node;
302         int ret;
303
304         ofnode_for_each_subnode(node, parent->node) {
305                 const char *name = ofnode_get_name(node);
306                 enum usb_dr_mode dr_mode;
307                 struct udevice *dev;
308                 const char *driver = NULL;
309
310                 debug("%s: subnode name: %s\n", __func__, name);
311
312                 dr_mode = usb_get_dr_mode(node);
313
314                 switch (dr_mode) {
315                 case USB_DR_MODE_PERIPHERAL:
316                 case USB_DR_MODE_OTG:
317 #if CONFIG_IS_ENABLED(DM_USB_GADGET)
318                         debug("%s: dr_mode: OTG or Peripheral\n", __func__);
319                         driver = "dwc3-generic-peripheral";
320 #endif
321                         break;
322 #if defined(CONFIG_SPL_USB_HOST_SUPPORT) || !defined(CONFIG_SPL_BUILD)
323                 case USB_DR_MODE_HOST:
324                         debug("%s: dr_mode: HOST\n", __func__);
325                         driver = "dwc3-generic-host";
326                         break;
327 #endif
328                 default:
329                         debug("%s: unsupported dr_mode\n", __func__);
330                         return -ENODEV;
331                 };
332
333                 if (!driver)
334                         continue;
335
336                 ret = device_bind_driver_to_node(parent, driver, name,
337                                                  node, &dev);
338                 if (ret) {
339                         debug("%s: not able to bind usb device mode\n",
340                               __func__);
341                         return ret;
342                 }
343         }
344
345         return 0;
346 }
347
348 static int dwc3_glue_reset_init(struct udevice *dev,
349                                 struct dwc3_glue_data *glue)
350 {
351         int ret;
352
353         ret = reset_get_bulk(dev, &glue->resets);
354         if (ret == -ENOTSUPP || ret == -ENOENT)
355                 return 0;
356         else if (ret)
357                 return ret;
358
359         ret = reset_deassert_bulk(&glue->resets);
360         if (ret) {
361                 reset_release_bulk(&glue->resets);
362                 return ret;
363         }
364
365         return 0;
366 }
367
368 static int dwc3_glue_clk_init(struct udevice *dev,
369                               struct dwc3_glue_data *glue)
370 {
371         int ret;
372
373         ret = clk_get_bulk(dev, &glue->clks);
374         if (ret == -ENOSYS || ret == -ENOENT)
375                 return 0;
376         if (ret)
377                 return ret;
378
379 #if CONFIG_IS_ENABLED(CLK)
380         ret = clk_enable_bulk(&glue->clks);
381         if (ret) {
382                 clk_release_bulk(&glue->clks);
383                 return ret;
384         }
385 #endif
386
387         return 0;
388 }
389
390 static int dwc3_glue_probe(struct udevice *dev)
391 {
392         struct dwc3_glue_ops *ops = (struct dwc3_glue_ops *)dev_get_driver_data(dev);
393         struct dwc3_glue_data *glue = dev_get_platdata(dev);
394         struct udevice *child = NULL;
395         int index = 0;
396         int ret;
397
398         glue->regs = dev_read_addr(dev);
399
400         ret = dwc3_glue_clk_init(dev, glue);
401         if (ret)
402                 return ret;
403
404         ret = dwc3_glue_reset_init(dev, glue);
405         if (ret)
406                 return ret;
407
408         ret = device_find_first_child(dev, &child);
409         if (ret)
410                 return ret;
411
412         if (glue->resets.count == 0) {
413                 ret = dwc3_glue_reset_init(child, glue);
414                 if (ret)
415                         return ret;
416         }
417
418         while (child) {
419                 enum usb_dr_mode dr_mode;
420
421                 dr_mode = usb_get_dr_mode(child->node);
422                 device_find_next_child(&child);
423                 if (ops && ops->select_dr_mode)
424                         ops->select_dr_mode(dev, index, dr_mode);
425                 index++;
426         }
427
428         return 0;
429 }
430
431 static int dwc3_glue_remove(struct udevice *dev)
432 {
433         struct dwc3_glue_data *glue = dev_get_platdata(dev);
434
435         reset_release_bulk(&glue->resets);
436
437         clk_release_bulk(&glue->clks);
438
439         return 0;
440 }
441
442 static const struct udevice_id dwc3_glue_ids[] = {
443         { .compatible = "xlnx,zynqmp-dwc3" },
444         { .compatible = "xlnx,versal-dwc3" },
445         { .compatible = "ti,keystone-dwc3"},
446         { .compatible = "ti,dwc3", .data = (ulong)&ti_ops },
447         { .compatible = "ti,am437x-dwc3", .data = (ulong)&ti_ops },
448         { .compatible = "ti,am654-dwc3" },
449         { .compatible = "rockchip,rk3328-dwc3" },
450         { .compatible = "rockchip,rk3399-dwc3" },
451         { .compatible = "qcom,dwc3" },
452         { }
453 };
454
455 U_BOOT_DRIVER(dwc3_generic_wrapper) = {
456         .name   = "dwc3-generic-wrapper",
457         .id     = UCLASS_NOP,
458         .of_match = dwc3_glue_ids,
459         .bind = dwc3_glue_bind,
460         .probe = dwc3_glue_probe,
461         .remove = dwc3_glue_remove,
462         .platdata_auto_alloc_size = sizeof(struct dwc3_glue_data),
463
464 };