Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * xHCI host controller driver for HiSilicon STB SoCs
0004  *
0005  * Copyright (C) 2017-2018 HiSilicon Co., Ltd. http://www.hisilicon.com
0006  *
0007  * Authors: Jianguo Sun <sunjianguo1@huawei.com>
0008  */
0009 
0010 #include <linux/clk.h>
0011 #include <linux/dma-mapping.h>
0012 #include <linux/kernel.h>
0013 #include <linux/module.h>
0014 #include <linux/of.h>
0015 #include <linux/platform_device.h>
0016 #include <linux/pm_runtime.h>
0017 #include <linux/reset.h>
0018 
0019 #include "xhci.h"
0020 
0021 #define GTXTHRCFG       0xc108
0022 #define GRXTHRCFG       0xc10c
0023 #define REG_GUSB2PHYCFG0    0xc200
0024 #define BIT_UTMI_8_16       BIT(3)
0025 #define BIT_UTMI_ULPI       BIT(4)
0026 #define BIT_FREECLK_EXIST   BIT(30)
0027 
0028 #define REG_GUSB3PIPECTL0   0xc2c0
0029 #define USB3_DEEMPHASIS_MASK    GENMASK(2, 1)
0030 #define USB3_DEEMPHASIS0    BIT(1)
0031 #define USB3_TX_MARGIN1     BIT(4)
0032 
0033 struct xhci_hcd_histb {
0034     struct device       *dev;
0035     struct usb_hcd      *hcd;
0036     void __iomem        *ctrl;
0037     struct clk      *bus_clk;
0038     struct clk      *utmi_clk;
0039     struct clk      *pipe_clk;
0040     struct clk      *suspend_clk;
0041     struct reset_control    *soft_reset;
0042 };
0043 
0044 static inline struct xhci_hcd_histb *hcd_to_histb(struct usb_hcd *hcd)
0045 {
0046     return dev_get_drvdata(hcd->self.controller);
0047 }
0048 
0049 static int xhci_histb_config(struct xhci_hcd_histb *histb)
0050 {
0051     struct device_node *np = histb->dev->of_node;
0052     u32 regval;
0053 
0054     if (of_property_match_string(np, "phys-names", "inno") >= 0) {
0055         /* USB2 PHY chose ulpi 8bit interface */
0056         regval = readl(histb->ctrl + REG_GUSB2PHYCFG0);
0057         regval &= ~BIT_UTMI_ULPI;
0058         regval &= ~(BIT_UTMI_8_16);
0059         regval &= ~BIT_FREECLK_EXIST;
0060         writel(regval, histb->ctrl + REG_GUSB2PHYCFG0);
0061     }
0062 
0063     if (of_property_match_string(np, "phys-names", "combo") >= 0) {
0064         /*
0065          * write 0x010c0012 to GUSB3PIPECTL0
0066          * GUSB3PIPECTL0[5:3] = 010 : Tx Margin = 900mV ,
0067          * decrease TX voltage
0068          * GUSB3PIPECTL0[2:1] = 01 : Tx Deemphasis = -3.5dB,
0069          * refer to xHCI spec
0070          */
0071         regval = readl(histb->ctrl + REG_GUSB3PIPECTL0);
0072         regval &= ~USB3_DEEMPHASIS_MASK;
0073         regval |= USB3_DEEMPHASIS0;
0074         regval |= USB3_TX_MARGIN1;
0075         writel(regval, histb->ctrl + REG_GUSB3PIPECTL0);
0076     }
0077 
0078     writel(0x23100000, histb->ctrl + GTXTHRCFG);
0079     writel(0x23100000, histb->ctrl + GRXTHRCFG);
0080 
0081     return 0;
0082 }
0083 
0084 static int xhci_histb_clks_get(struct xhci_hcd_histb *histb)
0085 {
0086     struct device *dev = histb->dev;
0087 
0088     histb->bus_clk = devm_clk_get(dev, "bus");
0089     if (IS_ERR(histb->bus_clk)) {
0090         dev_err(dev, "fail to get bus clk\n");
0091         return PTR_ERR(histb->bus_clk);
0092     }
0093 
0094     histb->utmi_clk = devm_clk_get(dev, "utmi");
0095     if (IS_ERR(histb->utmi_clk)) {
0096         dev_err(dev, "fail to get utmi clk\n");
0097         return PTR_ERR(histb->utmi_clk);
0098     }
0099 
0100     histb->pipe_clk = devm_clk_get(dev, "pipe");
0101     if (IS_ERR(histb->pipe_clk)) {
0102         dev_err(dev, "fail to get pipe clk\n");
0103         return PTR_ERR(histb->pipe_clk);
0104     }
0105 
0106     histb->suspend_clk = devm_clk_get(dev, "suspend");
0107     if (IS_ERR(histb->suspend_clk)) {
0108         dev_err(dev, "fail to get suspend clk\n");
0109         return PTR_ERR(histb->suspend_clk);
0110     }
0111 
0112     return 0;
0113 }
0114 
0115 static int xhci_histb_host_enable(struct xhci_hcd_histb *histb)
0116 {
0117     int ret;
0118 
0119     ret = clk_prepare_enable(histb->bus_clk);
0120     if (ret) {
0121         dev_err(histb->dev, "failed to enable bus clk\n");
0122         return ret;
0123     }
0124 
0125     ret = clk_prepare_enable(histb->utmi_clk);
0126     if (ret) {
0127         dev_err(histb->dev, "failed to enable utmi clk\n");
0128         goto err_utmi_clk;
0129     }
0130 
0131     ret = clk_prepare_enable(histb->pipe_clk);
0132     if (ret) {
0133         dev_err(histb->dev, "failed to enable pipe clk\n");
0134         goto err_pipe_clk;
0135     }
0136 
0137     ret = clk_prepare_enable(histb->suspend_clk);
0138     if (ret) {
0139         dev_err(histb->dev, "failed to enable suspend clk\n");
0140         goto err_suspend_clk;
0141     }
0142 
0143     reset_control_deassert(histb->soft_reset);
0144 
0145     return 0;
0146 
0147 err_suspend_clk:
0148     clk_disable_unprepare(histb->pipe_clk);
0149 err_pipe_clk:
0150     clk_disable_unprepare(histb->utmi_clk);
0151 err_utmi_clk:
0152     clk_disable_unprepare(histb->bus_clk);
0153 
0154     return ret;
0155 }
0156 
0157 static void xhci_histb_host_disable(struct xhci_hcd_histb *histb)
0158 {
0159     reset_control_assert(histb->soft_reset);
0160 
0161     clk_disable_unprepare(histb->suspend_clk);
0162     clk_disable_unprepare(histb->pipe_clk);
0163     clk_disable_unprepare(histb->utmi_clk);
0164     clk_disable_unprepare(histb->bus_clk);
0165 }
0166 
0167 static void xhci_histb_quirks(struct device *dev, struct xhci_hcd *xhci)
0168 {
0169     /*
0170      * As of now platform drivers don't provide MSI support so we ensure
0171      * here that the generic code does not try to make a pci_dev from our
0172      * dev struct in order to setup MSI
0173      */
0174     xhci->quirks |= XHCI_PLAT;
0175 }
0176 
0177 /* called during probe() after chip reset completes */
0178 static int xhci_histb_setup(struct usb_hcd *hcd)
0179 {
0180     struct xhci_hcd_histb *histb = hcd_to_histb(hcd);
0181     int ret;
0182 
0183     if (usb_hcd_is_primary_hcd(hcd)) {
0184         ret = xhci_histb_config(histb);
0185         if (ret)
0186             return ret;
0187     }
0188 
0189     return xhci_gen_setup(hcd, xhci_histb_quirks);
0190 }
0191 
0192 static const struct xhci_driver_overrides xhci_histb_overrides __initconst = {
0193     .reset = xhci_histb_setup,
0194 };
0195 
0196 static struct hc_driver __read_mostly xhci_histb_hc_driver;
0197 static int xhci_histb_probe(struct platform_device *pdev)
0198 {
0199     struct device *dev = &pdev->dev;
0200     struct xhci_hcd_histb *histb;
0201     const struct hc_driver *driver;
0202     struct usb_hcd *hcd;
0203     struct xhci_hcd *xhci;
0204     struct resource *res;
0205     int irq;
0206     int ret = -ENODEV;
0207 
0208     if (usb_disabled())
0209         return -ENODEV;
0210 
0211     driver = &xhci_histb_hc_driver;
0212     histb = devm_kzalloc(dev, sizeof(*histb), GFP_KERNEL);
0213     if (!histb)
0214         return -ENOMEM;
0215 
0216     histb->dev = dev;
0217 
0218     irq = platform_get_irq(pdev, 0);
0219     if (irq < 0)
0220         return irq;
0221 
0222     histb->ctrl = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
0223     if (IS_ERR(histb->ctrl))
0224         return PTR_ERR(histb->ctrl);
0225 
0226     ret = xhci_histb_clks_get(histb);
0227     if (ret)
0228         return ret;
0229 
0230     histb->soft_reset = devm_reset_control_get(dev, "soft");
0231     if (IS_ERR(histb->soft_reset)) {
0232         dev_err(dev, "failed to get soft reset\n");
0233         return PTR_ERR(histb->soft_reset);
0234     }
0235 
0236     pm_runtime_enable(dev);
0237     pm_runtime_get_sync(dev);
0238     device_enable_async_suspend(dev);
0239 
0240     /* Initialize dma_mask and coherent_dma_mask to 32-bits */
0241     ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
0242     if (ret)
0243         goto disable_pm;
0244 
0245     hcd = usb_create_hcd(driver, dev, dev_name(dev));
0246     if (!hcd) {
0247         ret = -ENOMEM;
0248         goto disable_pm;
0249     }
0250 
0251     hcd->regs = histb->ctrl;
0252     hcd->rsrc_start = res->start;
0253     hcd->rsrc_len = resource_size(res);
0254 
0255     histb->hcd = hcd;
0256     dev_set_drvdata(hcd->self.controller, histb);
0257 
0258     ret = xhci_histb_host_enable(histb);
0259     if (ret)
0260         goto put_hcd;
0261 
0262     xhci = hcd_to_xhci(hcd);
0263 
0264     device_wakeup_enable(hcd->self.controller);
0265 
0266     xhci->main_hcd = hcd;
0267     xhci->shared_hcd = usb_create_shared_hcd(driver, dev, dev_name(dev),
0268                          hcd);
0269     if (!xhci->shared_hcd) {
0270         ret = -ENOMEM;
0271         goto disable_host;
0272     }
0273 
0274     if (device_property_read_bool(dev, "usb2-lpm-disable"))
0275         xhci->quirks |= XHCI_HW_LPM_DISABLE;
0276 
0277     if (device_property_read_bool(dev, "usb3-lpm-capable"))
0278         xhci->quirks |= XHCI_LPM_SUPPORT;
0279 
0280     /* imod_interval is the interrupt moderation value in nanoseconds. */
0281     xhci->imod_interval = 40000;
0282     device_property_read_u32(dev, "imod-interval-ns",
0283                  &xhci->imod_interval);
0284 
0285     ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
0286     if (ret)
0287         goto put_usb3_hcd;
0288 
0289     if (HCC_MAX_PSA(xhci->hcc_params) >= 4)
0290         xhci->shared_hcd->can_do_streams = 1;
0291 
0292     ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED);
0293     if (ret)
0294         goto dealloc_usb2_hcd;
0295 
0296     device_enable_async_suspend(dev);
0297     pm_runtime_put_noidle(dev);
0298 
0299     /*
0300      * Prevent runtime pm from being on as default, users should enable
0301      * runtime pm using power/control in sysfs.
0302      */
0303     pm_runtime_forbid(dev);
0304 
0305     return 0;
0306 
0307 dealloc_usb2_hcd:
0308     usb_remove_hcd(hcd);
0309 put_usb3_hcd:
0310     usb_put_hcd(xhci->shared_hcd);
0311 disable_host:
0312     xhci_histb_host_disable(histb);
0313 put_hcd:
0314     usb_put_hcd(hcd);
0315 disable_pm:
0316     pm_runtime_put_sync(dev);
0317     pm_runtime_disable(dev);
0318 
0319     return ret;
0320 }
0321 
0322 static int xhci_histb_remove(struct platform_device *dev)
0323 {
0324     struct xhci_hcd_histb *histb = platform_get_drvdata(dev);
0325     struct usb_hcd *hcd = histb->hcd;
0326     struct xhci_hcd *xhci = hcd_to_xhci(hcd);
0327     struct usb_hcd *shared_hcd = xhci->shared_hcd;
0328 
0329     xhci->xhc_state |= XHCI_STATE_REMOVING;
0330 
0331     usb_remove_hcd(shared_hcd);
0332     xhci->shared_hcd = NULL;
0333     device_wakeup_disable(&dev->dev);
0334 
0335     usb_remove_hcd(hcd);
0336     usb_put_hcd(shared_hcd);
0337 
0338     xhci_histb_host_disable(histb);
0339     usb_put_hcd(hcd);
0340     pm_runtime_put_sync(&dev->dev);
0341     pm_runtime_disable(&dev->dev);
0342 
0343     return 0;
0344 }
0345 
0346 static int __maybe_unused xhci_histb_suspend(struct device *dev)
0347 {
0348     struct xhci_hcd_histb *histb = dev_get_drvdata(dev);
0349     struct usb_hcd *hcd = histb->hcd;
0350     struct xhci_hcd *xhci = hcd_to_xhci(hcd);
0351     int ret;
0352 
0353     ret = xhci_suspend(xhci, device_may_wakeup(dev));
0354 
0355     if (!device_may_wakeup(dev))
0356         xhci_histb_host_disable(histb);
0357 
0358     return ret;
0359 }
0360 
0361 static int __maybe_unused xhci_histb_resume(struct device *dev)
0362 {
0363     struct xhci_hcd_histb *histb = dev_get_drvdata(dev);
0364     struct usb_hcd *hcd = histb->hcd;
0365     struct xhci_hcd *xhci = hcd_to_xhci(hcd);
0366 
0367     if (!device_may_wakeup(dev))
0368         xhci_histb_host_enable(histb);
0369 
0370     return xhci_resume(xhci, 0);
0371 }
0372 
0373 static const struct dev_pm_ops xhci_histb_pm_ops = {
0374     SET_SYSTEM_SLEEP_PM_OPS(xhci_histb_suspend, xhci_histb_resume)
0375 };
0376 #define DEV_PM_OPS (IS_ENABLED(CONFIG_PM) ? &xhci_histb_pm_ops : NULL)
0377 
0378 #ifdef CONFIG_OF
0379 static const struct of_device_id histb_xhci_of_match[] = {
0380     { .compatible = "hisilicon,hi3798cv200-xhci"},
0381     { },
0382 };
0383 MODULE_DEVICE_TABLE(of, histb_xhci_of_match);
0384 #endif
0385 
0386 static struct platform_driver histb_xhci_driver = {
0387     .probe  = xhci_histb_probe,
0388     .remove = xhci_histb_remove,
0389     .driver = {
0390         .name = "xhci-histb",
0391         .pm = DEV_PM_OPS,
0392         .of_match_table = of_match_ptr(histb_xhci_of_match),
0393     },
0394 };
0395 MODULE_ALIAS("platform:xhci-histb");
0396 
0397 static int __init xhci_histb_init(void)
0398 {
0399     xhci_init_driver(&xhci_histb_hc_driver, &xhci_histb_overrides);
0400     return platform_driver_register(&histb_xhci_driver);
0401 }
0402 module_init(xhci_histb_init);
0403 
0404 static void __exit xhci_histb_exit(void)
0405 {
0406     platform_driver_unregister(&histb_xhci_driver);
0407 }
0408 module_exit(xhci_histb_exit);
0409 
0410 MODULE_DESCRIPTION("HiSilicon STB xHCI Host Controller Driver");
0411 MODULE_LICENSE("GPL v2");