cdns3-imx.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  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 = "lpm" },
  94. { .id = "bus" },
  95. { .id = "aclk" },
  96. { .id = "ipg" },
  97. { .id = "core" },
  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 void 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. }
  197. #ifdef CONFIG_PM
  198. static void cdns3_set_wakeup(struct cdns_imx *data, bool enable)
  199. {
  200. u32 value;
  201. value = cdns_imx_readl(data, USB3_INT_REG);
  202. if (enable)
  203. value |= OTG_WAKEUP_EN | DEVU3_WAEKUP_EN;
  204. else
  205. value &= ~(OTG_WAKEUP_EN | DEVU3_WAEKUP_EN);
  206. cdns_imx_writel(data, USB3_INT_REG, value);
  207. }
  208. static int cdns_imx_platform_suspend(struct device *dev,
  209. bool suspend, bool wakeup)
  210. {
  211. struct cdns *cdns = dev_get_drvdata(dev);
  212. struct device *parent = dev->parent;
  213. struct cdns_imx *data = dev_get_drvdata(parent);
  214. void __iomem *otg_regs = (void __iomem *)(cdns->otg_regs);
  215. void __iomem *xhci_regs = cdns->xhci_regs;
  216. u32 value;
  217. int ret = 0;
  218. if (cdns->role != USB_ROLE_HOST)
  219. return 0;
  220. if (suspend) {
  221. /* SW request low power when all usb ports allow to it ??? */
  222. value = readl(xhci_regs + XECP_PM_PMCSR);
  223. value &= ~PS_MASK;
  224. value |= PS_D1;
  225. writel(value, xhci_regs + XECP_PM_PMCSR);
  226. /* mdctrl_clk_sel */
  227. value = cdns_imx_readl(data, USB3_CORE_CTRL1);
  228. value |= MDCTRL_CLK_SEL;
  229. cdns_imx_writel(data, USB3_CORE_CTRL1, value);
  230. /* wait for mdctrl_clk_status */
  231. value = cdns_imx_readl(data, USB3_CORE_STATUS);
  232. ret = readl_poll_timeout(data->noncore + USB3_CORE_STATUS, value,
  233. (value & MDCTRL_CLK_STATUS) == MDCTRL_CLK_STATUS,
  234. 10, 100000);
  235. if (ret)
  236. dev_warn(parent, "wait mdctrl_clk_status timeout\n");
  237. /* wait lpm_clk_req to be 0 */
  238. value = cdns_imx_readl(data, USB3_INT_REG);
  239. ret = readl_poll_timeout(data->noncore + USB3_INT_REG, value,
  240. (value & LPM_CLK_REQ) != LPM_CLK_REQ,
  241. 10, 100000);
  242. if (ret)
  243. dev_warn(parent, "wait lpm_clk_req timeout\n");
  244. /* wait phy_refclk_req to be 0 */
  245. value = cdns_imx_readl(data, USB3_SSPHY_STATUS);
  246. ret = readl_poll_timeout(data->noncore + USB3_SSPHY_STATUS, value,
  247. (value & PHY_REFCLK_REQ) != PHY_REFCLK_REQ,
  248. 10, 100000);
  249. if (ret)
  250. dev_warn(parent, "wait phy_refclk_req timeout\n");
  251. cdns3_set_wakeup(data, wakeup);
  252. } else {
  253. cdns3_set_wakeup(data, false);
  254. /* SW request D0 */
  255. value = readl(xhci_regs + XECP_PM_PMCSR);
  256. value &= ~PS_MASK;
  257. value |= PS_D0;
  258. writel(value, xhci_regs + XECP_PM_PMCSR);
  259. /* clr CFG_RXDET_P3_EN */
  260. value = readl(xhci_regs + XECP_AUX_CTRL_REG1);
  261. value &= ~CFG_RXDET_P3_EN;
  262. writel(value, xhci_regs + XECP_AUX_CTRL_REG1);
  263. /* clear mdctrl_clk_sel */
  264. value = cdns_imx_readl(data, USB3_CORE_CTRL1);
  265. value &= ~MDCTRL_CLK_SEL;
  266. cdns_imx_writel(data, USB3_CORE_CTRL1, value);
  267. /* wait CLK_125_REQ to be 1 */
  268. value = cdns_imx_readl(data, USB3_INT_REG);
  269. ret = readl_poll_timeout(data->noncore + USB3_INT_REG, value,
  270. (value & CLK_125_REQ) == CLK_125_REQ,
  271. 10, 100000);
  272. if (ret)
  273. dev_warn(parent, "wait CLK_125_REQ timeout\n");
  274. /* wait for mdctrl_clk_status is cleared */
  275. value = cdns_imx_readl(data, USB3_CORE_STATUS);
  276. ret = readl_poll_timeout(data->noncore + USB3_CORE_STATUS, value,
  277. (value & MDCTRL_CLK_STATUS) != MDCTRL_CLK_STATUS,
  278. 10, 100000);
  279. if (ret)
  280. dev_warn(parent, "wait mdctrl_clk_status cleared timeout\n");
  281. /* Wait until OTG_NRDY is 0 */
  282. value = readl(otg_regs + OTGSTS);
  283. ret = readl_poll_timeout(otg_regs + OTGSTS, value,
  284. (value & OTG_NRDY) != OTG_NRDY,
  285. 10, 100000);
  286. if (ret)
  287. dev_warn(parent, "wait OTG ready timeout\n");
  288. }
  289. return ret;
  290. }
  291. static int cdns_imx_resume(struct device *dev)
  292. {
  293. struct cdns_imx *data = dev_get_drvdata(dev);
  294. return clk_bulk_prepare_enable(data->num_clks, data->clks);
  295. }
  296. static int cdns_imx_suspend(struct device *dev)
  297. {
  298. struct cdns_imx *data = dev_get_drvdata(dev);
  299. clk_bulk_disable_unprepare(data->num_clks, data->clks);
  300. return 0;
  301. }
  302. /* Indicate if the controller was power lost before */
  303. static inline bool cdns_imx_is_power_lost(struct cdns_imx *data)
  304. {
  305. u32 value;
  306. value = cdns_imx_readl(data, USB3_CORE_CTRL1);
  307. if ((value & SW_RESET_MASK) == ALL_SW_RESET)
  308. return true;
  309. else
  310. return false;
  311. }
  312. static int __maybe_unused cdns_imx_system_suspend(struct device *dev)
  313. {
  314. pm_runtime_put_sync(dev);
  315. return 0;
  316. }
  317. static int __maybe_unused cdns_imx_system_resume(struct device *dev)
  318. {
  319. struct cdns_imx *data = dev_get_drvdata(dev);
  320. int ret;
  321. ret = pm_runtime_resume_and_get(dev);
  322. if (ret < 0) {
  323. dev_err(dev, "Could not get runtime PM.\n");
  324. return ret;
  325. }
  326. if (cdns_imx_is_power_lost(data)) {
  327. dev_dbg(dev, "resume from power lost\n");
  328. ret = cdns_imx_noncore_init(data);
  329. if (ret)
  330. cdns_imx_suspend(dev);
  331. }
  332. return ret;
  333. }
  334. #else
  335. static int cdns_imx_platform_suspend(struct device *dev,
  336. bool suspend, bool wakeup)
  337. {
  338. return 0;
  339. }
  340. #endif /* CONFIG_PM */
  341. static const struct dev_pm_ops cdns_imx_pm_ops = {
  342. SET_RUNTIME_PM_OPS(cdns_imx_suspend, cdns_imx_resume, NULL)
  343. SET_SYSTEM_SLEEP_PM_OPS(cdns_imx_system_suspend, cdns_imx_system_resume)
  344. };
  345. static const struct of_device_id cdns_imx_of_match[] = {
  346. { .compatible = "fsl,imx8qm-usb3", },
  347. {},
  348. };
  349. MODULE_DEVICE_TABLE(of, cdns_imx_of_match);
  350. static struct platform_driver cdns_imx_driver = {
  351. .probe = cdns_imx_probe,
  352. .remove_new = cdns_imx_remove,
  353. .driver = {
  354. .name = "cdns3-imx",
  355. .of_match_table = cdns_imx_of_match,
  356. .pm = &cdns_imx_pm_ops,
  357. },
  358. };
  359. module_platform_driver(cdns_imx_driver);
  360. MODULE_ALIAS("platform:cdns3-imx");
  361. MODULE_AUTHOR("Peter Chen <peter.chen@nxp.com>");
  362. MODULE_LICENSE("GPL v2");
  363. MODULE_DESCRIPTION("Cadence USB3 i.MX Glue Layer");