0488af0b29be4cd1578cca46be87db2ea68ee8b1
[firefly-linux-kernel-4.4.55.git] / drivers / usb / dwc3 / dwc3-rockchip.c
1 /**
2  * dwc3-rockchip.c - Rockchip Specific Glue layer
3  *
4  * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
5  *
6  * Authors: William Wu <william.wu@rock-chips.com>
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2  of
10  * the License as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  */
17
18 #include <linux/module.h>
19 #include <linux/mutex.h>
20 #include <linux/kernel.h>
21 #include <linux/slab.h>
22 #include <linux/platform_device.h>
23 #include <linux/dma-mapping.h>
24 #include <linux/clk.h>
25 #include <linux/clk-provider.h>
26 #include <linux/of.h>
27 #include <linux/of_platform.h>
28 #include <linux/pm_runtime.h>
29 #include <linux/extcon.h>
30 #include <linux/reset.h>
31 #include <linux/usb.h>
32 #include <linux/usb/hcd.h>
33
34 #include "core.h"
35 #include "io.h"
36 #include "../host/xhci.h"
37
38 #define DWC3_ROCKCHIP_AUTOSUSPEND_DELAY  500 /* ms */
39
40 struct dwc3_rockchip {
41         int                     num_clocks;
42         bool                    connected;
43         bool                    suspended;
44         struct device           *dev;
45         struct clk              **clks;
46         struct dwc3             *dwc;
47         struct reset_control    *otg_rst;
48         struct extcon_dev       *edev;
49         struct notifier_block   device_nb;
50         struct notifier_block   host_nb;
51         struct work_struct      otg_work;
52         struct mutex            lock;
53 };
54
55 static int dwc3_rockchip_device_notifier(struct notifier_block *nb,
56                                          unsigned long event, void *ptr)
57 {
58         struct dwc3_rockchip *rockchip =
59                 container_of(nb, struct dwc3_rockchip, device_nb);
60
61         if (!rockchip->suspended)
62                 schedule_work(&rockchip->otg_work);
63
64         return NOTIFY_DONE;
65 }
66
67 static int dwc3_rockchip_host_notifier(struct notifier_block *nb,
68                                        unsigned long event, void *ptr)
69 {
70         struct dwc3_rockchip *rockchip =
71                 container_of(nb, struct dwc3_rockchip, host_nb);
72
73         if (!rockchip->suspended)
74                 schedule_work(&rockchip->otg_work);
75
76         return NOTIFY_DONE;
77 }
78
79 static void dwc3_rockchip_otg_extcon_evt_work(struct work_struct *work)
80 {
81         struct dwc3_rockchip    *rockchip =
82                 container_of(work, struct dwc3_rockchip, otg_work);
83         struct dwc3             *dwc = rockchip->dwc;
84         struct extcon_dev       *edev = rockchip->edev;
85         struct usb_hcd          *hcd;
86         struct xhci_hcd         *xhci;
87         unsigned long           flags;
88         int                     ret;
89         u32                     reg;
90
91         mutex_lock(&rockchip->lock);
92
93         if (extcon_get_cable_state_(edev, EXTCON_USB) > 0) {
94                 if (rockchip->connected)
95                         goto out;
96
97                 /*
98                  * If dr_mode is host only, never to set
99                  * the mode to the peripheral mode.
100                  */
101                 if (dwc->dr_mode == USB_DR_MODE_HOST) {
102                         dev_warn(rockchip->dev, "USB peripheral not support!\n");
103                         goto out;
104                 }
105
106                 /*
107                  * Assert otg reset can put the dwc in P2 state, it's
108                  * necessary operation prior to phy power on. However,
109                  * asserting the otg reset may affect dwc chip operation.
110                  * The reset will clear all of the dwc controller registers.
111                  * So we need to reinit the dwc controller after deassert
112                  * the reset. We use pm runtime to initialize dwc controller.
113                  * Also, there are no synchronization primitives, meaning
114                  * the dwc3 core code could at least in theory access chip
115                  * registers while the reset is asserted, with unknown impact.
116                  */
117                 reset_control_assert(rockchip->otg_rst);
118                 usleep_range(1000, 1200);
119                 reset_control_deassert(rockchip->otg_rst);
120
121                 pm_runtime_get_sync(rockchip->dev);
122                 pm_runtime_get_sync(dwc->dev);
123
124                 spin_lock_irqsave(&dwc->lock, flags);
125                 dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_DEVICE);
126                 spin_unlock_irqrestore(&dwc->lock, flags);
127
128                 rockchip->connected = true;
129                 dev_info(rockchip->dev, "USB peripheral connected\n");
130         } else if (extcon_get_cable_state_(edev, EXTCON_USB_HOST) > 0) {
131                 if (rockchip->connected)
132                         goto out;
133
134                 /*
135                  * If dr_mode is device only, never to
136                  * set the mode to the host mode.
137                  */
138                 if (dwc->dr_mode == USB_DR_MODE_PERIPHERAL) {
139                         dev_warn(rockchip->dev, "USB HOST not support!\n");
140                         goto out;
141                 }
142
143                 /*
144                  * Assert otg reset can put the dwc in P2 state, it's
145                  * necessary operation prior to phy power on. However,
146                  * asserting the otg reset may affect dwc chip operation.
147                  * The reset will clear all of the dwc controller registers.
148                  * So we need to reinit the dwc controller after deassert
149                  * the reset. We use pm runtime to initialize dwc controller.
150                  * Also, there are no synchronization primitives, meaning
151                  * the dwc3 core code could at least in theory access chip
152                  * registers while the reset is asserted, with unknown impact.
153                  */
154                 reset_control_assert(rockchip->otg_rst);
155                 usleep_range(1000, 1200);
156                 reset_control_deassert(rockchip->otg_rst);
157
158                 /*
159                  * In usb3 phy init, it will access usb3 module, so we need
160                  * to resume rockchip dev before phy init to make sure usb3
161                  * pd is enabled.
162                  */
163                 pm_runtime_get_sync(rockchip->dev);
164
165                 /*
166                  * Don't abort on errors. If powering on a phy fails,
167                  * we still need to init dwc controller and add the
168                  * HCDs to avoid a crash when unloading the driver.
169                  */
170                 ret = phy_power_on(dwc->usb2_generic_phy);
171                 if (ret < 0)
172                         dev_err(dwc->dev, "Failed to power on usb2 phy\n");
173
174                 ret = phy_power_on(dwc->usb3_generic_phy);
175                 if (ret < 0) {
176                         phy_power_off(dwc->usb2_generic_phy);
177                         dev_err(dwc->dev, "Failed to power on usb3 phy\n");
178                 }
179
180                 pm_runtime_get_sync(dwc->dev);
181
182                 spin_lock_irqsave(&dwc->lock, flags);
183                 dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_HOST);
184                 spin_unlock_irqrestore(&dwc->lock, flags);
185
186                 /*
187                  * The following sleep helps to ensure that inserted USB3
188                  * Ethernet devices are discovered if already inserted
189                  * when booting.
190                  */
191                 usleep_range(10000, 11000);
192
193                 hcd = dev_get_drvdata(&dwc->xhci->dev);
194
195                 if (hcd->state == HC_STATE_HALT) {
196                         usb_add_hcd(hcd, hcd->irq, IRQF_SHARED);
197                         usb_add_hcd(hcd->shared_hcd, hcd->irq, IRQF_SHARED);
198                 }
199
200                 rockchip->connected = true;
201                 dev_info(rockchip->dev, "USB HOST connected\n");
202         } else {
203                 if (!rockchip->connected)
204                         goto out;
205
206                 reg = dwc3_readl(dwc->regs, DWC3_GCTL);
207
208                 /*
209                  * xhci does not support runtime pm. If HCDs are not removed
210                  * here and and re-added after a cable is inserted, USB3
211                  * connections will not work.
212                  * A clean(er) solution would be to implement runtime pm
213                  * support in xhci. After that is available, this code should
214                  * be removed.
215                  * HCDs have to be removed here to prevent attempts by the
216                  * xhci code to access xhci registers after the call to
217                  * pm_runtime_put_sync_suspend(). On rk3399, this can result
218                  * in a crash under certain circumstances (this was observed
219                  * on 3399 chromebook if the system is running on battery).
220                  */
221                 if (DWC3_GCTL_PRTCAP(reg) == DWC3_GCTL_PRTCAP_HOST ||
222                     DWC3_GCTL_PRTCAP(reg) == DWC3_GCTL_PRTCAP_OTG) {
223                         hcd = dev_get_drvdata(&dwc->xhci->dev);
224                         xhci = hcd_to_xhci(hcd);
225
226                         if (hcd->state != HC_STATE_HALT) {
227                                 xhci->xhc_state |= XHCI_STATE_REMOVING;
228                                 usb_remove_hcd(hcd->shared_hcd);
229                                 usb_remove_hcd(hcd);
230                         }
231
232                         phy_power_off(dwc->usb2_generic_phy);
233                         phy_power_off(dwc->usb3_generic_phy);
234                 }
235
236                 pm_runtime_put_sync(rockchip->dev);
237                 pm_runtime_put_sync_suspend(dwc->dev);
238
239                 rockchip->connected = false;
240                 dev_info(rockchip->dev, "USB unconnected\n");
241         }
242
243 out:
244         mutex_unlock(&rockchip->lock);
245 }
246
247 static int dwc3_rockchip_extcon_register(struct dwc3_rockchip *rockchip)
248 {
249         int                     ret;
250         struct device           *dev = rockchip->dev;
251         struct extcon_dev       *edev;
252
253         if (device_property_read_bool(dev, "extcon")) {
254                 edev = extcon_get_edev_by_phandle(dev, 0);
255                 if (IS_ERR(edev)) {
256                         if (PTR_ERR(edev) != -EPROBE_DEFER)
257                                 dev_err(dev, "couldn't get extcon device\n");
258                         return PTR_ERR(edev);
259                 }
260
261                 INIT_WORK(&rockchip->otg_work,
262                           dwc3_rockchip_otg_extcon_evt_work);
263
264                 rockchip->device_nb.notifier_call =
265                                 dwc3_rockchip_device_notifier;
266                 ret = extcon_register_notifier(edev, EXTCON_USB,
267                                                &rockchip->device_nb);
268                 if (ret < 0) {
269                         dev_err(dev, "failed to register notifier for USB\n");
270                         return ret;
271                 }
272
273                 rockchip->host_nb.notifier_call =
274                                 dwc3_rockchip_host_notifier;
275                 ret = extcon_register_notifier(edev, EXTCON_USB_HOST,
276                                                &rockchip->host_nb);
277                 if (ret < 0) {
278                         dev_err(dev, "failed to register notifier for USB HOST\n");
279                         extcon_unregister_notifier(edev, EXTCON_USB,
280                                                    &rockchip->device_nb);
281                         return ret;
282                 }
283
284                 rockchip->edev = edev;
285         }
286
287         return 0;
288 }
289
290 static void dwc3_rockchip_extcon_unregister(struct dwc3_rockchip *rockchip)
291 {
292         if (!rockchip->edev)
293                 return;
294
295         extcon_unregister_notifier(rockchip->edev, EXTCON_USB,
296                                    &rockchip->device_nb);
297         extcon_unregister_notifier(rockchip->edev, EXTCON_USB_HOST,
298                                    &rockchip->host_nb);
299         cancel_work_sync(&rockchip->otg_work);
300 }
301
302 static int dwc3_rockchip_probe(struct platform_device *pdev)
303 {
304         struct dwc3_rockchip    *rockchip;
305         struct device           *dev = &pdev->dev;
306         struct device_node      *np = dev->of_node, *child;
307         struct platform_device  *child_pdev;
308
309         unsigned int            count;
310         int                     ret;
311         int                     i;
312
313         rockchip = devm_kzalloc(dev, sizeof(*rockchip), GFP_KERNEL);
314
315         if (!rockchip)
316                 return -ENOMEM;
317
318         count = of_clk_get_parent_count(np);
319         if (!count)
320                 return -ENOENT;
321
322         rockchip->num_clocks = count;
323
324         rockchip->clks = devm_kcalloc(dev, rockchip->num_clocks,
325                                       sizeof(struct clk *), GFP_KERNEL);
326         if (!rockchip->clks)
327                 return -ENOMEM;
328
329         platform_set_drvdata(pdev, rockchip);
330
331         mutex_init(&rockchip->lock);
332
333         rockchip->dev = dev;
334
335         mutex_lock(&rockchip->lock);
336
337         for (i = 0; i < rockchip->num_clocks; i++) {
338                 struct clk      *clk;
339
340                 clk = of_clk_get(np, i);
341                 if (IS_ERR(clk)) {
342                         ret = PTR_ERR(clk);
343                         goto err0;
344                 }
345
346                 ret = clk_prepare_enable(clk);
347                 if (ret < 0) {
348                         clk_put(clk);
349                         goto err0;
350                 }
351
352                 rockchip->clks[i] = clk;
353         }
354
355         pm_runtime_set_active(dev);
356         pm_runtime_enable(dev);
357         ret = pm_runtime_get_sync(dev);
358         if (ret < 0) {
359                 dev_err(dev, "get_sync failed with err %d\n", ret);
360                 goto err1;
361         }
362
363         rockchip->otg_rst = devm_reset_control_get(dev, "usb3-otg");
364         if (IS_ERR(rockchip->otg_rst)) {
365                 dev_err(dev, "could not get reset controller\n");
366                 ret = PTR_ERR(rockchip->otg_rst);
367                 goto err1;
368         }
369
370         child = of_get_child_by_name(np, "dwc3");
371         if (!child) {
372                 dev_err(dev, "failed to find dwc3 core node\n");
373                 ret = -ENODEV;
374                 goto err1;
375         }
376
377         /* Allocate and initialize the core */
378         ret = of_platform_populate(np, NULL, NULL, dev);
379         if (ret) {
380                 dev_err(dev, "failed to create dwc3 core\n");
381                 goto err1;
382         }
383
384         child_pdev = of_find_device_by_node(child);
385         if (!child_pdev) {
386                 dev_err(dev, "failed to find dwc3 core device\n");
387                 ret = -ENODEV;
388                 goto err2;
389         }
390
391         rockchip->dwc = platform_get_drvdata(child_pdev);
392         if (!rockchip->dwc) {
393                 dev_err(dev, "failed to get drvdata dwc3\n");
394                 ret = -EPROBE_DEFER;
395                 goto err2;
396         }
397
398         ret = dwc3_rockchip_extcon_register(rockchip);
399         if (ret < 0)
400                 goto err2;
401
402         if (rockchip->edev) {
403                 if (rockchip->dwc->dr_mode == USB_DR_MODE_HOST ||
404                     rockchip->dwc->dr_mode == USB_DR_MODE_OTG) {
405                         struct usb_hcd *hcd =
406                                 dev_get_drvdata(&rockchip->dwc->xhci->dev);
407                         if (!hcd) {
408                                 dev_err(dev, "fail to get drvdata hcd\n");
409                                 ret = -EPROBE_DEFER;
410                                 goto err3;
411                         }
412                         if (hcd->state != HC_STATE_HALT) {
413                                 usb_remove_hcd(hcd->shared_hcd);
414                                 usb_remove_hcd(hcd);
415                         }
416                 }
417
418                 pm_runtime_set_autosuspend_delay(&child_pdev->dev,
419                                                  DWC3_ROCKCHIP_AUTOSUSPEND_DELAY);
420                 pm_runtime_allow(&child_pdev->dev);
421                 pm_runtime_suspend(&child_pdev->dev);
422                 pm_runtime_put_sync(dev);
423
424                 if ((extcon_get_cable_state_(rockchip->edev,
425                                              EXTCON_USB) > 0) ||
426                     (extcon_get_cable_state_(rockchip->edev,
427                                              EXTCON_USB_HOST) > 0))
428                         schedule_work(&rockchip->otg_work);
429         }
430
431         mutex_unlock(&rockchip->lock);
432
433         return ret;
434
435 err3:
436         dwc3_rockchip_extcon_unregister(rockchip);
437
438 err2:
439         of_platform_depopulate(dev);
440
441 err1:
442         pm_runtime_put_sync(dev);
443         pm_runtime_disable(dev);
444
445 err0:
446         for (i = 0; i < rockchip->num_clocks && rockchip->clks[i]; i++) {
447                 if (!pm_runtime_status_suspended(dev))
448                         clk_disable(rockchip->clks[i]);
449                 clk_unprepare(rockchip->clks[i]);
450                 clk_put(rockchip->clks[i]);
451         }
452
453         mutex_unlock(&rockchip->lock);
454
455         return ret;
456 }
457
458 static int dwc3_rockchip_remove(struct platform_device *pdev)
459 {
460         struct dwc3_rockchip    *rockchip = platform_get_drvdata(pdev);
461         struct device           *dev = &pdev->dev;
462         int                     i;
463
464         dwc3_rockchip_extcon_unregister(rockchip);
465
466         /* Restore hcd state before unregistering xhci */
467         if (rockchip->edev && !rockchip->connected) {
468                 struct usb_hcd *hcd =
469                         dev_get_drvdata(&rockchip->dwc->xhci->dev);
470
471                 pm_runtime_get_sync(dev);
472
473                 /*
474                  * The xhci code does not expect that HCDs have been removed.
475                  * It will unconditionally call usb_remove_hcd() when the xhci
476                  * driver is unloaded in of_platform_depopulate(). This results
477                  * in a crash if the HCDs were already removed. To avoid this
478                  * crash, add the HCDs here as dummy operation.
479                  * This code should be removed after pm runtime support
480                  * has been added to xhci.
481                  */
482                 if (hcd->state == HC_STATE_HALT) {
483                         usb_add_hcd(hcd, hcd->irq, IRQF_SHARED);
484                         usb_add_hcd(hcd->shared_hcd, hcd->irq, IRQF_SHARED);
485                 }
486         }
487
488         of_platform_depopulate(dev);
489
490         pm_runtime_put_sync(dev);
491         pm_runtime_disable(dev);
492
493         for (i = 0; i < rockchip->num_clocks; i++) {
494                 if (!pm_runtime_status_suspended(dev))
495                         clk_disable(rockchip->clks[i]);
496                 clk_unprepare(rockchip->clks[i]);
497                 clk_put(rockchip->clks[i]);
498         }
499
500         return 0;
501 }
502
503 #ifdef CONFIG_PM
504 static int dwc3_rockchip_runtime_suspend(struct device *dev)
505 {
506         struct dwc3_rockchip    *rockchip = dev_get_drvdata(dev);
507         int                     i;
508
509         for (i = 0; i < rockchip->num_clocks; i++)
510                 clk_disable(rockchip->clks[i]);
511
512         device_init_wakeup(dev, false);
513
514         return 0;
515 }
516
517 static int dwc3_rockchip_runtime_resume(struct device *dev)
518 {
519         struct dwc3_rockchip    *rockchip = dev_get_drvdata(dev);
520         int                     i;
521
522         for (i = 0; i < rockchip->num_clocks; i++)
523                 clk_enable(rockchip->clks[i]);
524
525         device_init_wakeup(dev, true);
526
527         return 0;
528 }
529
530 static int dwc3_rockchip_suspend(struct device *dev)
531 {
532         struct dwc3_rockchip *rockchip = dev_get_drvdata(dev);
533
534         rockchip->suspended = true;
535         cancel_work_sync(&rockchip->otg_work);
536
537         return 0;
538 }
539
540 static int dwc3_rockchip_resume(struct device *dev)
541 {
542         struct dwc3_rockchip *rockchip = dev_get_drvdata(dev);
543
544         rockchip->suspended = false;
545
546         return 0;
547 }
548
549 static const struct dev_pm_ops dwc3_rockchip_dev_pm_ops = {
550         SET_SYSTEM_SLEEP_PM_OPS(dwc3_rockchip_suspend, dwc3_rockchip_resume)
551         SET_RUNTIME_PM_OPS(dwc3_rockchip_runtime_suspend,
552                            dwc3_rockchip_runtime_resume, NULL)
553 };
554
555 #define DEV_PM_OPS      (&dwc3_rockchip_dev_pm_ops)
556 #else
557 #define DEV_PM_OPS      NULL
558 #endif /* CONFIG_PM */
559
560 static const struct of_device_id rockchip_dwc3_match[] = {
561         { .compatible = "rockchip,rk3399-dwc3" },
562         { /* Sentinel */ }
563 };
564
565 MODULE_DEVICE_TABLE(of, rockchip_dwc3_match);
566
567 static struct platform_driver dwc3_rockchip_driver = {
568         .probe          = dwc3_rockchip_probe,
569         .remove         = dwc3_rockchip_remove,
570         .driver         = {
571                 .name   = "rockchip-dwc3",
572                 .of_match_table = rockchip_dwc3_match,
573                 .pm     = DEV_PM_OPS,
574         },
575 };
576
577 module_platform_driver(dwc3_rockchip_driver);
578
579 MODULE_ALIAS("platform:rockchip-dwc3");
580 MODULE_AUTHOR("William Wu <william.wu@rock-chips.com>");
581 MODULE_LICENSE("GPL v2");
582 MODULE_DESCRIPTION("DesignWare USB3 ROCKCHIP Glue Layer");