uboot/drivers/usb/host/dwc2.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2012 Oleksandr Tymoshenko <gonzo@freebsd.org>
   3 * Copyright (C) 2014 Marek Vasut <marex@denx.de>
   4 *
   5 * SPDX-License-Identifier:     GPL-2.0+
   6 */
   7
   8#include <common.h>
   9#include <errno.h>
  10#include <usb.h>
  11#include <malloc.h>
  12#include <usbroothubdes.h>
  13#include <asm/io.h>
  14
  15#include "dwc2.h"
  16
  17/* Use only HC channel 0. */
  18#define DWC2_HC_CHANNEL                 0
  19
  20#define DWC2_STATUS_BUF_SIZE            64
  21#define DWC2_DATA_BUF_SIZE              (64 * 1024)
  22
  23/* We need doubleword-aligned buffers for DMA transfers */
  24DEFINE_ALIGN_BUFFER(uint8_t, aligned_buffer, DWC2_DATA_BUF_SIZE, 8);
  25DEFINE_ALIGN_BUFFER(uint8_t, status_buffer, DWC2_STATUS_BUF_SIZE, 8);
  26
  27#define MAX_DEVICE                      16
  28#define MAX_ENDPOINT                    16
  29static int bulk_data_toggle[MAX_DEVICE][MAX_ENDPOINT];
  30static int control_data_toggle[MAX_DEVICE][MAX_ENDPOINT];
  31
  32static int root_hub_devnum;
  33
  34static struct dwc2_core_regs *regs =
  35        (struct dwc2_core_regs *)CONFIG_USB_DWC2_REG_ADDR;
  36
  37/*
  38 * DWC2 IP interface
  39 */
  40static int wait_for_bit(void *reg, const uint32_t mask, bool set)
  41{
  42        unsigned int timeout = 1000000;
  43        uint32_t val;
  44
  45        while (--timeout) {
  46                val = readl(reg);
  47                if (!set)
  48                        val = ~val;
  49
  50                if ((val & mask) == mask)
  51                        return 0;
  52
  53                udelay(1);
  54        }
  55
  56        debug("%s: Timeout (reg=%p mask=%08x wait_set=%i)\n",
  57              __func__, reg, mask, set);
  58
  59        return -ETIMEDOUT;
  60}
  61
  62/*
  63 * Initializes the FSLSPClkSel field of the HCFG register
  64 * depending on the PHY type.
  65 */
  66static void init_fslspclksel(struct dwc2_core_regs *regs)
  67{
  68        uint32_t phyclk;
  69
  70#if (CONFIG_DWC2_PHY_TYPE == DWC2_PHY_TYPE_FS)
  71        phyclk = DWC2_HCFG_FSLSPCLKSEL_48_MHZ;  /* Full speed PHY */
  72#else
  73        /* High speed PHY running at full speed or high speed */
  74        phyclk = DWC2_HCFG_FSLSPCLKSEL_30_60_MHZ;
  75#endif
  76
  77#ifdef CONFIG_DWC2_ULPI_FS_LS
  78        uint32_t hwcfg2 = readl(&regs->ghwcfg2);
  79        uint32_t hval = (ghwcfg2 & DWC2_HWCFG2_HS_PHY_TYPE_MASK) >>
  80                        DWC2_HWCFG2_HS_PHY_TYPE_OFFSET;
  81        uint32_t fval = (ghwcfg2 & DWC2_HWCFG2_FS_PHY_TYPE_MASK) >>
  82                        DWC2_HWCFG2_FS_PHY_TYPE_OFFSET;
  83
  84        if (hval == 2 && fval == 1)
  85                phyclk = DWC2_HCFG_FSLSPCLKSEL_48_MHZ;  /* Full speed PHY */
  86#endif
  87
  88        clrsetbits_le32(&regs->host_regs.hcfg,
  89                        DWC2_HCFG_FSLSPCLKSEL_MASK,
  90                        phyclk << DWC2_HCFG_FSLSPCLKSEL_OFFSET);
  91}
  92
  93/*
  94 * Flush a Tx FIFO.
  95 *
  96 * @param regs Programming view of DWC_otg controller.
  97 * @param num Tx FIFO to flush.
  98 */
  99static void dwc_otg_flush_tx_fifo(struct dwc2_core_regs *regs, const int num)
 100{
 101        int ret;
 102
 103        writel(DWC2_GRSTCTL_TXFFLSH | (num << DWC2_GRSTCTL_TXFNUM_OFFSET),
 104               &regs->grstctl);
 105        ret = wait_for_bit(&regs->grstctl, DWC2_GRSTCTL_TXFFLSH, 0);
 106        if (ret)
 107                printf("%s: Timeout!\n", __func__);
 108
 109        /* Wait for 3 PHY Clocks */
 110        udelay(1);
 111}
 112
 113/*
 114 * Flush Rx FIFO.
 115 *
 116 * @param regs Programming view of DWC_otg controller.
 117 */
 118static void dwc_otg_flush_rx_fifo(struct dwc2_core_regs *regs)
 119{
 120        int ret;
 121
 122        writel(DWC2_GRSTCTL_RXFFLSH, &regs->grstctl);
 123        ret = wait_for_bit(&regs->grstctl, DWC2_GRSTCTL_RXFFLSH, 0);
 124        if (ret)
 125                printf("%s: Timeout!\n", __func__);
 126
 127        /* Wait for 3 PHY Clocks */
 128        udelay(1);
 129}
 130
 131/*
 132 * Do core a soft reset of the core.  Be careful with this because it
 133 * resets all the internal state machines of the core.
 134 */
 135static void dwc_otg_core_reset(struct dwc2_core_regs *regs)
 136{
 137        int ret;
 138
 139        /* Wait for AHB master IDLE state. */
 140        ret = wait_for_bit(&regs->grstctl, DWC2_GRSTCTL_AHBIDLE, 1);
 141        if (ret)
 142                printf("%s: Timeout!\n", __func__);
 143
 144        /* Core Soft Reset */
 145        writel(DWC2_GRSTCTL_CSFTRST, &regs->grstctl);
 146        ret = wait_for_bit(&regs->grstctl, DWC2_GRSTCTL_CSFTRST, 0);
 147        if (ret)
 148                printf("%s: Timeout!\n", __func__);
 149
 150        /*
 151         * Wait for core to come out of reset.
 152         * NOTE: This long sleep is _very_ important, otherwise the core will
 153         *       not stay in host mode after a connector ID change!
 154         */
 155        mdelay(100);
 156}
 157
 158/*
 159 * This function initializes the DWC_otg controller registers for
 160 * host mode.
 161 *
 162 * This function flushes the Tx and Rx FIFOs and it flushes any entries in the
 163 * request queues. Host channels are reset to ensure that they are ready for
 164 * performing transfers.
 165 *
 166 * @param regs Programming view of DWC_otg controller
 167 *
 168 */
 169static void dwc_otg_core_host_init(struct dwc2_core_regs *regs)
 170{
 171        uint32_t nptxfifosize = 0;
 172        uint32_t ptxfifosize = 0;
 173        uint32_t hprt0 = 0;
 174        int i, ret, num_channels;
 175
 176        /* Restart the Phy Clock */
 177        writel(0, &regs->pcgcctl);
 178
 179        /* Initialize Host Configuration Register */
 180        init_fslspclksel(regs);
 181#ifdef CONFIG_DWC2_DFLT_SPEED_FULL
 182        setbits_le32(&regs->host_regs.hcfg, DWC2_HCFG_FSLSSUPP);
 183#endif
 184
 185        /* Configure data FIFO sizes */
 186#ifdef CONFIG_DWC2_ENABLE_DYNAMIC_FIFO
 187        if (readl(&regs->ghwcfg2) & DWC2_HWCFG2_DYNAMIC_FIFO) {
 188                /* Rx FIFO */
 189                writel(CONFIG_DWC2_HOST_RX_FIFO_SIZE, &regs->grxfsiz);
 190
 191                /* Non-periodic Tx FIFO */
 192                nptxfifosize |= CONFIG_DWC2_HOST_NPERIO_TX_FIFO_SIZE <<
 193                                DWC2_FIFOSIZE_DEPTH_OFFSET;
 194                nptxfifosize |= CONFIG_DWC2_HOST_RX_FIFO_SIZE <<
 195                                DWC2_FIFOSIZE_STARTADDR_OFFSET;
 196                writel(nptxfifosize, &regs->gnptxfsiz);
 197
 198                /* Periodic Tx FIFO */
 199                ptxfifosize |= CONFIG_DWC2_HOST_PERIO_TX_FIFO_SIZE <<
 200                                DWC2_FIFOSIZE_DEPTH_OFFSET;
 201                ptxfifosize |= (CONFIG_DWC2_HOST_RX_FIFO_SIZE +
 202                                CONFIG_DWC2_HOST_NPERIO_TX_FIFO_SIZE) <<
 203                                DWC2_FIFOSIZE_STARTADDR_OFFSET;
 204                writel(ptxfifosize, &regs->hptxfsiz);
 205        }
 206#endif
 207
 208        /* Clear Host Set HNP Enable in the OTG Control Register */
 209        clrbits_le32(&regs->gotgctl, DWC2_GOTGCTL_HSTSETHNPEN);
 210
 211        /* Make sure the FIFOs are flushed. */
 212        dwc_otg_flush_tx_fifo(regs, 0x10);      /* All Tx FIFOs */
 213        dwc_otg_flush_rx_fifo(regs);
 214
 215        /* Flush out any leftover queued requests. */
 216        num_channels = readl(&regs->ghwcfg2);
 217        num_channels &= DWC2_HWCFG2_NUM_HOST_CHAN_MASK;
 218        num_channels >>= DWC2_HWCFG2_NUM_HOST_CHAN_OFFSET;
 219        num_channels += 1;
 220
 221        for (i = 0; i < num_channels; i++)
 222                clrsetbits_le32(&regs->hc_regs[i].hcchar,
 223                                DWC2_HCCHAR_CHEN | DWC2_HCCHAR_EPDIR,
 224                                DWC2_HCCHAR_CHDIS);
 225
 226        /* Halt all channels to put them into a known state. */
 227        for (i = 0; i < num_channels; i++) {
 228                clrsetbits_le32(&regs->hc_regs[i].hcchar,
 229                                DWC2_HCCHAR_EPDIR,
 230                                DWC2_HCCHAR_CHEN | DWC2_HCCHAR_CHDIS);
 231                ret = wait_for_bit(&regs->hc_regs[i].hcchar,
 232                                   DWC2_HCCHAR_CHEN, 0);
 233                if (ret)
 234                        printf("%s: Timeout!\n", __func__);
 235        }
 236
 237        /* Turn on the vbus power. */
 238        if (readl(&regs->gintsts) & DWC2_GINTSTS_CURMODE_HOST) {
 239                hprt0 = readl(&regs->hprt0);
 240                hprt0 &= ~(DWC2_HPRT0_PRTENA | DWC2_HPRT0_PRTCONNDET);
 241                hprt0 &= ~(DWC2_HPRT0_PRTENCHNG | DWC2_HPRT0_PRTOVRCURRCHNG);
 242                if (!(hprt0 & DWC2_HPRT0_PRTPWR)) {
 243                        hprt0 |= DWC2_HPRT0_PRTPWR;
 244                        writel(hprt0, &regs->hprt0);
 245                }
 246        }
 247}
 248
 249/*
 250 * This function initializes the DWC_otg controller registers and
 251 * prepares the core for device mode or host mode operation.
 252 *
 253 * @param regs Programming view of the DWC_otg controller
 254 */
 255static void dwc_otg_core_init(struct dwc2_core_regs *regs)
 256{
 257        uint32_t ahbcfg = 0;
 258        uint32_t usbcfg = 0;
 259        uint8_t brst_sz = CONFIG_DWC2_DMA_BURST_SIZE;
 260
 261        /* Common Initialization */
 262        usbcfg = readl(&regs->gusbcfg);
 263
 264        /* Program the ULPI External VBUS bit if needed */
 265#ifdef CONFIG_DWC2_PHY_ULPI_EXT_VBUS
 266        usbcfg |= DWC2_GUSBCFG_ULPI_EXT_VBUS_DRV;
 267#else
 268        usbcfg &= ~DWC2_GUSBCFG_ULPI_EXT_VBUS_DRV;
 269#endif
 270
 271        /* Set external TS Dline pulsing */
 272#ifdef CONFIG_DWC2_TS_DLINE
 273        usbcfg |= DWC2_GUSBCFG_TERM_SEL_DL_PULSE;
 274#else
 275        usbcfg &= ~DWC2_GUSBCFG_TERM_SEL_DL_PULSE;
 276#endif
 277        writel(usbcfg, &regs->gusbcfg);
 278
 279        /* Reset the Controller */
 280        dwc_otg_core_reset(regs);
 281
 282        /*
 283         * This programming sequence needs to happen in FS mode before
 284         * any other programming occurs
 285         */
 286#if defined(CONFIG_DWC2_DFLT_SPEED_FULL) && \
 287        (CONFIG_DWC2_PHY_TYPE == DWC2_PHY_TYPE_FS)
 288        /* If FS mode with FS PHY */
 289        setbits_le32(&regs->gusbcfg, DWC2_GUSBCFG_PHYSEL);
 290
 291        /* Reset after a PHY select */
 292        dwc_otg_core_reset(regs);
 293
 294        /*
 295         * Program DCFG.DevSpd or HCFG.FSLSPclkSel to 48Mhz in FS.
 296         * Also do this on HNP Dev/Host mode switches (done in dev_init
 297         * and host_init).
 298         */
 299        if (readl(&regs->gintsts) & DWC2_GINTSTS_CURMODE_HOST)
 300                init_fslspclksel(regs);
 301
 302#ifdef CONFIG_DWC2_I2C_ENABLE
 303        /* Program GUSBCFG.OtgUtmifsSel to I2C */
 304        setbits_le32(&regs->gusbcfg, DWC2_GUSBCFG_OTGUTMIFSSEL);
 305
 306        /* Program GI2CCTL.I2CEn */
 307        clrsetbits_le32(&regs->gi2cctl, DWC2_GI2CCTL_I2CEN |
 308                        DWC2_GI2CCTL_I2CDEVADDR_MASK,
 309                        1 << DWC2_GI2CCTL_I2CDEVADDR_OFFSET);
 310        setbits_le32(&regs->gi2cctl, DWC2_GI2CCTL_I2CEN);
 311#endif
 312
 313#else
 314        /* High speed PHY. */
 315
 316        /*
 317         * HS PHY parameters. These parameters are preserved during
 318         * soft reset so only program the first time. Do a soft reset
 319         * immediately after setting phyif.
 320         */
 321        usbcfg &= ~(DWC2_GUSBCFG_ULPI_UTMI_SEL | DWC2_GUSBCFG_PHYIF);
 322        usbcfg |= CONFIG_DWC2_PHY_TYPE << DWC2_GUSBCFG_ULPI_UTMI_SEL_OFFSET;
 323
 324        if (usbcfg & DWC2_GUSBCFG_ULPI_UTMI_SEL) {      /* ULPI interface */
 325#ifdef CONFIG_DWC2_PHY_ULPI_DDR
 326                usbcfg |= DWC2_GUSBCFG_DDRSEL;
 327#else
 328                usbcfg &= ~DWC2_GUSBCFG_DDRSEL;
 329#endif
 330        } else {        /* UTMI+ interface */
 331#if (CONFIG_DWC2_UTMI_PHY_WIDTH == 16)
 332                usbcfg |= DWC2_GUSBCFG_PHYIF;
 333#endif
 334        }
 335
 336        writel(usbcfg, &regs->gusbcfg);
 337
 338        /* Reset after setting the PHY parameters */
 339        dwc_otg_core_reset(regs);
 340#endif
 341
 342        usbcfg = readl(&regs->gusbcfg);
 343        usbcfg &= ~(DWC2_GUSBCFG_ULPI_FSLS | DWC2_GUSBCFG_ULPI_CLK_SUS_M);
 344#ifdef CONFIG_DWC2_ULPI_FS_LS
 345        uint32_t hwcfg2 = readl(&regs->ghwcfg2);
 346        uint32_t hval = (ghwcfg2 & DWC2_HWCFG2_HS_PHY_TYPE_MASK) >>
 347                        DWC2_HWCFG2_HS_PHY_TYPE_OFFSET;
 348        uint32_t fval = (ghwcfg2 & DWC2_HWCFG2_FS_PHY_TYPE_MASK) >>
 349                        DWC2_HWCFG2_FS_PHY_TYPE_OFFSET;
 350        if (hval == 2 && fval == 1) {
 351                usbcfg |= DWC2_GUSBCFG_ULPI_FSLS;
 352                usbcfg |= DWC2_GUSBCFG_ULPI_CLK_SUS_M;
 353        }
 354#endif
 355        writel(usbcfg, &regs->gusbcfg);
 356
 357        /* Program the GAHBCFG Register. */
 358        switch (readl(&regs->ghwcfg2) & DWC2_HWCFG2_ARCHITECTURE_MASK) {
 359        case DWC2_HWCFG2_ARCHITECTURE_SLAVE_ONLY:
 360                break;
 361        case DWC2_HWCFG2_ARCHITECTURE_EXT_DMA:
 362                while (brst_sz > 1) {
 363                        ahbcfg |= ahbcfg + (1 << DWC2_GAHBCFG_HBURSTLEN_OFFSET);
 364                        ahbcfg &= DWC2_GAHBCFG_HBURSTLEN_MASK;
 365                        brst_sz >>= 1;
 366                }
 367
 368#ifdef CONFIG_DWC2_DMA_ENABLE
 369                ahbcfg |= DWC2_GAHBCFG_DMAENABLE;
 370#endif
 371                break;
 372
 373        case DWC2_HWCFG2_ARCHITECTURE_INT_DMA:
 374                ahbcfg |= DWC2_GAHBCFG_HBURSTLEN_INCR4;
 375#ifdef CONFIG_DWC2_DMA_ENABLE
 376                ahbcfg |= DWC2_GAHBCFG_DMAENABLE;
 377#endif
 378                break;
 379        }
 380
 381        writel(ahbcfg, &regs->gahbcfg);
 382
 383        /* Program the GUSBCFG register for HNP/SRP. */
 384        setbits_le32(&regs->gusbcfg, DWC2_GUSBCFG_HNPCAP | DWC2_GUSBCFG_SRPCAP);
 385
 386#ifdef CONFIG_DWC2_IC_USB_CAP
 387        setbits_le32(&regs->gusbcfg, DWC2_GUSBCFG_IC_USB_CAP);
 388#endif
 389}
 390
 391/*
 392 * Prepares a host channel for transferring packets to/from a specific
 393 * endpoint. The HCCHARn register is set up with the characteristics specified
 394 * in _hc. Host channel interrupts that may need to be serviced while this
 395 * transfer is in progress are enabled.
 396 *
 397 * @param regs Programming view of DWC_otg controller
 398 * @param hc Information needed to initialize the host channel
 399 */
 400static void dwc_otg_hc_init(struct dwc2_core_regs *regs, uint8_t hc_num,
 401                uint8_t dev_addr, uint8_t ep_num, uint8_t ep_is_in,
 402                uint8_t ep_type, uint16_t max_packet)
 403{
 404        struct dwc2_hc_regs *hc_regs = &regs->hc_regs[hc_num];
 405        const uint32_t hcchar = (dev_addr << DWC2_HCCHAR_DEVADDR_OFFSET) |
 406                                (ep_num << DWC2_HCCHAR_EPNUM_OFFSET) |
 407                                (ep_is_in << DWC2_HCCHAR_EPDIR_OFFSET) |
 408                                (ep_type << DWC2_HCCHAR_EPTYPE_OFFSET) |
 409                                (max_packet << DWC2_HCCHAR_MPS_OFFSET);
 410
 411        /* Clear old interrupt conditions for this host channel. */
 412        writel(0x3fff, &hc_regs->hcint);
 413
 414        /*
 415         * Program the HCCHARn register with the endpoint characteristics
 416         * for the current transfer.
 417         */
 418        writel(hcchar, &hc_regs->hcchar);
 419
 420        /* Program the HCSPLIT register for SPLITs */
 421        writel(0, &hc_regs->hcsplt);
 422}
 423
 424/*
 425 * DWC2 to USB API interface
 426 */
 427/* Direction: In ; Request: Status */
 428static int dwc_otg_submit_rh_msg_in_status(struct usb_device *dev, void *buffer,
 429                                           int txlen, struct devrequest *cmd)
 430{
 431        uint32_t hprt0 = 0;
 432        uint32_t port_status = 0;
 433        uint32_t port_change = 0;
 434        int len = 0;
 435        int stat = 0;
 436
 437        switch (cmd->requesttype & ~USB_DIR_IN) {
 438        case 0:
 439                *(uint16_t *)buffer = cpu_to_le16(1);
 440                len = 2;
 441                break;
 442        case USB_RECIP_INTERFACE:
 443        case USB_RECIP_ENDPOINT:
 444                *(uint16_t *)buffer = cpu_to_le16(0);
 445                len = 2;
 446                break;
 447        case USB_TYPE_CLASS:
 448                *(uint32_t *)buffer = cpu_to_le32(0);
 449                len = 4;
 450                break;
 451        case USB_RECIP_OTHER | USB_TYPE_CLASS:
 452                hprt0 = readl(&regs->hprt0);
 453                if (hprt0 & DWC2_HPRT0_PRTCONNSTS)
 454                        port_status |= USB_PORT_STAT_CONNECTION;
 455                if (hprt0 & DWC2_HPRT0_PRTENA)
 456                        port_status |= USB_PORT_STAT_ENABLE;
 457                if (hprt0 & DWC2_HPRT0_PRTSUSP)
 458                        port_status |= USB_PORT_STAT_SUSPEND;
 459                if (hprt0 & DWC2_HPRT0_PRTOVRCURRACT)
 460                        port_status |= USB_PORT_STAT_OVERCURRENT;
 461                if (hprt0 & DWC2_HPRT0_PRTRST)
 462                        port_status |= USB_PORT_STAT_RESET;
 463                if (hprt0 & DWC2_HPRT0_PRTPWR)
 464                        port_status |= USB_PORT_STAT_POWER;
 465
 466                port_status |= USB_PORT_STAT_HIGH_SPEED;
 467
 468                if (hprt0 & DWC2_HPRT0_PRTENCHNG)
 469                        port_change |= USB_PORT_STAT_C_ENABLE;
 470                if (hprt0 & DWC2_HPRT0_PRTCONNDET)
 471                        port_change |= USB_PORT_STAT_C_CONNECTION;
 472                if (hprt0 & DWC2_HPRT0_PRTOVRCURRCHNG)
 473                        port_change |= USB_PORT_STAT_C_OVERCURRENT;
 474
 475                *(uint32_t *)buffer = cpu_to_le32(port_status |
 476                                        (port_change << 16));
 477                len = 4;
 478                break;
 479        default:
 480                puts("unsupported root hub command\n");
 481                stat = USB_ST_STALLED;
 482        }
 483
 484        dev->act_len = min(len, txlen);
 485        dev->status = stat;
 486
 487        return stat;
 488}
 489
 490/* Direction: In ; Request: Descriptor */
 491static int dwc_otg_submit_rh_msg_in_descriptor(struct usb_device *dev,
 492                                               void *buffer, int txlen,
 493                                               struct devrequest *cmd)
 494{
 495        unsigned char data[32];
 496        uint32_t dsc;
 497        int len = 0;
 498        int stat = 0;
 499        uint16_t wValue = cpu_to_le16(cmd->value);
 500        uint16_t wLength = cpu_to_le16(cmd->length);
 501
 502        switch (cmd->requesttype & ~USB_DIR_IN) {
 503        case 0:
 504                switch (wValue & 0xff00) {
 505                case 0x0100:    /* device descriptor */
 506                        len = min3(txlen, (int)sizeof(root_hub_dev_des), (int)wLength);
 507                        memcpy(buffer, root_hub_dev_des, len);
 508                        break;
 509                case 0x0200:    /* configuration descriptor */
 510                        len = min3(txlen, (int)sizeof(root_hub_config_des), (int)wLength);
 511                        memcpy(buffer, root_hub_config_des, len);
 512                        break;
 513                case 0x0300:    /* string descriptors */
 514                        switch (wValue & 0xff) {
 515                        case 0x00:
 516                                len = min3(txlen, (int)sizeof(root_hub_str_index0),
 517                                           (int)wLength);
 518                                memcpy(buffer, root_hub_str_index0, len);
 519                                break;
 520                        case 0x01:
 521                                len = min3(txlen, (int)sizeof(root_hub_str_index1),
 522                                           (int)wLength);
 523                                memcpy(buffer, root_hub_str_index1, len);
 524                                break;
 525                        }
 526                        break;
 527                default:
 528                        stat = USB_ST_STALLED;
 529                }
 530                break;
 531
 532        case USB_TYPE_CLASS:
 533                /* Root port config, set 1 port and nothing else. */
 534                dsc = 0x00000001;
 535
 536                data[0] = 9;            /* min length; */
 537                data[1] = 0x29;
 538                data[2] = dsc & RH_A_NDP;
 539                data[3] = 0;
 540                if (dsc & RH_A_PSM)
 541                        data[3] |= 0x1;
 542                if (dsc & RH_A_NOCP)
 543                        data[3] |= 0x10;
 544                else if (dsc & RH_A_OCPM)
 545                        data[3] |= 0x8;
 546
 547                /* corresponds to data[4-7] */
 548                data[5] = (dsc & RH_A_POTPGT) >> 24;
 549                data[7] = dsc & RH_B_DR;
 550                if (data[2] < 7) {
 551                        data[8] = 0xff;
 552                } else {
 553                        data[0] += 2;
 554                        data[8] = (dsc & RH_B_DR) >> 8;
 555                        data[9] = 0xff;
 556                        data[10] = data[9];
 557                }
 558
 559                len = min3(txlen, (int)data[0], (int)wLength);
 560                memcpy(buffer, data, len);
 561                break;
 562        default:
 563                puts("unsupported root hub command\n");
 564                stat = USB_ST_STALLED;
 565        }
 566
 567        dev->act_len = min(len, txlen);
 568        dev->status = stat;
 569
 570        return stat;
 571}
 572
 573/* Direction: In ; Request: Configuration */
 574static int dwc_otg_submit_rh_msg_in_configuration(struct usb_device *dev,
 575                                                  void *buffer, int txlen,
 576                                                  struct devrequest *cmd)
 577{
 578        int len = 0;
 579        int stat = 0;
 580
 581        switch (cmd->requesttype & ~USB_DIR_IN) {
 582        case 0:
 583                *(uint8_t *)buffer = 0x01;
 584                len = 1;
 585                break;
 586        default:
 587                puts("unsupported root hub command\n");
 588                stat = USB_ST_STALLED;
 589        }
 590
 591        dev->act_len = min(len, txlen);
 592        dev->status = stat;
 593
 594        return stat;
 595}
 596
 597/* Direction: In */
 598static int dwc_otg_submit_rh_msg_in(struct usb_device *dev,
 599                                 void *buffer, int txlen,
 600                                 struct devrequest *cmd)
 601{
 602        switch (cmd->request) {
 603        case USB_REQ_GET_STATUS:
 604                return dwc_otg_submit_rh_msg_in_status(dev, buffer,
 605                                                       txlen, cmd);
 606        case USB_REQ_GET_DESCRIPTOR:
 607                return dwc_otg_submit_rh_msg_in_descriptor(dev, buffer,
 608                                                           txlen, cmd);
 609        case USB_REQ_GET_CONFIGURATION:
 610                return dwc_otg_submit_rh_msg_in_configuration(dev, buffer,
 611                                                              txlen, cmd);
 612        default:
 613                puts("unsupported root hub command\n");
 614                return USB_ST_STALLED;
 615        }
 616}
 617
 618/* Direction: Out */
 619static int dwc_otg_submit_rh_msg_out(struct usb_device *dev,
 620                                 void *buffer, int txlen,
 621                                 struct devrequest *cmd)
 622{
 623        int len = 0;
 624        int stat = 0;
 625        uint16_t bmrtype_breq = cmd->requesttype | (cmd->request << 8);
 626        uint16_t wValue = cpu_to_le16(cmd->value);
 627
 628        switch (bmrtype_breq & ~USB_DIR_IN) {
 629        case (USB_REQ_CLEAR_FEATURE << 8) | USB_RECIP_ENDPOINT:
 630        case (USB_REQ_CLEAR_FEATURE << 8) | USB_TYPE_CLASS:
 631                break;
 632
 633        case (USB_REQ_CLEAR_FEATURE << 8) | USB_RECIP_OTHER | USB_TYPE_CLASS:
 634                switch (wValue) {
 635                case USB_PORT_FEAT_C_CONNECTION:
 636                        setbits_le32(&regs->hprt0, DWC2_HPRT0_PRTCONNDET);
 637                        break;
 638                }
 639                break;
 640
 641        case (USB_REQ_SET_FEATURE << 8) | USB_RECIP_OTHER | USB_TYPE_CLASS:
 642                switch (wValue) {
 643                case USB_PORT_FEAT_SUSPEND:
 644                        break;
 645
 646                case USB_PORT_FEAT_RESET:
 647                        clrsetbits_le32(&regs->hprt0, DWC2_HPRT0_PRTENA |
 648                                        DWC2_HPRT0_PRTCONNDET |
 649                                        DWC2_HPRT0_PRTENCHNG |
 650                                        DWC2_HPRT0_PRTOVRCURRCHNG,
 651                                        DWC2_HPRT0_PRTRST);
 652                        mdelay(50);
 653                        clrbits_le32(&regs->hprt0, DWC2_HPRT0_PRTRST);
 654                        break;
 655
 656                case USB_PORT_FEAT_POWER:
 657                        clrsetbits_le32(&regs->hprt0, DWC2_HPRT0_PRTENA |
 658                                        DWC2_HPRT0_PRTCONNDET |
 659                                        DWC2_HPRT0_PRTENCHNG |
 660                                        DWC2_HPRT0_PRTOVRCURRCHNG,
 661                                        DWC2_HPRT0_PRTRST);
 662                        break;
 663
 664                case USB_PORT_FEAT_ENABLE:
 665                        break;
 666                }
 667                break;
 668        case (USB_REQ_SET_ADDRESS << 8):
 669                root_hub_devnum = wValue;
 670                break;
 671        case (USB_REQ_SET_CONFIGURATION << 8):
 672                break;
 673        default:
 674                puts("unsupported root hub command\n");
 675                stat = USB_ST_STALLED;
 676        }
 677
 678        len = min(len, txlen);
 679
 680        dev->act_len = len;
 681        dev->status = stat;
 682
 683        return stat;
 684}
 685
 686static int dwc_otg_submit_rh_msg(struct usb_device *dev, unsigned long pipe,
 687                                 void *buffer, int txlen,
 688                                 struct devrequest *cmd)
 689{
 690        int stat = 0;
 691
 692        if (usb_pipeint(pipe)) {
 693                puts("Root-Hub submit IRQ: NOT implemented\n");
 694                return 0;
 695        }
 696
 697        if (cmd->requesttype & USB_DIR_IN)
 698                stat = dwc_otg_submit_rh_msg_in(dev, buffer, txlen, cmd);
 699        else
 700                stat = dwc_otg_submit_rh_msg_out(dev, buffer, txlen, cmd);
 701
 702        mdelay(1);
 703
 704        return stat;
 705}
 706
 707/* U-Boot USB transmission interface */
 708int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
 709                    int len)
 710{
 711        int devnum = usb_pipedevice(pipe);
 712        int ep = usb_pipeendpoint(pipe);
 713        int max = usb_maxpacket(dev, pipe);
 714        int done = 0;
 715        uint32_t hctsiz, sub, tmp;
 716        struct dwc2_hc_regs *hc_regs = &regs->hc_regs[DWC2_HC_CHANNEL];
 717        uint32_t hcint;
 718        uint32_t xfer_len;
 719        uint32_t num_packets;
 720        int stop_transfer = 0;
 721        unsigned int timeout = 1000000;
 722
 723        if (devnum == root_hub_devnum) {
 724                dev->status = 0;
 725                return -EINVAL;
 726        }
 727
 728        if (len > DWC2_DATA_BUF_SIZE) {
 729                printf("%s: %d is more then available buffer size (%d)\n",
 730                       __func__, len, DWC2_DATA_BUF_SIZE);
 731                dev->status = 0;
 732                dev->act_len = 0;
 733                return -EINVAL;
 734        }
 735
 736        while ((done < len) && !stop_transfer) {
 737                /* Initialize channel */
 738                dwc_otg_hc_init(regs, DWC2_HC_CHANNEL, devnum, ep,
 739                                usb_pipein(pipe), DWC2_HCCHAR_EPTYPE_BULK, max);
 740
 741                xfer_len = len - done;
 742                /* Make sure that xfer_len is a multiple of max packet size. */
 743                if (xfer_len > CONFIG_DWC2_MAX_TRANSFER_SIZE)
 744                        xfer_len = CONFIG_DWC2_MAX_TRANSFER_SIZE - max + 1;
 745
 746                if (xfer_len > 0) {
 747                        num_packets = (xfer_len + max - 1) / max;
 748                        if (num_packets > CONFIG_DWC2_MAX_PACKET_COUNT) {
 749                                num_packets = CONFIG_DWC2_MAX_PACKET_COUNT;
 750                                xfer_len = num_packets * max;
 751                        }
 752                } else {
 753                        num_packets = 1;
 754                }
 755
 756                if (usb_pipein(pipe))
 757                        xfer_len = num_packets * max;
 758
 759                writel((xfer_len << DWC2_HCTSIZ_XFERSIZE_OFFSET) |
 760                       (num_packets << DWC2_HCTSIZ_PKTCNT_OFFSET) |
 761                       (bulk_data_toggle[devnum][ep] <<
 762                                DWC2_HCTSIZ_PID_OFFSET),
 763                       &hc_regs->hctsiz);
 764
 765                memcpy(aligned_buffer, (char *)buffer + done, len - done);
 766                writel((uint32_t)aligned_buffer, &hc_regs->hcdma);
 767
 768                /* Set host channel enable after all other setup is complete. */
 769                clrsetbits_le32(&hc_regs->hcchar, DWC2_HCCHAR_MULTICNT_MASK |
 770                                DWC2_HCCHAR_CHEN | DWC2_HCCHAR_CHDIS,
 771                                (1 << DWC2_HCCHAR_MULTICNT_OFFSET) |
 772                                DWC2_HCCHAR_CHEN);
 773
 774                while (1) {
 775                        hcint = readl(&hc_regs->hcint);
 776
 777                        if (!(hcint & DWC2_HCINT_CHHLTD))
 778                                continue;
 779
 780                        if (hcint & DWC2_HCINT_XFERCOMP) {
 781                                hctsiz = readl(&hc_regs->hctsiz);
 782                                done += xfer_len;
 783
 784                                sub = hctsiz & DWC2_HCTSIZ_XFERSIZE_MASK;
 785                                sub >>= DWC2_HCTSIZ_XFERSIZE_OFFSET;
 786
 787                                if (usb_pipein(pipe)) {
 788                                        done -= sub;
 789                                        if (hctsiz & DWC2_HCTSIZ_XFERSIZE_MASK)
 790                                                stop_transfer = 1;
 791                                }
 792
 793                                tmp = hctsiz & DWC2_HCTSIZ_PID_MASK;
 794                                tmp >>= DWC2_HCTSIZ_PID_OFFSET;
 795                                if (tmp == DWC2_HC_PID_DATA1) {
 796                                        bulk_data_toggle[devnum][ep] =
 797                                                DWC2_HC_PID_DATA1;
 798                                } else {
 799                                        bulk_data_toggle[devnum][ep] =
 800                                                DWC2_HC_PID_DATA0;
 801                                }
 802                                break;
 803                        }
 804
 805                        if (hcint & DWC2_HCINT_STALL) {
 806                                puts("DWC OTG: Channel halted\n");
 807                                bulk_data_toggle[devnum][ep] =
 808                                        DWC2_HC_PID_DATA0;
 809
 810                                stop_transfer = 1;
 811                                break;
 812                        }
 813
 814                        if (!--timeout) {
 815                                printf("%s: Timeout!\n", __func__);
 816                                break;
 817                        }
 818                }
 819        }
 820
 821        if (done && usb_pipein(pipe))
 822                memcpy(buffer, aligned_buffer, done);
 823
 824        writel(0, &hc_regs->hcintmsk);
 825        writel(0xFFFFFFFF, &hc_regs->hcint);
 826
 827        dev->status = 0;
 828        dev->act_len = done;
 829
 830        return 0;
 831}
 832
 833int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
 834                       int len, struct devrequest *setup)
 835{
 836        struct dwc2_hc_regs *hc_regs = &regs->hc_regs[DWC2_HC_CHANNEL];
 837        int done = 0;
 838        int devnum = usb_pipedevice(pipe);
 839        int ep = usb_pipeendpoint(pipe);
 840        int max = usb_maxpacket(dev, pipe);
 841        uint32_t hctsiz = 0, sub, tmp, ret;
 842        uint32_t hcint;
 843        const uint32_t hcint_comp_hlt_ack = DWC2_HCINT_XFERCOMP |
 844                DWC2_HCINT_CHHLTD | DWC2_HCINT_ACK;
 845        unsigned int timeout = 1000000;
 846
 847        /* For CONTROL endpoint pid should start with DATA1 */
 848        int status_direction;
 849
 850        if (devnum == root_hub_devnum) {
 851                dev->status = 0;
 852                dev->speed = USB_SPEED_HIGH;
 853                return dwc_otg_submit_rh_msg(dev, pipe, buffer, len, setup);
 854        }
 855
 856        if (len > DWC2_DATA_BUF_SIZE) {
 857                printf("%s: %d is more then available buffer size(%d)\n",
 858                       __func__, len, DWC2_DATA_BUF_SIZE);
 859                dev->status = 0;
 860                dev->act_len = 0;
 861                return -EINVAL;
 862        }
 863
 864        /* Initialize channel, OUT for setup buffer */
 865        dwc_otg_hc_init(regs, DWC2_HC_CHANNEL, devnum, ep, 0,
 866                        DWC2_HCCHAR_EPTYPE_CONTROL, max);
 867
 868        /* SETUP stage  */
 869        writel((8 << DWC2_HCTSIZ_XFERSIZE_OFFSET) |
 870               (1 << DWC2_HCTSIZ_PKTCNT_OFFSET) |
 871               (DWC2_HC_PID_SETUP << DWC2_HCTSIZ_PID_OFFSET),
 872               &hc_regs->hctsiz);
 873
 874        writel((uint32_t)setup, &hc_regs->hcdma);
 875
 876        /* Set host channel enable after all other setup is complete. */
 877        clrsetbits_le32(&hc_regs->hcchar, DWC2_HCCHAR_MULTICNT_MASK |
 878                        DWC2_HCCHAR_CHEN | DWC2_HCCHAR_CHDIS,
 879                        (1 << DWC2_HCCHAR_MULTICNT_OFFSET) | DWC2_HCCHAR_CHEN);
 880
 881        ret = wait_for_bit(&hc_regs->hcint, DWC2_HCINT_CHHLTD, 1);
 882        if (ret)
 883                printf("%s: Timeout!\n", __func__);
 884
 885        hcint = readl(&hc_regs->hcint);
 886
 887        if (!(hcint & DWC2_HCINT_CHHLTD) || !(hcint & DWC2_HCINT_XFERCOMP)) {
 888                printf("%s: Error (HCINT=%08x)\n", __func__, hcint);
 889                dev->status = 0;
 890                dev->act_len = 0;
 891                return -EINVAL;
 892        }
 893
 894        /* Clear interrupts */
 895        writel(0, &hc_regs->hcintmsk);
 896        writel(0xFFFFFFFF, &hc_regs->hcint);
 897
 898        if (buffer) {
 899                /* DATA stage */
 900                dwc_otg_hc_init(regs, DWC2_HC_CHANNEL, devnum, ep,
 901                                usb_pipein(pipe),
 902                                DWC2_HCCHAR_EPTYPE_CONTROL, max);
 903
 904                /* TODO: check if len < 64 */
 905                control_data_toggle[devnum][ep] = DWC2_HC_PID_DATA1;
 906                writel((len << DWC2_HCTSIZ_XFERSIZE_OFFSET) |
 907                       (1 << DWC2_HCTSIZ_PKTCNT_OFFSET) |
 908                       (control_data_toggle[devnum][ep] <<
 909                                DWC2_HCTSIZ_PID_OFFSET),
 910                       &hc_regs->hctsiz);
 911
 912                writel((uint32_t)buffer, &hc_regs->hcdma);
 913
 914                /* Set host channel enable after all other setup is complete */
 915                clrsetbits_le32(&hc_regs->hcchar, DWC2_HCCHAR_MULTICNT_MASK |
 916                                DWC2_HCCHAR_CHEN | DWC2_HCCHAR_CHDIS,
 917                                (1 << DWC2_HCCHAR_MULTICNT_OFFSET) |
 918                                DWC2_HCCHAR_CHEN);
 919
 920                while (1) {
 921                        hcint = readl(&hc_regs->hcint);
 922                        if (!(hcint & DWC2_HCINT_CHHLTD))
 923                                continue;
 924
 925                        if (hcint & DWC2_HCINT_XFERCOMP) {
 926                                hctsiz = readl(&hc_regs->hctsiz);
 927                                done = len;
 928
 929                                sub = hctsiz & DWC2_HCTSIZ_XFERSIZE_MASK;
 930                                sub >>= DWC2_HCTSIZ_XFERSIZE_OFFSET;
 931
 932                                if (usb_pipein(pipe))
 933                                        done -= sub;
 934                        }
 935
 936                        if (hcint & DWC2_HCINT_ACK) {
 937                                tmp = hctsiz & DWC2_HCTSIZ_PID_MASK;
 938                                tmp >>= DWC2_HCTSIZ_PID_OFFSET;
 939                                if (tmp == DWC2_HC_PID_DATA0) {
 940                                        control_data_toggle[devnum][ep] =
 941                                                DWC2_HC_PID_DATA0;
 942                                } else {
 943                                        control_data_toggle[devnum][ep] =
 944                                                DWC2_HC_PID_DATA1;
 945                                }
 946                        }
 947
 948                        if (hcint != hcint_comp_hlt_ack) {
 949                                printf("%s: Error (HCINT=%08x)\n",
 950                                       __func__, hcint);
 951                                goto out;
 952                        }
 953
 954                        if (!--timeout) {
 955                                printf("%s: Timeout!\n", __func__);
 956                                goto out;
 957                        }
 958
 959                        break;
 960                }
 961        } /* End of DATA stage */
 962
 963        /* STATUS stage */
 964        if ((len == 0) || usb_pipeout(pipe))
 965                status_direction = 1;
 966        else
 967                status_direction = 0;
 968
 969        dwc_otg_hc_init(regs, DWC2_HC_CHANNEL, devnum, ep,
 970                        status_direction, DWC2_HCCHAR_EPTYPE_CONTROL, max);
 971
 972        writel((1 << DWC2_HCTSIZ_PKTCNT_OFFSET) |
 973               (DWC2_HC_PID_DATA1 << DWC2_HCTSIZ_PID_OFFSET),
 974               &hc_regs->hctsiz);
 975
 976        writel((uint32_t)status_buffer, &hc_regs->hcdma);
 977
 978        /* Set host channel enable after all other setup is complete. */
 979        clrsetbits_le32(&hc_regs->hcchar, DWC2_HCCHAR_MULTICNT_MASK |
 980                        DWC2_HCCHAR_CHEN | DWC2_HCCHAR_CHDIS,
 981                        (1 << DWC2_HCCHAR_MULTICNT_OFFSET) | DWC2_HCCHAR_CHEN);
 982
 983        while (1) {
 984                hcint = readl(&hc_regs->hcint);
 985                if (hcint & DWC2_HCINT_CHHLTD)
 986                        break;
 987        }
 988
 989        if (hcint != hcint_comp_hlt_ack)
 990                printf("%s: Error (HCINT=%08x)\n", __func__, hcint);
 991
 992out:
 993        dev->act_len = done;
 994        dev->status = 0;
 995
 996        return done;
 997}
 998
 999int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
