ehci-pmcmsp.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. /*
  2. * PMC MSP EHCI (Host Controller Driver) for USB.
  3. *
  4. * (C) Copyright 2006-2010 PMC-Sierra Inc
  5. *
  6. * This file is subject to the terms and conditions of the GNU General Public
  7. * License. See the file "COPYING" in the main directory of this archive
  8. * for more details.
  9. *
  10. */
  11. /* includes */
  12. #include <linux/platform_device.h>
  13. #include <linux/gpio.h>
  14. #include <linux/usb.h>
  15. #include <msp_usb.h>
  16. /* stream disable*/
  17. #define USB_CTRL_MODE_STREAM_DISABLE 0x10
  18. /* threshold */
  19. #define USB_CTRL_FIFO_THRESH 0x00300000
  20. /* register offset for usb_mode */
  21. #define USB_EHCI_REG_USB_MODE 0x68
  22. /* register offset for usb fifo */
  23. #define USB_EHCI_REG_USB_FIFO 0x24
  24. /* register offset for usb status */
  25. #define USB_EHCI_REG_USB_STATUS 0x44
  26. /* serial/parallel transceiver */
  27. #define USB_EHCI_REG_BIT_STAT_STS (1<<29)
  28. /* TWI USB0 host device pin */
  29. #define MSP_PIN_USB0_HOST_DEV 49
  30. /* TWI USB1 host device pin */
  31. #define MSP_PIN_USB1_HOST_DEV 50
  32. static void usb_hcd_tdi_set_mode(struct ehci_hcd *ehci)
  33. {
  34. u8 *base;
  35. u8 *statreg;
  36. u8 *fiforeg;
  37. u32 val;
  38. struct ehci_regs *reg_base = ehci->regs;
  39. /* get register base */
  40. base = (u8 *)reg_base + USB_EHCI_REG_USB_MODE;
  41. statreg = (u8 *)reg_base + USB_EHCI_REG_USB_STATUS;
  42. fiforeg = (u8 *)reg_base + USB_EHCI_REG_USB_FIFO;
  43. /* Disable controller mode stream */
  44. val = ehci_readl(ehci, (u32 *)base);
  45. ehci_writel(ehci, (val | USB_CTRL_MODE_STREAM_DISABLE),
  46. (u32 *)base);
  47. /* clear STS to select parallel transceiver interface */
  48. val = ehci_readl(ehci, (u32 *)statreg);
  49. val = val & ~USB_EHCI_REG_BIT_STAT_STS;
  50. ehci_writel(ehci, val, (u32 *)statreg);
  51. /* write to set the proper fifo threshold */
  52. ehci_writel(ehci, USB_CTRL_FIFO_THRESH, (u32 *)fiforeg);
  53. /* set TWI GPIO USB_HOST_DEV pin high */
  54. gpio_direction_output(MSP_PIN_USB0_HOST_DEV, 1);
  55. #ifdef CONFIG_MSP_HAS_DUAL_USB
  56. gpio_direction_output(MSP_PIN_USB1_HOST_DEV, 1);
  57. #endif
  58. }
  59. /* called during probe() after chip reset completes */
  60. static int ehci_msp_setup(struct usb_hcd *hcd)
  61. {
  62. struct ehci_hcd *ehci = hcd_to_ehci(hcd);
  63. int retval;
  64. ehci->big_endian_mmio = 1;
  65. ehci->big_endian_desc = 1;
  66. ehci->caps = hcd->regs;
  67. ehci->regs = hcd->regs +
  68. HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase));
  69. dbg_hcs_params(ehci, "reset");
  70. dbg_hcc_params(ehci, "reset");
  71. /* cache this readonly data; minimize chip reads */
  72. ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
  73. hcd->has_tt = 1;
  74. retval = ehci_halt(ehci);
  75. if (retval)
  76. return retval;
  77. ehci_reset(ehci);
  78. /* data structure init */
  79. retval = ehci_init(hcd);
  80. if (retval)
  81. return retval;
  82. usb_hcd_tdi_set_mode(ehci);
  83. ehci_port_power(ehci, 0);
  84. return retval;
  85. }
  86. /* configure so an HC device and id are always provided
  87. * always called with process context; sleeping is OK
  88. */
  89. static int usb_hcd_msp_map_regs(struct mspusb_device *dev)
  90. {
  91. struct resource *res;
  92. struct platform_device *pdev = &dev->dev;
  93. u32 res_len;
  94. int retval;
  95. /* MAB register space */
  96. res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
  97. if (res == NULL)
  98. return -ENOMEM;
  99. res_len = resource_size(res);
  100. if (!request_mem_region(res->start, res_len, "mab regs"))
  101. return -EBUSY;
  102. dev->mab_regs = ioremap_nocache(res->start, res_len);
  103. if (dev->mab_regs == NULL) {
  104. retval = -ENOMEM;
  105. goto err1;
  106. }
  107. /* MSP USB register space */
  108. res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
  109. if (res == NULL) {
  110. retval = -ENOMEM;
  111. goto err2;
  112. }
  113. res_len = resource_size(res);
  114. if (!request_mem_region(res->start, res_len, "usbid regs")) {
  115. retval = -EBUSY;
  116. goto err2;
  117. }
  118. dev->usbid_regs = ioremap_nocache(res->start, res_len);
  119. if (dev->usbid_regs == NULL) {
  120. retval = -ENOMEM;
  121. goto err3;
  122. }
  123. return 0;
  124. err3:
  125. res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
  126. res_len = resource_size(res);
  127. release_mem_region(res->start, res_len);
  128. err2:
  129. iounmap(dev->mab_regs);
  130. err1:
  131. res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
  132. res_len = resource_size(res);
  133. release_mem_region(res->start, res_len);
  134. dev_err(&pdev->dev, "Failed to map non-EHCI regs.\n");
  135. return retval;
  136. }
  137. /**
  138. * usb_hcd_msp_probe - initialize PMC MSP-based HCDs
  139. * Context: !in_interrupt()
  140. *
  141. * Allocates basic resources for this USB host controller, and
  142. * then invokes the start() method for the HCD associated with it
  143. * through the hotplug entry's driver_data.
  144. *
  145. */
  146. int usb_hcd_msp_probe(const struct hc_driver *driver,
  147. struct platform_device *dev)
  148. {
  149. int retval;
  150. struct usb_hcd *hcd;
  151. struct resource *res;
  152. struct ehci_hcd *ehci ;
  153. hcd = usb_create_hcd(driver, &dev->dev, "pmcmsp");
  154. if (!hcd)
  155. return -ENOMEM;
  156. res = platform_get_resource(dev, IORESOURCE_MEM, 0);
  157. if (res == NULL) {
  158. pr_debug("No IOMEM resource info for %s.\n", dev->name);
  159. retval = -ENOMEM;
  160. goto err1;
  161. }
  162. hcd->rsrc_start = res->start;
  163. hcd->rsrc_len = resource_size(res);
  164. if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, dev->name)) {
  165. retval = -EBUSY;
  166. goto err1;
  167. }
  168. hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len);
  169. if (!hcd->regs) {
  170. pr_debug("ioremap failed");
  171. retval = -ENOMEM;
  172. goto err2;
  173. }
  174. res = platform_get_resource(dev, IORESOURCE_IRQ, 0);
  175. if (res == NULL) {
  176. dev_err(&dev->dev, "No IRQ resource info for %s.\n", dev->name);
  177. retval = -ENOMEM;
  178. goto err3;
  179. }
  180. /* Map non-EHCI register spaces */
  181. retval = usb_hcd_msp_map_regs(to_mspusb_device(dev));
  182. if (retval != 0)
  183. goto err3;
  184. ehci = hcd_to_ehci(hcd);
  185. ehci->big_endian_mmio = 1;
  186. ehci->big_endian_desc = 1;
  187. retval = usb_add_hcd(hcd, res->start, IRQF_SHARED);
  188. if (retval == 0)
  189. return 0;
  190. usb_remove_hcd(hcd);
  191. err3:
  192. iounmap(hcd->regs);
  193. err2:
  194. release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
  195. err1:
  196. usb_put_hcd(hcd);
  197. return retval;
  198. }
  199. /**
  200. * usb_hcd_msp_remove - shutdown processing for PMC MSP-based HCDs
  201. * @dev: USB Host Controller being removed
  202. * Context: !in_interrupt()
  203. *
  204. * Reverses the effect of usb_hcd_msp_probe(), first invoking
  205. * the HCD's stop() method. It is always called from a thread
  206. * context, normally "rmmod", "apmd", or something similar.
  207. *
  208. * may be called without controller electrically present
  209. * may be called with controller, bus, and devices active
  210. */
  211. void usb_hcd_msp_remove(struct usb_hcd *hcd, struct platform_device *dev)
  212. {
  213. usb_remove_hcd(hcd);
  214. iounmap(hcd->regs);
  215. release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
  216. usb_put_hcd(hcd);
  217. }
  218. #ifdef CONFIG_MSP_HAS_DUAL_USB
  219. /*
  220. * Wrapper around the main ehci_irq. Since both USB host controllers are
  221. * sharing the same IRQ, need to first determine whether we're the intended
  222. * recipient of this interrupt.
  223. */
  224. static irqreturn_t ehci_msp_irq(struct usb_hcd *hcd)
  225. {
  226. u32 int_src;
  227. struct device *dev = hcd->self.controller;
  228. struct platform_device *pdev;
  229. struct mspusb_device *mdev;
  230. struct ehci_hcd *ehci = hcd_to_ehci(hcd);
  231. /* need to reverse-map a couple of containers to get our device */
  232. pdev = to_platform_device(dev);
  233. mdev = to_mspusb_device(pdev);
  234. /* Check to see if this interrupt is for this host controller */
  235. int_src = ehci_readl(ehci, &mdev->mab_regs->int_stat);
  236. if (int_src & (1 << pdev->id))
  237. return ehci_irq(hcd);
  238. /* Not for this device */
  239. return IRQ_NONE;
  240. }
  241. #endif /* DUAL_USB */
  242. static const struct hc_driver ehci_msp_hc_driver = {
  243. .description = hcd_name,
  244. .product_desc = "PMC MSP EHCI",
  245. .hcd_priv_size = sizeof(struct ehci_hcd),
  246. /*
  247. * generic hardware linkage
  248. */
  249. #ifdef CONFIG_MSP_HAS_DUAL_USB
  250. .irq = ehci_msp_irq,
  251. #else
  252. .irq = ehci_irq,
  253. #endif
  254. .flags = HCD_MEMORY | HCD_USB2,
  255. /*
  256. * basic lifecycle operations
  257. */
  258. .reset = ehci_msp_setup,
  259. .start = ehci_run,
  260. .shutdown = ehci_shutdown,
  261. .start = ehci_run,
  262. .stop = ehci_stop,
  263. /*
  264. * managing i/o requests and associated device resources
  265. */
  266. .urb_enqueue = ehci_urb_enqueue,
  267. .urb_dequeue = ehci_urb_dequeue,
  268. .endpoint_disable = ehci_endpoint_disable,
  269. .endpoint_reset = ehci_endpoint_reset,
  270. /*
  271. * scheduling support
  272. */
  273. .get_frame_number = ehci_get_frame,
  274. /*
  275. * root hub support
  276. */
  277. .hub_status_data = ehci_hub_status_data,
  278. .hub_control = ehci_hub_control,
  279. .bus_suspend = ehci_bus_suspend,
  280. .bus_resume = ehci_bus_resume,
  281. .relinquish_port = ehci_relinquish_port,
  282. .port_handed_over = ehci_port_handed_over,
  283. .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
  284. };
  285. static int ehci_hcd_msp_drv_probe(struct platform_device *pdev)
  286. {
  287. int ret;
  288. pr_debug("In ehci_hcd_msp_drv_probe");
  289. if (usb_disabled())
  290. return -ENODEV;
  291. gpio_request(MSP_PIN_USB0_HOST_DEV, "USB0_HOST_DEV_GPIO");
  292. #ifdef CONFIG_MSP_HAS_DUAL_USB
  293. gpio_request(MSP_PIN_USB1_HOST_DEV, "USB1_HOST_DEV_GPIO");
  294. #endif
  295. ret = usb_hcd_msp_probe(&ehci_msp_hc_driver, pdev);
  296. return ret;
  297. }
  298. static int ehci_hcd_msp_drv_remove(struct platform_device *pdev)
  299. {
  300. struct usb_hcd *hcd = platform_get_drvdata(pdev);
  301. usb_hcd_msp_remove(hcd, pdev);
  302. /* free TWI GPIO USB_HOST_DEV pin */
  303. gpio_free(MSP_PIN_USB0_HOST_DEV);
  304. #ifdef CONFIG_MSP_HAS_DUAL_USB
  305. gpio_free(MSP_PIN_USB1_HOST_DEV);
  306. #endif
  307. return 0;
  308. }
  309. MODULE_ALIAS("pmcmsp-ehci");
  310. static struct platform_driver ehci_hcd_msp_driver = {
  311. .probe = ehci_hcd_msp_drv_probe,
  312. .remove = ehci_hcd_msp_drv_remove,
  313. .driver = {
  314. .name = "pmcmsp-ehci",
  315. .owner = THIS_MODULE,
  316. },
  317. };