197-USB-bcma-add-USB-3.0-support.patch 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. From 121ec6539abedbc0e975cf35f48ee044b323e4c3 Mon Sep 17 00:00:00 2001
  2. From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
  3. Date: Tue, 16 Jun 2015 17:14:26 +0200
  4. Subject: [PATCH v3 5/6] usb: bcma: add USB 3.0 support
  5. MIME-Version: 1.0
  6. Content-Type: text/plain; charset=UTF-8
  7. Content-Transfer-Encoding: 8bit
  8. Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
  9. Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
  10. ---
  11. drivers/usb/host/bcma-hcd.c | 225 ++++++++++++++++++++++++++++++++++++++++++++
  12. 1 file changed, 225 insertions(+)
  13. --- a/drivers/usb/host/bcma-hcd.c
  14. +++ b/drivers/usb/host/bcma-hcd.c
  15. @@ -29,6 +29,7 @@
  16. #include <linux/of_gpio.h>
  17. #include <linux/usb/ehci_pdriver.h>
  18. #include <linux/usb/ohci_pdriver.h>
  19. +#include <linux/usb/xhci_pdriver.h>
  20. MODULE_AUTHOR("Hauke Mehrtens");
  21. MODULE_DESCRIPTION("Common USB driver for BCMA Bus");
  22. @@ -38,6 +39,7 @@ struct bcma_hcd_device {
  23. struct bcma_device *core;
  24. struct platform_device *ehci_dev;
  25. struct platform_device *ohci_dev;
  26. + struct platform_device *xhci_dev;
  27. struct gpio_desc *gpio_desc;
  28. };
  29. @@ -245,6 +247,10 @@ static const struct usb_ehci_pdata ehci_
  30. static const struct usb_ohci_pdata ohci_pdata = {
  31. };
  32. +static const struct usb_xhci_pdata xhci_pdata = {
  33. + .usb3_fake_doorbell = 1
  34. +};
  35. +
  36. static struct platform_device *bcma_hcd_create_pdev(struct bcma_device *dev,
  37. const char *name, u32 addr,
  38. const void *data,
  39. @@ -338,6 +344,216 @@ err_unregister_ohci_dev:
  40. return err;
  41. }
  42. +static bool bcma_wait_reg(struct bcma_bus *bus, void __iomem *addr, u32 mask,
  43. + u32 value, int timeout)
  44. +{
  45. + unsigned long deadline = jiffies + timeout;
  46. + u32 val;
  47. +
  48. + do {
  49. + val = readl(addr);
  50. + if ((val & mask) == value)
  51. + return true;
  52. + cpu_relax();
  53. + udelay(10);
  54. + } while (!time_after_eq(jiffies, deadline));
  55. +
  56. + pr_err("Timeout waiting for register %p\n", addr);
  57. +
  58. + return false;
  59. +}
  60. +
  61. +static void bcma_hcd_usb30_phy_init(struct bcma_hcd_device *bcma_hcd)
  62. +{
  63. + struct bcma_device *core = bcma_hcd->core;
  64. + struct bcma_bus *bus = core->bus;
  65. + struct bcma_chipinfo *chipinfo = &bus->chipinfo;
  66. + struct bcma_drv_cc_b *ccb = &bus->drv_cc_b;
  67. + struct bcma_device *arm_core;
  68. + void __iomem *dmu = NULL;
  69. + u32 cru_straps_ctrl;
  70. +
  71. + if (chipinfo->id != BCMA_CHIP_ID_BCM4707 &&
  72. + chipinfo->id != BCMA_CHIP_ID_BCM53018)
  73. + return;
  74. +
  75. + arm_core = bcma_find_core(bus, BCMA_CORE_ARMCA9);
  76. + if (!arm_core)
  77. + return;
  78. +
  79. + dmu = ioremap_nocache(arm_core->addr_s[0], 0x1000);
  80. + if (!dmu)
  81. + goto out;
  82. +
  83. + /* Check strapping of PCIE/USB3 SEL */
  84. + cru_straps_ctrl = ioread32(dmu + 0x2a0);
  85. + if ((cru_straps_ctrl & 0x10) == 0)
  86. + goto out;
  87. +
  88. + /* Perform USB3 system soft reset */
  89. + bcma_awrite32(core, BCMA_RESET_CTL, BCMA_RESET_CTL_RESET);
  90. +
  91. + /* Enable MDIO. Setting MDCDIV as 26 */
  92. + iowrite32(0x0000009a, ccb->mii + 0x000);
  93. + udelay(2);
  94. +
  95. + switch (chipinfo->id) {
  96. + case BCMA_CHIP_ID_BCM4707:
  97. + if (chipinfo->rev == 4) {
  98. + /* For NS-B0, USB3 PLL Block */
  99. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  100. + iowrite32(0x587e8000, ccb->mii + 0x004);
  101. +
  102. + /* Clear ana_pllSeqStart */
  103. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  104. + iowrite32(0x58061000, ccb->mii + 0x004);
  105. +
  106. + /* CMOS Divider ratio to 25 */
  107. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  108. + iowrite32(0x582a6400, ccb->mii + 0x004);
  109. +
  110. + /* Asserting PLL Reset */
  111. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  112. + iowrite32(0x582ec000, ccb->mii + 0x004);
  113. +
  114. + /* Deaaserting PLL Reset */
  115. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  116. + iowrite32(0x582e8000, ccb->mii + 0x004);
  117. +
  118. + /* Deasserting USB3 system reset */
  119. + bcma_awrite32(core, BCMA_RESET_CTL, 0);
  120. +
  121. + /* Set ana_pllSeqStart */
  122. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  123. + iowrite32(0x58069000, ccb->mii + 0x004);
  124. +
  125. + /* RXPMD block */
  126. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  127. + iowrite32(0x587e8020, ccb->mii + 0x004);
  128. +
  129. + /* CDR int loop locking BW to 1 */
  130. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  131. + iowrite32(0x58120049, ccb->mii + 0x004);
  132. +
  133. + /* CDR int loop acquisition BW to 1 */
  134. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  135. + iowrite32(0x580e0049, ccb->mii + 0x004);
  136. +
  137. + /* CDR prop loop BW to 1 */
  138. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  139. + iowrite32(0x580a005c, ccb->mii + 0x004);
  140. +
  141. + /* Waiting MII Mgt interface idle */
  142. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  143. + } else {
  144. + /* PLL30 block */
  145. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  146. + iowrite32(0x587e8000, ccb->mii + 0x004);
  147. +
  148. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  149. + iowrite32(0x582a6400, ccb->mii + 0x004);
  150. +
  151. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  152. + iowrite32(0x587e80e0, ccb->mii + 0x004);
  153. +
  154. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  155. + iowrite32(0x580a009c, ccb->mii + 0x004);
  156. +
  157. + /* Enable SSC */
  158. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  159. + iowrite32(0x587e8040, ccb->mii + 0x004);
  160. +
  161. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  162. + iowrite32(0x580a21d3, ccb->mii + 0x004);
  163. +
  164. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  165. + iowrite32(0x58061003, ccb->mii + 0x004);
  166. +
  167. + /* Waiting MII Mgt interface idle */
  168. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  169. +
  170. + /* Deasserting USB3 system reset */
  171. + bcma_awrite32(core, BCMA_RESET_CTL, 0);
  172. + }
  173. + break;
  174. + case BCMA_CHIP_ID_BCM53018:
  175. + /* USB3 PLL Block */
  176. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  177. + iowrite32(0x587e8000, ccb->mii + 0x004);
  178. +
  179. + /* Assert Ana_Pllseq start */
  180. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  181. + iowrite32(0x58061000, ccb->mii + 0x004);
  182. +
  183. + /* Assert CML Divider ratio to 26 */
  184. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  185. + iowrite32(0x582a6400, ccb->mii + 0x004);
  186. +
  187. + /* Asserting PLL Reset */
  188. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  189. + iowrite32(0x582ec000, ccb->mii + 0x004);
  190. +
  191. + /* Deaaserting PLL Reset */
  192. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  193. + iowrite32(0x582e8000, ccb->mii + 0x004);
  194. +
  195. + /* Waiting MII Mgt interface idle */
  196. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  197. +
  198. + /* Deasserting USB3 system reset */
  199. + bcma_awrite32(core, BCMA_RESET_CTL, 0);
  200. +
  201. + /* PLL frequency monitor enable */
  202. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  203. + iowrite32(0x58069000, ccb->mii + 0x004);
  204. +
  205. + /* PIPE Block */
  206. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  207. + iowrite32(0x587e8060, ccb->mii + 0x004);
  208. +
  209. + /* CMPMAX & CMPMINTH setting */
  210. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  211. + iowrite32(0x580af30d, ccb->mii + 0x004);
  212. +
  213. + /* DEGLITCH MIN & MAX setting */
  214. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  215. + iowrite32(0x580e6302, ccb->mii + 0x004);
  216. +
  217. + /* TXPMD block */
  218. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  219. + iowrite32(0x587e8040, ccb->mii + 0x004);
  220. +
  221. + /* Enabling SSC */
  222. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  223. + iowrite32(0x58061003, ccb->mii + 0x004);
  224. +
  225. + /* Waiting MII Mgt interface idle */
  226. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  227. +
  228. + break;
  229. + }
  230. +out:
  231. + if (dmu)
  232. + iounmap(dmu);
  233. +}
  234. +
  235. +static int bcma_hcd_usb30_init(struct bcma_hcd_device *bcma_hcd)
  236. +{
  237. + struct bcma_device *core = bcma_hcd->core;
  238. +
  239. + bcma_core_enable(core, 0);
  240. +
  241. + bcma_hcd_usb30_phy_init(bcma_hcd);
  242. +
  243. + bcma_hcd->xhci_dev = bcma_hcd_create_pdev(core, "xhci-hcd", core->addr,
  244. + &xhci_pdata,
  245. + sizeof(xhci_pdata));
  246. + if (IS_ERR(bcma_hcd->ohci_dev))
  247. + return PTR_ERR(bcma_hcd->ohci_dev);
  248. +
  249. + return 0;
  250. +}
  251. +
  252. static int bcma_hcd_probe(struct bcma_device *dev)
  253. {
  254. int err;
  255. @@ -364,6 +580,11 @@ static int bcma_hcd_probe(struct bcma_de
  256. if (err)
  257. return err;
  258. break;
  259. + case BCMA_CORE_NS_USB30:
  260. + err = bcma_hcd_usb30_init(usb_dev);
  261. + if (err)
  262. + return err;
  263. + break;
  264. default:
  265. return -ENODEV;
  266. }
  267. @@ -377,11 +598,14 @@ static void bcma_hcd_remove(struct bcma_
  268. struct bcma_hcd_device *usb_dev = bcma_get_drvdata(dev);
  269. struct platform_device *ohci_dev = usb_dev->ohci_dev;
  270. struct platform_device *ehci_dev = usb_dev->ehci_dev;
  271. + struct platform_device *xhci_dev = usb_dev->xhci_dev;
  272. if (ohci_dev)
  273. platform_device_unregister(ohci_dev);
  274. if (ehci_dev)
  275. platform_device_unregister(ehci_dev);
  276. + if (xhci_dev)
  277. + platform_device_unregister(xhci_dev);
  278. bcma_core_disable(dev, 0);
  279. }
  280. @@ -418,6 +642,7 @@ static int bcma_hcd_resume(struct bcma_d
  281. static const struct bcma_device_id bcma_hcd_table[] = {
  282. BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_USB20_HOST, BCMA_ANY_REV, BCMA_ANY_CLASS),
  283. BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_NS_USB20, BCMA_ANY_REV, BCMA_ANY_CLASS),
  284. + BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_NS_USB30, BCMA_ANY_REV, BCMA_ANY_CLASS),
  285. {},
  286. };
  287. MODULE_DEVICE_TABLE(bcma, bcma_hcd_table);