linux/drivers/usb/chipidea/host.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * host.c - ChipIdea USB host controller driver
   4 *
   5 * Copyright (c) 2012 Intel Corporation
   6 *
   7 * Author: Alexander Shishkin
   8 */
   9
  10#include <linux/kernel.h>
  11#include <linux/io.h>
  12#include <linux/usb.h>
  13#include <linux/usb/hcd.h>
  14#include <linux/usb/chipidea.h>
  15#include <linux/regulator/consumer.h>
  16#include <linux/pinctrl/consumer.h>
  17
  18#include "../host/ehci.h"
  19
  20#include "ci.h"
  21#include "bits.h"
  22#include "host.h"
  23
  24static struct hc_driver __read_mostly ci_ehci_hc_driver;
  25static int (*orig_bus_suspend)(struct usb_hcd *hcd);
  26
  27struct ehci_ci_priv {
  28        struct regulator *reg_vbus;
  29        bool enabled;
  30};
  31
  32static int ehci_ci_portpower(struct usb_hcd *hcd, int portnum, bool enable)
  33{
  34        struct ehci_hcd *ehci = hcd_to_ehci(hcd);
  35        struct ehci_ci_priv *priv = (struct ehci_ci_priv *)ehci->priv;
  36        struct device *dev = hcd->self.controller;
  37        struct ci_hdrc *ci = dev_get_drvdata(dev);
  38        int ret = 0;
  39        int port = HCS_N_PORTS(ehci->hcs_params);
  40
  41        if (priv->reg_vbus && enable != priv->enabled) {
  42                if (port > 1) {
  43                        dev_warn(dev,
  44                                "Not support multi-port regulator control\n");
  45                        return 0;
  46                }
  47                if (enable)
  48                        ret = regulator_enable(priv->reg_vbus);
  49                else
  50                        ret = regulator_disable(priv->reg_vbus);
  51                if (ret) {
  52                        dev_err(dev,
  53                                "Failed to %s vbus regulator, ret=%d\n",
  54                                enable ? "enable" : "disable", ret);
  55                        return ret;
  56                }
  57                priv->enabled = enable;
  58        }
  59
  60        if (enable && (ci->platdata->phy_mode == USBPHY_INTERFACE_MODE_HSIC)) {
  61                /*
  62                 * Marvell 28nm HSIC PHY requires forcing the port to HS mode.
  63                 * As HSIC is always HS, this should be safe for others.
  64                 */
  65                hw_port_test_set(ci, 5);
  66                hw_port_test_set(ci, 0);
  67        }
  68        return 0;
  69};
  70
  71static int ehci_ci_reset(struct usb_hcd *hcd)
  72{
  73        struct device *dev = hcd->self.controller;
  74        struct ci_hdrc *ci = dev_get_drvdata(dev);
  75        struct ehci_hcd *ehci = hcd_to_ehci(hcd);
  76        int ret;
  77
  78        ret = ehci_setup(hcd);
  79        if (ret)
  80                return ret;
  81
  82        ehci->need_io_watchdog = 0;
  83
  84        if (ci->platdata->notify_event) {
  85                ret = ci->platdata->notify_event(ci,
  86                                CI_HDRC_CONTROLLER_RESET_EVENT);
  87                if (ret)
  88                        return ret;
  89        }
  90
  91        ci_platform_configure(ci);
  92
  93        return ret;
  94}
  95
  96static const struct ehci_driver_overrides ehci_ci_overrides = {
  97        .extra_priv_size = sizeof(struct ehci_ci_priv),
  98        .port_power      = ehci_ci_portpower,
  99        .reset           = ehci_ci_reset,
 100};
 101
 102static irqreturn_t host_irq(struct ci_hdrc *ci)
 103{
 104        return usb_hcd_irq(ci->irq, ci->hcd);
 105}
 106
 107static int host_start(struct ci_hdrc *ci)
 108{
 109        struct usb_hcd *hcd;
 110        struct ehci_hcd *ehci;
 111        struct ehci_ci_priv *priv;
 112        int ret;
 113
 114        if (usb_disabled())
 115                return -ENODEV;
 116
 117        hcd = __usb_create_hcd(&ci_ehci_hc_driver, ci->dev->parent,
 118                               ci->dev, dev_name(ci->dev), NULL);
 119        if (!hcd)
 120                return -ENOMEM;
 121
 122        dev_set_drvdata(ci->dev, ci);
 123        hcd->rsrc_start = ci->hw_bank.phys;
 124        hcd->rsrc_len = ci->hw_bank.size;
 125        hcd->regs = ci->hw_bank.abs;
 126        hcd->has_tt = 1;
 127
 128        hcd->power_budget = ci->platdata->power_budget;
 129        hcd->tpl_support = ci->platdata->tpl_support;
 130        if (ci->phy || ci->usb_phy) {
 131                hcd->skip_phy_initialization = 1;
 132                if (ci->usb_phy)
 133                        hcd->usb_phy = ci->usb_phy;
 134        }
 135
 136        ehci = hcd_to_ehci(hcd);
 137        ehci->caps = ci->hw_bank.cap;
 138        ehci->has_hostpc = ci->hw_bank.lpm;
 139        ehci->has_tdi_phy_lpm = ci->hw_bank.lpm;
 140        ehci->imx28_write_fix = ci->imx28_write_fix;
 141
 142        priv = (struct ehci_ci_priv *)ehci->priv;
 143        priv->reg_vbus = NULL;
 144
 145        if (ci->platdata->reg_vbus && !ci_otg_is_fsm_mode(ci)) {
 146                if (ci->platdata->flags & CI_HDRC_TURN_VBUS_EARLY_ON) {
 147                        ret = regulator_enable(ci->platdata->reg_vbus);
 148                        if (ret) {
 149                                dev_err(ci->dev,
 150                                "Failed to enable vbus regulator, ret=%d\n",
 151                                                                        ret);
 152                                goto put_hcd;
 153                        }
 154                } else {
 155                        priv->reg_vbus = ci->platdata->reg_vbus;
 156                }
 157        }
 158
 159        if (ci->platdata->pins_host)
 160                pinctrl_select_state(ci->platdata->pctl,
 161                                     ci->platdata->pins_host);
 162
 163        ret = usb_add_hcd(hcd, 0, 0);
 164        if (ret) {
 165                goto disable_reg;
 166        } else {
 167                struct usb_otg *otg = &ci->otg;
 168
 169                ci->hcd = hcd;
 170
 171                if (ci_otg_is_fsm_mode(ci)) {
 172                        otg->host = &hcd->self;
 173                        hcd->self.otg_port = 1;
 174                }
 175
 176                if (ci->platdata->notify_event &&
 177                        (ci->platdata->flags & CI_HDRC_IMX_IS_HSIC))
 178                        ci->platdata->notify_event
 179                                (ci, CI_HDRC_IMX_HSIC_ACTIVE_EVENT);
 180        }
 181
 182        return ret;
 183
 184disable_reg:
 185        if (ci->platdata->reg_vbus && !ci_otg_is_fsm_mode(ci) &&
 186                        (ci->platdata->flags & CI_HDRC_TURN_VBUS_EARLY_ON))
 187                regulator_disable(ci->platdata->reg_vbus);
 188put_hcd:
 189        usb_put_hcd(hcd);
 190
 191        return ret;
 192}
 193
 194static void host_stop(struct ci_hdrc *ci)
 195{
 196        struct usb_hcd *hcd = ci->hcd;
 197
 198        if (hcd) {
 199                if (ci->platdata->notify_event)
 200                        ci->platdata->notify_event(ci,
 201                                CI_HDRC_CONTROLLER_STOPPED_EVENT);
 202                usb_remove_hcd(hcd);
 203                ci->role = CI_ROLE_END;
 204                synchronize_irq(ci->irq);
 205                usb_put_hcd(hcd);
 206                if (ci->platdata->reg_vbus && !ci_otg_is_fsm_mode(ci) &&
 207                        (ci->platdata->flags & CI_HDRC_TURN_VBUS_EARLY_ON))
 208                                regulator_disable(ci->platdata->reg_vbus);
 209        }
 210        ci->hcd = NULL;
 211        ci->otg.host = NULL;
 212
 213        if (ci->platdata->pins_host && ci->platdata->pins_default)
 214                pinctrl_select_state(ci->platdata->pctl,
 215                                     ci->platdata->pins_default);
 216}
 217
 218
 219void ci_hdrc_host_destroy(struct ci_hdrc *ci)
 220{
 221        if (ci->role == CI_ROLE_HOST && ci->hcd)
 222                host_stop(ci);
 223}
 224
 225/* The below code is based on tegra ehci driver */
 226static int ci_ehci_hub_control(
 227        struct usb_hcd  *hcd,
 228        u16             typeReq,
 229        u16             wValue,
 230        u16             wIndex,
 231        char            *buf,
 232        u16             wLength
 233)
 234{
 235        struct ehci_hcd *ehci = hcd_to_ehci(hcd);
 236        u32 __iomem     *status_reg;
 237        u32             temp;
 238        unsigned long   flags;
 239        int             retval = 0;
 240        struct device *dev = hcd->self.controller;
 241        struct ci_hdrc *ci = dev_get_drvdata(dev);
 242
 243        status_reg = &ehci->regs->port_status[(wIndex & 0xff) - 1];
 244
 245        spin_lock_irqsave(&ehci->lock, flags);
 246
 247        if (typeReq == SetPortFeature && wValue == USB_PORT_FEAT_SUSPEND) {
 248                temp = ehci_readl(ehci, status_reg);
 249                if ((temp & PORT_PE) == 0 || (temp & PORT_RESET) != 0) {
 250                        retval = -EPIPE;
 251                        goto done;
 252                }
 253
 254                temp &= ~(PORT_RWC_BITS | PORT_WKCONN_E);
 255                temp |= PORT_WKDISC_E | PORT_WKOC_E;
 256                ehci_writel(ehci, temp | PORT_SUSPEND, status_reg);
 257
 258                /*
 259                 * If a transaction is in progress, there may be a delay in
 260                 * suspending the port. Poll until the port is suspended.
 261                 */
 262                if (ehci_handshake(ehci, status_reg, PORT_SUSPEND,
 263                        PORT_SUSPEND, 5000))
 264                        ehci_err(ehci, "timeout waiting for SUSPEND\n");
 265
 266                if (ci->platdata->flags & CI_HDRC_IMX_IS_HSIC) {
 267                        if (ci->platdata->notify_event)
 268                                ci->platdata->notify_event(ci,
 269                                        CI_HDRC_IMX_HSIC_SUSPEND_EVENT);
 270
 271                        temp = ehci_readl(ehci, status_reg);
 272                        temp &= ~(PORT_WKDISC_E | PORT_WKCONN_E);
 273                        ehci_writel(ehci, temp, status_reg);
 274                }
 275
 276                set_bit((wIndex & 0xff) - 1, &ehci->suspended_ports);
 277                goto done;
 278        }
 279
 280        /*
 281         * After resume has finished, it needs do some post resume
 282         * operation for some SoCs.
 283         */
 284        else if (typeReq == ClearPortFeature &&
 285                wValue == USB_PORT_FEAT_C_SUSPEND) {
 286                /* Make sure the resume has finished, it should be finished */
 287                if (ehci_handshake(ehci, status_reg, PORT_RESUME, 0, 25000))
 288                        ehci_err(ehci, "timeout waiting for resume\n");
 289        }
 290
 291        spin_unlock_irqrestore(&ehci->lock, flags);
 292
 293        /* Handle the hub control events here */
 294        return ehci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength);
 295done:
 296        spin_unlock_irqrestore(&ehci->lock, flags);
 297        return retval;
 298}
 299static int ci_ehci_bus_suspend(struct usb_hcd *hcd)
 300{
 301        struct ehci_hcd *ehci = hcd_to_ehci(hcd);
 302        struct device *dev = hcd->self.controller;
 303        struct ci_hdrc *ci = dev_get_drvdata(dev);
 304        int port;
 305        u32 tmp;
 306
 307        int ret = orig_bus_suspend(hcd);
 308
 309        if (ret)
 310                return ret;
 311
 312        port = HCS_N_PORTS(ehci->hcs_params);
 313        while (port--) {
 314                u32 __iomem *reg = &ehci->regs->port_status[port];
 315                u32 portsc = ehci_readl(ehci, reg);
 316
 317                if (portsc & PORT_CONNECT) {
 318                        /*
 319                         * For chipidea, the resume signal will be ended
 320                         * automatically, so for remote wakeup case, the
 321                         * usbcmd.rs may not be set before the resume has
 322                         * ended if other resume paths consumes too much
 323                         * time (~24ms), in that case, the SOF will not
 324                         * send out within 3ms after resume ends, then the
 325                         * high speed device will enter full speed mode.
 326                         */
 327
 328                        tmp = ehci_readl(ehci, &ehci->regs->command);
 329                        tmp |= CMD_RUN;
 330                        ehci_writel(ehci, tmp, &ehci->regs->command);
 331                        /*
 332                         * It needs a short delay between set RS bit and PHCD.
 333                         */
 334                        usleep_range(150, 200);
 335                        /*
 336                         * Need to clear WKCN and WKOC for imx HSIC,
 337                         * otherwise, there will be wakeup event.
 338                         */
 339                        if (ci->platdata->flags & CI_HDRC_IMX_IS_HSIC) {
 340                                tmp = ehci_readl(ehci, reg);
 341                                tmp &= ~(PORT_WKDISC_E | PORT_WKCONN_E);
 342                                ehci_writel(ehci, tmp, reg);
 343                        }
 344
 345                        break;
 346                }
 347        }
 348
 349        return 0;
 350}
 351
 352int ci_hdrc_host_init(struct ci_hdrc *ci)
 353{
 354        struct ci_role_driver *rdrv;
 355
 356        if (!hw_read(ci, CAP_DCCPARAMS, DCCPARAMS_HC))
 357                return -ENXIO;
 358
 359        rdrv = devm_kzalloc(ci->dev, sizeof(struct ci_role_driver), GFP_KERNEL);
 360        if (!rdrv)
 361                return -ENOMEM;
 362
 363        rdrv->start     = host_start;
 364        rdrv->stop      = host_stop;
 365        rdrv->irq       = host_irq;
 366        rdrv->name      = "host";
 367        ci->roles[CI_ROLE_HOST] = rdrv;
 368
 369        return 0;
 370}
 371
 372void ci_hdrc_host_driver_init(void)
 373{
 374        ehci_init_driver(&ci_ehci_hc_driver, &ehci_ci_overrides);
 375        orig_bus_suspend = ci_ehci_hc_driver.bus_suspend;
 376        ci_ehci_hc_driver.bus_suspend = ci_ehci_bus_suspend;
 377        ci_ehci_hc_driver.hub_control = ci_ehci_hub_control;
 378}
 379