xhci-histb.c 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * xHCI host controller driver for HiSilicon STB SoCs
  4. *
  5. * Copyright (C) 2017-2018 HiSilicon Co., Ltd. http://www.hisilicon.com
  6. *
  7. * Authors: Jianguo Sun <sunjianguo1@huawei.com>
  8. */
  9. #include <linux/clk.h>
  10. #include <linux/dma-mapping.h>
  11. #include <linux/kernel.h>
  12. #include <linux/module.h>
  13. #include <linux/of.h>
  14. #include <linux/platform_device.h>
  15. #include <linux/pm_runtime.h>
  16. #include <linux/reset.h>
  17. #include "xhci.h"
  18. #define GTXTHRCFG 0xc108
  19. #define GRXTHRCFG 0xc10c
  20. #define REG_GUSB2PHYCFG0 0xc200
  21. #define BIT_UTMI_8_16 BIT(3)
  22. #define BIT_UTMI_ULPI BIT(4)
  23. #define BIT_FREECLK_EXIST BIT(30)
  24. #define REG_GUSB3PIPECTL0 0xc2c0
  25. #define USB3_DEEMPHASIS_MASK GENMASK(2, 1)
  26. #define USB3_DEEMPHASIS0 BIT(1)
  27. #define USB3_TX_MARGIN1 BIT(4)
  28. struct xhci_hcd_histb {
  29. struct device *dev;
  30. struct usb_hcd *hcd;
  31. void __iomem *ctrl;
  32. struct clk *bus_clk;
  33. struct clk *utmi_clk;
  34. struct clk *pipe_clk;
  35. struct clk *suspend_clk;
  36. struct reset_control *soft_reset;
  37. };
  38. static inline struct xhci_hcd_histb *hcd_to_histb(struct usb_hcd *hcd)
  39. {
  40. return dev_get_drvdata(hcd->self.controller);
  41. }
  42. static int xhci_histb_config(struct xhci_hcd_histb *histb)
  43. {
  44. struct device_node *np = histb->dev->of_node;
  45. u32 regval;
  46. if (of_property_match_string(np, "phys-names", "inno") >= 0) {
  47. /* USB2 PHY chose ulpi 8bit interface */
  48. regval = readl(histb->ctrl + REG_GUSB2PHYCFG0);
  49. regval &= ~BIT_UTMI_ULPI;
  50. regval &= ~(BIT_UTMI_8_16);
  51. regval &= ~BIT_FREECLK_EXIST;
  52. writel(regval, histb->ctrl + REG_GUSB2PHYCFG0);
  53. }
  54. if (of_property_match_string(np, "phys-names", "combo") >= 0) {
  55. /*
  56. * write 0x010c0012 to GUSB3PIPECTL0
  57. * GUSB3PIPECTL0[5:3] = 010 : Tx Margin = 900mV ,
  58. * decrease TX voltage
  59. * GUSB3PIPECTL0[2:1] = 01 : Tx Deemphasis = -3.5dB,
  60. * refer to xHCI spec
  61. */
  62. regval = readl(histb->ctrl + REG_GUSB3PIPECTL0);
  63. regval &= ~USB3_DEEMPHASIS_MASK;
  64. regval |= USB3_DEEMPHASIS0;
  65. regval |= USB3_TX_MARGIN1;
  66. writel(regval, histb->ctrl + REG_GUSB3PIPECTL0);
  67. }
  68. writel(0x23100000, histb->ctrl + GTXTHRCFG);
  69. writel(0x23100000, histb->ctrl + GRXTHRCFG);
  70. return 0;
  71. }
  72. static int xhci_histb_clks_get(struct xhci_hcd_histb *histb)
  73. {
  74. struct device *dev = histb->dev;
  75. histb->bus_clk = devm_clk_get(dev, "bus");
  76. if (IS_ERR(histb->bus_clk)) {
  77. dev_err(dev, "fail to get bus clk\n");
  78. return PTR_ERR(histb->bus_clk);
  79. }
  80. histb->utmi_clk = devm_clk_get(dev, "utmi");
  81. if (IS_ERR(histb->utmi_clk)) {
  82. dev_err(dev, "fail to get utmi clk\n");
  83. return PTR_ERR(histb->utmi_clk);
  84. }
  85. histb->pipe_clk = devm_clk_get(dev, "pipe");
  86. if (IS_ERR(histb->pipe_clk)) {
  87. dev_err(dev, "fail to get pipe clk\n");
  88. return PTR_ERR(histb->pipe_clk);
  89. }
  90. histb->suspend_clk = devm_clk_get(dev, "suspend");
  91. if (IS_ERR(histb->suspend_clk)) {
  92. dev_err(dev, "fail to get suspend clk\n");
  93. return PTR_ERR(histb->suspend_clk);
  94. }
  95. return 0;
  96. }
  97. static int xhci_histb_host_enable(struct xhci_hcd_histb *histb)
  98. {
  99. int ret;
  100. ret = clk_prepare_enable(histb->bus_clk);
  101. if (ret) {
  102. dev_err(histb->dev, "failed to enable bus clk\n");
  103. return ret;
  104. }
  105. ret = clk_prepare_enable(histb->utmi_clk);
  106. if (ret) {
  107. dev_err(histb->dev, "failed to enable utmi clk\n");
  108. goto err_utmi_clk;
  109. }
  110. ret = clk_prepare_enable(histb->pipe_clk);
  111. if (ret) {
  112. dev_err(histb->dev, "failed to enable pipe clk\n");
  113. goto err_pipe_clk;
  114. }
  115. ret = clk_prepare_enable(histb->suspend_clk);
  116. if (ret) {
  117. dev_err(histb->dev, "failed to enable suspend clk\n");
  118. goto err_suspend_clk;
  119. }
  120. reset_control_deassert(histb->soft_reset);
  121. return 0;
  122. err_suspend_clk:
  123. clk_disable_unprepare(histb->pipe_clk);
  124. err_pipe_clk:
  125. clk_disable_unprepare(histb->utmi_clk);
  126. err_utmi_clk:
  127. clk_disable_unprepare(histb->bus_clk);
  128. return ret;
  129. }
  130. static void xhci_histb_host_disable(struct xhci_hcd_histb *histb)
  131. {
  132. reset_control_assert(histb->soft_reset);
  133. clk_disable_unprepare(histb->suspend_clk);
  134. clk_disable_unprepare(histb->pipe_clk);
  135. clk_disable_unprepare(histb->utmi_clk);
  136. clk_disable_unprepare(histb->bus_clk);
  137. }
  138. /* called during probe() after chip reset completes */
  139. static int xhci_histb_setup(struct usb_hcd *hcd)
  140. {
  141. struct xhci_hcd_histb *histb = hcd_to_histb(hcd);
  142. int ret;
  143. if (usb_hcd_is_primary_hcd(hcd)) {
  144. ret = xhci_histb_config(histb);
  145. if (ret)
  146. return ret;
  147. }
  148. return xhci_gen_setup(hcd, NULL);
  149. }
  150. static const struct xhci_driver_overrides xhci_histb_overrides __initconst = {
  151. .reset = xhci_histb_setup,
  152. };
  153. static struct hc_driver __read_mostly xhci_histb_hc_driver;
  154. static int xhci_histb_probe(struct platform_device *pdev)
  155. {
  156. struct device *dev = &pdev->dev;
  157. struct xhci_hcd_histb *histb;
  158. const struct hc_driver *driver;
  159. struct usb_hcd *hcd;
  160. struct xhci_hcd *xhci;
  161. struct resource *res;
  162. int irq;
  163. int ret = -ENODEV;
  164. if (usb_disabled())
  165. return -ENODEV;
  166. driver = &xhci_histb_hc_driver;
  167. histb = devm_kzalloc(dev, sizeof(*histb), GFP_KERNEL);
  168. if (!histb)
  169. return -ENOMEM;
  170. histb->dev = dev;
  171. irq = platform_get_irq(pdev, 0);
  172. if (irq < 0)
  173. return irq;
  174. histb->ctrl = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
  175. if (IS_ERR(histb->ctrl))
  176. return PTR_ERR(histb->ctrl);
  177. ret = xhci_histb_clks_get(histb);
  178. if (ret)
  179. return ret;
  180. histb->soft_reset = devm_reset_control_get(dev, "soft");
  181. if (IS_ERR(histb->soft_reset)) {
  182. dev_err(dev, "failed to get soft reset\n");
  183. return PTR_ERR(histb->soft_reset);
  184. }
  185. pm_runtime_enable(dev);
  186. pm_runtime_get_sync(dev);
  187. device_enable_async_suspend(dev);
  188. /* Initialize dma_mask and coherent_dma_mask to 32-bits */
  189. ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
  190. if (ret)
  191. goto disable_pm;
  192. hcd = usb_create_hcd(driver, dev, dev_name(dev));
  193. if (!hcd) {
  194. ret = -ENOMEM;
  195. goto disable_pm;
  196. }
  197. hcd->regs = histb->ctrl;
  198. hcd->rsrc_start = res->start;
  199. hcd->rsrc_len = resource_size(res);
  200. histb->hcd = hcd;
  201. dev_set_drvdata(hcd->self.controller, histb);
  202. ret = xhci_histb_host_enable(histb);
  203. if (ret)
  204. goto put_hcd;
  205. xhci = hcd_to_xhci(hcd);
  206. device_wakeup_enable(hcd->self.controller);
  207. xhci->main_hcd = hcd;
  208. xhci->shared_hcd = usb_create_shared_hcd(driver, dev, dev_name(dev),
  209. hcd);
  210. if (!xhci->shared_hcd) {
  211. ret = -ENOMEM;
  212. goto disable_host;
  213. }
  214. if (device_property_read_bool(dev, "usb2-lpm-disable"))
  215. xhci->quirks |= XHCI_HW_LPM_DISABLE;
  216. if (device_property_read_bool(dev, "usb3-lpm-capable"))
  217. xhci->quirks |= XHCI_LPM_SUPPORT;
  218. /* imod_interval is the interrupt moderation value in nanoseconds. */
  219. xhci->imod_interval = 40000;
  220. device_property_read_u32(dev, "imod-interval-ns",
  221. &xhci->imod_interval);
  222. ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
  223. if (ret)
  224. goto put_usb3_hcd;
  225. if (HCC_MAX_PSA(xhci->hcc_params) >= 4)
  226. xhci->shared_hcd->can_do_streams = 1;
  227. ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED);
  228. if (ret)
  229. goto dealloc_usb2_hcd;
  230. device_enable_async_suspend(dev);
  231. pm_runtime_put_noidle(dev);
  232. /*
  233. * Prevent runtime pm from being on as default, users should enable
  234. * runtime pm using power/control in sysfs.
  235. */
  236. pm_runtime_forbid(dev);
  237. return 0;
  238. dealloc_usb2_hcd:
  239. usb_remove_hcd(hcd);
  240. put_usb3_hcd:
  241. usb_put_hcd(xhci->shared_hcd);
  242. disable_host:
  243. xhci_histb_host_disable(histb);
  244. put_hcd:
  245. usb_put_hcd(hcd);
  246. disable_pm:
  247. pm_runtime_put_sync(dev);
  248. pm_runtime_disable(dev);
  249. return ret;
  250. }
  251. static void xhci_histb_remove(struct platform_device *dev)
  252. {
  253. struct xhci_hcd_histb *histb = platform_get_drvdata(dev);
  254. struct usb_hcd *hcd = histb->hcd;
  255. struct xhci_hcd *xhci = hcd_to_xhci(hcd);
  256. struct usb_hcd *shared_hcd = xhci->shared_hcd;
  257. xhci->xhc_state |= XHCI_STATE_REMOVING;
  258. usb_remove_hcd(shared_hcd);
  259. xhci->shared_hcd = NULL;
  260. device_wakeup_disable(&dev->dev);
  261. usb_remove_hcd(hcd);
  262. usb_put_hcd(shared_hcd);
  263. xhci_histb_host_disable(histb);
  264. usb_put_hcd(hcd);
  265. pm_runtime_put_sync(&dev->dev);
  266. pm_runtime_disable(&dev->dev);
  267. }
  268. static int __maybe_unused xhci_histb_suspend(struct device *dev)
  269. {
  270. struct xhci_hcd_histb *histb = dev_get_drvdata(dev);
  271. struct usb_hcd *hcd = histb->hcd;
  272. struct xhci_hcd *xhci = hcd_to_xhci(hcd);
  273. int ret;
  274. ret = xhci_suspend(xhci, device_may_wakeup(dev));
  275. if (!device_may_wakeup(dev))
  276. xhci_histb_host_disable(histb);
  277. return ret;
  278. }
  279. static int __maybe_unused xhci_histb_resume(struct device *dev)
  280. {
  281. struct xhci_hcd_histb *histb = dev_get_drvdata(dev);
  282. struct usb_hcd *hcd = histb->hcd;
  283. struct xhci_hcd *xhci = hcd_to_xhci(hcd);
  284. if (!device_may_wakeup(dev))
  285. xhci_histb_host_enable(histb);
  286. return xhci_resume(xhci, PMSG_RESUME);
  287. }
  288. static const struct dev_pm_ops xhci_histb_pm_ops = {
  289. SET_SYSTEM_SLEEP_PM_OPS(xhci_histb_suspend, xhci_histb_resume)
  290. };
  291. #define DEV_PM_OPS (IS_ENABLED(CONFIG_PM) ? &xhci_histb_pm_ops : NULL)
  292. #ifdef CONFIG_OF
  293. static const struct of_device_id histb_xhci_of_match[] = {
  294. { .compatible = "hisilicon,hi3798cv200-xhci"},
  295. { },
  296. };
  297. MODULE_DEVICE_TABLE(of, histb_xhci_of_match);
  298. #endif
  299. static struct platform_driver histb_xhci_driver = {
  300. .probe = xhci_histb_probe,
  301. .remove_new = xhci_histb_remove,
  302. .driver = {
  303. .name = "xhci-histb",
  304. .pm = DEV_PM_OPS,
  305. .of_match_table = of_match_ptr(histb_xhci_of_match),
  306. },
  307. };
  308. MODULE_ALIAS("platform:xhci-histb");
  309. static int __init xhci_histb_init(void)
  310. {
  311. xhci_init_driver(&xhci_histb_hc_driver, &xhci_histb_overrides);
  312. return platform_driver_register(&histb_xhci_driver);
  313. }
  314. module_init(xhci_histb_init);
  315. static void __exit xhci_histb_exit(void)
  316. {
  317. platform_driver_unregister(&histb_xhci_driver);
  318. }
  319. module_exit(xhci_histb_exit);
  320. MODULE_DESCRIPTION("HiSilicon STB xHCI Host Controller Driver");
  321. MODULE_LICENSE("GPL v2");