usb: ehci: add rockchip relinquishing port quirk support
[firefly-linux-kernel-4.4.55.git] / drivers / usb / host / ehci1-rockchip.c
1 /* ehci-msm.c - HSUSB Host Controller Driver Implementation
2  *
3  * Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
4  *
5  * Partly derived from ehci-fsl.c and ehci-hcd.c
6  * Copyright (c) 2000-2004 by David Brownell
7  * Copyright (c) 2005 MontaVista Software
8  *
9  * All source code in this file is licensed under the following license except
10  * where indicated.
11  *
12  * This program is free software; you can redistribute it and/or modify it
13  * under the terms of the GNU General Public License version 2 as published
14  * by the Free Software Foundation.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19  *
20  * See the GNU General Public License for more details.
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, you can find it at http://www.fsf.org
23  */
24
25 # include <linux/platform_device.h>
26 # include <linux/clk.h>
27 # include <linux/err.h>
28 # include <linux/device.h>
29 # include <linux/of.h>
30 # include <linux/of_platform.h>
31 # include "ehci.h"
32 # include "../dwc_otg_310/usbdev_rk.h"
33
34 static int rkehci1_status = 1;
35 static struct ehci_hcd *g_ehci;
36 #define EHCI1_PRINT(x...)       printk(KERN_INFO "EHCI1: " x)
37
38 static void ehci1_rk_port_power(struct ehci_hcd *ehci, int is_on)
39 {
40         unsigned port;
41
42         if (!HCS_PPC(ehci->hcs_params))
43                 return;
44
45         ehci_dbg(ehci, "...power%s ports...\n", is_on ? "up" : "down");
46         for (port = HCS_N_PORTS(ehci->hcs_params); port > 0;)
47                 (void)ehci_hub_control(ehci_to_hcd(ehci),
48                                        is_on ? SetPortFeature :
49                                        ClearPortFeature, USB_PORT_FEAT_POWER,
50                                        port--, NULL, 0);
51         /* Flush those writes */
52         ehci_readl(ehci, &ehci->regs->command);
53         msleep(20);
54 }
55
56 static struct hc_driver rk_ehci1_driver = {
57         .description = hcd_name,
58         .product_desc = "Rockchip On-Chip EHCI1 Host Controller",
59         .hcd_priv_size = sizeof(struct ehci_hcd),
60
61         /*
62          * generic hardware linkage
63          */
64         .irq = ehci_irq,
65         .flags = HCD_USB2 | HCD_MEMORY,
66
67         .reset = ehci_init,
68         .start = ehci_run,
69
70         .stop = ehci_stop,
71         .shutdown = ehci_shutdown,
72
73         /*
74          * managing i/o requests and associated device resources
75          */
76         .urb_enqueue = ehci_urb_enqueue,
77         .urb_dequeue = ehci_urb_dequeue,
78         .endpoint_disable = ehci_endpoint_disable,
79         .endpoint_reset = ehci_endpoint_reset,
80         .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
81
82         /*
83          * scheduling support
84          */
85         .get_frame_number = ehci_get_frame,
86
87         /*
88          * root hub support
89          */
90         .hub_status_data = ehci_hub_status_data,
91         .hub_control = ehci_hub_control,
92         .relinquish_port = ehci_relinquish_port,
93         .port_handed_over = ehci_port_handed_over,
94
95         /*
96          * PM support
97          */
98 #ifdef CONFIG_PM
99         .bus_suspend = ehci_bus_suspend,
100         .bus_resume = ehci_bus_resume,
101 #endif
102 };
103
104 static ssize_t ehci1_rk_power_show(struct device *_dev,
105                                       struct device_attribute *attr, char *buf)
106 {
107         return sprintf(buf, "%d\n", rkehci1_status);
108 }
109
110 static ssize_t ehci1_rk_power_store(struct device *_dev,
111                                        struct device_attribute *attr,
112                                        const char *buf, size_t count)
113 {
114         uint32_t val = simple_strtoul(buf, NULL, 16);
115         struct usb_hcd *hcd = dev_get_drvdata(_dev);
116         struct ehci_hcd *ehci = hcd_to_ehci(hcd);
117         struct rkehci_platform_data *pldata = _dev->platform_data;
118
119         printk("%s: %d setting to: %d\n", __func__, rkehci1_status, val);
120         if (val == rkehci1_status)
121                 goto out;
122
123         rkehci1_status = val;
124         switch (val) {
125         case 0: /* power down */
126                 ehci1_rk_port_power(ehci, 0);
127                 writel_relaxed(0, hcd->regs + 0xb0);
128                 dsb();
129                 msleep(5);
130                 usb_remove_hcd(hcd);
131                 break;
132         case 1: /* power on */
133                 pldata->soft_reset(pldata, RST_POR);
134                 usb_add_hcd(hcd, hcd->irq, IRQF_DISABLED | IRQF_SHARED);
135
136                 ehci1_rk_port_power(ehci, 1);
137                 writel_relaxed(1, hcd->regs + 0xb0);
138                 writel_relaxed(0x1d4d, hcd->regs + 0x90);
139                 writel_relaxed(0x4, hcd->regs + 0xa0);
140                 dsb();
141                 break;
142         default:
143                 break;
144         }
145 out:
146         return count;
147 }
148
149 static DEVICE_ATTR(ehci1_rk_power, S_IRUGO | S_IWUSR, ehci1_rk_power_show,
150                    ehci1_rk_power_store);
151
152 static ssize_t ehci1_debug_show(struct device *_dev,
153                                struct device_attribute *attr, char *buf)
154 {
155         volatile uint32_t *addr;
156
157         EHCI1_PRINT("******** EHCI Capability Registers **********\n");
158         addr = &g_ehci->caps->hc_capbase;
159         EHCI1_PRINT("HCIVERSION / CAPLENGTH  @0x%08x:  0x%08x\n",
160                         (uint32_t) addr, readl_relaxed(addr));
161         addr = &g_ehci->caps->hcs_params;
162         EHCI1_PRINT("HCSPARAMS               @0x%08x:  0x%08x\n",
163                         (uint32_t) addr, readl_relaxed(addr));
164         addr = &g_ehci->caps->hcc_params;
165         EHCI1_PRINT("HCCPARAMS               @0x%08x:  0x%08x\n",
166                         (uint32_t) addr, readl_relaxed(addr));
167         EHCI1_PRINT("********* EHCI Operational Registers *********\n");
168         addr = &g_ehci->regs->command;
169         EHCI1_PRINT("USBCMD                  @0x%08x:  0x%08x\n",
170                         (uint32_t) addr, readl_relaxed(addr));
171         addr = &g_ehci->regs->status;
172         EHCI1_PRINT("USBSTS                  @0x%08x:  0x%08x\n",
173                         (uint32_t) addr, readl_relaxed(addr));
174         addr = &g_ehci->regs->intr_enable;
175         EHCI1_PRINT("USBINTR                 @0x%08x:  0x%08x\n",
176                         (uint32_t) addr, readl_relaxed(addr));
177         addr = &g_ehci->regs->frame_index;
178         EHCI1_PRINT("FRINDEX                 @0x%08x:  0x%08x\n",
179                         (uint32_t) addr, readl_relaxed(addr));
180         addr = &g_ehci->regs->segment;
181         EHCI1_PRINT("CTRLDSSEGMENT           @0x%08x:  0x%08x\n",
182                         (uint32_t) addr, readl_relaxed(addr));
183         addr = &g_ehci->regs->frame_list;
184         EHCI1_PRINT("PERIODICLISTBASE        @0x%08x:  0x%08x\n",
185                         (uint32_t) addr, readl_relaxed(addr));
186         addr = &g_ehci->regs->async_next;
187         EHCI1_PRINT("ASYNCLISTADDR           @0x%08x:  0x%08x\n",
188                         (uint32_t) addr, readl_relaxed(addr));
189         addr = &g_ehci->regs->configured_flag;
190         EHCI1_PRINT("CONFIGFLAG              @0x%08x:  0x%08x\n",
191                         (uint32_t) addr, readl_relaxed(addr));
192         addr = g_ehci->regs->port_status;
193         EHCI1_PRINT("PORTSC                  @0x%08x:  0x%08x\n",
194                         (uint32_t) addr, readl_relaxed(addr));
195         return sprintf(buf, "EHCI1 Registers Dump\n");
196 }
197
198 static DEVICE_ATTR(debug_ehci1, S_IRUGO, ehci1_debug_show, NULL);
199
200 static struct of_device_id rk_ehci1_of_match[] = {
201         {
202          .compatible = "rockchip,rk3188_rk_ehci_host",
203          .data = &rkehci_pdata_rk3188,
204          },
205         {
206          .compatible = "rockchip,rk3288_rk_ehci1_host",
207          .data = &rkehci1_pdata_rk3288,
208          },
209         {},
210 };
211
212 MODULE_DEVICE_TABLE(of, rk_ehci1_of_match);
213
214 static int ehci1_rk_probe(struct platform_device *pdev)
215 {
216         struct usb_hcd *hcd;
217         struct ehci_hcd *ehci;
218         struct resource *res;
219         struct device *dev = &pdev->dev;
220         struct rkehci_platform_data *pldata;
221         int ret;
222         int retval = 0;
223         static u64 usb_dmamask = 0xffffffffUL;
224         struct device_node *node = pdev->dev.of_node;
225         const struct of_device_id *match =
226             of_match_device(of_match_ptr(rk_ehci1_of_match), &pdev->dev);
227
228         dev_dbg(&pdev->dev, "ehci1_rk proble\n");
229
230         if (match && match->data) {
231                 dev->platform_data  = (void *)match->data;
232         } else {
233                 dev_err(dev, "ehci1_rk match failed\n");
234                 return -EINVAL;
235         }
236
237         pldata = dev->platform_data;
238         pldata->dev = dev;
239
240         if (!node) {
241                 dev_err(dev, "device node not found\n");
242                 return -EINVAL;
243         }
244
245         dev->dma_mask = &usb_dmamask;
246
247         retval = device_create_file(dev, &dev_attr_ehci1_rk_power);
248         retval = device_create_file(dev, &dev_attr_debug_ehci1);
249         hcd = usb_create_hcd(&rk_ehci1_driver, &pdev->dev, dev_name(&pdev->dev));
250         if (!hcd) {
251                 dev_err(&pdev->dev, "Unable to create HCD\n");
252                 return -ENOMEM;
253         }
254
255         if (pldata->hw_init)
256                 pldata->hw_init();
257
258         if (pldata->clock_init) {
259                 pldata->clock_init(pldata);
260                 pldata->clock_enable(pldata, 1);
261         }
262
263         if (pldata->soft_reset)
264                 pldata->soft_reset(pldata, RST_POR);;
265
266         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
267         if (!res) {
268                 dev_err(&pdev->dev, "Unable to get memory resource\n");
269                 ret = -ENODEV;
270                 goto put_hcd;
271         }
272
273         hcd->rsrc_start = res->start;
274         hcd->rsrc_len = resource_size(res);
275         hcd->regs = devm_ioremap_resource(dev, res);
276
277         if (!hcd->regs) {
278                 dev_err(&pdev->dev, "ioremap failed\n");
279                 ret = -ENOMEM;
280                 goto put_hcd;
281         }
282
283         hcd->irq = platform_get_irq(pdev, 0);
284         if (hcd->irq < 0) {
285                 dev_err(&pdev->dev, "Unable to get IRQ resource\n");
286                 ret = hcd->irq;
287                 goto put_hcd;
288         }
289
290         ehci = hcd_to_ehci(hcd);
291         ehci->caps = hcd->regs;
292         ehci->regs = hcd->regs + 0x10;
293         printk("%s %p %p\n", __func__, ehci->caps, ehci->regs);
294
295         dbg_hcs_params(ehci, "reset");
296         dbg_hcc_params(ehci, "reset");
297
298         ehci->hcs_params = readl(&ehci->caps->hcs_params);
299
300         ret = usb_add_hcd(hcd, hcd->irq, IRQF_DISABLED | IRQF_SHARED);
301         if (ret) {
302                 dev_err(&pdev->dev, "Failed to add USB HCD\n");
303                 goto put_hcd;
304         }
305
306         g_ehci = ehci;
307         ehci1_rk_port_power(ehci, 1);
308         writel_relaxed(1, hcd->regs + 0xb0);
309         writel_relaxed(0x1d4d, hcd->regs + 0x90);
310         writel_relaxed(0x4, hcd->regs + 0xa0);
311         dsb();
312
313         printk("%s ok\n", __func__);
314
315         return 0;
316
317 put_hcd:
318         if (pldata->clock_enable)
319                 pldata->clock_enable(pldata, 0);
320         usb_put_hcd(hcd);
321
322         return ret;
323 }
324
325 static int ehci1_rk_remove(struct platform_device *pdev)
326 {
327         struct usb_hcd *hcd = platform_get_drvdata(pdev);
328
329         usb_put_hcd(hcd);
330
331         return 0;
332 }
333
334 #ifdef CONFIG_PM
335 static int ehci1_rk_pm_suspend(struct device *dev)
336 {
337         struct usb_hcd *hcd = dev_get_drvdata(dev);
338         bool do_wakeup = device_may_wakeup(dev);
339         int ret;
340
341         dev_dbg(dev, "ehci1-rockchip PM suspend\n");
342         ret = ehci_suspend(hcd, do_wakeup);
343
344         return ret;
345 }
346
347 static int ehci1_rk_pm_resume(struct device *dev)
348 {
349         struct usb_hcd *hcd = dev_get_drvdata(dev);
350
351         dev_dbg(dev, "ehci1-rockchip PM resume\n");
352         ehci_resume(hcd, false);
353
354         return 0;
355 }
356 #else
357 #define ehci1_rk_pm_suspend     NULL
358 #define ehci1_rk_pm_resume      NULL
359 #endif
360
361 static const struct dev_pm_ops ehci1_rk_dev_pm_ops = {
362         .suspend = ehci1_rk_pm_suspend,
363         .resume = ehci1_rk_pm_resume,
364 };
365
366 static struct platform_driver ehci1_rk_driver = {
367         .probe = ehci1_rk_probe,
368         .remove = ehci1_rk_remove,
369         .driver = {
370                    .name = "rockchip_ehci1_host",
371                    .of_match_table = of_match_ptr(rk_ehci1_of_match),
372 #ifdef CONFIG_PM
373                    .pm = &ehci1_rk_dev_pm_ops,
374 #endif
375                    },
376 };