usb-ehci.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  1. /*
  2. * linux/arch/arm/mach-omap2/usb-ehci.c
  3. *
  4. * This file will contain the board specific details for the
  5. * Synopsys EHCI host controller on OMAP3430
  6. *
  7. * Copyright (C) 2007 Texas Instruments
  8. * Author: Vikram Pandita <vikram.pandita@ti.com>
  9. *
  10. * Generalization by:
  11. * Felipe Balbi <felipe.balbi@nokia.com>
  12. *
  13. * This program is free software; you can redistribute it and/or modify
  14. * it under the terms of the GNU General Public License version 2 as
  15. * published by the Free Software Foundation.
  16. */
  17. #include <linux/types.h>
  18. #include <linux/errno.h>
  19. #include <linux/delay.h>
  20. #include <linux/platform_device.h>
  21. #include <linux/clk.h>
  22. #include <linux/dma-mapping.h>
  23. #include <asm/io.h>
  24. #include <mach/hardware.h>
  25. #include <mach/irqs.h>
  26. #include <plat/usb.h>
  27. #include "mux.h"
  28. #if defined(CONFIG_USB_EHCI_HCD) || defined(CONFIG_USB_EHCI_HCD_MODULE)
  29. static struct resource ehci_resources[] = {
  30. {
  31. .start = OMAP34XX_EHCI_BASE,
  32. .end = OMAP34XX_EHCI_BASE + SZ_1K - 1,
  33. .flags = IORESOURCE_MEM,
  34. },
  35. {
  36. .start = OMAP34XX_UHH_CONFIG_BASE,
  37. .end = OMAP34XX_UHH_CONFIG_BASE + SZ_1K - 1,
  38. .flags = IORESOURCE_MEM,
  39. },
  40. {
  41. .start = OMAP34XX_USBTLL_BASE,
  42. .end = OMAP34XX_USBTLL_BASE + SZ_4K - 1,
  43. .flags = IORESOURCE_MEM,
  44. },
  45. { /* general IRQ */
  46. .start = INT_34XX_EHCI_IRQ,
  47. .flags = IORESOURCE_IRQ,
  48. }
  49. };
  50. static u64 ehci_dmamask = ~(u32)0;
  51. static struct platform_device ehci_device = {
  52. .name = "ehci-omap",
  53. .id = 0,
  54. .dev = {
  55. .dma_mask = &ehci_dmamask,
  56. .coherent_dma_mask = 0xffffffff,
  57. .platform_data = NULL,
  58. },
  59. .num_resources = ARRAY_SIZE(ehci_resources),
  60. .resource = ehci_resources,
  61. };
  62. /* MUX settings for EHCI pins */
  63. /*
  64. * setup_ehci_io_mux - initialize IO pad mux for USBHOST
  65. */
  66. static void setup_ehci_io_mux(const enum ehci_hcd_omap_mode *port_mode)
  67. {
  68. switch (port_mode[0]) {
  69. case EHCI_HCD_OMAP_MODE_PHY:
  70. omap_mux_init_signal("hsusb1_stp", OMAP_PIN_OUTPUT);
  71. omap_mux_init_signal("hsusb1_clk", OMAP_PIN_OUTPUT);
  72. omap_mux_init_signal("hsusb1_dir", OMAP_PIN_INPUT_PULLDOWN);
  73. omap_mux_init_signal("hsusb1_nxt", OMAP_PIN_INPUT_PULLDOWN);
  74. omap_mux_init_signal("hsusb1_data0", OMAP_PIN_INPUT_PULLDOWN);
  75. omap_mux_init_signal("hsusb1_data1", OMAP_PIN_INPUT_PULLDOWN);
  76. omap_mux_init_signal("hsusb1_data2", OMAP_PIN_INPUT_PULLDOWN);
  77. omap_mux_init_signal("hsusb1_data3", OMAP_PIN_INPUT_PULLDOWN);
  78. omap_mux_init_signal("hsusb1_data4", OMAP_PIN_INPUT_PULLDOWN);
  79. omap_mux_init_signal("hsusb1_data5", OMAP_PIN_INPUT_PULLDOWN);
  80. omap_mux_init_signal("hsusb1_data6", OMAP_PIN_INPUT_PULLDOWN);
  81. omap_mux_init_signal("hsusb1_data7", OMAP_PIN_INPUT_PULLDOWN);
  82. break;
  83. case EHCI_HCD_OMAP_MODE_TLL:
  84. omap_mux_init_signal("hsusb1_tll_stp",
  85. OMAP_PIN_INPUT_PULLUP);
  86. omap_mux_init_signal("hsusb1_tll_clk",
  87. OMAP_PIN_INPUT_PULLDOWN);
  88. omap_mux_init_signal("hsusb1_tll_dir",
  89. OMAP_PIN_INPUT_PULLDOWN);
  90. omap_mux_init_signal("hsusb1_tll_nxt",
  91. OMAP_PIN_INPUT_PULLDOWN);
  92. omap_mux_init_signal("hsusb1_tll_data0",
  93. OMAP_PIN_INPUT_PULLDOWN);
  94. omap_mux_init_signal("hsusb1_tll_data1",
  95. OMAP_PIN_INPUT_PULLDOWN);
  96. omap_mux_init_signal("hsusb1_tll_data2",
  97. OMAP_PIN_INPUT_PULLDOWN);
  98. omap_mux_init_signal("hsusb1_tll_data3",
  99. OMAP_PIN_INPUT_PULLDOWN);
  100. omap_mux_init_signal("hsusb1_tll_data4",
  101. OMAP_PIN_INPUT_PULLDOWN);
  102. omap_mux_init_signal("hsusb1_tll_data5",
  103. OMAP_PIN_INPUT_PULLDOWN);
  104. omap_mux_init_signal("hsusb1_tll_data6",
  105. OMAP_PIN_INPUT_PULLDOWN);
  106. omap_mux_init_signal("hsusb1_tll_data7",
  107. OMAP_PIN_INPUT_PULLDOWN);
  108. break;
  109. case EHCI_HCD_OMAP_MODE_UNKNOWN:
  110. /* FALLTHROUGH */
  111. default:
  112. break;
  113. }
  114. switch (port_mode[1]) {
  115. case EHCI_HCD_OMAP_MODE_PHY:
  116. omap_mux_init_signal("hsusb2_stp", OMAP_PIN_OUTPUT);
  117. omap_mux_init_signal("hsusb2_clk", OMAP_PIN_OUTPUT);
  118. omap_mux_init_signal("hsusb2_dir", OMAP_PIN_INPUT_PULLDOWN);
  119. omap_mux_init_signal("hsusb2_nxt", OMAP_PIN_INPUT_PULLDOWN);
  120. omap_mux_init_signal("hsusb2_data0",
  121. OMAP_PIN_INPUT_PULLDOWN);
  122. omap_mux_init_signal("hsusb2_data1",
  123. OMAP_PIN_INPUT_PULLDOWN);
  124. omap_mux_init_signal("hsusb2_data2",
  125. OMAP_PIN_INPUT_PULLDOWN);
  126. omap_mux_init_signal("hsusb2_data3",
  127. OMAP_PIN_INPUT_PULLDOWN);
  128. omap_mux_init_signal("hsusb2_data4",
  129. OMAP_PIN_INPUT_PULLDOWN);
  130. omap_mux_init_signal("hsusb2_data5",
  131. OMAP_PIN_INPUT_PULLDOWN);
  132. omap_mux_init_signal("hsusb2_data6",
  133. OMAP_PIN_INPUT_PULLDOWN);
  134. omap_mux_init_signal("hsusb2_data7",
  135. OMAP_PIN_INPUT_PULLDOWN);
  136. break;
  137. case EHCI_HCD_OMAP_MODE_TLL:
  138. omap_mux_init_signal("hsusb2_tll_stp",
  139. OMAP_PIN_INPUT_PULLUP);
  140. omap_mux_init_signal("hsusb2_tll_clk",
  141. OMAP_PIN_INPUT_PULLDOWN);
  142. omap_mux_init_signal("hsusb2_tll_dir",
  143. OMAP_PIN_INPUT_PULLDOWN);
  144. omap_mux_init_signal("hsusb2_tll_nxt",
  145. OMAP_PIN_INPUT_PULLDOWN);
  146. omap_mux_init_signal("hsusb2_tll_data0",
  147. OMAP_PIN_INPUT_PULLDOWN);
  148. omap_mux_init_signal("hsusb2_tll_data1",
  149. OMAP_PIN_INPUT_PULLDOWN);
  150. omap_mux_init_signal("hsusb2_tll_data2",
  151. OMAP_PIN_INPUT_PULLDOWN);
  152. omap_mux_init_signal("hsusb2_tll_data3",
  153. OMAP_PIN_INPUT_PULLDOWN);
  154. omap_mux_init_signal("hsusb2_tll_data4",
  155. OMAP_PIN_INPUT_PULLDOWN);
  156. omap_mux_init_signal("hsusb2_tll_data5",
  157. OMAP_PIN_INPUT_PULLDOWN);
  158. omap_mux_init_signal("hsusb2_tll_data6",
  159. OMAP_PIN_INPUT_PULLDOWN);
  160. omap_mux_init_signal("hsusb2_tll_data7",
  161. OMAP_PIN_INPUT_PULLDOWN);
  162. break;
  163. case EHCI_HCD_OMAP_MODE_UNKNOWN:
  164. /* FALLTHROUGH */
  165. default:
  166. break;
  167. }
  168. switch (port_mode[2]) {
  169. case EHCI_HCD_OMAP_MODE_PHY:
  170. printk(KERN_WARNING "Port3 can't be used in PHY mode\n");
  171. break;
  172. case EHCI_HCD_OMAP_MODE_TLL:
  173. omap_mux_init_signal("hsusb3_tll_stp",
  174. OMAP_PIN_INPUT_PULLUP);
  175. omap_mux_init_signal("hsusb3_tll_clk",
  176. OMAP_PIN_INPUT_PULLDOWN);
  177. omap_mux_init_signal("hsusb3_tll_dir",
  178. OMAP_PIN_INPUT_PULLDOWN);
  179. omap_mux_init_signal("hsusb3_tll_nxt",
  180. OMAP_PIN_INPUT_PULLDOWN);
  181. omap_mux_init_signal("hsusb3_tll_data0",
  182. OMAP_PIN_INPUT_PULLDOWN);
  183. omap_mux_init_signal("hsusb3_tll_data1",
  184. OMAP_PIN_INPUT_PULLDOWN);
  185. omap_mux_init_signal("hsusb3_tll_data2",
  186. OMAP_PIN_INPUT_PULLDOWN);
  187. omap_mux_init_signal("hsusb3_tll_data3",
  188. OMAP_PIN_INPUT_PULLDOWN);
  189. omap_mux_init_signal("hsusb3_tll_data4",
  190. OMAP_PIN_INPUT_PULLDOWN);
  191. omap_mux_init_signal("hsusb3_tll_data5",
  192. OMAP_PIN_INPUT_PULLDOWN);
  193. omap_mux_init_signal("hsusb3_tll_data6",
  194. OMAP_PIN_INPUT_PULLDOWN);
  195. omap_mux_init_signal("hsusb3_tll_data7",
  196. OMAP_PIN_INPUT_PULLDOWN);
  197. break;
  198. case EHCI_HCD_OMAP_MODE_UNKNOWN:
  199. /* FALLTHROUGH */
  200. default:
  201. break;
  202. }
  203. return;
  204. }
  205. void __init usb_ehci_init(const struct ehci_hcd_omap_platform_data *pdata)
  206. {
  207. platform_device_add_data(&ehci_device, pdata, sizeof(*pdata));
  208. /* Setup Pin IO MUX for EHCI */
  209. if (cpu_is_omap34xx())
  210. setup_ehci_io_mux(pdata->port_mode);
  211. if (platform_device_register(&ehci_device) < 0) {
  212. printk(KERN_ERR "Unable to register HS-USB (EHCI) device\n");
  213. return;
  214. }
  215. }
  216. #else
  217. void __init usb_ehci_init(const struct ehci_hcd_omap_platform_data *pdata)
  218. {
  219. }
  220. #endif /* CONFIG_USB_EHCI_HCD */
  221. #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
  222. static struct resource ohci_resources[] = {
  223. {
  224. .start = OMAP34XX_OHCI_BASE,
  225. .end = OMAP34XX_OHCI_BASE + SZ_1K - 1,
  226. .flags = IORESOURCE_MEM,
  227. },
  228. {
  229. .start = OMAP34XX_UHH_CONFIG_BASE,
  230. .end = OMAP34XX_UHH_CONFIG_BASE + SZ_1K - 1,
  231. .flags = IORESOURCE_MEM,
  232. },
  233. {
  234. .start = OMAP34XX_USBTLL_BASE,
  235. .end = OMAP34XX_USBTLL_BASE + SZ_4K - 1,
  236. .flags = IORESOURCE_MEM,
  237. },
  238. { /* general IRQ */
  239. .start = INT_34XX_OHCI_IRQ,
  240. .flags = IORESOURCE_IRQ,
  241. }
  242. };
  243. static u64 ohci_dmamask = DMA_BIT_MASK(32);
  244. static struct platform_device ohci_device = {
  245. .name = "ohci-omap3",
  246. .id = 0,
  247. .dev = {
  248. .dma_mask = &ohci_dmamask,
  249. .coherent_dma_mask = 0xffffffff,
  250. },
  251. .num_resources = ARRAY_SIZE(ohci_resources),
  252. .resource = ohci_resources,
  253. };
  254. static void setup_ohci_io_mux(const enum ohci_omap3_port_mode *port_mode)
  255. {
  256. switch (port_mode[0]) {
  257. case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0:
  258. case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM:
  259. case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0:
  260. case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM:
  261. omap_mux_init_signal("mm1_rxdp",
  262. OMAP_PIN_INPUT_PULLDOWN);
  263. omap_mux_init_signal("mm1_rxdm",
  264. OMAP_PIN_INPUT_PULLDOWN);
  265. /* FALLTHROUGH */
  266. case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM:
  267. case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM:
  268. omap_mux_init_signal("mm1_rxrcv",
  269. OMAP_PIN_INPUT_PULLDOWN);
  270. /* FALLTHROUGH */
  271. case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0:
  272. case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0:
  273. omap_mux_init_signal("mm1_txen_n", OMAP_PIN_OUTPUT);
  274. /* FALLTHROUGH */
  275. case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0:
  276. case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM:
  277. omap_mux_init_signal("mm1_txse0",
  278. OMAP_PIN_INPUT_PULLDOWN);
  279. omap_mux_init_signal("mm1_txdat",
  280. OMAP_PIN_INPUT_PULLDOWN);
  281. break;
  282. case OMAP_OHCI_PORT_MODE_UNUSED:
  283. /* FALLTHROUGH */
  284. default:
  285. break;
  286. }
  287. switch (port_mode[1]) {
  288. case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0:
  289. case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM:
  290. case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0:
  291. case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM:
  292. omap_mux_init_signal("mm2_rxdp",
  293. OMAP_PIN_INPUT_PULLDOWN);
  294. omap_mux_init_signal("mm2_rxdm",
  295. OMAP_PIN_INPUT_PULLDOWN);
  296. /* FALLTHROUGH */
  297. case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM:
  298. case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM:
  299. omap_mux_init_signal("mm2_rxrcv",
  300. OMAP_PIN_INPUT_PULLDOWN);
  301. /* FALLTHROUGH */
  302. case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0:
  303. case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0:
  304. omap_mux_init_signal("mm2_txen_n", OMAP_PIN_OUTPUT);
  305. /* FALLTHROUGH */
  306. case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0:
  307. case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM:
  308. omap_mux_init_signal("mm2_txse0",
  309. OMAP_PIN_INPUT_PULLDOWN);
  310. omap_mux_init_signal("mm2_txdat",
  311. OMAP_PIN_INPUT_PULLDOWN);
  312. break;
  313. case OMAP_OHCI_PORT_MODE_UNUSED:
  314. /* FALLTHROUGH */
  315. default:
  316. break;
  317. }
  318. switch (port_mode[2]) {
  319. case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0:
  320. case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM:
  321. case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0:
  322. case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM:
  323. omap_mux_init_signal("mm3_rxdp",
  324. OMAP_PIN_INPUT_PULLDOWN);
  325. omap_mux_init_signal("mm3_rxdm",
  326. OMAP_PIN_INPUT_PULLDOWN);
  327. /* FALLTHROUGH */
  328. case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM:
  329. case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM:
  330. omap_mux_init_signal("mm3_rxrcv",
  331. OMAP_PIN_INPUT_PULLDOWN);
  332. /* FALLTHROUGH */
  333. case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0:
  334. case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0:
  335. omap_mux_init_signal("mm3_txen_n", OMAP_PIN_OUTPUT);
  336. /* FALLTHROUGH */
  337. case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0:
  338. case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM:
  339. omap_mux_init_signal("mm3_txse0",
  340. OMAP_PIN_INPUT_PULLDOWN);
  341. omap_mux_init_signal("mm3_txdat",
  342. OMAP_PIN_INPUT_PULLDOWN);
  343. break;
  344. case OMAP_OHCI_PORT_MODE_UNUSED:
  345. /* FALLTHROUGH */
  346. default:
  347. break;
  348. }
  349. }
  350. void __init usb_ohci_init(const struct ohci_hcd_omap_platform_data *pdata)
  351. {
  352. platform_device_add_data(&ohci_device, pdata, sizeof(*pdata));
  353. /* Setup Pin IO MUX for OHCI */
  354. if (cpu_is_omap34xx())
  355. setup_ohci_io_mux(pdata->port_mode);
  356. if (platform_device_register(&ohci_device) < 0) {
  357. pr_err("Unable to register FS-USB (OHCI) device\n");
  358. return;
  359. }
  360. }
  361. #else
  362. void __init usb_ohci_init(const struct ohci_hcd_omap_platform_data *pdata)
  363. {
  364. }
  365. #endif /* CONFIG_USB_OHCI_HCD */