1000                   int len, int interval)
1001{
1002        printf("dev = %p pipe = %#lx buf = %p size = %d int = %d\n",
1003               dev, pipe, buffer, len, interval);
1004        return -ENOSYS;
1005}
1006
1007/* U-Boot USB control interface */
1008int usb_lowlevel_init(int index, enum usb_init_type init, void **controller)
1009{
1010        uint32_t snpsid;
1011        int i, j;
1012
1013        root_hub_devnum = 0;
1014
1015        snpsid = readl(&regs->gsnpsid);
1016        printf("Core Release: %x.%03x\n", snpsid >> 12 & 0xf, snpsid & 0xfff);
1017
1018        if ((snpsid & DWC2_SNPSID_DEVID_MASK) != DWC2_SNPSID_DEVID_VER_2xx) {
1019                printf("SNPSID invalid (not DWC2 OTG device): %08x\n", snpsid);
1020                return -ENODEV;
1021        }
1022
1023        dwc_otg_core_init(regs);
1024        dwc_otg_core_host_init(regs);
1025
1026        clrsetbits_le32(&regs->hprt0, DWC2_HPRT0_PRTENA |
1027                        DWC2_HPRT0_PRTCONNDET | DWC2_HPRT0_PRTENCHNG |
1028                        DWC2_HPRT0_PRTOVRCURRCHNG,
1029                        DWC2_HPRT0_PRTRST);
1030        mdelay(50);
1031        clrbits_le32(&regs->hprt0, DWC2_HPRT0_PRTENA | DWC2_HPRT0_PRTCONNDET |
1032                     DWC2_HPRT0_PRTENCHNG | DWC2_HPRT0_PRTOVRCURRCHNG |
1033                     DWC2_HPRT0_PRTRST);
1034
1035        for (i = 0; i < MAX_DEVICE; i++) {
1036                for (j = 0; j < MAX_ENDPOINT; j++) {
1037                        control_data_toggle[i][j] = DWC2_HC_PID_DATA1;
1038                        bulk_data_toggle[i][j] = DWC2_HC_PID_DATA0;
1039                }
1040        }
1041
1042        return 0;
1043}
1044
1045int usb_lowlevel_stop(int index)
1046{
1047        /* Put everything in reset. */
1048        clrsetbits_le32(&regs->hprt0, DWC2_HPRT0_PRTENA |
1049                        DWC2_HPRT0_PRTCONNDET | DWC2_HPRT0_PRTENCHNG |
1050                        DWC2_HPRT0_PRTOVRCURRCHNG,
1051                        DWC2_HPRT0_PRTRST);
1052        return 0;
1053}
1054