659bcf0fd41481e167180964aa456d2fefb1eaea
[firefly-linux-kernel-4.4.55.git] / drivers / usb / host / ehci-rkhsic.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 rkhsic_status = 1;
35 static struct ehci_hcd *g_hsic_ehci;
36 #define HSIC_EHCI_PRINT(x...)   printk(KERN_INFO "HSIC_EHCI: " x)
37
38 static struct rkehci_pdata_id rkhsic_pdata[] = {
39         {
40          .name = "rk3188-hsic",
41          .pdata = &rkhsic_pdata_rk3188,
42          },
43         {
44          .name = "rk3288-hsic",
45          .pdata = &rkhsic_pdata_rk3288,
46          },
47         {},
48 };
49
50 static void ehci_rkhsic_port_power(struct ehci_hcd *ehci, int is_on)
51 {
52         unsigned port;
53
54         if (!HCS_PPC(ehci->hcs_params))
55                 return;
56
57         ehci_dbg(ehci, "...power%s ports...\n", is_on ? "up" : "down");
58         for (port = HCS_N_PORTS(ehci->hcs_params); port > 0;)
59                 (void)ehci_hub_control(ehci_to_hcd(ehci),
60                                        is_on ? SetPortFeature :
61                                        ClearPortFeature, USB_PORT_FEAT_POWER,
62                                        port--, NULL, 0);
63         /* Flush those writes */
64         ehci_readl(ehci, &ehci->regs->command);
65         msleep(20);
66 }
67
68 static struct hc_driver rk_hsic_driver = {
69         .description = hcd_name,
70         .product_desc = "Rockchip On-Chip HSIC EHCI Host Controller",
71         .hcd_priv_size = sizeof(struct ehci_hcd),
72
73         /*
74          * generic hardware linkage
75          */
76         .irq = ehci_irq,
77         .flags = HCD_USB2 | HCD_MEMORY,
78
79         .reset = ehci_init,
80         .start = ehci_run,
81
82         .stop = ehci_stop,
83         .shutdown = ehci_shutdown,
84
85         /*
86          * managing i/o requests and associated device resources
87          */
88         .urb_enqueue = ehci_urb_enqueue,
89         .urb_dequeue = ehci_urb_dequeue,
90         .endpoint_disable = ehci_endpoint_disable,
91         .endpoint_reset = ehci_endpoint_reset,
92         .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
93
94         /*
95          * scheduling support
96          */
97         .get_frame_number = ehci_get_frame,
98
99         /*
100          * root hub support
101          */
102         .hub_status_data = ehci_hub_status_data,
103         .hub_control = ehci_hub_control,
104         .relinquish_port = ehci_relinquish_port,
105         .port_handed_over = ehci_port_handed_over,
106
107         /*
108          * PM support
109          */
110 #ifdef CONFIG_PM
111         .bus_suspend = ehci_bus_suspend,
112         .bus_resume = ehci_bus_resume,
113 #endif
114 };
115
116 static ssize_t ehci_rkhsic_power_show(struct device *_dev,
117                                       struct device_attribute *attr, char *buf)
118 {
119         return sprintf(buf, "%d\n", rkhsic_status);
120 }
121
122 static ssize_t ehci_rkhsic_power_store(struct device *_dev,
123                                        struct device_attribute *attr,
124                                        const char *buf, size_t count)
125 {
126         uint32_t val = simple_strtoul(buf, NULL, 16);
127         struct usb_hcd *hcd = dev_get_drvdata(_dev);
128         struct ehci_hcd *ehci = hcd_to_ehci(hcd);
129         struct rkehci_platform_data *pldata = _dev->platform_data;
130
131         printk("%s: %d setting to: %d\n", __func__, rkhsic_status, val);
132         if (val == rkhsic_status)
133                 goto out;
134
135         rkhsic_status = val;
136         switch (val) {
137         case 0: /* power down */
138                 ehci_rkhsic_port_power(ehci, 0);
139                 writel_relaxed(0, hcd->regs + 0xb0);
140                 dsb();
141                 msleep(5);
142                 usb_remove_hcd(hcd);
143                 break;
144         case 1: /* power on */
145                 pldata->soft_reset(pldata, RST_POR);
146                 usb_add_hcd(hcd, hcd->irq, IRQF_DISABLED | IRQF_SHARED);
147
148                 ehci_rkhsic_port_power(ehci, 1);
149                 writel_relaxed(1, hcd->regs + 0xb0);
150                 writel_relaxed(0x1d4d, hcd->regs + 0x90);
151                 writel_relaxed(0x4, hcd->regs + 0xa0);
152                 dsb();
153                 break;
154         default:
155                 break;
156         }
157 out:
158         return count;
159 }
160
161 static DEVICE_ATTR(ehci_rkhsic_power, S_IRUGO | S_IWUSR, ehci_rkhsic_power_show,
162                    ehci_rkhsic_power_store);
163
164 static ssize_t hsic_debug_show(struct device *_dev,
165                                struct device_attribute *attr, char *buf)
166 {
167         volatile uint32_t *addr;
168
169         HSIC_EHCI_PRINT("******** EHCI Capability Registers **********\n");
170         addr = &g_hsic_ehci->caps->hc_capbase;
171         HSIC_EHCI_PRINT("HCIVERSION / CAPLENGTH  @0x%08x:  0x%08x\n",
172                         (uint32_t) addr, readl_relaxed(addr));
173         addr = &g_hsic_ehci->caps->hcs_params;
174         HSIC_EHCI_PRINT("HCSPARAMS               @0x%08x:  0x%08x\n",
175                         (uint32_t) addr, readl_relaxed(addr));
176         addr = &g_hsic_ehci->caps->hcc_params;
177         HSIC_EHCI_PRINT("HCCPARAMS               @0x%08x:  0x%08x\n",
178                         (uint32_t) addr, readl_relaxed(addr));
179         HSIC_EHCI_PRINT("********* EHCI Operational Registers *********\n");
180         addr = &g_hsic_ehci->regs->command;
181         HSIC_EHCI_PRINT("USBCMD                  @0x%08x:  0x%08x\n",
182                         (uint32_t) addr, readl_relaxed(addr));
183         addr = &g_hsic_ehci->regs->status;
184         HSIC_EHCI_PRINT("USBSTS                  @0x%08x:  0x%08x\n",
185                         (uint32_t) addr, readl_relaxed(addr));
186         addr = &g_hsic_ehci->regs->intr_enable;
187         HSIC_EHCI_PRINT("USBINTR                 @0x%08x:  0x%08x\n",
188                         (uint32_t) addr, readl_relaxed(addr));
189         addr = &g_hsic_ehci->regs->frame_index;
190         HSIC_EHCI_PRINT("FRINDEX                 @0x%08x:  0x%08x\n",
191                         (uint32_t) addr, readl_relaxed(addr));
192         addr = &g_hsic_ehci->regs->segment;
193         HSIC_EHCI_PRINT("CTRLDSSEGMENT           @0x%08x:  0x%08x\n",
194                         (uint32_t) addr, readl_relaxed(addr));
195         addr = &g_hsic_ehci->regs->frame_list;
196         HSIC_EHCI_PRINT("PERIODICLISTBASE        @0x%08x:  0x%08x\n",
197                         (uint32_t) addr, readl_relaxed(addr));
198         addr = &g_hsic_ehci->regs->async_next;
199         HSIC_EHCI_PRINT("ASYNCLISTADDR           @0x%08x:  0x%08x\n",
200                         (uint32_t) addr, readl_relaxed(addr));
201         addr = &g_hsic_ehci->regs->configured_flag;
202         HSIC_EHCI_PRINT("CONFIGFLAG              @0x%08x:  0x%08x\n",
203                         (uint32_t) addr, readl_relaxed(addr));
204         addr = g_hsic_ehci->regs->port_status;
205         HSIC_EHCI_PRINT("PORTSC                  @0x%08x:  0x%08x\n",
206                         (uint32_t) addr, readl_relaxed(addr));
207         return sprintf(buf, "HSIC_EHCI Registers Dump\n");
208 }
209
210 static DEVICE_ATTR(hsic_debug_ehci, S_IRUGO, hsic_debug_show, NULL);
211
212 static struct of_device_id rk_hsic_of_match[] = {
213         {
214          .compatible = "rockchip,rk3188_rk_hsic_host",
215          .data = &rkhsic_pdata[RK3188_USB_CTLR],
216          },
217         {
218          .compatible = "rockchip,rk3288_rk_hsic_host",
219          .data = &rkhsic_pdata[RK3288_USB_CTLR],
220          },
221         {},
222 };
223
224 MODULE_DEVICE_TABLE(of, rk_hsic_of_match);
225
226 static int ehci_rkhsic_probe(struct platform_device *pdev)
227 {
228         struct usb_hcd *hcd;
229         struct ehci_hcd *ehci;
230         struct resource *res;
231         struct device *dev = &pdev->dev;
232         struct rkehci_platform_data *pldata;
233         int ret;
234         int retval = 0;
235         static u64 usb_dmamask = 0xffffffffUL;
236         struct device_node *node = pdev->dev.of_node;
237         struct rkehci_pdata_id *p;
238         const struct of_device_id *match =
239             of_match_device(of_match_ptr(rk_hsic_of_match), &pdev->dev);
240
241         dev_dbg(&pdev->dev, "ehci_rkhsic proble\n");
242
243         if (match) {
244                 p = (struct rkehci_pdata_id *)match->data;
245         } else {
246                 dev_err(dev, "ehci_rkhsic match failed\n");
247                 return -EINVAL;
248         }
249
250         dev->platform_data = p->pdata;
251         pldata = dev->platform_data;
252         pldata->dev = dev;
253
254         if (!node) {
255                 dev_err(dev, "device node not found\n");
256                 return -EINVAL;
257         }
258
259         dev->dma_mask = &usb_dmamask;
260
261         retval = device_create_file(dev, &dev_attr_ehci_rkhsic_power);
262         retval = device_create_file(dev, &dev_attr_hsic_debug_ehci);
263         hcd = usb_create_hcd(&rk_hsic_driver, &pdev->dev, dev_name(&pdev->dev));
264         if (!hcd) {
265                 dev_err(&pdev->dev, "Unable to create HCD\n");
266                 return -ENOMEM;
267         }
268
269         if (pldata->hw_init)
270                 pldata->hw_init();
271
272         if (pldata->clock_init) {
273                 pldata->clock_init(pldata);
274                 pldata->clock_enable(pldata, 1);
275         }
276
277         if (pldata->soft_reset)
278                 pldata->soft_reset(pldata, RST_POR);;
279
280         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
281         if (!res) {
282                 dev_err(&pdev->dev, "Unable to get memory resource\n");
283                 ret = -ENODEV;
284                 goto put_hcd;
285         }
286
287         hcd->rsrc_start = res->start;
288         hcd->rsrc_len = resource_size(res);
289         hcd->regs = devm_ioremap_resource(dev, res);
290
291         if (!hcd->regs) {
292                 dev_err(&pdev->dev, "ioremap failed\n");
293                 ret = -ENOMEM;
294                 goto put_hcd;
295         }
296
297         hcd->irq = platform_get_irq(pdev, 0);
298         if (hcd->irq < 0) {
299                 dev_err(&pdev->dev, "Unable to get IRQ resource\n");
300                 ret = hcd->irq;
301                 goto put_hcd;
302         }
303
304         ehci = hcd_to_ehci(hcd);
305         ehci->caps = hcd->regs;
306         ehci->regs = hcd->regs + 0x10;
307         printk("%s %p %p\n", __func__, ehci->caps, ehci->regs);
308
309         dbg_hcs_params(ehci, "reset");
310         dbg_hcc_params(ehci, "reset");
311
312         ehci->hcs_params = readl(&ehci->caps->hcs_params);
313
314         ret = usb_add_hcd(hcd, hcd->irq, IRQF_DISABLED | IRQF_SHARED);
315         if (ret) {
316                 dev_err(&pdev->dev, "Failed to add USB HCD\n");
317                 goto put_hcd;
318         }
319
320         g_hsic_ehci = ehci;
321         ehci_rkhsic_port_power(ehci, 1);
322         writel_relaxed(1, hcd->regs + 0xb0);
323         writel_relaxed(0x1d4d, hcd->regs + 0x90);
324         writel_relaxed(0x4, hcd->regs + 0xa0);
325         dsb();
326
327         printk("%s ok\n", __func__);
328
329         return 0;
330
331 put_hcd:
332         if (pldata->clock_enable)
333                 pldata->clock_enable(pldata, 0);
334         usb_put_hcd(hcd);
335
336         return ret;
337 }
338
339 static int ehci_rkhsic_remove(struct platform_device *pdev)
340 {
341         struct usb_hcd *hcd = platform_get_drvdata(pdev);
342
343         usb_put_hcd(hcd);
344
345         return 0;
346 }
347
348 #ifdef CONFIG_PM
349 static int ehci_rkhsic_pm_suspend(struct device *dev)
350 {
351         struct usb_hcd *hcd = dev_get_drvdata(dev);
352         bool do_wakeup = device_may_wakeup(dev);
353         int ret;
354
355         dev_dbg(dev, "ehci-rkhsic PM suspend\n");
356         ret = ehci_suspend(hcd, do_wakeup);
357
358         return ret;
359 }
360
361 static int ehci_rkhsic_pm_resume(struct device *dev)
362 {
363         struct usb_hcd *hcd = dev_get_drvdata(dev);
364
365         dev_dbg(dev, "ehci-rkhsic PM resume\n");
366         ehci_resume(hcd, false);
367
368         return 0;
369 }
370 #else
371 #define ehci_rkhsic_pm_suspend  NULL
372 #define ehci_rkhsic_pm_resume   NULL
373 #endif
374
375 static const struct dev_pm_ops ehci_rkhsic_dev_pm_ops = {
376         .suspend = ehci_rkhsic_pm_suspend,
377         .resume = ehci_rkhsic_pm_resume,
378 };
379
380 static struct platform_driver ehci_rkhsic_driver = {
381         .probe = ehci_rkhsic_probe,
382         .remove = ehci_rkhsic_remove,
383         .driver = {
384                    .name = "rockchip_hsic_host",
385                    .of_match_table = of_match_ptr(rk_hsic_of_match),
386 #ifdef CONFIG_PM
387                    .pm = &ehci_rkhsic_dev_pm_ops,
388 #endif
389                    },
390 };