pxa3xx-ulpi.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401
  1. /*
  2. * linux/arch/arm/mach-pxa/pxa3xx-ulpi.c
  3. *
  4. * code specific to pxa3xx aka Monahans
  5. *
  6. * Copyright (C) 2010 CompuLab Ltd.
  7. *
  8. * 2010-13-07: Igor Grinberg <grinberg@compulab.co.il>
  9. * initial version: pxa310 USB Host mode support
  10. *
  11. * This program is free software; you can redistribute it and/or modify
  12. * it under the terms of the GNU General Public License version 2 as
  13. * published by the Free Software Foundation.
  14. */
  15. #include <linux/module.h>
  16. #include <linux/kernel.h>
  17. #include <linux/slab.h>
  18. #include <linux/device.h>
  19. #include <linux/platform_device.h>
  20. #include <linux/err.h>
  21. #include <linux/io.h>
  22. #include <linux/delay.h>
  23. #include <linux/clk.h>
  24. #include <linux/usb.h>
  25. #include <linux/usb/otg.h>
  26. #include <mach/hardware.h>
  27. #include <mach/regs-u2d.h>
  28. #include <mach/pxa3xx-u2d.h>
  29. struct pxa3xx_u2d_ulpi {
  30. struct clk *clk;
  31. void __iomem *mmio_base;
  32. struct otg_transceiver *otg;
  33. unsigned int ulpi_mode;
  34. };
  35. static struct pxa3xx_u2d_ulpi *u2d;
  36. static inline u32 u2d_readl(u32 reg)
  37. {
  38. return __raw_readl(u2d->mmio_base + reg);
  39. }
  40. static inline void u2d_writel(u32 reg, u32 val)
  41. {
  42. __raw_writel(val, u2d->mmio_base + reg);
  43. }
  44. #if defined(CONFIG_PXA310_ULPI)
  45. enum u2d_ulpi_phy_mode {
  46. SYNCH = 0,
  47. CARKIT = (1 << 0),
  48. SER_3PIN = (1 << 1),
  49. SER_6PIN = (1 << 2),
  50. LOWPOWER = (1 << 3),
  51. };
  52. static inline enum u2d_ulpi_phy_mode pxa310_ulpi_get_phymode(void)
  53. {
  54. return (u2d_readl(U2DOTGUSR) >> 28) & 0xF;
  55. }
  56. static int pxa310_ulpi_poll(void)
  57. {
  58. int timeout = 50000;
  59. while (timeout--) {
  60. if (!(u2d_readl(U2DOTGUCR) & U2DOTGUCR_RUN))
  61. return 0;
  62. cpu_relax();
  63. }
  64. pr_warning("%s: ULPI access timed out!\n", __func__);
  65. return -ETIMEDOUT;
  66. }
  67. static int pxa310_ulpi_read(struct otg_transceiver *otg, u32 reg)
  68. {
  69. int err;
  70. if (pxa310_ulpi_get_phymode() != SYNCH) {
  71. pr_warning("%s: PHY is not in SYNCH mode!\n", __func__);
  72. return -EBUSY;
  73. }
  74. u2d_writel(U2DOTGUCR, U2DOTGUCR_RUN | U2DOTGUCR_RNW | (reg << 16));
  75. msleep(5);
  76. err = pxa310_ulpi_poll();
  77. if (err)
  78. return err;
  79. return u2d_readl(U2DOTGUCR) & U2DOTGUCR_RDATA;
  80. }
  81. static int pxa310_ulpi_write(struct otg_transceiver *otg, u32 val, u32 reg)
  82. {
  83. if (pxa310_ulpi_get_phymode() != SYNCH) {
  84. pr_warning("%s: PHY is not in SYNCH mode!\n", __func__);
  85. return -EBUSY;
  86. }
  87. u2d_writel(U2DOTGUCR, U2DOTGUCR_RUN | (reg << 16) | (val << 8));
  88. msleep(5);
  89. return pxa310_ulpi_poll();
  90. }
  91. struct otg_io_access_ops pxa310_ulpi_access_ops = {
  92. .read = pxa310_ulpi_read,
  93. .write = pxa310_ulpi_write,
  94. };
  95. static void pxa310_otg_transceiver_rtsm(void)
  96. {
  97. u32 u2dotgcr;
  98. /* put PHY to sync mode */
  99. u2dotgcr = u2d_readl(U2DOTGCR);
  100. u2dotgcr |= U2DOTGCR_RTSM | U2DOTGCR_UTMID;
  101. u2d_writel(U2DOTGCR, u2dotgcr);
  102. msleep(10);
  103. /* setup OTG sync mode */
  104. u2dotgcr = u2d_readl(U2DOTGCR);
  105. u2dotgcr |= U2DOTGCR_ULAF;
  106. u2dotgcr &= ~(U2DOTGCR_SMAF | U2DOTGCR_CKAF);
  107. u2d_writel(U2DOTGCR, u2dotgcr);
  108. }
  109. static int pxa310_start_otg_host_transcvr(struct usb_bus *host)
  110. {
  111. int err;
  112. pxa310_otg_transceiver_rtsm();
  113. err = otg_init(u2d->otg);
  114. if (err) {
  115. pr_err("OTG transceiver init failed");
  116. return err;
  117. }
  118. err = otg_set_vbus(u2d->otg, 1);
  119. if (err) {
  120. pr_err("OTG transceiver VBUS set failed");
  121. return err;
  122. }
  123. err = otg_set_host(u2d->otg, host);
  124. if (err)
  125. pr_err("OTG transceiver Host mode set failed");
  126. return err;
  127. }
  128. static int pxa310_start_otg_hc(struct usb_bus *host)
  129. {
  130. u32 u2dotgcr;
  131. int err;
  132. /* disable USB device controller */
  133. u2d_writel(U2DCR, u2d_readl(U2DCR) & ~U2DCR_UDE);
  134. u2d_writel(U2DOTGCR, u2d_readl(U2DOTGCR) | U2DOTGCR_UTMID);
  135. u2d_writel(U2DOTGICR, u2d_readl(U2DOTGICR) & ~0x37F7F);
  136. err = pxa310_start_otg_host_transcvr(host);
  137. if (err)
  138. return err;
  139. /* set xceiver mode */
  140. if (u2d->ulpi_mode & ULPI_IC_6PIN_SERIAL)
  141. u2d_writel(U2DP3CR, u2d_readl(U2DP3CR) & ~U2DP3CR_P2SS);
  142. else if (u2d->ulpi_mode & ULPI_IC_3PIN_SERIAL)
  143. u2d_writel(U2DP3CR, u2d_readl(U2DP3CR) | U2DP3CR_P2SS);
  144. /* start OTG host controller */
  145. u2dotgcr = u2d_readl(U2DOTGCR) | U2DOTGCR_SMAF;
  146. u2d_writel(U2DOTGCR, u2dotgcr & ~(U2DOTGCR_ULAF | U2DOTGCR_CKAF));
  147. return 0;
  148. }
  149. static void pxa310_stop_otg_hc(void)
  150. {
  151. pxa310_otg_transceiver_rtsm();
  152. otg_set_host(u2d->otg, NULL);
  153. otg_set_vbus(u2d->otg, 0);
  154. otg_shutdown(u2d->otg);
  155. }
  156. static void pxa310_u2d_setup_otg_hc(void)
  157. {
  158. u32 u2dotgcr;
  159. u2dotgcr = u2d_readl(U2DOTGCR);
  160. u2dotgcr |= U2DOTGCR_ULAF | U2DOTGCR_UTMID;
  161. u2dotgcr &= ~(U2DOTGCR_SMAF | U2DOTGCR_CKAF);
  162. u2d_writel(U2DOTGCR, u2dotgcr);
  163. msleep(5);
  164. u2d_writel(U2DOTGCR, u2dotgcr | U2DOTGCR_ULE);
  165. msleep(5);
  166. u2d_writel(U2DOTGICR, u2d_readl(U2DOTGICR) & ~0x37F7F);
  167. }
  168. static int pxa310_otg_init(struct pxa3xx_u2d_platform_data *pdata)
  169. {
  170. unsigned int ulpi_mode = ULPI_OTG_DRVVBUS;
  171. if (pdata) {
  172. if (pdata->ulpi_mode & ULPI_SER_6PIN)
  173. ulpi_mode |= ULPI_IC_6PIN_SERIAL;
  174. else if (pdata->ulpi_mode & ULPI_SER_3PIN)
  175. ulpi_mode |= ULPI_IC_3PIN_SERIAL;
  176. }
  177. u2d->ulpi_mode = ulpi_mode;
  178. u2d->otg = otg_ulpi_create(&pxa310_ulpi_access_ops, ulpi_mode);
  179. if (!u2d->otg)
  180. return -ENOMEM;
  181. u2d->otg->io_priv = u2d->mmio_base;
  182. return 0;
  183. }
  184. static void pxa310_otg_exit(void)
  185. {
  186. kfree(u2d->otg);
  187. }
  188. #else
  189. static inline void pxa310_u2d_setup_otg_hc(void) {}
  190. static inline int pxa310_start_otg_hc(struct usb_bus *host)
  191. {
  192. return 0;
  193. }
  194. static inline void pxa310_stop_otg_hc(void) {}
  195. static inline int pxa310_otg_init(struct pxa3xx_u2d_platform_data *pdata)
  196. {
  197. return 0;
  198. }
  199. static inline void pxa310_otg_exit(void) {}
  200. #endif /* CONFIG_PXA310_ULPI */
  201. int pxa3xx_u2d_start_hc(struct usb_bus *host)
  202. {
  203. int err = 0;
  204. /* In case the PXA3xx ULPI isn't used, do nothing. */
  205. if (!u2d)
  206. return 0;
  207. clk_enable(u2d->clk);
  208. if (cpu_is_pxa310()) {
  209. pxa310_u2d_setup_otg_hc();
  210. err = pxa310_start_otg_hc(host);
  211. }
  212. return err;
  213. }
  214. void pxa3xx_u2d_stop_hc(struct usb_bus *host)
  215. {
  216. /* In case the PXA3xx ULPI isn't used, do nothing. */
  217. if (!u2d)
  218. return;
  219. if (cpu_is_pxa310())
  220. pxa310_stop_otg_hc();
  221. clk_disable(u2d->clk);
  222. }
  223. static int pxa3xx_u2d_probe(struct platform_device *pdev)
  224. {
  225. struct pxa3xx_u2d_platform_data *pdata = pdev->dev.platform_data;
  226. struct resource *r;
  227. int err;
  228. u2d = kzalloc(sizeof(struct pxa3xx_u2d_ulpi), GFP_KERNEL);
  229. if (!u2d) {
  230. dev_err(&pdev->dev, "failed to allocate memory\n");
  231. return -ENOMEM;
  232. }
  233. u2d->clk = clk_get(&pdev->dev, NULL);
  234. if (IS_ERR(u2d->clk)) {
  235. dev_err(&pdev->dev, "failed to get u2d clock\n");
  236. err = PTR_ERR(u2d->clk);
  237. goto err_free_mem;
  238. }
  239. r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  240. if (!r) {
  241. dev_err(&pdev->dev, "no IO memory resource defined\n");
  242. err = -ENODEV;
  243. goto err_put_clk;
  244. }
  245. r = request_mem_region(r->start, resource_size(r), pdev->name);
  246. if (!r) {
  247. dev_err(&pdev->dev, "failed to request memory resource\n");
  248. err = -EBUSY;
  249. goto err_put_clk;
  250. }
  251. u2d->mmio_base = ioremap(r->start, resource_size(r));
  252. if (!u2d->mmio_base) {
  253. dev_err(&pdev->dev, "ioremap() failed\n");
  254. err = -ENODEV;
  255. goto err_free_res;
  256. }
  257. if (pdata->init) {
  258. err = pdata->init(&pdev->dev);
  259. if (err)
  260. goto err_free_io;
  261. }
  262. /* Only PXA310 U2D has OTG functionality */
  263. if (cpu_is_pxa310()) {
  264. err = pxa310_otg_init(pdata);
  265. if (err)
  266. goto err_free_plat;
  267. }
  268. platform_set_drvdata(pdev, &u2d);
  269. return 0;
  270. err_free_plat:
  271. if (pdata->exit)
  272. pdata->exit(&pdev->dev);
  273. err_free_io:
  274. iounmap(u2d->mmio_base);
  275. err_free_res:
  276. release_mem_region(r->start, resource_size(r));
  277. err_put_clk:
  278. clk_put(u2d->clk);
  279. err_free_mem:
  280. kfree(u2d);
  281. return err;
  282. }
  283. static int pxa3xx_u2d_remove(struct platform_device *pdev)
  284. {
  285. struct pxa3xx_u2d_platform_data *pdata = pdev->dev.platform_data;
  286. struct resource *r;
  287. if (cpu_is_pxa310()) {
  288. pxa310_stop_otg_hc();
  289. pxa310_otg_exit();
  290. }
  291. if (pdata->exit)
  292. pdata->exit(&pdev->dev);
  293. platform_set_drvdata(pdev, NULL);
  294. iounmap(u2d->mmio_base);
  295. r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  296. release_mem_region(r->start, resource_size(r));
  297. clk_put(u2d->clk);
  298. kfree(u2d);
  299. return 0;
  300. }
  301. static struct platform_driver pxa3xx_u2d_ulpi_driver = {
  302. .driver = {
  303. .name = "pxa3xx-u2d",
  304. .owner = THIS_MODULE,
  305. },
  306. .probe = pxa3xx_u2d_probe,
  307. .remove = pxa3xx_u2d_remove,
  308. };
  309. static int pxa3xx_u2d_ulpi_init(void)
  310. {
  311. return platform_driver_register(&pxa3xx_u2d_ulpi_driver);
  312. }
  313. module_init(pxa3xx_u2d_ulpi_init);
  314. static void __exit pxa3xx_u2d_ulpi_exit(void)
  315. {
  316. platform_driver_unregister(&pxa3xx_u2d_ulpi_driver);
  317. }
  318. module_exit(pxa3xx_u2d_ulpi_exit);
  319. MODULE_DESCRIPTION("PXA3xx U2D ULPI driver");
  320. MODULE_AUTHOR("Igor Grinberg");
  321. MODULE_LICENSE("GPL v2");