linux/drivers/usb/host/xhci-histb.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * xHCI host controller driver for HiSilicon STB SoCs
   4 *
   5 * Copyright (C) 2017-2018 HiSilicon Co., Ltd. http://www.hisilicon.com
   6 *
   7 * Authors: Jianguo Sun <sunjianguo1@huawei.com>
   8 */
   9
  10#include <linux/clk.h>
  11#include <linux/dma-mapping.h>
  12#include <linux/kernel.h>
  13#include <linux/module.h>
  14#include <linux/of.h>
  15#include <linux/platform_device.h>
  16#include <linux/pm_runtime.h>
  17#include <linux/reset.h>
  18
  19#include "xhci.h"
  20
  21#define GTXTHRCFG               0xc108
  22#define GRXTHRCFG               0xc10c
  23#define REG_GUSB2PHYCFG0        0xc200
  24#define BIT_UTMI_8_16           BIT(3)
  25#define BIT_UTMI_ULPI           BIT(4)
  26#define BIT_FREECLK_EXIST       BIT(30)
  27
  28#define REG_GUSB3PIPECTL0       0xc2c0
  29#define USB3_DEEMPHASIS_MASK    GENMASK(2, 1)
  30#define USB3_DEEMPHASIS0        BIT(1)
  31#define USB3_TX_MARGIN1         BIT(4)
  32
  33struct xhci_hcd_histb {
  34        struct device           *dev;
  35        struct usb_hcd          *hcd;
  36        void __iomem            *ctrl;
  37        struct clk              *bus_clk;
  38        struct clk              *utmi_clk;
  39        struct clk              *pipe_clk;
  40        struct clk              *suspend_clk;
  41        struct reset_control    *soft_reset;
  42};
  43
  44static inline struct xhci_hcd_histb *hcd_to_histb(struct usb_hcd *hcd)
  45{
  46        return dev_get_drvdata(hcd->self.controller);
  47}
  48
  49static int xhci_histb_config(struct xhci_hcd_histb *histb)
  50{
  51        struct device_node *np = histb->dev->of_node;
  52        u32 regval;
  53
  54        if (of_property_match_string(np, "phys-names", "inno") >= 0) {
  55                /* USB2 PHY chose ulpi 8bit interface */
  56                regval = readl(histb->ctrl + REG_GUSB2PHYCFG0);
  57                regval &= ~BIT_UTMI_ULPI;
  58                regval &= ~(BIT_UTMI_8_16);
  59                regval &= ~BIT_FREECLK_EXIST;
  60                writel(regval, histb->ctrl + REG_GUSB2PHYCFG0);
  61        }
  62
  63        if (of_property_match_string(np, "phys-names", "combo") >= 0) {
  64                /*
  65                 * write 0x010c0012 to GUSB3PIPECTL0
  66                 * GUSB3PIPECTL0[5:3] = 010 : Tx Margin = 900mV ,
  67                 * decrease TX voltage
  68                 * GUSB3PIPECTL0[2:1] = 01 : Tx Deemphasis = -3.5dB,
  69                 * refer to xHCI spec
  70                 */
  71                regval = readl(histb->ctrl + REG_GUSB3PIPECTL0);
  72                regval &= ~USB3_DEEMPHASIS_MASK;
  73                regval |= USB3_DEEMPHASIS0;
  74                regval |= USB3_TX_MARGIN1;
  75                writel(regval, histb->ctrl + REG_GUSB3PIPECTL0);
  76        }
  77
  78        writel(0x23100000, histb->ctrl + GTXTHRCFG);
  79        writel(0x23100000, histb->ctrl + GRXTHRCFG);
  80
  81        return 0;
  82}
  83
  84static int xhci_histb_clks_get(struct xhci_hcd_histb *histb)
  85{
  86        struct device *dev = histb->dev;
  87
  88        histb->bus_clk = devm_clk_get(dev, "bus");
  89        if (IS_ERR(histb->bus_clk)) {
  90                dev_err(dev, "fail to get bus clk\n");
  91                return PTR_ERR(histb->bus_clk);
  92        }
  93
  94        histb->utmi_clk = devm_clk_get(dev, "utmi");
  95        if (IS_ERR(histb->utmi_clk)) {
  96                dev_err(dev, "fail to get utmi clk\n");
  97                return PTR_ERR(histb->utmi_clk);
  98        }
  99
 100        histb->pipe_clk = devm_clk_get(dev, "pipe");
 101        if (IS_ERR(histb->pipe_clk)) {
 102                dev_err(dev, "fail to get pipe clk\n");
 103                return PTR_ERR(histb->pipe_clk);
 104        }
 105
 106        histb->suspend_clk = devm_clk_get(dev, "suspend");
 107        if (IS_ERR(histb->suspend_clk)) {
 108                dev_err(dev, "fail to get suspend clk\n");
 109                return PTR_ERR(histb->suspend_clk);
 110        }
 111
 112        return 0;
 113}
 114
 115static int xhci_histb_host_enable(struct xhci_hcd_histb *histb)
 116{
 117        int ret;
 118
 119        ret = clk_prepare_enable(histb->bus_clk);
 120        if (ret) {
 121                dev_err(histb->dev, "failed to enable bus clk\n");
 122                return ret;
 123        }
 124
 125        ret = clk_prepare_enable(histb->utmi_clk);
 126        if (ret) {
 127                dev_err(histb->dev, "failed to enable utmi clk\n");
 128                goto err_utmi_clk;
 129        }
 130
 131        ret = clk_prepare_enable(histb->pipe_clk);
 132        if (ret) {
 133                dev_err(histb->dev, "failed to enable pipe clk\n");
 134                goto err_pipe_clk;
 135        }
 136
 137        ret = clk_prepare_enable(histb->suspend_clk);
 138        if (ret) {
 139                dev_err(histb->dev, "failed to enable suspend clk\n");
 140                goto err_suspend_clk;
 141        }
 142
 143        reset_control_deassert(histb->soft_reset);
 144
 145        return 0;
 146
 147err_suspend_clk:
 148        clk_disable_unprepare(histb->pipe_clk);
 149err_pipe_clk:
 150        clk_disable_unprepare(histb->utmi_clk);
 151err_utmi_clk:
 152        clk_disable_unprepare(histb->bus_clk);
 153
 154        return ret;
 155}
 156
 157static void xhci_histb_host_disable(struct xhci_hcd_histb *histb)
 158{
 159        reset_control_assert(histb->soft_reset);
 160
 161        clk_disable_unprepare(histb->suspend_clk);
 162        clk_disable_unprepare(histb->pipe_clk);
 163        clk_disable_unprepare(histb->utmi_clk);
 164        clk_disable_unprepare(histb->bus_clk);
 165}
 166
 167static void xhci_histb_quirks(struct device *dev, struct xhci_hcd *xhci)
 168{
 169        /*
 170         * As of now platform drivers don't provide MSI support so we ensure
 171         * here that the generic code does not try to make a pci_dev from our
 172         * dev struct in order to setup MSI
 173         */
 174        xhci->quirks |= XHCI_PLAT;
 175}
 176
 177/* called during probe() after chip reset completes */
 178static int xhci_histb_setup(struct usb_hcd *hcd)
 179{
 180        struct xhci_hcd_histb *histb = hcd_to_histb(hcd);
 181        int ret;
 182
 183        if (usb_hcd_is_primary_hcd(hcd)) {
 184                ret = xhci_histb_config(histb);
 185                if (ret)
 186                        return ret;
 187        }
 188
 189        return xhci_gen_setup(hcd, xhci_histb_quirks);
 190}
 191
 192static const struct xhci_driver_overrides xhci_histb_overrides __initconst = {
 193        .reset = xhci_histb_setup,
 194};
 195
 196static struct hc_driver __read_mostly xhci_histb_hc_driver;
 197static int xhci_histb_probe(struct platform_device *pdev)
 198{
 199        struct device *dev = &pdev->dev;
 200        struct xhci_hcd_histb *histb;
 201        const struct hc_driver *driver;
 202        struct usb_hcd *hcd;
 203        struct xhci_hcd *xhci;
 204        struct resource *res;
 205        int irq;
 206        int ret = -ENODEV;
 207
 208        if (usb_disabled())
 209                return -ENODEV;
 210
 211        driver = &xhci_histb_hc_driver;
 212        histb = devm_kzalloc(dev, sizeof(*histb), GFP_KERNEL);
 213        if (!histb)
 214                return -ENOMEM;
 215
 216        histb->dev = dev;
 217
 218        irq = platform_get_irq(pdev, 0);
 219        if (irq < 0)
 220                return irq;
 221
 222        histb->ctrl = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
 223        if (IS_ERR(histb->ctrl))
 224                return PTR_ERR(histb->ctrl);
 225
 226        ret = xhci_histb_clks_get(histb);
 227        if (ret)
 228                return ret;
 229
 230        histb->soft_reset = devm_reset_control_get(dev, "soft");
 231        if (IS_ERR(histb->soft_reset)) {
 232                dev_err(dev, "failed to get soft reset\n");
 233                return PTR_ERR(histb->soft_reset);
 234        }
 235
 236        pm_runtime_enable(dev);
 237        pm_runtime_get_sync(dev);
 238        device_enable_async_suspend(dev);
 239
 240        /* Initialize dma_mask and coherent_dma_mask to 32-bits */
 241        ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
 242        if (ret)
 243                goto disable_pm;
 244
 245        hcd = usb_create_hcd(driver, dev, dev_name(dev));
 246        if (!hcd) {
 247                ret = -ENOMEM;
 248                goto disable_pm;
 249        }
 250
 251        hcd->regs = histb->ctrl;
 252        hcd->rsrc_start = res->start;
 253        hcd->rsrc_len = resource_size(res);
 254
 255        histb->hcd = hcd;
 256        dev_set_drvdata(hcd->self.controller, histb);
 257
 258        ret = xhci_histb_host_enable(histb);
 259        if (ret)
 260                goto put_hcd;
 261
 262        xhci = hcd_to_xhci(hcd);
 263
 264        device_wakeup_enable(hcd->self.controller);
 265
 266        xhci->main_hcd = hcd;
 267        xhci->shared_hcd = usb_create_shared_hcd(driver, dev, dev_name(dev),
 268                                                 hcd);
 269        if (!xhci->shared_hcd) {
 270                ret = -ENOMEM;
 271                goto disable_host;
 272        }
 273
 274        if (device_property_read_bool(dev, "usb2-lpm-disable"))
 275                xhci->quirks |= XHCI_HW_LPM_DISABLE;
 276
 277        if (device_property_read_bool(dev, "usb3-lpm-capable"))
 278                xhci->quirks |= XHCI_LPM_SUPPORT;
 279
 280        /* imod_interval is the interrupt moderation value in nanoseconds. */
 281        xhci->imod_interval = 40000;
 282        device_property_read_u32(dev, "imod-interval-ns",
 283                                 &xhci->imod_interval);
 284
 285        ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
 286        if (ret)
 287                goto put_usb3_hcd;
 288
 289        if (HCC_MAX_PSA(xhci->hcc_params) >= 4)
 290                xhci->shared_hcd->can_do_streams = 1;
 291
 292        ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED);
 293        if (ret)
 294                goto dealloc_usb2_hcd;
 295
 296        device_enable_async_suspend(dev);
 297        pm_runtime_put_noidle(dev);
 298
 299        /*
 300         * Prevent runtime pm from being on as default, users should enable
 301         * runtime pm using power/control in sysfs.
 302         */
 303        pm_runtime_forbid(dev);
 304
 305        return 0;
 306
 307dealloc_usb2_hcd:
 308        usb_remove_hcd(hcd);
 309put_usb3_hcd:
 310        usb_put_hcd(xhci->shared_hcd);
 311disable_host:
 312        xhci_histb_host_disable(histb);
 313put_hcd:
 314        usb_put_hcd(hcd);
 315disable_pm:
 316        pm_runtime_put_sync(dev);
 317        pm_runtime_disable(dev);
 318
 319        return ret;
 320}
 321
 322static int xhci_histb_remove(struct platform_device *dev)
 323{
 324        struct xhci_hcd_histb *histb = platform_get_drvdata(dev);
 325        struct usb_hcd *hcd = histb->hcd;
 326        struct xhci_hcd *xhci = hcd_to_xhci(hcd);
 327        struct usb_hcd *shared_hcd = xhci->shared_hcd;
 328
 329        xhci->xhc_state |= XHCI_STATE_REMOVING;
 330
 331        usb_remove_hcd(shared_hcd);
 332        xhci->shared_hcd = NULL;
 333        device_wakeup_disable(&dev->dev);
 334
 335        usb_remove_hcd(hcd);
 336        usb_put_hcd(shared_hcd);
 337
 338        xhci_histb_host_disable(histb);
 339        usb_put_hcd(hcd);
 340        pm_runtime_put_sync(&dev->dev);
 341        pm_runtime_disable(&dev->dev);
 342
 343        return 0;
 344}
 345
 346static int __maybe_unused xhci_histb_suspend(struct device *dev)
 347{
 348        struct xhci_hcd_histb *histb = dev_get_drvdata(dev);
 349        struct usb_hcd *hcd = histb->hcd;
 350        struct xhci_hcd *xhci = hcd_to_xhci(hcd);
 351        int ret;
 352
 353        ret = xhci_suspend(xhci, device_may_wakeup(dev));
 354
 355        if (!device_may_wakeup(dev))
 356                xhci_histb_host_disable(histb);
 357
 358        return ret;
 359}
 360
 361static int __maybe_unused xhci_histb_resume(struct device *dev)
 362{
 363        struct xhci_hcd_histb *histb = dev_get_drvdata(dev);
 364        struct usb_hcd *hcd = histb->hcd;
 365        struct xhci_hcd *xhci = hcd_to_xhci(hcd);
 366
 367        if (!device_may_wakeup(dev))
 368                xhci_histb_host_enable(histb);
 369
 370        return xhci_resume(xhci, 0);
 371}
 372
 373static const struct dev_pm_ops xhci_histb_pm_ops = {
 374        SET_SYSTEM_SLEEP_PM_OPS(xhci_histb_suspend, xhci_histb_resume)
 375};
 376#define DEV_PM_OPS (IS_ENABLED(CONFIG_PM) ? &xhci_histb_pm_ops : NULL)
 377
 378#ifdef CONFIG_OF
 379static const struct of_device_id histb_xhci_of_match[] = {
 380        { .compatible = "hisilicon,hi3798cv200-xhci"},
 381        { },
 382};
 383MODULE_DEVICE_TABLE(of, histb_xhci_of_match);
 384#endif
 385
 386static struct platform_driver histb_xhci_driver = {
 387        .probe  = xhci_histb_probe,
 388        .remove = xhci_histb_remove,
 389        .driver = {
 390                .name = "xhci-histb",
 391                .pm = DEV_PM_OPS,
 392                .of_match_table = of_match_ptr(histb_xhci_of_match),
 393        },
 394};
 395MODULE_ALIAS("platform:xhci-histb");
 396
 397static int __init xhci_histb_init(void)
 398{
 399        xhci_init_driver(&xhci_histb_hc_driver, &xhci_histb_overrides);
 400        return platform_driver_register(&histb_xhci_driver);
 401}
 402module_init(xhci_histb_init);
 403
 404static void __exit xhci_histb_exit(void)
 405{
 406        platform_driver_unregister(&histb_xhci_driver);
 407}
 408module_exit(xhci_histb_exit);
 409
 410MODULE_DESCRIPTION("HiSilicon STB xHCI Host Controller Driver");
 411MODULE_LICENSE("GPL v2");
 412