ohci-da8xx.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. /*
  2. * OHCI HCD (Host Controller Driver) for USB.
  3. *
  4. * TI DA8xx (OMAP-L1x) Bus Glue
  5. *
  6. * Derived from: ohci-omap.c and ohci-s3c2410.c
  7. * Copyright (C) 2008-2009 MontaVista Software, Inc. <source@mvista.com>
  8. *
  9. * This file is licensed under the terms of the GNU General Public License
  10. * version 2. This program is licensed "as is" without any warranty of any
  11. * kind, whether express or implied.
  12. */
  13. #include <linux/interrupt.h>
  14. #include <linux/jiffies.h>
  15. #include <linux/platform_device.h>
  16. #include <linux/clk.h>
  17. #include <mach/da8xx.h>
  18. #include <linux/platform_data/usb-davinci.h>
  19. #ifndef CONFIG_ARCH_DAVINCI_DA8XX
  20. #error "This file is DA8xx bus glue. Define CONFIG_ARCH_DAVINCI_DA8XX."
  21. #endif
  22. #define CFGCHIP2 DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG)
  23. static struct clk *usb11_clk;
  24. static struct clk *usb20_clk;
  25. /* Over-current indicator change bitmask */
  26. static volatile u16 ocic_mask;
  27. static void ohci_da8xx_clock(int on)
  28. {
  29. u32 cfgchip2;
  30. cfgchip2 = __raw_readl(CFGCHIP2);
  31. if (on) {
  32. clk_enable(usb11_clk);
  33. /*
  34. * If USB 1.1 reference clock is sourced from USB 2.0 PHY, we
  35. * need to enable the USB 2.0 module clocking, start its PHY,
  36. * and not allow it to stop the clock during USB 2.0 suspend.
  37. */
  38. if (!(cfgchip2 & CFGCHIP2_USB1PHYCLKMUX)) {
  39. clk_enable(usb20_clk);
  40. cfgchip2 &= ~(CFGCHIP2_RESET | CFGCHIP2_PHYPWRDN);
  41. cfgchip2 |= CFGCHIP2_PHY_PLLON;
  42. __raw_writel(cfgchip2, CFGCHIP2);
  43. pr_info("Waiting for USB PHY clock good...\n");
  44. while (!(__raw_readl(CFGCHIP2) & CFGCHIP2_PHYCLKGD))
  45. cpu_relax();
  46. }
  47. /* Enable USB 1.1 PHY */
  48. cfgchip2 |= CFGCHIP2_USB1SUSPENDM;
  49. } else {
  50. clk_disable(usb11_clk);
  51. if (!(cfgchip2 & CFGCHIP2_USB1PHYCLKMUX))
  52. clk_disable(usb20_clk);
  53. /* Disable USB 1.1 PHY */
  54. cfgchip2 &= ~CFGCHIP2_USB1SUSPENDM;
  55. }
  56. __raw_writel(cfgchip2, CFGCHIP2);
  57. }
  58. /*
  59. * Handle the port over-current indicator change.
  60. */
  61. static void ohci_da8xx_ocic_handler(struct da8xx_ohci_root_hub *hub,
  62. unsigned port)
  63. {
  64. ocic_mask |= 1 << port;
  65. /* Once over-current is detected, the port needs to be powered down */
  66. if (hub->get_oci(port) > 0)
  67. hub->set_power(port, 0);
  68. }
  69. static int ohci_da8xx_init(struct usb_hcd *hcd)
  70. {
  71. struct device *dev = hcd->self.controller;
  72. struct da8xx_ohci_root_hub *hub = dev_get_platdata(dev);
  73. struct ohci_hcd *ohci = hcd_to_ohci(hcd);
  74. int result;
  75. u32 rh_a;
  76. dev_dbg(dev, "starting USB controller\n");
  77. ohci_da8xx_clock(1);
  78. /*
  79. * DA8xx only have 1 port connected to the pins but the HC root hub
  80. * register A reports 2 ports, thus we'll have to override it...
  81. */
  82. ohci->num_ports = 1;
  83. result = ohci_init(ohci);
  84. if (result < 0)
  85. return result;
  86. /*
  87. * Since we're providing a board-specific root hub port power control
  88. * and over-current reporting, we have to override the HC root hub A
  89. * register's default value, so that ohci_hub_control() could return
  90. * the correct hub descriptor...
  91. */
  92. rh_a = ohci_readl(ohci, &ohci->regs->roothub.a);
  93. if (hub->set_power) {
  94. rh_a &= ~RH_A_NPS;
  95. rh_a |= RH_A_PSM;
  96. }
  97. if (hub->get_oci) {
  98. rh_a &= ~RH_A_NOCP;
  99. rh_a |= RH_A_OCPM;
  100. }
  101. rh_a &= ~RH_A_POTPGT;
  102. rh_a |= hub->potpgt << 24;
  103. ohci_writel(ohci, rh_a, &ohci->regs->roothub.a);
  104. return result;
  105. }
  106. static void ohci_da8xx_stop(struct usb_hcd *hcd)
  107. {
  108. ohci_stop(hcd);
  109. ohci_da8xx_clock(0);
  110. }
  111. static int ohci_da8xx_start(struct usb_hcd *hcd)
  112. {
  113. struct ohci_hcd *ohci = hcd_to_ohci(hcd);
  114. int result;
  115. result = ohci_run(ohci);
  116. if (result < 0)
  117. ohci_da8xx_stop(hcd);
  118. return result;
  119. }
  120. /*
  121. * Update the status data from the hub with the over-current indicator change.
  122. */
  123. static int ohci_da8xx_hub_status_data(struct usb_hcd *hcd, char *buf)
  124. {
  125. int length = ohci_hub_status_data(hcd, buf);
  126. /* See if we have OCIC bit set on port 1 */
  127. if (ocic_mask & (1 << 1)) {
  128. dev_dbg(hcd->self.controller, "over-current indicator change "
  129. "on port 1\n");
  130. if (!length)
  131. length = 1;
  132. buf[0] |= 1 << 1;
  133. }
  134. return length;
  135. }
  136. /*
  137. * Look at the control requests to the root hub and see if we need to override.
  138. */
  139. static int ohci_da8xx_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
  140. u16 wIndex, char *buf, u16 wLength)
  141. {
  142. struct device *dev = hcd->self.controller;
  143. struct da8xx_ohci_root_hub *hub = dev_get_platdata(dev);
  144. int temp;
  145. switch (typeReq) {
  146. case GetPortStatus:
  147. /* Check the port number */
  148. if (wIndex != 1)
  149. break;
  150. dev_dbg(dev, "GetPortStatus(%u)\n", wIndex);
  151. temp = roothub_portstatus(hcd_to_ohci(hcd), wIndex - 1);
  152. /* The port power status (PPS) bit defaults to 1 */
  153. if (hub->get_power && hub->get_power(wIndex) == 0)
  154. temp &= ~RH_PS_PPS;
  155. /* The port over-current indicator (POCI) bit is always 0 */
  156. if (hub->get_oci && hub->get_oci(wIndex) > 0)
  157. temp |= RH_PS_POCI;
  158. /* The over-current indicator change (OCIC) bit is 0 too */
  159. if (ocic_mask & (1 << wIndex))
  160. temp |= RH_PS_OCIC;
  161. put_unaligned(cpu_to_le32(temp), (__le32 *)buf);
  162. return 0;
  163. case SetPortFeature:
  164. temp = 1;
  165. goto check_port;
  166. case ClearPortFeature:
  167. temp = 0;
  168. check_port:
  169. /* Check the port number */
  170. if (wIndex != 1)
  171. break;
  172. switch (wValue) {
  173. case USB_PORT_FEAT_POWER:
  174. dev_dbg(dev, "%sPortFeature(%u): %s\n",
  175. temp ? "Set" : "Clear", wIndex, "POWER");
  176. if (!hub->set_power)
  177. return -EPIPE;
  178. return hub->set_power(wIndex, temp) ? -EPIPE : 0;
  179. case USB_PORT_FEAT_C_OVER_CURRENT:
  180. dev_dbg(dev, "%sPortFeature(%u): %s\n",
  181. temp ? "Set" : "Clear", wIndex,
  182. "C_OVER_CURRENT");
  183. if (temp)
  184. ocic_mask |= 1 << wIndex;
  185. else
  186. ocic_mask &= ~(1 << wIndex);
  187. return 0;
  188. }
  189. }
  190. return ohci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength);
  191. }
  192. static const struct hc_driver ohci_da8xx_hc_driver = {
  193. .description = hcd_name,
  194. .product_desc = "DA8xx OHCI",
  195. .hcd_priv_size = sizeof(struct ohci_hcd),
  196. /*
  197. * generic hardware linkage
  198. */
  199. .irq = ohci_irq,
  200. .flags = HCD_USB11 | HCD_MEMORY,
  201. /*
  202. * basic lifecycle operations
  203. */
  204. .reset = ohci_da8xx_init,
  205. .start = ohci_da8xx_start,
  206. .stop = ohci_da8xx_stop,
  207. .shutdown = ohci_shutdown,
  208. /*
  209. * managing i/o requests and associated device resources
  210. */
  211. .urb_enqueue = ohci_urb_enqueue,
  212. .urb_dequeue = ohci_urb_dequeue,
  213. .endpoint_disable = ohci_endpoint_disable,
  214. /*
  215. * scheduling support
  216. */
  217. .get_frame_number = ohci_get_frame,
  218. /*
  219. * root hub support
  220. */
  221. .hub_status_data = ohci_da8xx_hub_status_data,
  222. .hub_control = ohci_da8xx_hub_control,
  223. #ifdef CONFIG_PM
  224. .bus_suspend = ohci_bus_suspend,
  225. .bus_resume = ohci_bus_resume,
  226. #endif
  227. .start_port_reset = ohci_start_port_reset,
  228. };
  229. /*-------------------------------------------------------------------------*/
  230. /**
  231. * usb_hcd_da8xx_probe - initialize DA8xx-based HCDs
  232. * Context: !in_interrupt()
  233. *
  234. * Allocates basic resources for this USB host controller, and
  235. * then invokes the start() method for the HCD associated with it
  236. * through the hotplug entry's driver_data.
  237. */
  238. static int usb_hcd_da8xx_probe(const struct hc_driver *driver,
  239. struct platform_device *pdev)
  240. {
  241. struct da8xx_ohci_root_hub *hub = dev_get_platdata(&pdev->dev);
  242. struct usb_hcd *hcd;
  243. struct resource *mem;
  244. int error, irq;
  245. if (hub == NULL)
  246. return -ENODEV;
  247. usb11_clk = devm_clk_get(&pdev->dev, "usb11");
  248. if (IS_ERR(usb11_clk))
  249. return PTR_ERR(usb11_clk);
  250. usb20_clk = devm_clk_get(&pdev->dev, "usb20");
  251. if (IS_ERR(usb20_clk))
  252. return PTR_ERR(usb20_clk);
  253. hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
  254. if (!hcd)
  255. return -ENOMEM;
  256. mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  257. hcd->regs = devm_ioremap_resource(&pdev->dev, mem);
  258. if (IS_ERR(hcd->regs)) {
  259. error = PTR_ERR(hcd->regs);
  260. goto err;
  261. }
  262. hcd->rsrc_start = mem->start;
  263. hcd->rsrc_len = resource_size(mem);
  264. ohci_hcd_init(hcd_to_ohci(hcd));
  265. irq = platform_get_irq(pdev, 0);
  266. if (irq < 0) {
  267. error = -ENODEV;
  268. goto err;
  269. }
  270. error = usb_add_hcd(hcd, irq, 0);
  271. if (error)
  272. goto err;
  273. device_wakeup_enable(hcd->self.controller);
  274. if (hub->ocic_notify) {
  275. error = hub->ocic_notify(ohci_da8xx_ocic_handler);
  276. if (!error)
  277. return 0;
  278. }
  279. usb_remove_hcd(hcd);
  280. err:
  281. usb_put_hcd(hcd);
  282. return error;
  283. }
  284. /**
  285. * usb_hcd_da8xx_remove - shutdown processing for DA8xx-based HCDs
  286. * @dev: USB Host Controller being removed
  287. * Context: !in_interrupt()
  288. *
  289. * Reverses the effect of usb_hcd_da8xx_probe(), first invoking
  290. * the HCD's stop() method. It is always called from a thread
  291. * context, normally "rmmod", "apmd", or something similar.
  292. */
  293. static inline void
  294. usb_hcd_da8xx_remove(struct usb_hcd *hcd, struct platform_device *pdev)
  295. {
  296. struct da8xx_ohci_root_hub *hub = dev_get_platdata(&pdev->dev);
  297. hub->ocic_notify(NULL);
  298. usb_remove_hcd(hcd);
  299. usb_put_hcd(hcd);
  300. }
  301. static int ohci_hcd_da8xx_drv_probe(struct platform_device *dev)
  302. {
  303. return usb_hcd_da8xx_probe(&ohci_da8xx_hc_driver, dev);
  304. }
  305. static int ohci_hcd_da8xx_drv_remove(struct platform_device *dev)
  306. {
  307. struct usb_hcd *hcd = platform_get_drvdata(dev);
  308. usb_hcd_da8xx_remove(hcd, dev);
  309. return 0;
  310. }
  311. #ifdef CONFIG_PM
  312. static int ohci_da8xx_suspend(struct platform_device *pdev,
  313. pm_message_t message)
  314. {
  315. struct usb_hcd *hcd = platform_get_drvdata(pdev);
  316. struct ohci_hcd *ohci = hcd_to_ohci(hcd);
  317. bool do_wakeup = device_may_wakeup(&pdev->dev);
  318. int ret;
  319. if (time_before(jiffies, ohci->next_statechange))
  320. msleep(5);
  321. ohci->next_statechange = jiffies;
  322. ret = ohci_suspend(hcd, do_wakeup);
  323. if (ret)
  324. return ret;
  325. ohci_da8xx_clock(0);
  326. hcd->state = HC_STATE_SUSPENDED;
  327. return ret;
  328. }
  329. static int ohci_da8xx_resume(struct platform_device *dev)
  330. {
  331. struct usb_hcd *hcd = platform_get_drvdata(dev);
  332. struct ohci_hcd *ohci = hcd_to_ohci(hcd);
  333. if (time_before(jiffies, ohci->next_statechange))
  334. msleep(5);
  335. ohci->next_statechange = jiffies;
  336. ohci_da8xx_clock(1);
  337. dev->dev.power.power_state = PMSG_ON;
  338. usb_hcd_resume_root_hub(hcd);
  339. return 0;
  340. }
  341. #endif
  342. /*
  343. * Driver definition to register with platform structure.
  344. */
  345. static struct platform_driver ohci_hcd_da8xx_driver = {
  346. .probe = ohci_hcd_da8xx_drv_probe,
  347. .remove = ohci_hcd_da8xx_drv_remove,
  348. .shutdown = usb_hcd_platform_shutdown,
  349. #ifdef CONFIG_PM
  350. .suspend = ohci_da8xx_suspend,
  351. .resume = ohci_da8xx_resume,
  352. #endif
  353. .driver = {
  354. .name = "ohci",
  355. },
  356. };
  357. MODULE_ALIAS("platform:ohci");