cdns3-imx.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * cdns3-imx.c - NXP i.MX specific Glue layer for Cadence USB Controller
  4. *
  5. * Copyright (C) 2019 NXP
  6. */
  7. #include <linux/bits.h>
  8. #include <linux/clk.h>
  9. #include <linux/module.h>
  10. #include <linux/kernel.h>
  11. #include <linux/interrupt.h>
  12. #include <linux/platform_device.h>
  13. #include <linux/dma-mapping.h>
  14. #include <linux/io.h>
  15. #include <linux/of_platform.h>
  16. #include <linux/iopoll.h>
  17. #include <linux/pm_runtime.h>
  18. #include "core.h"
  19. #define USB3_CORE_CTRL1 0x00
  20. #define USB3_CORE_CTRL2 0x04
  21. #define USB3_INT_REG 0x08
  22. #define USB3_CORE_STATUS 0x0c
  23. #define XHCI_DEBUG_LINK_ST 0x10
  24. #define XHCI_DEBUG_BUS 0x14
  25. #define USB3_SSPHY_CTRL1 0x40
  26. #define USB3_SSPHY_CTRL2 0x44
  27. #define USB3_SSPHY_STATUS 0x4c
  28. #define USB2_PHY_CTRL1 0x50
  29. #define USB2_PHY_CTRL2 0x54
  30. #define USB2_PHY_STATUS 0x5c
  31. /* Register bits definition */
  32. /* USB3_CORE_CTRL1 */
  33. #define SW_RESET_MASK GENMASK(31, 26)
  34. #define PWR_SW_RESET BIT(31)
  35. #define APB_SW_RESET BIT(30)
  36. #define AXI_SW_RESET BIT(29)
  37. #define RW_SW_RESET BIT(28)
  38. #define PHY_SW_RESET BIT(27)
  39. #define PHYAHB_SW_RESET BIT(26)
  40. #define ALL_SW_RESET (PWR_SW_RESET | APB_SW_RESET | AXI_SW_RESET | \
  41. RW_SW_RESET | PHY_SW_RESET | PHYAHB_SW_RESET)
  42. #define OC_DISABLE BIT(9)
  43. #define MDCTRL_CLK_SEL BIT(7)
  44. #define MODE_STRAP_MASK (0x7)
  45. #define DEV_MODE (1 << 2)
  46. #define HOST_MODE (1 << 1)
  47. #define OTG_MODE (1 << 0)
  48. /* USB3_INT_REG */
  49. #define CLK_125_REQ BIT(29)
  50. #define LPM_CLK_REQ BIT(28)
  51. #define DEVU3_WAEKUP_EN BIT(14)
  52. #define OTG_WAKEUP_EN BIT(12)
  53. #define DEV_INT_EN (3 << 8) /* DEV INT b9:8 */
  54. #define HOST_INT1_EN (1 << 0) /* HOST INT b7:0 */
  55. /* USB3_CORE_STATUS */
  56. #define MDCTRL_CLK_STATUS BIT(15)
  57. #define DEV_POWER_ON_READY BIT(13)
  58. #define HOST_POWER_ON_READY BIT(12)
  59. /* USB3_SSPHY_STATUS */
  60. #define CLK_VALID_MASK (0x3f << 26)
  61. #define CLK_VALID_COMPARE_BITS (0xf << 28)
  62. #define PHY_REFCLK_REQ (1 << 0)
  63. /* OTG registers definition */
  64. #define OTGSTS 0x4
  65. /* OTGSTS */
  66. #define OTG_NRDY BIT(11)
  67. /* xHCI registers definition */
  68. #define XECP_PM_PMCSR 0x8018
  69. #define XECP_AUX_CTRL_REG1 0x8120
  70. /* Register bits definition */
  71. /* XECP_AUX_CTRL_REG1 */
  72. #define CFG_RXDET_P3_EN BIT(15)
  73. /* XECP_PM_PMCSR */
  74. #define PS_MASK GENMASK(1, 0)
  75. #define PS_D0 0
  76. #define PS_D1 1
  77. struct cdns_imx {
  78. struct device *dev;
  79. void __iomem *noncore;
  80. struct clk_bulk_data *clks;
  81. int num_clks;
  82. struct platform_device *cdns3_pdev;
  83. };
  84. static inline u32 cdns_imx_readl(struct cdns_imx *data, u32 offset)
  85. {
  86. return readl(data->noncore + offset);
  87. }
  88. static inline void cdns_imx_writel(struct cdns_imx *data, u32 offset, u32 value)
  89. {
  90. writel(value, data->noncore + offset);
  91. }
  92. static const struct clk_bulk_data imx_cdns3_core_clks[] = {
  93. { .id = "usb3_lpm_clk" },
  94. { .id = "usb3_bus_clk" },
  95. { .id = "usb3_aclk" },
  96. { .id = "usb3_ipg_clk" },
  97. { .id = "usb3_core_pclk" },
  98. };
  99. static int cdns_imx_noncore_init(struct cdns_imx *data)
  100. {
  101. u32 value;
  102. int ret;
  103. struct device *dev = data->dev;
  104. cdns_imx_writel(data, USB3_SSPHY_STATUS, CLK_VALID_MASK);
  105. udelay(1);
  106. ret = readl_poll_timeout(data->noncore + USB3_SSPHY_STATUS, value,
  107. (value & CLK_VALID_COMPARE_BITS) == CLK_VALID_COMPARE_BITS,
  108. 10, 100000);
  109. if (ret) {
  110. dev_err(dev, "wait clkvld timeout\n");
  111. return ret;
  112. }
  113. value = cdns_imx_readl(data, USB3_CORE_CTRL1);
  114. value |= ALL_SW_RESET;
  115. cdns_imx_writel(data, USB3_CORE_CTRL1, value);
  116. udelay(1);
  117. value = cdns_imx_readl(data, USB3_CORE_CTRL1);
  118. value = (value & ~MODE_STRAP_MASK) | OTG_MODE | OC_DISABLE;
  119. cdns_imx_writel(data, USB3_CORE_CTRL1, value);
  120. value = cdns_imx_readl(data, USB3_INT_REG);
  121. value |= HOST_INT1_EN | DEV_INT_EN;
  122. cdns_imx_writel(data, USB3_INT_REG, value);
  123. value = cdns_imx_readl(data, USB3_CORE_CTRL1);
  124. value &= ~ALL_SW_RESET;
  125. cdns_imx_writel(data, USB3_CORE_CTRL1, value);
  126. return ret;
  127. }
  128. static int cdns_imx_platform_suspend(struct device *dev,
  129. bool suspend, bool wakeup);
  130. static struct cdns3_platform_data cdns_imx_pdata = {
  131. .platform_suspend = cdns_imx_platform_suspend,
  132. .quirks = CDNS3_DEFAULT_PM_RUNTIME_ALLOW,
  133. };
  134. static const struct of_dev_auxdata cdns_imx_auxdata[] = {
  135. {
  136. .compatible = "cdns,usb3",
  137. .platform_data = &cdns_imx_pdata,
  138. },
  139. {},
  140. };
  141. static int cdns_imx_probe(struct platform_device *pdev)
  142. {
  143. struct device *dev = &pdev->dev;
  144. struct device_node *node = dev->of_node;
  145. struct cdns_imx *data;
  146. int ret;
  147. if (!node)
  148. return -ENODEV;
  149. data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
  150. if (!data)
  151. return -ENOMEM;
  152. platform_set_drvdata(pdev, data);
  153. data->dev = dev;
  154. data->noncore = devm_platform_ioremap_resource(pdev, 0);
  155. if (IS_ERR(data->noncore)) {
  156. dev_err(dev, "can't map IOMEM resource\n");
  157. return PTR_ERR(data->noncore);
  158. }
  159. data->num_clks = ARRAY_SIZE(imx_cdns3_core_clks);
  160. data->clks = devm_kmemdup(dev, imx_cdns3_core_clks,
  161. sizeof(imx_cdns3_core_clks), GFP_KERNEL);
  162. if (!data->clks)
  163. return -ENOMEM;
  164. ret = devm_clk_bulk_get(dev, data->num_clks, data->clks);
  165. if (ret)
  166. return ret;
  167. ret = clk_bulk_prepare_enable(data->num_clks, data->clks);
  168. if (ret)
  169. return ret;
  170. ret = cdns_imx_noncore_init(data);
  171. if (ret)
  172. goto err;
  173. ret = of_platform_populate(node, NULL, cdns_imx_auxdata, dev);
  174. if (ret) {
  175. dev_err(dev, "failed to create children: %d\n", ret);
  176. goto err;
  177. }
  178. device_set_wakeup_capable(dev, true);
  179. pm_runtime_set_active(dev);
  180. pm_runtime_enable(dev);
  181. return ret;
  182. err:
  183. clk_bulk_disable_unprepare(data->num_clks, data->clks);
  184. return ret;
  185. }
  186. static int cdns_imx_remove(struct platform_device *pdev)
  187. {
  188. struct device *dev = &pdev->dev;
  189. struct cdns_imx *data = dev_get_drvdata(dev);
  190. pm_runtime_get_sync(dev);
  191. of_platform_depopulate(dev);
  192. clk_bulk_disable_unprepare(data->num_clks, data->clks);
  193. pm_runtime_disable(dev);
  194. pm_runtime_put_noidle(dev);
  195. platform_set_drvdata(pdev, NULL);
  196. return 0;
  197. }
  198. #ifdef CONFIG_PM
  199. static void cdns3_set_wakeup(struct cdns_imx *data, bool enable)
  200. {
  201. u32 value;
  202. value = cdns_imx_readl(data, USB3_INT_REG);
  203. if (enable)
  204. value |= OTG_WAKEUP_EN | DEVU3_WAEKUP_EN;
  205. else
  206. value &= ~(OTG_WAKEUP_EN | DEVU3_WAEKUP_EN);
  207. cdns_imx_writel(data, USB3_INT_REG, value);
  208. }
  209. static int cdns_imx_platform_suspend(struct device *dev,
  210. bool suspend, bool wakeup)
  211. {
  212. struct cdns *cdns = dev_get_drvdata(dev);
  213. struct device *parent = dev->parent;
  214. struct cdns_imx *data = dev_get_drvdata(parent);
  215. void __iomem *otg_regs = (void __iomem *)(cdns->otg_regs);
  216. void __iomem *xhci_regs = cdns->xhci_regs;
  217. u32 value;
  218. int ret = 0;
  219. if (cdns->role != USB_ROLE_HOST)
  220. return 0;
  221. if (suspend) {
  222. /* SW request low power when all usb ports allow to it ??? */
  223. value = readl(xhci_regs + XECP_PM_PMCSR);
  224. value &= ~PS_MASK;
  225. value |= PS_D1;
  226. writel(value, xhci_regs + XECP_PM_PMCSR);
  227. /* mdctrl_clk_sel */
  228. value = cdns_imx_readl(data, USB3_CORE_CTRL1);
  229. value |= MDCTRL_CLK_SEL;
  230. cdns_imx_writel(data, USB3_CORE_CTRL1, value);
  231. /* wait for mdctrl_clk_status */
  232. value = cdns_imx_readl(data, USB3_CORE_STATUS);
  233. ret = readl_poll_timeout(data->noncore + USB3_CORE_STATUS, value,
  234. (value & MDCTRL_CLK_STATUS) == MDCTRL_CLK_STATUS,
  235. 10, 100000);
  236. if (ret)
  237. dev_warn(parent, "wait mdctrl_clk_status timeout\n");
  238. /* wait lpm_clk_req to be 0 */
  239. value = cdns_imx_readl(data, USB3_INT_REG);
  240. ret = readl_poll_timeout(data->noncore + USB3_INT_REG, value,
  241. (value & LPM_CLK_REQ) != LPM_CLK_REQ,
  242. 10, 100000);
  243. if (ret)
  244. dev_warn(parent, "wait lpm_clk_req timeout\n");
  245. /* wait phy_refclk_req to be 0 */
  246. value = cdns_imx_readl(data, USB3_SSPHY_STATUS);
  247. ret = readl_poll_timeout(data->noncore + USB3_SSPHY_STATUS, value,
  248. (value & PHY_REFCLK_REQ) != PHY_REFCLK_REQ,
  249. 10, 100000);
  250. if (ret)
  251. dev_warn(parent, "wait phy_refclk_req timeout\n");
  252. cdns3_set_wakeup(data, wakeup);
  253. } else {
  254. cdns3_set_wakeup(data, false);
  255. /* SW request D0 */
  256. value = readl(xhci_regs + XECP_PM_PMCSR);
  257. value &= ~PS_MASK;
  258. value |= PS_D0;
  259. writel(value, xhci_regs + XECP_PM_PMCSR);
  260. /* clr CFG_RXDET_P3_EN */
  261. value = readl(xhci_regs + XECP_AUX_CTRL_REG1);
  262. value &= ~CFG_RXDET_P3_EN;
  263. writel(value, xhci_regs + XECP_AUX_CTRL_REG1);
  264. /* clear mdctrl_clk_sel */
  265. value = cdns_imx_readl(data, USB3_CORE_CTRL1);
  266. value &= ~MDCTRL_CLK_SEL;
  267. cdns_imx_writel(data, USB3_CORE_CTRL1, value);
  268. /* wait CLK_125_REQ to be 1 */
  269. value = cdns_imx_readl(data, USB3_INT_REG);
  270. ret = readl_poll_timeout(data->noncore + USB3_INT_REG, value,
  271. (value & CLK_125_REQ) == CLK_125_REQ,
  272. 10, 100000);
  273. if (ret)
  274. dev_warn(parent, "wait CLK_125_REQ timeout\n");
  275. /* wait for mdctrl_clk_status is cleared */
  276. value = cdns_imx_readl(data, USB3_CORE_STATUS);
  277. ret = readl_poll_timeout(data->noncore + USB3_CORE_STATUS, value,
  278. (value & MDCTRL_CLK_STATUS) != MDCTRL_CLK_STATUS,
  279. 10, 100000);
  280. if (ret)
  281. dev_warn(parent, "wait mdctrl_clk_status cleared timeout\n");
  282. /* Wait until OTG_NRDY is 0 */
  283. value = readl(otg_regs + OTGSTS);
  284. ret = readl_poll_timeout(otg_regs + OTGSTS, value,
  285. (value & OTG_NRDY) != OTG_NRDY,
  286. 10, 100000);
  287. if (ret)
  288. dev_warn(parent, "wait OTG ready timeout\n");
  289. }
  290. return ret;
  291. }
  292. static int cdns_imx_resume(struct device *dev)
  293. {
  294. struct cdns_imx *data = dev_get_drvdata(dev);
  295. return clk_bulk_prepare_enable(data->num_clks, data->clks);
  296. }
  297. static int cdns_imx_suspend(struct device *dev)
  298. {
  299. struct cdns_imx *data = dev_get_drvdata(dev);
  300. clk_bulk_disable_unprepare(data->num_clks, data->clks);
  301. return 0;
  302. }
  303. /* Indicate if the controller was power lost before */
  304. static inline bool cdns_imx_is_power_lost(struct cdns_imx *data)
  305. {
  306. u32 value;
  307. value = cdns_imx_readl(data, USB3_CORE_CTRL1);
  308. if ((value & SW_RESET_MASK) == ALL_SW_RESET)
  309. return true;
  310. else
  311. return false;
  312. }
  313. static int __maybe_unused cdns_imx_system_resume(struct device *dev)
  314. {
  315. struct cdns_imx *data = dev_get_drvdata(dev);
  316. int ret;
  317. ret = cdns_imx_resume(dev);
  318. if (ret)
  319. return ret;
  320. if (cdns_imx_is_power_lost(data)) {
  321. dev_dbg(dev, "resume from power lost\n");
  322. ret = cdns_imx_noncore_init(data);
  323. if (ret)
  324. cdns_imx_suspend(dev);
  325. }
  326. return ret;
  327. }
  328. #else
  329. static int cdns_imx_platform_suspend(struct device *dev,
  330. bool suspend, bool wakeup)
  331. {
  332. return 0;
  333. }
  334. #endif /* CONFIG_PM */
  335. static const struct dev_pm_ops cdns_imx_pm_ops = {
  336. SET_RUNTIME_PM_OPS(cdns_imx_suspend, cdns_imx_resume, NULL)
  337. SET_SYSTEM_SLEEP_PM_OPS(cdns_imx_suspend, cdns_imx_system_resume)
  338. };
  339. static const struct of_device_id cdns_imx_of_match[] = {
  340. { .compatible = "fsl,imx8qm-usb3", },
  341. {},
  342. };
  343. MODULE_DEVICE_TABLE(of, cdns_imx_of_match);
  344. static struct platform_driver cdns_imx_driver = {
  345. .probe = cdns_imx_probe,
  346. .remove = cdns_imx_remove,
  347. .driver = {
  348. .name = "cdns3-imx",
  349. .of_match_table = cdns_imx_of_match,
  350. .pm = &cdns_imx_pm_ops,
  351. },
  352. };
  353. module_platform_driver(cdns_imx_driver);
  354. MODULE_ALIAS("platform:cdns3-imx");
  355. MODULE_AUTHOR("Peter Chen <[email protected]>");
  356. MODULE_LICENSE("GPL v2");
  357. MODULE_DESCRIPTION("Cadence USB3 i.MX Glue Layer");