dwc3-thead.c 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393
  1. // SPDX-License-Identifier: GPL-2.0
  2. /* Copyright (c) 2018, The Linux Foundation. All rights reserved.
  3. *
  4. * Inspired by dwc3-of-simple.c
  5. */
  6. #include <linux/acpi.h>
  7. #include <linux/io.h>
  8. #include <linux/of.h>
  9. #include <linux/clk.h>
  10. #include <linux/irq.h>
  11. #include <linux/of_clk.h>
  12. #include <linux/module.h>
  13. #include <linux/kernel.h>
  14. #include <linux/extcon.h>
  15. #include <linux/of_platform.h>
  16. #include <linux/gpio/consumer.h>
  17. #include <linux/regulator/consumer.h>
  18. #include <linux/mfd/syscon.h>
  19. #include <linux/regmap.h>
  20. #include <linux/platform_device.h>
  21. #include <linux/phy/phy.h>
  22. #include <linux/usb/of.h>
  23. #include "core.h"
  24. /* USB3_DRD registers */
  25. #define USB_CLK_GATE_STS 0x0
  26. #define USB_LOGIC_ANALYZER_TRACE_STS0 0x4
  27. #define USB_LOGIC_ANALYZER_TRACE_STS1 0x8
  28. #define USB_GPIO 0xc
  29. #define USB_DEBUG_STS0 0x10
  30. #define USB_DEBUG_STS1 0x14
  31. #define USB_DEBUG_STS2 0x18
  32. #define USBCTL_CLK_CTRL0 0x1c
  33. #define USBPHY_CLK_CTRL1 0x20
  34. #define USBPHY_TEST_CTRL0 0x24
  35. #define USBPHY_TEST_CTRL1 0x28
  36. #define USBPHY_TEST_CTRL2 0x2c
  37. #define USBPHY_TEST_CTRL3 0x30
  38. #define USB_SSP_EN 0x34
  39. #define USB_HADDR_SEL 0x38
  40. #define USB_SYS 0x3c
  41. #define USB_HOST_STATUS 0x40
  42. #define USB_HOST_CTRL 0x44
  43. #define USBPHY_HOST_CTRL 0x48
  44. #define USBPHY_HOST_STATUS 0x4c
  45. #define USB_TEST_REG0 0x50
  46. #define USB_TEST_REG1 0x54
  47. #define USB_TEST_REG2 0x58
  48. #define USB_TEST_REG3 0x5c
  49. /* Bit fields */
  50. /* USB_SYS */
  51. #define TEST_POWERDOWN_SSP BIT(2)
  52. #define TEST_POWERDOWN_HSP BIT(1)
  53. #define COMMONONN BIT(0)
  54. /* USB_SSP_EN */
  55. #define REF_SSP_EN BIT(0)
  56. /* USBPHY_HOST_CTRL */
  57. #define HOST_U2_PORT_DISABLE BIT(6)
  58. #define HOST_U3_PORT_DISABLE BIT(5)
  59. /* MISC_SYSREG registers */
  60. #define USB3_DRD_SWRST 0x14
  61. /* Bit fields */
  62. /* USB3_DRD_SWRST */
  63. #define USB3_DRD_VCCRST BIT(2)
  64. #define USB3_DRD_PHYRST BIT(1)
  65. #define USB3_DRD_PRST BIT(0)
  66. #define USB3_DRD_MASK GENMASK(2, 0)
  67. struct dwc3_thead {
  68. struct device *dev;
  69. struct platform_device *dwc3;
  70. struct regmap *usb0_apb;
  71. struct regmap *misc_sysreg;
  72. struct extcon_dev *edev;
  73. struct extcon_dev *host_edev;
  74. struct notifier_block vbus_nb;
  75. struct notifier_block host_nb;
  76. struct gpio_desc *hubswitch;
  77. struct regulator *hub1v2;
  78. struct regulator *hub5v;
  79. struct regulator *vbus;
  80. enum usb_dr_mode mode;
  81. bool is_suspended;
  82. bool pm_suspended;
  83. };
  84. static int dwc3_thead_vbus_notifier(struct notifier_block *nb,
  85. unsigned long event, void *ptr)
  86. {
  87. struct dwc3_thead *thead = container_of(nb, struct dwc3_thead, vbus_nb);
  88. /* enable vbus override for device mode */
  89. thead->mode = event ? USB_DR_MODE_PERIPHERAL : USB_DR_MODE_HOST;
  90. return NOTIFY_DONE;
  91. }
  92. static int dwc3_thead_host_notifier(struct notifier_block *nb,
  93. unsigned long event, void *ptr)
  94. {
  95. struct dwc3_thead *thead = container_of(nb, struct dwc3_thead, host_nb);
  96. /* disable vbus override in host mode */
  97. thead->mode = event ? USB_DR_MODE_HOST : USB_DR_MODE_PERIPHERAL;
  98. return NOTIFY_DONE;
  99. }
  100. static int dwc3_thead_register_extcon(struct dwc3_thead *thead)
  101. {
  102. struct device *dev = thead->dev;
  103. struct extcon_dev *host_edev;
  104. int ret;
  105. if (!of_property_read_bool(dev->of_node, "extcon"))
  106. return 0;
  107. thead->edev = extcon_get_edev_by_phandle(dev, 0);
  108. if (IS_ERR(thead->edev))
  109. return PTR_ERR(thead->edev);
  110. thead->vbus_nb.notifier_call = dwc3_thead_vbus_notifier;
  111. thead->host_edev = extcon_get_edev_by_phandle(dev, 1);
  112. if (IS_ERR(thead->host_edev))
  113. thead->host_edev = NULL;
  114. ret = devm_extcon_register_notifier(dev, thead->edev, EXTCON_USB,
  115. &thead->vbus_nb);
  116. if (ret < 0) {
  117. dev_err(dev, "VBUS notifier register failed\n");
  118. return ret;
  119. }
  120. if (thead->host_edev)
  121. host_edev = thead->host_edev;
  122. else
  123. host_edev = thead->edev;
  124. thead->host_nb.notifier_call = dwc3_thead_host_notifier;
  125. ret = devm_extcon_register_notifier(dev, host_edev, EXTCON_USB_HOST,
  126. &thead->host_nb);
  127. if (ret < 0) {
  128. dev_err(dev, "Host notifier register failed\n");
  129. return ret;
  130. }
  131. /* Update initial VBUS override based on extcon state */
  132. if (extcon_get_state(thead->edev, EXTCON_USB) ||
  133. !extcon_get_state(host_edev, EXTCON_USB_HOST))
  134. dwc3_thead_vbus_notifier(&thead->vbus_nb, true, thead->edev);
  135. else
  136. dwc3_thead_vbus_notifier(&thead->vbus_nb, false, thead->edev);
  137. return 0;
  138. }
  139. static int dwc3_thead_suspend(struct dwc3_thead *thead)
  140. {
  141. return 0;
  142. }
  143. static int dwc3_thead_resume(struct dwc3_thead *thead)
  144. {
  145. return 0;
  146. }
  147. static int dwc3_thead_of_register_core(struct platform_device *pdev)
  148. {
  149. struct dwc3_thead *thead = platform_get_drvdata(pdev);
  150. struct device_node *np = pdev->dev.of_node, *dwc3_np;
  151. struct device *dev = &pdev->dev;
  152. int ret;
  153. dwc3_np = of_get_child_by_name(np, "dwc3");
  154. if (!dwc3_np) {
  155. dev_err(dev, "failed to find dwc3 core child\n");
  156. return -ENODEV;
  157. }
  158. ret = of_platform_populate(np, NULL, NULL, dev);
  159. if (ret) {
  160. dev_err(dev, "failed to register dwc3 core - %d\n", ret);
  161. goto node_put;
  162. }
  163. thead->dwc3 = of_find_device_by_node(dwc3_np);
  164. if (!thead->dwc3) {
  165. ret = -ENODEV;
  166. dev_err(dev, "failed to get dwc3 platform device\n");
  167. }
  168. node_put:
  169. of_node_put(dwc3_np);
  170. return ret;
  171. }
  172. static void dwc3_thead_savepower_u3phy(struct dwc3_thead *thead)
  173. {
  174. struct device *dev = thead->dev;
  175. int reg;
  176. /* config usb top within USB ctrl & PHY reset */
  177. regmap_update_bits(thead->misc_sysreg, USB3_DRD_SWRST,
  178. USB3_DRD_MASK, USB3_DRD_PRST);
  179. /*
  180. * dwc reg also need to be configed to save power
  181. * 1 set USB_SYS[COMMONONN] while GCTL[SOFITPSYNC]=1
  182. * notice GCTL[SOFITPSYNC] should be mutex with GFLADJ[LPM_SEL].
  183. * 2 enable GUSB3PIPECLT[SUSPENDEN]
  184. */
  185. regmap_update_bits(thead->usb0_apb, USB_SYS,
  186. COMMONONN, COMMONONN);
  187. regmap_update_bits(thead->usb0_apb, USB_SSP_EN,
  188. REF_SSP_EN, REF_SSP_EN);
  189. regmap_write(thead->usb0_apb, USB_HOST_CTRL, 0x1101);
  190. regmap_update_bits(thead->misc_sysreg, USB3_DRD_SWRST,
  191. USB3_DRD_MASK, USB3_DRD_MASK);
  192. regmap_read(thead->usb0_apb, USB_SYS, &reg);
  193. dev_dbg(dev, "usb_sys:0x%x\n", reg);
  194. regmap_read(thead->usb0_apb, USB_HOST_CTRL, &reg);
  195. dev_dbg(dev, "host_ctrl:0x%x\n", reg);
  196. regmap_read(thead->misc_sysreg, USB3_DRD_SWRST, &reg);
  197. dev_dbg(dev, "drd_swrst:0x%x\n", reg);
  198. }
  199. static int dwc3_thead_probe(struct platform_device *pdev)
  200. {
  201. struct device *dev = &pdev->dev;
  202. struct device_node *np = dev->of_node;
  203. struct dwc3_thead *thead;
  204. int ret;
  205. thead = devm_kzalloc(&pdev->dev, sizeof(*thead), GFP_KERNEL);
  206. if (!thead)
  207. return -ENOMEM;
  208. platform_set_drvdata(pdev, thead);
  209. thead->dev = &pdev->dev;
  210. thead->hubswitch = devm_gpiod_get(dev, "hubswitch", GPIOD_OUT_HIGH);
  211. if (IS_ERR(thead->hubswitch))
  212. dev_dbg(dev, "no need to get hubswitch GPIO\n");
  213. thead->vbus = devm_regulator_get(dev, "vbus");
  214. if (IS_ERR(thead->vbus))
  215. dev_dbg(dev, "no need to get vbus\n");
  216. else
  217. regulator_enable(thead->vbus);
  218. thead->hub1v2 = devm_regulator_get(dev, "hub1v2");
  219. if (IS_ERR(thead->hub1v2))
  220. dev_dbg(dev, "no need to set hub1v2\n");
  221. else
  222. regulator_enable(thead->hub1v2);
  223. thead->hub5v = devm_regulator_get(dev, "hub5v");
  224. if (IS_ERR(thead->hub5v))
  225. dev_dbg(dev, "no need to set hub5v\n");
  226. else
  227. regulator_enable(thead->hub5v);
  228. thead->misc_sysreg = syscon_regmap_lookup_by_phandle(np, "usb3-misc-regmap");
  229. if (IS_ERR(thead->misc_sysreg))
  230. return PTR_ERR(thead->misc_sysreg);
  231. thead->usb0_apb = syscon_regmap_lookup_by_phandle(np, "usb3-drd-regmap");
  232. if (IS_ERR(thead->usb0_apb))
  233. return PTR_ERR(thead->usb0_apb);
  234. dwc3_thead_savepower_u3phy(thead);
  235. ret = dwc3_thead_of_register_core(pdev);
  236. if (ret) {
  237. dev_err(dev, "failed to register DWC3 Core, err=%d\n", ret);
  238. goto depopulate;
  239. }
  240. /* fixme: need to verify because hw can't support detect event */
  241. ret = dwc3_thead_register_extcon(thead);
  242. if (ret)
  243. goto err;
  244. device_init_wakeup(&pdev->dev, 1);
  245. thead->is_suspended = false;
  246. pm_runtime_set_active(dev);
  247. pm_runtime_enable(dev);
  248. pm_runtime_forbid(dev);
  249. dev_info(dev, "light dwc3 probe ok!\n");
  250. return 0;
  251. depopulate:
  252. of_platform_depopulate(&pdev->dev);
  253. err:
  254. return ret;
  255. }
  256. static int dwc3_thead_remove(struct platform_device *pdev)
  257. {
  258. struct device *dev = &pdev->dev;
  259. pm_runtime_allow(dev);
  260. pm_runtime_disable(dev);
  261. return 0;
  262. }
  263. static int __maybe_unused dwc3_thead_pm_suspend(struct device *dev)
  264. {
  265. struct dwc3_thead *thead = dev_get_drvdata(dev);
  266. int ret = 0;
  267. ret = dwc3_thead_suspend(thead);
  268. if (!ret)
  269. thead->pm_suspended = true;
  270. return ret;
  271. }
  272. static int __maybe_unused dwc3_thead_pm_resume(struct device *dev)
  273. {
  274. struct dwc3_thead *thead = dev_get_drvdata(dev);
  275. int ret;
  276. ret = dwc3_thead_resume(thead);
  277. if (!ret)
  278. thead->pm_suspended = false;
  279. return ret;
  280. }
  281. static int __maybe_unused dwc3_thead_runtime_suspend(struct device *dev)
  282. {
  283. struct dwc3_thead *thead = dev_get_drvdata(dev);
  284. return dwc3_thead_suspend(thead);
  285. }
  286. static int __maybe_unused dwc3_thead_runtime_resume(struct device *dev)
  287. {
  288. struct dwc3_thead *thead = dev_get_drvdata(dev);
  289. return dwc3_thead_resume(thead);
  290. }
  291. static const struct dev_pm_ops dwc3_thead_dev_pm_ops = {
  292. SET_SYSTEM_SLEEP_PM_OPS(dwc3_thead_pm_suspend, dwc3_thead_pm_resume)
  293. SET_RUNTIME_PM_OPS(dwc3_thead_runtime_suspend, dwc3_thead_runtime_resume,
  294. NULL)
  295. };
  296. static const struct of_device_id dwc3_thead_of_match[] = {
  297. { .compatible = "thead,dwc3" },
  298. { },
  299. };
  300. MODULE_DEVICE_TABLE(of, dwc3_thead_of_match);
  301. static struct platform_driver dwc3_thead_driver = {
  302. .probe = dwc3_thead_probe,
  303. .remove = dwc3_thead_remove,
  304. .driver = {
  305. .name = "dwc3-thead",
  306. /*
  307. * fixme: need to verify because hw can't support plug event
  308. */
  309. // .pm = &dwc3_thead_dev_pm_ops,
  310. .of_match_table = dwc3_thead_of_match,
  311. },
  312. };
  313. module_platform_driver(dwc3_thead_driver);
  314. MODULE_LICENSE("GPL v2");
  315. MODULE_DESCRIPTION("DesignWare DWC3 Thead Glue Driver");