uboot/drivers/usb/host/xhci-dwc3.c
<<
>>
Prefs
   1/*
   2 * Copyright 2015 Freescale Semiconductor, Inc.
   3 *
   4 * DWC3 controller driver
   5 *
   6 * Author: Ramneek Mehresh<ramneek.mehresh@freescale.com>
   7 *
   8 * SPDX-License-Identifier:     GPL-2.0+
   9 */
  10
  11#include <common.h>
  12#include <asm/io.h>
  13#include <linux/usb/dwc3.h>
  14
  15void dwc3_set_mode(struct dwc3 *dwc3_reg, u32 mode)
  16{
  17        clrsetbits_le32(&dwc3_reg->g_ctl,
  18                        DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_OTG),
  19                        DWC3_GCTL_PRTCAPDIR(mode));
  20}
  21
  22void dwc3_phy_reset(struct dwc3 *dwc3_reg)
  23{
  24        /* Assert USB3 PHY reset */
  25        setbits_le32(&dwc3_reg->g_usb3pipectl[0], DWC3_GUSB3PIPECTL_PHYSOFTRST);
  26
  27        /* Assert USB2 PHY reset */
  28        setbits_le32(&dwc3_reg->g_usb2phycfg, DWC3_GUSB2PHYCFG_PHYSOFTRST);
  29
  30        mdelay(100);
  31
  32        /* Clear USB3 PHY reset */
  33        clrbits_le32(&dwc3_reg->g_usb3pipectl[0], DWC3_GUSB3PIPECTL_PHYSOFTRST);
  34
  35        /* Clear USB2 PHY reset */
  36        clrbits_le32(&dwc3_reg->g_usb2phycfg, DWC3_GUSB2PHYCFG_PHYSOFTRST);
  37}
  38
  39void dwc3_core_soft_reset(struct dwc3 *dwc3_reg)
  40{
  41        /* Before Resetting PHY, put Core in Reset */
  42        setbits_le32(&dwc3_reg->g_ctl, DWC3_GCTL_CORESOFTRESET);
  43
  44        /* reset USB3 phy - if required */
  45        dwc3_phy_reset(dwc3_reg);
  46
  47        mdelay(100);
  48
  49        /* After PHYs are stable we can take Core out of reset state */
  50        clrbits_le32(&dwc3_reg->g_ctl, DWC3_GCTL_CORESOFTRESET);
  51}
  52
  53int dwc3_core_init(struct dwc3 *dwc3_reg)
  54{
  55        u32 reg;
  56        u32 revision;
  57        unsigned int dwc3_hwparams1;
  58
  59        revision = readl(&dwc3_reg->g_snpsid);
  60        /* This should read as U3 followed by revision number */
  61        if ((revision & DWC3_GSNPSID_MASK) != 0x55330000) {
  62                puts("this is not a DesignWare USB3 DRD Core\n");
  63                return -1;
  64        }
  65
  66        dwc3_core_soft_reset(dwc3_reg);
  67
  68        dwc3_hwparams1 = readl(&dwc3_reg->g_hwparams1);
  69
  70        reg = readl(&dwc3_reg->g_ctl);
  71        reg &= ~DWC3_GCTL_SCALEDOWN_MASK;
  72        reg &= ~DWC3_GCTL_DISSCRAMBLE;
  73        switch (DWC3_GHWPARAMS1_EN_PWROPT(dwc3_hwparams1)) {
  74        case DWC3_GHWPARAMS1_EN_PWROPT_CLK:
  75                reg &= ~DWC3_GCTL_DSBLCLKGTNG;
  76                break;
  77        default:
  78                debug("No power optimization available\n");
  79        }
  80
  81        /*
  82         * WORKAROUND: DWC3 revisions <1.90a have a bug
  83         * where the device can fail to connect at SuperSpeed
  84         * and falls back to high-speed mode which causes
  85         * the device to enter a Connect/Disconnect loop
  86         */
  87        if ((revision & DWC3_REVISION_MASK) < 0x190a)
  88                reg |= DWC3_GCTL_U2RSTECN;
  89
  90        writel(reg, &dwc3_reg->g_ctl);
  91
  92        return 0;
  93}
  94
  95void dwc3_set_fladj(struct dwc3 *dwc3_reg, u32 val)
  96{
  97        setbits_le32(&dwc3_reg->g_fladj, GFLADJ_30MHZ_REG_SEL |
  98                        GFLADJ_30MHZ(val));
  99}
 100