2 * EHCI-compliant USB host controller driver for Rockchip SoCs
4 * Copyright (C) 2010 Google, Inc.
5 * Copyright (C) 2009 - 2013 NVIDIA Corporation
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
18 # include <linux/platform_device.h>
19 # include <linux/clk.h>
20 # include <linux/err.h>
21 # include <linux/device.h>
22 # include <linux/of.h>
23 # include <linux/of_platform.h>
24 # include <linux/usb.h>
25 # include <linux/usb/hcd.h>
26 # include <linux/usb/otg.h>
28 # include "../dwc_otg_310/usbdev_rk.h"
31 static int rkehci_status = 1;
32 static struct hc_driver rk_ehci_hc_driver;
35 struct ehci_hcd *ehci;
37 uint8_t host_setenable;
38 struct rkehci_platform_data *pldata;
39 struct timer_list connect_detect_timer;
40 struct delayed_work host_enable_work;
42 #define EHCI_PRINT(x...) printk(KERN_INFO "EHCI: " x)
44 static void rk_ehci_hcd_enable(struct work_struct *work)
46 struct rk_ehci_hcd *rk_ehci;
48 struct rkehci_platform_data *pldata;
49 struct ehci_hcd *ehci;
51 rk_ehci = container_of(work, struct rk_ehci_hcd, host_enable_work.work);
52 pldata = rk_ehci->pldata;
54 hcd = ehci_to_hcd(ehci);
56 if (rk_ehci->host_enabled == rk_ehci->host_setenable) {
57 EHCI_PRINT("%s, enable flag %d\n", __func__,
58 rk_ehci->host_setenable);
62 if (rk_ehci->host_setenable == 2) {
63 /* enable -> disable */
64 if (pldata->get_status(USB_STATUS_DPDM)) {
65 /* usb device connected */
66 rk_ehci->host_setenable = 1;
70 EHCI_PRINT("%s, disable host controller\n", __func__);
73 /* reset cru and reinitialize EHCI controller */
74 pldata->soft_reset(pldata, RST_RECNT);
75 usb_add_hcd(hcd, hcd->irq, IRQF_DISABLED | IRQF_SHARED);
76 if (pldata->phy_suspend)
77 pldata->phy_suspend(pldata, USB_PHY_SUSPEND);
78 /* do not disable EHCI clk, otherwise RK3288
79 * host1(DWC_OTG) can't work normally.
81 /* pldata->clock_enable(pldata, 0); */
82 } else if (rk_ehci->host_setenable == 1) {
83 /* pldata->clock_enable(pldata, 1); */
84 if (pldata->phy_suspend)
85 pldata->phy_suspend(pldata, USB_PHY_ENABLED);
87 EHCI_PRINT("%s, enable host controller\n", __func__);
89 rk_ehci->host_enabled = rk_ehci->host_setenable;
95 static void rk_ehci_hcd_connect_detect(unsigned long pdata)
97 struct rk_ehci_hcd *rk_ehci = (struct rk_ehci_hcd *)pdata;
98 struct ehci_hcd *ehci = rk_ehci->ehci;
99 struct rkehci_platform_data *pldata;
103 local_irq_save(flags);
105 pldata = rk_ehci->pldata;
107 if (pldata->get_status(USB_STATUS_DPDM)) {
108 /* usb device connected */
109 rk_ehci->host_setenable = 1;
111 /* no device, suspend host */
112 status = readl(&ehci->regs->port_status[0]);
113 if (!(status & PORT_CONNECT)) {
114 rk_ehci->host_setenable = 2;
118 if ((rk_ehci->host_enabled)
119 && (rk_ehci->host_setenable != rk_ehci->host_enabled)) {
120 schedule_delayed_work(&rk_ehci->host_enable_work, 1);
123 mod_timer(&rk_ehci->connect_detect_timer, jiffies + (HZ << 1));
125 local_irq_restore(flags);
129 static ssize_t ehci_power_show(struct device *_dev,
130 struct device_attribute *attr, char *buf)
132 return sprintf(buf, "%d\n", rkehci_status);
135 static ssize_t ehci_power_store(struct device *_dev,
136 struct device_attribute *attr,
137 const char *buf, size_t count)
139 uint32_t val = simple_strtoul(buf, NULL, 16);
140 struct usb_hcd *hcd = dev_get_drvdata(_dev);
141 struct rkehci_platform_data *pldata = _dev->platform_data;
142 struct rk_ehci_hcd *rk_ehci = (struct rk_ehci_hcd *)hcd_to_ehci(hcd)->priv;
144 EHCI_PRINT("%s: %d setting to: %d\n", __func__, rkehci_status, val);
145 if (val == rkehci_status)
150 case 0: /* power down */
151 rk_ehci->host_enabled = 0;
155 case 1: /* power on */
156 pldata->soft_reset(pldata, RST_POR);
157 usb_add_hcd(hcd, hcd->irq, IRQF_DISABLED | IRQF_SHARED);
158 rk_ehci->host_enabled = 2;
167 static DEVICE_ATTR(ehci_power, S_IRUGO | S_IWUSR, ehci_power_show,
169 static ssize_t debug_show(struct device *dev, struct device_attribute *attr,
172 struct ehci_hcd *ehci = hcd_to_ehci(dev_get_drvdata(dev));
173 volatile uint32_t *addr;
175 EHCI_PRINT("******** EHCI Capability Registers **********\n");
176 addr = &ehci->caps->hc_capbase;
177 EHCI_PRINT("HCIVERSION / CAPLENGTH @0z%p: 0x%08x\n",
178 addr, readl_relaxed(addr));
179 addr = &ehci->caps->hcs_params;
180 EHCI_PRINT("HCSPARAMS @0x%p: 0x%08x\n",
181 addr, readl_relaxed(addr));
182 addr = &ehci->caps->hcc_params;
183 EHCI_PRINT("HCCPARAMS @0x%p: 0x%08x\n",
184 addr, readl_relaxed(addr));
185 EHCI_PRINT("********* EHCI Operational Registers *********\n");
186 addr = &ehci->regs->command;
187 EHCI_PRINT("USBCMD @0x%p: 0x%08x\n",
188 addr, readl_relaxed(addr));
189 addr = &ehci->regs->status;
190 EHCI_PRINT("USBSTS @0x%p: 0x%08x\n",
191 addr, readl_relaxed(addr));
192 addr = &ehci->regs->intr_enable;
193 EHCI_PRINT("USBINTR @0x%p: 0x%08x\n",
194 addr, readl_relaxed(addr));
195 addr = &ehci->regs->frame_index;
196 EHCI_PRINT("FRINDEX @0x%p: 0x%08x\n",
197 addr, readl_relaxed(addr));
198 addr = &ehci->regs->segment;
199 EHCI_PRINT("CTRLDSSEGMENT @0x%p: 0x%08x\n",
200 addr, readl_relaxed(addr));
201 addr = &ehci->regs->frame_list;
202 EHCI_PRINT("PERIODICLISTBASE @0x%p: 0x%08x\n",
203 addr, readl_relaxed(addr));
204 addr = &ehci->regs->async_next;
205 EHCI_PRINT("ASYNCLISTADDR @0x%p: 0x%08x\n",
206 addr, readl_relaxed(addr));
207 addr = &ehci->regs->configured_flag;
208 EHCI_PRINT("CONFIGFLAG @0x%p: 0x%08x\n",
209 addr, readl_relaxed(addr));
210 addr = &ehci->regs->port_status[0];
211 EHCI_PRINT("PORTSC @0x%p: 0x%08x\n",
212 addr, readl_relaxed(addr));
213 return sprintf(buf, "EHCI Registers Dump\n");
216 static DEVICE_ATTR(debug_ehci, S_IRUGO, debug_show, NULL);
218 static int test_sq(struct ehci_hcd *ehci)
220 u32 portc = readl(&ehci->regs->port_status);
222 if ((portc & PORT_PE) && !(portc & PORT_SUSPEND)) {
223 writel(PORT_TEST_PKT, &ehci->regs->port_status);
224 EHCI_PRINT("Start packet test\n");
228 EHCI_PRINT("Invalid connect status PORTC = 0x%08x\n", portc);
233 static ssize_t test_sq_store(struct device *dev,
234 struct device_attribute *attr,
235 const char *buf, size_t count)
238 struct rkehci_platform_data *pldata = dev->platform_data;
239 struct ehci_hcd *ehci = hcd_to_ehci(dev_get_drvdata(dev));
241 if (pldata->phy_status == USB_PHY_SUSPEND) {
242 EHCI_PRINT("Invalid status : SUSPEND\n");
246 return (test_sq(ehci)) ? -EBUSY : count;
249 static DEVICE_ATTR(test_sq, S_IWUSR, NULL, test_sq_store);
251 static struct of_device_id rk_ehci_of_match[] = {
253 .compatible = "rockchip,rk3288_rk_ehci_host",
254 .data = &rkehci_pdata_rk3288,
259 MODULE_DEVICE_TABLE(of, rk_ehci_of_match);
261 static int ehci_rk_probe(struct platform_device *pdev)
264 struct ehci_hcd *ehci;
265 struct resource *res;
266 struct device *dev = &pdev->dev;
267 struct rkehci_platform_data *pldata;
269 struct device_node *node = pdev->dev.of_node;
270 struct rk_ehci_hcd *rk_ehci;
271 const struct of_device_id *match =
272 of_match_device(of_match_ptr(rk_ehci_of_match), &pdev->dev);
274 dev_dbg(&pdev->dev, "ehci_rk probe!\n");
276 if (match && match->data) {
277 dev->platform_data = (void *)match->data;
279 dev_err(dev, "ehci_rk match failed\n");
283 pldata = dev->platform_data;
287 dev_err(dev, "device node not found\n");
291 if (!pdev->dev.dma_mask)
292 pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
293 if (!pdev->dev.coherent_dma_mask)
294 pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
296 device_create_file(dev, &dev_attr_ehci_power);
297 device_create_file(dev, &dev_attr_debug_ehci);
298 device_create_file(dev, &dev_attr_test_sq);
301 usb_create_hcd(&rk_ehci_hc_driver, &pdev->dev,
302 dev_name(&pdev->dev));
304 dev_err(&pdev->dev, "Unable to create HCD\n");
311 if (pldata->clock_init) {
312 pldata->clock_init(pldata);
313 pldata->clock_enable(pldata, 1);
316 if (pldata->phy_suspend)
317 pldata->phy_suspend(pldata, USB_PHY_ENABLED);
319 if (pldata->soft_reset)
320 pldata->soft_reset(pldata, RST_POR);;
322 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
324 dev_err(&pdev->dev, "Unable to get memory resource\n");
329 hcd->rsrc_start = res->start;
330 hcd->rsrc_len = resource_size(res);
331 hcd->regs = devm_ioremap_resource(dev, res);
333 dev_err(&pdev->dev, "ioremap failed\n");
338 hcd->irq = platform_get_irq(pdev, 0);
340 dev_err(&pdev->dev, "Unable to get IRQ resource\n");
345 ehci = hcd_to_ehci(hcd);
346 ehci->caps = hcd->regs;
347 ehci->regs = hcd->regs + 0x10;
348 EHCI_PRINT("%s %p %p\n", __func__, ehci->caps, ehci->regs);
350 ehci->hcs_params = readl(&ehci->caps->hcs_params);
352 ret = usb_add_hcd(hcd, hcd->irq, IRQF_DISABLED | IRQF_SHARED);
354 dev_err(&pdev->dev, "Failed to add USB HCD\n");
358 rk_ehci = (struct rk_ehci_hcd *)hcd_to_ehci(hcd)->priv;
365 rk_ehci->ehci = ehci;
366 rk_ehci->pldata = pldata;
367 rk_ehci->host_enabled = 2;
368 rk_ehci->host_setenable = 2;
369 rk_ehci->connect_detect_timer.function = rk_ehci_hcd_connect_detect;
370 rk_ehci->connect_detect_timer.data = (unsigned long)(rk_ehci);
371 init_timer(&rk_ehci->connect_detect_timer);
372 mod_timer(&rk_ehci->connect_detect_timer, jiffies + (HZ << 1));
373 INIT_DELAYED_WORK(&rk_ehci->host_enable_work, rk_ehci_hcd_enable);
375 if (pldata->phy_suspend) {
376 if (pldata->phy_status == USB_PHY_ENABLED) {
377 pldata->phy_suspend(pldata, USB_PHY_SUSPEND);
378 /* do not disable EHCI clk, otherwise RK3288
379 * host1(DWC_OTG) can't work normally.
381 * pldata->clock_enable(pldata, 0);
386 EHCI_PRINT("%s ok\n", __func__);
391 if (pldata->clock_enable)
392 pldata->clock_enable(pldata, 0);
398 static int ehci_rk_remove(struct platform_device *pdev)
400 struct usb_hcd *hcd = platform_get_drvdata(pdev);
401 struct device *dev = &pdev->dev;
403 device_remove_file(dev, &dev_attr_ehci_power);
404 device_remove_file(dev, &dev_attr_debug_ehci);
405 device_remove_file(dev, &dev_attr_test_sq);
413 static int ehci_rk_pm_suspend(struct device *dev)
415 struct usb_hcd *hcd = dev_get_drvdata(dev);
416 bool do_wakeup = device_may_wakeup(dev);
419 dev_dbg(dev, "ehci-rockchip PM suspend\n");
421 ret = ehci_suspend(hcd, do_wakeup);
426 static int ehci_rk_pm_resume(struct device *dev)
428 struct usb_hcd *hcd = dev_get_drvdata(dev);
430 dev_dbg(dev, "ehci-rockchip PM resume\n");
431 ehci_resume(hcd, false);
436 #define ehci_rk_pm_suspend NULL
437 #define ehci_rk_pm_resume NULL
440 static const struct dev_pm_ops ehci_rk_dev_pm_ops = {
441 .suspend = ehci_rk_pm_suspend,
442 .resume = ehci_rk_pm_resume,
445 static struct platform_driver rk_ehci_driver = {
446 .probe = ehci_rk_probe,
447 .remove = ehci_rk_remove,
449 .name = "rockchip_ehci_host",
450 .of_match_table = of_match_ptr(rk_ehci_of_match),
452 .pm = &ehci_rk_dev_pm_ops,
457 static const struct ehci_driver_overrides rk_overrides __initdata = {
458 .extra_priv_size = sizeof(struct rk_ehci_hcd),
461 static int __init ehci_rk_init(void)
466 ehci_init_driver(&rk_ehci_hc_driver, &rk_overrides);
467 return platform_driver_register(&rk_ehci_driver);
469 module_init(ehci_rk_init);
471 static void __exit ehci_rk_cleanup(void)
473 platform_driver_unregister(&rk_ehci_driver);
475 module_exit(ehci_rk_cleanup);
476 MODULE_AUTHOR("Rockchip");
477 MODULE_LICENSE("GPL v2");