Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * cdns3-imx.c - NXP i.MX specific Glue layer for Cadence USB Controller
0004  *
0005  * Copyright (C) 2019 NXP
0006  */
0007 
0008 #include <linux/bits.h>
0009 #include <linux/clk.h>
0010 #include <linux/module.h>
0011 #include <linux/kernel.h>
0012 #include <linux/interrupt.h>
0013 #include <linux/platform_device.h>
0014 #include <linux/dma-mapping.h>
0015 #include <linux/io.h>
0016 #include <linux/of_platform.h>
0017 #include <linux/iopoll.h>
0018 #include <linux/pm_runtime.h>
0019 #include "core.h"
0020 
0021 #define USB3_CORE_CTRL1    0x00
0022 #define USB3_CORE_CTRL2    0x04
0023 #define USB3_INT_REG       0x08
0024 #define USB3_CORE_STATUS   0x0c
0025 #define XHCI_DEBUG_LINK_ST 0x10
0026 #define XHCI_DEBUG_BUS     0x14
0027 #define USB3_SSPHY_CTRL1   0x40
0028 #define USB3_SSPHY_CTRL2   0x44
0029 #define USB3_SSPHY_STATUS  0x4c
0030 #define USB2_PHY_CTRL1     0x50
0031 #define USB2_PHY_CTRL2     0x54
0032 #define USB2_PHY_STATUS    0x5c
0033 
0034 /* Register bits definition */
0035 
0036 /* USB3_CORE_CTRL1 */
0037 #define SW_RESET_MASK   GENMASK(31, 26)
0038 #define PWR_SW_RESET    BIT(31)
0039 #define APB_SW_RESET    BIT(30)
0040 #define AXI_SW_RESET    BIT(29)
0041 #define RW_SW_RESET BIT(28)
0042 #define PHY_SW_RESET    BIT(27)
0043 #define PHYAHB_SW_RESET BIT(26)
0044 #define ALL_SW_RESET    (PWR_SW_RESET | APB_SW_RESET | AXI_SW_RESET | \
0045         RW_SW_RESET | PHY_SW_RESET | PHYAHB_SW_RESET)
0046 #define OC_DISABLE  BIT(9)
0047 #define MDCTRL_CLK_SEL  BIT(7)
0048 #define MODE_STRAP_MASK (0x7)
0049 #define DEV_MODE    (1 << 2)
0050 #define HOST_MODE   (1 << 1)
0051 #define OTG_MODE    (1 << 0)
0052 
0053 /* USB3_INT_REG */
0054 #define CLK_125_REQ BIT(29)
0055 #define LPM_CLK_REQ BIT(28)
0056 #define DEVU3_WAEKUP_EN BIT(14)
0057 #define OTG_WAKEUP_EN   BIT(12)
0058 #define DEV_INT_EN  (3 << 8) /* DEV INT b9:8 */
0059 #define HOST_INT1_EN    (1 << 0) /* HOST INT b7:0 */
0060 
0061 /* USB3_CORE_STATUS */
0062 #define MDCTRL_CLK_STATUS   BIT(15)
0063 #define DEV_POWER_ON_READY  BIT(13)
0064 #define HOST_POWER_ON_READY BIT(12)
0065 
0066 /* USB3_SSPHY_STATUS */
0067 #define CLK_VALID_MASK      (0x3f << 26)
0068 #define CLK_VALID_COMPARE_BITS  (0xf << 28)
0069 #define PHY_REFCLK_REQ      (1 << 0)
0070 
0071 /* OTG registers definition */
0072 #define OTGSTS      0x4
0073 /* OTGSTS */
0074 #define OTG_NRDY    BIT(11)
0075 
0076 /* xHCI registers definition  */
0077 #define XECP_PM_PMCSR       0x8018
0078 #define XECP_AUX_CTRL_REG1  0x8120
0079 
0080 /* Register bits definition */
0081 /* XECP_AUX_CTRL_REG1 */
0082 #define CFG_RXDET_P3_EN     BIT(15)
0083 
0084 /* XECP_PM_PMCSR */
0085 #define PS_MASK         GENMASK(1, 0)
0086 #define PS_D0           0
0087 #define PS_D1           1
0088 
0089 struct cdns_imx {
0090     struct device *dev;
0091     void __iomem *noncore;
0092     struct clk_bulk_data *clks;
0093     int num_clks;
0094     struct platform_device *cdns3_pdev;
0095 };
0096 
0097 static inline u32 cdns_imx_readl(struct cdns_imx *data, u32 offset)
0098 {
0099     return readl(data->noncore + offset);
0100 }
0101 
0102 static inline void cdns_imx_writel(struct cdns_imx *data, u32 offset, u32 value)
0103 {
0104     writel(value, data->noncore + offset);
0105 }
0106 
0107 static const struct clk_bulk_data imx_cdns3_core_clks[] = {
0108     { .id = "usb3_lpm_clk" },
0109     { .id = "usb3_bus_clk" },
0110     { .id = "usb3_aclk" },
0111     { .id = "usb3_ipg_clk" },
0112     { .id = "usb3_core_pclk" },
0113 };
0114 
0115 static int cdns_imx_noncore_init(struct cdns_imx *data)
0116 {
0117     u32 value;
0118     int ret;
0119     struct device *dev = data->dev;
0120 
0121     cdns_imx_writel(data, USB3_SSPHY_STATUS, CLK_VALID_MASK);
0122     udelay(1);
0123     ret = readl_poll_timeout(data->noncore + USB3_SSPHY_STATUS, value,
0124         (value & CLK_VALID_COMPARE_BITS) == CLK_VALID_COMPARE_BITS,
0125         10, 100000);
0126     if (ret) {
0127         dev_err(dev, "wait clkvld timeout\n");
0128         return ret;
0129     }
0130 
0131     value = cdns_imx_readl(data, USB3_CORE_CTRL1);
0132     value |= ALL_SW_RESET;
0133     cdns_imx_writel(data, USB3_CORE_CTRL1, value);
0134     udelay(1);
0135 
0136     value = cdns_imx_readl(data, USB3_CORE_CTRL1);
0137     value = (value & ~MODE_STRAP_MASK) | OTG_MODE | OC_DISABLE;
0138     cdns_imx_writel(data, USB3_CORE_CTRL1, value);
0139 
0140     value = cdns_imx_readl(data, USB3_INT_REG);
0141     value |= HOST_INT1_EN | DEV_INT_EN;
0142     cdns_imx_writel(data, USB3_INT_REG, value);
0143 
0144     value = cdns_imx_readl(data, USB3_CORE_CTRL1);
0145     value &= ~ALL_SW_RESET;
0146     cdns_imx_writel(data, USB3_CORE_CTRL1, value);
0147     return ret;
0148 }
0149 
0150 static int cdns_imx_platform_suspend(struct device *dev,
0151     bool suspend, bool wakeup);
0152 static struct cdns3_platform_data cdns_imx_pdata = {
0153     .platform_suspend = cdns_imx_platform_suspend,
0154     .quirks       = CDNS3_DEFAULT_PM_RUNTIME_ALLOW,
0155 };
0156 
0157 static const struct of_dev_auxdata cdns_imx_auxdata[] = {
0158     {
0159         .compatible = "cdns,usb3",
0160         .platform_data = &cdns_imx_pdata,
0161     },
0162     {},
0163 };
0164 
0165 static int cdns_imx_probe(struct platform_device *pdev)
0166 {
0167     struct device *dev = &pdev->dev;
0168     struct device_node *node = dev->of_node;
0169     struct cdns_imx *data;
0170     int ret;
0171 
0172     if (!node)
0173         return -ENODEV;
0174 
0175     data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
0176     if (!data)
0177         return -ENOMEM;
0178 
0179     platform_set_drvdata(pdev, data);
0180     data->dev = dev;
0181     data->noncore = devm_platform_ioremap_resource(pdev, 0);
0182     if (IS_ERR(data->noncore)) {
0183         dev_err(dev, "can't map IOMEM resource\n");
0184         return PTR_ERR(data->noncore);
0185     }
0186 
0187     data->num_clks = ARRAY_SIZE(imx_cdns3_core_clks);
0188     data->clks = devm_kmemdup(dev, imx_cdns3_core_clks,
0189                 sizeof(imx_cdns3_core_clks), GFP_KERNEL);
0190     if (!data->clks)
0191         return -ENOMEM;
0192 
0193     ret = devm_clk_bulk_get(dev, data->num_clks, data->clks);
0194     if (ret)
0195         return ret;
0196 
0197     ret = clk_bulk_prepare_enable(data->num_clks, data->clks);
0198     if (ret)
0199         return ret;
0200 
0201     ret = cdns_imx_noncore_init(data);
0202     if (ret)
0203         goto err;
0204 
0205     ret = of_platform_populate(node, NULL, cdns_imx_auxdata, dev);
0206     if (ret) {
0207         dev_err(dev, "failed to create children: %d\n", ret);
0208         goto err;
0209     }
0210 
0211     device_set_wakeup_capable(dev, true);
0212     pm_runtime_set_active(dev);
0213     pm_runtime_enable(dev);
0214 
0215     return ret;
0216 err:
0217     clk_bulk_disable_unprepare(data->num_clks, data->clks);
0218     return ret;
0219 }
0220 
0221 static int cdns_imx_remove(struct platform_device *pdev)
0222 {
0223     struct device *dev = &pdev->dev;
0224     struct cdns_imx *data = dev_get_drvdata(dev);
0225 
0226     pm_runtime_get_sync(dev);
0227     of_platform_depopulate(dev);
0228     clk_bulk_disable_unprepare(data->num_clks, data->clks);
0229     pm_runtime_disable(dev);
0230     pm_runtime_put_noidle(dev);
0231     platform_set_drvdata(pdev, NULL);
0232 
0233     return 0;
0234 }
0235 
0236 #ifdef CONFIG_PM
0237 static void cdns3_set_wakeup(struct cdns_imx *data, bool enable)
0238 {
0239     u32 value;
0240 
0241     value = cdns_imx_readl(data, USB3_INT_REG);
0242     if (enable)
0243         value |= OTG_WAKEUP_EN | DEVU3_WAEKUP_EN;
0244     else
0245         value &= ~(OTG_WAKEUP_EN | DEVU3_WAEKUP_EN);
0246 
0247     cdns_imx_writel(data, USB3_INT_REG, value);
0248 }
0249 
0250 static int cdns_imx_platform_suspend(struct device *dev,
0251         bool suspend, bool wakeup)
0252 {
0253     struct cdns *cdns = dev_get_drvdata(dev);
0254     struct device *parent = dev->parent;
0255     struct cdns_imx *data = dev_get_drvdata(parent);
0256     void __iomem *otg_regs = (void __iomem *)(cdns->otg_regs);
0257     void __iomem *xhci_regs = cdns->xhci_regs;
0258     u32 value;
0259     int ret = 0;
0260 
0261     if (cdns->role != USB_ROLE_HOST)
0262         return 0;
0263 
0264     if (suspend) {
0265         /* SW request low power when all usb ports allow to it ??? */
0266         value = readl(xhci_regs + XECP_PM_PMCSR);
0267         value &= ~PS_MASK;
0268         value |= PS_D1;
0269         writel(value, xhci_regs + XECP_PM_PMCSR);
0270 
0271         /* mdctrl_clk_sel */
0272         value = cdns_imx_readl(data, USB3_CORE_CTRL1);
0273         value |= MDCTRL_CLK_SEL;
0274         cdns_imx_writel(data, USB3_CORE_CTRL1, value);
0275 
0276         /* wait for mdctrl_clk_status */
0277         value = cdns_imx_readl(data, USB3_CORE_STATUS);
0278         ret = readl_poll_timeout(data->noncore + USB3_CORE_STATUS, value,
0279             (value & MDCTRL_CLK_STATUS) == MDCTRL_CLK_STATUS,
0280             10, 100000);
0281         if (ret)
0282             dev_warn(parent, "wait mdctrl_clk_status timeout\n");
0283 
0284         /* wait lpm_clk_req to be 0 */
0285         value = cdns_imx_readl(data, USB3_INT_REG);
0286         ret = readl_poll_timeout(data->noncore + USB3_INT_REG, value,
0287             (value & LPM_CLK_REQ) != LPM_CLK_REQ,
0288             10, 100000);
0289         if (ret)
0290             dev_warn(parent, "wait lpm_clk_req timeout\n");
0291 
0292         /* wait phy_refclk_req to be 0 */
0293         value = cdns_imx_readl(data, USB3_SSPHY_STATUS);
0294         ret = readl_poll_timeout(data->noncore + USB3_SSPHY_STATUS, value,
0295             (value & PHY_REFCLK_REQ) != PHY_REFCLK_REQ,
0296             10, 100000);
0297         if (ret)
0298             dev_warn(parent, "wait phy_refclk_req timeout\n");
0299 
0300         cdns3_set_wakeup(data, wakeup);
0301     } else {
0302         cdns3_set_wakeup(data, false);
0303 
0304         /* SW request D0 */
0305         value = readl(xhci_regs + XECP_PM_PMCSR);
0306         value &= ~PS_MASK;
0307         value |= PS_D0;
0308         writel(value, xhci_regs + XECP_PM_PMCSR);
0309 
0310         /* clr CFG_RXDET_P3_EN */
0311         value = readl(xhci_regs + XECP_AUX_CTRL_REG1);
0312         value &= ~CFG_RXDET_P3_EN;
0313         writel(value, xhci_regs + XECP_AUX_CTRL_REG1);
0314 
0315         /* clear mdctrl_clk_sel */
0316         value = cdns_imx_readl(data, USB3_CORE_CTRL1);
0317         value &= ~MDCTRL_CLK_SEL;
0318         cdns_imx_writel(data, USB3_CORE_CTRL1, value);
0319 
0320         /* wait CLK_125_REQ to be 1 */
0321         value = cdns_imx_readl(data, USB3_INT_REG);
0322         ret = readl_poll_timeout(data->noncore + USB3_INT_REG, value,
0323             (value & CLK_125_REQ) == CLK_125_REQ,
0324             10, 100000);
0325         if (ret)
0326             dev_warn(parent, "wait CLK_125_REQ timeout\n");
0327 
0328         /* wait for mdctrl_clk_status is cleared */
0329         value = cdns_imx_readl(data, USB3_CORE_STATUS);
0330         ret = readl_poll_timeout(data->noncore + USB3_CORE_STATUS, value,
0331             (value & MDCTRL_CLK_STATUS) != MDCTRL_CLK_STATUS,
0332             10, 100000);
0333         if (ret)
0334             dev_warn(parent, "wait mdctrl_clk_status cleared timeout\n");
0335 
0336         /* Wait until OTG_NRDY is 0 */
0337         value = readl(otg_regs + OTGSTS);
0338         ret = readl_poll_timeout(otg_regs + OTGSTS, value,
0339             (value & OTG_NRDY) != OTG_NRDY,
0340             10, 100000);
0341         if (ret)
0342             dev_warn(parent, "wait OTG ready timeout\n");
0343     }
0344 
0345     return ret;
0346 
0347 }
0348 
0349 static int cdns_imx_resume(struct device *dev)
0350 {
0351     struct cdns_imx *data = dev_get_drvdata(dev);
0352 
0353     return clk_bulk_prepare_enable(data->num_clks, data->clks);
0354 }
0355 
0356 static int cdns_imx_suspend(struct device *dev)
0357 {
0358     struct cdns_imx *data = dev_get_drvdata(dev);
0359 
0360     clk_bulk_disable_unprepare(data->num_clks, data->clks);
0361 
0362     return 0;
0363 }
0364 
0365 
0366 /* Indicate if the controller was power lost before */
0367 static inline bool cdns_imx_is_power_lost(struct cdns_imx *data)
0368 {
0369     u32 value;
0370 
0371     value = cdns_imx_readl(data, USB3_CORE_CTRL1);
0372     if ((value & SW_RESET_MASK) == ALL_SW_RESET)
0373         return true;
0374     else
0375         return false;
0376 }
0377 
0378 static int __maybe_unused cdns_imx_system_resume(struct device *dev)
0379 {
0380     struct cdns_imx *data = dev_get_drvdata(dev);
0381     int ret;
0382 
0383     ret = cdns_imx_resume(dev);
0384     if (ret)
0385         return ret;
0386 
0387     if (cdns_imx_is_power_lost(data)) {
0388         dev_dbg(dev, "resume from power lost\n");
0389         ret = cdns_imx_noncore_init(data);
0390         if (ret)
0391             cdns_imx_suspend(dev);
0392     }
0393 
0394     return ret;
0395 }
0396 
0397 #else
0398 static int cdns_imx_platform_suspend(struct device *dev,
0399     bool suspend, bool wakeup)
0400 {
0401     return 0;
0402 }
0403 
0404 #endif /* CONFIG_PM */
0405 
0406 static const struct dev_pm_ops cdns_imx_pm_ops = {
0407     SET_RUNTIME_PM_OPS(cdns_imx_suspend, cdns_imx_resume, NULL)
0408     SET_SYSTEM_SLEEP_PM_OPS(cdns_imx_suspend, cdns_imx_system_resume)
0409 };
0410 
0411 static const struct of_device_id cdns_imx_of_match[] = {
0412     { .compatible = "fsl,imx8qm-usb3", },
0413     {},
0414 };
0415 MODULE_DEVICE_TABLE(of, cdns_imx_of_match);
0416 
0417 static struct platform_driver cdns_imx_driver = {
0418     .probe      = cdns_imx_probe,
0419     .remove     = cdns_imx_remove,
0420     .driver     = {
0421         .name   = "cdns3-imx",
0422         .of_match_table = cdns_imx_of_match,
0423         .pm = &cdns_imx_pm_ops,
0424     },
0425 };
0426 module_platform_driver(cdns_imx_driver);
0427 
0428 MODULE_ALIAS("platform:cdns3-imx");
0429 MODULE_AUTHOR("Peter Chen <peter.chen@nxp.com>");
0430 MODULE_LICENSE("GPL v2");
0431 MODULE_DESCRIPTION("Cadence USB3 i.MX Glue Layer");