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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  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,167 @@ 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_BCM47094 &&
  73. + chipinfo->id != BCMA_CHIP_ID_BCM53018)
  74. + return;
  75. +
  76. + arm_core = bcma_find_core(bus, BCMA_CORE_ARMCA9);
  77. + if (!arm_core)
  78. + return;
  79. +
  80. + dmu = ioremap_nocache(arm_core->addr_s[0], 0x1000);
  81. + if (!dmu)
  82. + goto out;
  83. +
  84. + /* Check strapping of PCIE/USB3 SEL */
  85. + cru_straps_ctrl = ioread32(dmu + 0x2a0);
  86. + if ((cru_straps_ctrl & 0x10) == 0)
  87. + goto out;
  88. +
  89. + /* Perform USB3 system soft reset */
  90. + bcma_awrite32(core, BCMA_RESET_CTL, BCMA_RESET_CTL_RESET);
  91. +
  92. + /* Enable MDIO. Setting MDCDIV as 26 */
  93. + iowrite32(0x0000009a, ccb->mii + 0x000);
  94. + udelay(2);
  95. +
  96. + if (chipinfo->id == BCMA_CHIP_ID_BCM53018 ||
  97. + (chipinfo->id == BCMA_CHIP_ID_BCM4707 && (chipinfo->rev == 4 || chipinfo->rev == 6)) ||
  98. + chipinfo->id == BCMA_CHIP_ID_BCM47094) {
  99. + /* For NS-B0, USB3 PLL Block */
  100. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  101. + iowrite32(0x587e8000, ccb->mii + 0x004);
  102. +
  103. + /* Clear ana_pllSeqStart */
  104. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  105. + iowrite32(0x58061000, ccb->mii + 0x004);
  106. +
  107. + /* CMOS Divider ratio to 25 */
  108. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  109. + iowrite32(0x582a6400, ccb->mii + 0x004);
  110. +
  111. + /* Asserting PLL Reset */
  112. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  113. + iowrite32(0x582ec000, ccb->mii + 0x004);
  114. +
  115. + /* Deaaserting PLL Reset */
  116. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  117. + iowrite32(0x582e8000, ccb->mii + 0x004);
  118. +
  119. + /* Waiting MII Mgt interface idle */
  120. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  121. +
  122. + /* Deasserting USB3 system reset */
  123. + bcma_awrite32(core, BCMA_RESET_CTL, 0);
  124. +
  125. + /* PLL frequency monitor enable */
  126. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  127. + iowrite32(0x58069000, ccb->mii + 0x004);
  128. +
  129. + /* PIPE Block */
  130. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  131. + iowrite32(0x587e8060, ccb->mii + 0x004);
  132. +
  133. + /* CMPMAX & CMPMINTH setting */
  134. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  135. + iowrite32(0x580af30d, ccb->mii + 0x004);
  136. +
  137. + /* DEGLITCH MIN & MAX setting */
  138. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  139. + iowrite32(0x580e6302, ccb->mii + 0x004);
  140. +
  141. + /* TXPMD block */
  142. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  143. + iowrite32(0x587e8040, ccb->mii + 0x004);
  144. +
  145. + /* Enabling SSC */
  146. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  147. + iowrite32(0x58061003, ccb->mii + 0x004);
  148. +
  149. + /* Waiting MII Mgt interface idle */
  150. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  151. + } else if (chipinfo->id == BCMA_CHIP_ID_BCM4707) {
  152. + /* PLL30 block */
  153. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  154. + iowrite32(0x587e8000, ccb->mii + 0x004);
  155. +
  156. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  157. + iowrite32(0x582a6400, ccb->mii + 0x004);
  158. +
  159. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  160. + iowrite32(0x587e80e0, ccb->mii + 0x004);
  161. +
  162. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  163. + iowrite32(0x580a009c, ccb->mii + 0x004);
  164. +
  165. + /* Enable SSC */
  166. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  167. + iowrite32(0x587e8040, ccb->mii + 0x004);
  168. +
  169. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  170. + iowrite32(0x580a21d3, ccb->mii + 0x004);
  171. +
  172. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  173. + iowrite32(0x58061003, ccb->mii + 0x004);
  174. +
  175. + /* Waiting MII Mgt interface idle */
  176. + bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
  177. +
  178. + /* Deasserting USB3 system reset */
  179. + bcma_awrite32(core, BCMA_RESET_CTL, 0);
  180. + }
  181. +out:
  182. + if (dmu)
  183. + iounmap(dmu);
  184. +}
  185. +
  186. +static int bcma_hcd_usb30_init(struct bcma_hcd_device *bcma_hcd)
  187. +{
  188. + struct bcma_device *core = bcma_hcd->core;
  189. +
  190. + bcma_core_enable(core, 0);
  191. +
  192. + bcma_hcd_usb30_phy_init(bcma_hcd);
  193. +
  194. + bcma_hcd->xhci_dev = bcma_hcd_create_pdev(core, "xhci-hcd", core->addr,
  195. + &xhci_pdata,
  196. + sizeof(xhci_pdata));
  197. + if (IS_ERR(bcma_hcd->ohci_dev))
  198. + return PTR_ERR(bcma_hcd->ohci_dev);
  199. +
  200. + return 0;
  201. +}
  202. +
  203. static int bcma_hcd_probe(struct bcma_device *core)
  204. {
  205. int err;
  206. @@ -362,6 +529,11 @@ static int bcma_hcd_probe(struct bcma_de
  207. if (err)
  208. return err;
  209. break;
  210. + case BCMA_CORE_NS_USB30:
  211. + err = bcma_hcd_usb30_init(usb_dev);
  212. + if (err)
  213. + return err;
  214. + break;
  215. default:
  216. return -ENODEV;
  217. }
  218. @@ -375,11 +547,14 @@ static void bcma_hcd_remove(struct bcma_
  219. struct bcma_hcd_device *usb_dev = bcma_get_drvdata(dev);
  220. struct platform_device *ohci_dev = usb_dev->ohci_dev;
  221. struct platform_device *ehci_dev = usb_dev->ehci_dev;
  222. + struct platform_device *xhci_dev = usb_dev->xhci_dev;
  223. if (ohci_dev)
  224. platform_device_unregister(ohci_dev);
  225. if (ehci_dev)
  226. platform_device_unregister(ehci_dev);
  227. + if (xhci_dev)
  228. + platform_device_unregister(xhci_dev);
  229. bcma_core_disable(dev, 0);
  230. }
  231. @@ -416,6 +591,7 @@ static int bcma_hcd_resume(struct bcma_d
  232. static const struct bcma_device_id bcma_hcd_table[] = {
  233. BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_USB20_HOST, BCMA_ANY_REV, BCMA_ANY_CLASS),
  234. BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_NS_USB20, BCMA_ANY_REV, BCMA_ANY_CLASS),
  235. + BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_NS_USB30, BCMA_ANY_REV, BCMA_ANY_CLASS),
  236. {},
  237. };
  238. MODULE_DEVICE_TABLE(bcma, bcma_hcd_table);