GNU Linux-libre 4.19.211-gnu1
[releases.git] / drivers / usb / dwc3 / dwc3-qcom.c
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2018, The Linux Foundation. All rights reserved.
3  *
4  * Inspired by dwc3-of-simple.c
5  */
6
7 #include <linux/io.h>
8 #include <linux/of.h>
9 #include <linux/clk.h>
10 #include <linux/irq.h>
11 #include <linux/clk-provider.h>
12 #include <linux/module.h>
13 #include <linux/kernel.h>
14 #include <linux/extcon.h>
15 #include <linux/of_platform.h>
16 #include <linux/platform_device.h>
17 #include <linux/phy/phy.h>
18 #include <linux/usb/of.h>
19 #include <linux/reset.h>
20 #include <linux/iopoll.h>
21
22 #include "core.h"
23
24 /* USB QSCRATCH Hardware registers */
25 #define QSCRATCH_HS_PHY_CTRL                    0x10
26 #define UTMI_OTG_VBUS_VALID                     BIT(20)
27 #define SW_SESSVLD_SEL                          BIT(28)
28
29 #define QSCRATCH_SS_PHY_CTRL                    0x30
30 #define LANE0_PWR_PRESENT                       BIT(24)
31
32 #define QSCRATCH_GENERAL_CFG                    0x08
33 #define PIPE_UTMI_CLK_SEL                       BIT(0)
34 #define PIPE3_PHYSTATUS_SW                      BIT(3)
35 #define PIPE_UTMI_CLK_DIS                       BIT(8)
36
37 #define PWR_EVNT_IRQ_STAT_REG                   0x58
38 #define PWR_EVNT_LPM_IN_L2_MASK                 BIT(4)
39 #define PWR_EVNT_LPM_OUT_L2_MASK                BIT(5)
40
41 struct dwc3_qcom {
42         struct device           *dev;
43         void __iomem            *qscratch_base;
44         struct platform_device  *dwc3;
45         struct clk              **clks;
46         int                     num_clocks;
47         struct reset_control    *resets;
48
49         int                     hs_phy_irq;
50         int                     dp_hs_phy_irq;
51         int                     dm_hs_phy_irq;
52         int                     ss_phy_irq;
53
54         struct extcon_dev       *edev;
55         struct extcon_dev       *host_edev;
56         struct notifier_block   vbus_nb;
57         struct notifier_block   host_nb;
58
59         enum usb_dr_mode        mode;
60         bool                    is_suspended;
61         bool                    pm_suspended;
62 };
63
64 static inline void dwc3_qcom_setbits(void __iomem *base, u32 offset, u32 val)
65 {
66         u32 reg;
67
68         reg = readl(base + offset);
69         reg |= val;
70         writel(reg, base + offset);
71
72         /* ensure that above write is through */
73         readl(base + offset);
74 }
75
76 static inline void dwc3_qcom_clrbits(void __iomem *base, u32 offset, u32 val)
77 {
78         u32 reg;
79
80         reg = readl(base + offset);
81         reg &= ~val;
82         writel(reg, base + offset);
83
84         /* ensure that above write is through */
85         readl(base + offset);
86 }
87
88 static void dwc3_qcom_vbus_overrride_enable(struct dwc3_qcom *qcom, bool enable)
89 {
90         if (enable) {
91                 dwc3_qcom_setbits(qcom->qscratch_base, QSCRATCH_SS_PHY_CTRL,
92                                   LANE0_PWR_PRESENT);
93                 dwc3_qcom_setbits(qcom->qscratch_base, QSCRATCH_HS_PHY_CTRL,
94                                   UTMI_OTG_VBUS_VALID | SW_SESSVLD_SEL);
95         } else {
96                 dwc3_qcom_clrbits(qcom->qscratch_base, QSCRATCH_SS_PHY_CTRL,
97                                   LANE0_PWR_PRESENT);
98                 dwc3_qcom_clrbits(qcom->qscratch_base, QSCRATCH_HS_PHY_CTRL,
99                                   UTMI_OTG_VBUS_VALID | SW_SESSVLD_SEL);
100         }
101 }
102
103 static int dwc3_qcom_vbus_notifier(struct notifier_block *nb,
104                                    unsigned long event, void *ptr)
105 {
106         struct dwc3_qcom *qcom = container_of(nb, struct dwc3_qcom, vbus_nb);
107
108         /* enable vbus override for device mode */
109         dwc3_qcom_vbus_overrride_enable(qcom, event);
110         qcom->mode = event ? USB_DR_MODE_PERIPHERAL : USB_DR_MODE_HOST;
111
112         return NOTIFY_DONE;
113 }
114
115 static int dwc3_qcom_host_notifier(struct notifier_block *nb,
116                                    unsigned long event, void *ptr)
117 {
118         struct dwc3_qcom *qcom = container_of(nb, struct dwc3_qcom, host_nb);
119
120         /* disable vbus override in host mode */
121         dwc3_qcom_vbus_overrride_enable(qcom, !event);
122         qcom->mode = event ? USB_DR_MODE_HOST : USB_DR_MODE_PERIPHERAL;
123
124         return NOTIFY_DONE;
125 }
126
127 static int dwc3_qcom_register_extcon(struct dwc3_qcom *qcom)
128 {
129         struct device           *dev = qcom->dev;
130         struct extcon_dev       *host_edev;
131         int                     ret;
132
133         if (!of_property_read_bool(dev->of_node, "extcon"))
134                 return 0;
135
136         qcom->edev = extcon_get_edev_by_phandle(dev, 0);
137         if (IS_ERR(qcom->edev))
138                 return PTR_ERR(qcom->edev);
139
140         qcom->vbus_nb.notifier_call = dwc3_qcom_vbus_notifier;
141
142         qcom->host_edev = extcon_get_edev_by_phandle(dev, 1);
143         if (IS_ERR(qcom->host_edev))
144                 qcom->host_edev = NULL;
145
146         ret = devm_extcon_register_notifier(dev, qcom->edev, EXTCON_USB,
147                                             &qcom->vbus_nb);
148         if (ret < 0) {
149                 dev_err(dev, "VBUS notifier register failed\n");
150                 return ret;
151         }
152
153         if (qcom->host_edev)
154                 host_edev = qcom->host_edev;
155         else
156                 host_edev = qcom->edev;
157
158         qcom->host_nb.notifier_call = dwc3_qcom_host_notifier;
159         ret = devm_extcon_register_notifier(dev, host_edev, EXTCON_USB_HOST,
160                                             &qcom->host_nb);
161         if (ret < 0) {
162                 dev_err(dev, "Host notifier register failed\n");
163                 return ret;
164         }
165
166         /* Update initial VBUS override based on extcon state */
167         if (extcon_get_state(qcom->edev, EXTCON_USB) ||
168             !extcon_get_state(host_edev, EXTCON_USB_HOST))
169                 dwc3_qcom_vbus_notifier(&qcom->vbus_nb, true, qcom->edev);
170         else
171                 dwc3_qcom_vbus_notifier(&qcom->vbus_nb, false, qcom->edev);
172
173         return 0;
174 }
175
176 static void dwc3_qcom_disable_interrupts(struct dwc3_qcom *qcom)
177 {
178         if (qcom->hs_phy_irq) {
179                 disable_irq_wake(qcom->hs_phy_irq);
180                 disable_irq_nosync(qcom->hs_phy_irq);
181         }
182
183         if (qcom->dp_hs_phy_irq) {
184                 disable_irq_wake(qcom->dp_hs_phy_irq);
185                 disable_irq_nosync(qcom->dp_hs_phy_irq);
186         }
187
188         if (qcom->dm_hs_phy_irq) {
189                 disable_irq_wake(qcom->dm_hs_phy_irq);
190                 disable_irq_nosync(qcom->dm_hs_phy_irq);
191         }
192
193         if (qcom->ss_phy_irq) {
194                 disable_irq_wake(qcom->ss_phy_irq);
195                 disable_irq_nosync(qcom->ss_phy_irq);
196         }
197 }
198
199 static void dwc3_qcom_enable_interrupts(struct dwc3_qcom *qcom)
200 {
201         if (qcom->hs_phy_irq) {
202                 enable_irq(qcom->hs_phy_irq);
203                 enable_irq_wake(qcom->hs_phy_irq);
204         }
205
206         if (qcom->dp_hs_phy_irq) {
207                 enable_irq(qcom->dp_hs_phy_irq);
208                 enable_irq_wake(qcom->dp_hs_phy_irq);
209         }
210
211         if (qcom->dm_hs_phy_irq) {
212                 enable_irq(qcom->dm_hs_phy_irq);
213                 enable_irq_wake(qcom->dm_hs_phy_irq);
214         }
215
216         if (qcom->ss_phy_irq) {
217                 enable_irq(qcom->ss_phy_irq);
218                 enable_irq_wake(qcom->ss_phy_irq);
219         }
220 }
221
222 static int dwc3_qcom_suspend(struct dwc3_qcom *qcom)
223 {
224         u32 val;
225         int i;
226
227         if (qcom->is_suspended)
228                 return 0;
229
230         val = readl(qcom->qscratch_base + PWR_EVNT_IRQ_STAT_REG);
231         if (!(val & PWR_EVNT_LPM_IN_L2_MASK))
232                 dev_err(qcom->dev, "HS-PHY not in L2\n");
233
234         for (i = qcom->num_clocks - 1; i >= 0; i--)
235                 clk_disable_unprepare(qcom->clks[i]);
236
237         if (device_may_wakeup(qcom->dev))
238                 dwc3_qcom_enable_interrupts(qcom);
239
240         qcom->is_suspended = true;
241
242         return 0;
243 }
244
245 static int dwc3_qcom_resume(struct dwc3_qcom *qcom)
246 {
247         int ret;
248         int i;
249
250         if (!qcom->is_suspended)
251                 return 0;
252
253         if (device_may_wakeup(qcom->dev))
254                 dwc3_qcom_disable_interrupts(qcom);
255
256         for (i = 0; i < qcom->num_clocks; i++) {
257                 ret = clk_prepare_enable(qcom->clks[i]);
258                 if (ret < 0) {
259                         while (--i >= 0)
260                                 clk_disable_unprepare(qcom->clks[i]);
261                         return ret;
262                 }
263         }
264
265         /* Clear existing events from PHY related to L2 in/out */
266         dwc3_qcom_setbits(qcom->qscratch_base, PWR_EVNT_IRQ_STAT_REG,
267                           PWR_EVNT_LPM_IN_L2_MASK | PWR_EVNT_LPM_OUT_L2_MASK);
268
269         qcom->is_suspended = false;
270
271         return 0;
272 }
273
274 static irqreturn_t qcom_dwc3_resume_irq(int irq, void *data)
275 {
276         struct dwc3_qcom *qcom = data;
277         struct dwc3     *dwc = platform_get_drvdata(qcom->dwc3);
278
279         /* If pm_suspended then let pm_resume take care of resuming h/w */
280         if (qcom->pm_suspended)
281                 return IRQ_HANDLED;
282
283         if (dwc->xhci)
284                 pm_runtime_resume(&dwc->xhci->dev);
285
286         return IRQ_HANDLED;
287 }
288
289 static void dwc3_qcom_select_utmi_clk(struct dwc3_qcom *qcom)
290 {
291         /* Configure dwc3 to use UTMI clock as PIPE clock not present */
292         dwc3_qcom_setbits(qcom->qscratch_base, QSCRATCH_GENERAL_CFG,
293                           PIPE_UTMI_CLK_DIS);
294
295         usleep_range(100, 1000);
296
297         dwc3_qcom_setbits(qcom->qscratch_base, QSCRATCH_GENERAL_CFG,
298                           PIPE_UTMI_CLK_SEL | PIPE3_PHYSTATUS_SW);
299
300         usleep_range(100, 1000);
301
302         dwc3_qcom_clrbits(qcom->qscratch_base, QSCRATCH_GENERAL_CFG,
303                           PIPE_UTMI_CLK_DIS);
304 }
305
306 static int dwc3_qcom_setup_irq(struct platform_device *pdev)
307 {
308         struct dwc3_qcom *qcom = platform_get_drvdata(pdev);
309         int irq, ret;
310
311         irq = platform_get_irq_byname(pdev, "hs_phy_irq");
312         if (irq > 0) {
313                 /* Keep wakeup interrupts disabled until suspend */
314                 irq_set_status_flags(irq, IRQ_NOAUTOEN);
315                 ret = devm_request_threaded_irq(qcom->dev, irq, NULL,
316                                         qcom_dwc3_resume_irq,
317                                         IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
318                                         "qcom_dwc3 HS", qcom);
319                 if (ret) {
320                         dev_err(qcom->dev, "hs_phy_irq failed: %d\n", ret);
321                         return ret;
322                 }
323                 qcom->hs_phy_irq = irq;
324         }
325
326         irq = platform_get_irq_byname(pdev, "dp_hs_phy_irq");
327         if (irq > 0) {
328                 irq_set_status_flags(irq, IRQ_NOAUTOEN);
329                 ret = devm_request_threaded_irq(qcom->dev, irq, NULL,
330                                         qcom_dwc3_resume_irq,
331                                         IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
332                                         "qcom_dwc3 DP_HS", qcom);
333                 if (ret) {
334                         dev_err(qcom->dev, "dp_hs_phy_irq failed: %d\n", ret);
335                         return ret;
336                 }
337                 qcom->dp_hs_phy_irq = irq;
338         }
339
340         irq = platform_get_irq_byname(pdev, "dm_hs_phy_irq");
341         if (irq > 0) {
342                 irq_set_status_flags(irq, IRQ_NOAUTOEN);
343                 ret = devm_request_threaded_irq(qcom->dev, irq, NULL,
344                                         qcom_dwc3_resume_irq,
345                                         IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
346                                         "qcom_dwc3 DM_HS", qcom);
347                 if (ret) {
348                         dev_err(qcom->dev, "dm_hs_phy_irq failed: %d\n", ret);
349                         return ret;
350                 }
351                 qcom->dm_hs_phy_irq = irq;
352         }
353
354         irq = platform_get_irq_byname(pdev, "ss_phy_irq");
355         if (irq > 0) {
356                 irq_set_status_flags(irq, IRQ_NOAUTOEN);
357                 ret = devm_request_threaded_irq(qcom->dev, irq, NULL,
358                                         qcom_dwc3_resume_irq,
359                                         IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
360                                         "qcom_dwc3 SS", qcom);
361                 if (ret) {
362                         dev_err(qcom->dev, "ss_phy_irq failed: %d\n", ret);
363                         return ret;
364                 }
365                 qcom->ss_phy_irq = irq;
366         }
367
368         return 0;
369 }
370
371 static int dwc3_qcom_clk_init(struct dwc3_qcom *qcom, int count)
372 {
373         struct device           *dev = qcom->dev;
374         struct device_node      *np = dev->of_node;
375         int                     i;
376
377         qcom->num_clocks = count;
378
379         if (!count)
380                 return 0;
381
382         qcom->clks = devm_kcalloc(dev, qcom->num_clocks,
383                                   sizeof(struct clk *), GFP_KERNEL);
384         if (!qcom->clks)
385                 return -ENOMEM;
386
387         for (i = 0; i < qcom->num_clocks; i++) {
388                 struct clk      *clk;
389                 int             ret;
390
391                 clk = of_clk_get(np, i);
392                 if (IS_ERR(clk)) {
393                         while (--i >= 0)
394                                 clk_put(qcom->clks[i]);
395                         return PTR_ERR(clk);
396                 }
397
398                 ret = clk_prepare_enable(clk);
399                 if (ret < 0) {
400                         while (--i >= 0) {
401                                 clk_disable_unprepare(qcom->clks[i]);
402                                 clk_put(qcom->clks[i]);
403                         }
404                         clk_put(clk);
405
406                         return ret;
407                 }
408
409                 qcom->clks[i] = clk;
410         }
411
412         return 0;
413 }
414
415 static int dwc3_qcom_probe(struct platform_device *pdev)
416 {
417         struct device_node      *np = pdev->dev.of_node, *dwc3_np;
418         struct device           *dev = &pdev->dev;
419         struct dwc3_qcom        *qcom;
420         struct resource         *res;
421         int                     ret, i;
422         bool                    ignore_pipe_clk;
423
424         qcom = devm_kzalloc(&pdev->dev, sizeof(*qcom), GFP_KERNEL);
425         if (!qcom)
426                 return -ENOMEM;
427
428         platform_set_drvdata(pdev, qcom);
429         qcom->dev = &pdev->dev;
430
431         qcom->resets = devm_reset_control_array_get_optional_exclusive(dev);
432         if (IS_ERR(qcom->resets)) {
433                 ret = PTR_ERR(qcom->resets);
434                 dev_err(&pdev->dev, "failed to get resets, err=%d\n", ret);
435                 return ret;
436         }
437
438         ret = reset_control_assert(qcom->resets);
439         if (ret) {
440                 dev_err(&pdev->dev, "failed to assert resets, err=%d\n", ret);
441                 return ret;
442         }
443
444         usleep_range(10, 1000);
445
446         ret = reset_control_deassert(qcom->resets);
447         if (ret) {
448                 dev_err(&pdev->dev, "failed to deassert resets, err=%d\n", ret);
449                 goto reset_assert;
450         }
451
452         ret = dwc3_qcom_clk_init(qcom, of_count_phandle_with_args(np,
453                                                 "clocks", "#clock-cells"));
454         if (ret) {
455                 dev_err(dev, "failed to get clocks\n");
456                 goto reset_assert;
457         }
458
459         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
460         qcom->qscratch_base = devm_ioremap_resource(dev, res);
461         if (IS_ERR(qcom->qscratch_base)) {
462                 dev_err(dev, "failed to map qscratch, err=%d\n", ret);
463                 ret = PTR_ERR(qcom->qscratch_base);
464                 goto clk_disable;
465         }
466
467         ret = dwc3_qcom_setup_irq(pdev);
468         if (ret)
469                 goto clk_disable;
470
471         dwc3_np = of_get_child_by_name(np, "dwc3");
472         if (!dwc3_np) {
473                 dev_err(dev, "failed to find dwc3 core child\n");
474                 ret = -ENODEV;
475                 goto clk_disable;
476         }
477
478         /*
479          * Disable pipe_clk requirement if specified. Used when dwc3
480          * operates without SSPHY and only HS/FS/LS modes are supported.
481          */
482         ignore_pipe_clk = device_property_read_bool(dev,
483                                 "qcom,select-utmi-as-pipe-clk");
484         if (ignore_pipe_clk)
485                 dwc3_qcom_select_utmi_clk(qcom);
486
487         ret = of_platform_populate(np, NULL, NULL, dev);
488         if (ret) {
489                 dev_err(dev, "failed to register dwc3 core - %d\n", ret);
490                 goto clk_disable;
491         }
492
493         qcom->dwc3 = of_find_device_by_node(dwc3_np);
494         if (!qcom->dwc3) {
495                 dev_err(&pdev->dev, "failed to get dwc3 platform device\n");
496                 ret = -ENODEV;
497                 goto depopulate;
498         }
499
500         qcom->mode = usb_get_dr_mode(&qcom->dwc3->dev);
501
502         /* enable vbus override for device mode */
503         if (qcom->mode == USB_DR_MODE_PERIPHERAL)
504                 dwc3_qcom_vbus_overrride_enable(qcom, true);
505
506         /* register extcon to override sw_vbus on Vbus change later */
507         ret = dwc3_qcom_register_extcon(qcom);
508         if (ret)
509                 goto depopulate;
510
511         device_init_wakeup(&pdev->dev, 1);
512         qcom->is_suspended = false;
513         pm_runtime_set_active(dev);
514         pm_runtime_enable(dev);
515         pm_runtime_forbid(dev);
516
517         return 0;
518
519 depopulate:
520         of_platform_depopulate(&pdev->dev);
521 clk_disable:
522         for (i = qcom->num_clocks - 1; i >= 0; i--) {
523                 clk_disable_unprepare(qcom->clks[i]);
524                 clk_put(qcom->clks[i]);
525         }
526 reset_assert:
527         reset_control_assert(qcom->resets);
528
529         return ret;
530 }
531
532 static int dwc3_qcom_remove(struct platform_device *pdev)
533 {
534         struct dwc3_qcom *qcom = platform_get_drvdata(pdev);
535         struct device *dev = &pdev->dev;
536         int i;
537
538         of_platform_depopulate(dev);
539
540         for (i = qcom->num_clocks - 1; i >= 0; i--) {
541                 clk_disable_unprepare(qcom->clks[i]);
542                 clk_put(qcom->clks[i]);
543         }
544         qcom->num_clocks = 0;
545
546         reset_control_assert(qcom->resets);
547
548         pm_runtime_allow(dev);
549         pm_runtime_disable(dev);
550
551         return 0;
552 }
553
554 static int __maybe_unused dwc3_qcom_pm_suspend(struct device *dev)
555 {
556         struct dwc3_qcom *qcom = dev_get_drvdata(dev);
557         int ret = 0;
558
559         ret = dwc3_qcom_suspend(qcom);
560         if (!ret)
561                 qcom->pm_suspended = true;
562
563         return ret;
564 }
565
566 static int __maybe_unused dwc3_qcom_pm_resume(struct device *dev)
567 {
568         struct dwc3_qcom *qcom = dev_get_drvdata(dev);
569         int ret;
570
571         ret = dwc3_qcom_resume(qcom);
572         if (!ret)
573                 qcom->pm_suspended = false;
574
575         return ret;
576 }
577
578 static int __maybe_unused dwc3_qcom_runtime_suspend(struct device *dev)
579 {
580         struct dwc3_qcom *qcom = dev_get_drvdata(dev);
581
582         return dwc3_qcom_suspend(qcom);
583 }
584
585 static int __maybe_unused dwc3_qcom_runtime_resume(struct device *dev)
586 {
587         struct dwc3_qcom *qcom = dev_get_drvdata(dev);
588
589         return dwc3_qcom_resume(qcom);
590 }
591
592 static const struct dev_pm_ops dwc3_qcom_dev_pm_ops = {
593         SET_SYSTEM_SLEEP_PM_OPS(dwc3_qcom_pm_suspend, dwc3_qcom_pm_resume)
594         SET_RUNTIME_PM_OPS(dwc3_qcom_runtime_suspend, dwc3_qcom_runtime_resume,
595                            NULL)
596 };
597
598 static const struct of_device_id dwc3_qcom_of_match[] = {
599         { .compatible = "qcom,dwc3" },
600         { .compatible = "qcom,msm8996-dwc3" },
601         { .compatible = "qcom,sdm845-dwc3" },
602         { }
603 };
604 MODULE_DEVICE_TABLE(of, dwc3_qcom_of_match);
605
606 static struct platform_driver dwc3_qcom_driver = {
607         .probe          = dwc3_qcom_probe,
608         .remove         = dwc3_qcom_remove,
609         .driver         = {
610                 .name   = "dwc3-qcom",
611                 .pm     = &dwc3_qcom_dev_pm_ops,
612                 .of_match_table = dwc3_qcom_of_match,
613         },
614 };
615
616 module_platform_driver(dwc3_qcom_driver);
617
618 MODULE_LICENSE("GPL v2");
619 MODULE_DESCRIPTION("DesignWare DWC3 QCOM Glue Driver");