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